001: /*
002: ** Copyright (c) 1997 by Tim Endres
003: **
004: ** This program is free software.
005: **
006: ** You may redistribute it and/or modify it under the terms of the GNU
007: ** General Public License as published by the Free Software Foundation.
008: ** Version 2 of the license should be included with this distribution in
009: ** the file LICENSE, as well as License.html. If the license is not
010: ** included with this distribution, you may find a copy at the FSF web
011: ** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
012: ** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
013: **
014: ** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
015: ** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
016: ** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
017: ** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
018: ** REDISTRIBUTION OF THIS SOFTWARE.
019: **
020: */
021:
022: package com.ice.util;
023:
024: import java.io.*;
025: import java.awt.*;
026: import java.util.*;
027: import java.net.*;
028:
029: /**
030: * The UserProperties class.
031: *
032: * @version $Revision: 1.1 $
033: * @author Tim Endres,
034: * <a href="mailto:time@ice.com">time@ice.com</a>.
035: */
036:
037: public abstract class UserProperties {
038: private static final String RCS_ID = "$Id: UserProperties.java,v 1.1 2002/03/14 09:55:00 deniger Exp $";
039: private static final String RCS_NAME = "$Name: $";
040: private static final String RCS_REV = "$Revision: 1.1 $";
041:
042: private static final String PREFIX_PROPERTY = "propertyPrefix";
043: private static final String DEFAULTS_RSRC_NAME = ".com.ice.global.defaultsResource.";
044:
045: private static final String GLOBAL_RSRCLIST_NAME = ".com.ice.global.propertyResourceList";
046: private static final String GLOBAL_RSRC_PREFIX = ".com.ice.global.propertyResource.";
047:
048: private static final String APP_RSRCLIST_NAME = ".com.ice.local.propertyResourceList";
049: private static final String APP_RSRC_PREFIX = ".com.ice.local.propertyResource.";
050:
051: private static final String LOCAL_PROPERTY = "global.localPropertyFile";
052: private static final String LOCAL_DEFAULT = "properties.txt";
053:
054: private static boolean debug;
055: private static boolean verbose;
056:
057: private static String osname;
058: private static String userName;
059: private static String userHome;
060:
061: private static String prefix;
062:
063: private static String osSuffix;
064: private static String userSuffix;
065:
066: private static String defaultsResource;
067: private static String localPropertyFile;
068:
069: static {
070: UserProperties.debug = false;
071: UserProperties.verbose = false;
072:
073: UserProperties.prefix = null;
074:
075: UserProperties.defaultsResource = null;
076: UserProperties.localPropertyFile = null;
077:
078: UserProperties.osname = System.getProperty("os.name");
079: UserProperties.userName = System.getProperty("user.name");
080: UserProperties.userHome = System.getProperty("user.home");
081:
082: UserProperties.osSuffix = UserProperties.osname.replace(' ',
083: '_');
084: UserProperties.userSuffix = UserProperties.userName.replace(
085: ' ', '_');
086: }
087:
088: static public String getOSName() {
089: return UserProperties.osname;
090: }
091:
092: static public String getUserHome() {
093: return UserProperties.userHome;
094: }
095:
096: static public String getUserName() {
097: return UserProperties.userName;
098: }
099:
100: static public void setDebug(boolean debug) {
101: UserProperties.debug = debug;
102: }
103:
104: static public void setVerbose(boolean verbose) {
105: UserProperties.verbose = verbose;
106: }
107:
108: static public void setLocalPropertyFile(String fileName) {
109: UserProperties.localPropertyFile = fileName;
110: }
111:
112: static public void setDefaultsResource(String rsrcName) {
113: UserProperties.defaultsResource = rsrcName;
114: }
115:
116: static public void setOSSuffix(String suffix) {
117: UserProperties.osSuffix = suffix;
118: }
119:
120: static public void setUserSuffix(String suffix) {
121: UserProperties.userSuffix = suffix;
122: }
123:
124: static public void setPropertyPrefix(String prefix) {
125: if (prefix.endsWith("."))
126: UserProperties.prefix = prefix;
127: else
128: UserProperties.prefix = prefix + ".";
129: }
130:
131: static public String getPropertyPrefix() {
132: return UserProperties.prefix;
133: }
134:
135: static public Font getFont(String name, Font defaultFont) {
136: return Font.getFont(UserProperties.fullPropertyName(name),
137: defaultFont);
138: }
139:
140: static public Color getColor(String name, Color defaultColor) {
141: return Color.getColor(UserProperties.fullPropertyName(name),
142: defaultColor);
143: }
144:
145: static public String fullPropertyName(String name) {
146: return UserProperties.prefix + name;
147: }
148:
149: /**
150: * Retrieve a system string property.
151: * Returns a provided default value if the property
152: * is not defined.
153: *
154: * @param name The name of the property to retrieve.
155: * @param defval A default string value.
156: * @return The string value of the named property.
157: */
158:
159: static private String getOverridableProperty(String name,
160: String defval) {
161: String value = null;
162: String overName = null;
163: String fullName = null;
164:
165: if (name.startsWith("."))
166: fullName = name.substring(1);
167: else
168: fullName = UserProperties.fullPropertyName(name);
169:
170: if (fullName.endsWith(".")) {
171: fullName = fullName.substring(0, fullName.length());
172: value = System.getProperty(fullName, defval);
173: if (UserProperties.debug)
174: System.err
175: .println("UserProperties.getOverridableProperty: "
176: + fullName + " = '" + value + "'");
177: return value;
178: }
179:
180: if (UserProperties.osSuffix != null
181: && UserProperties.userSuffix != null) {
182: overName = fullName + "." + UserProperties.osSuffix + "."
183: + UserProperties.userSuffix;
184: value = System.getProperty(overName, null);
185: if (UserProperties.debug)
186: System.err
187: .println("UserProperties.getOverridableProperty: "
188: + overName + " = '" + value + "'");
189: if (value != null)
190: return value;
191: }
192:
193: if (UserProperties.userSuffix != null) {
194: overName = fullName + "." + UserProperties.userSuffix;
195: value = System.getProperty(overName, null);
196: if (UserProperties.debug)
197: System.err
198: .println("UserProperties.getOverridableProperty: "
199: + overName + " = '" + value + "'");
200: if (value != null)
201: return value;
202: }
203:
204: if (UserProperties.osSuffix != null) {
205: overName = fullName + "." + UserProperties.osSuffix;
206: value = System.getProperty(overName, null);
207: if (UserProperties.debug)
208: System.err
209: .println("UserProperties.getOverridableProperty: "
210: + overName + " = '" + value + "'");
211: if (value != null)
212: return value;
213: }
214:
215: if (value == null) {
216: value = System.getProperty(fullName, null);
217: if (UserProperties.debug)
218: System.err
219: .println("UserProperties.getOverridableProperty: "
220: + fullName + " = '" + value + "'");
221: }
222:
223: if (value == null) {
224: value = defval;
225: if (UserProperties.debug)
226: System.err
227: .println("UserProperties.getOverridableProperty: "
228: + name
229: + " defaulted to '"
230: + value
231: + "'");
232: }
233:
234: return value;
235: }
236:
237: /**
238: * Retrieve a system string property.
239: * Returns a provided default value if the property
240: * is not defined.
241: *
242: * @param name The name of the property to retrieve.
243: * @param defval A default string value.
244: * @return The string value of the named property.
245: */
246:
247: static public String getProperty(String name, String defval) {
248: String result = UserProperties.getOverridableProperty(name,
249: defval);
250: return result;
251: }
252:
253: /**
254: * Retrieve a system integer property.
255: * Returns a provided default value if the property
256: * is not defined.
257: *
258: * @param name The name of the property to retrieve.
259: * @param defval A default integer value.
260: * @return The integer value of the named property.
261: */
262:
263: static public int getProperty(String name, int defval) {
264: int result = defval;
265:
266: String val = UserProperties.getProperty(name, null);
267:
268: if (val != null) {
269: try {
270: result = Integer.parseInt(val);
271: } catch (NumberFormatException ex) {
272: result = defval;
273: }
274: }
275:
276: return result;
277: }
278:
279: /**
280: * Retrieve a system double property.
281: * Returns a provided default value if the property
282: * is not defined.
283: *
284: * @param name The name of the property to retrieve.
285: * @param defval A default double value.
286: * @return The double value of the named property.
287: */
288:
289: static public double getProperty(String name, double defval) {
290: double result = defval;
291:
292: String val = UserProperties.getProperty(name, null);
293:
294: if (val != null) {
295: try {
296: result = Double.valueOf(val).doubleValue();
297: } catch (NumberFormatException ex) {
298: result = defval;
299: }
300: }
301:
302: return result;
303: }
304:
305: /**
306: * Retrieve a system boolean property.
307: * Returns a provided default value if the property
308: * is not defined.
309: *
310: * @param name The name of the property to retrieve.
311: * @param defval A default boolean value.
312: * @return The boolean value of the named property.
313: */
314:
315: static public boolean getProperty(String name, boolean defval) {
316: boolean result = defval;
317:
318: String val = UserProperties.getProperty(name, null);
319:
320: if (val != null) {
321: if (val.equalsIgnoreCase("TRUE"))
322: result = true;
323: else if (val.equalsIgnoreCase("FALSE"))
324: result = false;
325: }
326:
327: return result;
328: }
329:
330: /**
331: * Establishes critical default properties.
332: *
333: * @param props The system properties to add properties into.
334: */
335:
336: static public void defaultProperties(Properties props) {
337: props.put("com.ice.util.UserProperties.revision",
338: "$Revision: 1.1 $");
339: props.put("copyright", "Copyright (c) by Tim Endres");
340:
341: //
342: // Define the following to create a global
343: // enterprise-wide defaults resource...
344: // e.g.
345: //
346: // props.put
347: // ( UserProperties.DEFAULTS_RSRC_NAME,
348: // "http://www.ice.com/properties/defaults.txt" );
349: //
350: }
351:
352: static public void
353: addDefaultProperties( Properties props, Properties defaultProps )
354: {
355: Enumeration enum = defaultProps.keys();
356:
357: for ( ; enum.hasMoreElements() ; )
358: {
359: String key = null;
360:
361: try { key = (String)enum.nextElement(); }
362: catch ( NoSuchElementException ex )
363: { key = null; }
364:
365: if ( key != null )
366: {
367: String value = (String) defaultProps.get( key );
368:
369: if ( value == null )
370: {
371: System.err.println
372: ( "UserProperties.addDefaultProperties: "
373: + "key '" + key + "' has null value!" );
374: }
375: else
376: {
377: props.put( key, value );
378: }
379: }
380: }
381: }
382:
383: /**
384: * Loads a properties stream into the System properties table.
385: *
386: * @param path The properties data's input stream.
387: * @param props The system properties to add properties into.
388: */
389:
390: static private boolean loadPropertiesStream(InputStream in,
391: Properties props) throws IOException {
392: props.load(in);
393: return true;
394: }
395:
396: /**
397: * Loads a named properties file into the System properties table.
398: *
399: * @param path The properties file's pathname.
400: * @param props The system properties to add properties into.
401: */
402:
403: static private boolean loadPropertiesFile(String path,
404: Properties props) {
405: FileInputStream in;
406: boolean result = true;
407:
408: try {
409: in = new FileInputStream(path);
410: } catch (IOException ex) {
411: System.err.println("ERROR opening property file '" + path
412: + "' - " + ex.getMessage());
413: result = false;
414: in = null;
415: }
416:
417: if (result) {
418: try {
419: UserProperties.loadPropertiesStream(in, props);
420: } catch (IOException ex) {
421: System.err.println("ERROR loading property file '"
422: + path + "' - " + ex.getMessage());
423: result = false;
424: }
425: }
426:
427: if (in != null) {
428: try {
429: in.close();
430: } catch (IOException ex) {
431: System.err.println("ERROR closing property file '"
432: + path + "' - " + ex.getMessage());
433: result = false;
434: }
435: }
436:
437: if (result)
438: System.err.println("Loaded property file '" + path + "'.");
439:
440: return result;
441: }
442:
443: /**
444: * Loads a named resource into the System properties table.
445: *
446: * @param path The properties resource's name.
447: * @param props The system properties to add properties into.
448: */
449:
450: static private InputStream openNamedResource(String name)
451: throws java.io.IOException {
452: InputStream in = null;
453: boolean result = false;
454: boolean httpURL = true;
455: URL propsURL = null;
456:
457: //
458: // UNDONE REVIEW
459: // I really should be getting the URL's protocol, when it
460: // is a "full" URL, and checking for the different possible
461: // error returns for http, ftp, et.al.
462: //
463: try {
464: propsURL = new URL(name);
465: } catch (MalformedURLException ex) {
466: httpURL = false;
467: propsURL = null;
468: }
469:
470: if (propsURL == null) {
471: propsURL = UserProperties.class.getResource(name);
472: }
473:
474: if (propsURL != null) {
475: URLConnection urlConn = propsURL.openConnection();
476:
477: if (httpURL) {
478: String hdrVal = urlConn.getHeaderField(0);
479: if (hdrVal != null) {
480: String code = HTTPUtilities.getResultCode(hdrVal);
481:
482: if (code != null) {
483: if (!code.equals("200")) {
484: throw new java.io.IOException(
485: "status code = " + code);
486: }
487: }
488: }
489: }
490:
491: in = urlConn.getInputStream();
492: }
493:
494: return in;
495: }
496:
497: static private boolean loadPropertiesResource(String name,
498: Properties props) {
499: InputStream in;
500: boolean result = false;
501:
502: try {
503: in = UserProperties.openNamedResource(name);
504: if (in != null) {
505: UserProperties.loadPropertiesStream(in, props);
506: in.close();
507: result = true;
508: }
509: } catch (java.io.IOException ex) {
510: System.err.println("ERROR loading properties resource '"
511: + name + "' - " + ex.getMessage());
512: }
513:
514: return result;
515: }
516:
517: private static void loadPropertyResourceList(String listPropName,
518: String rsrcPrefix, Properties props) {
519: String rsrcListStr = UserProperties.getProperty(listPropName,
520: null);
521:
522: if (rsrcListStr != null) {
523: String[] rsrcList = StringUtilities.splitString(
524: rsrcListStr, ":");
525:
526: for (int rIdx = 0; rsrcList != null
527: && rIdx < rsrcList.length; ++rIdx) {
528: String rsrcTag = rsrcPrefix + rsrcList[rIdx];
529:
530: String rsrcName = UserProperties.getProperty(rsrcTag,
531: null);
532:
533: if (rsrcName != null) {
534: boolean result = UserProperties
535: .loadPropertiesResource(rsrcName, props);
536:
537: if (!result) {
538: System.err
539: .println("ERROR loading property resource '"
540: + rsrcName + "'");
541: }
542: }
543: }
544: }
545: }
546:
547: // UNDONE
548: // This routine need to use JNDI (?) to get a 'global' property
549: // file name (typically on a network mounted volume) to read,
550: // which should in turn set the name of the local property file.
551: // JNDI should also set some 'critical' properties, such as
552: // the important OTA hostnames, service ports, etc.
553:
554: // REVIEW
555: // UNDONE
556: // This routine should have a 'filter' that filters out all
557: // global properties that do not start with prefix?
558:
559: /**
560: * Load all related properties for this application.
561: * This class method will look for a global properties
562: * file, loading it if found, then looks for a local
563: * properties file and loads that.
564: */
565:
566: static public void loadProperties(String packageName,
567: Properties appProps) {
568: boolean result;
569: File propFile;
570: String propPath;
571: String propName;
572: String rsrcName;
573:
574: if (UserProperties.debug) {
575: UserProperties.printContext(System.err);
576: }
577:
578: Properties sysProps = System.getProperties();
579:
580: if (sysProps == null)
581: return;
582:
583: UserProperties.defaultProperties(sysProps);
584:
585: //
586: // ---- PROCESS THE DEFAULT PROPERTIES RESOURCE
587: //
588: rsrcName = UserProperties.defaultsResource;
589: if (rsrcName == null) {
590: rsrcName = UserProperties.getProperty(
591: UserProperties.DEFAULTS_RSRC_NAME, null);
592: }
593:
594: if (rsrcName != null) {
595: result = UserProperties.loadPropertiesResource(rsrcName,
596: sysProps);
597:
598: System.err.println("Loaded " + (result ? "the " : "no ")
599: + "default properties.");
600: }
601:
602: //
603: // ---- PROCESS THE APPLICATION DEFAULT PROPERTIES
604: //
605: if (appProps != null) {
606: UserProperties.addDefaultProperties(sysProps, appProps);
607: }
608:
609: //
610: // ---- PROCESS THE PREFIX PROPERTY
611: //
612: String newPrefix = UserProperties.prefix;
613: if (newPrefix == null) {
614: UserProperties.getProperty(packageName + "."
615: + UserProperties.PREFIX_PROPERTY, null);
616:
617: if (newPrefix != null) {
618: UserProperties.setPropertyPrefix(newPrefix);
619: if (UserProperties.verbose)
620: System.err.println("Property prefix set to '"
621: + newPrefix + "'");
622: }
623: }
624:
625: //
626: // ---- PROCESS THE GLOBAL PROPERTIES RESOURCES
627: //
628: UserProperties.loadPropertyResourceList(
629: UserProperties.GLOBAL_RSRCLIST_NAME,
630: UserProperties.GLOBAL_RSRC_PREFIX, sysProps);
631:
632: //
633: // ---- PROCESS THE LOCAL PROPERTIES FILE
634: //
635: propPath = UserProperties.localPropertyFile;
636: if (propPath == null) {
637: propPath = UserProperties.getProperty(
638: UserProperties.LOCAL_PROPERTY,
639: UserProperties.LOCAL_DEFAULT);
640: }
641:
642: if (propPath != null) {
643: propFile = new File(propPath);
644: if (propFile.exists()) {
645: result = UserProperties.loadPropertiesFile(propPath,
646: sysProps);
647:
648: if (!result) {
649: System.err
650: .println("ERROR loading local property file '"
651: + propPath + "'");
652: }
653: }
654: }
655:
656: //
657: // ---- PROCESS THE GLOBAL PROPERTIES RESOURCES
658: //
659: UserProperties.loadPropertyResourceList(
660: UserProperties.APP_RSRCLIST_NAME,
661: UserProperties.APP_RSRC_PREFIX, sysProps);
662: }
663:
664: public static void printContext(PrintStream out) {
665: out.println("os.name = '" + UserProperties.osname + "'");
666: out.println("user.name = '" + UserProperties.userName + "'");
667: out.println("user.home = '" + UserProperties.userHome + "'");
668:
669: out.println("");
670:
671: out.println("prefix = '" + UserProperties.prefix + "'");
672: out.println("osSuffix = '" + UserProperties.osSuffix + "'");
673: out.println("userSuffix = '" + UserProperties.userSuffix + "'");
674:
675: out.println("");
676: }
677:
678: public static void printUsage(PrintStream out) {
679: out.println("Properties options:");
680:
681: out.println(" -propDebug -- "
682: + "turns on debugging of property loading");
683: out.println(" -propVerbose -- "
684: + "turns on verbose messages during loading");
685:
686: out.println(" -propDefaults rsrcName -- "
687: + "sets default properties resource name");
688: out.println(" -propFile path -- "
689: + "sets application property file path");
690:
691: out.println(" -propOS suffix -- "
692: + "sets the os suffix");
693: out.println(" -propUser suffix -- "
694: + "sets the user suffix");
695: out.println(" -propPrefix prefix -- "
696: + "sets application property prefix");
697: }
698:
699: static public String[] processOptions(String[] args) {
700: Vector newArgs = new Vector(args.length);
701:
702: for (int iArg = 0; iArg < args.length; ++iArg) {
703: if (args[iArg].equals("-propPrefix")
704: && (iArg + 1) < args.length) {
705: UserProperties.setPropertyPrefix(args[++iArg]);
706: } else if (args[iArg].equals("-propFile")
707: && (iArg + 1) < args.length) {
708: UserProperties.setLocalPropertyFile(args[++iArg]);
709: } else if (args[iArg].equals("-propDefaults")
710: && (iArg + 1) < args.length) {
711: UserProperties.setDefaultsResource(args[++iArg]);
712: } else if (args[iArg].equals("-propDebug")) {
713: UserProperties.setDebug(true);
714: } else if (args[iArg].equals("-propVerbose")) {
715: UserProperties.setVerbose(true);
716: } else if (args[iArg].equals("-propOS")
717: && (iArg + 1) < args.length) {
718: UserProperties.setOSSuffix(args[++iArg]);
719: } else if (args[iArg].equals("-propUser")
720: && (iArg + 1) < args.length) {
721: UserProperties.setUserSuffix(args[++iArg]);
722: } else {
723: newArgs.addElement(args[iArg]);
724: }
725: }
726:
727: String[] result = new String[newArgs.size()];
728: for (int i = 0; i < newArgs.size(); ++i)
729: result[i] = (String) newArgs.elementAt(i);
730:
731: return result;
732: }
733:
734: }
|