001: /*
002: * JBoss, Home of Professional Open Source
003: * Copyright 2005, JBoss Inc., and individual contributors as indicated
004: * by the @authors tag. See the copyright.txt in the distribution for a
005: * full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software 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 GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jbpm.configuration;
023:
024: import java.io.InputStream;
025: import java.io.Serializable;
026: import java.lang.reflect.Constructor;
027: import java.util.ArrayList;
028: import java.util.HashMap;
029: import java.util.List;
030: import java.util.Map;
031:
032: import org.jbpm.JbpmException;
033: import org.jbpm.util.XmlUtil;
034: import org.w3c.dom.Element;
035:
036: public class ObjectFactoryParser implements Serializable {
037:
038: private static final long serialVersionUID = 1L;
039:
040: static Map defaultMappings = null;
041:
042: public static Map getDefaultMappings() {
043: if (defaultMappings == null) {
044: defaultMappings = new HashMap();
045: addMapping(defaultMappings, "bean", BeanInfo.class);
046: addMapping(defaultMappings, "ref", RefInfo.class);
047: addMapping(defaultMappings, "list", ListInfo.class);
048: addMapping(defaultMappings, "map", MapInfo.class);
049: addMapping(defaultMappings, "string", StringInfo.class);
050: addMapping(defaultMappings, "int", IntegerInfo.class);
051: addMapping(defaultMappings, "integer", IntegerInfo.class);
052: addMapping(defaultMappings, "long", LongInfo.class);
053: addMapping(defaultMappings, "float", FloatInfo.class);
054: addMapping(defaultMappings, "double", DoubleInfo.class);
055: addMapping(defaultMappings, "char", CharacterInfo.class);
056: addMapping(defaultMappings, "character",
057: CharacterInfo.class);
058: addMapping(defaultMappings, "boolean", BooleanInfo.class);
059: addMapping(defaultMappings, "true", BooleanInfo.class);
060: addMapping(defaultMappings, "false", BooleanInfo.class);
061: addMapping(defaultMappings, "null", NullInfo.class);
062: addMapping(defaultMappings, "jbpm-context",
063: JbpmContextInfo.class);
064: addMapping(defaultMappings, "jbpm-type",
065: JbpmTypeObjectInfo.class);
066: }
067: return defaultMappings;
068: }
069:
070: static final Class[] constructorParameterTypes = new Class[] {
071: Element.class, ObjectFactoryParser.class };
072:
073: static void addMapping(Map mappings, String elementTagName,
074: Class objectInfoClass) {
075: try {
076: Constructor constructor = objectInfoClass
077: .getDeclaredConstructor(constructorParameterTypes);
078: mappings.put(elementTagName, constructor);
079: } catch (Exception e) {
080: throw new JbpmException(
081: "couldn't add mapping for element '"
082: + elementTagName + "': constructor("
083: + Element.class.getName() + ","
084: + ObjectFactoryParser.class.getName()
085: + ") was missing for class '"
086: + objectInfoClass.getName() + "'", e);
087: }
088: }
089:
090: public static ObjectFactoryImpl parseXmlString(String xml) {
091: Element rootElement = XmlUtil.parseXmlText(xml)
092: .getDocumentElement();
093: return createObjectFactory(rootElement);
094: }
095:
096: public static ObjectFactoryImpl parseInputStream(
097: InputStream xmlInputStream) {
098: Element rootElement = XmlUtil.parseXmlInputStream(
099: xmlInputStream).getDocumentElement();
100: return createObjectFactory(rootElement);
101: }
102:
103: public static ObjectFactoryImpl parseResource(String resource) {
104: Element rootElement = XmlUtil.parseXmlResource(resource)
105: .getDocumentElement();
106: return createObjectFactory(rootElement);
107: }
108:
109: public static ObjectFactoryImpl createObjectFactory(
110: Element rootElement) {
111: ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
112: List objectInfos = new ArrayList();
113: List topLevelElements = XmlUtil.elements(rootElement);
114: for (int i = 0; i < topLevelElements.size(); i++) {
115: Element topLevelElement = (Element) topLevelElements.get(i);
116: ObjectInfo objectInfo = objectFactoryParser
117: .parse(topLevelElement);
118: objectInfos.add(objectInfo);
119: }
120: return new ObjectFactoryImpl(
121: objectFactoryParser.namedObjectInfos, objectInfos);
122: }
123:
124: public void parseElementsFromResource(String resource,
125: ObjectFactoryImpl objectFactoryImpl) {
126: Element rootElement = XmlUtil.parseXmlResource(resource)
127: .getDocumentElement();
128: parseElements(rootElement, objectFactoryImpl);
129: }
130:
131: public void parseElementsStream(InputStream inputStream,
132: ObjectFactoryImpl objectFactoryImpl) {
133: Element rootElement = XmlUtil.parseXmlInputStream(inputStream)
134: .getDocumentElement();
135: parseElements(rootElement, objectFactoryImpl);
136: }
137:
138: public void parseElements(Element element,
139: ObjectFactoryImpl objectFactoryImpl) {
140: List objectInfoElements = XmlUtil.elements(element);
141: for (int i = 0; i < objectInfoElements.size(); i++) {
142: Element objectInfoElement = (Element) objectInfoElements
143: .get(i);
144: ObjectInfo objectInfo = parse(objectInfoElement);
145: objectFactoryImpl.addObjectInfo(objectInfo);
146: }
147: }
148:
149: Map mappings = null;
150: Map namedObjectInfos = null;
151:
152: public ObjectFactoryParser() {
153: this (getDefaultMappings());
154: }
155:
156: public ObjectFactoryParser(Map mappings) {
157: this .mappings = mappings;
158: this .namedObjectInfos = new HashMap();
159: }
160:
161: public ObjectInfo parse(Element element) {
162: ObjectInfo objectInfo = null;
163: String elementTagName = element.getTagName().toLowerCase();
164: Constructor constructor = (Constructor) mappings
165: .get(elementTagName);
166: if (constructor == null) {
167: throw new JbpmException(
168: "no ObjectInfo class specified for element '"
169: + elementTagName + "'");
170: }
171: try {
172: objectInfo = (ObjectInfo) constructor
173: .newInstance(new Object[] { element, this });
174: } catch (Exception e) {
175: throw new JbpmException("couldn't parse '" + elementTagName
176: + "' into a '"
177: + constructor.getDeclaringClass().getName() + "': "
178: + XmlUtil.toString(element), e);
179: }
180: return objectInfo;
181: }
182:
183: public void addNamedObjectInfo(String name, ObjectInfo objectInfo) {
184: namedObjectInfos.put(name, objectInfo);
185: }
186:
187: public void addMapping(String elementName, Class objectInfoClass) {
188: if (mappings == getDefaultMappings()) {
189: mappings = new HashMap(getDefaultMappings());
190: }
191: addMapping(mappings, elementName, objectInfoClass);
192: }
193: }
|