Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.empire.xml; import java.io.Closeable; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.beanutils.BeanUtils; import org.apache.empire.commons.ObjectUtils; import org.apache.empire.commons.StringUtils; import org.apache.empire.exceptions.FileParseException; import org.apache.empire.exceptions.FileReadException; import org.apache.empire.exceptions.InternalException; import org.apache.empire.exceptions.InvalidArgumentException; import org.apache.empire.exceptions.ItemNotFoundException; import org.apache.empire.exceptions.ObjectNotValidException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * <PRE> * This class manages the configuration of a Java Bean by an xml configuration file. * It also supports configuration of Log4J. * </PRE> * */ public class XMLConfiguration { private static final Logger log = LoggerFactory.getLogger(XMLConfiguration.class); private Element configRootNode = null; /** * Initialize the configuration. * * @param filename the file * @param fromResource will read from the classpath if true */ public void init(String filename, boolean fromResource) { // Read the properties file readConfiguration(filename, fromResource); } /** * returns the configuration root element or null if init() has not been called. * @return the configuration root element */ public Element getRootNode() { return configRootNode; } /** * Reads the configuration file and parses the XML Configuration. */ protected void readConfiguration(String fileName, boolean fromResource) { FileReader reader = null; InputStream inputStream = null; try { DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = null; if (fromResource) { // Open Resource log.info("reading resource file: " + fileName); inputStream = getClass().getClassLoader().getResourceAsStream(fileName); // Parse File doc = docBuilder.parse(inputStream); } else { // Open File log.info("reading configuration file: " + fileName); reader = new FileReader(fileName); // Parse File doc = docBuilder.parse(new InputSource(reader)); } // Get Root Element configRootNode = doc.getDocumentElement(); } catch (FileNotFoundException e) { log.error("Configuration file {} not found!", fileName, e); throw new FileReadException(fileName, e); } catch (IOException e) { log.error("Error reading configuration file {}", fileName, e); throw new FileReadException(fileName, e); } catch (SAXException e) { log.error("Invalid XML in configuration file {}", fileName, e); throw new FileParseException(fileName, e); } catch (ParserConfigurationException e) { log.error("ParserConfigurationException: {}", e.getMessage(), e); throw new InternalException(e); } finally { close(reader); close(inputStream); } } /** * reads all properties from a given properties node and applies them to the given bean * @param bean the bean to which to apply the configuration * @param propertiesNodeNames the name of the properties node below the root element */ public void readProperties(Object bean, String... propertiesNodeNames) { // Check state if (configRootNode == null) throw new ObjectNotValidException(this); // Check arguments if (bean == null) throw new InvalidArgumentException("bean", bean); Element propertiesNode = configRootNode; for (String nodeName : propertiesNodeNames) { if (StringUtils.isEmpty(nodeName)) throw new InvalidArgumentException("propertiesNodeNames", null); // Get configuration node propertiesNode = XMLUtil.findFirstChild(propertiesNode, nodeName); if (propertiesNode == null) { // Configuration log.error("Property-Node {} has not been found.", nodeName); throw new ItemNotFoundException(nodeName); } } // read the properties readProperties(bean, propertiesNode); } /** * reads all properties from a given properties node and applies them to the given bean * @param bean the bean to which to apply the configuration * @param propertiesNode the properties node */ public void readProperties(Object bean, Element propertiesNode) { // Check arguments if (propertiesNode == null) throw new InvalidArgumentException("propertiesNode", propertiesNode); if (bean == null) throw new InvalidArgumentException("bean", bean); // apply configuration log.info("reading bean properties from node: {}", propertiesNode.getNodeName()); NodeList nodeList = propertiesNode.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node item = nodeList.item(i); if (item.getNodeType() != Node.ELEMENT_NODE) continue; // Get the Text and set the Property setPropertyValue(bean, item); } } protected void setPropertyValue(Object bean, Node item) { // Get the Text and set the Property String name = item.getNodeName(); try { String newValue = XMLUtil.getElementText(item); BeanUtils.setProperty(bean, name, newValue); Object value = BeanUtils.getProperty(bean, name); if (ObjectUtils.compareEqual(newValue, value)) { log.info("Configuration property '{}' set to \"{}\"", name, newValue); } else { log.error("Failed to set property '{}'. Value is \"{}\"", name, value); } } catch (IllegalAccessException e) { log.error("Access to Property {} denied.", name); } catch (InvocationTargetException e) { log.error("Unable to set Property {}", name); } catch (NoSuchMethodException e) { log.error("Property '{}' not found in {}", name, bean.getClass().getName()); } } private void close(final Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException e) { log.debug(e.getMessage()); } } } }