KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lutris > util > ConfigFile


1
2 /*
3  * Enhydra Java Application Server Project
4  *
5  * The contents of this file are subject to the Enhydra Public License
6  * Version 1.1 (the "License"); you may not use this file except in
7  * compliance with the License. You may obtain a copy of the License on
8  * the Enhydra web site ( http://www.enhydra.org/ ).
9  *
10  * Software distributed under the License is distributed on an "AS IS"
11  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
12  * the License for the specific terms governing rights and limitations
13  * under the License.
14  *
15  * The Initial Developer of the Enhydra Application Server is Lutris
16  * Technologies, Inc. The Enhydra Application Server and portions created
17  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
18  * All Rights Reserved.
19  *
20  * Contributor(s):
21  *
22  * $Id: ConfigFile.java,v 1.12 2005/03/25 16:41:03 slobodan Exp $
23  */

24
25 package com.lutris.util;
26
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.io.PrintWriter JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Hashtable JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.Vector JavaDoc;
37
38 import org.enhydra.util.AbsConfigFile;
39 import org.enhydra.util.ConfConfiguration;
40 import org.enhydra.util.JNDIAdapter;
41
42 /**
43  * ConfigFile is used to manipulate Multiserver configuration (*.conf) files.
44  *
45  * Presents all configuration elements in the form of a keyed
46  * table. Configuration elements are grouped by string "keys" according
47  * to the function they configure. The syntax is described more formally
48  * below.
49  * <PRE>
50  * stream ::= entry | stream entry
51  * entry ::= key "=" value_list | comment | blank
52  * value_list ::= value | value_list "," value
53  * value ::= fragment | value "+" fragment
54  * fragment ::= key | quoted_string
55  * quoted_string ::= (C/C++ style quoted string)
56  * key ::= (A string matching [A-Za-z_\./][A-Za-z0-9_-\./]*)
57  * comment ::= "#" (any text up to a newline)
58  * blank ::= (A line containing only white space)
59  * </PRE>
60  * In addition to the above syntax, some additional semantic rules apply.
61  * The operator "+" concatenates the fragment immediately to the left
62  * and to the right of it. Thus <code>ab + cd</code> results in
63  * <code>abcd</code>. The operator "," terminates one element and begins
64  * the next element. Thus, the line <code>val = hello, world</code>
65  * creates a configuration entry with the key "val" and the two elements
66  * "hello", and "world". If the characters "+", ",", or "\" occur at
67  * the end of a line, then the entry is continued on the next line.
68  * Trailing and leading whitespaces are ignored, and multiple whitespace
69  * characters are converted by default into a single space. The "+"
70  * operator leaves no whitespace between operands.
71  * Finally, within quoted strings, C-style backslash escapes are
72  * recognized. These include "\n" for newline, "\t" for tab, etc.
73  * An example configuration input file is given below.
74  * <PRE>
75  * #==============================================================
76  * # Sample.config
77  * #==============================================================
78  * LDAP_SERVERS[] = "server1.ldap.gov:338",
79  * "server2.ldap.gov:1000"
80  * USER_TIMEOUT = 3600 # seconds. Comments can follow on same line.
81  * STRANGE_ENTRY = "This is a long long long long long " +
82  * "long long line. Notice how the \"+\" " +
83  * "operator is used to break this line up " +
84  * "into more than one line in the config file." ,
85  * "And this is the second element."
86  * # etc.
87  * </PRE>
88  *
89  * @see Config
90  * @author Shawn McMurdo
91  * @version $Revision: 1.12 $
92  */

