org.openremote.modeler.service.ProtocolParser.java Source code

Java tutorial

Introduction

Here is the source code for org.openremote.modeler.service.ProtocolParser.java

Source

/* OpenRemote, the Home of the Digital Home.
* Copyright 2008-2009, OpenRemote Inc.
*
* See the contributors.txt file in the distribution for a
* full listing of individual contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.openremote.modeler.service;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXValidator;
import org.dom4j.io.XMLWriter;
import org.dom4j.util.XMLErrorHandler;
import org.openremote.modeler.exception.ParseProtocolException;
import org.openremote.modeler.protocol.ProtocolAttrDefinition;
import org.openremote.modeler.protocol.ProtocolDefinition;
import org.openremote.modeler.protocol.ProtocolValidator;
import org.xml.sax.SAXException;

/**
 * Parse all the protocol describe xml file in classpath/protocols.
 * 
 * @author <a href="mailto:allen.wei@finalist.cn">allen.wei</a>
 */
@SuppressWarnings("unchecked")
public class ProtocolParser {

    /** The Constant PROTOCOL_ELEMENT_NAME. */
    private static final String PROTOCOL_ELEMENT_NAME = "protocol";

    /** The Constant PROTOCOLS_DIR. */
    private static final String PROTOCOLS_DIR = "/protocols";

    /** The Constant PROTOCOL_XSD_FILE_NAME. */
    private static final String PROTOCOL_XSD_FILE_NAME = "protocol.xsd";

    /** The Constant VALIDATIONS_ElEMENT_NAME. */
    private static final String VALIDATIONS_ElEMENT_NAME = "validations";

    /** The Constant ATTR_ELEMENT_NAME. */
    private static final String ATTR_ELEMENT_NAME = "attr";

    /** The Constant LABEL_ATTR_NAME. */
    private static final String LABEL_ATTR_NAME = "label";

    /** The Constant NAME_ATTR_NAME. */
    private static final String NAME_ATTR_NAME = "name";

    /** The Constant DISPLAY_NAME_ATTR_NAME. */
    private static final String DISPLAY_NAME_ATTR_NAME = "displayName";

    /** The Constant TAG_NAME_ATTR_NAME. */
    private static final String TAG_NAME_ATTR_NAME = "tagName";

    /** The Constant MESSAGE_ATTR_NAME. */
    private static final String MESSAGE_ATTR_NAME = "message";

    /** The xml path. */
    private String xmlPath = "";

    /**
     * Parses the xmls.
     * 
     * @return the hash map< string, protocol definition>
     */
    public HashMap<String, ProtocolDefinition> parseXmls() {
        HashMap<String, ProtocolDefinition> definitionHashMap = new HashMap<String, ProtocolDefinition>();
        File dir = new File(getPath());
        for (File file : dir.listFiles(new FileFilter() {

            public boolean accept(File pathname) {
                if (pathname.getName().lastIndexOf(".xml") > 0) {
                    return true;
                }
                return false;
            }
        })) {
            definitionHashMap.putAll(parse(file));
        }
        return definitionHashMap;
    }

    /**
     * Parses the.
     * 
     * @param file the file
     * 
     * @return the map< string, protocol definition>
     */
    private Map<String, ProtocolDefinition> parse(File file) {
        Map<String, ProtocolDefinition> map = new HashMap<String, ProtocolDefinition>();

        Document protocolDoc = readXmlFromFile(file);

        Element openremoteElement = protocolDoc.getRootElement();
        Iterator<Element> protocolItr = openremoteElement.elementIterator(PROTOCOL_ELEMENT_NAME);
        while (protocolItr.hasNext()) {
            Element protocolElement = protocolItr.next();
            ProtocolDefinition protocolDefinition = new ProtocolDefinition();
            // set protocol displayName
            protocolDefinition.setDisplayName(protocolElement.attributeValue(DISPLAY_NAME_ATTR_NAME));
            // set protocol tagName
            protocolDefinition.setTagName(protocolElement.attributeValue(TAG_NAME_ATTR_NAME));

            // parse attr element start
            protocolDefinition.getAttrs().addAll(parseAttributs(protocolElement));
            map.put(protocolDefinition.getDisplayName(), protocolDefinition);
        }
        return map;
    }

