Package com.alibaba.citrus.springext.impl

Source Code of com.alibaba.citrus.springext.impl.SchemaImpl

/*
* 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.citrus.springext.impl;

import static com.alibaba.citrus.springext.support.SchemaUtil.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.BasicConstant.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import static com.alibaba.citrus.util.io.StreamUtil.*;
import static javax.xml.XMLConstants.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.InputStreamSource;

import com.alibaba.citrus.springext.ConfigurationPointException;
import com.alibaba.citrus.springext.DocumentFilter;
import com.alibaba.citrus.springext.Schema;
import com.alibaba.citrus.springext.support.SchemaInternal;
import com.alibaba.citrus.springext.support.SchemaUtil;

public class SchemaImpl implements SchemaInternal {
    private final static Logger log = LoggerFactory.getLogger(Schema.class);
    private final String name;
    private final String version;
    private final String sourceDesc;
    private final InputStreamSource source;
    private String targetNamespace;
    private String preferredNsPrefix;
    private String[] includes;
    private String[] elements;
    private boolean parsed;
    private boolean parsingTargetNamespace;

    /**
     * ���� configuration point �� main schema �� versioned schema��
     */
    public SchemaImpl(String name, String version, String targetNamespace, String preferredNsPrefix, String sourceDesc,
                      InputStreamSource source) {
        this(name, version, targetNamespace, preferredNsPrefix, false, sourceDesc, source);
    }

    /**
     * ���� contribution �� main schema �� versioned schema��
     */
    public SchemaImpl(String name, String version, String sourceDesc, InputStreamSource source) {
        this(name, version, null, null, false, sourceDesc, source);
    }

    /**
     * ����spring.schemas�ж����schema��
     */
    public SchemaImpl(String name, String version, boolean parsingTargetNamespace, String sourceDesc,
                      InputStreamSource source) {
        this(name, version, null, null, parsingTargetNamespace, sourceDesc, source);
    }

    /**
     * ����spring.schemas�ж����schema��
     * <p>
     * ���<code>parsingTargetNamespace</code>Ϊ <code>true</code>������ͼͨ������xml��ȡ��ns��
     * </p>
     */
    private SchemaImpl(String name, String version, String targetNamespace, String preferredNsPrefix,
                       boolean parsingTargetNamespace, String sourceDesc, InputStreamSource source) {
        this.name = name;
        this.version = version;
        this.targetNamespace = trimToNull(targetNamespace);
        this.preferredNsPrefix = trimToNull(preferredNsPrefix);
        this.parsingTargetNamespace = parsingTargetNamespace;
        this.sourceDesc = sourceDesc;
        this.source = source;
    }

    public String getName() {
        return name;
    }

    public String getVersion() {
        return version;
    }

    public String getTargetNamespace() {
        if (parsingTargetNamespace) {
            parse();
        }

        return targetNamespace;
    }

    public String getPreferredNsPrefix() {
        return preferredNsPrefix;
    }

    public String[] getIncludes() {
        parse();
        return includes == null ? EMPTY_STRING_ARRAY : includes;
    }

    public String[] getElements() {
        if (elements != null) {
            return elements;
        }

        parse();
        return elements == null ? EMPTY_STRING_ARRAY : elements;
    }

    /**
     * ��schemaSet�����á�
     */
    public void setElements(String[] elements) {
        this.elements = elements;
    }

    public String getNamespacePrefix() {
        return SchemaUtil.getNamespacePrefix(getPreferredNsPrefix(), getTargetNamespace());
    }

    public String getSourceDescription() {
        return sourceDesc;
    }

    public InputStream getInputStream() throws IOException {
        return source.getInputStream();
    }

    public Document getDocument() {
        try {
            return readDocument(source.getInputStream(), name, true);
        } catch (DocumentException e) {
            log.warn("Not a valid XML doc: {}, source={},\n{}", new Object[] { name, source, e.getMessage() });
            return null;
        } catch (IOException e) {
            throw new ConfigurationPointException("Failed to read text of schema file: " + name + ", source=" + source,
                    e);
        }
    }

    public String getText() throws IOException {
        return getText(null, null);
    }

    public String getText(String charset) throws IOException {
        return getText(charset, null);
    }

    public String getText(String charset, DocumentFilter filter) throws IOException {
        String content;

        // parse
        Document doc = getDocument();

        // read text if it's an invalid XML doc.
        if (doc == null) {
            return readText(getInputStream(), "ISO-8859-1", true);
        }

        // filter the doc
        if (filter != null) {
            doc = assertNotNull(filter.filter(doc, name), "doc filter returned null");
        }

        // output
        try {
            content = SchemaUtil.getDocumentText(doc, charset);
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw new ConfigurationPointException("Failed to read text of schema file: " + name + ", source=" + source,
                    e);
        }

        return content;
    }

    /**
     * ����schema��ȡ��������Ϣ��
     * <ol>
     * <li>targetNamespace</li>
     * <li>include name</li>
     * </ol>
     */
    private void parse() {
        if (parsed) {
            return;
        }

        parsed = true;
        Document doc = getDocument();

        // return if it's not a valid XML file
        if (doc == null) {
            return;
        }

        Element root = doc.getRootElement();

        // return if not a schema file
        if (!W3C_XML_SCHEMA_NS_URI.equals(root.getNamespaceURI()) || !"schema".equals(root.getName())) {
            return;
        }

        // parse targetNamespace
        if (parsingTargetNamespace) {
            Attribute attr = root.attribute("targetNamespace");

            if (attr != null) {
                targetNamespace = attr.getStringValue();
            }
        }

        // parse include
        Namespace xsd = DocumentHelper.createNamespace("xsd", W3C_XML_SCHEMA_NS_URI);
        QName includeName = DocumentHelper.createQName("include", xsd);
        List<String> includeNames = createLinkedList();

        // for each <xsd:include>
        for (Iterator<?> i = root.elementIterator(includeName); i.hasNext();) {
            Element includeElement = (Element) i.next();
            String schemaLocation = trimToNull(includeElement.attributeValue("schemaLocation"));

            if (schemaLocation != null) {
                includeNames.add(schemaLocation);
            }
        }

        includes = includeNames.toArray(new String[includeNames.size()]);

        // parse xsd:element
        if (elements == null) {
            QName elementName = DocumentHelper.createQName("element", xsd);
            List<String> elementNames = createLinkedList();

            // for each <xsd:element>
            for (Iterator<?> i = root.elementIterator(elementName); i.hasNext();) {
                Element elementElement = (Element) i.next();
                String name = trimToNull(elementElement.attributeValue("name"));

                if (name != null) {
                    elementNames.add(name);
                }
            }

            elements = elementNames.toArray(new String[elementNames.size()]);
        }
    }

    @Override
    public String toString() {
        if (targetNamespace == null) {
            return String.format("Schema[name=%s, version=%s, source=%s]", name, version, source);
        } else {
            return String.format("Schema[name=%s, version=%s, targetNamespace=%s, source=%s]", name, version,
                    targetNamespace, source);
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.springext.impl.SchemaImpl

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.