/* * 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.dev.handler.util; import static com.alibaba.citrus.util.ArrayUtil.*; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.ExceptionUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.List; import java.util.Set; import com.alibaba.citrus.dev.handler.util.DomUtil.ElementFilter; import org.dom4j.Namespace; import org.dom4j.QName; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.ResourcePatternResolver; public class ConfigurationFileReader { private final ConfigurationFile[] configurationFiles; private final String baseURL; private final ResourceLoader loader; public ConfigurationFileReader(ResourceLoader loader, String[] configLocations) throws IOException { this.loader = assertNotNull(loader); // 取得所有顶层resources List<NamedResource> resources = createLinkedList(); for (String configLocation : configLocations) { if (loader instanceof ResourcePatternResolver) { Resource[] results = ((ResourcePatternResolver) loader).getResources(configLocation); if (!isEmptyArray(results)) { for (Resource res : results) { resources.add(new NamedResource(configLocation, res)); } } } else { Resource res = loader.getResource(configLocation); if (res != null) { resources.add(new NamedResource(configLocation, res)); } } } // 计算baseurl URL base = null; try { base = URI.create(loader.getResource("WEB-INF/web.xml").getURL().toURI() + "/../..").normalize().toURL(); } catch (URISyntaxException e) { unexpectedException(e); } this.baseURL = trimEnd(base.toExternalForm(), "/"); // 读取configuration files List<ConfigurationFile> configurationFiles = createLinkedList(); Set<String> parsedNames = createHashSet(); for (NamedResource namedResource : resources) { ConfigurationFile configurationFile = parseConfigurationFile(namedResource, parsedNames); if (configurationFile != null) { configurationFiles.add(configurationFile); } } this.configurationFiles = configurationFiles.toArray(new ConfigurationFile[configurationFiles.size()]); } private ConfigurationFile parseConfigurationFile(final NamedResource namedResource, final Set<String> parsedNames) { URL url; try { url = namedResource.resource.getURL(); } catch (IOException e) { unexpectedException(e); return null; } String name = url.toExternalForm(); if (name.startsWith(baseURL)) { name = name.substring(baseURL.length()); } if (parsedNames.contains(name)) { return null; } parsedNames.add(name); final List<ConfigurationFile> importedConfigurationFiles = createLinkedList(); Element rootElement; try { rootElement = DomUtil.readDocument(name, url, new ElementFilter() { public org.dom4j.Element filter(org.dom4j.Element e) throws Exception { // 删除schemaLocation org.dom4j.Attribute attr = e.attribute(new QName("schemaLocation", new Namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"))); if (attr != null) { e.remove(attr); } // 导入beans:import,并删除element if ("http://www.springframework.org/schema/beans".equals(e.getNamespaceURI()) && "import".equals(e.getName())) { String importedResourceName = trimToNull(e.attributeValue("resource")); if (importedResourceName != null) { Resource importedResource; if (importedResourceName.contains(":")) { importedResource = loader.getResource(importedResourceName); } else { importedResource = namedResource.resource.createRelative(importedResourceName); } ConfigurationFile importedConfigurationFile = parseConfigurationFile(new NamedResource( importedResourceName, importedResource), parsedNames); if (importedConfigurationFile != null) { importedConfigurationFiles.add(importedConfigurationFile); } } return null; } return e; } }); } catch (Exception e) { rootElement = new Element("read-error").setText(getStackTrace(getRootCause(e))); } return new ConfigurationFile(namedResource.name, url, importedConfigurationFiles.toArray(new ConfigurationFile[importedConfigurationFiles.size()]), rootElement); } public ConfigurationFile[] toConfigurationFiles() { return configurationFiles; } private static class NamedResource { private final String name; private final Resource resource; public NamedResource(String name, Resource resource) { this.name = name; this.resource = resource; } } }