Package com.alibaba.citrus.springext.support.resolver

Source Code of com.alibaba.citrus.springext.support.resolver.SpringPluggableSchemas

/*
* 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.support.resolver;

import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;
import static org.springframework.util.ResourceUtils.*;

import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.citrus.springext.ConfigurationPointException;
import com.alibaba.citrus.springext.Schema;
import com.alibaba.citrus.springext.Schemas;
import com.alibaba.citrus.springext.impl.SchemaImpl;
import com.alibaba.citrus.util.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.xml.PluggableSchemaResolver;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

/**
* 将Spring所支持的<code>META-INF/spring.schemas</code>中定义的schemas移到本地服务器。
*
* @author Michael Zhou
*/
public class SpringPluggableSchemas implements Schemas {
    private final static Logger  log                      = LoggerFactory.getLogger(SpringPluggableSchemas.class);
    private final static String  SCHEMA_MAPPINGS_LOCATION = PluggableSchemaResolver.DEFAULT_SCHEMA_MAPPINGS_LOCATION;
    private final static Pattern SCHEMA_VERSION_PATTERN   = Pattern.compile("-((\\d+)(.\\d+)*)\\.xsd$");
    private final ResourceLoader      resourceLoader;
    private final Map<String, Schema> nameToSchemaMappings;
    private final Map<String, String> uriToNameMappings;
    private       boolean             initialized;

    public SpringPluggableSchemas() {
        this(null);
    }

    public SpringPluggableSchemas(ResourceLoader resourceLoader) {
        if (resourceLoader == null) {
            resourceLoader = new DefaultResourceLoader();
        }

        this.resourceLoader = resourceLoader;
        this.nameToSchemaMappings = createTreeMap();
        this.uriToNameMappings = createTreeMap();
    }

    public Map<String, Schema> getNamedMappings() {
        ensureInit();
        return nameToSchemaMappings;
    }

    public Map<String, String> getUriToNameMappings() {
        ensureInit();
        return uriToNameMappings;
    }

    private void ensureInit() {
        if (initialized) {
            return;
        }

        initialized = true;

        Properties uriToClasspathLocationMappings;

        log.trace("Trying to load Spring schema mappings at {}", SCHEMA_MAPPINGS_LOCATION);

        try {
            uriToClasspathLocationMappings = PropertiesLoaderUtils.loadAllProperties(SCHEMA_MAPPINGS_LOCATION,
                                                                                     resourceLoader.getClassLoader());
        } catch (IOException e) {
            throw new ConfigurationPointException("Unable to load Spring schema mappings from "
                                                  + SCHEMA_MAPPINGS_LOCATION, e);
        }

        String desc = "SpringSchema[" + SCHEMA_MAPPINGS_LOCATION + "]";

        for (Entry<Object, Object> entry : uriToClasspathLocationMappings.entrySet()) {
            String uri = trimToNull((String) entry.getKey());
            String classpathLocation = trimToNull((String) entry.getValue());
            String schemaName = getSchemaName(uri);
            Matcher matcher = SCHEMA_VERSION_PATTERN.matcher(schemaName);
            String version = null;

            if (matcher.find()) {
                version = matcher.group(1);
            }

            InputStreamSource source = getResource(classpathLocation, uri);

            if (source != null) {
                nameToSchemaMappings.put(schemaName, new SchemaImpl(schemaName, version, true, desc, source));
                uriToNameMappings.put(uri, schemaName);
            }
        }

        if (log.isDebugEnabled() && !uriToNameMappings.isEmpty()) {
            ToStringBuilder buf = new ToStringBuilder();

            buf.format("Loaded Spring schema mappings at %s, %d schemas found.", SCHEMA_MAPPINGS_LOCATION,
                       uriToNameMappings.size()).appendMap(uriToNameMappings);

            log.debug(buf.toString());
        }
    }

    private InputStreamSource getResource(String classpathLocation, String uri) {
        if (!classpathLocation.startsWith(CLASSPATH_URL_PREFIX)) {
            classpathLocation = CLASSPATH_URL_PREFIX + classpathLocation;
        }

        URL resource;

        try {
            resource = resourceLoader.getResource(classpathLocation).getURL();
        } catch (Exception e) {
            log.warn("Could not find schema {} for URI: {},\n  {}",
                     new String[] { classpathLocation, uri, e.getMessage() });

            return null;
        }

        return new UrlResource(resource) {
            @Override
            public String getDescription() {
                try {
                    return getURL().toExternalForm();
                } catch (IOException e) {
                    unexpectedException(e);
                    return null;
                }
            }
        };
    }

    private String getSchemaName(String uri) {
        // 替换URI,将http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        // 替换成:www.springframework.org/schema/beans/spring-beans-2.5.xsd
        return URI.create(uri).normalize().getSchemeSpecificPart().replaceAll("^/+|/+$", "");
    }

    @Override
    public String toString() {
        ToStringBuilder buf = new ToStringBuilder();

        buf.format("SpringPluggableSchemas[loaded from %s]", SCHEMA_MAPPINGS_LOCATION);
        buf.appendMap(uriToNameMappings);

        return buf.toString();
    }
}
TOP

Related Classes of com.alibaba.citrus.springext.support.resolver.SpringPluggableSchemas

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.