001: package com.jat.core.config;
002:
003: import java.io.BufferedReader;
004: import java.io.File;
005: import java.io.FileInputStream;
006: import java.io.FileOutputStream;
007: import java.io.IOException;
008: import java.io.InputStreamReader;
009: import java.io.PrintWriter;
010: import java.util.Enumeration;
011: import java.util.Hashtable;
012: import java.util.Vector;
013:
014: import com.jat.util.OrderVector;
015: import com.jat.util.StringOrderable;
016: import com.jat.util.StringUtil;
017:
018: /**
019: * <p>Title: JAT</p>
020: * <p>Description: </p>
021: * <p>Copyright: Copyright (c) 2004 -2005 Stefano Fratini (stefano.fratini@gmail.com)</p>
022: * <p>Distributed under the terms of the GNU Lesser General Public License, v2.1 or later</p>
023: * @author stf
024: * @version 1.0
025: */
026:
027: public class CGIniFile extends File {
028:
029: private Hashtable sections_;
030:
031: private String line_;
032: private String filename_;
033:
034: /**
035: * Creates a new reference to an INI file. Reads in all the INI data.
036: * Then , it closes the file.
037: * This class should be fixed to allow more flexible parameters.
038: *
039: * @parameter _filename The path and filename of the INI file.
040: * @throws Exception if anything goes wrong during read.
041: * @see readSection
042: */
043: public CGIniFile(String _filename) throws Exception {
044: super (_filename);
045: BufferedReader dis; // Read buffer, will be closed after init
046:
047: line_ = "";
048: filename_ = "";
049: filename_ = _filename;
050:
051: dis = new BufferedReader(new InputStreamReader(
052: new FileInputStream(this )));
053:
054: sections_ = new Hashtable();
055: for (line_ = dis.readLine(); line_ != null;) {
056: while (line_ != null && !line_.startsWith("["))
057: line_ = dis.readLine();
058:
059: readSection(dis);
060: }
061:
062: }
063:
064: /**
065: * Reads all lines in one section if the config file
066: *
067: * @param _dis The "File descriptor" to the config file. It should be
068: * opened and set to the first line in the section
069: * @throws Exception if anything goes wrong during read
070: * @see CGIniFile
071: */
072: private void readSection(BufferedReader _dis) throws Exception {
073: String key = null;
074: String value = null;
075:
076: try {
077: Hashtable hashtable = new Hashtable();
078: String s = line_.substring(1, line_.lastIndexOf(93));
079: for (line_ = _dis.readLine(); line_ != null
080: && !line_.startsWith("["); line_ = _dis.readLine()) {
081: if (line_ != null && line_.length() != 0
082: && !line_.startsWith(";")
083: && !line_.startsWith("#")) {
084: key = line_.substring(0, line_.indexOf("=")).trim();
085: value = line_.substring(line_.indexOf("=") + 1)
086: .trim();
087: if (value.startsWith("\"")) {
088: value = value.substring(1);
089: if (value.endsWith("\""))
090: value = value.substring(0,
091: value.length() - 1);
092: }
093: hashtable.put(key, value);
094: }
095: }
096: sections_.put(s, hashtable);
097: } catch (Exception e) {
098: throw new Exception(
099: "CGIniFile::readSection : error when reading the config file = "
100: + e.toString());
101: }
102:
103: }
104:
105: /**
106: * Allows the reading of a single piece of configuration data from any section within the INI file.
107: * @parameter _sec The section within the INI file (without []'s)
108: * @parameter _key The key whose value is to be found within that section
109: * @return The string containing the value of the key.
110: * @throws Exception
111: */
112: public String getValue(String _sec, String _key) throws Exception {
113: if (existsValue(_sec, _key))
114: return (String) ((Hashtable) sections_.get(_sec)).get(_key);
115: throw new Exception("Section |" + _sec + "|, value |" + _key
116: + "| missing in config files.");
117: }
118:
119: /**
120: * Return true if a section within the INI file contains the specified key.
121: * @parameter _sec The section within the INI file (without []'s)
122: * @parameter _key The key whose value is to be found within that section
123: * @return boolean.
124: */
125: public boolean existsValue(String _sec, String _key) {
126: return (sections_.containsKey(_sec) && ((Hashtable) sections_
127: .get(_sec)).containsKey(_key));
128: }
129:
130: /**
131: * Allows the reading of an entire section of configuration data.
132: * @parameter _sec The section within the INI file (without []'s)
133: * @return The Hashtable containing the keys and values as strings in that section, null if the section does not exist.
134: */
135: public Hashtable getSection(String _sec) {
136: return (Hashtable) sections_.get(_sec);
137: }
138:
139: /**
140: * Allows the reading of the entire INI file.
141: * @return The Hashtable containing the Hashtables for each section. Will be empty if no sections exist.
142: */
143: public Hashtable getAll() {
144: return (sections_);
145: }
146:
147: protected void setAll(Hashtable _section) {
148: this .sections_ = _section;
149: }
150:
151: /**
152: * Assigns a value to a key in a section of the INI file.
153: * Any method calls where the section or key are null or zero length will be ignored.
154: * Remember to save() when ready.
155: * @parameter _sec The section to add to. If the section does not exist, it will be created.
156: * @parameter _key The key to add. If the key does not exist, it will be created.
157: * @parameter _value The value to assign to the key. This value can be "".
158: * @return The value of any key that is overwritten in this operation.
159: */
160: public String addValue(String _sec, String _key, String _value) {
161: if (_sec != null && _key != null && _sec != "" && _key != "") {
162: Hashtable hashtable;
163: if (!sections_.containsKey(_sec))
164: sections_.put(_sec, hashtable = new Hashtable());
165: else
166: hashtable = (Hashtable) sections_.get(_sec);
167: return (String) hashtable.put(_key, _value);
168: } else {
169: return (null);
170: }
171: }
172:
173: /**
174: * Creates a new section in the INI file.
175: * If the section already exists or the section is null or "" then no action is taken.
176: * Remember to save() when ready.
177: * @parameter _sec The section (without []'s) to be created.
178: */
179: public void addSection(String _sec) {
180: if (!this .existsSection(_sec))
181: sections_.put(_sec.trim(), new Hashtable());
182: }
183:
184: /**
185: * Check if a section exists in the INI file.
186: * @parameter _sec The section (without []'s) to be created.
187: * @return true is section _sec exists, false otherwise
188: */
189: public boolean existsSection(String _sec) {
190: return _sec != null && !_sec.trim().equals("")
191: && sections_.containsKey(_sec);
192: }
193:
194: /**
195: * Removes a key (and it's corresponding value) from the INI file.
196: * Remember to save() when ready.
197: * @parameter _sec Section that the key and value is in.
198: * @parameter _key The key to be removed.
199: * @return The value of any value that is removed. Null if nothing is removed.
200: */
201: public String removeValue(String _sec, String _key) {
202: if (!sections_.containsKey(_sec))
203: return (null);
204: else
205: return (String) ((Hashtable) sections_.get(_sec))
206: .remove(_key);
207: }
208:
209: /**
210: * Removes all keys (and theirs corresponding values) starting with _key plus '.' from the INI file.
211: * Remember to save() when ready.
212: * @parameter _sec Section that the keys and values are in.
213: * @parameter _key The key to be removed.
214: */
215: public void removeKeys(String _sec, String _key) {
216: if (!sections_.containsKey(_sec))
217: return;
218: Hashtable hash = (Hashtable) sections_.get(_sec);
219: for (Enumeration e = hash.keys(); e.hasMoreElements();) {
220: String key = (String) e.nextElement();
221: if (key.startsWith(_key + "."))
222: hash.remove(key);
223: }
224: }
225:
226: /**
227: * Removes a section (and all it's keys) from the INI file.
228: * Remember to save() when ready.
229: * @parameter _sec Section to be removed (without []'s)
230: * @return Any section removed as a Hashtable. Null if nothing is removed.
231: */
232: public Hashtable removeSection(String _sec) {
233: return (Hashtable) sections_.remove(_sec);
234: }
235:
236: /**
237: * Clears the entire INI file. Remember to save() when ready.
238: * @return The Hashtable containing the Hashtables for each section.
239: */
240: public Hashtable removeAll() {
241: Hashtable hashtable = sections_;
242: sections_ = new Hashtable();
243: return (hashtable);
244: }
245:
246: /**
247: * Writes out the current data to a file, overwriting the original file,
248: * or the latest filename that it has been saved to successfully.
249: * @throws IOException if an error occurs while writing.
250: */
251: public void save() throws IOException {
252: save(this .getFilename());
253: }
254:
255: /**
256: * Writes out the current data to a file.
257: * @parameter _filename The file to save to.
258: * @throws IOException if an error occurs while writing.
259: */
260: public void save(String _filename) throws IOException {
261: PrintWriter printwriter = new PrintWriter(new FileOutputStream(
262: _filename));
263: printwriter
264: .println("################################################################################");
265: printwriter
266: .println("# JAT Configuration file #");
267: printwriter
268: .println("# #");
269: printwriter
270: .println("# This file contains configuration parameters for JAT Application. #");
271: printwriter
272: .println("# #");
273: printwriter
274: .println("# Copyright (c) 2004 -2005 Stefano Fratini (stefano.fratini@gmail.com) #");
275: printwriter
276: .println("# #");
277: printwriter
278: .println("# Distributed under the terms of the GNU Lesser General Public License, #");
279: printwriter
280: .println("# v2.1 or later #");
281: printwriter
282: .println("##################################################################edited by jat#");
283: printwriter.println("");
284: for (Enumeration enumeration = sections_.keys(); enumeration
285: .hasMoreElements(); printwriter.println()) {
286: String s1 = (String) enumeration.nextElement();
287: printwriter.println("[" + s1 + "]");
288: Vector vect = this .getOrderedKeyInSection(s1);
289: Hashtable hashtable = (Hashtable) sections_.get(s1);
290: String s2;
291: for (Enumeration enumeration1 = vect.elements(); enumeration1
292: .hasMoreElements(); printwriter.println(s2 + "="
293: + (String) hashtable.get(s2)))
294: s2 = enumeration1.nextElement().toString();
295: }
296: if (printwriter.checkError()) {
297: throw new IOException(
298: "An I/O exception occurred while saving the file.");
299: } else {
300: filename_ = _filename;
301: return;
302: }
303: }
304:
305: private OrderVector getOrderedKeyInSection(String section) {
306: OrderVector vect = new OrderVector();
307: Hashtable hashtable = (Hashtable) sections_.get(section);
308: for (Enumeration enumeration1 = hashtable.keys(); enumeration1
309: .hasMoreElements();) {
310: String str = (String) enumeration1.nextElement();
311: vect.addAscElement(new StringOrderable(str));
312: }
313: return vect;
314: }
315:
316: /**
317: * Return a Vector of values containing keyPattern
318: * @param _section section name in the ini file
319: * @param _keyPattern pattern criteria
320: * @throws Exception if an error occurs.
321: * @return Vector of values
322: */
323: public Vector getSubValues(String _section, String _keyPattern)
324: throws Exception {
325: Vector ret = new Vector();
326: for (Enumeration e = this .getSubKeys(_section, _keyPattern)
327: .elements(); e.hasMoreElements();) {
328: ret.addElement(this .getValue(_section, (String) e
329: .nextElement()));
330: }
331: return ret;
332: }
333:
334: /**
335: * Return a Vector of keys containing keyPattern
336: * @param _section section name in the ini file
337: * @param _keyPattern pattern criteria
338: * @throws Exception if an error occurs.
339: * @return Vector of keys
340: */
341: public Vector getSubKeys(String _section, String _keyPattern)
342: throws Exception {
343: Hashtable hTable = getSection(_section);
344:
345: Vector subKeys = new Vector();
346:
347: for (Enumeration e = hTable.keys(); e.hasMoreElements();) {
348: String key = (String) e.nextElement();
349:
350: if ((key.length() > _keyPattern.length())
351: && (key.substring(0, _keyPattern.length())
352: .compareTo(_keyPattern) == 0)) {
353:
354: int keyIndex = key.indexOf(".", _keyPattern.length());
355: if (keyIndex == -1) {
356: keyIndex = key.length();
357: }
358: String subKey = key.substring(0, keyIndex);
359:
360: boolean alreadyExist = false;
361: int i = 0;
362: while ((!alreadyExist) && (i < subKeys.size())) {
363: if (subKey.compareTo((String) subKeys.elementAt(i)) == 0) {
364: alreadyExist = true;
365: }
366: i++;
367: }
368:
369: if (!alreadyExist) {
370: subKeys.addElement(new String(subKey));
371: }
372: }
373: }
374: return (sort(subKeys));
375: }
376:
377: public String getFilename() {
378: return this .filename_;
379: }
380:
381: /**
382: * Sort Vector lexicalogicaly
383: * @param _tab Vector to sort
384: * @return Sorted Vector
385: */
386: static protected Vector sort(Vector _tab) {
387: Vector sortedTab = new Vector();
388: for (int i = 0; i < _tab.size(); i++) {
389: int j = 0;
390: while ((j < sortedTab.size())
391: && !StringUtil.less((String) _tab.elementAt(i),
392: (String) sortedTab.elementAt(j)))
393: j++;
394: if (j == sortedTab.size())
395: sortedTab.addElement(_tab.elementAt(i));
396: else {
397: sortedTab.insertElementAt(_tab.elementAt(i), j);
398: }
399: }
400: return (sortedTab);
401: }
402: }
|