Package com.alibaba.antx.util.configuration

Source Code of com.alibaba.antx.util.configuration.DefaultConfigurationSerializer

/*
* Copyright 2010 Alibaba Group Holding Limited.
* All rights reserved.
*
* 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.alibaba.antx.util.configuration;

import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.NamespaceSupport;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;

import java.net.URL;

import java.util.Properties;

/**
* A ConfigurationSerializer serializes configurations via SAX2 compliant parser.
*
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
*
*/
public class DefaultConfigurationSerializer {
    private SAXTransformerFactory m_tfactory;
    private Properties            m_format = new Properties();

    /**
     * Sets the Serializer's use of indentation.  This will cause linefeeds to be added after each
     * element, but it does not add any indentation via spaces.
     *
     * @param indent a <code>boolean</code> value
     */
    public void setIndent(boolean indent) {
        if (indent) {
            m_format.put(OutputKeys.INDENT, "yes");
        } else {
            m_format.put(OutputKeys.INDENT, "no");
        }
    }

    /**
     * Create a ContentHandler for an OutputStream
     *
     * @param result the result
     *
     * @return contenthandler that goes to specified OutputStream
     */
    protected ContentHandler createContentHandler(final Result result) {
        try {
            TransformerHandler handler = getTransformerFactory().newTransformerHandler();

            m_format.put(OutputKeys.METHOD, "xml");
            handler.setResult(result);
            handler.getTransformer().setOutputProperties(m_format);

            return handler;
        } catch (final Exception e) {
            throw new RuntimeException(e.toString());
        }
    }

    /**
     * Get the SAXTransformerFactory so we can get a serializer without being tied to one vendor.
     *
     * @return a <code>SAXTransformerFactory</code> value
     */
    protected SAXTransformerFactory getTransformerFactory() {
        if (m_tfactory == null) {
            m_tfactory = (SAXTransformerFactory) TransformerFactory.newInstance();
        }

        return m_tfactory;
    }

    /**
     * Serialize the configuration to a ContentHandler
     *
     * @param handler a <code>ContentHandler</code> to serialize to
     * @param source a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public void serialize(final ContentHandler handler, final Configuration source)
            throws SAXException, ConfigurationException {
        handler.startDocument();
        serializeElement(handler, new NamespaceSupport(), source);
        handler.endDocument();
    }

    /**
     * Serialize each Configuration element.  This method is called recursively.
     *
     * @param handler a <code>ContentHandler</code> to use
     * @param namespaceSupport a <code>NamespaceSupport</code> to use
     * @param element a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    protected void serializeElement(final ContentHandler handler,
        final NamespaceSupport namespaceSupport, final Configuration element)
            throws SAXException, ConfigurationException {
        namespaceSupport.pushContext();

        AttributesImpl attr      = new AttributesImpl();
        String[]       attrNames = element.getAttributeNames();

        if (null != attrNames) {
            for (int i = 0; i < attrNames.length; i++) {
                attr.addAttribute("", // namespace URI
                    attrNames[i], // local name
                    attrNames[i], // qName
                    "CDATA", // type
                    element.getAttribute(attrNames[i], "") // value
                );
            }
        }

        final String nsURI    = element.getNamespace();
        String       nsPrefix = "";

        if (element instanceof AbstractConfiguration) {
            nsPrefix = ((AbstractConfiguration) element).getPrefix();
        }

        // nsPrefix is guaranteed to be non-null at this point.
        boolean      nsWasDeclared = false;

        final String existingURI = namespaceSupport.getURI(nsPrefix);

        // ie, there is no existing URI declared for this prefix or we're
        // remapping the prefix to a different URI
        if ((existingURI == null) || !existingURI.equals(nsURI)) {
            nsWasDeclared = true;

            if (nsPrefix.equals("") && nsURI.equals("")) {
                // implicit mapping; don't need to declare
            } else if (nsPrefix.equals("")) {
                // (re)declare the default namespace
                attr.addAttribute("", "xmlns", "xmlns", "CDATA", nsURI);
            } else {
                // (re)declare a mapping from nsPrefix to nsURI
                attr.addAttribute("", "xmlns:" + nsPrefix, "xmlns:" + nsPrefix, "CDATA", nsURI);
            }

            handler.startPrefixMapping(nsPrefix, nsURI);
            namespaceSupport.declarePrefix(nsPrefix, nsURI);
        }

        String localName = element.getName();
        String qName = element.getName();

        if ((nsPrefix == null) || (nsPrefix.length() == 0)) {
            qName = localName;
        } else {
            qName = nsPrefix + ":" + localName;
        }

        handler.startElement(nsURI, localName, qName, attr);

        String value = element.getValue(null);

        if (null == value) {
            Configuration[] children = element.getChildren();

            for (int i = 0; i < children.length; i++) {
                serializeElement(handler, namespaceSupport, children[i]);
            }
        } else {
            handler.characters(value.toCharArray(), 0, value.length());
        }

        handler.endElement(nsURI, localName, qName);

        if (nsWasDeclared) {
            handler.endPrefixMapping(nsPrefix);
        }

        namespaceSupport.popContext();
    }

    /**
     * Serialize the configuration object to a file using a filename.
     *
     * @param filename a <code>String</code> value
     * @param source a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws IOException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public void serializeToFile(final String filename, final Configuration source)
            throws SAXException, IOException, ConfigurationException {
        serializeToFile(new File(filename), source);
    }

    /**
     * Serialize the configuration object to a file using a File object.
     *
     * @param file a <code>File</code> value
     * @param source a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws IOException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public void serializeToFile(final File file, final Configuration source)
            throws SAXException, IOException, ConfigurationException {
        OutputStream outputStream = null;

        try {
            outputStream = new FileOutputStream(file);
            serialize(outputStream, source);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * Serialize the configuration object to an output stream.
     *
     * @param outputStream an <code>OutputStream</code> value
     * @param source a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws IOException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public void serialize(final OutputStream outputStream, final Configuration source)
            throws SAXException, IOException, ConfigurationException {
        serialize(createContentHandler(new StreamResult(outputStream)), source);
    }

    /**
     * Serialize the configuration object to an output stream derived from an URI.  The URI must be
     * resolveable by the <code>java.net.URL</code> object.
     *
     * @param uri a <code>String</code> value
     * @param source a <code>Configuration</code> value
     *
     * @throws SAXException if an error occurs
     * @throws IOException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public void serialize(final String uri, final Configuration source)
            throws SAXException, IOException, ConfigurationException {
        OutputStream outputStream = null;

        try {
            outputStream = new URL(uri).openConnection().getOutputStream();
            serialize(outputStream, source);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }

    /**
     * Serialize the configuration object to a string
     *
     * @param source a <code>Configuration</code> value
     *
     * @return configuration serialized as a string.
     *
     * @throws SAXException if an error occurs
     * @throws ConfigurationException if an error occurs
     */
    public String serialize(final Configuration source) throws SAXException, ConfigurationException {
        final StringWriter writer = new StringWriter();

        serialize(createContentHandler(new StreamResult(writer)), source);

        return writer.toString();
    }
}
TOP

Related Classes of com.alibaba.antx.util.configuration.DefaultConfigurationSerializer

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.