propertylist/IPropertylist: removed obsolete loadHash_low()
[metux-java.git] / propertylist / Propertylist.java
blob74381d974bf70c9f303c5523eefdbd47529bc703
2 //
3 // FIXME: replace Hashtable by Properties
4 //
6 package org.de.metux.propertylist;
8 import java.io.*;
9 import java.util.Enumeration;
10 import java.util.Hashtable;
11 import java.util.Properties;
13 import java.lang.NumberFormatException;
15 import org.de.metux.util.StrSplit;
16 import org.de.metux.util.TextDB;
17 import org.de.metux.util.UniqueNameList;
18 import org.de.metux.util.LoadFile;
19 import org.de.metux.util.StrUtil;
20 import org.de.metux.util.CachedDatasource;
22 import java.net.URLEncoder;
24 import java.net.URL;
26 public class Propertylist implements IPropertylist
28 Properties db = new Properties();
29 Properties cache = new Properties();
30 IPostprocessor postprocessor;
32 public boolean enable_datasource_cache = false;
33 public static Hashtable db_recycling = null;
34 public static CachedDatasource datasource_cache = new CachedDatasource();
36 private class dbcache_ent
38 public Properties proplist;
39 public String text;
42 /* this method loads data from a hashtable into the propertysheet
43 with low priority, means that existing fields are not touched.
45 the opposite would be high priority meaning existing fields
46 will be overwritten.
49 public void setPostprocessor(IPostprocessor p)
51 postprocessor = p;
54 public void runPostprocessor()
55 throws EIllegalValue
57 if (postprocessor==null)
58 return;
60 /* run as long as it returns true */
61 while(postprocessor.propertylist_postprocess((IPropertylist)this));
64 /* get a really raw string, directly from database */
65 public String db_get(String field)
67 return (String)db.get(field);
70 @Deprecated
71 public void loadHash_sub(Hashtable h)
73 for (Enumeration e = h.keys(); e.hasMoreElements(); )
75 String key = (String) e.nextElement();
77 /* fields with !! always have precedence */
78 if (key.startsWith("!!"))
79 db.put(key.substring(2),(String)h.get(key));
81 /* fields with ++ are always added, not just overwritten */
82 else if (key.startsWith("++"))
83 add(key.substring(2),(String)h.get(key));
85 /* in this loading mode we do not overwrite existing fields */
86 else if (!db.containsKey(key))
87 set(key,(String)h.get(key));
89 cache.clear();
92 public void loadProperties_sub(Properties pr)
94 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
96 String key = (String) e.nextElement();
98 /* fields with !! always have precedence */
99 if (key.startsWith("!!"))
100 db.put(key.substring(2),(String)pr.get(key));
102 /* fields with ++ are always added, not just overwritten */
103 else if (key.startsWith("++"))
104 add(key.substring(2),(String)pr.get(key));
106 /* in this loading mode we do not overwrite existing fields */
107 else if (!db.containsKey(key))
108 set(key,(String)pr.get(key));
110 cache.clear();
113 @Deprecated
114 public void loadHash_top(Hashtable h)
116 for (Enumeration e = h.keys(); e.hasMoreElements(); )
118 String key = (String) e.nextElement();
119 if (key.startsWith("!!"))
120 set(key.substring(2),(String)h.get(key));
121 else if (key.startsWith("++"))
122 add(key.substring(2),(String)h.get(key));
123 else
124 set(key,(String)h.get(key));
128 public void loadProperties_top(Properties pr)
130 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
132 String key = (String) e.nextElement();
133 if (key.startsWith("!!"))
134 set(key.substring(2),(String)pr.get(key));
135 else if (key.startsWith("++"))
136 add(key.substring(2),(String)pr.get(key));
137 else
138 set(key,(String)pr.get(key));
142 private Properties _load_properties(String filename)
144 if (enable_datasource_cache)
146 if (db_recycling==null)
147 db_recycling = new Hashtable();
149 dbcache_ent ent = (dbcache_ent)db_recycling.get(filename);
150 if (ent!=null)
152 // System.err.println("Found in cache: "+filename);
153 return ent.proplist;
156 ent = new dbcache_ent();
157 ent.proplist = new Properties();
158 if (!TextDB.LoadIntoHashtable(filename,ent.proplist))
160 // System.err.println("Could not load: "+filename);
161 ent.proplist = null;
163 // else
164 // System.err.println("Loaded: "+filename);
166 db_recycling.put(filename,ent);
167 return ent.proplist;
169 else
171 Properties pr = new Properties();
172 if (!TextDB.LoadIntoHashtable(filename,pr))
173 return null;
174 else
175 return pr;
179 public boolean loadTextDB_sub(String filename)
181 Properties pr = _load_properties(filename);
182 if (pr==null)
184 // System.err.println("Couldnt load properties from: "+filename);
185 return false;
187 loadHash_sub(pr);
188 return true;
191 public boolean loadTextDB_top(File filename)
193 return loadTextDB_top(filename.toString());
196 public boolean loadTextDB_top(String filename)
198 Properties pr = _load_properties(filename);
200 if (pr==null)
201 return false;
203 loadHash_top(pr);
204 return true;
207 public void remove ( String key )
209 db.remove(key);
210 cache.clear();
213 public void set ( String key, String value )
215 db.put(key,value);
216 cache.clear();
219 public void add ( String key, String value )
221 String got;
222 if ((key==null)||(value==null)) return;
224 if ((got=db_get(key))!=null)
225 db.put(key,got+"\n"+value);
226 else
227 db.put(key,value);
230 // can be overwritten, ie for namespace handling, hierachies, etc
231 public String get_raw(String name)
232 throws EIllegalValue
234 if (name.startsWith(":URLENCODE:"))
236 name = name.substring(11);
237 return URLEncoder.encode(get_str(name));
240 return db_get(name);
243 public String get_str(String name)
244 throws EIllegalValue
246 return get_str_rec(name,100);
249 public String[] get_list(String name)
250 throws EIllegalValue
252 return StrSplit.split(get_str(name));
255 /* can be overwritten in order to handle special things like exec()
256 returns null if nothing happened */
257 public String handle_special_str(String key)
259 return null;
262 public boolean get_bool(String name, boolean def)
266 return get_bool(name);
268 catch (EIllegalValue e)
270 return def;
274 public boolean get_bool(String name) throws EIllegalValue
276 String val=get_str(name);
279 return StrUtil.toBool(val);
281 catch (NumberFormatException e)
283 throw new EIllegalValue(name,val);
287 private final String get_str_rec(String key, int depth)
288 throws EIllegalValue
290 if (depth<1)
291 throw new EInfiniteRecursion(key,get_raw(key));
293 /* if we someday want to add special vars/commands, this
294 would probably be the right point */
296 String value;
297 boolean notnull = false;
298 boolean notempty = false;
300 /* handle subclass-defined specials */
301 if ((value=handle_special_str(key))!=null)
302 return value;
304 /* -- parse special modifiers -- */
305 for (boolean parsing=true; parsing;)
307 if (key.startsWith("!notnull!"))
309 notnull = true;
310 key = key.substring(9);
312 else if (key.startsWith("!notempty!"))
314 notempty = true;
315 key = key.substring(10);
317 else
318 parsing = false;
321 if ((value=get_raw(key))==null)
323 if (notnull)
324 throw new EVariableNull(key,value);
325 else
326 return "";
329 /* --- now replace variables --- */
330 int start, end;
332 while ((start=value.indexOf("$("))!=-1) /* scan for $( */
334 if ((end=value.indexOf(')', start+2))!=-1)
336 String name = value.substring(start+2,end);
337 String newval =
338 value.substring(0,start)+
339 get_str_rec(name,depth-1)+
340 value.substring(end+1);
342 value = newval;
344 else
345 throw new EVariableParseError(key,value);
348 if (value.equals("") && notempty)
349 throw new EVariableEmpty(key,value);
351 return value;
354 public String dump()
356 String res = "";
357 for (Enumeration e = db.keys(); e.hasMoreElements(); )
359 String key = (String) e.nextElement();
360 res += key+"=\""+db_get(key)+"\"\n";
362 return res;
365 public boolean load_content(String field, File filename, boolean strip_comments)
367 String text = datasource_cache.loadContent(filename,strip_comments);
369 if (text==null)
370 return false;
371 set(field,text);
372 return true;
375 public boolean load_content(String field, URL url, boolean strip_comments)
377 String text = datasource_cache.loadContent(url,strip_comments);
378 if (text==null)
379 return false;
381 set(field,text);
382 return true;
385 public Enumeration propertyNames()
387 return db.keys();
390 public IPropertylist clone()
392 Propertylist pr = new Propertylist();
393 pr.db = (Properties)db.clone();
395 // copy the database
396 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
398 String k = (String)keys.nextElement();
399 pr.set(k,db_get(k));
401 return pr;
404 public String toString()
406 String str = "[PROPERTYLIST]\n";
407 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
409 String k = (String)keys.nextElement();
410 str += k+"=\""+db_get(k)+"\"\n";
412 return str;