001: // kelondroXMLTables.java
002: // -------------------------
003: // part of The Kelondro Database
004: // (C) by Michael Peter Christen; mc@anomic.de
005: // first published on http://www.anomic.de
006: // Frankfurt, Germany, 2006
007: // created 09.02.2006
008: //
009: // $LastChangedDate: 2008-01-19 00:40:19 +0000 (Sa, 19 Jan 2008) $
010: // $LastChangedRevision: 4343 $
011: // $LastChangedBy: orbiter $
012: //
013: // This program is free software; you can redistribute it and/or modify
014: // it under the terms of the GNU General Public License as published by
015: // the Free Software Foundation; either version 2 of the License, or
016: // (at your option) any later version.
017: //
018: // This program is distributed in the hope that it will be useful,
019: // but WITHOUT ANY WARRANTY; without even the implied warranty of
020: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
021: // GNU General Public License for more details.
022: //
023: // You should have received a copy of the GNU General Public License
024: // along with this program; if not, write to the Free Software
025: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
026: //
027: // Using this software in any meaning (reading, learning, copying, compiling,
028: // running) means that you agree that the Author(s) is (are) not responsible
029: // for cost, loss of data or any harm that may be caused directly or indirectly
030: // by usage of this softare or this documentation. The usage of this software
031: // is on your own risk. The installation and usage (starting/running) of this
032: // software may allow other people or application to access your computer and
033: // any attached devices and is highly dependent on the configuration of the
034: // software which must be done by the user of the software; the author(s) is
035: // (are) also not responsible for proper configuration and usage of the
036: // software, even if provoked by documentation provided together with
037: // the software.
038: //
039: // Any changes to this file according to the GPL as documented in the file
040: // gpl.txt aside this file in the shipment you received can be done to the
041: // lines that follows this copyright notice here, but changes must not be
042: // done inside the copyright notive above. A re-distribution must contain
043: // the intact and unchanged copyright notice.
044: // Contributions and changes to the program code must be marked as such.
045:
046: package de.anomic.kelondro;
047:
048: import java.beans.XMLDecoder;
049: import java.beans.XMLEncoder;
050: import java.io.File;
051: import java.io.FileInputStream;
052: import java.io.FileOutputStream;
053: import java.io.IOException;
054: import java.util.Enumeration;
055: import java.util.Hashtable;
056:
057: public class kelondroXMLTables {
058:
059: private Hashtable<String, Hashtable<String, String>> tables;
060:
061: // tables is a hashtable that contains hashtables as values in the table
062: private File propFile;
063: private long timestamp;
064:
065: public kelondroXMLTables() {
066: this .propFile = null;
067: this .timestamp = System.currentTimeMillis();
068: this .tables = new Hashtable<String, Hashtable<String, String>>();
069: }
070:
071: @SuppressWarnings("unchecked")
072: public kelondroXMLTables(File file) throws IOException {
073: this .propFile = file;
074: this .timestamp = System.currentTimeMillis();
075: if (propFile.exists()) {
076: XMLDecoder xmldec = new XMLDecoder(new FileInputStream(
077: propFile));
078: tables = (Hashtable<String, Hashtable<String, String>>) xmldec
079: .readObject();
080: xmldec.close();
081: } else {
082: tables = new Hashtable<String, Hashtable<String, String>>();
083: }
084: }
085:
086: public void commit(File target) throws IOException {
087: // this method is used if the Mircrotable was created without assigning
088: // a file to it as an empty table the table then becomes file-based,
089: // and write operation will be committed to the file
090: this .propFile = target;
091: commit(true);
092: }
093:
094: private void commit(boolean force) throws IOException {
095: // this function commits the data to a file
096: // it does not save the data until a specific waiting-time has been lasted
097: if ((force) || (System.currentTimeMillis() - timestamp > 10000)) {
098: // check error case: can only occur if logical programmic error
099: // exists
100: if (this .propFile == null)
101: throw new RuntimeException(
102: "Microtables.commit: no file specified");
103:
104: // write first to a temporary file
105: File tmpFile = new File(this .propFile.toString() + ".tmp");
106:
107: // write file
108: XMLEncoder xmlenc = new XMLEncoder(new FileOutputStream(
109: tmpFile));
110: xmlenc.writeObject(tables);
111: xmlenc.close();
112:
113: // delete old file and rename tmp-file to old file's name
114: this .propFile.delete();
115: tmpFile.renameTo(this .propFile);
116:
117: // set the new time stamp
118: timestamp = System.currentTimeMillis();
119: }
120: }
121:
122: public boolean hasTable(String table) {
123: return (tables.get(table) != null);
124: }
125:
126: public int sizeTable(String table) {
127: // returns number of entries in table; if table does not exist -1
128: Hashtable<String, String> l = tables.get(table);
129: if (l == null)
130: return -1;
131: return l.size();
132: }
133:
134: public void createTable(String table) throws IOException {
135: // creates a new table
136: Hashtable<String, String> l = tables.get(table);
137: if (l != null)
138: return; // we do not overwite
139: tables.put(table, new Hashtable<String, String>());
140: if (this .propFile != null)
141: commit(false);
142: }
143:
144: public void set(String table, String key, String value)
145: throws IOException {
146: if (table != null) {
147: Hashtable<String, String> l = tables.get(table);
148: if (l == null)
149: throw new RuntimeException(
150: "Microtables.set: table does not exist");
151: if (value == null)
152: value = "";
153: l.put(key, value);
154: }
155: if (this .propFile != null)
156: commit(false);
157: }
158:
159: public String get(String table, String key, String deflt) {
160: if (table != null) {
161: Hashtable<String, String> l = tables.get(table);
162: if (l == null)
163: throw new RuntimeException(
164: "Microtables.get: table does not exist");
165: if (l.containsKey(key))
166: return (String) l.get(key);
167: else
168: return deflt;
169: }
170: return null;
171: }
172:
173: public boolean has(String table, String key) {
174: if (table != null) {
175: Hashtable<String, String> l = tables.get(table);
176: if (l == null)
177: throw new RuntimeException(
178: "Microtables.has: table does not exist");
179: return (l.containsKey(key));
180: }
181: return false;
182: }
183:
184: public Enumeration<String> keys(String table) {
185: if (table != null) {
186: Hashtable<String, String> l = tables.get(table);
187: if (l == null)
188: throw new RuntimeException(
189: "Microtables.keys: table does not exist");
190: return l.keys();
191: }
192: return null;
193: }
194:
195: public void close() throws IOException {
196: finalize();
197: }
198:
199: // we finalize the operation by saving everything throug the scheduler
200: // this method is called by the java GC bevore it destroys the object
201: protected void finalize() throws IOException {
202: commit(true);
203: }
204:
205: }
|