Source code: org/mrbook/mrpostman/gui/ModuleOptionGuiParser.java
1 /*
2 * -*- mode: java; c-basic-indent: 4; indent-tabs-mode: nil -*-
3 * :indentSize=4:noTabs=true:tabSize=4:indentOnTab=true:indentOnEnter=true:mode=java:
4 * ex: set tabstop=4 expandtab:
5 *
6 * MrPostman - webmail <-> email gateway
7 * Copyright (C) 2002-2003 MrPostman Development Group
8 * Projectpage: http://mrbook.org/mrpostman/
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 * In particular, this implies that users are responsible for
21 * using MrPostman after reading the terms and conditions given
22 * by their web-mail provider.
23 *
24 * You should have received a copy of the GNU General Public License
25 * Named LICENSE in the base directory of this distribution,
26 * if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */
29
30 package org.mrbook.mrpostman.gui;
31
32 import org.mrbook.mrpostman.gui.config.Input;
33
34 //Application specific imports...
35 import org.mrbook.mrpostman.gui.config.Module;
36 import org.mrbook.mrpostman.gui.config.ModuleOption;
37
38 import org.w3c.dom.Document;
39
40 import org.xml.sax.SAXException;
41 import org.xml.sax.SAXParseException;
42
43 import java.io.ByteArrayOutputStream;
44 import java.io.IOException;
45
46 //General imports...
47 import java.io.InputStream;
48 import java.io.PrintWriter;
49
50 import java.util.HashMap;
51 import java.util.logging.Level;
52 //Logging imports...
53 import java.util.logging.Logger;
54
55 import javax.xml.parsers.DocumentBuilder;
56 //XML imports...
57 import javax.xml.parsers.DocumentBuilderFactory;
58 import javax.xml.parsers.ParserConfigurationException;
59
60
61 /**
62 * A Utility class capable of parsing the module option gui configuration XML file
63 * and returning the data objects.
64 * Creation date: (16/01/2003 7:05:41 PM)
65 * @author: Chris Humphreys
66 */
67 public class ModuleOptionGuiParser {
68 public static final String CVSID = "$Id: ModuleOptionGuiParser.java,v 1.5 2003/02/09 23:38:14 lbruand Exp $";
69
70 /**
71 * The <code>Log</code> instance for this application.
72 */
73 private static Logger logger = Logger.getLogger("org.mrbook.mrpostman.MrPostman");
74
75 /**
76 * ModuleOptionGuiParser constructor comment.
77 */
78 public ModuleOptionGuiParser() {
79 super();
80 }
81
82 /**
83 * Parse the XML input stream and return the
84 * populated data model.
85 * Creation date: (22/07/2002 7:08:37 PM)
86 */
87 public HashMap parse(InputStream input) throws ModuleOptionGuiConfigException {
88 // This object will contain the parsed contents of the xml input...
89 HashMap modules = new HashMap();
90
91 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
92
93 try {
94 DocumentBuilder builder = factory.newDocumentBuilder();
95 Document document = builder.parse(input);
96
97 org.w3c.dom.Node root = document.getFirstChild();
98
99 if (!root.getNodeName().equals("module-options")) {
100 throw new ModuleOptionGuiConfigException("Invalid XML file (expecting root='module-options')");
101 }
102 org.w3c.dom.Node entry = null;
103
104 entry = root.getFirstChild();
105
106 while (entry != null) {
107 if (entry.getNodeName().equals("module")) {
108 Module module = parseModule(entry);
109 modules.put(module.getId(), module);
110 }
111 entry = entry.getNextSibling();
112 }
113
114 return modules;
115 } catch (SAXParseException spe) {
116 // Error generated by the parser
117 logger.log(Level.SEVERE, "Parsing error" + ", line " + spe.getLineNumber() + ", uri " + spe.getSystemId());
118 logger.log(Level.SEVERE, " " + spe.getMessage());
119 // Use the contained exception, if any
120 Exception x = spe;
121
122 if (spe.getException() != null) {
123 x = spe.getException();
124 }
125 ByteArrayOutputStream bos = new ByteArrayOutputStream();
126 x.printStackTrace(new PrintWriter(bos, true));
127 logger.log(Level.SEVERE, bos.toString());
128 throw new ModuleOptionGuiConfigException("Error parsing module option gui config (" + spe.getMessage()
129 + ")");
130 } catch (SAXException sxe) {
131 // Error generated by this application
132 // (or a parser-initialization error)
133 Exception x = sxe;
134
135 if (sxe.getException() != null) {
136 x = sxe.getException();
137 }
138 ByteArrayOutputStream bos = new ByteArrayOutputStream();
139 x.printStackTrace(new PrintWriter(bos, true));
140 logger.log(Level.SEVERE, bos.toString());
141 throw new ModuleOptionGuiConfigException("Error parsing module option gui config (" + sxe.getMessage()
142 + ")");
143 } catch (ParserConfigurationException pce) {
144 // Parser with specified options can't be built
145 ByteArrayOutputStream bos = new ByteArrayOutputStream();
146 pce.printStackTrace(new PrintWriter(bos, true));
147 logger.log(Level.SEVERE, bos.toString());
148 throw new ModuleOptionGuiConfigException("Error parsing module option gui config (" + pce.getMessage()
149 + ")");
150 } catch (IOException ioe) {
151 // I/O error
152 ByteArrayOutputStream bos = new ByteArrayOutputStream();
153 ioe.printStackTrace(new PrintWriter(bos, true));
154 logger.log(Level.SEVERE, bos.toString());
155 throw new ModuleOptionGuiConfigException("Error parsing module option gui config (" + ioe.getMessage()
156 + ")");
157 }
158 }
159
160 /**
161 * Parse the <code>module</code> sub branch of the DOM
162 * and return an Module object
163 * @param moduleNode org.w3c.dom.Node
164 */
165 protected Module parseModule(org.w3c.dom.Node moduleNode) {
166 Module module = new Module();
167
168 //set the id attribute...
169 module.setId(getAttributeValue(moduleNode, "id"));
170
171 org.w3c.dom.Node entry = null;
172 entry = moduleNode.getFirstChild();
173
174 while (entry != null) {
175 if (entry.getNodeName().equals("module-option")) {
176 module.addOption(parseModuleOption(entry));
177 }
178 entry = entry.getNextSibling();
179 }
180
181 return module;
182 }
183
184 /**
185 * Parse the <code>module-option</code> sub branch of the DOM
186 * and return an ModuleOption object.
187 * @param node org.w3c.dom.Node
188 */
189 protected ModuleOption parseModuleOption(org.w3c.dom.Node node) {
190 ModuleOption moduleOption = new ModuleOption();
191
192 //set the id attribute...
193 moduleOption.setId(getAttributeValue(node, "id"));
194
195 org.w3c.dom.Node entry = null;
196 entry = node.getFirstChild();
197
198 //For now this configuration file only contains the application-types nodes
199 // so we'll loop till we find that...
200 while (entry != null) {
201 if (entry.getNodeName().equals("label")) {
202 moduleOption.setLabel(entry.getFirstChild().getNodeValue());
203 } else if (entry.getNodeName().equals("desc")) {
204 moduleOption.setDesc(entry.getFirstChild().getNodeValue());
205 } else if (entry.getNodeName().equals("input")) {
206 moduleOption.setInput(parseInput(entry));
207 }
208 entry = entry.getNextSibling();
209 }
210
211 return moduleOption;
212 }
213
214 /**
215 * Parse the <code>module-option/input</code> sub branch of the DOM
216 * and return an Input object.
217 * @param node org.w3c.dom.Node
218 */
219 protected Input parseInput(org.w3c.dom.Node node) {
220 Input input = new Input();
221
222 //set the id attribute...
223 input.setType(getAttributeValue(node, "type"));
224
225 return input;
226 }
227
228 /**
229 * Helper method to return the string representation of a node's named attribute (if found)
230 * returns null if not found.
231 */
232 protected String getAttributeValue(org.w3c.dom.Node node, String attributeName) {
233 org.w3c.dom.NamedNodeMap namedNodeMap = node.getAttributes();
234 org.w3c.dom.Node attribute = namedNodeMap.getNamedItem(attributeName);
235
236 if (attribute != null) {
237 return attribute.getNodeValue();
238 } else {
239 return null;
240 }
241 }
242 }