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