propertylist/IPropertylist: removed obsolete loadHash_top()
[metux-java.git] / propertylist / Propertylist.java
blobee3a28f8fdafa87cb5c5ba1a99970b1387edfe1e
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 public void loadProperties_top(Properties pr)
93 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
95 String key = (String) e.nextElement();
96 if (key.startsWith("!!"))
97 set(key.substring(2),(String)pr.get(key));
98 else if (key.startsWith("++"))
99 add(key.substring(2),(String)pr.get(key));
100 else
101 set(key,(String)pr.get(key));
105 private Properties _load_properties(String filename)
107 if (enable_datasource_cache)
109 if (db_recycling==null)
110 db_recycling = new Hashtable();
112 dbcache_ent ent = (dbcache_ent)db_recycling.get(filename);
113 if (ent!=null)
115 // System.err.println("Found in cache: "+filename);
116 return ent.proplist;
119 ent = new dbcache_ent();
120 ent.proplist = new Properties();
121 if (!TextDB.LoadIntoHashtable(filename,ent.proplist))
123 // System.err.println("Could not load: "+filename);
124 ent.proplist = null;
126 // else
127 // System.err.println("Loaded: "+filename);
129 db_recycling.put(filename,ent);
130 return ent.proplist;
132 else
134 Properties pr = new Properties();
135 if (!TextDB.LoadIntoHashtable(filename,pr))
136 return null;
137 else
138 return pr;
142 public void remove ( String key )
144 db.remove(key);
145 cache.clear();
148 public void set ( String key, String value )
150 db.put(key,value);
151 cache.clear();
154 public void add ( String key, String value )
156 String got;
157 if ((key==null)||(value==null)) return;
159 if ((got=db_get(key))!=null)
160 db.put(key,got+"\n"+value);
161 else
162 db.put(key,value);
165 // can be overwritten, ie for namespace handling, hierachies, etc
166 public String get_raw(String name)
167 throws EIllegalValue
169 if (name.startsWith(":URLENCODE:"))
171 name = name.substring(11);
172 return URLEncoder.encode(get_str(name));
175 return db_get(name);
178 public String get_str(String name)
179 throws EIllegalValue
181 return get_str_rec(name,100);
184 public String[] get_list(String name)
185 throws EIllegalValue
187 return StrSplit.split(get_str(name));
190 /* can be overwritten in order to handle special things like exec()
191 returns null if nothing happened */
192 public String handle_special_str(String key)
194 return null;
197 public boolean get_bool(String name, boolean def)
201 return get_bool(name);
203 catch (EIllegalValue e)
205 return def;
209 public boolean get_bool(String name) throws EIllegalValue
211 String val=get_str(name);
214 return StrUtil.toBool(val);
216 catch (NumberFormatException e)
218 throw new EIllegalValue(name,val);
222 private final String get_str_rec(String key, int depth)
223 throws EIllegalValue
225 if (depth<1)
226 throw new EInfiniteRecursion(key,get_raw(key));
228 /* if we someday want to add special vars/commands, this
229 would probably be the right point */
231 String value;
232 boolean notnull = false;
233 boolean notempty = false;
235 /* handle subclass-defined specials */
236 if ((value=handle_special_str(key))!=null)
237 return value;
239 /* -- parse special modifiers -- */
240 for (boolean parsing=true; parsing;)
242 if (key.startsWith("!notnull!"))
244 notnull = true;
245 key = key.substring(9);
247 else if (key.startsWith("!notempty!"))
249 notempty = true;
250 key = key.substring(10);
252 else
253 parsing = false;
256 if ((value=get_raw(key))==null)
258 if (notnull)
259 throw new EVariableNull(key,value);
260 else
261 return "";
264 /* --- now replace variables --- */
265 int start, end;
267 while ((start=value.indexOf("$("))!=-1) /* scan for $( */
269 if ((end=value.indexOf(')', start+2))!=-1)
271 String name = value.substring(start+2,end);
272 String newval =
273 value.substring(0,start)+
274 get_str_rec(name,depth-1)+
275 value.substring(end+1);
277 value = newval;
279 else
280 throw new EVariableParseError(key,value);
283 if (value.equals("") && notempty)
284 throw new EVariableEmpty(key,value);
286 return value;
289 public String dump()
291 String res = "";
292 for (Enumeration e = db.keys(); e.hasMoreElements(); )
294 String key = (String) e.nextElement();
295 res += key+"=\""+db_get(key)+"\"\n";
297 return res;
300 public boolean load_content(String field, File filename, boolean strip_comments)
302 String text = datasource_cache.loadContent(filename,strip_comments);
304 if (text==null)
305 return false;
306 set(field,text);
307 return true;
310 public boolean load_content(String field, URL url, boolean strip_comments)
312 String text = datasource_cache.loadContent(url,strip_comments);
313 if (text==null)
314 return false;
316 set(field,text);
317 return true;
320 public Enumeration propertyNames()
322 return db.keys();
325 public IPropertylist clone()
327 Propertylist pr = new Propertylist();
328 pr.db = (Properties)db.clone();
330 // copy the database
331 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
333 String k = (String)keys.nextElement();
334 pr.set(k,db_get(k));
336 return pr;
339 public String toString()
341 String str = "[PROPERTYLIST]\n";
342 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
344 String k = (String)keys.nextElement();
345 str += k+"=\""+db_get(k)+"\"\n";
347 return str;