001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.util.config.internal.catalog;
020:
021: import java.io.InputStream;
022: import java.io.IOException;
023: import javax.xml.parsers.DocumentBuilderFactory;
024: import javax.xml.parsers.DocumentBuilder;
025: import javax.xml.parsers.ParserConfigurationException;
026:
027: import org.apache.beehive.netui.util.config.bean.CatalogConfig;
028: import org.apache.beehive.netui.util.config.bean.CommandConfig;
029: import org.apache.beehive.netui.util.config.bean.ChainConfig;
030: import org.apache.beehive.netui.util.config.bean.CustomPropertyConfig;
031: import org.apache.beehive.netui.util.xml.DomUtils;
032: import org.apache.commons.logging.LogFactory;
033: import org.apache.commons.logging.Log;
034: import org.w3c.dom.Document;
035: import org.w3c.dom.Element;
036: import org.w3c.dom.NodeList;
037: import org.w3c.dom.Node;
038: import org.xml.sax.ErrorHandler;
039: import org.xml.sax.SAXParseException;
040: import org.xml.sax.InputSource;
041: import org.xml.sax.EntityResolver;
042: import org.xml.sax.SAXException;
043:
044: /**
045: *
046: */
047: public class CatalogParser {
048:
049: private static final Log LOG = LogFactory
050: .getLog(CatalogParser.class);
051: private static final String CONFIG_SCHEMA = "org/apache/beehive/netui/util/config/internal/catalog/catalog-config.xsd";
052: private static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
053: private static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
054: private static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
055:
056: public static CatalogParser getInstance() {
057: return new CatalogParser();
058: }
059:
060: private CatalogParser() {
061: }
062:
063: public CatalogConfig parse(Element catalogElement) {
064: return parseCatalog(catalogElement);
065: }
066:
067: public CatalogConfig parse(final String resourcePath,
068: final InputStream inputStream) {
069: CatalogConfig catalogConfig = null;
070: InputStream xmlInputStream = null;
071: InputStream xsdInputStream = null;
072: try {
073: xmlInputStream = inputStream;
074: xsdInputStream = getClass().getClassLoader()
075: .getResourceAsStream(CONFIG_SCHEMA);
076:
077: DocumentBuilderFactory dbf = DocumentBuilderFactory
078: .newInstance();
079: dbf.setValidating(true);
080: dbf.setNamespaceAware(true);
081: dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
082: dbf.setAttribute(JAXP_SCHEMA_SOURCE, xsdInputStream);
083:
084: DocumentBuilder db = dbf.newDocumentBuilder();
085: db.setErrorHandler(new ErrorHandler() {
086: public void warning(SAXParseException exception) {
087: LOG
088: .info("Validation warning validating config file \""
089: + resourcePath
090: + "\" against XML Schema \""
091: + CONFIG_SCHEMA);
092: }
093:
094: public void error(SAXParseException exception) {
095: throw new RuntimeException(
096: "Validation errors occurred parsing the config file \""
097: + resourcePath + "\". Cause: "
098: + exception, exception);
099: }
100:
101: public void fatalError(SAXParseException exception) {
102: throw new RuntimeException(
103: "Validation errors occurred parsing the config file \""
104: + resourcePath + "\". Cause: "
105: + exception, exception);
106: }
107: });
108:
109: db.setEntityResolver(new EntityResolver() {
110: public InputSource resolveEntity(String publicId,
111: String systemId) {
112: if (systemId.endsWith("/catalog-config.xsd")) {
113: InputStream inputStream = getClass()
114: .getClassLoader().getResourceAsStream(
115: CONFIG_SCHEMA);
116: return new InputSource(inputStream);
117: } else
118: return null;
119: }
120: });
121:
122: Document document = db.parse(xmlInputStream);
123: Element catalogElement = document.getDocumentElement();
124: catalogConfig = parse(catalogElement);
125:
126: } catch (ParserConfigurationException e) {
127: throw new RuntimeException(
128: "Error occurred parsing the config file \""
129: + resourcePath + "\"", e);
130: } catch (IOException e) {
131: throw new RuntimeException(
132: "Error occurred parsing the config file \""
133: + resourcePath + "\"", e);
134: } catch (SAXException e) {
135: throw new RuntimeException(
136: "Error occurred parsing the config file \""
137: + resourcePath + "\"", e);
138: } finally {
139: try {
140: if (xsdInputStream != null)
141: xsdInputStream.close();
142: } catch (IOException e) {
143: }
144: }
145:
146: return catalogConfig;
147: }
148:
149: private static CatalogConfig parseCatalog(Element catalogElement) {
150: CatalogConfig catalogConfig = null;
151: if (catalogElement != null && catalogElement.hasChildNodes()) {
152: catalogConfig = new CatalogConfig();
153: NodeList nodeList = catalogElement.getChildNodes();
154: if (nodeList != null) {
155: for (int i = 0; i < nodeList.getLength(); i++) {
156: Node node = nodeList.item(i);
157: if (!(node.getNodeType() == Node.ELEMENT_NODE))
158: continue;
159:
160: if (node.getNodeName().equals("chain")) {
161: Element element = (Element) node;
162: String name = element.getAttribute("name");
163: ChainConfig chainConfig = new ChainConfig();
164: chainConfig.setName(name);
165:
166: NodeList commandList = element
167: .getElementsByTagName("command");
168: if (commandList != null) {
169: for (int j = 0; j < commandList.getLength(); j++) {
170: Element commandElement = (Element) commandList
171: .item(j);
172: CommandConfig commandConfig = parseCommand(commandElement);
173: chainConfig.addCommand(commandConfig);
174: }
175: }
176: catalogConfig.addCommand(chainConfig);
177: } else if (node.getNodeName().equals("command")) {
178: Element element = (Element) node;
179: CommandConfig commandConfig = parseCommand(element);
180: catalogConfig.addCommand(commandConfig);
181: }
182: }
183: }
184: }
185:
186: return catalogConfig;
187: }
188:
189: private static CommandConfig parseCommand(Element element) {
190: assert element != null;
191: assert element.getNodeName().equals("command");
192:
193: CommandConfig commandConfig = new CommandConfig();
194: String id = DomUtils.getChildElementText(element, "id");
195: String classname = DomUtils.getChildElementText(element,
196: "command-class");
197: commandConfig.setId(id);
198: commandConfig.setClassname(classname);
199:
200: NodeList propertyList = element
201: .getElementsByTagName("custom-property");
202: if (propertyList != null) {
203: for (int k = 0; k < propertyList.getLength(); k++) {
204: Element propertyElement = (Element) propertyList
205: .item(k);
206: String propName = DomUtils.getChildElementText(
207: propertyElement, "name");
208: String propValue = DomUtils.getChildElementText(
209: propertyElement, "value");
210: CustomPropertyConfig propertyConfig = new CustomPropertyConfig(
211: propName, propValue);
212: commandConfig.addParameter(propertyConfig);
213: }
214: }
215:
216: return commandConfig;
217: }
218: }
|