001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.property.PropertyUtil
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.services.property;
023:
024: import org.apache.derby.iapi.reference.Property;
025: import org.apache.derby.iapi.reference.SQLState;
026: import org.apache.derby.iapi.reference.Attribute;
027: import org.apache.derby.iapi.reference.EngineType;
028: import org.apache.derby.iapi.services.monitor.Monitor;
029: import org.apache.derby.iapi.services.monitor.ModuleFactory;
030: import org.apache.derby.iapi.error.StandardException;
031: import org.apache.derby.iapi.util.StringUtil;
032:
033: import java.util.Properties;
034: import java.io.Serializable;
035: import java.util.Dictionary;
036:
037: /**
038: There are 5 property objects within a JBMS system.
039:
040: 1) JVM - JVM set - those in System.getProperties
041: 2) APP - Application set - derby.properties file
042: 3) SRV - Persistent Service set - Those stored in service.properties
043: 4) TRAN - Persistent Transactional set - Those stored via the AccessManager interface
044: 5) BOOT - Set by a boot method (rare)
045:
046: This class has a set of static methods to find a property using a consistent search order
047: from the above set.
048: <BR>
049: getSystem*() methods use the search order.
050: <OL>
051: <LI> JVM
052: <LI> APP
053: </OL>
054: <BR>
055: getService* methods use the search order
056: <OL>
057: <LI> JVM
058: <LI> TRAN
059: <LI> SRV
060: <LI> APP
061: </OL>
062:
063: */
064: public class PropertyUtil {
065:
066: // List of properties that are stored in the service.properties file
067: public static final String[] servicePropertyList = {
068: EngineType.PROPERTY, Property.NO_AUTO_BOOT,
069: Property.STORAGE_TEMP_DIRECTORY, Attribute.CRYPTO_PROVIDER,
070: Attribute.CRYPTO_ALGORITHM, Attribute.RESTORE_FROM,
071: Attribute.LOG_DEVICE, Property.LOG_ARCHIVE_MODE };
072:
073: /**
074: Property is set in JVM set
075: */
076: public static final int SET_IN_JVM = 0;
077: /**
078: Property is set in DATABASE set
079: */
080: public static final int SET_IN_DATABASE = 1;
081: /**
082: Property is set in APPLICATION (derby.properties) set
083: */
084: public static final int SET_IN_APPLICATION = 2;
085:
086: /**
087: Property is not set.
088: */
089: public static final int NOT_SET = -1;
090:
091: static int whereSet(String key, Dictionary set) {
092:
093: boolean dbOnly = isDBOnly(set);
094:
095: if (!dbOnly) {
096: if (Monitor.getMonitor().getJVMProperty(key) != null) {
097: return SET_IN_JVM;
098: }
099: }
100:
101: if ((set != null) && (set.get(key) != null))
102: return SET_IN_DATABASE;
103:
104: if (!dbOnly) {
105: if (PropertyUtil.getSystemProperty(key) != null)
106: return SET_IN_APPLICATION;
107: }
108:
109: return NOT_SET;
110: }
111:
112: public static boolean isDBOnly(Dictionary set) {
113:
114: if (set == null)
115: return false;
116:
117: String value = (String) set
118: .get(Property.DATABASE_PROPERTIES_ONLY);
119:
120: boolean dbOnly = Boolean.valueOf(
121: (value != null ? value.trim() : value)).booleanValue();
122:
123: return dbOnly;
124: }
125:
126: public static boolean isDBOnly(Properties set) {
127:
128: if (set == null)
129: return false;
130:
131: String value = set
132: .getProperty(Property.DATABASE_PROPERTIES_ONLY);
133:
134: boolean dbOnly = Boolean.valueOf(
135: (value != null ? value.trim() : value)).booleanValue();
136:
137: return dbOnly;
138: }
139:
140: /**
141: Find a system wide property.
142:
143: @return the value of the property or null if it does not exist.
144: @see #getSystemProperty(String,String)
145: */
146: public static String getSystemProperty(String key) {
147: return PropertyUtil.getSystemProperty(key, (String) null);
148: }
149:
150: /**
151: Find a system wide property with a default. Search order is
152:
153: <OL>
154: <LI> JVM property
155: <LI> derby.properties
156: </OL>
157:
158: <P>
159: This method can be used by a system that is not running Cloudscape,
160: just to maintain the same lookup logic and security manager concerns
161: for finding derby.properties and reading system properties.
162:
163: @return the value of the property or defaultValue if it does not exist.
164: */
165: public static String getSystemProperty(String key,
166: String defaultValue) {
167:
168: ModuleFactory monitor = Monitor.getMonitorLite();
169:
170: String value = monitor.getJVMProperty(key);
171:
172: if (value == null) {
173:
174: Properties applicationProperties = monitor
175: .getApplicationProperties();
176:
177: if (applicationProperties != null)
178: value = applicationProperties.getProperty(key);
179: }
180: return value == null ? defaultValue : value;
181: }
182:
183: /**
184: Get a property from the passed in set. The passed in set is
185: either:
186:
187: <UL>
188: <LI> The properties object passed into ModuleControl.boot()
189: after the database has been booted. This set will be a DoubleProperties
190: object with the per-database transaction set as the read set
191: and the service.properties as the write set.
192: <LI>
193: The Dictionary set returned/passed in by a method of BasicService.Properties.
194: </UL>
195: <BR>
196: This method uses the same search order as the getService() calls.
197:
198: */
199: public static String getPropertyFromSet(Properties set, String key) {
200:
201: boolean dbOnly = set != null ? isDBOnly(set) : false;
202:
203: return PropertyUtil.getPropertyFromSet(dbOnly, set, key);
204: }
205:
206: public static Serializable getPropertyFromSet(Dictionary set,
207: String key) {
208:
209: boolean dbOnly = set != null ? isDBOnly(set) : false;
210:
211: return PropertyUtil.getPropertyFromSet(dbOnly, set, key);
212: }
213:
214: public static Serializable getPropertyFromSet(boolean dbOnly,
215: Dictionary set, String key) {
216:
217: if (set != null) {
218:
219: Serializable value;
220:
221: if (!dbOnly) {
222: value = Monitor.getMonitor().getJVMProperty(key);
223: if (value != null)
224: return value;
225: }
226:
227: value = (Serializable) set.get(key);
228: if (value != null)
229: return value;
230:
231: if (dbOnly)
232: return null;
233: }
234:
235: return PropertyUtil.getSystemProperty(key);
236: }
237:
238: public static String getPropertyFromSet(boolean dbOnly,
239: 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,
268: String key) throws StandardException {
269:
270: if (set == null)
271: return null;
272:
273: Object obj = set.getProperty(key);
274: if (obj == null) {
275: return null;
276: }
277: return obj.toString();
278: }
279:
280: /**
281: Find a service wide property with a default. Search order is
282:
283: The service is the persistent service associated with the
284: current context stack.
285:
286: @return the value of the property or defaultValue if it does not exist.
287:
288: @exception StandardException Standard Cloudscape error handling.
289: */
290: public static String getServiceProperty(PersistentSet set,
291: String key, String defaultValue) throws StandardException {
292:
293: String value = PropertyUtil.getDatabaseProperty(set,
294: Property.DATABASE_PROPERTIES_ONLY);
295:
296: boolean dbOnly = Boolean.valueOf(
297: (value != null ? value.trim() : value)).booleanValue();
298:
299: if (!dbOnly) {
300: value = Monitor.getMonitor().getJVMProperty(key);
301: if (value != null)
302: return value;
303: }
304:
305: value = PropertyUtil.getDatabaseProperty(set, key);
306: if (value != null)
307: return value;
308:
309: if (dbOnly) {
310: return defaultValue;
311: }
312:
313: return PropertyUtil.getSystemProperty(key, defaultValue);
314: }
315:
316: /**
317: Find a service wide property.
318:
319: The service is the persistent service associated with the
320: current context stack.
321:
322: @return the value of the property or null if it does not exist.
323:
324: @exception StandardException Standard Cloudscape error handling.
325: */
326: public static String getServiceProperty(PersistentSet set,
327: String key) throws StandardException {
328: return PropertyUtil.getServiceProperty(set, key, (String) null);
329: }
330:
331: /**
332: Get a system wide property as a boolean.
333:
334: @return true of the property is set to 'true, TRUE', false otherwise
335: */
336: public static boolean getSystemBoolean(String key) {
337:
338: String value = PropertyUtil.getSystemProperty(key);
339:
340: return (Boolean.valueOf((value != null ? value.trim() : value))
341: .booleanValue());
342: }
343:
344: /**
345: Get a service wide property as a boolean.
346:
347: @return true of the property is set to 'true, TRUE', false otherwise
348:
349: @exception StandardException Standard Cloudscape error handling.
350: */
351: public static boolean getServiceBoolean(PersistentSet set,
352: String key, boolean defValue) throws StandardException {
353:
354: String value = PropertyUtil.getServiceProperty(set, key);
355:
356: return booleanProperty(key, value, defValue);
357: }
358:
359: /**s
360: Get a system wide property as a int.
361:
362: @return value of the property if set subject to min and max, defaultValue if
363: it is not set or set to a non-integer value.
364: */
365: public static int getSystemInt(String key, int min, int max,
366: int defaultValue) {
367: return PropertyUtil.handleInt(PropertyUtil
368: .getSystemProperty(key), min, max, defaultValue);
369: }
370:
371: /**
372: Get a service wide property as a int.
373:
374: @return value of the property if set subject to min and max, defaultValue if
375: it is not set or set to a non-integer value.
376:
377: @exception StandardException Standard Cloudscape error handling.
378:
379: */
380: public static int getServiceInt(PersistentSet set, String key,
381: 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(
385: set, key), min, max, defaultValue);
386: }
387:
388: /**
389: Get a service wide property as a int. The passed in Properties
390: set overrides any system, applcation or per-database properties.
391:
392: @return value of the property if set subject to min and max, defaultValue if
393: it is not set or set to a non-integer value.
394:
395: @exception StandardException Standard Cloudscape error handling.
396:
397: */
398: public static int getServiceInt(PersistentSet set,
399: Properties props, String key, int min, int max,
400: int defaultValue) throws StandardException {
401:
402: String value = null;
403:
404: if (props != null)
405: value = props.getProperty(key);
406:
407: if (value == null)
408: value = PropertyUtil.getServiceProperty(set, key);
409:
410: return PropertyUtil.handleInt(value, min, max, defaultValue);
411: }
412:
413: /**
414: Get a system wide property as a int.
415:
416: @return value of the property if, defaultValue if
417: it is not set or set to a non-integer value.
418: */
419: public static int getSystemInt(String key, int defaultValue) {
420: return PropertyUtil.getSystemInt(key, 0, Integer.MAX_VALUE,
421: defaultValue);
422: }
423:
424: /**
425: Parse an string as an int based property value.
426: */
427: public static int handleInt(String value, int min, int max,
428: int defaultValue) {
429:
430: if (value == null)
431: return defaultValue;
432:
433: try {
434: int intValue = Integer.parseInt(value);
435: if ((intValue >= min) && (intValue <= max))
436: return intValue;
437: } catch (NumberFormatException nfe) {
438: // just leave the default.
439: }
440: return defaultValue;
441: }
442:
443: /**
444: Parse and validate and return a boolean property value. If the value is invalid
445: raise an exception.
446:
447: <P>
448: The following are valid property values.
449: <UL>
450: <LI> null - returns defaultValue
451: <LI> "true" - returns true (in any case without the quotes)
452: <LI> "false" - return true (in any case without the quotes)
453: </UL>
454: @exception StandardException Oops
455: */
456: public static boolean booleanProperty(String p, Serializable v,
457: boolean defaultValue) throws StandardException {
458: if (v == null)
459: return defaultValue;
460:
461: String vS = ((String) v).trim();
462: if (StringUtil.SQLToLowerCase(vS).equals("true"))
463: return true;
464: if (StringUtil.SQLToLowerCase(vS).equals("false"))
465: return false;
466:
467: throw StandardException.newException(
468: SQLState.PROPERTY_INVALID_VALUE, p, vS);
469: }
470:
471: /**
472: Parse, validate and return an integer property value. If the value is invalid
473: raise an exception. If the value passed in is null return a default value.
474:
475: @exception StandardException Oops
476: */
477: public static int intPropertyValue(String p, Serializable v,
478: int minValue, int maxValue, int defaultValue)
479: throws StandardException {
480: if (v == null)
481: return defaultValue;
482:
483: String vs = ((String) v).trim();
484: try {
485: int result = Integer.parseInt(vs);
486: if (result < minValue || result > maxValue)
487: throw StandardException.newException(
488: SQLState.PROPERTY_INVALID_VALUE, p, vs);
489: return result;
490: } catch (NumberFormatException nfe) {
491: throw StandardException.newException(
492: SQLState.PROPERTY_INVALID_VALUE, p, vs);
493: }
494: }
495:
496: /**
497: Return true iff the key is the name of a database property that is
498: stored in services.properties.
499: */
500: public static boolean isServiceProperty(String key) {
501: for (int i = 0; i < PropertyUtil.servicePropertyList.length; i++)
502: if (key.equals(PropertyUtil.servicePropertyList[i]))
503: return true;
504: return false;
505: }
506: }
|