Project

General

Profile

Bug #3219 ยป Config.java

Aaron Aaron, 04/11/2008 11:10 AM

 
1
/**
2
 *    '$RCSfile: Config.java,v $'
3
 *
4
 *     '$Author: barseghian $'
5
 *       '$Date: 2007/10/11 00:36:37 $'
6
 *   '$Revision: 1.22 $'
7
 *
8
 *  For Details: http://kepler.ecoinformatics.org
9
 *
10
 * Copyright (c) 2003 The Regents of the University of California.
11
 * All rights reserved.
12
 *
13
 * Permission is hereby granted, without written agreement and without
14
 * license or royalty fees, to use, copy, modify, and distribute this
15
 * software and its documentation for any purpose, provided that the
16
 * above copyright notice and the following two paragraphs appear in
17
 * all copies of this software.
18
 *
19
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
20
 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
21
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
22
 * IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
23
 * OF SUCH DAMAGE.
24
 *
25
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
26
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
28
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
29
 * OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
30
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
31
 */
32

    
33
package org.ecoinformatics.util;
34

    
35
import java.io.File;
36
import java.io.FileNotFoundException;
37
import java.io.InputStream;
38
import java.util.Collections;
39
import java.util.Hashtable;
40
import java.util.List;
41
import java.util.Map;
42
import java.util.Vector;
43

    
44
import javax.xml.transform.TransformerException;
45

    
46
import org.apache.commons.logging.Log;
47
import org.apache.commons.logging.LogFactory;
48
import org.apache.xpath.XPathAPI;
49
import org.w3c.dom.Node;
50
import org.w3c.dom.NodeList;
51

    
52
import edu.ucsb.nceas.configxml.ConfigXML;
53
import edu.ucsb.nceas.configxml.exception.ElementNotFoundException;
54
import edu.ucsb.nceas.configxml.exception.IndexTooLargeException;
55
import java.net.URL;
56

    
57
/**
58
 *
59
 * configuration file routines
60
 *
61
 */
