1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
15 package org.simantics.utils.ui.workbench;
17 import java.io.UnsupportedEncodingException;
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.List;
23 import java.util.TreeMap;
24 import java.util.Map.Entry;
26 import org.eclipse.ui.IMemento;
27 import org.simantics.utils.bytes.Base64;
28 import org.simantics.utils.datastructures.Pair;
29 import org.simantics.utils.strings.EString;
33 * StringMemento is IMemento implementation that
34 * handles all information in a single string.
36 * @author Toni Kalajainen
38 public class StringMemento implements IMemento {
40 public final static String TAG_TEXTDATA = "org.simantics.utils.ui.workbench.StringMemento.TAG_TEXTDATA";
42 public final static String CHILD_TAG_CHAR = "#";
43 public final static String ESCAPE_SET = ",="+CHILD_TAG_CHAR;
44 public final static char ESCAPE_CHAR = '\\';
46 protected Map<String, String> values = new TreeMap<String, String>();
47 protected List<ChildType> types = new ArrayList<ChildType>();
48 protected String type = "";
51 StringMemento memento;
52 public ChildType(StringMemento memento)
54 this.memento = memento;
58 public StringMemento()
62 public StringMemento(String data)
63 throws IllegalArgumentException
68 public IMemento createChild(String type) {
69 ChildType ct = new ChildType(new StringMemento());
70 ct.memento.type = type;
75 public IMemento createChild(String type, String id) {
76 IMemento result = createChild(type);
77 result.putString(IMemento.TAG_ID, id);
81 public IMemento getChild(String type) {
82 for (ChildType ct : types)
83 if (ct.memento.type.equals(type))
89 * @see org.eclipse.ui.IMemento#getChildren()
92 public IMemento[] getChildren() {
93 List<IMemento> result = new ArrayList<IMemento>();
94 for (ChildType ct : types)
95 result.add(ct.memento);
96 return result.toArray(new IMemento[result.size()]);
99 public IMemento[] getChildren(String type) {
100 List<IMemento> result = new ArrayList<IMemento>();
101 for (ChildType ct : types)
102 if (ct.memento.type.equals(type))
103 result.add(ct.memento);
104 return result.toArray(new IMemento[result.size()]);
107 public Boolean getBoolean(String key) {
108 String value = getString(key);
109 if (value==null) return null;
110 return Boolean.valueOf(value);
113 public Float getFloat(String key)
115 String value = getString(key);
116 if (value==null) return null;
117 return new Float(value);
120 public Long getLong(String key)
122 String value = getString(key);
123 if (value==null) return null;
124 return new Long(value);
127 public String getType() {
131 public String getID() {
132 return getString(IMemento.TAG_ID);
135 public Integer getInteger(String key) {
136 String value = getString(key);
137 if (value==null) return null;
138 return new Integer(value);
141 public String getString(String key) {
142 return values.get(key);
145 public String getTextData() {
146 return getString(TAG_TEXTDATA);
149 public String[] getAttributeKeys() {
150 Set<String> keys = values.keySet();
151 return keys.toArray(new String[keys.size()]);
154 public void putFloat(String key, float value) {
155 putString(key, new Float(value).toString());
158 public void putInteger(String key, int value) {
159 putString(key, new Integer(value).toString());
162 public void putLong(String key, long value) {
163 putString(key, new Long(value).toString());
166 public void putBoolean(String key, boolean value) {
167 putString(key, String.valueOf(value));
170 public StringMemento clone()
172 return new StringMemento(toString());
175 public void putMemento(IMemento memento) {
176 StringMemento sm = ((StringMemento) memento);
177 addStringData(sm.toString());
181 * Writes self to <code>dst</code>
184 public void writeToMemento(IMemento dst) {
185 for (Entry<String, String> e : values.entrySet())
187 dst.putString(e.getKey(), e.getValue());
189 for (ChildType c : types)
191 IMemento cdst = dst.createChild(c.memento.type);
192 c.memento.writeToMemento(cdst);
196 public void putString(String key, String value) {
197 values.put(key, value);
200 public void putTextData(String data) {
201 putString(TAG_TEXTDATA, data);
204 public boolean isEmpty() {
205 return values.isEmpty() && types.isEmpty();
208 // Serialization part //
210 protected String escapeString(String str)
212 return EString.escapeString(str, ESCAPE_SET, ESCAPE_CHAR);
215 protected String unescapeString(String str)
217 return EString.unescapeString(str, ESCAPE_CHAR);
220 private String scanEscapedString(String str, char endMark)
222 return EString.scanEscapedString(str, ESCAPE_CHAR, endMark);
226 public String toString() {
227 StringBuilder sb = new StringBuilder(100);
228 for (Entry<String, String> e : values.entrySet())
234 if (e.getValue()==null) continue;
235 sb.append(escapeString(e.getKey())+"="+escapeString(e.getValue()));
238 for (ChildType ct : types)
243 sb.append(CHILD_TAG_CHAR+escapeString(ct.memento.type)+"="+escapeString(ct.memento.toString()));
246 return sb.toString();
253 public Set<String> getKeys() {
254 return new HashSet<String>(values.keySet());
258 * Parses string into memento variables and children
259 * @param data string data
260 * @throws IllegalArgumentException
262 public void setStringData(String data)
263 throws IllegalArgumentException
279 * Parses string into memento variables and children
280 * @param data string data
281 * @throws IllegalArgumentException
283 public void addStringData(String data)
284 throws IllegalArgumentException
286 // key\==\=value,key2=value,key3=value,#type=(key\=value\,key2\=value)
287 for (Pair<String, String> pair : scanKeyValues(data))
289 String key = unescapeString(pair.first);
290 String value = unescapeString(pair.second);
292 if (key.startsWith(CHILD_TAG_CHAR))
294 String type = key.substring(1);
295 StringMemento sm = new StringMemento(value);
297 ChildType ct = new ChildType(sm);
300 values.put(key, value);
305 private List<Pair<String, String>> scanKeyValues(String str)
307 List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
309 while(str.length()>0)
311 // Get next key, value -pair
312 String chunk = scanEscapedString(str, ',');
314 if (chunk.length()+1<str.length())
315 str = str.substring(chunk.length()+1);
318 // break chunk into key and value
319 String key = scanEscapedString(chunk, '=');
320 if (key.length()+1<chunk.length())
321 chunk = chunk.substring(key.length()+1);
324 String value = chunk;
326 result.add(new Pair<String, String>(key, value));
333 @SuppressWarnings("unused")
334 public static void main(String [] args)
337 //StringMemento sm = new StringMemento("key\\==\\=value,key2=value,key3=value,#type=key\\=value\\,key2\\=value");
338 StringMemento sm = new StringMemento();
339 sm.putString("Level", "1");
340 StringMemento sm2 = (StringMemento) sm.createChild("Children");
341 sm2.putString("Level", "2");
342 StringMemento sm3 = (StringMemento) sm2.createChild("Children");
343 sm3.putString("Level", "3");
345 StringMemento sm4 = new StringMemento(sm.toString());
346 System.out.println(sm.getChild("Children").getChild("Children").getString("Level"));
347 IMemento sms[] = sm.getChildren("Children");
348 System.out.println(sm.toString());
350 StringMemento sm5 = new StringMemento();
351 IMemento sm6 = sm5.createChild("argument");
352 sm6.putString("arg", "-server");
353 sm6.putString("value", "localhost:6668");
354 System.out.println("simantics link: " + sm5.toString());
356 String b64 = Base64.encode(sm5.toString().getBytes("UTF-8"));
357 System.out.println("simantics link: " + b64);
358 } catch (UnsupportedEncodingException e) {