93 public class ConfigFile extends AbsConfigFile{
94
95 /**
96  * Constructor from an InputStream.
97  * @param inputStream The input stream from which to parse the config file.
98  * @exception ConfigException
99  */

100   public ConfigFile(InputStream JavaDoc inputStream) throws ConfigException {
101     config = new Config();
102     order = new Vector JavaDoc();
103     comments = new Hashtable JavaDoc();
104     ConfigParser parser = new ConfigParser(inputStream);
105     try {
106       parser.process(this);
107     }
108     catch (ParseException e) {
109       throw new ConfigException(ConfigException.SYNTAX, e.getMessage());
110     }
111     
112     //SV 25.03.2005.
113
try {
114       readJndi();
115     } catch (Exception JavaDoc e){}
116
117   }
118
119    public ConfigFile () {
120     super();
121   }
122
123 /**
124  * Constructor from a File. Allows to later write back the configuration to the
125  * same file.
126  * @param file The local file to parse.
127  * @exception IOException
128  * @exception ConfigException
129  */

130   public ConfigFile (File JavaDoc file) throws ConfigException, IOException JavaDoc {
131    super(file);
132   }
133
134 /**
135  * Constructor from a KeywordValueTable.
136  * @param kvt A KeywordValueTable from which to populate the config file.
137  * @exception ConfigException
138  */

139   public ConfigFile(KeywordValueTable kvt) throws ConfigException {
140    super(kvt);
141   }
142
143 /**
144  * Reads application configuration parameters by using JNDI Context.
145  */

146  protected void readJndi() throws ConfigException {
147    try {
148      if (jndiAdapt == null){
149        try {
150          jndiAdapt = new JNDIAdapter(this.file.getAbsolutePath(), "org.enhydra.spi.conf.ConfFileInitialContextFactory");
151        }
152        catch(Exception JavaDoc e){
153          jndiAdapt = new JNDIAdapter();
154        }
155      }
156      
157       String JavaDoc[] leafKeys = jndiAdapt.leafKeys();
158       if (leafKeys != null) {
159         int leafKeysLength = leafKeys.length;
160         String JavaDoc newKey = null;
161         String JavaDoc stringValue;
162         String JavaDoc[] stringValues;
163         boolean has_configuration_keys = false;
164         ConfConfiguration configuration_value = null;
165         for (int i=0; i<leafKeysLength; i++){
166           String JavaDoc leafKey = leafKeys[i];
167           if (leafKey != null) {
168             if (leafKey.equals("configuration/ConfConfigurationFactory")) {
169                 has_configuration_keys = true;
170                 configuration_value = (ConfConfiguration) jndiAdapt.get("configuration/ConfConfigurationFactory");
171             }
172             else {
173               if (jndiAdapt.isArray(leafKey)){
174                 newKey = jndiAdapt.removeArrayMark(leafKey);
175                 if (newKey !=null) {
176                   stringValues = jndiAdapt.getStrings(newKey);
177                   newKey = jndiAdapt.makeConfigString(newKey);
178                   config.set(newKey, stringValues);
179                   if (!order.contains(newKey))
180                     order.addElement(newKey);
181                 comments.put(newKey, "");
182                 }
183               }
184               else {
185                    Object JavaDoc ovalue = jndiAdapt.get(leafKey);
186                    newKey = jndiAdapt.makeConfigString(leafKey);
187
188 // stringValue = (String)jndiAdapt.get(leafKey);
189
if (ovalue instanceof java.lang.String JavaDoc){
190                       stringValue = (String JavaDoc)ovalue;
191                               if (stringValue.startsWith("jndi:")){
192
193                                 stringValue = stringValue.substring(5);
194                                 Object JavaDoc resource = jndiAdapt.getResource(stringValue);
195                                 if (resource != null) {
196                                   config.set(newKey, resource);
197                                   jndiParameterNames.put(newKey,stringValue);
198                                 }
199                                 else {
200                                   config.set(newKey, "jndi:"+stringValue);
201                                 }
202                               }
203                               else {
204                                 config.set(newKey, stringValue);
205                               }
206                               if ( (newKey !=null) && (!order.contains(newKey))) {
207                                 order.addElement(newKey);
208                               }
209                               comments.put(newKey, "");
210                           }
211                           else {
212                   }
213               } // else
214
} // else from if (leafKey.equals("configuration/ConfConfigurationFactory"))
215
} // if (leafKey != null)
216
} // for
217
if (has_configuration_keys && (configuration_value != null)) {
218            HashMap JavaDoc elems = configuration_value.getResults();
219            Set JavaDoc set1 = elems.keySet();
220            Iterator JavaDoc iter1 = set1.iterator();
221            while (iter1.hasNext()){
222               String JavaDoc key = (String JavaDoc)iter1.next();
223               if (jndiAdapt.isArray(key)) {
224                  stringValues = (String JavaDoc[])elems.get(key);
225                  newKey = jndiAdapt.removeArrayMark(key);
226                  newKey = jndiAdapt.makeConfigString(newKey);
227                  config.set(newKey, stringValues);
228                  if (!order.contains(newKey))
229                     order.addElement(newKey);
230                  comments.put(newKey, "");
231                }
232                else {
233                  stringValue = (String JavaDoc)elems.get(key);
234                  
235                  newKey = jndiAdapt.makeConfigString(key);
236                  
237                  if (stringValue.startsWith("jndi:")){
238                     stringValue = stringValue.substring(5);
239                         Object JavaDoc resource = jndiAdapt.getResource(stringValue);
240                         if (resource != null) {
241                           config.set(newKey, resource);
242                             jndiParameterNames.put(newKey,stringValue);
243                            }
244                            else {
245                               config.set(newKey, "jndi:"+stringValue);
246                              }
247                           }
248                           else {
249                              config.set(newKey, stringValue);
250                           }
251                   if (!order.contains(newKey))
252                      order.addElement(newKey);
253                   comments.put(newKey, "");
254               }
255            } // while
256
} // if (has_configuration_keys)
257

258         
259       }
260    } // try
261
catch (Exception JavaDoc e){
262     //System.err.println("Error readJndi conf file");
263
//e.printStackTrace();
264
throw new ConfigException("Error in reading JNDI configuration parameters.");
265    }
266  }
267
268 /**
269  * Writes out a config file to the OutputStream specified. Note that Objects
270  * other than String or String[] will be converted into a String.
271  * @param outputStream The output stream on which to write the config file.
272  */

273   public void write(OutputStream JavaDoc outputStream) {
274     PrintWriter JavaDoc out = new PrintWriter JavaDoc(outputStream, true);
275     boolean isArray = false;
276     String JavaDoc key;
277     String JavaDoc comment;
278     String JavaDoc[] values;
279     Hashtable JavaDoc remaining = new Hashtable JavaDoc();
280     String JavaDoc[] remainingkeys = config.leafKeys();
281
282 // Set up the remaining keys list
283
// The value doesn't matter, just the key
284
for (int i = 0; i < remainingkeys.length; i++)
285       remaining.put(remainingkeys[i], "X");
286
287 // Do all the entries for which we have comments
288
for (int i = 0; i < order.size(); i++) {
289       key = (String JavaDoc) order.elementAt(i);
290       comment = (String JavaDoc) comments.get(key);
291       isArray = false;
292       try {
293         Object JavaDoc o = config.get(key);
294         if (o == null) {
295           continue;
296         }
297         isArray = o.getClass().isArray();
298         if (isArray) {
299           Object JavaDoc[] oa = (Object JavaDoc[])o;
300           if ((oa.length > 0) && (oa[0] instanceof java.lang.String JavaDoc))
301             values = (String JavaDoc[]) o;
302           else {
303             values = new String JavaDoc[oa.length];
304             for (int k = 0; k < oa.length; k++)
305               values[k] = oa[k].toString();
306           }
307         }
308         else {
309           values = new String JavaDoc[1];
310           if (o instanceof java.lang.String JavaDoc)
311             values[0] = (String JavaDoc) o;
312           else
313             values[0] = o.toString();
314         }
315       }
316       catch (KeywordValueException e) {
317         values = null;
318       }
319       // write out entry
320
if ((values == null) || (values.length == 0)) {
321         if ((comment != null) && !(comment.equals(""))) {
322           if (comment.endsWith("\n"))
323             out.print(comment);
324           else
325             out.println(comment);
326         }
327         out.print(key);
328         if (isArray) out.print("[]");
329         out.println(" =");
330       }
331       else {
332         if ((comment != null) && !(comment.equals(""))) {
333           if (comment.endsWith("\n"))
334             out.print(comment);
335           else
336             out.println(comment);
337         }
338         if (isArray)
339           out.print(key + "[] = " + quoteStr(values[0]));
340         else {
341            if (jndiParameterNames.containsKey(key)){
342               String JavaDoc newValueString = "jndi:" + (String JavaDoc)jndiParameterNames.get(key);
343               out.print(key + " = " + quoteStr(newValueString));
344 // jndiParameterNames.remove(key);
345
}
346            else {
347               out.print(key + " = " + quoteStr(values[0]));
348            }
349           
350          }
351         for (int j = 1; j < values.length; j++)
352           out.print(", " + quoteStr(values[j]));
353         out.println();
354       }
355       remaining.remove(key);
356     }
357
358 // Do the trailing comment
359
comment = (String JavaDoc) comments.get(TRAILING_COMMENT);
360     if ((comment != null) && !(comment.equals(""))) {
361       if (comment.endsWith("\n")) {
362         out.print(comment);
363       }
364       else {
365         out.println(comment);
366       }
367     }
368     remaining.remove(TRAILING_COMMENT);
369
370
371     // The new keys are in a hash table with no order
372
// sort them here so that they will be grouped correctly
373
// in the conf file. It makes it easier to read.
374
// XXX This is dependent on JDK 1.2 so comment it out
375
// XXX until we don't support JDK 1.1 anymore.
376
/* XXX
377       java.util.Arrays.sort(remainingkeys,new Comparator() {
378          public int compare(Object o1, Object o2) {
379             String s1 = (String) o1;
380             return s1.compareTo((String) o2);
381          }
382       });
383 XXX */

384
385
386     int i=0;
387     String JavaDoc lastWord = "";
388     while (i != remainingkeys.length) {
389       key = remainingkeys[i];
390       i++;
391       // Do the remaining config entries
392
if (remaining.get(key) != null) {
393         isArray = false;
394         if (!key.startsWith(lastWord))
395           out.println("");
396         int dot = key.indexOf('.');
397         if (dot == -1)
398           dot = key.length();
399         lastWord = key.substring(0,dot);
400
401         try {
402           Object JavaDoc o = config.get(key);
403           if (o == null)
404             continue;
405           isArray = o.getClass().isArray();
406           if (isArray) {
407             Object JavaDoc[] oa = (Object JavaDoc[])o;
408             if (oa[0] instanceof java.lang.String JavaDoc)
409               values = (String JavaDoc[]) o;
410             else {
411               values = new String JavaDoc[oa.length];
412               for (int k = 0; k < oa.length; k++)
413                 values[k] = oa[k].toString();
414             }
415           }
416           else {
417             values = new String JavaDoc[1];
418             if (o instanceof java.lang.String JavaDoc)
419               values[0] = (String JavaDoc) o;
420             else
421               values[0] = o.toString();
422           }
423         }
424         catch (KeywordValueException e) {
425           values = null;
426         }
427         // write out entry
428
if ((values == null) || (values.length == 0)) {
429           out.println(key + " =");
430         }
431         else {
432           if (isArray)
433             out.print(key + "[] = " + quoteStr(values[0]));
434           else
435             out.print(key + " = " + quoteStr(values[0]));
436
437           for (int j = 1; j < values.length; j++)
438             out.print(", " + quoteStr(values[j])); // VR 14.12.2002
439
// out.print(key + ", " + quoteStr(values[j])); VR 14.12.2002
440
out.println();
441         }
442       }
443     }
444   }
445
446
447   private boolean containsWhiteSpace(String JavaDoc str) {
448     if (str.indexOf(" ") != -1) {
449       return true;
450     }
451     else if (str.indexOf("\t") != -1) {
452       return true;
453     }
454     return false;
455   }
456
457
458   private static final String JavaDoc quoteStr(String JavaDoc s) {
459     if ((s == null) || (s.length() < 1)) return "";
460     char[] chars = s.toCharArray();
461     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
462     boolean needQuotes = false;
463     for (int i=0; i<chars.length; i++) {
464       switch (chars[i]) {
465       // Chars that get special backquotes
466
case '\n':
467         needQuotes = true;
468         sb.append("\\n");
469         break;
470       case '\b':
471         needQuotes = true;
472         sb.append("\\b");
473         break;
474       case '\r':
475         needQuotes = true;
476         sb.append("\\r");
477         break;
478       case '\f':
479         needQuotes = true;
480         sb.append("\\f");
481         break;
482       case '"':
483         needQuotes = true;
484         sb.append("\\\"");
485         break;
486       case '\\':
487         needQuotes = true;
488         sb.append("\\\\");
489         break;
490
491         // Chars that cause the string to be enclosed in
492
// double quotes.
493
case '\t': case ' ': case '!': case '#': case '$':
494       case '%': case '&': case '\'': case '(': case ')':
495       case '*': case '+': case ',': case '/': case ':':
496       case ';': case '<': case '=': case '>': case '?':
497       case '[': case ']': case '^': case '`': case '{':
498       case '|': case '}': case '~':
499         needQuotes = true;
500         sb.append(chars[i]);
501         break;
502
503         // All other characters.
504
default:
505         if ((chars[i] < ' ') || (chars[i] == 0x7f)) {
506           needQuotes = true;
507           int ival = (int) chars[i];
508           sb.append('\\');
509           sb.append(digits[(ival & 0xc0) >> 6]);
510           sb.append(digits[(ival & 0x38) >> 3]);
511           sb.append(digits[(ival & 0x07)]);
512         }
513         else if (chars[i] > 0x7f) {
514           needQuotes = true;
515           int ival = (int) chars[i];
516           sb.append("\\u");
517           sb.append(digits[(ival & 0xf000) >> 12]);
518           sb.append(digits[(ival & 0x0f00) >> 8]);
519           sb.append(digits[(ival & 0x00f0) >> 4]);
520           sb.append(digits[(ival & 0x000f)]);
521         }
522         else
523           sb.append(chars[i]);
524       }
525     }
526     if (needQuotes)
527       return( "\"" + sb.toString() + "\"");
528     return sb.toString();
529   }
530
531   private static final char[] digits = {
532     '0', '1', '2', '3', '4', '5', '6', '7',
533     '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
534   };
535
536 }
537
538
Popular Tags