62
public class Config
63
{
64
  //private static final String configfilename = "kepler/config.xml";
65
  private static final String configfilename = "config.xml";
66

    
67
  private static final String settingsdir = ".kepler";
68

    
69
  // Define useful static strings.  At some point in time, these could be moved
70
  // into the config.xml file, environment variable, or something else
71
  // which could move this directory to another location.
72
  
73
  // KEPLER_USER_DIR is returned by Config.getUserDirPath().
74
  private static final String KEPLER_USER_DIR = System.getProperty("user.home")
75
                + File.separator + settingsdir + File.separator;
76

    
77
  // KEPLER_CACHE_DIR is returned by Config.getCacheDirPath().
78
  private static final String KEPLER_CACHE_DIR = KEPLER_USER_DIR + "cache" + File.separator;
79

    
80
  /**
81
   * The singleton instance.
82
   */
83
  private static Config configure ;
84
  static {
85
	  configure = new Config();
86
  }
87
  
88
  private static Log log;
89
  static {
90
	  log = LogFactory.getLog("org.ecoinformatics.util.Config");
91
  }
92
  
93
  // Instance variables.
94
  
95
  /**
96
   * The underlying ConfigXML object.
97
   */
98
  private ConfigXML config;
99
  
100
  /**
101
   * Error indicator.  Set to true if ConfigXML has problems.
102
   */
103
  private boolean error = false;
104
  
105
  /**
106
   * Method for get object as a singleton class
107
   * @return Config
108
   */
109
  public static Config getInstance()
110
  {
111
    return configure;
112
  }
113

    
114
  /*
115
   * Constructor for ConfigDatasource.
116
   * @throws FileNotFoundException
117
   * @throws Exception
118
   */
119
  private Config()
120
  {
121
    try
122
    {
123
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(configfilename);
124
        if (is == null) {
125
            throw new FileNotFoundException("Failed to find \"" 
126
                    + configfilename + "\" as a resource");
127
        }
128
	    URL configFileURL = this.getClass().getClassLoader().getSystemResource(configfilename);
129
	    File configFile = new File(configFileURL.toURI());
130
	    config = new ConfigXML( is, configFile.getAbsolutePath() );
131

    
132
        //config = new ConfigXML(configfilename);
133
    }
134
    catch(FileNotFoundException fnfe)
135
    {
136
      error = true;
137
      throw new RuntimeException("Config file not found at " + configfilename, fnfe );
138
    }
139
    catch(Exception e)
140
    {
141
      error = true;
142
      throw new RuntimeException("Unspecified error creating config object: ", e );
143
    }
144
  }
145

    
146
  /**
147
   * Method to get a string value from config.xml base on given element path
148
   * @param path String
149
   * @return String
150
   */
151
  public static String getValue(String path)
152
  {
153
    Config configInstance = Config.getInstance();
154
    return configInstance.getValueFromPath(path);
155
  }
156

    
157
  private String getValueFromPath(String path)
158
  {
159
    String value = null;
160
    if ( error ) {
161
    	return value;
162
    }
163
    if ( path == null ) {
164
    	return value;
165
    }
166
    	try {
167
    		Vector valueVector = config.getValuesForPath(path);
168
            value = (String) valueVector.elementAt(0);
169
    	}
170
    	catch ( ElementNotFoundException e1 ) {
171
    		log.debug("Element " + path + " not found");
172
    	}
173
    	catch ( Exception e2 ) {
174
    		log.error("Exception occurred:", e2 );
175
    	}
176
    log.debug("The value for path " + path + " in config.xml is " + ((value==null) ? "null" : value) );
177
    return value;
178
  }//getValues
179

    
180
  /**
181
   * Method returns an unmodifiable list of values from config.xml base on given path.
182
   * If the argument is null or not found in config.xml, return EMPTY_LIST.
183
   * 
184
   * @param path String
185
   * @return Vector
186
   */
187
  public static List getList(String path)
188
  {
189
    Config configInstance = Config.getInstance();
190
    return configInstance.getListFromPath(path);
191
  }
192

    
193
  private List getListFromPath(String path)
194
  {
195
	  List value = Collections.EMPTY_LIST;
196
	    if ( error ) {
197
	    	return value;
198
	    }
199
	    if ( path == null ) {
200
	    	return value;
201
	    }
202
    	try {
203
    		value = Collections.unmodifiableList(config.getValuesForPath(path));
204
    	}
205
    	catch ( ElementNotFoundException e1 ) {
206
    		log.debug("Element " + path + " not found");
207
    	}
208
    	catch ( Exception e2 ) {
209
    		log.error("Exception occurred:", e2 );
210
    	}
211

    
212
    return value;
213
  }//getList
214

    
215
  /**
216
   * Method to get unmodifiable map for some given pathes in config.xml.
217
   * If the arguments are invalid (either null) or not found, return an empty map.
218
   * Here is the segment of config.xml:
219
   * <parenetElement>
220
   *   <keyElement>key1</keyElement>
221
   *   <valueElement>value1</valueElement>
222
   *  </parentElement>
223
   *  <parentElement>
224
   *   <keyElement>key2</keyElement>
225
   *   <valueElement>value2</valueElement>
226
   *  </parentElement>
227
   * The parentPath can be "//parentElement", keyPath should be "./keyElement",
228
   * and valuePath should be "./valuePath".
229
   * @param parentPath String
230
   * @param keyPath String
231
   * @param valuePath String
232
   * @throws ElementNotFoundException
233
   * @throws Exception
234
   * @return Hashtable
235
   */
236
  public static Map getMap(String parentPath, String keyPath, String valuePath)
237
  {
238
    Config configInstance = Config.getInstance();
239
    return configInstance.getMapFromPath(parentPath, keyPath, valuePath);
240
  }
241

    
242
  private Map getMapFromPath(String parentPath, String keyPath, String valuePath)
243
  {
244
    Map map = Collections.EMPTY_MAP;
245
    if ( error ) {
246
    	return map;
247
    }
248
    if ( parentPath == null || keyPath == null || valuePath == null ) {
249
    	return map;
250
    }
251
    NodeList nl = null;
252
    try {
253
        nl = config.getPathContent(parentPath);
254
    }
255
    catch ( ElementNotFoundException e1 ) {
256
    	log.debug("Element " + parentPath + " not found");
257
    	return map;
258
    }
259
    catch ( TransformerException e2 ) {
260
    	log.error("Transfomer Exception when reading parentPath " + parentPath, e2);
261
    	return map;
262
    }
263
    // At this point nl != null because we didn't get an ElementNotFoundException
264
    map = new Hashtable();
265
    try {
266
        for (int i = 0; i < nl.getLength(); i++)
267
        {
268
          Node n = nl.item(i);
269
          Node keyNode = XPathAPI.selectSingleNode(n, keyPath);
270
          Node valueNode = XPathAPI.selectSingleNode(n, valuePath);
271
          if (keyNode == null || valueNode == null)
272
          {
273
            log.debug("keyNode or valueNode not found at iteration " + i);
274
            continue;
275
          }
276

    
277
          String keyNodeValue = keyNode.getFirstChild().getNodeValue();
278
          String valueNodeValue = valueNode.getFirstChild().getNodeValue();
279
          if (keyNodeValue == null || valueNodeValue == null)
280
          {
281
        	  log.debug("keyNodeValue or valueNodeValue is null at iteration " + i);
282
        	  continue;
283
          }
284
          log.debug("The value of " + keyPath + " " + keyNodeValue + " and " +
285
                    " the value of " + valuePath + " " + valueNodeValue +
286
                    " are put into mapping");
287

    
288
          map.put(keyNodeValue, valueNodeValue);
289
        } //for
290
    }
291
    catch ( TransformerException e ) {
292
    	log.error("Transfomer Exception in loop ", e);
293
    }
294
    return Collections.unmodifiableMap(map);
295
  }//getMap
296
  
297
  /**
298
   * Get a node list base on the given xpath in config file
299
   * @param path String  the xpath
300
   * @return NodeList
301
   */
302
  public static NodeList getNodeListFromPath(String path)
303
  {
304
    Config configInstance = Config.getInstance();
305
    return configInstance.getNodeListFromXPath(path);
306
  }
307
  
308
  /*
309
   * This method will get a node list from config file
310
   */
311
  private NodeList getNodeListFromXPath(String xpath)
312
  {
313
    NodeList list = null;
314
    if ( error ) {
315
    	return list;
316
    }
317
    try
318
    {
319
      list = config.getPathContent(xpath);
320
    }
321
    catch (ElementNotFoundException e)
322
    {
323
    	log.debug("Element Not found for " + xpath );
324
    }
325
    catch ( TransformerException e2 ) {
326
    	log.error( "Transformer Exception for " + xpath );
327
    }
328
    return list;
329
  }
330

    
331
  /**
332
   * Method to get error state
333
   */
334
  public boolean getErrorState()
335
  {
336
    return error;
337
  }
338

    
339
  /** 
340
   * Returns the path of the Kepler hidden working directory terminated with File.seperator.
341
   * This directory is current coded to be ${system.home}/.kepler.
342
   * 
343
   * @return the path to the .kepler directory.
344
   */
345
  public static String getUserDirPath()
346
  {
347
	  return KEPLER_USER_DIR;  
348
  }
349
  
350
  /**
351
   * Returns the path to a subdirectory of the working directory.
352
   * The pathname is normalized to use the system style File.separator.
353
   * 
354
   * 
355
   * @param path a subdirectory of the working directory
356
   * @return normalized pathname of the subdirectory.
357
   */
358
  public static String getUserDirPath( String path )
359
  {
360
	  String pdir = path;
361
	  // In the config file we use unix style separators.
362
	  // Convert them to windows if on windows.
363
	  if ( '/' != File.separatorChar ) {
364
		  pdir.replace('/', File.separatorChar );
365
	  }
366
	  pdir = KEPLER_USER_DIR + path;
367
	  if ( pdir.endsWith(File.separator) ) {
368
		  return pdir;
369
	  }
370
	  else {
371
		  return pdir + File.separator;
372
	  }
373
  }
374
  
375
  /**
376
   * Returns the path to the Cache working directory terminated with File.seperator.
377
   * This directory is currently in getUserDirPath() + "cache".
378
   * 
379
   * @return the path to the cache directory
380
   */
381
  public static String getCacheDirPath()
382
  {
383
	  return KEPLER_CACHE_DIR;
384
  }
385
  
386
  /**
387
   * Method save. - pass through to ConfigXML member
388
   * @throws Exception
389
   */
390
  public void save() throws Exception
391
  {
392
	config.save();
393
  }
394

    
395
  /**
396
   * Method set. - pass through to ConfigXML member
397
   * @param arg1
398
   * @param arg2
399
   * @param arg3
400
   * @throws ElementNotFoundException
401
   */
402
  public void set(String arg1, int arg2, String arg3) throws ElementNotFoundException
403
  {
404
    config.set(arg1, arg2, arg3);
405
  }
406

    
407
   
408
  /**
409
   * Method deleteSubFields. - pass through to ConfigXML member
410
   * @param parentName 
411
   * @param i 
412
   * @throws IndexTooLargeException 
413
   */
414
  public void deleteSubFields(String parentName, int i) throws IndexTooLargeException 
415
  {
416
    config.deleteSubFields(parentName, i);
417
  }
418

    
419
  /**
420
   * Method addSubFields. - pass through to ConfigXML member
421
   * @param parentName
422
   * @param i
423
   * @param childName
424
   * @param value
425
   * @throws IndexTooLargeException
426
   */
427
  public void addSubField(String parentName, int i, String childName, String value)
428
                       throws IndexTooLargeException
429
  {
430
    config.addSubField(parentName, i, childName, value);
431
  }
432

    
433
}
434

    
    (1-1/1)