1 24 package org.ofbiz.base.util.collections; 25 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.Serializable ; 29 import java.net.URL ; 30 import java.util.ArrayList ; 31 import java.util.Enumeration ; 32 import java.util.Iterator ; 33 import java.util.Properties ; 34 import java.util.Set ; 35 36 import org.ofbiz.base.util.Debug; 37 38 45 public class FlexibleProperties extends Properties implements Serializable { 46 47 public static final String module = FlexibleProperties.class.getName(); 48 49 private static final boolean truncateIfMissingDefault = false; 50 private static final boolean doPropertyExpansionDefault = true; 51 52 private URL url = null; 53 private boolean doPropertyExpansion = doPropertyExpansionDefault; 54 private boolean truncateIfMissing = truncateIfMissingDefault; 55 56 public FlexibleProperties() { 58 super(); 59 } 60 61 public FlexibleProperties(Properties properties) { 62 super(properties); 63 } 64 65 public FlexibleProperties(URL url) { 66 this.url = url; 67 init(); 68 } 69 70 public FlexibleProperties(URL url, Properties properties) { 71 super(properties); 72 this.url = url; 73 init(); 74 } 75 76 public static FlexibleProperties makeFlexibleProperties(Properties properties) { 78 return new FlexibleProperties(properties); 79 } 80 81 public static FlexibleProperties makeFlexibleProperties(URL url) { 82 return new FlexibleProperties(url); 83 } 84 85 public static FlexibleProperties makeFlexibleProperties(URL url, Properties properties) { 86 return new FlexibleProperties(url, properties); 87 } 88 89 public static FlexibleProperties makeFlexibleProperties(String [] keysAndValues) { 90 if ((keysAndValues.length % 2) != 0) { 92 throw new IllegalArgumentException ("FlexibleProperties(String[] keysAndValues) cannot accept an odd number of elements!"); 93 } 94 Properties newProperties = new Properties (); 95 96 for (int i = 0; i < keysAndValues.length; i += 2) { 97 newProperties.setProperty(keysAndValues[i], keysAndValues[i + 1]); 98 } 99 100 return new FlexibleProperties(newProperties); 101 } 102 103 private void init() { 104 try { 105 load(); 106 } catch (IOException e) { 107 Debug.log(e, module); 108 } 109 } 110 111 public boolean getDoPropertyExpansion() { 112 return doPropertyExpansion; 113 } 114 115 public void setDoPropertyExpansion(boolean doPropertyExpansion) { 116 this.doPropertyExpansion = doPropertyExpansion; 117 } 118 119 public boolean getTruncateIfMissing() { 120 return truncateIfMissing; 121 } 122 123 public void setTruncateIfMissing(boolean truncateIfMissing) { 124 this.truncateIfMissing = truncateIfMissing; 125 } 126 127 public URL getURL() { 128 return url; 129 } 130 131 public void setURL(URL url) { 132 this.url = url; 133 init(); 134 } 135 136 public Properties getDefaultProperties() { 137 return this.defaults; 138 } 139 140 public void setDefaultProperties(Properties defaults) { 141 this.defaults = new FlexibleProperties(defaults); 142 } 143 144 protected synchronized void load() throws IOException { 145 if (url == null) return; 146 InputStream in = null; 147 148 try { 149 in = url.openStream(); 150 } catch (Exception urlex) { 151 Debug.log(urlex, "[FlexibleProperties.load]: Couldn't find the URL: " + url, module); 152 } 153 154 if (in == null) throw new IOException ("Could not open resource URL " + url); 155 156 super.load(in); 157 in.close(); 158 159 if (defaults instanceof FlexibleProperties) ((FlexibleProperties) defaults).reload(); 160 if (getDoPropertyExpansion()) interpolateProperties(); 161 } 162 163 public synchronized void store(String header) throws IOException { 164 super.store(url.openConnection().getOutputStream(), header); 165 } 166 167 public synchronized void reload() throws IOException { 168 Debug.log("Reloading the resource: " + url, module); 169 this.load(); 170 } 171 172 public void interpolateProperties() { 174 if ((defaults != null) && (defaults instanceof FlexibleProperties)) { 175 ((FlexibleProperties) defaults).interpolateProperties(); 176 } 177 interpolateProperties(this, getTruncateIfMissing()); 178 } 179 180 public static void interpolateProperties(Properties props) { 181 interpolateProperties(props, truncateIfMissingDefault); 182 } 183 184 public static void interpolateProperties(Properties props, boolean truncateIfMissing) { 185 Enumeration keys = props.keys(); 186 187 while (keys.hasMoreElements()) { 188 String key = keys.nextElement().toString(); 189 String value = props.getProperty(key); 190 191 key = interpolate(key, props, truncateIfMissing); 192 props.setProperty(key, interpolate(value, props, truncateIfMissing)); 193 } 194 } 195 196 public static String interpolate(String value, Properties props) { 197 return interpolate(value, props, truncateIfMissingDefault); 198 } 199 200 public static String interpolate(String value, Properties props, boolean truncateIfMissing) { 201 return interpolate(value, props, truncateIfMissing, null); 202 } 203 204 public static String interpolate(String value, Properties props, boolean truncateIfMissing, ArrayList beenThere) { 205 if (props == null || value == null) return value; 206 if (beenThere == null) { 207 beenThere = new ArrayList (); 208 } else { } 211 int start = value.indexOf("${"); 212 213 while (start > -1) { 214 int end = value.indexOf("}", (start + 2)); 215 216 if (end > start + 2) { 217 String keyToExpand = value.substring((start + 2), end); 218 int nestedStart = keyToExpand.indexOf("${"); 219 220 while (nestedStart > -1) { 221 end = value.indexOf("}", (end + 1)); 222 if (end > -1) { 223 keyToExpand = value.substring((start + 2), end); 224 nestedStart = keyToExpand.indexOf("${", (nestedStart + 2)); 225 } else { 226 Debug.log("[FlexibleProperties.interpolate] Malformed value: [" + value + "] " + "contained unbalanced start \"${\" and end \"}\" characters", module); 227 return value; 228 } 229 } 230 if (keyToExpand.indexOf("${") > -1) { 232 234 ArrayList tempBeenThere = new ArrayList (beenThere); 236 237 beenThere.add(keyToExpand); 238 keyToExpand = interpolate(keyToExpand, props, truncateIfMissing, beenThere); 239 beenThere = tempBeenThere; 240 } 241 if (beenThere.contains(keyToExpand)) { 242 beenThere.add(keyToExpand); 243 Debug.log("[FlexibleProperties.interpolate] Recursion loop detected: Property:[" + beenThere.get(0) + "] " + "included property: [" + keyToExpand + "]", module); 244 Debug.log("[FlexibleProperties.interpolate] Recursion loop path:" + beenThere, module); 245 return value; 246 } else { 247 String expandValue = null; 248 249 if (keyToExpand.startsWith("env.")) { 250 String envValue = System.getProperty(keyToExpand.substring(4)); 251 252 if (envValue == null) { 253 Debug.log("[FlexibleProperties.interpolate] ERROR: Could not find environment variable named: " + keyToExpand.substring(4), module); 254 } else { 255 expandValue = envValue; 256 } 258 } else { 259 expandValue = props.getProperty(keyToExpand); 260 } 262 263 if (expandValue != null) { 264 266 if (expandValue.indexOf("${") > -1) { 268 ArrayList tempBeenThere = new ArrayList (beenThere); 271 272 beenThere.add(keyToExpand); 273 expandValue = interpolate(expandValue, props, truncateIfMissing, beenThere); 274 beenThere = tempBeenThere; 275 } 276 value = value.substring(0, start) + expandValue + value.substring(end + 1); 277 end = start + expandValue.length(); 278 279 } else { 280 if (truncateIfMissing == true) { 282 value = value.substring(0, start) + value.substring(end + 1); 283 } 284 } 285 } 286 } else { 287 Debug.log("[FlexibleProperties.interpolate] Value [" + value + "] starts but does end variable", module); 288 return value; 289 } 290 start = value.indexOf("${", end); 291 } 292 return value; 293 } 294 295 public Object clone() { 297 FlexibleProperties c = (FlexibleProperties) super.clone(); 298 299 if (defaults != null && !this.equals(defaults)) { 301 c.defaults = (FlexibleProperties) getDefaultProperties().clone(); 302 } 303 return c; 304 } 305 306 public String toString() { 307 StringBuffer retVal = new StringBuffer (); 308 Set keySet = keySet(); 309 Iterator keys = keySet.iterator(); 310 311 while (keys.hasNext()) { 312 String key = keys.next().toString(); 313 String value = getProperty(key); 314 315 retVal.append(key); 316 retVal.append("="); 317 retVal.append(value); 318 retVal.append("\n"); 319 } 320 321 return retVal.toString(); 322 } 323 } 324 | Popular Tags |