]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui.workbench/src/org/simantics/utils/ui/workbench/StringMemento.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.utils.ui.workbench / src / org / simantics / utils / ui / workbench / StringMemento.java
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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 /*\r
13  * 28.6.2006\r
14  */\r
15 package org.simantics.utils.ui.workbench;\r
16 \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
25 \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
30 \r
31 \r
32 /**\r
33  * StringMemento is IMemento implementation that \r
34  * handles all information in a single string.\r
35  * \r
36  * @author Toni Kalajainen\r
37  */\r
38 public class StringMemento implements IMemento {\r
39 \r
40     public final static String TAG_TEXTDATA = "org.simantics.utils.ui.workbench.StringMemento.TAG_TEXTDATA";\r
41 \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
45 \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
49 \r
50     class ChildType {\r
51         StringMemento memento;\r
52         public ChildType(StringMemento memento)\r
53         {\r
54             this.memento = memento;\r
55         }\r
56     }\r
57 \r
58     public StringMemento()\r
59     {\r
60     }\r
61 \r
62     public StringMemento(String data)\r
63     throws IllegalArgumentException\r
64     {\r
65         setStringData(data);\r
66     }\r
67 \r
68     public IMemento createChild(String type) {\r
69         ChildType ct = new ChildType(new StringMemento());\r
70         ct.memento.type = type;\r
71         types.add(ct);\r
72         return ct.memento;\r
73     }\r
74 \r
75     public IMemento createChild(String type, String id) {\r
76         IMemento result = createChild(type);\r
77         result.putString(IMemento.TAG_ID, id);\r
78         return result;\r
79     }\r
80 \r
81     public IMemento getChild(String type) {\r
82         for (ChildType ct : types)\r
83             if (ct.memento.type.equals(type))\r
84                 return ct.memento;\r
85         return null;\r
86     }\r
87 \r
88     /* (non-Javadoc)\r
89      * @see org.eclipse.ui.IMemento#getChildren()\r
90      * @since 3.8\r
91      */\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
97     }\r
98 \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
105     }\r
106 \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
111     }\r
112 \r
113     public Float getFloat(String key) \r
114     {\r
115         String value = getString(key);\r
116         if (value==null) return null;\r
117         return new Float(value);\r
118     }\r
119 \r
120     public Long getLong(String key) \r
121     {\r
122         String value = getString(key);\r
123         if (value==null) return null;\r
124         return new Long(value);\r
125     }\r
126 \r
127     public String getType() {\r
128         return type;\r
129     }\r
130 \r
131     public String getID() {\r
132         return getString(IMemento.TAG_ID);\r
133     }\r
134 \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
139     }\r
140 \r
141     public String getString(String key) {\r
142         return values.get(key);\r
143     }\r
144 \r
145     public String getTextData() {\r
146         return getString(TAG_TEXTDATA);\r
147     }\r
148 \r
149     public String[] getAttributeKeys() {\r
150         Set<String> keys = values.keySet();\r
151         return keys.toArray(new String[keys.size()]);\r
152     }\r
153 \r
154     public void putFloat(String key, float value) {\r
155         putString(key, new Float(value).toString());\r
156     }\r
157 \r
158     public void putInteger(String key, int value) {\r
159         putString(key, new Integer(value).toString());\r
160     }\r
161 \r
162     public void putLong(String key, long value) {\r
163         putString(key, new Long(value).toString());\r
164     }\r
165 \r
166     public void putBoolean(String key, boolean value) {\r
167         putString(key, String.valueOf(value));\r
168     }\r
169 \r
170     public StringMemento clone()\r
171     {\r
172         return new StringMemento(toString());\r
173     }\r
174 \r
175     public void putMemento(IMemento memento) {\r
176         StringMemento sm = ((StringMemento) memento);\r
177         addStringData(sm.toString());\r
178     }\r
179 \r
180     /**\r
181      * Writes self to <code>dst</code>\r
182      * @param dst \r
183      */\r
184     public void writeToMemento(IMemento dst) {\r
185         for (Entry<String, String> e : values.entrySet())\r
186         {\r
187                 dst.putString(e.getKey(), e.getValue());\r
188         }\r
189         for (ChildType c : types)\r
190         {\r
191                 IMemento cdst = dst.createChild(c.memento.type);\r
192                 c.memento.writeToMemento(cdst);\r
193         }\r
194     }\r
195 \r
196     public void putString(String key, String value) {\r
197         values.put(key, value);\r
198     }\r
199 \r
200     public void putTextData(String data) {\r
201         putString(TAG_TEXTDATA, data);\r
202     }\r
203 \r
204     public boolean isEmpty() {\r
205         return values.isEmpty() && types.isEmpty();\r
206     }\r
207 \r
208     // Serialization part //\r
209 \r
210     protected String escapeString(String str)\r
211     {\r
212         return EString.escapeString(str, ESCAPE_SET, ESCAPE_CHAR);\r
213     }\r
214 \r
215     protected String unescapeString(String str)\r
216     {\r
217         return EString.unescapeString(str, ESCAPE_CHAR);\r
218     }\r
219 \r
220     private String scanEscapedString(String str, char endMark)\r
221     {\r
222         return EString.scanEscapedString(str, ESCAPE_CHAR, endMark);\r
223     }\r
224 \r
225     @Override\r
226     public String toString() {\r
227         StringBuilder sb = new StringBuilder(100);\r
228         for (Entry<String, String> e : values.entrySet())\r
229         {\r
230             // Add ,\r
231             if (sb.length()>0)\r
232                 sb.append(",");\r
233             // Add key=value\r
234             if (e.getValue()==null) continue;\r
235             sb.append(escapeString(e.getKey())+"="+escapeString(e.getValue()));\r
236         }\r
237         \r
238         for (ChildType ct : types)\r
239         {\r
240             // Add ,\r
241             if (sb.length()>0)\r
242                 sb.append(",");\r
243             sb.append(CHILD_TAG_CHAR+escapeString(ct.memento.type)+"="+escapeString(ct.memento.toString()));\r
244         }\r
245         \r
246         return sb.toString();\r
247     }\r
248     \r
249     /**\r
250      * Get keys\r
251      * @return\r
252      */\r
253     public Set<String> getKeys() {\r
254         return new HashSet<String>(values.keySet());\r
255     }\r
256 \r
257     /**\r
258      * Parses string into memento variables and children\r
259      * @param data string data\r
260      * @throws IllegalArgumentException\r
261      */\r
262     public void setStringData(String data)\r
263     throws IllegalArgumentException\r
264     {\r
265         clear();\r
266         addStringData(data);\r
267     }\r
268     \r
269     /**\r
270      * Clears all data\r
271      */\r
272     public void clear()\r
273     {\r
274         values.clear();\r
275         types.clear();\r
276     }\r
277     \r
278     /**\r
279      * Parses string into memento variables and children\r
280      * @param data string data\r
281      * @throws IllegalArgumentException\r
282      */\r
283     public void addStringData(String data)\r
284     throws IllegalArgumentException\r
285     {\r
286         // key\==\=value,key2=value,key3=value,#type=(key\=value\,key2\=value)\r
287         for (Pair<String, String> pair : scanKeyValues(data))\r
288         {\r
289             String key = unescapeString(pair.first);\r
290             String value = unescapeString(pair.second);\r
291             \r
292             if (key.startsWith(CHILD_TAG_CHAR))\r
293             {\r
294                 String type = key.substring(1);\r
295                 StringMemento sm = new StringMemento(value);\r
296                 sm.type = type;\r
297                 ChildType ct = new ChildType(sm);\r
298                 types.add(ct);\r
299             } else {\r
300                 values.put(key, value);\r
301             }\r
302         }\r
303     }    \r
304     \r
305     private List<Pair<String, String>> scanKeyValues(String str)\r
306     {\r
307         List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();\r
308         \r
309         while(str.length()>0)\r
310         {\r
311             // Get next key, value -pair\r
312             String chunk = scanEscapedString(str, ',');\r
313             // Crop the chunk\r
314             if (chunk.length()+1<str.length())\r
315                 str = str.substring(chunk.length()+1);\r
316             else\r
317                 str = "";\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
322             else\r
323                 chunk = "";\r
324             String value = chunk;\r
325             \r
326             result.add(new Pair<String, String>(key, value));\r
327         }\r
328         \r
329         return result;\r
330     }\r
331 \r
332 \r
333     @SuppressWarnings("unused")\r
334     public static void main(String [] args)\r
335     {\r
336         \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
344                 \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
349 \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
355         try {\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
360         }\r
361     }\r
362 \r
363 }\r