/* * 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.impl; import static com.alibaba.citrus.springext.ContributionType.*; import static com.alibaba.citrus.test.TestEnvStatic.*; import static com.alibaba.citrus.test.TestUtil.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.Map; import com.alibaba.citrus.springext.ConfigurationPoint; import com.alibaba.citrus.springext.Contribution; import com.alibaba.citrus.springext.ContributionType; import com.alibaba.citrus.springext.contrib.MyBeanDefinitionDecorator; import com.alibaba.citrus.springext.contrib.MyBeanDefinitionDecorator2; import com.alibaba.citrus.springext.contrib.MyBeanDefinitionParser; import com.alibaba.citrus.springext.contrib.MyBeanDefinitionParser2; import com.alibaba.citrus.springext.contrib.simple.Test1; import com.alibaba.citrus.springext.contrib.simple.Test2; import com.alibaba.citrus.springext.contrib.simple.Test3; import com.alibaba.citrus.springext.contrib.simple.Test4; import com.alibaba.citrus.springext.support.SchemaUtil; import com.alibaba.citrus.springext.support.context.XmlApplicationContext; import com.alibaba.citrus.test.TestEnvStatic; import com.alibaba.citrus.test.runner.TestNameAware; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.core.io.FileSystemResource; @RunWith(TestNameAware.class) public class ContributionTests { private ConfigurationPointsImpl cps; static { TestEnvStatic.init(); } @Test public void test6_contributionAware() throws Exception { createConfigurationPoints("TEST-INF/test6/cps"); ConfigurationPointImpl cp = (ConfigurationPointImpl) cps.getConfigurationPointByName("cp1"); assertEquals(6, cp.getContributions().size()); assertSame(cps, cp.getConfigurationPoints()); Iterator<Contribution> i = cp.getContributions().iterator(); Contribution contrib; // cp1:my1, MyBeanDefinitionParser contrib = i.next(); MyBeanDefinitionParser c1 = getContributionImplementation(cp, BEAN_DEFINITION_PARSER, "my1", MyBeanDefinitionParser.class); assertNotNull(c1); // cp1:my1, MyBeanDefinitionDecorator contrib = i.next(); MyBeanDefinitionDecorator c2 = getContributionImplementation(cp, BEAN_DEFINITION_DECORATOR, "my1", MyBeanDefinitionDecorator.class); assertNotNull(c2); assertSame(cp, contrib.getConfigurationPoint()); // cp1:my1, MyBeanDefinitionDecorator contrib = i.next(); MyBeanDefinitionDecorator c3 = getContributionImplementation(cp, BEAN_DEFINITION_DECORATOR_FOR_ATTRIBUTE, "my1", MyBeanDefinitionDecorator.class); assertNotNull(c3); assertSame(cp, contrib.getConfigurationPoint()); // cp1:my2, MyBeanDefinitionParser2 contrib = i.next(); MyBeanDefinitionParser2 c4 = getContributionImplementation(cp, BEAN_DEFINITION_PARSER, "my2", MyBeanDefinitionParser2.class); assertSame(contrib, c4.getContribution()); assertSame(cp, contrib.getConfigurationPoint()); // cp1:my2, MyBeanDefinitionDecorator2 contrib = i.next(); MyBeanDefinitionDecorator2 c5 = getContributionImplementation(cp, BEAN_DEFINITION_DECORATOR, "my2", MyBeanDefinitionDecorator2.class); assertSame(contrib, c5.getContribution()); assertSame(cp, contrib.getConfigurationPoint()); // cp1:my2, MyBeanDefinitionDecorator2 contrib = i.next(); MyBeanDefinitionDecorator2 c6 = getContributionImplementation(cp, BEAN_DEFINITION_DECORATOR_FOR_ATTRIBUTE, "my2", MyBeanDefinitionDecorator2.class); assertSame(contrib, c6.getContribution()); assertSame(cp, contrib.getConfigurationPoint()); } @Test public void expandConfigurationPointElements() throws Exception { createConfigurationPoints(null); ConfigurationPoint cp1 = cps.getConfigurationPointByName("my/cp1"); ConfigurationPoint cp2 = cps.getConfigurationPointByName("my/cp2"); String test1 = getSchemaText(cp1.getContribution("test1", BEAN_DEFINITION_PARSER)); String test2 = getSchemaText(cp1.getContribution("test2", BEAN_DEFINITION_PARSER)); String test3 = getSchemaText(cp2.getContribution("test3", BEAN_DEFINITION_PARSER)); String test4 = getSchemaText(cp2.getContribution("test4", BEAN_DEFINITION_PARSER)); // 假如ns已经import了,确保不重复import;确保不import自己所在的cp。 assertSchemaText(test1, 1); assertSchemaText(test2, 2); assertSchemaText(test3, 3); assertSchemaText(test4, 4); } @Test public void getAnnotation() { createConfigurationPoints("TEST-INF/test9/cps"); ConfigurationPoint cp = cps.getConfigurationPointByName("my/services"); Contribution service1 = cp.getContribution("service1", ContributionType.BEAN_DEFINITION_PARSER); Contribution service2 = cp.getContribution("service2", ContributionType.BEAN_DEFINITION_PARSER); assertEquals("this\n" + "is\n" + "service1", service1.getAnnotation()); assertEquals(null, service2.getAnnotation()); } private void assertSchemaText(String text, int caseNo) { text = text.replaceAll("\\s+", " "); // 去除换行,便于检查 String import_cp1 = "<xsd:import namespace=\"http://www.alibaba.com/schema/my/cp1\""; String import_cp1_location = "<xsd:import namespace=\"http://www.alibaba.com/schema/my/cp1\" schemaLocation=\"my-cp1.xsd\"/>"; String import_cp2 = "<xsd:import namespace=\"http://www.alibaba.com/schema/my/cp2\""; String import_cp2_location = "<xsd:import namespace=\"http://www.alibaba.com/schema/my/cp2\" schemaLocation=\"my-cp2.xsd\"/>"; String import_cp2_specificLocation = "<xsd:import namespace=\"http://www.alibaba.com/schema/my/cp2\" schemaLocation=\"http://localhost:8080/schema/my-cp2.xsd\"/>"; String ns_cp1 = "<xsd:schema.+xmlns:cp1=\"http://www\\.alibaba\\.com/schema/my/cp1\""; String ns_cp2 = "<xsd:schema.+xmlns:cp2ns=\"http://www\\.alibaba\\.com/schema/my/cp2\""; String targetNamespace_cp1 = "<xsd:schema.+targetNamespace=\"http://www\\.alibaba\\.com/schema/my/cp1\""; String defaultNamespace_cp1 = "<xsd:schema.+xmlns=\"http://www\\.alibaba\\.com/schema/my/cp1\""; String targetNamespace_cp2 = "<xsd:schema.+targetNamespace=\"http://www\\.alibaba\\.com/schema/my/cp2\""; String defaultNamespace_cp2 = "<xsd:schema.+xmlns=\"http://www\\.alibaba\\.com/schema/my/cp2\""; String any_cp1 = "<xsd:choice>" // + " <xsd:element ref=\"cp1:test1\"/>" // + " <xsd:element ref=\"cp1:test2\"/>" // + " <xsd:element ref=\"cp1:object1\"/>" // + " </xsd:choice>"; String any_cp1_optional = "<xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">" // + " <xsd:element ref=\"cp1:test1\"/>" // + " <xsd:element ref=\"cp1:test2\"/>" // + " <xsd:element ref=\"cp1:object1\"/>" // + " </xsd:choice>"; String any_cp2_optional = "<xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">" // + " <xsd:element ref=\"cp2ns:test3\"/>" // + " <xsd:element ref=\"cp2ns:test4\"/>" // + " </xsd:choice>"; switch (caseNo) { case 1: assertThat(text, not(containsString(import_cp1))); assertThat(text, containsString(import_cp2_specificLocation)); assertThat(text, containsRegex(ns_cp1)); assertThat(text, containsRegex(ns_cp2)); assertThat(text, containsRegex(targetNamespace_cp1)); assertThat(text, containsRegex(defaultNamespace_cp1)); assertThat(text, containsString(any_cp1_optional)); assertThat(text, containsString(any_cp2_optional)); break; case 2: assertThat(text, not(containsString(import_cp1))); assertThat(text, containsString(import_cp2_location)); assertThat(text, containsRegex(ns_cp1)); assertThat(text, containsRegex(ns_cp2)); assertThat(text, containsRegex(targetNamespace_cp1)); assertThat(text, containsRegex(defaultNamespace_cp1)); assertThat(text, containsString(any_cp1_optional)); assertThat(text, containsString(any_cp2_optional)); break; case 3: case 4: assertThat(text, containsString(import_cp1_location)); assertThat(text, not(containsString(import_cp2))); assertThat(text, containsRegex(ns_cp1)); assertThat(text, not(containsRegex(ns_cp2))); assertThat(text, containsRegex(targetNamespace_cp2)); assertThat(text, containsRegex(defaultNamespace_cp2)); assertThat(text, containsString(any_cp1)); assertThat(text, not(containsString(any_cp2_optional))); break; default: fail(); return; } } private String getSchemaText(Contribution contrib) throws IOException { return SchemaUtil.getDocumentText(contrib.getSchemas().getMainSchema().getDocument(), null); } @Test public void parse_import_each_other() throws Exception { ApplicationContext ctx = new XmlApplicationContext(new FileSystemResource(new File(srcdir, "test-import-each-other.xml"))); Test1 test1 = new Test1(new Test3(new Test1()), new Test4(new Test2())); Test3 test3 = new Test3(new Test1()); assertEquals(test1, ctx.getBean("test1")); assertEquals(test3, ctx.getBean("test3")); } private <T> T getContributionImplementation(ConfigurationPointImpl cp, ContributionType type, String name, Class<T> expectedClass) throws Exception { Map<?, ?> mapField; switch (type) { case BEAN_DEFINITION_PARSER: mapField = getFieldValue(cp, "parsers", Map.class); break; case BEAN_DEFINITION_DECORATOR: mapField = getFieldValue(cp, "decorators", Map.class); break; case BEAN_DEFINITION_DECORATOR_FOR_ATTRIBUTE: mapField = getFieldValue(cp, "attributeDecorators", Map.class); break; default: fail(); return null; } assertNotNull(mapField); return expectedClass.cast(mapField.get(name)); } private void createConfigurationPoints(String location) { cps = new ConfigurationPointsImpl((ClassLoader) null, location); } }