001: /* CVS ID: $Id: XMLUserModel.java,v 1.1.1.1 2002/10/02 18:42:55 wastl Exp $ */
002: package net.wastl.webmail.xml;
003:
004: import java.util.*;
005:
006: import org.w3c.dom.*;
007: import javax.xml.parsers.ParserConfigurationException;
008:
009: import net.wastl.webmail.server.*;
010: import net.wastl.webmail.exceptions.*;
011:
012: /*
013: * XMLUserModel.java
014: *
015: * Created: Tue Mar 21 15:08:18 2000
016: *
017: * Copyright (C) 2000 Sebastian Schaffert
018: *
019: * This program is free software; you can redistribute it and/or
020: * modify it under the terms of the GNU General Public License
021: * as published by the Free Software Foundation; either version 2
022: * of the License, or (at your option) any later version.
023: *
024: * This program is distributed in the hope that it will be useful,
025: * but WITHOUT ANY WARRANTY; without even the implied warranty of
026: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
027: * GNU General Public License for more details.
028: *
029: * You should have received a copy of the GNU General Public License
030: * along with this program; if not, write to the Free Software
031: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
032: *
033: */
034:
035: /**
036: *
037: * Mainly consists of a DOM that represents all of the data in the user's session.
038: * On subtrees, there are the SYSDATA and the USERDATA DOM trees (among other stuff like folder list,
039: * message list, etc)
040: *
041: * Many methods here are synchronized but that shouldn't hurt performance too much since the cases where several
042: * Threads access the model are rare anyway
043: *
044: * @author Sebastian Schaffert
045: * @version
046: */
047:
048: public class XMLUserModel extends XMLGenericModel {
049:
050: protected Element usermodel;
051:
052: protected Element userdata;
053:
054: public XMLUserModel(WebMailServer parent, Element rsysdata,
055: Element ruserdata) throws ParserConfigurationException {
056:
057: super (parent, rsysdata);
058:
059: usermodel = root.getDocumentElement();
060:
061: this .userdata = ruserdata;
062:
063: update();
064: }
065:
066: protected void initRoot() {
067: // Create a new usermodel from the template file
068: try {
069: root = parser.parse("file://"
070: + parent.getProperty("webmail.xml.path")
071: + System.getProperty("file.separator")
072: + "usermodel_template.xml");
073: } catch (Exception ex) {
074: System.err
075: .println("Error parsing WebMail UserModel template "
076: + ex.getMessage());
077: ex.printStackTrace();
078: }
079: }
080:
081: public synchronized void update() {
082: // Insert the sysdata and userdata objects into the usermodel tree
083: super .update();
084: try {
085: NodeList nl = root.getElementsByTagName("USERDATA");
086: usermodel.replaceChild(root.importNode(userdata, true), nl
087: .item(0));
088: } catch (ArrayIndexOutOfBoundsException ex) {
089: System.err
090: .println("The WebMail UserModel template file didn't contain a USERDATA tag.");
091: } catch (DOMException ex) {
092: System.err
093: .println("Something went wrong with the XML user model.");
094: }
095: }
096:
097: public synchronized Element createFolder(String id, String name,
098: boolean holds_folders, boolean holds_messages) {
099: Element folder = root.createElement("FOLDER");
100: folder.setAttribute("id", id);
101: folder.setAttribute("name", name);
102: folder.setAttribute("holds_folders", holds_folders + "");
103: folder.setAttribute("holds_messages", holds_messages + "");
104: return folder;
105: }
106:
107: public synchronized Element getFolder(String id) {
108: return XMLCommon.getElementByAttribute(usermodel, "FOLDER",
109: "id", id);
110: }
111:
112: public synchronized Element createMessageList() {
113: Element messagelist = root.createElement("MESSAGELIST");
114: return messagelist;
115: }
116:
117: /**
118: * Get messagelist for folder. Create if necessary.
119: */
120: public synchronized Element getMessageList(Element folder) {
121: NodeList nl = folder.getChildNodes();
122: Element messagelist = null;
123: for (int i = 0; i < nl.getLength(); i++) {
124: Element tmp = (Element) nl.item(i);
125: if (tmp.getTagName().equals("MESSAGELIST")) {
126: messagelist = tmp;
127: break;
128: }
129: }
130: if (messagelist == null) {
131: messagelist = createMessageList();
132: folder.appendChild(messagelist);
133: }
134: return messagelist;
135: }
136:
137: public synchronized void removeMessageList(Element folder) {
138: XMLCommon.genericRemoveAll(folder, "MESSAGELIST");
139: }
140:
141: /**
142: * Check whether we already fetched this message. This can save a lot of time and CPU.
143: */
144: public synchronized boolean messageCached(Element folder,
145: String msgid) {
146: NodeList nl = folder.getElementsByTagName("MESSAGE");
147: Element message = null;
148: for (int i = 0; i < nl.getLength(); i++) {
149: Element test = (Element) nl.item(i);
150: if (test.getAttribute("msgid").equals(msgid)) {
151: message = test;
152: break;
153: }
154: }
155: return message != null;
156: }
157:
158: public synchronized XMLMessage getMessage(Element folder,
159: String msgnr, String msgid) {
160: NodeList nl = folder.getElementsByTagName("MESSAGE");
161: Element message = null;
162: for (int i = 0; i < nl.getLength(); i++) {
163: Element test = (Element) nl.item(i);
164: if (test.getAttribute("msgid").equals(msgid)) {
165: message = test;
166: break;
167: }
168: }
169: if (message == null) {
170: message = root.createElement("MESSAGE");
171: message.setAttribute("msgid", msgid);
172: Element msglist = getMessageList(folder);
173: msglist.appendChild(message);
174: }
175: message.setAttribute("msgnr", msgnr);
176: return new XMLMessage(message);
177: }
178:
179: /**
180: * Return the WORK element that stores messages that are currently edited.
181: */
182: public synchronized XMLMessage getWorkMessage() {
183: NodeList nl = usermodel.getElementsByTagName("WORK");
184: Element work;
185: if (nl.getLength() > 0) {
186: work = (Element) nl.item(0);
187: } else {
188: work = root.createElement("WORK");
189: usermodel.appendChild(work);
190: }
191: nl = work.getElementsByTagName("MESSAGE");
192:
193: XMLMessage message;
194: if (nl.getLength() > 0) {
195: message = new XMLMessage((Element) nl.item(0));
196: } else {
197: message = new XMLMessage(root.createElement("MESSAGE"));
198: work.appendChild(message.getMessageElement());
199: message.setAttribute("msgnr", "0");
200: message.setAttribute("msgid", WebMailServer
201: .generateMessageID("webmailuser"));
202: XMLMessagePart multipart = message.createPart("multi");
203: multipart.createPart("text");
204: }
205: return message;
206: }
207:
208: public synchronized void clearWork() {
209: NodeList nl=usermodel.getElementsByTagName("WORK");
210: if(nl.getLength() > 0) {
211: Element work=(Element)nl.item(0);
212: NodeList nl2=work.getChildNodes();
213: Vector v=new Vector();
214: for(int i=0;i<nl2.getLength();i++) {
215: v.addElement(nl2.item(i));
216: }
217: Enumeration enum=v.elements();
218: while(enum.hasMoreElements()) {
219: work.removeChild((Node)enum.nextElement());
220: }
221: }
222: }
223:
224: /**
225: * Set the current work message (for forwarding and replying).
226: * Note that this method uses importNode, therefore the newly
227: * cloned message element is returned by this method.
228: */
229: public synchronized XMLMessage setWorkMessage(XMLMessage message) {
230: clearWork();
231: NodeList nl = usermodel.getElementsByTagName("WORK");
232: Element work;
233: if (nl.getLength() > 0) {
234: work = (Element) nl.item(0);
235: } else {
236: work = root.createElement("WORK");
237: usermodel.appendChild(work);
238: }
239:
240: Element newmessage = (Element) root.importNode(message
241: .getMessageElement(), true);
242: work.appendChild(newmessage);
243: return new XMLMessage(newmessage);
244: }
245:
246: public synchronized Element createMailhost(String name, String id,
247: String url) {
248: Element mh = root.createElement("MAILHOST_MODEL");
249: mh.setAttribute("name", name);
250: mh.setAttribute("id", id);
251: if (url != null) {
252: mh.setAttribute("url", url);
253: }
254: return mh;
255: }
256:
257: /**
258: * Add a previously created Mailhost to the DOM.
259: * The Mailhost should already contain all the subfolders.:-)
260: */
261: public synchronized void addMailhost(Element mh) {
262: String name = mh.getAttribute("name");
263: Element elem = XMLCommon.getElementByAttribute(usermodel,
264: "MAILHOST_MODEL", "name", name);
265: if (elem == null) {
266: usermodel.appendChild(mh);
267: } else {
268: usermodel.replaceChild(mh, elem);
269: }
270: }
271:
272: protected synchronized Element setCurrent(String type, String id) {
273: NodeList nl = usermodel.getElementsByTagName("CURRENT");
274: Element current = null;
275: for (int i = 0; i < nl.getLength(); i++) {
276: if (((Element) nl.item(i)).getAttribute("type")
277: .equals(type)) {
278: current = (Element) nl.item(i);
279: break;
280: }
281: }
282: if (current == null) {
283: current = root.createElement("CURRENT");
284: current.setAttribute("type", type);
285: usermodel.appendChild(current);
286: }
287: current.setAttribute("id", id);
288: return current;
289: }
290:
291: protected synchronized Element getCurrent(String type, String id) {
292: NodeList nl = usermodel.getElementsByTagName("CURRENT");
293: Element current = null;
294: for (int i = 0; i < nl.getLength(); i++) {
295: if (((Element) nl.item(i)).getAttribute("type")
296: .equals(type)) {
297: current = (Element) nl.item(i);
298: break;
299: }
300: }
301: return current;
302: }
303:
304: public Element setCurrentMessage(String id) {
305: return setCurrent("message", id);
306: }
307:
308: public Element setCurrentFolder(String id) {
309: return setCurrent("folder", id);
310: }
311:
312: public Element getCurrentMessage(String id) {
313: return getCurrent("message", id);
314: }
315:
316: public Element getCurrentFolder(String id) {
317: return getCurrent("folder", id);
318: }
319:
320: } // XMLUserModel
|