001: /*
002: * :tabSize=8:indentSize=8:noTabs=false:
003: * :folding=explicit:collapseFolds=1:
004: *
005: * Copyright (C) 2007 Kazutoshi Satoda
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.gjt.sp.jedit;
023:
024: //{{{ Imports
025: import java.io.File;
026: import java.io.IOException;
027: import java.io.FileOutputStream;
028: import java.io.FileInputStream;
029: import java.io.BufferedWriter;
030: import java.io.OutputStreamWriter;
031:
032: import org.xml.sax.helpers.DefaultHandler;
033:
034: import org.gjt.sp.util.XMLUtilities;
035:
036: //}}}
037:
038: /**
039: * A XML file in the settings directory.
040: * This class provides some common operations to load/save settings
041: * from/into a XML file.
042: * - Proper encoding and XML declaration.
043: * - Two stage save.
044: * - Making backup on each save.
045: * - Detection of change on disk.
046: */
047: class SettingsXML {
048: //{{{ Saver class
049: /**
050: * A Writer to write XML for saving.
051: * The real settings file is not changed until the finish()
052: * method succeeds, in which case the previous settings file is
053: * backuped.
054: */
055: public class Saver extends BufferedWriter {
056: //{{{ writeXMLDeclaration() method
057: /**
058: * Write the XML 1.0 declaration.
059: * This should be the first output.
060: */
061: public void writeXMLDeclaration() throws IOException {
062: writeXMLDeclaration("1.0");
063: } //}}}
064:
065: //{{{ writeXMLDeclaration() method
066: /**
067: * Write the XML declaration of a specific version.
068: * This should be the first output.
069: */
070: public void writeXMLDeclaration(String version)
071: throws IOException {
072: write("<?xml" + " version=\"" + version + "\""
073: + " encoding=\"" + encoding + "\"" + " ?>");
074: newLine();
075: } //}}}
076:
077: //{{{ finish() method
078: /**
079: * Perform the final step of saving.
080: */
081: public void finish() throws IOException {
082: close();
083: jEdit.backupSettingsFile(file);
084: file.delete();
085: twoStageSaveFile.renameTo(file);
086: knownLastModified = file.lastModified();
087: } //}}}
088:
089: //{{{ Private members
090: private File twoStageSaveFile;
091: private static final String encoding = "UTF-8";
092:
093: // Only used by SettingsXML#opneSaver().
094: Saver() throws IOException {
095: this (new File(file.getParentFile(), "#" + file.getName()
096: + "#save#"));
097: }
098:
099: // A workaround for a restriction of super().
100: private Saver(File twoStageSaveFile) throws IOException {
101: super (new OutputStreamWriter(new FileOutputStream(
102: twoStageSaveFile), encoding));
103: this .twoStageSaveFile = twoStageSaveFile;
104: }
105:
106: //}}}
107: } //}}}
108:
109: //{{{ Constructor
110: /**
111: * Construct a SettingsXML with specific location and name.
112: * @param settingsDirectory
113: * The settings directory of jedit
114: * @param name
115: * The file name will be (name + ".xml")
116: */
117: public SettingsXML(String settingsDirectory, String name) {
118: String filename = name + ".xml";
119: file = new File(MiscUtilities.constructPath(settingsDirectory,
120: filename));
121: } //}}}
122:
123: //{{{ fileExits() method
124: /**
125: * Returns true if the file exists.
126: */
127: public boolean fileExists() {
128: return file.exists();
129: } //}}}
130:
131: //{{{ load() method
132: /**
133: * Parse the XML file to load.
134: * @param handler
135: * The handler to receive SAX notifications.
136: */
137: public void load(DefaultHandler handler) throws IOException {
138: XMLUtilities.parseXML(new FileInputStream(file), handler);
139: knownLastModified = file.lastModified();
140: } //}}}
141:
142: //{{{ openSaver() method
143: /**
144: * Open the file to save in XML.
145: */
146: public Saver openSaver() throws IOException {
147: return new Saver();
148: } //}}}
149:
150: //{{{ hasChangedOnDisk() method
151: /**
152: * Returns true if the file has been changed on disk.
153: * This is based on the last modified time at the last saving
154: * or loading.
155: */
156: public boolean hasChangedOnDisk() {
157: return file.exists()
158: && (file.lastModified() != knownLastModified);
159: } //}}}
160:
161: //{{{ toString() method
162: /**
163: * Returns the file's path.
164: */
165: public String toString() {
166: return file.toString();
167: } //}}}
168:
169: //{{{ Private members
170: private File file;
171: private long knownLastModified;
172: //}}}
173: }
|