/*
* 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;
import static com.alibaba.citrus.test.TestEnvStatic.*;
import static com.alibaba.citrus.test.TestUtil.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static javax.xml.XMLConstants.*;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.alibaba.citrus.springext.Namespaces;
import com.alibaba.citrus.springext.Schema;
import com.alibaba.citrus.springext.Schema.Element;
import com.alibaba.citrus.springext.Schemas;
import com.alibaba.citrus.springext.impl.SchemaImpl;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.io.InputStreamSource;
public class SchemaSetTests {
private Schema s1;
private Schema s2;
private Schema s3;
private Schema s4;
private NamespacesSchemas schemas1;
private Schemas schemas2;
private SchemaSet set1;
@Before
public void init_data1() {
// create schema
s1 = createSchemaFromFile("b/c", "schema/ns.xsd");
s2 = createSchemaFromFile("b/d", "schema/ns.xsd");
s3 = createSchemaFromFile("a/b/c", "schema/ns.xsd");
s4 = createSchemaFromFile("a/b/d", "schema/ns.xsd");
// mocks to Schemas
schemas1 = createMock(NamespacesSchemas.class);
schemas2 = createMock(Schemas.class);
Map<String, Schema> nameToSchemas1 = createHashMap();
nameToSchemas1.put("b/c", s1);
nameToSchemas1.put("b/d", s2);
expect(schemas1.getNamedMappings()).andReturn(nameToSchemas1);
Set<String> namespaces1 = createHashSet();
namespaces1.add("http://www.alibaba.com/schema/test");
namespaces1.add("http://www.springframework.com/schema/p");
namespaces1.add("http://www.springframework.com/schema/c");
expect(schemas1.getAvailableNamespaces()).andReturn(namespaces1);
Map<String, Schema> nameToSchemas2 = createHashMap();
nameToSchemas2.put("a/b/c", s3);
nameToSchemas2.put("a/b/d", s4);
expect(schemas2.getNamedMappings()).andReturn(nameToSchemas2);
replay(schemas1, schemas2);
// schema set
set1 = new SchemaSet(schemas1, schemas2);
}
@Test
public void new_noSchemas() {
try {
new SchemaSet((Schemas[]) null);
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("schemasList"));
}
try {
new SchemaSet(new Schemas[0]);
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("schemasList"));
}
}
@Test
public void getNamespaceMappings_getAvailableNamespaces() {
Map<String, Set<Schema>> namespaceMappings = set1.getNamespaceMappings();
Set<String> namespaces = set1.getAvailableNamespaces();
assertEquals(3, namespaces.size());
assertEquals(3, namespaceMappings.size());
assertTrue(namespaces.contains("http://www.alibaba.com/schema/test"));
assertTrue(namespaces.contains("http://www.springframework.com/schema/p"));
assertTrue(namespaces.contains("http://www.springframework.com/schema/c"));
assertTrue(namespaceMappings.containsKey("http://www.alibaba.com/schema/test"));
assertTrue(namespaceMappings.containsKey("http://www.springframework.com/schema/p"));
assertTrue(namespaceMappings.containsKey("http://www.springframework.com/schema/c"));
assertEquals(4, namespaceMappings.get("http://www.alibaba.com/schema/test").size());
assertEquals(0, namespaceMappings.get("http://www.springframework.com/schema/p").size());
assertEquals(0, namespaceMappings.get("http://www.springframework.com/schema/c").size());
}
@Test
public void getNamedMappings() {
Map<String, Schema> schemas = createHashMap();
schemas.putAll(set1.getNamedMappings());
assertSame(s1, schemas.remove("b/c"));
assertSame(s2, schemas.remove("b/d"));
assertSame(s3, schemas.remove("a/b/c"));
assertSame(s4, schemas.remove("a/b/d"));
assertTrue(schemas.isEmpty());
}
@Test
public void findSchema() {
// empty
try {
set1.findSchema(null);
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("systemId"));
}
try {
set1.findSchema(" ");
fail();
} catch (IllegalArgumentException e) {
assertThat(e, exception("systemId"));
}
// not found
assertSame(null, set1.findSchema("b/e"));
// priority
assertSame(s1, set1.findSchema("b/c"));
assertSame(s2, set1.findSchema("b/d"));
assertSame(s3, set1.findSchema("a/b/c")); // 同时匹配b/c和a/b/c,但后者优先
assertSame(s4, set1.findSchema("a/b/d")); // 同时匹配b/d和a/b/d,但后者优先
// normalize
assertSame(s3, set1.findSchema(" a/b/c "));
assertSame(s3, set1.findSchema(" a//b\\/c "));
assertSame(s3, set1.findSchema(" http://localhost:8080/a//b\\/c "));
}
@Test
public void toString_() {
String str = "";
str += "SchemaSet [\n";
str += " [1/4] a/b/c\n";
str += " [2/4] a/b/d\n";
str += " [3/4] b/c\n";
str += " [4/4] b/d\n";
str += "]";
assertEquals(str, set1.toString());
}
private Schema all;
private Schema x;
private Schema y;
private Schema z;
private Schema a;
private Schema b;
private Schemas schemas;
private SchemaSet set2;
@Before
public void init_data2() {
// create schema:
all = createSchemaFromFile("schema/all.xsd");
x = createSchemaFromFile("schema/x.xsd");
y = createSchemaFromFile("schema/y.xsd");
z = createSchemaFromFile("schema/z.xsd");
a = createSchemaFromFile("schema/a.xsd");
b = createSchemaFromFile("schema/b.xsd");
// mocks to Schemas
schemas = createMock(Schemas.class);
Map<String, Schema> nameToSchemas = createHashMap();
nameToSchemas.put("schema/all.xsd", all);
nameToSchemas.put("schema/x.xsd", x);
nameToSchemas.put("schema/y.xsd", y);
nameToSchemas.put("schema/z.xsd", z);
nameToSchemas.put("schema/a.xsd", a);
nameToSchemas.put("schema/b.xsd", b);
expect(schemas.getNamedMappings()).andReturn(nameToSchemas);
replay(schemas);
// schema set
set2 = new SchemaSet(schemas);
}
@Test
public void getAnnotation() {
String annotation1 = all.getElement("test").getAnnotation();
String annotation2 = all.getElement("testa").getAnnotation();
String annotation3 = all.getElement("testb").getAnnotation();
assertEquals("line 1\n" +
"line 2\n" +
"line 3", annotation1);
assertEquals("line 1/a\n" +
"line 2/a\n" +
"line 3/a", annotation2);
assertEquals(null, annotation3);
}
@Test
public void getAllElements() {
// all -> x, y, z
// x -> a, z
// y -> b, z
// z ->
// a ->
// b ->
assertArrayEquals(new String[] { "test", "testa", "testb", "testx", "testy", "testz" },
getElements(set2, "all"));
assertArrayEquals(new String[] { "testa", "testx", "testz" }, getElements(set2, "x"));
assertArrayEquals(new String[] { "testb", "testy", "testz" }, getElements(set2, "y"));
assertArrayEquals(new String[] { "testz" }, getElements(set2, "z"));
assertArrayEquals(new String[] { "testa" }, getElements(set2, "a"));
assertArrayEquals(new String[] { "testb" }, getElements(set2, "b"));
}
private String[] getElements(Schemas schemas, String name) {
Schema schema = schemas.getNamedMappings().get("schema/" + name + ".xsd");
Collection<Element> elements = schema.getElements();
String[] elementNames = new String[elements.size()];
int i = 0;
for (Element element : elements) {
String elementName = element.getName();
assertGetElement(schema, element, "Element[" + elementName + "]");
elementNames[i++] = elementName;
}
return elementNames;
}
private void assertGetElement(Schema schema, Element element, String toString) {
assertSame(element, schema.getElement(element.getName()));
assertSame(null, schema.getElement(null));
assertSame(null, schema.getElement("not exists"));
assertEquals(toString, element.toString());
}
@Test
public void processIncludes() throws Exception {
// all -> x, y, z
// x -> a, z
// y -> b, z
// z ->
// a ->
// b ->
Map<String, Schema> nameToSchemas = set2.getNamedMappings();
assertEquals(6, nameToSchemas.size());
assertSame(all, nameToSchemas.get("schema/all.xsd"));
assertSame(x, nameToSchemas.get("schema/x.xsd"));
assertSame(y, nameToSchemas.get("schema/y.xsd"));
assertSame(z, nameToSchemas.get("schema/z.xsd"));
assertSame(a, nameToSchemas.get("schema/a.xsd"));
assertSame(b, nameToSchemas.get("schema/b.xsd"));
// 检查内容: all被转换
Iterator<org.dom4j.Element> i = getNodes(all, "http://www.alibaba.com/schema/test", 6).iterator();
assertEquals("schema/a.xsd", i.next().attributeValue("schemaLocation"));
assertEquals("schema/z.xsd", i.next().attributeValue("schemaLocation"));
assertEquals("schema/x.xsd", i.next().attributeValue("schemaLocation"));
assertEquals("schema/b.xsd", i.next().attributeValue("schemaLocation"));
assertEquals("schema/y.xsd", i.next().attributeValue("schemaLocation"));
assertEquals("test", i.next().attributeValue("name"));
// 检查内容: x被转换
i = getNodes(x, null, 1).iterator();
assertEquals("testx", i.next().attributeValue("name"));
// 检查内容: y被转换
i = getNodes(y, null, 1).iterator();
assertEquals("testy", i.next().attributeValue("name"));
}
private List<org.dom4j.Element> getNodes(Schema schema, String ns, int count) {
org.dom4j.Element root = schema.getDocument().getRootElement();
assertEquals(W3C_XML_SCHEMA_NS_URI, root.getNamespaceURI());
assertEquals("schema", root.getName());
assertEquals(ns, root.attributeValue("targetNamespace"));
@SuppressWarnings("unchecked")
List<org.dom4j.Element> elements = root.elements();
assertEquals(count, elements.size());
return elements;
}
private Schema createSchemaFromFile(String fileName) {
return createSchemaFromFile(fileName, fileName);
}
private Schema createSchemaFromFile(String name, final String fileName) {
return SchemaImpl.create(name, null, true, fileName + " desc", new InputStreamSource() {
public InputStream getInputStream() throws IOException {
return new FileInputStream(new File(srcdir, fileName));
}
});
}
interface NamespacesSchemas extends Schemas, Namespaces {
}
}