Makefile added / pkg-config descriptor
[metux-java.git] / propertylist / Propertylist.java
blob5a6a913e74dc8a88f401c50234095f2bdb76eaba
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 static Hashtable db_recycling = null;
33 public static CachedDatasource datasource_cache = new CachedDatasource();
35 private class dbcache_ent
37 public Properties proplist;
38 public String text;
41 /* this method loads data from a hashtable into the propertysheet
42 with low priority, means that existing fields are not touched.
44 the opposite would be high priority meaning existing fields
45 will be overwritten.
48 public void setPostprocessor(IPostprocessor p)
50 postprocessor = p;
53 public void runPostprocessor()
54 throws EIllegalValue
56 if (postprocessor==null)
57 return;
59 /* run as long as it returns true */
60 while(postprocessor.propertylist_postprocess((IPropertylist)this));
63 /* get a really raw string, directly from database */
64 public String db_get(String field)
66 return (String)db.get(field);
69 public void loadProperties_sub(Properties pr)
71 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
73 String key = (String) e.nextElement();
75 /* fields with !! always have precedence */
76 if (key.startsWith("!!"))
77 db.put(key.substring(2),(String)pr.get(key));
79 /* fields with ++ are always added, not just overwritten */
80 else if (key.startsWith("++"))
81 add(key.substring(2),(String)pr.get(key));
83 /* in this loading mode we do not overwrite existing fields */
84 else if (!db.containsKey(key))
85 set(key,(String)pr.get(key));
87 cache.clear();
90 public void loadProperties_top(Properties pr)
92 for (Enumeration e = pr.keys(); e.hasMoreElements(); )
94 String key = (String) e.nextElement();
95 if (key.startsWith("!!"))
96 set(key.substring(2),(String)pr.get(key));
97 else if (key.startsWith("++"))
98 add(key.substring(2),(String)pr.get(key));
99 else
100 set(key,(String)pr.get(key));
104 public void remove ( String key )
106 db.remove(key);
107 cache.clear();
110 public void set ( String key, String value )
112 db.put(key,value);
113 cache.clear();
116 public void add ( String key, String value )
118 String got;
119 if ((key==null)||(value==null)) return;
121 if ((got=db_get(key))!=null)
122 db.put(key,got+"\n"+value);
123 else
124 db.put(key,value);
127 // can be overwritten, ie for namespace handling, hierachies, etc
128 public String get_raw(String name)
129 throws EIllegalValue
131 if (name.startsWith(":URLENCODE:"))
133 name = name.substring(11);
134 return URLEncoder.encode(get_str(name));
137 return db_get(name);
140 public String get_str(String name)
141 throws EIllegalValue
143 return get_str_rec(name,100);
146 public String[] get_list(String name)
147 throws EIllegalValue
149 return StrSplit.split(get_str(name));
152 /* can be overwritten in order to handle special things like exec()
153 returns null if nothing happened */
154 public String handle_special_str(String key)
156 return null;
159 public boolean get_bool(String name, boolean def)
163 return get_bool(name);
165 catch (EIllegalValue e)
167 return def;
171 public boolean get_bool(String name) throws EIllegalValue
173 String val=get_str(name);
176 return StrUtil.toBool(val);
178 catch (NumberFormatException e)
180 throw new EIllegalValue(name,val);
184 private final String get_str_rec(String key, int depth)
185 throws EIllegalValue
187 if (depth<1)
188 throw new EInfiniteRecursion(key,get_raw(key));
190 /* if we someday want to add special vars/commands, this
191 would probably be the right point */
193 String value;
194 boolean notnull = false;
195 boolean notempty = false;
197 /* handle subclass-defined specials */
198 if ((value=handle_special_str(key))!=null)
199 return value;
201 /* -- parse special modifiers -- */
202 for (boolean parsing=true; parsing;)
204 if (key.startsWith("!notnull!"))
206 notnull = true;
207 key = key.substring(9);
209 else if (key.startsWith("!notempty!"))
211 notempty = true;
212 key = key.substring(10);
214 else
215 parsing = false;
218 if ((value=get_raw(key))==null)
220 if (notnull)
221 throw new EVariableNull(key,value);
222 else
223 return "";
226 /* --- now replace variables --- */
227 int start, end;
229 while ((start=value.indexOf("$("))!=-1) /* scan for $( */
231 if ((end=value.indexOf(')', start+2))!=-1)
233 String name = value.substring(start+2,end);
234 String newval =
235 value.substring(0,start)+
236 get_str_rec(name,depth-1)+
237 value.substring(end+1);
239 value = newval;
241 else
242 throw new EVariableParseError(key,value);
245 if (value.equals("") && notempty)
246 throw new EVariableEmpty(key,value);
248 return value;
251 public String dump()
253 String res = "";
254 for (Enumeration e = db.keys(); e.hasMoreElements(); )
256 String key = (String) e.nextElement();
257 res += key+"=\""+db_get(key)+"\"\n";
259 return res;
262 public boolean load_content(String field, File filename, boolean strip_comments)
264 String text = datasource_cache.loadContent(filename,strip_comments);
266 if (text==null)
267 return false;
268 set(field,text);
269 return true;
272 public boolean load_content(String field, URL url, boolean strip_comments)
274 String text = datasource_cache.loadContent(url,strip_comments);
275 if (text==null)
276 return false;
278 set(field,text);
279 return true;
282 public Enumeration propertyNames()
284 return db.keys();
287 public IPropertylist clone()
289 Propertylist pr = new Propertylist();
290 pr.db = (Properties)db.clone();
292 // copy the database
293 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
295 String k = (String)keys.nextElement();
296 pr.set(k,db_get(k));
298 return pr;
301 public String toString()
303 String str = "[PROPERTYLIST]\n";
304 for (Enumeration keys = db.keys(); keys.hasMoreElements(); )
306 String k = (String)keys.nextElement();
307 str += k+"=\""+db_get(k)+"\"\n";
309 return str;