Package com.alibaba.citrus.springext.export

Source Code of com.alibaba.citrus.springext.export.SchemaExporter$Entries

/*
* Copyright (c) 2002-2012 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.export;

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

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.alibaba.citrus.springext.Schema;
import com.alibaba.citrus.springext.Schema.Transformer;
import com.alibaba.citrus.springext.Schemas;
import com.alibaba.citrus.springext.support.SpringExtSchemaSet;
import com.alibaba.citrus.springext.support.SchemaSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 装载和分析schemas,并输出到任意输出流。
*
* @author Michael Zhou
*/
public class SchemaExporter {
    protected final Logger log = LoggerFactory.getLogger(getClass());
    private final Entries   entries;
    private final SchemaSet schemas;

    public SchemaExporter() {
        this(new SpringExtSchemaSet());
    }

    public SchemaExporter(Schemas... schemasList) {
        this.entries = new Entries();
        this.schemas = SchemaSet.getInstance(schemasList);

        for (Schema schema : schemas.getNamedMappings().values()) {
            this.entries.put(schema.getName(), new Entry(schema.getName(), schema));
        }
    }

    private Entries getEntries() {
        return entries;
    }

    public Entry getRootEntry() {
        return getEntries().getRoot();
    }

    public Entry getEntry(String path) {
        return getEntries().get(path);
    }

    public void writeTo(Writer out, Entry entry, String charset) throws IOException {
        writeTo(out, entry, charset, (String) null);
    }

    public void writeTo(Writer out, Entry entry, String charset, String uriPrefix) throws IOException {
        writeTo(out, entry, charset, uriPrefix == null ? null : getAddPrefixTransformer(schemas, uriPrefix));
    }

    private void writeTo(Writer out, Entry entry, String charset, Transformer transformer) throws IOException {
        writeText(entry.getSchema().getText(charset, transformer), out, true);
    }

    /** 代表一个schema文件结点。 */
    public static final class Entry {
        private final String             path;
        private final String             name;
        private final boolean            directory;
        private final boolean            root;
        private final Schema             schema;
        private final Map<String, Entry> subEntries;

        /** 创建特殊的root entry。 */
        private Entry() {
            this.path = "";
            this.name = "";
            this.directory = true;
            this.root = true;
            this.schema = null;
            this.subEntries = createTreeMap();
        }

        public Entry(String path) {
            this(path, null);
        }

        public Entry(String path, Schema schema) {
            this.path = assertNotNull(trimToNull(path), "path");
            this.directory = path.endsWith("/");

            int fromIndex = this.directory ? path.length() - 2 : path.length();

            this.name = path.substring(path.lastIndexOf("/", fromIndex) + 1);
            this.root = false;
            this.schema = schema;
            this.subEntries = createTreeMap();

            if (this.directory) {
                assertNull(schema, "schema");
            } else {
                assertNotNull(schema, "schema");
            }
        }

        public String getPath() {
            return path;
        }

        public String getId() {
            if (isRoot()) {
                return "ROOT";
            } else {
                return path.replaceFirst("\\.[^-\\./]*$|/+$", "").replace('/', '-').replace('.', '-');
            }
        }

        public String getName() {
            return name;
        }

        public boolean isDirectory() {
            return directory;
        }

        public boolean isRoot() {
            return root;
        }

        public Collection<Entry> getSubEntries() {
            return subEntries.values();
        }

        public Schema getSchema() {
            return schema;
        }

        public boolean containsSchemaWithTargetNamespace() {
            boolean hasNs = false;

            if (isDirectory()) {
                for (Entry subEntry : getSubEntries()) {
                    if (subEntry.containsSchemaWithTargetNamespace()) {
                        hasNs = true;
                        break;
                    }
                }
            } else if (getSchema() != null) {
                hasNs = getSchema().getTargetNamespace() != null;
            }

            return hasNs;
        }

        private final static String PREFIX_ITEM             = "+---";
        private final static String PREFIX_LAST_ITEM        = "\\---";
        private final static String INDENT_BEFORE_LAST_ITEM = "|   ";
        private final static String INDENT_AFTER_LAST_ITEM  = "    ";

        public String tree() {
            StringWriter sw = new StringWriter();

            try {
                tree(sw);
            } catch (IOException e) {
                unexpectedException(e);
            }

            return sw.toString();
        }

        public void tree(Appendable buf) throws IOException {
            tree(buf, "");
        }

        public void tree(Appendable buf, String prefix) throws IOException {
            tree(buf, prefix, prefix);
        }

        private void tree(Appendable buf, String prefix, String indent) throws IOException {
            buf.append(prefix).append(getName()).append("\n");

            for (Iterator<Entry> i = subEntries.values().iterator(); i.hasNext(); ) {
                Entry subEntry = i.next();
                String subPrefix;
                String subIndent;

                if (i.hasNext()) {
                    subPrefix = indent + PREFIX_ITEM;
                    subIndent = indent + INDENT_BEFORE_LAST_ITEM;
                } else {
                    subPrefix = indent + PREFIX_LAST_ITEM;
                    subIndent = indent + INDENT_AFTER_LAST_ITEM;
                }

                subEntry.tree(buf, subPrefix, subIndent);
            }
        }

        /** Files sort by name without extension, then directories. */
        private String getSortKey() {
            String name = getName();

            if (!isDirectory()) {
                int slashIndex = name.lastIndexOf("/");
                int dotIndex = name.lastIndexOf(".");

                if (slashIndex < dotIndex && dotIndex >= 0) {
                    return "0-" + name.substring(0, dotIndex);
                }

                return "0-" + name;
            }

            return "1-" + name;
        }

        @Override
        public String toString() {
            return root ? "/" : path;
        }
    }

    private final class Entries extends HashMap<String, Entry> {
        private static final long serialVersionUID = -4000525580274040823L;

        public Entries() {
            super.put("", new Entry());
        }

        public Entry getRoot() {
            return get("");
        }

        @Override
        public Entry put(String path, Entry entry) {
            assertTrue(path.equals(entry.getPath()));

            if (path.endsWith("/")) {
                path = path.substring(0, path.length() - 1);
            }

            String parentPath = path.substring(0, path.lastIndexOf("/") + 1);
            Entry parentEntry = get(parentPath);

            if (parentEntry == null) {
                parentEntry = new Entry(parentPath);
                this.put(parentPath, parentEntry); // recursively
            }

            parentEntry.subEntries.put(entry.getSortKey(), entry);

            Entry old = super.put(entry.getPath(), entry);

            log.trace("Added entry: {}", entry.getPath());

            return old;
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.springext.export.SchemaExporter$Entries

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.