propertylist/IPropertylist: removed obsolete loadHash_sub()
[metux-java.git] / propertylist / Propertylist.java
blob5e81d7a0a32fd5eb0b9f909701920a37a63da9fe
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 public void loadProperties_sub(Properties pr)
72 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
74 String key = (String) e.nextElement();
76 /* fields with !! always have precedence */
77 if (key.startsWith("!!"))
78 db.put(key.substring(2),(String)pr.get(key));
80 /* fields with ++ are always added, not just overwritten */
81 else if (key.startsWith("++"))
82 add(key.substring(2),(String)pr.get(key));
84 /* in this loading mode we do not overwrite existing fields */
85 else if (!db.containsKey(key))
86 set(key,(String)pr.get(key));
88 cache.clear();
91 @Deprecated
92 public void loadHash_top(Hashtable h)
94 for (Enumeration e = h.keys(); e.hasMoreElements(); )
96 String key = (String) e.nextElement();
97 if (key.startsWith("!!"))
98 set(key.substring(2),(String)h.get(key));
99 else if (key.startsWith("++"))
100 add(key.substring(2),(String)h.get(key));
101 else
102 set(key,(String)h.get(key));
106 public void loadProperties_top(Properties pr)
108 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
110 String key = (String) e.nextElement();
111 if (key.startsWith("!!"))
112 set(key.substring(2),(String)pr.get(key));
113 else if (key.startsWith("++"))
114 add(key.substring(2),(String)pr.get(key));
115 else
116 set(key,(String)pr.get(key));
120 private Properties _load_properties(String filename)
122 if (enable_datasource_cache)
124 if (db_recycling==null)
125 db_recycling = new Hashtable();
127 dbcache_ent ent = (dbcache_ent)db_recycling.get(filename);
128 if (ent!=null)
130 // System.err.println("Found in cache: "+filename);
131 return ent.proplist;
134 ent = new dbcache_ent();
135 ent.proplist = new Properties();
136 if (!TextDB.LoadIntoHashtable(filename,ent.proplist))
138 // System.err.println("Could not load: "+filename);
139 ent.proplist = null;
141 // else
142 // System.err.println("Loaded: "+filename);
144 db_recycling.put(filename,ent);
145 return ent.proplist;
147 else
149 Properties pr = new Properties();
150 if (!TextDB.LoadIntoHashtable(filename,pr))
151 return null;
152 else
153 return pr;
157 public void remove ( String key )
159 db.remove(key);
160 cache.clear();
163 public void set ( String key, String value )
165 db.put(key,value);
166 cache.clear();
169 public void add ( String key, String value )
171 String got;
172 if ((key==null)||(value==null)) return;
174 if ((got=db_get(key))!=null)
175 db.put(key,got+"\n"+value);
176 else
177 db.put(key,value);
180 // can be overwritten, ie for namespace handling, hierachies, etc
181 public String get_raw(String name)
182 throws EIllegalValue
184 if (name.startsWith(":URLENCODE:"))
186 name = name.substring(11);
187 return URLEncoder.encode(get_str(name));
190 return db_get(name);
193 public String get_str(String name)
194 throws EIllegalValue
196 return get_str_rec(name,100);
199 public String[] get_list(String name)
200 throws EIllegalValue
202 return StrSplit.split(get_str(name));
205 /* can be overwritten in order to handle special things like exec()
206 returns null if nothing happened */
207 public String handle_special_str(String key)
209 return null;
212 public boolean get_bool(String name, boolean def)
216 return get_bool(name);
218 catch (EIllegalValue e)
220 return def;
224 public boolean get_bool(String name) throws EIllegalValue
226 String val=get_str(name);
229 return StrUtil.toBool(val);
231 catch (NumberFormatException e)
233 throw new EIllegalValue(name,val);
237 private final String get_str_rec(String key, int depth)
238 throws EIllegalValue
240 if (depth<1)
241 throw new EInfiniteRecursion(key,get_raw(key));
243 /* if we someday want to add special vars/commands, this
244 would probably be the right point */
246 String value;
247 boolean notnull = false;
248 boolean notempty = false;
250 /* handle subclass-defined specials */
251 if ((value=handle_special_str(key))!=null)
252 return value;
254 /* -- parse special modifiers -- */
255 for (boolean parsing=true; parsing;)
257 if (key.startsWith("!notnull!"))
259 notnull = true;
260 key = key.substring(9);
262 else if (key.startsWith("!notempty!"))
264 notempty = true;
265 key = key.substring(10);
267 else
268 parsing = false;
271 if ((value=get_raw(key))==null)
273 if (notnull)
274 throw new EVariableNull(key,value);
275 else
276 return "";
279 /* --- now replace variables --- */
280 int start, end;
282 while ((start=value.indexOf("$("))!=-1) /* scan for $( */
284 if ((end=value.indexOf(')', start+2))!=-1)
286 String name = value.substring(start+2,end);
287 String newval =
288 value.substring(0,start)+
289 get_str_rec(name,depth-1)+
290 value.substring(end+1);
292 value = newval;
294 else
295 throw new EVariableParseError(key,value);
298 if (value.equals("") && notempty)
299 throw new EVariableEmpty(key,value);
301 return value;
304 public String dump()
306 String res = "";
307 for (Enumeration e = db.keys(); e.hasMoreElements(); )
309 String key = (String) e.nextElement();
310 res += key+"=\""+db_get(key)+"\"\n";
312 return res;
315 public boolean load_content(String field, File filename, boolean strip_comments)
317 String text = datasource_cache.loadContent(filename,strip_comments);
319 if (text==null)
320 return false;
321 set(field,text);
322 return true;
325 public boolean load_content(String field, URL url, boolean strip_comments)
327 String text = datasource_cache.loadContent(url,strip_comments);
328 if (text==null)
329 return false;
331 set(field,text);
332 return true;
335 public Enumeration propertyNames()
337 return db.keys();
340 public IPropertylist clone()
342 Propertylist pr = new Propertylist();
343 pr.db = (Properties)db.clone();
345 // copy the database
346 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
348 String k = (String)keys.nextElement();
349 pr.set(k,db_get(k));
351 return pr;
354 public String toString()
356 String str = "[PROPERTYLIST]\n";
357 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
359 String k = (String)keys.nextElement();
360 str += k+"=\""+db_get(k)+"\"\n";
362 return str;