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