001: package org.columba.core.plugin;
002:
003: import java.io.IOException;
004: import java.io.InputStream;
005: import java.util.Enumeration;
006: import java.util.Hashtable;
007: import java.util.Iterator;
008: import java.util.List;
009: import java.util.Map;
010: import java.util.Vector;
011:
012: import org.columba.api.plugin.ExtensionHandlerMetadata;
013: import org.columba.api.plugin.ExtensionMetadata;
014: import org.columba.api.plugin.PluginMetadata;
015: import org.jdom.Attribute;
016: import org.jdom.Document;
017: import org.jdom.Element;
018: import org.jdom.JDOMException;
019: import org.jdom.input.SAXBuilder;
020:
021: /**
022: * Convenience methods for parsing the various xml-file resources.
023: *
024: * @author Frederik Dietzs
025: */
026: public class ExtensionXMLParser {
027:
028: private static final String XML_ELEMENT_EXTENSION = "extension";
029:
030: private static final String XML_ELEMENT_EXTENSIONLIST = "extensionlist";
031:
032: private static final String XML_ATTRIBUTE_DESCRIPTION = "description";
033:
034: private static final String XML_ATTRIBUTE_CATEGORY = "category";
035:
036: private static final String XML_ATTRIBUTE_VERSION = "version";
037:
038: private static final String XML_ATTRIBUTE_NAME = "name";
039:
040: private static final String XML_ELEMENT_HANDLERLIST = "handlerlist";
041:
042: private static final String XML_ATTRIBUTE_SINGLETON = "singleton";
043:
044: private static final String XML_ATTRIBUTE_ENABLED = "enabled";
045:
046: private static final String XML_ATTRIBUTE_CLASS = "class";
047:
048: private static final String XML_ATTRIBUTE_PARENT = "parent";
049:
050: private static final String XML_ATTRIBUTE_ID = "id";
051:
052: private static final String XML_ELEMENT_PROPERTIES = "properties";
053:
054: private static final java.util.logging.Logger LOG = java.util.logging.Logger
055: .getLogger("org.columba.core.plugin");
056:
057: /**
058: * Parse IExtension enumeration metadata from xml file.
059: *
060: * @param is
061: * inputstream of xml extension file
062: * @param pluginMetadata
063: * can be <code>null</code>, in case of internal plugin
064: * @param internal
065: * true, if internal, False, otherwise.
066: * @return enumeration of <code>Extension</code>
067: */
068: public Enumeration loadExtensionsFromStream(InputStream is,
069: PluginMetadata pluginMetadata, boolean internal) {
070: Vector<Extension> vector = new Vector<Extension>();
071:
072: Document doc = retrieveDocument(is);
073:
074: Element parent = doc.getRootElement();
075:
076: if (parent == null
077: || !parent.getName().equals(XML_ELEMENT_EXTENSIONLIST)) {
078: LOG.severe("missing <extensionlist> element");
079: return null;
080: }
081:
082: Iterator iterator = parent.getChildren().listIterator();
083: Element extensionXmlElement;
084:
085: while (iterator.hasNext()) {
086: extensionXmlElement = (Element) iterator.next();
087:
088: ExtensionMetadata metadata = parseExtensionMetadata(extensionXmlElement);
089:
090: if (internal == true)
091: vector.add(new Extension(metadata, internal));
092: else
093: vector.add(new Extension(pluginMetadata, metadata));
094:
095: }
096:
097: return vector.elements();
098: }
099:
100: /**
101: * Parse extension metadata.
102: *
103: * @param extensionXmlElement
104: * @return
105: */
106: public ExtensionMetadata parseExtensionMetadata(
107: Element extensionXmlElement) {
108: String id = extensionXmlElement
109: .getAttributeValue(XML_ATTRIBUTE_ID);
110: if (id == null) {
111: LOG.severe("missing attribute \"id\"");
112: return null;
113: }
114:
115: String clazz = extensionXmlElement.getAttributeValue("class");
116: if (clazz == null) {
117: LOG.severe("missing attribute \"class\"");
118: return null;
119: }
120:
121: String enabledString = extensionXmlElement
122: .getAttributeValue(XML_ATTRIBUTE_ENABLED);
123: String singletonString = extensionXmlElement
124: .getAttributeValue(XML_ATTRIBUTE_SINGLETON);
125:
126: Element attributesElement = extensionXmlElement
127: .getChild(XML_ELEMENT_PROPERTIES);
128: Map<String, String> attributes = new Hashtable<String, String>();
129: if (attributesElement != null) {
130: List list = attributesElement.getAttributes();
131: for (int i = 0; i < list.size(); i++) {
132: Attribute a = (Attribute) list.get(i);
133: attributes.put(a.getName(), a.getValue());
134: }
135: }
136:
137: ExtensionMetadata metadata = null;
138: if (attributes != null)
139: metadata = new ExtensionMetadata(id, clazz, attributes);
140: else
141: metadata = new ExtensionMetadata(id, clazz);
142:
143: if (enabledString != null)
144: metadata.setEnabled(new Boolean(enabledString)
145: .booleanValue());
146:
147: if (singletonString != null)
148: metadata.setSingleton(new Boolean(singletonString)
149: .booleanValue());
150:
151: return metadata;
152: }
153:
154: /**
155: * Parse plugin metadata.
156: *
157: * @param pluginElement
158: * @return
159: */
160: public PluginMetadata parsePluginMetadata(Element pluginElement) {
161:
162: String id = pluginElement.getAttributeValue(XML_ATTRIBUTE_ID);
163: String name = pluginElement
164: .getAttributeValue(XML_ATTRIBUTE_NAME);
165: String version = pluginElement
166: .getAttributeValue(XML_ATTRIBUTE_VERSION);
167: String enabled = pluginElement
168: .getAttributeValue(XML_ATTRIBUTE_ENABLED);
169: String category = pluginElement
170: .getAttributeValue(XML_ATTRIBUTE_CATEGORY);
171: String description = pluginElement
172: .getAttributeValue(XML_ATTRIBUTE_DESCRIPTION);
173:
174: PluginMetadata pluginMetadata = new PluginMetadata(id, name,
175: description, version, category, new Boolean(enabled)
176: .booleanValue());
177:
178: return pluginMetadata;
179: }
180:
181: /**
182: * @param vector
183: * @param xmlFile
184: * @return
185: */
186: public Enumeration<ExtensionHandlerMetadata> parseExtensionHandlerList(
187: InputStream is) {
188: Vector<ExtensionHandlerMetadata> vector = new Vector<ExtensionHandlerMetadata>();
189:
190: Document doc = retrieveDocument(is);
191:
192: Element list = doc.getRootElement();
193: if (list == null
194: || !list.getName().equals(XML_ELEMENT_HANDLERLIST)) {
195: LOG.severe("element <handlerlist> expected.");
196: return vector.elements();
197: }
198:
199: Iterator it = list.getChildren().listIterator();
200: while (it.hasNext()) {
201: Element child = (Element) it.next();
202: // skip non-matching elements
203: if (child.getName().equals("handler") == false)
204: continue;
205: String id = child.getAttributeValue(XML_ATTRIBUTE_ID);
206: String parent = child
207: .getAttributeValue(XML_ATTRIBUTE_PARENT);
208:
209: ExtensionHandlerMetadata metadata = new ExtensionHandlerMetadata(
210: id, parent);
211:
212: vector.add(metadata);
213: }
214:
215: return vector.elements();
216: }
217:
218: /**
219: * "plugin.xml" file parse.
220: *
221: * @param is inputstream of "plugin.xml" file
222: * @param hashtable
223: * hashtable will be filled with Vector of all extensions
224: * @return plugin metadata
225: */
226: public PluginMetadata parsePlugin(InputStream is,
227: Hashtable hashtable) {
228: Document doc = retrieveDocument(is);
229:
230: Element pluginElement = doc.getRootElement();
231:
232: PluginMetadata pluginMetadata = new ExtensionXMLParser()
233: .parsePluginMetadata(pluginElement);
234:
235: // loop through all extensions this plugin uses
236: Iterator it = pluginElement.getChildren().listIterator();
237: while (it.hasNext()) {
238: Element extensionListXmlElement = (Element) it.next();
239:
240: // skip if no <extensionlist> element found
241: if (extensionListXmlElement.getName().equals(
242: XML_ELEMENT_EXTENSIONLIST) == false)
243: continue;
244:
245: String extensionpointId = extensionListXmlElement
246: .getAttributeValue(XML_ATTRIBUTE_ID);
247: if (extensionpointId == null) {
248: LOG.severe("missing extension point id attribute");
249: continue;
250: }
251:
252: Vector<ExtensionMetadata> vector = new Vector<ExtensionMetadata>();
253:
254: Iterator it2 = extensionListXmlElement.getChildren()
255: .listIterator();
256: while (it2.hasNext()) {
257: Element extensionXmlElement = (Element) it2.next();
258:
259: // skip if no <extension> element found
260: if (extensionXmlElement.getName().equals(
261: XML_ELEMENT_EXTENSION) == false)
262: continue;
263:
264: ExtensionMetadata extensionMetadata = new ExtensionXMLParser()
265: .parseExtensionMetadata(extensionXmlElement);
266:
267: vector.add(extensionMetadata);
268:
269: }
270:
271: hashtable.put(extensionpointId, vector);
272: }
273:
274: return pluginMetadata;
275: }
276:
277: // retrieve JDom Document from inputstream
278: private static Document retrieveDocument(InputStream is) {
279: SAXBuilder builder = new SAXBuilder();
280: builder.setIgnoringElementContentWhitespace(true);
281: Document doc = null;
282: try {
283: doc = builder.build(is);
284: } catch (JDOMException e) {
285: LOG.severe(e.getMessage());
286: e.printStackTrace();
287: } catch (IOException e) {
288: LOG.severe(e.getMessage());
289: e.printStackTrace();
290: }
291: return doc;
292: }
293: }
|