/* * Copyright 2010-2011 Research In Motion Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.rim.tumbler.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import net.rim.tumbler.config.WidgetFeature; import net.rim.tumbler.file.Library; import net.rim.tumbler.file.Library.Configuration; import net.rim.tumbler.file.Library.Extension; import net.rim.tumbler.file.Library.Jar; import net.rim.tumbler.file.Library.Platform; import net.rim.tumbler.file.Library.Src; import net.rim.tumbler.file.Library.Target; import net.rim.tumbler.log.LogType; import net.rim.tumbler.log.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class LibraryXMLParser { private static final String NODE_LIBRARY = "library"; private static final String NODE_EXTENSION = "extension"; private static final String NODE_ENTRYCLASS = "entryClass"; private static final String NODE_DEPENDENCIES = "dependencies"; private static final String NODE_JAR = "jar"; private static final String NODE_PLATFORMS = "platforms"; private static final String NODE_PLATFORM = "platform"; private static final String NODE_TARGET = "target"; private static final String NODE_CONFIGURATIONS = "configurations"; private static final String NODE_CONFIGURATION = "configuration"; private static final String NODE_SRC = "src"; private static final String NODE_FEATURES = "features"; private static final String NODE_FEATURE = "feature"; private static final String ATTR_VALUE = "value"; private static final String ATTR_VERSION = "version"; private static final String ATTR_CONFIG = "config"; private static final String ATTR_NAME = "name"; private static final String ATTR_TYPE = "type"; private static final String ATTR_PATH = "path"; private static final String ATTR_ID = "id"; private static final String ATTR_REQUIRED = "required"; private Library _library = null; public LibraryXMLParser() { _library = new Library(); } public Library parseXML(String libraryXMLPath) throws Exception { // TODO need to log anything? try { DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document doc = builder.parse(new File(libraryXMLPath)); doc.getDocumentElement().normalize(); return parseDocument(doc); } catch (SAXException e) { // TODO might not need to re-throw? Logger.logMessage(LogType.WARNING, "EXCEPTION_INVALID_LBRARY_XML", new String[] { libraryXMLPath }); } return null; } private String processText(String text) { if (text == null) { return null; } return text.replaceAll("\t", "").replaceAll("\n", "").trim(); } private String getTextValue(Node node) { if (node == null) return ""; if (node.getNodeType() == Node.ATTRIBUTE_NODE) { return processText(node.getNodeValue()); } NodeList list = node.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node chilNode = list.item(i); if (chilNode.getNodeType() == Node.TEXT_NODE) { return processText(chilNode.getNodeValue()); } } return ""; } private Library parseDocument(Document doc) { Node root = (Node) doc.getElementsByTagName(NODE_LIBRARY).item(0); NodeList childNodes = root.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { if (node.getNodeName().equals(NODE_EXTENSION)) { processExtensionNode(node); } else if (node.getNodeName().equals(NODE_PLATFORMS)) { processPlatformsNode(node); } else if (node.getNodeName().equals(NODE_CONFIGURATIONS)) { processConfigurationsNode(node); } else if (node.getNodeName().equals(NODE_FEATURES)) { processFeaturesNode(node); } } } return _library; } private void processExtensionNode(Node extensionNode) { if (extensionNode instanceof Element) { NamedNodeMap attrs = extensionNode.getAttributes(); Node idAttr = attrs.getNamedItem(ATTR_ID); // id attribute does not exist in extension that comes as a JAR // even if it's not there, it is not necessarily an error if (idAttr != null) { Extension extension = new Extension(idAttr.getNodeValue()); _library.setExtension(extension); } NodeList childNodes = extensionNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node.getNodeName().equals(NODE_ENTRYCLASS)) { _library.setEntryClass(getTextValue(node).trim()); } else if (node.getNodeName().equals(NODE_DEPENDENCIES)) { processDependenciesNode(node); } } } } private void processDependenciesNode(Node dependenciesNode) { if (dependenciesNode instanceof Element) { NodeList extensionNodes = ((Element) dependenciesNode).getElementsByTagName(NODE_EXTENSION); for (int i = 0; i < extensionNodes.getLength(); i++) { Node node = extensionNodes.item(i); NamedNodeMap attrs = node.getAttributes(); if (attrs != null) { Node idAttr = attrs.getNamedItem(ATTR_ID); if (idAttr != null) { Extension dependency = new Extension(idAttr.getNodeValue()); _library.addDependency(dependency); } } } NodeList jarNodes = ((Element) dependenciesNode).getElementsByTagName(NODE_JAR); for (int i = 0; i < jarNodes.getLength(); i++) { Node node = jarNodes.item(i); NamedNodeMap attrs = node.getAttributes(); if (attrs != null) { Node pathAttr = attrs.getNamedItem(ATTR_PATH); if (pathAttr != null) { Jar jar = new Jar(pathAttr.getNodeValue()); _library.addJarDependency(jar); } } } } } private void processPlatformsNode(Node platformsNode) { NodeList childNodes = platformsNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Platform p = processPlatformNode(childNodes.item(i)); if (p != null) { _library.addPlatform(p); } } } private Platform processPlatformNode(Node platformNode) { if (platformNode.getNodeName().equals(NODE_PLATFORM)) { NamedNodeMap attrs = platformNode.getAttributes(); if (attrs != null) { Node valueAttr = attrs.getNamedItem(ATTR_VALUE); if (valueAttr != null) { Platform platform = new Platform(valueAttr.getNodeValue()); NodeList childNodes = platformNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Target target = processTargetNode(childNodes.item(i)); if (target != null) { platform.addTarget(target); } } return platform; } } } return null; } private Target processTargetNode(Node targetNode) { if (targetNode.getNodeName().equals(NODE_TARGET)) { NamedNodeMap attrs = targetNode.getAttributes(); if (attrs != null) { Node versionAttr = attrs.getNamedItem(ATTR_VERSION); Node configAttr = attrs.getNamedItem(ATTR_CONFIG); if (versionAttr != null && configAttr != null) { Target target = new Target(versionAttr.getNodeValue(), configAttr.getNodeValue()); return target; } } } return null; } private void processConfigurationsNode(Node configurationsNode) { NodeList childNodes = configurationsNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Configuration config = processConfigurationNode(childNodes.item(i)); if (config != null) { _library.addConfiguration(config); } } } private Configuration processConfigurationNode(Node configurationNode) { if (configurationNode.getNodeName().equals(NODE_CONFIGURATION)) { NamedNodeMap attrs = configurationNode.getAttributes(); if (attrs != null) { Node nameAttr = attrs.getNamedItem(ATTR_NAME); Node versionAttr = attrs.getNamedItem(ATTR_VERSION); if (nameAttr != null && versionAttr != null) { Configuration config = new Configuration(nameAttr.getNodeValue(), versionAttr.getNodeValue()); NodeList childNodes = configurationNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Src src = processSrcNode(childNodes.item(i)); if (src != null) { config.addSrc(src); } } return config; } } } return null; } private Src processSrcNode(Node srcNode) { if (srcNode.getNodeName().equals(NODE_SRC)) { NamedNodeMap attrs = srcNode.getAttributes(); if (attrs != null) { Node typeAttr = attrs.getNamedItem(ATTR_TYPE); Node pathAttr = attrs.getNamedItem(ATTR_PATH); if (typeAttr != null && pathAttr != null) { Src src = new Src(typeAttr.getNodeValue(), pathAttr.getNodeValue()); return src; } } } return null; } private void processFeaturesNode(Node featuresNode) { NodeList childNodes = featuresNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { WidgetFeature feature = processFeatureNode(childNodes.item(i)); if (feature != null) { _library.addFeature(feature); } } } private WidgetFeature processFeatureNode(Node featureNode) { if (featureNode.getNodeName().equals(NODE_FEATURE)) { NamedNodeMap attrs = featureNode.getAttributes(); if (attrs != null) { Node idAttr = attrs.getNamedItem(ATTR_ID); Node versionAttr = attrs.getNamedItem(ATTR_VERSION); Node requiredAttr = attrs.getNamedItem(ATTR_REQUIRED); if (idAttr != null && versionAttr != null) { boolean isRequired = true; if (requiredAttr != null) { isRequired = !requiredAttr.getNodeValue() .equalsIgnoreCase(Boolean.FALSE.toString()); } WidgetFeature feature = new WidgetFeature(idAttr .getNodeValue(), isRequired, versionAttr .getNodeValue(), null); return feature; } } } return null; } }