001: package org.columba.core.config;
002:
003: import java.io.BufferedInputStream;
004: import java.io.BufferedOutputStream;
005: import java.io.File;
006: import java.io.FileInputStream;
007: import java.io.FileNotFoundException;
008: import java.io.FileOutputStream;
009: import java.io.IOException;
010: import java.io.InputStream;
011: import java.io.OutputStream;
012:
013: import org.columba.api.exception.StoreException;
014: import org.columba.api.shutdown.IShutdownManager;
015: import org.columba.core.io.DiskIO;
016: import org.columba.core.shutdown.ShutdownManager;
017: import org.jdom.Document;
018: import org.jdom.JDOMException;
019: import org.jdom.input.SAXBuilder;
020: import org.jdom.output.XMLOutputter;
021:
022: public class XmlConfig {
023:
024: private static final java.util.logging.Logger LOG = java.util.logging.Logger
025: .getLogger("org.columba.core.confignew");
026:
027: private String defaultConfig;
028:
029: private File xmlFile;
030:
031: private Document document;
032:
033: /**
034: * @param xmlFile
035: * location of xml configuration file
036: * @param defaultConfig
037: * location of default configuration file in classpath (for
038: * example: "org/columba/core/config/tags"). Can be
039: * <code>null</code>.
040: */
041: public XmlConfig(final File xmlFile, final String defaultConfig) {
042: if (xmlFile == null)
043: throw new IllegalArgumentException("xmlFile == null");
044:
045: this .defaultConfig = defaultConfig;
046: this .xmlFile = xmlFile;
047:
048: // register at shutdown manager
049: // -> this will save all configuration data, when closing Columba
050: final IShutdownManager shutdownManager = ShutdownManager
051: .getInstance();
052:
053: shutdownManager.register(new Runnable() {
054: public void run() {
055: try {
056: // callback
057: transformModelToDocument(document);
058:
059: File tmpFile = File
060: .createTempFile("tag", ".backup");
061:
062: BufferedOutputStream out = new BufferedOutputStream(
063: new FileOutputStream(tmpFile));
064:
065: saveDocument(document, out);
066:
067: // if everything worked out all right, we copy the tmp file to the destination file
068: DiskIO.copyFile(tmpFile, xmlFile);
069: } catch (final Exception e) {
070: LOG.severe(e.getMessage());
071: throw new StoreException(
072: "could not store configuration file at: "
073: + xmlFile.getAbsolutePath(), e);
074: }
075: }
076: });
077: }
078:
079: public Document load() throws StoreException {
080: if (!xmlFile.exists()) {
081: if (defaultConfig != null) {
082: // create initial version from default configuration file
083: try {
084: DiskIO
085: .copyResource(defaultConfig + ".xml",
086: xmlFile);
087: } catch (IOException e) {
088: LOG.severe(e.getMessage());
089: throw new StoreException(
090: "could not create initial configuration file at: "
091: + xmlFile.getAbsolutePath(), e);
092: }
093: } else {
094: // return plain document
095: document = new Document();
096: return document;
097: }
098:
099: }
100:
101: // load xml configuration from file
102: BufferedInputStream buf;
103: try {
104: buf = new BufferedInputStream(new FileInputStream(xmlFile));
105: } catch (FileNotFoundException e) {
106: LOG.severe(e.getMessage());
107: throw new StoreException(
108: "could not load configuration file at: "
109: + xmlFile.getAbsolutePath(), e);
110: }
111:
112: document = retrieveDocument(buf);
113:
114: return document;
115: }
116:
117: /**
118: * retrieve JDom Document from inputstream
119: */
120: private Document retrieveDocument(InputStream is)
121: throws StoreException {
122: SAXBuilder builder = new SAXBuilder();
123: builder.setIgnoringElementContentWhitespace(true);
124: Document doc = null;
125: try {
126: doc = builder.build(is);
127: } catch (JDOMException e) {
128: LOG.severe(e.getMessage());
129: throw new StoreException(
130: "could not parse configuration file at: "
131: + xmlFile.getAbsolutePath(), e);
132: } catch (IOException e) {
133: LOG.severe(e.getMessage());
134: throw new StoreException(
135: "could not parse configuration file at: "
136: + xmlFile.getAbsolutePath(), e);
137: }
138: return doc;
139: }
140:
141: /**
142: * store JDom document in outputstream
143: */
144: public void saveDocument(Document doc, OutputStream os)
145: throws StoreException {
146: try {
147: XMLOutputter outp = new XMLOutputter(" ", true);
148:
149: outp.output(doc, os);
150: } catch (IOException e) {
151: LOG.severe(e.getMessage());
152: throw new StoreException(
153: "could not store configuration file at: "
154: + xmlFile.getAbsolutePath(), e);
155: }
156: }
157:
158: /**
159: * Overwrite method in case you transformed the xml presentation to your internal
160: * domain model. Before saving the xml document this method is used to transform
161: * the domain model back to the xml presentation.
162: *
163: * @param document jdom xml document
164: */
165: protected void transformModelToDocument(Document document) {
166: }
167: }
|