Java tutorial
/* * Copyright 2014 Subhabrata Ghosh * * 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 com.sqewd.os.maracache.core; import org.apache.commons.lang.StringUtils; import org.w3c.dom.*; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.IOException; /** * Container class for a XML parsed configuration object. * <p/> * Created by subghosh on 14/02/14. */ public class Config { private String filePath; private String configPath; private ConfigNode node; private EObjectState state = EObjectState.Unknown; /** * Construct the configuration handle with the configuration path specified. * * @param filePath - XML file to load the configuration from. * @param configPath - XML path for loading the root configuration node. */ public Config(String filePath, String configPath) { this.filePath = filePath; this.configPath = configPath; } /** * Get the file this configuration was loaded from. * * @return - Config file path. */ public String getFilePath() { return filePath; } /** * Get the root configuration node. * * @return - Root configuration node. */ public ConfigNode getNode() { return node; } /** * Search for a configuration element in the tree. * * @param path - Path to the configuration element. Paths are represented using the dot(.) notation. Example : * name1.name2.name3 * @return - Configuration node (path node or value). Null is returned if path not found. * @throws ConfigException */ public ConfigNode search(String path) throws ConfigException { try { EObjectState.checkState(state, EObjectState.Available, this.getClass()); if (node != null && (node instanceof ConfigPath)) { if (!StringUtils.isEmpty(path)) { String[] parts = path.split("\\."); if (parts != null && parts.length > 0) { return ((ConfigPath) node).search(parts, 0); } } } } catch (ObjectStateException ose) { throw new ConfigException(ose.getLocalizedMessage(), ose); } return null; } /** * Load the configuration from the path and file specified. * * @throws ConfigException */ public void load() throws ConfigException { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(filePath); //optional, but recommended //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work doc.getDocumentElement().normalize(); XPath xp = XPathFactory.newInstance().newXPath(); Element root = (Element) xp.compile(configPath).evaluate(doc, XPathConstants.NODE); if (root == null) { throw new ConfigException("Cannot find specified path in document. [path=" + configPath + "]"); } node = new ConfigPath(root.getNodeName(), null); load(node, root); state = EObjectState.Available; } catch (ParserConfigurationException pse) { state = EObjectState.Exception; state.setException(pse); throw new ConfigException("Error building the configuration document.", pse); } catch (IOException ioe) { state = EObjectState.Exception; state.setException(ioe); throw new ConfigException("Error reading configuration file [path=" + filePath + "]", ioe); } catch (SAXException se) { state = EObjectState.Exception; state.setException(se); throw new ConfigException("Error parsing document [document=" + filePath + "]", se); } catch (XPathExpressionException xpe) { state = EObjectState.Exception; state.setException(xpe); throw new ConfigException("Error parsing specified XPath expression.", xpe); } } private ConfigPath load(ConfigNode parent, Element elm) throws ConfigException { if (parent instanceof ConfigPath) { // Check if there are any attributes. // Attributes are treated as Value nodes. if (elm.hasAttributes()) { NamedNodeMap map = elm.getAttributes(); if (map.getLength() > 0) { for (int ii = 0; ii < map.getLength(); ii++) { Node n = map.item(ii); ((ConfigPath) parent).addValueNode(n.getNodeName(), n.getNodeValue()); } } } if (elm.hasChildNodes()) { NodeList children = elm.getChildNodes(); for (int ii = 0; ii < children.getLength(); ii++) { Node cn = children.item(ii); if (cn.getNodeType() == Node.ELEMENT_NODE) { Element e = (Element) cn; if (e.hasChildNodes()) { int nc = 0; for (int jj = 0; jj < e.getChildNodes().getLength(); jj++) { Node ccn = e.getChildNodes().item(jj); // Read the text node if there is any. if (ccn.getNodeType() == Node.TEXT_NODE) { String n = e.getNodeName(); String v = ccn.getNodeValue(); if (!StringUtils.isEmpty(v.trim())) ((ConfigPath) parent).addValueNode(n, v); nc++; } } // Make sure this in not a text only node. if (e.getChildNodes().getLength() > nc) { // Check if this is a parameter node. Parameters are treated differently. if (e.getNodeName().compareToIgnoreCase(ConfigParams.NODE_NAME) == 0) { ConfigParams cp = ((ConfigPath) parent).addParamNode(); setParams(cp, e); } else { ConfigPath cp = ((ConfigPath) parent).addPathNode(e.getNodeName()); load(cp, e); } } } } } } } return (ConfigPath) parent; } private void setParams(ConfigParams node, Element elm) { for (int ii = 0; ii < elm.getChildNodes().getLength(); ii++) { Node n = elm.getChildNodes().item(ii); if (n.getNodeType() == Node.ELEMENT_NODE) { Element e = (Element) n; if (e.getNodeName().compareToIgnoreCase(ConfigParams.NODE_VALUE_NAME) == 0) { String name = e.getAttribute(ConfigParams.NODE_ATTR_NAME); String value = e.getAttribute(ConfigParams.NODE_ATTR_VALUE); if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(value)) { node.addParam(name, value); } } } } } @Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("[FILE:").append(filePath).append("]\n"); if (node != null) { sb.append(node.toString()); } return sb.toString(); } }