1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.services.property.PropertyUtil |
4 | |
5 | Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.services.property; |
22 | |
23 | import org.apache.derby.iapi.reference.Property; |
24 | import org.apache.derby.iapi.reference.SQLState; |
25 | import org.apache.derby.iapi.reference.Attribute; |
26 | import org.apache.derby.iapi.reference.EngineType; |
27 | import org.apache.derby.iapi.services.monitor.Monitor; |
28 | import org.apache.derby.iapi.services.monitor.ModuleFactory; |
29 | import org.apache.derby.iapi.error.StandardException; |
30 | import org.apache.derby.iapi.util.StringUtil; |
31 | |
32 | import java.util.Properties; |
33 | import java.io.Serializable; |
34 | import java.util.Dictionary; |
35 | |
36 | /** |
37 | There are 5 property objects within a JBMS system. |
38 | |
39 | 1) JVM - JVM set - those in System.getProperties |
40 | 2) APP - Application set - derby.properties file |
41 | 3) SRV - Persistent Service set - Those stored in service.properties |
42 | 4) TRAN - Persistent Transactional set - Those stored via the AccessManager interface |
43 | 5) BOOT - Set by a boot method (rare) |
44 | |
45 | This class has a set of static methods to find a property using a consistent search order |
46 | from the above set. |
47 | <BR> |
48 | getSystem*() methods use the search order. |
49 | <OL> |
50 | <LI> JVM |
51 | <LI> APP |
52 | </OL> |
53 | <BR> |
54 | getService* methods use the search order |
55 | <OL> |
56 | <LI> JVM |
57 | <LI> TRAN |
58 | <LI> SRV |
59 | <LI> APP |
60 | </OL> |
61 | |
62 | */ |
63 | public class PropertyUtil { |
64 | |
65 | // List of properties that are stored in the service.properties file |
66 | public static final String[] servicePropertyList = { |
67 | EngineType.PROPERTY, |
68 | Property.NO_AUTO_BOOT, |
69 | Property.STORAGE_TEMP_DIRECTORY, |
70 | Attribute.CRYPTO_PROVIDER, |
71 | Attribute.CRYPTO_ALGORITHM, |
72 | Attribute.RESTORE_FROM, |
73 | Attribute.LOG_DEVICE, |
74 | Property.LOG_ARCHIVE_MODE |
75 | }; |
76 | |
77 | /** |
78 | Property is set in JVM set |
79 | */ |
80 | public static final int SET_IN_JVM = 0; |
81 | /** |
82 | Property is set in DATABASE set |
83 | */ |
84 | public static final int SET_IN_DATABASE = 1; |
85 | /** |
86 | Property is set in APPLICATION (derby.properties) set |
87 | */ |
88 | public static final int SET_IN_APPLICATION = 2; |
89 | |
90 | /** |
91 | Property is not set. |
92 | */ |
93 | public static final int NOT_SET = -1; |
94 | |
95 | |
96 | static int whereSet(String key, Dictionary set) { |
97 | |
98 | boolean dbOnly = isDBOnly(set); |
99 | |
100 | if (!dbOnly) { |
101 | if (Monitor.getMonitor().getJVMProperty(key) != null) { |
102 | return SET_IN_JVM; |
103 | } |
104 | } |
105 | |
106 | if ((set != null) && (set.get(key) != null)) |
107 | return SET_IN_DATABASE; |
108 | |
109 | if (!dbOnly) { |
110 | if (PropertyUtil.getSystemProperty(key) != null) |
111 | return SET_IN_APPLICATION; |
112 | } |
113 | |
114 | return NOT_SET; |
115 | } |
116 | |
117 | public static boolean isDBOnly(Dictionary set) { |
118 | |
119 | if (set == null) |
120 | return false; |
121 | |
122 | String value = (String) set.get(Property.DATABASE_PROPERTIES_ONLY); |
123 | |
124 | boolean dbOnly = Boolean.valueOf( |
125 | (value != null ? value.trim() : value)).booleanValue(); |
126 | |
127 | return dbOnly; |
128 | } |
129 | |
130 | public static boolean isDBOnly(Properties set) { |
131 | |
132 | if (set == null) |
133 | return false; |
134 | |
135 | String value = set.getProperty(Property.DATABASE_PROPERTIES_ONLY); |
136 | |
137 | boolean dbOnly = Boolean.valueOf( |
138 | (value != null ? value.trim() : value)).booleanValue(); |
139 | |
140 | return dbOnly; |
141 | } |
142 | |
143 | /** |
144 | Find a system wide property. |
145 | |
146 | @return the value of the property or null if it does not exist. |
147 | @see #getSystemProperty(String,String) |
148 | */ |
149 | public static String getSystemProperty(String key) { |
150 | return PropertyUtil.getSystemProperty(key, (String) null); |
151 | } |
152 | |
153 | /** |
154 | Find a system wide property with a default. Search order is |
155 | |
156 | <OL> |
157 | <LI> JVM property |
158 | <LI> derby.properties |
159 | </OL> |
160 | |
161 | <P> |
162 | This method can be used by a system that is not running Cloudscape, |
163 | just to maintain the same lookup logic and security manager concerns |
164 | for finding derby.properties and reading system properties. |
165 | |
166 | @return the value of the property or defaultValue if it does not exist. |
167 | */ |
168 | public static String getSystemProperty(String key, String defaultValue) { |
169 | |
170 | ModuleFactory monitor = Monitor.getMonitorLite(); |
171 | |
172 | String value = monitor.getJVMProperty(key); |
173 | |
174 | if (value == null) { |
175 | |
176 | Properties applicationProperties = |
177 | monitor.getApplicationProperties(); |
178 | |
179 | if (applicationProperties != null) |
180 | value = applicationProperties.getProperty(key); |
181 | } |
182 | return value == null ? defaultValue : value; |
183 | } |
184 | |
185 | |
186 | /** |
187 | Get a property from the passed in set. The passed in set is |
188 | either: |
189 | |
190 | <UL> |
191 | <LI> The properties object passed into ModuleControl.boot() |
192 | after the database has been booted. This set will be a DoubleProperties |
193 | object with the per-database transaction set as the read set |
194 | and the service.properties as the write set. |
195 | <LI> |
196 | The Dictionary set returned/passed in by a method of BasicService.Properties. |
197 | </UL> |
198 | <BR> |
199 | This method uses the same search order as the getService() calls. |
200 | |
201 | */ |
202 | public static String getPropertyFromSet(Properties set, String key) { |
203 | |
204 | boolean dbOnly = set != null ? isDBOnly(set) : false; |
205 | |
206 | return PropertyUtil.getPropertyFromSet(dbOnly, set, key); |
207 | } |
208 | |
209 | public static Serializable getPropertyFromSet(Dictionary set, String key) { |
210 | |
211 | boolean dbOnly = set != null ? isDBOnly(set) : false; |
212 | |
213 | return PropertyUtil.getPropertyFromSet(dbOnly, set, key); |
214 | } |
215 | |
216 | public static Serializable getPropertyFromSet(boolean dbOnly, Dictionary set, String key) { |
217 | |
218 | if (set != null) { |
219 | |
220 | Serializable value; |
221 | |
222 | if (!dbOnly) { |
223 | value = Monitor.getMonitor().getJVMProperty(key); |
224 | if (value != null) |
225 | return value; |
226 | } |
227 | |
228 | value = (Serializable) set.get(key); |
229 | if (value != null) |
230 | return value; |
231 | |
232 | if (dbOnly) |
233 | return null; |
234 | } |
235 | |
236 | return PropertyUtil.getSystemProperty(key); |
237 | } |
238 | |
239 | public static String getPropertyFromSet(boolean dbOnly, Properties set, String key) { |
240 | |
241 | if (set != null) { |
242 | |
243 | String value; |
244 | |
245 | if (!dbOnly) { |
246 | value = Monitor.getMonitor().getJVMProperty(key); |
247 | if (value != null) |
248 | return value; |
249 | } |
250 | |
251 | value = set.getProperty(key); |
252 | if (value != null) |
253 | return value; |
254 | |
255 | if (dbOnly) |
256 | return null; |
257 | } |
258 | |
259 | return PropertyUtil.getSystemProperty(key); |
260 | } |
261 | |
262 | /** |
263 | Get a property only looking in the Persistent Transactional (database) set. |
264 | |
265 | @exception StandardException Standard Cloudscape error handling. |
266 | */ |
267 | public static String getDatabaseProperty(PersistentSet set, String key) |
268 | throws StandardException { |
269 | |
270 | if (set == null) |
271 | return null; |
272 | |
273 | Object obj = set.getProperty(key); |
274 | if (obj == null) { return null; } |
275 | return obj.toString(); |
276 | } |
277 | |
278 | /** |
279 | Find a service wide property with a default. Search order is |
280 | |
281 | The service is the persistent service associated with the |
282 | current context stack. |
283 | |
284 | @return the value of the property or defaultValue if it does not exist. |
285 | |
286 | @exception StandardException Standard Cloudscape error handling. |
287 | */ |
288 | public static String getServiceProperty(PersistentSet set, String key, String defaultValue) |
289 | throws StandardException { |
290 | |
291 | |
292 | String value = |
293 | PropertyUtil.getDatabaseProperty( |
294 | set, Property.DATABASE_PROPERTIES_ONLY); |
295 | |
296 | boolean dbOnly = |
297 | Boolean.valueOf( |
298 | (value != null ? value.trim() : value)).booleanValue(); |
299 | |
300 | if (!dbOnly) { |
301 | value = Monitor.getMonitor().getJVMProperty(key); |
302 | if (value != null) |
303 | return value; |
304 | } |
305 | |
306 | value = PropertyUtil.getDatabaseProperty(set, key); |
307 | if (value != null) |
308 | return value; |
309 | |
310 | if (dbOnly) { |
311 | return defaultValue; |
312 | } |
313 | |
314 | return PropertyUtil.getSystemProperty(key, defaultValue); |
315 | } |
316 | |
317 | |
318 | /** |
319 | Find a service wide property. |
320 | |
321 | The service is the persistent service associated with the |
322 | current context stack. |
323 | |
324 | @return the value of the property or null if it does not exist. |
325 | |
326 | @exception StandardException Standard Cloudscape error handling. |
327 | */ |
328 | public static String getServiceProperty(PersistentSet set, String key) |
329 | throws StandardException { |
330 | return PropertyUtil.getServiceProperty(set, key, (String) null); |
331 | } |
332 | |
333 | /** |
334 | Get a system wide property as a boolean. |
335 | |
336 | @return true of the property is set to 'true, TRUE', false otherwise |
337 | */ |
338 | public static boolean getSystemBoolean(String key) { |
339 | |
340 | String value = PropertyUtil.getSystemProperty(key); |
341 | |
342 | return( |
343 | Boolean.valueOf( |
344 | (value != null ? value.trim() : value)).booleanValue()); |
345 | } |
346 | |
347 | /** |
348 | Get a service wide property as a boolean. |
349 | |
350 | @return true of the property is set to 'true, TRUE', false otherwise |
351 | |
352 | @exception StandardException Standard Cloudscape error handling. |
353 | */ |
354 | public static boolean getServiceBoolean(PersistentSet set, String key, boolean defValue) |
355 | throws StandardException { |
356 | |
357 | String value = PropertyUtil.getServiceProperty(set, key); |
358 | |
359 | return booleanProperty(key, value, defValue); |
360 | } |
361 | |
362 | /**s |
363 | Get a system wide property as a int. |
364 | |
365 | @return value of the property if set subject to min and max, defaultValue if |
366 | it is not set or set to a non-integer value. |
367 | */ |
368 | public static int getSystemInt(String key, int min, int max, int defaultValue) { |
369 | return PropertyUtil.handleInt(PropertyUtil.getSystemProperty(key), min, max, defaultValue); |
370 | } |
371 | |
372 | /** |
373 | Get a service wide property as a int. |
374 | |
375 | @return value of the property if set subject to min and max, defaultValue if |
376 | it is not set or set to a non-integer value. |
377 | |
378 | @exception StandardException Standard Cloudscape error handling. |
379 | |
380 | */ |
381 | public static int getServiceInt(PersistentSet set, String key, int min, int max, int defaultValue) |
382 | throws StandardException { |
383 | //return PropertyUtil.intPropertyValue(key, PropertyUtil.getServiceProperty(set, key), min, max, defaultValue); |
384 | return PropertyUtil.handleInt(PropertyUtil.getServiceProperty(set, key), min, max, defaultValue); |
385 | } |
386 | |
387 | /** |
388 | Get a service wide property as a int. The passed in Properties |
389 | set overrides any system, applcation or per-database properties. |
390 | |
391 | @return value of the property if set subject to min and max, defaultValue if |
392 | it is not set or set to a non-integer value. |
393 | |
394 | @exception StandardException Standard Cloudscape error handling. |
395 | |
396 | */ |
397 | public static int getServiceInt(PersistentSet set, Properties props, String key, int min, int max, int defaultValue) |
398 | throws StandardException { |
399 | |
400 | String value = null; |
401 | |
402 | if (props != null) |
403 | value = props.getProperty(key); |
404 | |
405 | if (value == null) |
406 | value = PropertyUtil.getServiceProperty(set, key); |
407 | |
408 | return PropertyUtil.handleInt(value, min, max, defaultValue); |
409 | } |
410 | |
411 | /** |
412 | Get a system wide property as a int. |
413 | |
414 | @return value of the property if, defaultValue if |
415 | it is not set or set to a non-integer value. |
416 | */ |
417 | public static int getSystemInt(String key, int defaultValue) { |
418 | return PropertyUtil.getSystemInt(key, 0, Integer.MAX_VALUE, defaultValue); |
419 | } |
420 | |
421 | /** |
422 | Parse an string as an int based property value. |
423 | */ |
424 | public static int handleInt(String value, int min, int max, int defaultValue) { |
425 | |
426 | if (value == null) |
427 | return defaultValue; |
428 | |
429 | try { |
430 | int intValue = Integer.parseInt(value); |
431 | if ((intValue >= min) && (intValue <= max)) |
432 | return intValue; |
433 | } |
434 | catch (NumberFormatException nfe) |
435 | { |
436 | // just leave the default. |
437 | } |
438 | return defaultValue; |
439 | } |
440 | |
441 | /** |
442 | Parse and validate and return a boolean property value. If the value is invalid |
443 | raise an exception. |
444 | |
445 | <P> |
446 | The following are valid property values. |
447 | <UL> |
448 | <LI> null - returns defaultValue |
449 | <LI> "true" - returns true (in any case without the quotes) |
450 | <LI> "false" - return true (in any case without the quotes) |
451 | </UL> |
452 | @exception StandardException Oops |
453 | */ |
454 | public static boolean booleanProperty(String p, Serializable v, boolean defaultValue) |
455 | throws StandardException |
456 | { |
457 | if (v==null) |
458 | return defaultValue; |
459 | |
460 | String vS = ((String) v).trim(); |
461 | if (StringUtil.SQLToLowerCase(vS).equals("true")) |
462 | return true; |
463 | if (StringUtil.SQLToLowerCase(vS).equals("false")) |
464 | return false; |
465 | |
466 | throw StandardException.newException(SQLState.PROPERTY_INVALID_VALUE, p,vS); |
467 | } |
468 | |
469 | /** |
470 | Parse, validate and return an integer property value. If the value is invalid |
471 | raise an exception. If the value passed in is null return a default value. |
472 | |
473 | @exception StandardException Oops |
474 | */ |
475 | public static int intPropertyValue(String p, Serializable v, |
476 | int minValue, int maxValue, int defaultValue) |
477 | throws StandardException |
478 | { |
479 | if (v==null) |
480 | return defaultValue; |
481 | |
482 | String vs = ((String)v).trim(); |
483 | try { |
484 | int result = Integer.parseInt(vs); |
485 | if (result < minValue || result > maxValue) |
486 | throw StandardException.newException(SQLState.PROPERTY_INVALID_VALUE, p,vs); |
487 | return result; |
488 | } |
489 | catch (NumberFormatException nfe) { |
490 | throw StandardException.newException(SQLState.PROPERTY_INVALID_VALUE, p,vs); |
491 | } |
492 | } |
493 | |
494 | /** |
495 | Return true iff the key is the name of a database property that is |
496 | stored in services.properties. |
497 | */ |
498 | public static boolean isServiceProperty(String key) |
499 | { |
500 | for (int i = 0; i < PropertyUtil.servicePropertyList.length; i++) |
501 | if (key.equals(PropertyUtil.servicePropertyList[i])) return true; |
502 | return false; |
503 | } |
504 | } |
505 | |