/* * 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.impl; import static com.alibaba.citrus.test.TestUtil.*; import static org.junit.Assert.*; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.LinkedList; import com.alibaba.citrus.springext.ConfigurationPointException; import com.alibaba.citrus.springext.Schema.Transformer; import com.alibaba.citrus.springext.support.SchemaUtil; import com.alibaba.citrus.test.TestEnvStatic; import com.alibaba.citrus.util.io.ByteArrayInputStream; import com.alibaba.citrus.util.io.StreamUtil; import org.dom4j.Document; import org.junit.Before; import org.junit.Test; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamSource; public class SchemaBaseTests { private SchemaBaseImpl schema; // test data private InputStreamSource source; private InputStreamSource illegalSource; private Transformer transformer; private Transformer transformer2; private Document document; private int analyzeCount; static { TestEnvStatic.init(); } @Before public void init() throws Exception { source = new ByteArrayResource("<hello></hello>".getBytes()); illegalSource = new ByteArrayResource("<hello>".getBytes()); transformer = new Transformer() { public void transform(Document document, String systemId) { document.getRootElement().addElement("world"); } }; transformer2 = new Transformer() { public void transform(Document document, String systemId) { document.getRootElement().addElement("hi"); } }; document = SchemaUtil.readDocument(new ByteArrayInputStream("<doc></doc>".getBytes()), "", true); schema = new SchemaBaseImpl(source); } @Test public void constructor_inputStreamSource() { try { new SchemaBaseImpl((InputStreamSource) null); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("no InputStreamSource provided")); } schema = new SchemaBaseImpl(source); assertFalse(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertNull(schema.getDocumentField()); assertNull(schema.getTransformedData()); } @Test public void constructor_documentSource() { try { new SchemaBaseImpl((Document) null); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("no Document provided")); } schema = new SchemaBaseImpl(document); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertSame(document, schema.getDocumentField()); assertNull(schema.getTransformedData()); } @Test public void transform() { try { schema.transform(null); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("no Transformer provided")); } // 按顺序执行transforms schema.transform(transformer2); // hi schema.transform(transformer); // world assertFalse(schema.isEverTransformed()); assertInputStream("<hello><hi/><world/></hello>", schema.getInputStream()); assertTrue(schema.isEverTransformed()); } @Test public void transform_doNow() { try { schema.transform(null, true); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("no Transformer provided")); } // 按顺序执行transforms schema.transform(transformer2, true); // hi schema.transform(transformer, true); // world assertTrue(schema.isEverTransformed()); assertInputStream("<hello><hi/><world/></hello>", schema.getInputStream()); assertTrue(schema.isEverTransformed()); } @Test public void getOriginalInputStream_exception() { // 情况1. parse时调用 schema = new SchemaBaseImpl(new InputStreamSource() { public InputStream getInputStream() throws IOException { throw new IOException("hi"); } @Override public String toString() { return "mysource"; } }); schema.transform(transformer); try { schema.getInputStream(); fail(); } catch (ConfigurationPointException e) { assertThat(e, exception("Failed to read text of schema file: myschema, source=mysource")); } // 情况2. getInputStream时调用(无transformer) schema = new SchemaBaseImpl(new InputStreamSource() { public InputStream getInputStream() throws IOException { throw new IOException("hi"); } @Override public String toString() { return "mysource"; } }); try { schema.getInputStream(); fail(); } catch (ConfigurationPointException e) { assertThat(e, exception("Failed to read text of schema file: myschema, source=mysource")); } } @Test public void inputStreamSource_noParse_noTransform() { schema = new SchemaBaseImpl(source); assertInputStream("<hello></hello>", schema.getInputStream()); assertFalse(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertNull(schema.getDocumentField()); assertNull(schema.getTransformedData()); } @Test public void inputStreamSource_noParse_noTransform_illegalSource() { schema = new SchemaBaseImpl(illegalSource); assertInputStream("<hello>", schema.getInputStream()); assertFalse(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertNull(schema.getDocumentField()); assertNull(schema.getTransformedData()); } @Test public void inputStreamSource_withParse_withTransform() { Document doc; byte[] data; schema.transform(transformer); assertFalse(schema.getTransformersQueue().isEmpty()); assertInputStream("<hello><world/></hello>", schema.getInputStream()); assertTrue(schema.isParsed()); assertTrue(schema.isEverTransformed()); assertNotNull(doc = schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNotNull(data = schema.getTransformedData()); // 第二次取,不会再次生成data assertInputStream("<hello><world/></hello>", schema.getInputStream()); assertSame(data, schema.getTransformedData()); assertSame(doc, schema.getDocumentField()); // 再次transform,不会重新parse schema.transform(transformer); assertInputStream("<hello><world/><world/></hello>", schema.getInputStream()); assertSame(doc, schema.getDocumentField()); } @Test public void inputStreamSource_withParse_withTransform_illegalSource() { schema = new SchemaBaseImpl(illegalSource); schema.transform(transformer); assertFalse(schema.getTransformersQueue().isEmpty()); assertInputStream("<hello>", schema.getInputStream()); assertTrue(schema.isParsed()); assertTrue(schema.isEverTransformed()); assertNull(schema.getDocumentField()); assertNull(schema.getTransformedData()); assertTrue(schema.getTransformersQueue().isEmpty()); // 第二次取data assertInputStream("<hello>", schema.getInputStream()); assertNull(schema.getTransformedData()); } @Test public void documentSource_skipParse_noTransform() { byte[] data; schema = new SchemaBaseImpl(document); assertTrue(schema.getTransformersQueue().isEmpty()); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertInputStream("<doc/>", schema.getInputStream()); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertSame(document, schema.getDocumentField()); assertNotNull(data = schema.getTransformedData()); // 第二次取,不会再次生成data assertInputStream("<doc/>", schema.getInputStream()); assertSame(document, schema.getDocumentField()); assertSame(data, schema.getTransformedData()); } @Test public void documentSource_skipParse_withTransform() { byte[] data; schema = new SchemaBaseImpl(document); schema.transform(transformer); assertFalse(schema.getTransformersQueue().isEmpty()); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertInputStream("<doc><world/></doc>", schema.getInputStream()); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertTrue(schema.isEverTransformed()); assertSame(document, schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNotNull(data = schema.getTransformedData()); // 第二次取,不会再次生成data assertInputStream("<doc><world/></doc>", schema.getInputStream()); assertSame(document, schema.getDocumentField()); assertSame(data, schema.getTransformedData()); // 再次transform,不会重新parse schema.transform(transformer); assertInputStream("<doc><world/><world/></doc>", schema.getInputStream()); assertSame(document, schema.getDocumentField()); } @Test public void inputStreamSource_noTransform_analyze() { schema.analyze(); assertTrue(schema.isParsed()); assertTrue(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertEquals(1, analyzeCount); // 不会重复调用analyze schema.analyze(); assertEquals(1, analyzeCount); // 尽管document存在,由于没有经过transform,故inputStream仍然直接从inputStreamSource取得。 assertInputStream("<hello></hello>", schema.getInputStream()); assertNull(schema.getTransformedData()); } @Test public void inputStreamSource_withTransform_analyze() { schema.transform(transformer); schema.analyze(); assertTrue(schema.isParsed()); assertTrue(schema.isAnalyzed()); assertTrue(schema.isEverTransformed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertEquals(1, analyzeCount); // 不会重复调用analyze schema.analyze(); assertEquals(1, analyzeCount); assertInputStream("<hello><world/></hello>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } @Test public void documentSource_noTransform_analyze() { schema = new SchemaBaseImpl(document); schema.analyze(); assertTrue(schema.isParsed()); assertTrue(schema.isAnalyzed()); assertFalse(schema.isEverTransformed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertEquals(1, analyzeCount); // 不会重复调用analyze schema.analyze(); assertEquals(1, analyzeCount); assertInputStream("<doc/>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } @Test public void documentSource_withTransform_analyze() { schema = new SchemaBaseImpl(document); schema.transform(transformer); schema.analyze(); assertTrue(schema.isEverTransformed()); assertTrue(schema.isParsed()); assertTrue(schema.isAnalyzed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertEquals(1, analyzeCount); // 不会重复调用analyze schema.analyze(); assertEquals(1, analyzeCount); assertInputStream("<doc><world/></doc>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } private void assertInputStream(String bytes, InputStream inputStream) { String text = null; try { text = StreamUtil.readText(inputStream, "UTF-8", true); } catch (IOException e) { fail(e.getMessage()); } String decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; if (text.startsWith(decl)) { text = text.substring(decl.length()).trim().replaceAll(">\\s+<", "><"); } assertEquals(bytes, text); } @Test public void inputStreamSource_noTransform_getDocument() { schema.getDocument(); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); // 尽管document存在,由于没有经过transform,故inputStream仍然直接从inputStreamSource取得。 assertInputStream("<hello></hello>", schema.getInputStream()); assertNull(schema.getTransformedData()); } @Test public void inputStreamSource_withTransform_getDocument() { schema.transform(transformer); schema.getDocument(); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertInputStream("<hello><world/></hello>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } @Test public void documentSource_noTransform_getDocument() { schema = new SchemaBaseImpl(document); schema.getDocument(); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertInputStream("<doc/>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } @Test public void documentSource_withTransform_getDocument() { schema = new SchemaBaseImpl(document); schema.transform(transformer); schema.getDocument(); assertTrue(schema.isParsed()); assertFalse(schema.isAnalyzed()); assertNotNull(schema.getDocumentField()); assertTrue(schema.getTransformersQueue().isEmpty()); assertNull(schema.getTransformedData()); assertInputStream("<doc><world/></doc>", schema.getInputStream()); assertNotNull(schema.getTransformedData()); } @Test public void inputStreamSource_toString() { assertEquals("resource loaded from byte array", schema.toString()); } @Test public void documentSource_toString() { schema = new SchemaBaseImpl(document); assertEquals("generated-content", schema.toString()); } private class SchemaBaseImpl extends SchemaBase { private SchemaBaseImpl(InputStreamSource originalSource) { super(originalSource); } private SchemaBaseImpl(Document originalDocument) { super(originalDocument); } public boolean isParsed() { return getFieldValue(this, "parsed", Boolean.class); } public boolean isEverTransformed() { return getFieldValue(this, "everTransformed", Boolean.class); } public boolean isAnalyzed() { return getFieldValue(this, "analyzed", Boolean.class); } public Document getDocumentField() { return getFieldValue(this, "document", Document.class); } public byte[] getTransformedData() { return getFieldValue(this, "transformedData", byte[].class); } public LinkedList<?> getTransformersQueue() { return getFieldValue(this, "transformersQueue", LinkedList.class); } @Override public String getName() { return "myschema"; } @Override public String getVersion() { throw new UnsupportedOperationException(); } @Override public String getTargetNamespace() { throw new UnsupportedOperationException(); } @Override public String getPreferredNsPrefix() { throw new UnsupportedOperationException(); } @Override public String[] getIncludes() { throw new UnsupportedOperationException(); } @Override public Collection<Element> getElements() { throw new UnsupportedOperationException(); } @Override public String getNamespacePrefix() { throw new UnsupportedOperationException(); } @Override public String getSourceDescription() { throw new UnsupportedOperationException(); } @Override public String getText() { throw new UnsupportedOperationException(); } @Override public String getText(String charset) { throw new UnsupportedOperationException(); } @Override public String getText(String charset, Transformer transformer) { throw new UnsupportedOperationException(); } @Override public Element getElement(String elementName) { throw new UnsupportedOperationException(); } @Override public void setElements(Collection<Element> elements) { throw new UnsupportedOperationException(); } @Override protected void doAnalyze() { analyzeCount++; } } }