001: /*
002: * MailboxProperties.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: MailboxProperties.java,v 1.4 2003/06/25 18:36:45 piso Exp $
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 (at your option) 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.armedbear.j.mail;
023:
024: import java.io.BufferedWriter;
025: import java.io.IOException;
026: import java.io.OutputStreamWriter;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029: import org.armedbear.j.Debug;
030: import org.armedbear.j.Directories;
031: import org.armedbear.j.Editor;
032: import org.armedbear.j.FastStringBuffer;
033: import org.armedbear.j.File;
034: import org.armedbear.j.Log;
035: import org.armedbear.j.Property;
036: import org.armedbear.j.PropertyList;
037: import org.armedbear.j.Utilities;
038: import org.xml.sax.Attributes;
039: import org.xml.sax.ContentHandler;
040: import org.xml.sax.InputSource;
041: import org.xml.sax.SAXException;
042: import org.xml.sax.XMLReader;
043: import org.xml.sax.helpers.DefaultHandler;
044:
045: public final class MailboxProperties {
046: private static final int MAX_ENTRIES = 100;
047:
048: private static final String lineSeparator = System
049: .getProperty("line.separator");
050:
051: private static ArrayList list;
052:
053: private MailboxProperties() {
054: }
055:
056: public static synchronized PropertyList getProperties(MailboxURL url) {
057: if (list == null)
058: initialize();
059: String name = url.getCanonicalName();
060: for (int i = list.size() - 1; i >= 0; i--) {
061: Entry entry = (Entry) list.get(i);
062: if (entry.name.equals(name))
063: return entry.properties;
064: }
065: return null;
066: }
067:
068: public static synchronized void saveProperties(Mailbox mb) {
069: MailboxURL url = mb.getUrl();
070: if (url == null) {
071: Debug.bug();
072: return;
073: }
074: String name = url.getCanonicalName();
075: if (name == null) {
076: Debug.bug();
077: return;
078: }
079: if (name.length() == 0) {
080: Debug.bug();
081: return;
082: }
083: PropertyList properties = mb.getProperties();
084: if (properties == null || properties.size() == 0) {
085: Log
086: .debug("MailboxProperties.saveProperties no properties set");
087: return;
088: }
089: if (list == null)
090: initialize();
091: Entry newEntry = new Entry(name, properties);
092: final int limit = list.size();
093: for (int i = 0; i < limit; i++) {
094: Entry entry = (Entry) list.get(i);
095: if (entry.name.equals(name)) {
096: if (i == 0) {
097: list.set(0, newEntry);
098: save();
099: return;
100: }
101: list.remove(i);
102: break;
103: }
104: }
105: // Add new entry.
106: list.add(0, newEntry);
107: save();
108: }
109:
110: private static synchronized void initialize() {
111: if (list == null) {
112: Editor.protect(MailboxProperties.class);
113: list = new ArrayList();
114: File file = getFile();
115: if (file.isFile()) {
116: XMLReader xmlReader = Utilities.getDefaultXMLReader();
117: if (xmlReader != null) {
118: try {
119: xmlReader.setContentHandler(new Handler());
120: InputSource inputSource = new InputSource(file
121: .getInputStream());
122: xmlReader.parse(inputSource);
123: } catch (Exception e) {
124: Log.error(e);
125: }
126: }
127: }
128: // Delete old mailboxes.xml in ~/.j (if any).
129: File oldFile = File.getInstance(Directories
130: .getEditorDirectory(), "mailboxes.xml");
131: if (oldFile != null && oldFile.isFile())
132: oldFile.delete();
133: }
134: }
135:
136: private static void add(Entry entry) {
137: list.add(entry);
138: }
139:
140: private static synchronized void save() {
141: try {
142: File file = getFile();
143: BufferedWriter writer = new BufferedWriter(
144: new OutputStreamWriter(file.getOutputStream()));
145: writer.write("<?xml version=\"1.0\"?>");
146: writer.newLine();
147: writer
148: .write("<mailboxes version=\"" + getVersion()
149: + "\">");
150: writer.newLine();
151: final int limit = Math.min(list.size(), MAX_ENTRIES);
152: for (int i = 0; i < limit; i++) {
153: Entry entry = (Entry) list.get(i);
154: writer.write(entry.toXml());
155: writer.newLine();
156: }
157: writer.write("</mailboxes>");
158: writer.flush();
159: writer.close();
160: } catch (IOException e) {
161: Log.error(e);
162: }
163: }
164:
165: private static final File getFile() {
166: return File.getInstance(Directories.getMailDirectory(),
167: "mailboxes.xml");
168: }
169:
170: private static final String getVersion() {
171: return "1";
172: }
173:
174: private static class Entry {
175: final String name;
176: final PropertyList properties;
177: long when;
178:
179: Entry(String name, PropertyList properties) {
180: this .name = name;
181: this .properties = properties;
182: when = System.currentTimeMillis();
183: }
184:
185: Entry(String name) {
186: this .name = name;
187: properties = new PropertyList();
188: }
189:
190: String toXml() {
191: FastStringBuffer sb = new FastStringBuffer(
192: " <mailbox name=\"");
193: sb.append(name);
194: sb.append("\"");
195: sb.append(" when=\"");
196: sb.append(String.valueOf(when));
197: sb.append("\"");
198: sb.append(">");
199: sb.append(lineSeparator);
200: if (properties != null) {
201: Iterator it = properties.keyIterator();
202: if (it != null) {
203: while (it.hasNext()) {
204: Property property = (Property) it.next();
205: Object value = properties.getProperty(property);
206: if (value != null) {
207: sb
208: .append(propertyToXml(property
209: .getDisplayName(), value
210: .toString()));
211: }
212: }
213: }
214: }
215: sb.append(" </mailbox>");
216: return sb.toString();
217: }
218:
219: private static String propertyToXml(String name, String value) {
220: FastStringBuffer sb = new FastStringBuffer(
221: " <property name=\"");
222: sb.append(name);
223: sb.append("\" value=\"");
224: sb.append(value);
225: sb.append("\"/>");
226: sb.append(lineSeparator);
227: return new String(sb.toString());
228: }
229: }
230:
231: private static class Handler extends DefaultHandler implements
232: ContentHandler {
233: private Entry currentEntry = null;
234:
235: public void startElement(String uri, String localName,
236: String qName, Attributes attributes)
237: throws SAXException {
238: if (localName.equals("mailboxes")
239: || qName.equals("mailboxes")) {
240: String version = attributes.getValue("version");
241: if (!version.equals(MailboxProperties.getVersion()))
242: throw new SAXException(
243: "Unknown mailbox history format");
244: } else if (localName.equals("mailbox")
245: || qName.equals("mailbox")) {
246: // Start a new entry.
247: String mailboxName = attributes.getValue("name");
248: currentEntry = new Entry(mailboxName);
249: try {
250: currentEntry.when = Long.parseLong(attributes
251: .getValue("when"));
252: } catch (NumberFormatException e) {
253: Log.error(e);
254: }
255: } else if (localName.equals("property")
256: || qName.equals("property")) {
257: Debug.assertTrue(currentEntry != null);
258: String key = attributes.getValue("name");
259: if (key != null) {
260: String value = attributes.getValue("value");
261: if (value != null) {
262: Property property = Property.findProperty(key);
263: if (property != null)
264: currentEntry.properties
265: .setPropertyFromString(property,
266: value);
267: }
268: }
269: }
270: }
271:
272: public void endElement(String uri, String localName,
273: String qName) {
274: if (localName.equals("mailbox") || qName.equals("mailbox")) {
275: MailboxProperties.add(currentEntry);
276: currentEntry = null;
277: }
278: }
279: }
280: }
|