blob: ba3dbe361f8166e2ee29365ce29572a0929716d1 [file] [log] [blame]
/* Copyright 2004 The Apache Software Foundation
*
* 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 ValidatingXSRTests.detailed;
import com.foo.sample.HeadingDocument;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.impl.validator.ValidatingXMLStreamReader;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.openuri.test.location.LocationDocument;
import org.openuri.test.mixedContent.LetterDocument;
import org.openuri.test.mixedContent.NoMixedDocument;
import org.openuri.test.person.Name;
import org.openuri.test.person.PersonDocument;
import org.openuri.test.person.PersonType;
import tools.util.JarUtil;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.StreamReaderDelegate;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
// Schema Imports
public class ValidatingXmlStreamReaderTests {
// Base variable
static String casesLoc = "xbean/ValidatingStream/";
//////////////////////////////////////////////////////////////////////
// Tests
// NOTE: Tests that use getCasesFile are reading files
// from cases/qatest/files/xbean
// Tests that use getResourceFromJar are getting the contents of
// the file in the same location, but packaged into xmlcases.jar
// SO, any change to the xml files for these tests will not be
// reflected till they make it into xmlcases.jar. (ant build.xmlcases)
@Test
public void testDocWithNoSchema() throws Exception {
checkDocIsInvalid(getCasesFile(casesLoc + "po.xml"), null);
}
@Test
public void testValidLocationDoc() throws Exception {
checkDocIsValid(getCasesFile(casesLoc + "location.xml"), null);
}
@Test
public void testInvalidLocationDoc() throws Exception {
checkDocIsInvalid(getCasesFile(casesLoc + "location-inv.xml"), LocationDocument.type);
}
@Test
public void testValidPersonDoc() throws Exception {
checkDocIsValid(getCasesFile(casesLoc + "person.xml"), PersonDocument.type);
}
@Test
public void testInvalidPersonDoc() throws Exception {
checkDocIsInvalid(getCasesFile(casesLoc + "person-inv.xml"), PersonDocument.type);
}
@Test
public void testValidMixedContentDoc() throws Exception {
checkDocIsValid(getCasesFile(casesLoc + "mixed-content.xml"),
LetterDocument.type);
}
@Test
public void testInvalidNomixedContentDoc() throws Exception {
checkDocIsInvalid(getCasesFile(casesLoc + "nomixed-content-inv.xml"),
NoMixedDocument.type);
}
@Test
public void testInvalidMissingAttributeDoc() throws Exception {
checkDocIsInvalid(getCasesFile(casesLoc + "foo-inv.xml"),
HeadingDocument.type);
}
@Test
public void testContentName() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-frag.xml");
SchemaType type = Name.type;
assertTrue("Xml-fragment is not valid:\n" + sXml,
checkContent(sXml, type, true));
}
// Same as testContentName.. expect the xml has no chars before the first
// start element
@Test
public void testContentName2() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-frag2.xml");
SchemaType type = Name.type;
assertTrue("Xml-fragment is not valid:\n" + sXml,
checkContent(sXml, type, true));
}
@Test
public void testContentSibling() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-sibling.xml");
SchemaType type = PersonType.type;
assertTrue("Xml-fragment is not valid:\n" + sXml,
checkContent(sXml, type, true));
}
@Test
public void testInvalidContentSibling() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-sibling-inv.xml");
SchemaType type = PersonType.type;
assertTrue("Invalid Xml-fragment is getting validated:\n" + sXml,
!checkContent(sXml, type, true));
}
@Test
public void testValidXsiType() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-justname.xml");
SchemaType type = Name.type;
assertTrue("Xml-fragment is not valid:\n" + sXml,
checkContent(sXml, type, true));
}
@Test
public void testInvalidXsiType() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-justname-inv.xml");
SchemaType type = Name.type;
assertTrue("Invalid Xml-fragment is getting validated:\n" + sXml,
!checkContent(sXml, type, true));
}
@Test
public void testIncompatibleXsiType() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "person-xsi-inv.xml");
SchemaType type = Name.type;
assertTrue("Invalid Xml-fragment is getting validated:\n" + sXml,
!checkContent(sXml, type, true));
}
@Test
public void testValidMixedContent() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "mixed-content.xml");
SchemaType type = org.openuri.test.mixedContent.LetterType.type;
assertTrue("Xml-fragment is not valid:\n" + sXml,
checkContent(sXml, type, true));
}
@Test
@Ignore
public void testGlobalAttribute() throws Exception {
String sXml = JarUtil.getResourceFromJar(casesLoc + "global-attr.xml");
assertTrue("Global Attribute test failed:\n",
checkContent(sXml, null, true));
}
// Tests for increasing code-coverage metrics
@Test
public void testValXsrReuse() throws Exception {
Collection errors = new ArrayList();
File[] xmls = new File[2];
xmls[0] = getCasesFile(casesLoc + "person.xml");
xmls[1] = getCasesFile(casesLoc + "person-inv.xml");
SchemaType type = PersonDocument.type;
boolean[] ret = runValidator(xmls, type, errors);
String common = "Test for ValidatingXmlStreamReader reuse failed";
assertEquals(common + "\nReturn value has more than 2 elements", 2, ret.length);
assertTrue(common + "\nExpected: true & false. Actual: "
+ ret[0] + " & " + ret[1],
ret[0] && !ret[1]);
}
public void testIllegalEvent() throws Exception {
// Will require writing another XSR wrapper.. albeit simple
}
/*/
public void testWalk() throws Exception {
walkXml(getCasesFile(casesLoc + "global-attr.xml"));
System.out.println();
walkXml(getCasesFile(casesLoc + "person-sibling.xml"));
}
// */
//////////////////////////////////////////////////////////////////////
// Utility Methods
private void walkXml(File xml) throws Exception {
XMLStreamReader xr = XMLInputFactory.newInstance().
createXMLStreamReader(new FileInputStream(xml));
//xsr.nextTag();
XmlContentTestXSR xsr = new XmlContentTestXSR(xr);
while(xsr.hasNext())
{
int type = xsr.next();
System.out.print(type);
//*
if (type == XMLEvent.START_ELEMENT)
{
System.out.print("\n" + xsr.getLocalName() + " ");
}
if (type == XMLEvent.END_ELEMENT)
{
System.out.println("/" + xsr.getLocalName());
}
if (type == XMLEvent.CHARACTERS)
{
char[] arr = xsr.getTextCharacters();
String str = new String(arr);
System.out.print("Char:" + str + " ");
}
//*/
}
}
private boolean runValidator(File xml,
SchemaType type,
Collection errors)
throws IllegalArgumentException, Exception
{
if (errors == null)
throw new IllegalArgumentException(
"Collection object cannot be null");
XMLStreamReader xsr = XMLInputFactory.newInstance().
createXMLStreamReader(new FileInputStream(xml));
ValidatingXMLStreamReader valXsr = new ValidatingXMLStreamReader();
valXsr.init(xsr,
false,
type,
XmlBeans.typeLoaderForClassLoader(ValidatingXMLStreamReader.class.getClassLoader()),
null,
errors);
// Walk through the xml
while (valXsr.hasNext())
valXsr.next();
return valXsr.isValid();
//return true;
}
// This method is primarily for testing re-use of the ValXSR object.
// but could come in handy later..
private boolean[] runValidator(File[] xml,
SchemaType type,
Collection errors)
throws IllegalArgumentException, Exception
{
if (errors == null)
throw new IllegalArgumentException(
"Collection object cannot be null");
ValidatingXMLStreamReader valXsr = new ValidatingXMLStreamReader();
boolean[] retArray = new boolean[xml.length];
for (int i = 0; i < xml.length; i++)
{
XMLStreamReader xsr = XMLInputFactory.newInstance().
createXMLStreamReader(new FileInputStream(xml[i]));
valXsr.init(xsr,
false,
type,
XmlBeans.typeLoaderForClassLoader(ValidatingXMLStreamReader.class.getClassLoader()),
null,
errors);
// Walk through the xml
while (valXsr.hasNext())
valXsr.next();
retArray[i] = valXsr.isValid();
}
return retArray;
}
protected void checkDocIsValid(File file, SchemaType type) throws Exception {
Collection errors = new ArrayList();
boolean isValid = runValidator(file, type, errors);
tools.xml.Utils.printXMLErrors(errors);
Assert.assertTrue("File '" + file.getName() + "' is invalid.", isValid);
}
protected void checkDocIsInvalid(File file, SchemaType type) throws Exception {
Collection errors = new ArrayList();
boolean isValid = runValidator(file, type, errors);
assertTrue("File '" + file.getName() + "' is valid, but was expecting invalid.",
!isValid);
}
public boolean checkContent(String fragment,
SchemaType type,
boolean printErrors) throws Exception {
XMLStreamReader xsr = XMLInputFactory.newInstance().
createXMLStreamReader(new StringReader(fragment));
XmlContentTestXSR cxsr = new XmlContentTestXSR(xsr);
Collection errors = new ArrayList();
ValidatingXMLStreamReader valXsr = new ValidatingXMLStreamReader();
valXsr.init(cxsr,
false,
type,
XmlBeans.typeLoaderForClassLoader(ValidatingXMLStreamReader.class.getClassLoader()),
null,
errors);
// Walk through the xml
while (valXsr.hasNext())
valXsr.next();
if (!valXsr.isValid())
{
if (printErrors)
tools.xml.Utils.printXMLErrors(errors);
return false;
}
return true;
}
private static File getCasesFile(String path)
throws java.io.IOException
{
if (path.length()==0)
throw new IOException("getCasesFile was called with path of len 0");
return JarUtil.getResourceFromJarasFile(path);
//return new File(casesRoot + path);
}
/////////////////////////////////////////////////////////////////////////
// XmlStreamReader extension for content Validation
// will not work for Global Attribute
public class XmlContentTestXSR
extends StreamReaderDelegate
implements XMLStreamReader
{
private static final int TAGOPEN = 100;
private static final int TAGCLOSE = 101;
private static final int UNDEFINED = 99;
private static final int ATTRIBUTE = 102;
private static final int ENDCONTENT = 103;
int state = -1;
int depth = -1;
boolean initialized = false;
int attributeCount = -1;
boolean hasAttributes = false;
// Constructor Wrappers
public XmlContentTestXSR(XMLStreamReader xsr)
throws XMLStreamException
{
super(xsr);
}
public boolean hasNext()
{
if (state == UNDEFINED || state == ENDCONTENT)
return false;
if (!initialized) // next() has not been called yet
return true;
return true;
}
public int next()
throws XMLStreamException
{
int _next;
if (!initialized)
{
// First time next() is called..
// Scan for the first XMLEvent.START_ELEMENT
_next = UNDEFINED;
while ((super.hasNext()) && (_next != XMLEvent.START_ELEMENT))
_next = super.next();
if (_next != XMLEvent.START_ELEMENT)
throw new XMLStreamException(
"Could not find a start element");
initialized = true;
// Now move past the first tag
state = TAGOPEN;
depth = 1;
if ((attributeCount = super.getAttributeCount()) > 0)
{
// The first element has attributes.. this is part of
// the content. So the first event should XMLEvent.ATTRIBUTE
_next = XMLEvent.ATTRIBUTE;
}
else
{
// return super.next();
/*
If content is <xml-fragment/> then we will have returned
END_ELEMENT above, without ever generating a START_ELEMENT
In this case probably we should detect this and return a
END_DOCUMENT
*/
_next = super.next();
if (_next == XMLEvent.END_ELEMENT)
{
_next = XMLEvent.END_DOCUMENT;
state = ENDCONTENT;
}
}
return _next;
}
_next = super.next();
switch (_next)
{
case XMLEvent.START_ELEMENT:
state = TAGOPEN;
depth++;
break;
case XMLEvent.END_ELEMENT:
--depth;
if (depth < 0 && state == TAGOPEN)
{
throw new XMLStreamException(
"Illegal XML Stream state");
}
else if (depth == 0 && state == TAGOPEN)
{
state = ENDCONTENT;
// at this point we will return ENDDOCUMENT
_next = XMLEvent.END_DOCUMENT;
}
break;
}
return _next;
}
}
}