001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer(s): ____________________________________.
022: * Contributor(s): Adriana Danes
023: *
024: * --------------------------------------------------------------------------
025: * $Id: JProp.java 8701 2006-06-29 12:11:26Z durieuxp $
026: * --------------------------------------------------------------------------
027: */package org.objectweb.jonas.common;
028:
029: import java.io.BufferedWriter;
030: import java.io.File;
031: import java.io.FileInputStream;
032: import java.io.FileOutputStream;
033: import java.io.FileNotFoundException;
034: import java.io.FileWriter;
035: import java.io.IOException;
036: import java.util.Enumeration;
037: import java.util.Hashtable;
038: import java.util.Properties;
039: import java.util.StringTokenizer;
040: import javax.naming.Context;
041:
042: /**
043: * This class manages configuration properties for a JOnAS Server.
044: * It adopts the singleton design-pattern. Configuration parameters
045: * are read from .properties file (jonas.properties or resource.properties).
046: * In order to support dynamically created resources, JProp also allows for
047: * a .properties file generation using a java.lang.Properties object content
048: * @author jonas-team
049: * @author Adriana Danes
050: * @author Florent Benoit
051: * <ul>
052: * <li>
053: * ../03/2003 Adriana Danes
054: * <ol>
055: * <li>Manage unique instances for resource.properties
056: * <li>Replace 'config' with 'conf'
057: * <li>Change initial configuration policy : read properties file in a sole location : JONAS_BASE/CONFIG_DIR/
058: * <li>Replace method name <code>getFilesEnv</code> to <code>getConfigFileEnv</code>
059: * </ol>
060: * <li>
061: * 05/05/2003 Adriana Danes. Support JProp instance creation for dynamically created resources.
062: * </ul>
063: * 05/2003 Florent Benoit. Add support of xml files and checkstyle
064: */
065: public class JProp {
066:
067: public static final String JONAS_VERSIONS = "VERSIONS";
068: /**
069: * Prefix for jonas.properties file
070: */
071: public static final String JONASPREFIX = "jonas";
072:
073: /**
074: * Domain name
075: */
076: public static final String DOMAIN_NAME = "domain.name";
077:
078: /**
079: * JOnAS server name
080: */
081: public static final String JONAS_NAME = "jonas.name";
082:
083: /**
084: * Default server name
085: */
086: public static final String JONAS_DEF_NAME = "jonas";
087:
088: /**
089: * -Djonas.base property
090: */
091: public static final String JONAS_BASE = "jonas.base";
092:
093: /**
094: * configuration directory name (changed from 'config' to 'conf' !!)
095: */
096: private static final String CONFIG_DIR = "conf";
097:
098: /**
099: * System properties
100: */
101: private static Properties systEnv = System.getProperties();
102:
103: /**
104: * JONAS_BASE
105: */
106: private static String jonasBase = systEnv.getProperty(JONAS_BASE);
107:
108: /**
109: * JONAS_ROOT
110: */
111: private static String installRoot = systEnv
112: .getProperty("install.root");
113:
114: /**
115: * Separator of file
116: */
117: private static String fileSeparator = systEnv
118: .getProperty("file.separator");
119:
120: /**
121: * User home directory
122: */
123: private static String homeUser = systEnv.getProperty("user.home");
124:
125: /**
126: * Content of the file (xml)
127: */
128: private String configFileXml = null;
129:
130: /**
131: * Content of a text file (may be a .properties file
132: */
133: private String versionFileContent = null;
134:
135: /**
136: * Properties of the config file
137: */
138: private Properties configFileEnv = new Properties();
139:
140: /**
141: * System properties + properties of the file
142: */
143: private Properties allEnv = null;
144:
145: /**
146: * Name of the property file
147: */
148: private String propFileName = null;
149:
150: /**
151: * The JProp singleton for jonas.properties file
152: */
153: private static JProp unique = null;
154:
155: /**
156: * The multiple JProp objects for the resources configuration files (resource.properties)
157: * the keys are the configuration file names and the values, the JProp objects
158: */
159: private static Hashtable multiple = new Hashtable();
160:
161: /**
162: * Private constructor which reads a resource.properties file.
163: * @param fileName the file name to read (the resource name)
164: */
165: private JProp(String fileName) {
166: readFile(fileName);
167: }
168:
169: /**
170: * Private constructor which reads the JONAS properties file (jonas.properties).
171: * @throws Exception if it fails
172: */
173: private JProp() {
174: readFile(JONASPREFIX);
175: }
176:
177: /**
178: * private constructor which writes properties in the provided file.
179: * @param fileName the file name in which configuration properties are written
180: * @param props configuration properties used to initialize the resource
181: * @throws Exception if it fails
182: */
183: private JProp(String fileName, Properties props) {
184: writePropsToFile(fileName, props);
185: }
186:
187: /**
188: * private constructor which writes text in the provided file.
189: * @param fileName the file name in which configuration is written
190: * @param txt xml configuration for this resource
191: * @throws Exception if it fails
192: */
193: private JProp(String fileName, String txt) {
194: writeXmlToFile(fileName, txt);
195: }
196:
197: /**
198: * Get the unique instance corresponding to the JOnAS server.
199: * Create it at first call.
200: * @return unique instance corresponding to the JOnAS server.
201: * @throws Exception if no JProp can be built
202: */
203: public static JProp getInstance() {
204: if (unique == null) {
205: unique = new JProp();
206: }
207: return unique;
208: }
209:
210: /**
211: * Get one of the multiple instances corresponding to a given resource.
212: * Create it at first call with a given configuration file name
213: * @param fileName the name of the configuration file which is given by the resource name
214: * @return one of the multiple instances corresponding to a given resource.
215: * @throws Exception if no JProp can be built
216: */
217: public static JProp getInstance(String fileName) {
218: if (!multiple.containsKey(fileName)) {
219: multiple.put(fileName, new JProp(fileName));
220: }
221: return (JProp) multiple.get(fileName);
222: }
223:
224: /**
225: * Get one of the multiple instances corresponding to a given resource.
226: * Create it at first call with a given configuration file name
227: * @param fileName the name of the configuration file
228: * @param props the content of the configuration file to be written in fileName
229: * @return one of the multiple instances corresponding to a given resource.
230: * @throws Exception if no JProp can be built
231: */
232: public static JProp getInstance(String fileName, Properties props) {
233: if (!multiple.containsKey(fileName)) {
234: multiple.put(fileName, new JProp(fileName, props));
235: }
236: return (JProp) multiple.get(fileName);
237: }
238:
239: /**
240: * Remove the JProp instance corresponding to the given file name from the 'multiple'
241: * data structure
242: * @param fileName file name corresponding to the name of the resource to be removed
243: */
244: public static void removeInstance(String fileName) {
245: if (multiple.containsKey(fileName)) {
246: multiple.remove(fileName);
247: }
248: }
249:
250: /**
251: * Remove the JProp instance corresponding to the given file name from the 'multiple'
252: * data structure and delete the file
253: * @param fileName file name corresponding to the name of the resource to be removed
254: * and deleted from the file system
255: */
256: public static void deleteInstance(String fileName) {
257: if (multiple.containsKey(fileName)) {
258: multiple.remove(fileName);// Check the JONAS_BASE environment property
259: if (jonasBase == null) {
260: return;
261: }
262: jonasBase = jonasBase.trim();
263:
264: // JONAS_BASE/conf/fileName
265: String propFileName = jonasBase + fileSeparator
266: + CONFIG_DIR + fileSeparator + fileName
267: + ".properties";
268: File del = new File(propFileName);
269: del.delete();
270: }
271: }
272:
273: /**
274: * Write configuration properties in file getProperty(JONAS_BASE)/conf/fileName
275: * @param fileName name of the configuration file to write
276: * @param props Properties to register in the fileName file
277: * @throws Exception if it can't write to the specified file
278: */
279: private void writePropsToFile(String fileName, Properties props) {
280:
281: // Check the JONAS_BASE environment property
282: if (jonasBase == null) {
283: throw new RuntimeException(
284: "JOnAS configuration error: environment property jonas.base not set!");
285: }
286: jonasBase = jonasBase.trim();
287:
288: // JONAS_BASE/conf/fileName
289: propFileName = jonasBase + fileSeparator + CONFIG_DIR
290: + fileSeparator + fileName + ".properties";
291:
292: try {
293: FileOutputStream os = new FileOutputStream(propFileName);
294: props.store(os, "This file is generated by JOnAS");
295: os.close();
296: } catch (FileNotFoundException e) {
297: // File propFileName could not be opened
298: propFileName = null;
299: throw new RuntimeException("Cannot write config file :" + e);
300: } catch (IOException e) {
301: throw new RuntimeException("Cannot write config file :" + e);
302: }
303: configFileEnv = (Properties) props.clone();
304: allEnv = configFileEnv;
305: }
306:
307: /**
308: * Write xml configuration in file getProperty(JONAS_BASE)/conf/fileName
309: * @param fileName name of the configuration file to write
310: * @param txt text to write
311: * @throws Exception if it can't write to the specified file
312: */
313: private void writeXmlToFile(String fileName, String txt) {
314:
315: // Check the JONAS_BASE environment property
316: if (jonasBase == null) {
317: throw new RuntimeException(
318: "JOnAS configuration error: environment property jonas.base not set!");
319: }
320: jonasBase = jonasBase.trim();
321:
322: // JONAS_BASE/conf/fileName
323: propFileName = jonasBase + fileSeparator + CONFIG_DIR
324: + fileSeparator + fileName + ".properties";
325:
326: try {
327: BufferedWriter out = new BufferedWriter(new FileWriter(
328: new File(propFileName)));
329: out.write(txt);
330: out.flush();
331: out.close();
332: } catch (FileNotFoundException e) {
333: // File propFileName could not be opened
334: propFileName = null;
335: throw new RuntimeException(
336: "Cannot write xml configuration file:" + e);
337: } catch (IOException e) {
338: throw new RuntimeException(
339: "Cannot write xml configuration file:" + e);
340: }
341: }
342:
343: /**
344: * Read the content of the specified file. It can be an xml or properties file
345: * @param fileName name of the properties configuration file to read
346: * @throws Exception if it fails
347: */
348: private void readFile(String fileName) {
349:
350: // Check the JONAS_BASE environment property
351: if (jonasBase == null) {
352: throw new RuntimeException(
353: "JOnAS configuration error: environment property jonas.base not set!");
354: }
355: jonasBase = jonasBase.trim();
356:
357: if (fileName.equals(JONAS_VERSIONS)) {
358: readVersionFile();
359: return;
360: }
361:
362: // JONAS_BASE/conf/fileName
363: String fileFullPathname = jonasBase + fileSeparator
364: + CONFIG_DIR + fileSeparator + fileName;
365:
366: if (fileFullPathname.toLowerCase().endsWith(".xml")) {
367: readXmlFile(fileFullPathname);
368: } else {
369: readPropsFile(fileFullPathname);
370: }
371: }
372:
373: private void readVersionFile() {
374: String fileFullPathname = installRoot + fileSeparator
375: + JONAS_VERSIONS;
376: try {
377: File f = new File(fileFullPathname);
378: int length = (int) f.length();
379: FileInputStream fis = new FileInputStream(f);
380: byte[] buffer = new byte[length];
381: fis.read(buffer);
382: fis.close();
383: versionFileContent = new String(buffer);
384: } catch (FileNotFoundException e) {
385: throw new RuntimeException("Cannot find file "
386: + fileFullPathname);
387: } catch (IOException e) {
388: throw new RuntimeException("Cannot read file "
389: + fileFullPathname);
390: }
391: }
392:
393: /**
394: * Read initial configuration properties in file getProperty(JONAS_BASE)/conf/fileName
395: * These properties may be overridden by system properties, provided on the java command line.
396: * @param fileName name of the configuration file to read
397: * @throws Exception if it fails
398: */
399: private void readPropsFile(String fileName) {
400:
401: // Update filename of this JProp
402: this .propFileName = fileName;
403:
404: if (!fileName.endsWith(".properties")) {
405: propFileName += ".properties";
406: }
407:
408: File f = null;
409: try {
410: f = new File(propFileName);
411: FileInputStream is = new FileInputStream(f);
412: configFileEnv.load(is);
413: } catch (FileNotFoundException e) {
414: throw new RuntimeException("Cannot find properties for "
415: + propFileName);
416: } catch (IOException e) {
417: throw new RuntimeException("Cannot load properties for "
418: + propFileName);
419: }
420:
421: allEnv = (Properties) configFileEnv.clone();
422: // Overriddes with syst properties
423: if (f.getName().equalsIgnoreCase("jonas.properties")) {
424: for (Enumeration e = systEnv.keys(); e.hasMoreElements();) {
425: Object key = e.nextElement();
426: String value = ((String) systEnv.get(key)).trim();
427: allEnv.put(key, (Object) value);
428: }
429:
430: String serverName;
431: if (!systEnv.containsKey(JONAS_NAME)) {
432: allEnv.put(JONAS_NAME, JONAS_DEF_NAME);
433: }
434: serverName = ((String) allEnv.get(JONAS_NAME)).trim();
435:
436: if (!allEnv.containsKey(DOMAIN_NAME)
437: && !systEnv.containsKey(DOMAIN_NAME)) {
438: allEnv.put(DOMAIN_NAME, serverName);
439: }
440: }
441: }
442:
443: /**
444: * Read initial configuration in file getProperty(JONAS_BASE)/conf/fileName
445: * @param fileName name of the xml configuration file to read
446: */
447: private void readXmlFile(String fileName) {
448:
449: // Update filename of this JProp
450: this .propFileName = fileName;
451:
452: try {
453: File f = new File(propFileName);
454: int length = (int) f.length();
455: FileInputStream fis = new FileInputStream(f);
456: byte[] buffer = new byte[length];
457: fis.read(buffer);
458: fis.close();
459: configFileXml = new String(buffer);
460: } catch (FileNotFoundException e) {
461: throw new RuntimeException("Cannot find file "
462: + propFileName);
463: } catch (IOException e) {
464: throw new RuntimeException("Cannot read file "
465: + propFileName);
466: }
467: }
468:
469: /**
470: * Static method which return the JOnAS install root value.
471: * @return the JOnAS install root value.
472: */
473: public static String getInstallRoot() {
474: // Check install.root system property
475: if (installRoot == null) {
476: throw new RuntimeException(
477: "JOnAS configuration error: System property install.root not set!");
478: }
479: return installRoot;
480: }
481:
482: /**
483: * Static method which return the jonas.base property
484: * @return the jonas.base property
485: */
486: public static String getJonasBase() {
487: return jonasBase;
488: }
489:
490: /**
491: * Static method which return the working directory in jonas.base
492: * @return the jonas.base property
493: */
494: public static String getWorkDir() {
495: return jonasBase + File.separator + "work";
496: }
497:
498: /**
499: * Static method which return the working directory in jonas.base
500: * @return the jonas.base property
501: */
502: public static String getConfDir() {
503: return jonasBase + File.separator + CONFIG_DIR;
504: }
505:
506: /**
507: * Returns properties filename
508: *
509: * @return JOnAS properties filename
510: */
511: public String getPropFile() {
512: return propFileName;
513: }
514:
515: /**
516: * Returns JOnAS environment as configured with configuration file properties content and
517: * system properties.
518: * @return JOnAS properties
519: */
520: public Properties getEnv() {
521: return allEnv;
522: }
523:
524: /**
525: * Returns JOnAS environment as configured with files properties only.
526: *
527: * @return JOnAS properties
528: */
529: public Properties getConfigFileEnv() {
530: return configFileEnv;
531: }
532:
533: /**
534: * Returns xml content of the resource file
535: *
536: * @return xml content of the resource file
537: */
538: public String getConfigFileXml() {
539: return configFileXml;
540: }
541:
542: public String getVersionFile() {
543: return versionFileContent;
544: }
545:
546: /**
547: * Returns the value of the related property. With default values.
548: * @param key the search key
549: * @param defaultVal if the key is not found return this default value
550: * @return property value
551: */
552: public String getValue(String key, String defaultVal) {
553: String retProperty = allEnv.getProperty(key, defaultVal);
554: return retProperty.trim();
555: }
556:
557: /**
558: * Returns the value of the related property.
559: * The method returns null if the property is not found.
560: * @param key the wanted key
561: * @return property value, null if not exist
562: */
563: public String getValue(String key) {
564:
565: String retProperty = allEnv.getProperty(key);
566: if (retProperty != null) {
567: retProperty = retProperty.trim();
568: }
569: return retProperty;
570: }
571:
572: /**
573: * Returns the value of the related property as boolean.
574: * @param key the wanted key
575: * @param def default run if not found
576: * @return property value, true or false.
577: */
578: public boolean getValueAsBoolean(String key, boolean def) {
579: boolean ret = def;
580: String value = this .getValue(key);
581: if (value != null && value.equalsIgnoreCase("true")) {
582: ret = true;
583: }
584: return ret;
585: }
586:
587: /**
588: * Returns the value of the related property as String [].
589: * The method returns null if the property is not found.
590: * @param key the wanted key
591: * @return property value, null if not exist
592: */
593: public String[] getValueAsArray(String key) {
594:
595: String[] res = null;
596: String value = this .getValue(key);
597: if (value != null) {
598: StringTokenizer st = new StringTokenizer(value, ",");
599: res = new String[st.countTokens()];
600: int i = 0;
601: while (st.hasMoreTokens()) {
602: res[i++] = st.nextToken().trim();
603: }
604: }
605: return res;
606: }
607:
608: /**
609: * String representation of the object for trace purpose
610: * @return String representation of this object
611: */
612: public String toString() {
613: String s = new String();
614: for (Enumeration e = this .configFileEnv.keys(); e
615: .hasMoreElements();) {
616: Object key = e.nextElement();
617: Object value = this .configFileEnv.get(key);
618: s = s.concat(" " + key + " = " + value + "\n");
619: }
620: if (s.length() > 0) {
621: // take of the last '\n'
622: s = s.substring(0, s.length() - 1);
623: }
624: return s;
625: }
626:
627: /**
628: * Bind all the properties found in file properties in a naming context
629: * the naming context must be allocated by the caller
630: * @param ctx given context for bindings properties
631: * @throws Exception if it fails
632: */
633: public void env2Ctx(Context ctx) throws Exception {
634: Enumeration e = configFileEnv.propertyNames();
635: String key = null;
636: while (e.hasMoreElements()) {
637: key = (String) e.nextElement();
638: ctx.bind(key, configFileEnv.getProperty(key, ""));
639: }
640: }
641:
642: /**
643: * Displays the JOnAS properties values, as they are set by the
644: * different property files.
645: * @param args the arguments for launching this program
646: */
647: public static void main(String args[]) {
648:
649: JProp jonasProperties = null;
650: try {
651: jonasProperties = JProp.getInstance();
652: } catch (Exception e) {
653: System.err.println(e);
654: System.exit(2);
655: }
656: for (Enumeration e = jonasProperties.configFileEnv.keys(); e
657: .hasMoreElements();) {
658: Object key = e.nextElement();
659: Object value = jonasProperties.configFileEnv.get(key);
660: System.out.println(key.toString() + "=" + value.toString());
661: }
662: }
663:
664: }
|