/* * Copyright (c) 2002-2013 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; import static com.alibaba.citrus.util.CollectionUtil.*; import static java.util.Collections.*; import static javax.xml.XMLConstants.*; import static org.junit.Assert.*; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Set; import com.alibaba.citrus.springext.ConfigurationPoint; import com.alibaba.citrus.springext.Contribution; import com.alibaba.citrus.springext.Schema; import com.alibaba.citrus.springext.support.SpringExtSchemaSet.ConfigurationPointItem; import com.alibaba.citrus.springext.support.SpringExtSchemaSet.NamespaceItem; import com.alibaba.citrus.springext.support.SpringExtSchemaSet.SpringPluggableItem; import com.alibaba.citrus.springext.support.SpringExtSchemaSet.TreeItem; import com.alibaba.citrus.test.TestEnvStatic; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.QName; import org.junit.Before; import org.junit.Test; public class SpringExtSchemaSetTests { private SpringExtSchemaSet schemas; private List<SpringPluggableItem> springItems; private List<SpringPluggableItem> noSchemaItems; private List<ConfigurationPointItem> configurationPointItems; private List<ConfigurationPointItem> configurationPointAllItems; static { TestEnvStatic.init(); } @Before public void init() { schemas = new SpringExtSchemaSet("TEST-INF/test14/cps"); NamespaceItem[] items = schemas.getIndependentItems(); springItems = filter(SpringPluggableItem.class, items, true); noSchemaItems = filter(SpringPluggableItem.class, items, false); configurationPointItems = filter(ConfigurationPointItem.class, items, true); configurationPointAllItems = filter(ConfigurationPointItem.class, schemas.getAllItems(), true); } @Test public void test14_parentConfigurationPoints() { // 依赖关系: // <a1> -> b, c // <b1> -> c // <c1> -> a, h // <d1> -> d // <e1> -> f // <f1> -> g // <f2> -> h // <g1> assertArrayEquals(new String[] { "c" }, getParentConfigurationPoints("a")); assertArrayEquals(new String[] { "a" }, getParentConfigurationPoints("b")); assertArrayEquals(new String[] { "a", "b" }, getParentConfigurationPoints("c")); assertArrayEquals(new String[] { "d" }, getParentConfigurationPoints("d")); assertArrayEquals(new String[] { }, getParentConfigurationPoints("e")); assertArrayEquals(new String[] { "e" }, getParentConfigurationPoints("f")); assertArrayEquals(new String[] { "f" }, getParentConfigurationPoints("g")); assertArrayEquals(new String[] { "c", "f" }, getParentConfigurationPoints("h")); } @Test public void test14_configurationPointAllItems() { assertEquals(8, configurationPointAllItems.size()); Iterator<ConfigurationPointItem> i = configurationPointAllItems.iterator(); assertEquals("http://localhost/a", i.next().getNamespace()); assertEquals("http://localhost/b", i.next().getNamespace()); assertEquals("http://localhost/c", i.next().getNamespace()); assertEquals("http://localhost/d", i.next().getNamespace()); assertEquals("http://localhost/e", i.next().getNamespace()); assertEquals("http://localhost/f", i.next().getNamespace()); assertEquals("http://localhost/g", i.next().getNamespace()); assertEquals("http://localhost/h", i.next().getNamespace()); assertFalse(i.hasNext()); } @Test public void test14_configurationPointItems() { assertEquals(3, configurationPointItems.size()); assertEquals(true, configurationPointItems.get(0).hasChildren()); assertEquals("http://localhost/b {\n" + " b1 {\n" + " http://localhost/c {\n" + // a, b -> c -> a 循环引用被切断,变成 b -> c -> a " c1 {\n" + // 引用两个configuration points " http://localhost/a\n" + // c -> a " http://localhost/h\n" + // c, f -> h 被两个element引用 " }\n" + " }\n" + " }\n" + "}", configurationPointItems.get(0).dump()); assertEquals(false, configurationPointItems.get(1).hasChildren()); assertEquals("http://localhost/d", // 自己引用自己,就当没引用 configurationPointItems.get(1).dump()); assertEquals(true, configurationPointItems.get(2).hasChildren()); assertEquals("http://localhost/e {\n" + // e -> f " e1 {\n" + " http://localhost/f {\n" + // f在不同的标签中分别引用g和h " f1 {\n" + " http://localhost/g\n" + " }\n" + "\n" + " f2 {\n" + " http://localhost/h\n" + // c, f -> h,h也被c引用 " }\n" + " }\n" + " }\n" + "}", configurationPointItems.get(2).dump()); } @Test public void test14_configurationPointItems_includingAllContributions() { configurationPointItems = filter(ConfigurationPointItem.class, schemas.getIndependentItems(true), true); assertEquals(3, configurationPointItems.size()); assertEquals(true, hasGrandChildren(configurationPointItems.get(0))); assertEquals("http://localhost/b {\n" + " b1 {\n" + " http://localhost/c {\n" + // a, b -> c -> a 循环引用被切断,变成 b -> c -> a " c1 {\n" + // 引用两个configuration points " http://localhost/a {\n" + // c -> a " a1\n" + " }\n" + "\n" + " http://localhost/h {\n" + // c, f -> h 被两个element引用 " h1\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}", configurationPointItems.get(0).dump()); assertEquals(false, hasGrandChildren(configurationPointItems.get(1))); assertEquals("http://localhost/d {\n" + // 自己引用自己,就当没引用 " d1\n" + "}", configurationPointItems.get(1).dump()); assertEquals(true, hasGrandChildren(configurationPointItems.get(2))); assertEquals("http://localhost/e {\n" + // e -> f " e1 {\n" + " http://localhost/f {\n" + // f在不同的标签中分别引用g和h " f1 {\n" + " http://localhost/g {\n" + " g1\n" + " }\n" + " }\n" + "\n" + " f2 {\n" + " http://localhost/h {\n" + // c, f -> h,h也被c引用 " h1\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}", configurationPointItems.get(2).dump()); } @Test public void test14_with_or_without_allContributions() { NamespaceItem[] itemsAll = schemas.getAllItems(); NamespaceItem[] items = schemas.getIndependentItems(); NamespaceItem[] itemsWithAllContributions = schemas.getIndependentItems(true); // 多次调用值不变 assertSame(items, schemas.getIndependentItems()); assertSame(items, schemas.getIndependentItems(false)); assertSame(itemsWithAllContributions, schemas.getIndependentItems(true)); assertSame(itemsAll, schemas.getAllItems()); } @Test public void test14_springItems() { boolean found = false; for (SpringPluggableItem item : springItems) { if (item.getNamespace().equals("http://www.springframework.org/schema/beans")) { found = true; } } assertTrue(found); } @Test public void test14_noSchemaItems() { boolean found = false; for (SpringPluggableItem item : noSchemaItems) { if (item.getNamespace().equals("http://www.springframework.org/schema/p")) { found = true; } } assertTrue(found); } private <I> List<I> filter(Class<I> type, NamespaceItem[] items, boolean withSchemas) { List<I> list = createLinkedList(); for (NamespaceItem item : items) { if (type.isInstance(item) && withSchemas == !item.getSchemas().isEmpty()) { list.add(type.cast(item)); } } return list; } private String[] getParentConfigurationPoints(String cpName) { ConfigurationPoint cp = schemas.getConfigurationPoints().getConfigurationPointByName(cpName); List<String> depList = createLinkedList(); for (Contribution contribution : cp.getDependingContributions()) { depList.add(contribution.getConfigurationPoint().getName()); } return depList.toArray(new String[0]); } @Test public void test15_parentConfigurationPoints() { // services/s1 includes included-schema.xsd // services/s2 includes included-schema.xsd // services/s3 no includes schemas = new SpringExtSchemaSet("TEST-INF/test15/cps"); // 测试interceptors是否被s1和s2依赖 ConfigurationPoint interceptors = schemas.getConfigurationPoints().getConfigurationPointByName("interceptors"); Collection<Contribution> contributions = interceptors.getDependingContributions(); assertEquals(2, contributions.size()); for (Contribution contribution : contributions) { assertEquals("services", contribution.getConfigurationPoint().getName()); assertTrue("s1".equals(contribution.getName()) || "s2".equals(contribution.getName())); } // 测试included-schema.xsd中的anyElement是否被替换。 Schema includedSchema = schemas.getNamedMappings().get("localhost/included-schema.xsd"); Document doc = includedSchema.getDocument(); Namespace xsd = DocumentHelper.createNamespace("xsd", W3C_XML_SCHEMA_NS_URI); Element choice = doc.getRootElement() .element(QName.get("group", xsd)) .element(QName.get("sequence", xsd)) .element(QName.get("choice", xsd)); assertEquals("0", choice.attributeValue("minOccurs")); assertEquals("unbounded", choice.attributeValue("maxOccurs")); Set<String> refs = createTreeSet(); for (Object e : choice.elements()) { refs.add(((Element) e).attributeValue("ref")); } assertArrayEquals(new String[] { "interceptors:i1", "interceptors:i2" }, refs.toArray()); } @Test public void test15_includeWithRelativePath() { schemas = new SpringExtSchemaSet("TEST-INF/test15/cps"); Schema schema = schemas.getNamedMappings().get("localhost/transports/http/configuration/http-conf.xsd"); List<Schema.Element> elements = createArrayList(schema.getElements()); sort(elements, new Comparator<Schema.Element>() { @Override public int compare(Schema.Element o1, Schema.Element o2) { return o1.getName().compareTo(o2.getName()); } }); assertEquals("[Element[client], Element[server]]", elements.toString()); } private boolean hasGrandChildren(TreeItem item) { for (TreeItem child : item.getChildren()) { if (child.hasChildren()) { return true; } } return false; } }