    /**
     * Parses the attributs.
     * 
     * @param protocol the protocol
     * 
     * @return the list< protocol attr definition>
     */
    private List<ProtocolAttrDefinition> parseAttributs(Element protocol) {
        List<ProtocolAttrDefinition> attrs = new ArrayList<ProtocolAttrDefinition>();
        Iterator<Element> attrItr = protocol.elementIterator(ATTR_ELEMENT_NAME);
        while (attrItr.hasNext()) {
            Element attr = attrItr.next();
            ProtocolAttrDefinition attrDefinition = new ProtocolAttrDefinition();
            attrDefinition.setLabel(attr.attributeValue(LABEL_ATTR_NAME));
            attrDefinition.setName(attr.attributeValue(NAME_ATTR_NAME));
            Element validationsElement = attr.element(VALIDATIONS_ElEMENT_NAME);

            // parse validators start
            attrDefinition.getValidators().addAll(parseValidators(validationsElement));

            attrs.add(attrDefinition);

        }

        return attrs;
    }

    /**
     * Parses the validators.
     * 
     * @param validationsElement the validations element
     * 
     * @return the list< protocol validator>
     */
    private List<ProtocolValidator> parseValidators(Element validationsElement) {
        List<ProtocolValidator> validators = new ArrayList<ProtocolValidator>();

        for (Iterator<Element> validationsItr = validationsElement.elementIterator(); validationsItr.hasNext();) {
            Element validatorElement = validationsItr.next();
            if (getValidatorType(validatorElement.getName()) == -1) {
                throw new ParseProtocolException("Can't find validator " + validatorElement.getName());
            }
            ProtocolValidator protocolValidator = new ProtocolValidator(
                    getValidatorType(validatorElement.getName()), validatorElement.getTextTrim(),
                    validatorElement.attributeValue(MESSAGE_ATTR_NAME));
            validators.add(protocolValidator);
        }
        return validators;
    }

    /**
     * Gets the validator type.
     * 
     * @param elementName the element name
     * 
     * @return the validator type
     */
    private int getValidatorType(String elementName) {
        if (ProtocolValidator.ALLOW_BLANK.equals(elementName)) {
            return ProtocolValidator.ALLOW_BLANK_TYPE;
        } else if (ProtocolValidator.MAX_LENGTH.equals(elementName)) {
            return ProtocolValidator.MAX_LENGTH_TYPE;
        } else if (ProtocolValidator.MAX_LENGTH.equals(elementName)) {
            return ProtocolValidator.MAX_LENGTH_TYPE;
        } else if (ProtocolValidator.REGEX.equals(elementName)) {
            return ProtocolValidator.REGEX_TYPE;
        } else {
            return -1;
        }
    }

    /**
     * Read xml from file.
     * 
     * @param file the file
     * 
     * @return the document
     */
    private Document readXmlFromFile(File file) {
        Document protocolDoc = null;
        SAXReader reader = new SAXReader();
        XMLErrorHandler errorHandler = new XMLErrorHandler();
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(true);
        try {
            protocolDoc = reader.read(file);
            SAXParser parser = factory.newSAXParser();
            parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                    "http://www.w3.org/2001/XMLSchema");
            parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
                    "file:" + this.getClass().getResource("/").getPath().toString() + PROTOCOL_XSD_FILE_NAME);
            SAXValidator validator = new SAXValidator(parser.getXMLReader());
            validator.setErrorHandler(errorHandler);

            validator.validate(protocolDoc);

            XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint());

            if (errorHandler.getErrors().hasContent()) {
                writer.write(errorHandler.getErrors());
                throw new ParseProtocolException(
                        "validate xml schema on File " + file.getAbsolutePath() + " fail.");
            }
        } catch (ParserConfigurationException e) {
            throw new ParseProtocolException(
                    "Read xml From File " + file.getAbsolutePath() + " occur ParserConfigurationException.", e);
        } catch (SAXException e) {
            throw new ParseProtocolException(
                    "Read xml From File " + file.getAbsolutePath() + " occur SAXException.", e);
        } catch (UnsupportedEncodingException e) {
            throw new ParseProtocolException(
                    "Read xml From File " + file.getAbsolutePath() + " occur UnsupportedEncodingException.", e);
        } catch (IOException e) {
            throw new ParseProtocolException("Read xml From File " + file.getAbsolutePath() + " occur IOException.",
                    e);
        } catch (DocumentException e) {
            throw new ParseProtocolException(
                    "Read xml From File " + file.getAbsolutePath() + " occur DocumentException.", e);
        }
        return protocolDoc;
    }

    /**
     * Gets the path.
     * 
     * @return the path
     */
    private String getPath() {
        if (xmlPath != null && xmlPath.length() > 0) {
            return xmlPath;
        } else {
            return this.getClass().getResource(PROTOCOLS_DIR).getPath();

        }

    }

    /**
     * Sets the path.
     * 
     * @param path the new path
     */
    public void setPath(String path) {
        xmlPath = path;
    }
}