Package org.lilyproject.runtime.conf

Source Code of org.lilyproject.runtime.conf.XmlConfBuilder

/*
* Copyright 2013 NGDATA nv
* Copyright 2008 Outerthought bvba and Schaubroeck nv
*
* 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 org.lilyproject.runtime.conf;

import javax.xml.parsers.ParserConfigurationException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.lilyproject.util.io.IOUtils;
import org.lilyproject.util.location.Location;
import org.lilyproject.util.location.LocationImpl;
import org.lilyproject.util.xml.LocalSAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

public class XmlConfBuilder {
    private static final String CONFIG_NAMESPACE = "http://lilyproject.org/configuration";

    private XmlConfBuilder() {
    }

    public static ConfImpl build(File file) throws IOException, SAXException, ParserConfigurationException {
        InputStream is = null;
        try {
            is = new BufferedInputStream(new FileInputStream(file));
            return build(is, file.getAbsolutePath());
        } finally {
            IOUtils.closeQuietly(is, file.getAbsolutePath());
        }
    }

    public static ConfImpl build(InputStream is, String location) throws IOException, SAXException,
            ParserConfigurationException
    {
        InputSource inputSource = new InputSource(is);
        inputSource.setSystemId(location);

        XMLReader xmlReader = LocalSAXParserFactory.newXmlReader();
        ConfigurationHandler configHandler = new ConfigurationHandler();
        xmlReader.setContentHandler(configHandler);
        xmlReader.parse(inputSource);

        return configHandler.rootConfig;
    }

    private static class ConfigurationHandler implements ContentHandler {
        private List<ConfImpl> configs = new ArrayList<ConfImpl>();
        private ConfImpl rootConfig;
        private List<StringBuilder> charBuffers = new ArrayList<StringBuilder>();
        private Locator locator;

        public void setDocumentLocator(Locator locator) {
            this.locator = locator;
        }

        public void startDocument() throws SAXException {
        }

        public void endDocument() throws SAXException {
        }

        public void startPrefixMapping(String prefix, String uri) throws SAXException {
        }

        public void endPrefixMapping(String prefix) throws SAXException {
        }

        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
            if (uri.equals("")) {
                Location location = locator == null ? Location.UNKNOWN : new LocationImpl(null, locator.getSystemId(),
                        locator.getLineNumber(), locator.getColumnNumber());
                ConfImpl config = new ConfImpl(localName, location);
                configs.add(config);

                for (int i = 0; i < atts.getLength(); i++) {
                    if (atts.getURI(i).equals("")) {
                        config.addAttribute(atts.getLocalName(i), atts.getValue(i));
                    } else if (atts.getURI(i).equals(CONFIG_NAMESPACE)) {
                        if (atts.getLocalName(i).equals("inherit")) {
                            String inheritString = atts.getValue(i);
                            ConfImpl.Inheritance inherit;

                            if (inheritString.equals("none")) {
                                inherit = ConfImpl.Inheritance.NONE;
                            } else if (inheritString.equals("shallow")) {
                                inherit = ConfImpl.Inheritance.SHALLOW;
                            } else if (inheritString.equals("deep")) {
                                inherit = ConfImpl.Inheritance.DEEP;
                            } else {
                                throw new SAXException("Invalid value in attribute " + atts.getQName(i)
                                        + ": \"" + inheritString + "\", should be one of: none, shallow, deep. At "
                                        + location);
                            }

                            config.setInheritance(inherit);
                        } else if (atts.getLocalName(i).equals("inheritKey")) {
                            config.setInheritConstraint(atts.getValue(i));
                        } else {
                            throw new SAXException("Unsupported attribute: " + atts.getQName(i) + " at " + location);
                        }
                    }
                }

                charBuffers.add(new StringBuilder());
            } else if (configs.size() == 0) {
                throw new SAXException("Root element of a configuration file should not be in a namespace.");
            }
        }

        public void endElement(String uri, String localName, String qName) throws SAXException {
            if (uri.equals("")) {
                ConfImpl config = configs.remove(configs.size() - 1);

                String textualContent = charBuffers.remove(charBuffers.size() - 1).toString().trim();
                if (textualContent.length() > 0) {
                    if (config.getChildren().size() > 0) {
                        throw new SAXException("Mixed content is not allowed in configuration element "
                                + config.getName() + " at " + config.getLocation());
                    }
                    config.setValue(textualContent);
                }

                if (configs.size() > 0) {
                    configs.get(configs.size() - 1).addChild(config);
                } else {
                    rootConfig = config;
                }
            }
        }

        public void characters(char[] ch, int start, int length) throws SAXException {
            charBuffers.get(charBuffers.size() - 1).append(ch, start, length);
        }

        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        }

        public void processingInstruction(String target, String data) throws SAXException {
        }

        public void skippedEntity(String name) throws SAXException {
        }
    }
}
TOP

Related Classes of org.lilyproject.runtime.conf.XmlConfBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.