[jboss-svn-commits] JBoss Common SVN: r2048 - in jbossxb/trunk: . src src/test src/test/java src/test/java/org src/test/java/org/jboss src/test/java/org/jboss/test src/test/java/org/jboss/test/xml src/test/resources src/test/resources/org src/test/resources/org/jboss src/test/resources/org/jboss/test src/test/resources/org/jboss/test/xml
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Sep 21 03:19:29 EDT 2006
Author: alex.loubyansky at jboss.com
Date: 2006-09-21 03:19:23 -0400 (Thu, 21 Sep 2006)
New Revision: 2048
Added:
jbossxb/trunk/src/test/
jbossxb/trunk/src/test/java/
jbossxb/trunk/src/test/java/org/
jbossxb/trunk/src/test/java/org/jboss/
jbossxb/trunk/src/test/java/org/jboss/test/
jbossxb/trunk/src/test/java/org/jboss/test/xml/
jbossxb/trunk/src/test/java/org/jboss/test/xml/AbstractJBossXBTest.java
jbossxb/trunk/src/test/java/org/jboss/test/xml/JBossXBTestDelegate.java
jbossxb/trunk/src/test/java/org/jboss/test/xml/RepeatableTermsUnitTestCase.java
jbossxb/trunk/src/test/java/org/jboss/test/xml/XmlDiff.java
jbossxb/trunk/src/test/resources/
jbossxb/trunk/src/test/resources/org/
jbossxb/trunk/src/test/resources/org/jboss/
jbossxb/trunk/src/test/resources/org/jboss/test/
jbossxb/trunk/src/test/resources/org/jboss/test/xml/
jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xml
jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xsd
jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xml
jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xsd
Modified:
jbossxb/trunk/pom.xml
Log:
first local test
Modified: jbossxb/trunk/pom.xml
===================================================================
--- jbossxb/trunk/pom.xml 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/pom.xml 2006-09-21 07:19:23 UTC (rev 2048)
@@ -113,6 +113,11 @@
<version>1.0</version>
</dependency>
<dependency>
+ <groupId>jboss.logging.log4j</groupId>
+ <artifactId>jboss-logging-log4j</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
<groupId>jboss.common.core</groupId>
<artifactId>jboss-common-core</artifactId>
<version>1.0</version>
@@ -148,6 +153,18 @@
<version>1.2.1</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jboss.jboss-test</groupId>
+ <artifactId>jboss-test</artifactId>
+ <version>1.0.0.CR1</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Added: jbossxb/trunk/src/test/java/org/jboss/test/xml/AbstractJBossXBTest.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xml/AbstractJBossXBTest.java 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xml/AbstractJBossXBTest.java 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,192 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.xml;
+
+import java.net.URL;
+
+import org.jboss.test.AbstractTestCaseWithSetup;
+import org.jboss.test.AbstractTestDelegate;
+import org.jboss.util.Classes;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
+
+/**
+ * AbstractJBossXBTest.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 45077 $
+ */
+public class AbstractJBossXBTest extends AbstractTestCaseWithSetup
+{
+ private static final XmlDiff DIFF = new XmlDiff();
+
+ protected String rootName = getRootName();
+
+ /**
+ * Create a new AbstractJBossXBTest.
+ *
+ * @param name the name of the test
+ */
+ public AbstractJBossXBTest(String name)
+ {
+ super(name);
+ }
+
+ public void assertXmlEqual(String expected, String was)
+ {
+ String diff = DIFF.diff(expected, was);
+ if(diff != null)
+ {
+ fail(diff);
+ }
+ }
+
+ /**
+ * Unmarshal some xml
+ *
+ * @param name the name
+ * @param expected the expected type
+ * @return the unmarshalled object
+ * @throws Exception for any error
+ */
+ protected Object unmarshal(String name, Class expected) throws Exception
+ {
+ Object object = unmarshal(name);
+ if (object == null)
+ fail("No object from " + name);
+ assertTrue("Object '" + object + "' cannot be assigned to " + expected.getName(), expected.isAssignableFrom(object.getClass()));
+ return object;
+ }
+
+ /**
+ * Unmarshal some xml
+ *
+ * @param name the name
+ * @param expected the expected type
+ * @param resolver the resolver
+ * @return the unmarshalled object
+ * @throws Exception for any error
+ */
+ protected Object unmarshal(String name, Class expected, SchemaBindingResolver resolver) throws Exception
+ {
+ Object object = unmarshal(name, resolver);
+ if (object == null)
+ fail("No object from " + name);
+ assertTrue("Object '" + object + "' cannot be assigned to " + expected.getName(), expected.isAssignableFrom(object.getClass()));
+ return object;
+ }
+
+ /**
+ * Unmarshal some xml
+ *
+ * @param name the name
+ * @return the unmarshalled object
+ * @throws Exception for any error
+ */
+ protected Object unmarshal(String name) throws Exception
+ {
+ return unmarshal(name, (SchemaBindingResolver) null);
+ }
+
+ /**
+ * Unmarshal some xml
+ *
+ * @param name the name
+ * @return the unmarshalled object
+ * @throws Exception for any error
+ */
+ protected Object unmarshal(String name, SchemaBindingResolver resolver) throws Exception
+ {
+ String url = findXML(name);
+ return getJBossXBDelegate().unmarshal(url, resolver);
+ }
+
+ /**
+ * Find the xml
+ *
+ * @param name the name
+ * @return the url of the xml
+ */
+ protected String findXML(String name)
+ {
+ URL url = getResource(name);
+ if (url == null)
+ fail(name + " not found");
+ return url.toString();
+ }
+
+ /**
+ * Get a schema location
+ *
+ * @param clazz used to get the package
+ * @param schema the schema name
+ * @return the location in the "classpath"
+ */
+ protected static String getSchemaLocation(Class clazz, String schema)
+ {
+ String packageName = Classes.getPackageName(clazz);
+ packageName = packageName.replace('.', '/');
+ String name = packageName + '/' + schema;
+ return name;
+ }
+
+ /**
+ * Setup the test delegate
+ *
+ * @param clazz the class
+ * @return the delegate
+ * @throws Exception for any error
+ */
+ public static AbstractTestDelegate getDelegate(Class clazz) throws Exception
+ {
+ return new JBossXBTestDelegate(clazz);
+ }
+
+ protected JBossXBTestDelegate getJBossXBDelegate()
+ {
+ return (JBossXBTestDelegate) getDelegate();
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ configureLogging();
+ }
+
+ /**
+ * Get the package root name
+ *
+ * @return the root name
+ */
+ protected String getRootName()
+ {
+ String longName = getClass().getName();
+ int dot = longName.lastIndexOf('.');
+ if (dot != -1)
+ return longName.substring(dot + 1);
+ return longName;
+ }
+
+ protected void configureLogging()
+ {
+ //enableTrace("org.jboss.xb");
+ }
+}
Added: jbossxb/trunk/src/test/java/org/jboss/test/xml/JBossXBTestDelegate.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xml/JBossXBTestDelegate.java 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xml/JBossXBTestDelegate.java 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,128 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.xml;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+
+import org.jboss.net.protocol.URLStreamHandlerFactory;
+import org.jboss.test.AbstractTestDelegate;
+import org.jboss.xb.binding.Unmarshaller;
+import org.jboss.xb.binding.UnmarshallerFactory;
+import org.jboss.xb.binding.sunday.unmarshalling.DefaultSchemaResolver;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
+
+/**
+ * JBossXBTestDelegate.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 40492 $
+ */
+public class JBossXBTestDelegate extends AbstractTestDelegate
+{
+ /** Whether initialization has been done */
+ private static boolean done = false;
+
+ /** The unmarshaller factory */
+ protected UnmarshallerFactory unmarshallerFactory;
+
+ /** The resolver */
+ protected SchemaBindingResolver defaultResolver;
+
+ /**
+ * Initialize
+ */
+ public synchronized static void init()
+ {
+ if (done)
+ return;
+ done = true;
+ URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory());
+ URLStreamHandlerFactory.preload();
+ String handlerPkgs = System.getProperty("java.protocol.handler.pkgs");
+ if (handlerPkgs != null)
+ handlerPkgs += "|org.jboss.net.protocol";
+ else
+ handlerPkgs = "org.jboss.net.protocol";
+ System.setProperty("java.protocol.handler.pkgs", handlerPkgs);
+ }
+
+ /**
+ * Create a new JBossXBTestDelegate.
+ *
+ * @param clazz the test class
+ */
+ public JBossXBTestDelegate(Class clazz)
+ {
+ super(clazz);
+ }
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ init();
+ unmarshallerFactory = UnmarshallerFactory.newInstance();
+ initResolver();
+ }
+
+ protected void initResolver() throws Exception
+ {
+ try
+ {
+ Method method = clazz.getMethod("initResolver", null);
+ defaultResolver = (SchemaBindingResolver) method.invoke(null, null);
+ }
+ catch (NoSuchMethodException ignored)
+ {
+ defaultResolver = new DefaultSchemaResolver();
+ }
+ }
+
+ /**
+ * Unmarshal an object
+ *
+ * @param url the url
+ * @param resolver the resolver
+ * @return the object
+ * @throws Exception for any error
+ */
+ public Object unmarshal(String url, SchemaBindingResolver resolver) throws Exception
+ {
+ if (resolver == null)
+ resolver = defaultResolver;
+
+ long start = System.currentTimeMillis();
+ Unmarshaller unmarshaller = unmarshallerFactory.newUnmarshaller();
+ log.debug("Initialized parsing in " + (System.currentTimeMillis() - start) + "ms");
+ try
+ {
+ Object result = unmarshaller.unmarshal(url, resolver);
+ log.debug("Total parse for " + url + " took " + (System.currentTimeMillis() - start) + "ms");
+ return result;
+ }
+ catch (Exception e)
+ {
+ log.debug("Error during parsing: " + url, e);
+ throw e;
+ }
+ }
+}
Added: jbossxb/trunk/src/test/java/org/jboss/test/xml/RepeatableTermsUnitTestCase.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xml/RepeatableTermsUnitTestCase.java 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xml/RepeatableTermsUnitTestCase.java 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,240 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.xml;
+
+import java.util.Arrays;
+import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
+import org.jboss.xb.binding.Unmarshaller;
+import org.jboss.xb.binding.UnmarshallerFactory;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: $</tt>
+ */
+public class RepeatableTermsUnitTestCase
+ extends AbstractJBossXBTest
+{
+ public RepeatableTermsUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ protected void configureLogging()
+ {
+ //enableTrace("org.jboss.xb.binding.sunday");
+ //enableTrace("org.jboss.xb.binding.sunday.unmarshalling.SequenceBinding");
+ //enableTrace("org.jboss.xb.binding.sunday.unmarshalling.ChoiceBinding");
+ }
+
+ public void testUnmarshal1() throws Exception
+ {
+ Object o = unmarshal();
+
+ assertNotNull(o);
+ assertTrue(o instanceof Top);
+ Top top = (Top)o;
+
+ assertNotNull(top.item);
+ assertEquals(3, top.item.length);
+ assertEquals(new String[]{"item1", "item2", "item3"}, top.item);
+
+ assertNotNull(top.sequence);
+ //assertEquals(5, top.sequence.length);
+ assertEquals(
+ new Sequence[]
+ {
+ new Sequence("sequenceChoice1_1", null),
+ new Sequence(null, "sequenceChoice2_1"),
+ new Sequence("sequenceChoice1_2", null),
+ new Sequence("sequenceChoice1_3", null),
+ new Sequence(null, "sequenceChoice2_2")
+ },
+ top.sequence
+ );
+
+ assertNotNull(top.choice);
+ assertEquals(3, top.choice.length);
+ assertEquals(
+ new Choice[]
+ {
+ new Choice(new String[]{"choiceChoice1_1", "choiceChoice1_2"}, null),
+ new Choice(null, new String[]{"choiceChoice2_1", "choiceChoice2_2"}),
+ new Choice(new String[]{"choiceChoice1_3", "choiceChoice1_4"}, null),
+ },
+ top.choice
+ );
+ }
+
+ public void testUnmarshal2() throws Exception
+ {
+ Object o = unmarshal();
+ assertNotNull(o);
+ assertTrue(o instanceof Top);
+ Top top = (Top)o;
+
+ assertNull(top.item);
+ assertNull(top.choice);
+ assertNull(top.sequence);
+
+ assertEquals("item1", top.item1);
+ assertEquals("item2", top.item2);
+ }
+
+ private Object unmarshal() throws Exception
+ {
+ String testXsd = findXML(rootName + "_" + getName() + ".xsd");
+ SchemaBinding schema = XsdBinder.bind(testXsd, (SchemaBindingResolver)null);
+ schema.setIgnoreUnresolvedFieldOrClass(false);
+
+ Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
+ return unmarshaller.unmarshal(findXML(rootName + "_" + getName() + ".xml"), schema);
+ }
+
+ // Inner
+
+ public static final class Top
+ {
+ public String[] item;
+ public Sequence[] sequence;
+ public Choice[] choice;
+
+ public String item1;
+ public String item2;
+
+ public String toString()
+ {
+ return "[top item=" + (item == null ? null : Arrays.asList(item)) +
+ " sequence=" + (sequence == null ? null : Arrays.asList(sequence)) +
+ " choice=" + (choice == null ? null : Arrays.asList(choice)) +
+ " item1=" + item1 + " item2=" + item2 + "]";
+ }
+ }
+
+ public static final class Sequence
+ {
+ public String sequenceChoice1;
+ public String sequenceChoice2;
+
+ public Sequence()
+ {
+ }
+
+ public Sequence(String sequenceChoice1, String sequenceChoice2)
+ {
+ this.sequenceChoice1 = sequenceChoice1;
+ this.sequenceChoice2 = sequenceChoice2;
+ }
+
+ public String toString()
+ {
+ return "[" + sequenceChoice1 + " " + sequenceChoice2 + "]";
+ }
+
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof Sequence))
+ {
+ return false;
+ }
+
+ final Sequence sequence = (Sequence)o;
+
+ if(sequenceChoice1 != null ? !sequenceChoice1.equals(sequence.sequenceChoice1) : sequence.sequenceChoice1 != null)
+ {
+ return false;
+ }
+ if(sequenceChoice2 != null ? !sequenceChoice2.equals(sequence.sequenceChoice2) : sequence.sequenceChoice2 != null)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result;
+ result = (sequenceChoice1 != null ? sequenceChoice1.hashCode() : 0);
+ result = 29 * result + (sequenceChoice2 != null ? sequenceChoice2.hashCode() : 0);
+ return result;
+ }
+ }
+
+ public static final class Choice
+ {
+ public String[] choiceChoice1;
+ public String[] choiceChoice2;
+
+ public Choice()
+ {
+ }
+
+ public Choice(String[] choiceChoice1, String[] choiceChoice2)
+ {
+ this.choiceChoice1 = choiceChoice1;
+ this.choiceChoice2 = choiceChoice2;
+ }
+
+ public String toString()
+ {
+ return "[" +
+ (choiceChoice1 == null ? null : Arrays.asList(choiceChoice1)) +
+ " " + (choiceChoice2 == null ? null : Arrays.asList(choiceChoice2)) + "]";
+ }
+
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof Choice))
+ {
+ return false;
+ }
+
+ final Choice choice = (Choice)o;
+
+ if(!Arrays.equals(choiceChoice1, choice.choiceChoice1))
+ {
+ return false;
+ }
+ if(!Arrays.equals(choiceChoice2, choice.choiceChoice2))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return 0;
+ }
+ }
+}
Added: jbossxb/trunk/src/test/java/org/jboss/test/xml/XmlDiff.java
===================================================================
--- jbossxb/trunk/src/test/java/org/jboss/test/xml/XmlDiff.java 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/java/org/jboss/test/xml/XmlDiff.java 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,686 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.xml;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.jboss.xb.binding.Constants;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: 45494 $</tt>
+ */
+public class XmlDiff
+{
+ public static final ErrorHandler ERROR_HANDLER = new DefErrorHandler();
+
+ public static final byte PRINT_ELEMENT = 0;
+ public static final byte PRINT_PARENT = 1;
+ public static final byte PRINT_ALL = 2;
+
+ private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory.newInstance();
+ static
+ {
+ FACTORY.setNamespaceAware(true);
+ FACTORY.setValidating(true);
+ }
+
+ private static final String INDENT = " ";
+
+ public static void main(String[] args) throws Exception
+ {
+ String xml1 =
+ "<ns1:e xmlns:ns1='http://ns' attr1='attr1_val' ns1:attr2='attr2_val'>\n" +
+ " <ns1:child1>\n" +
+ " <ns2:child2 xmlns:ns2='http://ns2' child2_attr='child2_attr_val'>child2_val</ns2:child2>\n" +
+ " </ns1:child1>\n" +
+ " text\n" +
+ "</ns1:e>";
+
+ String xml2 =
+ "<e xmlns='http://ns' attr1='attr1_val'" +
+ " xmlns:ns='http://ns' ns:attr2='attr2_val'>text" +
+ " <child1>" +
+ " <child2 xmlns='http://ns2' child2_attr='child2_attr_val'>child2_val</child2>" +
+ " </child1>" +
+ "</e>";
+
+ System.out.println(new XmlDiff().diff(xml1, xml2));
+ }
+
+ public XmlDiff()
+ {
+ this(PRINT_ALL, true);
+ }
+
+ public XmlDiff(byte print, boolean reformat)
+ {
+ this.print = print;
+ this.reformat = reformat;
+ }
+
+ private byte print = PRINT_ALL;
+ private boolean reformat = true;
+
+ public byte getPrint()
+ {
+ return print;
+ }
+
+ public void setPrint(byte print)
+ {
+ this.print = print;
+ }
+
+ public boolean isReformat()
+ {
+ return reformat;
+ }
+
+ public void setReformat(boolean reformat)
+ {
+ this.reformat = reformat;
+ }
+
+ /**
+ * Compares two XML contents and returns a diff if they are different or null if they are equal.
+ *
+ * @param expected expected XML content
+ * @param was actual XML content
+ * @return difference between XML contents or null if the contents are equal
+ */
+ public String diff(String expected, String was)
+ {
+ return diff(expected, was, ERROR_HANDLER, null);
+ }
+
+ public String diff(String expected, String was, ErrorHandler eh)
+ {
+ return diff(expected, was, eh, null);
+ }
+
+ public String diff(String expected, String was, EntityResolver er)
+ {
+ return diff(expected, was, ERROR_HANDLER, er);
+ }
+
+ public String diff(String expected, String was, ErrorHandler eh, EntityResolver er)
+ {
+ DocumentBuilder documentBuilder = null;
+ try
+ {
+ documentBuilder = FACTORY.newDocumentBuilder();
+ }
+ catch(ParserConfigurationException e)
+ {
+ throw new IllegalStateException("Failed to create a document builder: " + e.getMessage());
+ }
+
+ if(eh != null)
+ {
+ documentBuilder.setErrorHandler(eh);
+ }
+
+ if(er != null)
+ {
+ documentBuilder.setEntityResolver(er);
+ }
+
+ Document expDoc = null;
+ try
+ {
+ expDoc = documentBuilder.parse(new InputSource(new StringReader(expected)));
+ }
+ catch(Exception e)
+ {
+ throw new IllegalStateException("Failed to parse expected XML\n" + expected + ": " + e.getMessage());
+ }
+
+ Document wasDoc = null;
+ try
+ {
+ wasDoc = documentBuilder.parse(new InputSource(new StringReader(was)));
+ }
+ catch(Exception e)
+ {
+ throw new IllegalStateException("Failed to parse XML\n" + was + ": " + e.getMessage());
+ }
+
+ Element expElement = expDoc.getDocumentElement();
+ Element wasElement = wasDoc.getDocumentElement();
+ return assertEquals(expElement, wasElement, expElement, wasElement);
+ }
+
+ private String assertEquals(Element exp, Element was, Element printAsExp, Element printAsWas)
+ {
+ QName expName = new QName(exp.getNamespaceURI(), exp.getLocalName());
+ QName wasName = new QName(was.getNamespaceURI(), was.getLocalName());
+
+ if(!expName.equals(wasName))
+ {
+ return fail("Expected name " + expName + " but was " + wasName, exp, was);
+ }
+
+ NamedNodeMap expAttrs = exp.getAttributes();
+ NamedNodeMap wasAttrs = was.getAttributes();
+
+ if(expAttrs == null && wasAttrs != null && hasNonIgnorableNs(wasAttrs))
+ {
+ return fail("Element " + expName + " doesn't have attributes", printAsExp, printAsWas);
+ }
+ else if(wasAttrs == null && expAttrs != null && hasNonIgnorableNs(expAttrs))
+ {
+ return fail("Element " + expName + " has attributes", printAsExp, printAsWas);
+ }
+ else if(expAttrs != null && wasAttrs != null)
+ {
+ String msg = assertAttrs(expAttrs, wasAttrs, printAsExp);
+ if(msg != null)
+ {
+ return fail(msg, printAsExp, printAsWas);
+ }
+ }
+
+ NodeList expChildren = exp.getChildNodes();
+ NodeList wasChildren = was.getChildNodes();
+
+ NodeList expTexts = getTextNodes(expChildren);
+ NodeList wasTexts = getTextNodes(wasChildren);
+ if(expTexts.getLength() > 0 && wasTexts.getLength() == 0)
+ {
+ return fail("Element " + expName + " has text content", printAsExp, printAsWas);
+ }
+ else if(expTexts.getLength() == 0 && wasTexts.getLength() > 0)
+ {
+ return fail("Element " + expName + " doesn't have text content", printAsExp, printAsWas);
+ }
+ // todo: should text content be concatenated before comparison?
+ else if(expTexts.getLength() != wasTexts.getLength())
+ {
+ return fail(
+ "Element " + expName + " has " + expTexts.getLength() + " text nodes (was " + wasTexts.getLength() + ")",
+ printAsExp,
+ printAsWas
+ );
+ }
+ else if(expTexts.getLength() > 0 && wasTexts.getLength() > 0)
+ {
+ for(int i = 0; i < expTexts.getLength(); ++i)
+ {
+ Text text = (Text)expTexts.item(i);
+ if(!containsText(text.getNodeValue(), wasTexts, i))
+ {
+ return fail("Element " + expName + " has text '" + text.getNodeValue() + "'", printAsExp, printAsWas);
+ }
+ }
+ }
+
+ NodeList expElems = sublist(expChildren, Node.ELEMENT_NODE);
+ NodeList wasElems = sublist(wasChildren, Node.ELEMENT_NODE);
+ if(expElems.getLength() > 0 && wasElems.getLength() == 0)
+ {
+ return fail("Element " + expName + " has child elements", printAsExp, printAsWas);
+ }
+ else if(expElems.getLength() == 0 && wasElems.getLength() > 0)
+ {
+ return fail("Element " + expName + " doesn't have child elements", printAsExp, printAsWas);
+ }
+ else if(expElems.getLength() != wasElems.getLength())
+ {
+ return fail("Element " +
+ expName +
+ " has " +
+ expElems.getLength() +
+ " child elements (was " +
+ wasElems.getLength() +
+ ")",
+ printAsExp,
+ printAsWas
+ );
+ }
+ else if(expElems.getLength() > 0 && wasElems.getLength() > 0)
+ {
+ if(print == PRINT_PARENT)
+ {
+ printAsExp = exp;
+ printAsWas = was;
+ }
+
+ for(int i = 0; i < expElems.getLength(); ++i)
+ {
+ Element expChild = (Element)expElems.item(i);
+ Element wasChild = getElement(expChild.getNamespaceURI(), expChild.getLocalName(), wasElems, i);
+ if(wasChild == null)
+ {
+ return fail("Element " +
+ expName +
+ " has child element " +
+ new QName(expChild.getNamespaceURI(), expChild.getLocalName()),
+ printAsExp,
+ printAsWas
+ );
+ }
+
+ if(print == PRINT_ELEMENT)
+ {
+ printAsExp = expChild;
+ printAsWas = wasChild;
+ }
+
+ String diff = assertEquals(expChild, wasChild, printAsExp, printAsWas);
+ if(diff != null)
+ {
+ return diff;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static Element getElement(String ns, String local, NodeList elements, int suggestedIndex)
+ {
+ if(suggestedIndex >= 0 && suggestedIndex < elements.getLength())
+ {
+ Element element = (Element)elements.item(suggestedIndex);
+ if((ns == null && element.getNamespaceURI() == null ||
+ ns != null && ns.equals(element.getNamespaceURI())
+ ) &&
+ local.equals(element.getLocalName()))
+ {
+ return element;
+ }
+ }
+
+ for(int i = 0; i < elements.getLength(); ++i)
+ {
+ Element element = (Element)elements.item(i);
+ if((ns == null && element.getNamespaceURI() == null ||
+ ns != null && ns.equals(element.getNamespaceURI())
+ ) &&
+ local.equals(element.getLocalName()))
+ {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ private static boolean containsText(String text, NodeList textNodes, int suggestedIndex)
+ {
+ text = text.trim();
+ if(suggestedIndex >= 0)
+ {
+ Text textNode = (Text)textNodes.item(suggestedIndex);
+ String wasText = textNode.getNodeValue().trim();
+ if(text.equals(wasText))
+ {
+ return true;
+ }
+ }
+
+ for(int i = 0; i < textNodes.getLength(); ++i)
+ {
+ Text textNode = (Text)textNodes.item(i);
+ String wasText = textNode.getNodeValue().trim();
+ if(text.equals(wasText))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static NodeList getTextNodes(NodeList list)
+ {
+ MutableNodeList result = new MutableNodeList();
+ for(int i = 0; i < list.getLength(); ++i)
+ {
+ Node node = list.item(i);
+ if(node.getNodeType() == Node.TEXT_NODE)
+ {
+ String text = node.getNodeValue();
+ if(text.trim().length() > 0)
+ {
+ result.add(node);
+ }
+ }
+ }
+ return result;
+ }
+
+ private static NodeList sublist(NodeList list, short nodeType)
+ {
+ MutableNodeList result = new MutableNodeList();
+ for(int i = 0; i < list.getLength(); ++i)
+ {
+ Node node = list.item(i);
+ if(node.getNodeType() == nodeType)
+ {
+ result.add(node);
+ }
+ }
+ return result;
+ }
+
+ private static String assertAttrs(NamedNodeMap attrsExp,
+ NamedNodeMap attrsWas,
+ Element printAsExp)
+ {
+ String result = assertSubset(attrsExp, attrsWas, printAsExp, true);
+ if(result == null)
+ {
+ result = assertSubset(attrsWas, attrsExp, printAsExp, false);
+ }
+ return result;
+ }
+
+ private static String assertSubset(NamedNodeMap attrsSubset,
+ NamedNodeMap attrsSet,
+ Element printAsExp,
+ boolean checkHave)
+ {
+ String msg = checkHave ? " has attribute " : " doesn't have attribute ";
+ QName expName = new QName(printAsExp.getNamespaceURI(), printAsExp.getLocalName());
+ for(int i = 0; i < attrsSubset.getLength(); ++i)
+ {
+ Attr attr = (Attr)attrsSubset.item(i);
+ String attrNs = attr.getNamespaceURI();
+ String localName = attr.getLocalName();
+ if(xsiNs(attrNs) && "type".equals(localName))
+ {
+ Attr wasAttr = (Attr)attrsSet.getNamedItemNS(attrNs, localName);
+ if(wasAttr == null)
+ {
+ return "Element " + expName + msg + new QName(attrNs, localName);
+ }
+
+ String typeName = attr.getValue();
+ int colon = typeName.indexOf(':');
+ if(colon != -1)
+ {
+ typeName = typeName.substring(colon);
+ }
+
+ if(!wasAttr.getValue().endsWith(typeName))
+ {
+ return "Element " + expName +
+ (checkHave ? " has xsi:type " : " doesn't have xsi:type ") +
+ attr.getValue();
+ }
+
+ //todo compare namespaces for xsi:types
+ }
+ else if(nonIgnorableNs(attrNs) || xsiNs(attrNs) && localName.equals("nil"))
+ {
+ Attr wasAttr = (Attr)attrsSet.getNamedItemNS(attrNs, localName);
+ if(wasAttr == null)
+ {
+ return "Element " + expName + msg + new QName(attrNs, localName);
+ }
+
+ if(!attr.getValue().equals(wasAttr.getValue()))
+ {
+ return "Attribute " +
+ new QName(attrNs, localName) +
+ " in element " +
+ expName +
+ " has value " + attr.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ private static boolean hasNonIgnorableNs(NamedNodeMap nodeMap)
+ {
+ for(int i = 0; i < nodeMap.getLength(); ++i)
+ {
+ Node node = nodeMap.item(i);
+ if(nonIgnorableNs(node.getNamespaceURI()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean nonIgnorableNs(String ns)
+ {
+ return ns == null ||
+ !ns.equals(Constants.NS_XML_SCHEMA)
+ && !ns.equals(Constants.NS_XML_SCHEMA_INSTANCE)
+ && !ns.equals(Constants.NS_XML_XMLNS);
+ }
+
+ private static boolean xsiNs(String ns)
+ {
+ return Constants.NS_XML_SCHEMA_INSTANCE.equals(ns);
+ }
+
+ private String fail(String msg, Element exp, Element was)
+ {
+ return msg + ". Expected\n" + toString(exp) + "\nbut was\n" + toString(was);
+ }
+
+ private String toString(Element e)
+ {
+ return append(e, new StringBuffer(), 0).toString();
+ }
+
+ private StringBuffer append(Element e, StringBuffer buf, int depth)
+ {
+ if(reformat && depth > 0)
+ {
+ buf.append('\n');
+ for(int i = 0; i < depth; ++i)
+ {
+ buf.append(INDENT);
+ }
+ }
+
+ buf.append('<');
+ if(e.getPrefix() != null && e.getPrefix().length() > 0)
+ {
+ buf.append(e.getPrefix()).append(':');
+ }
+ buf.append(e.getLocalName());
+
+ NamedNodeMap attrs = e.getAttributes();
+ if(attrs != null && attrs.getLength() > 0)
+ {
+ for(int i = 0; i < attrs.getLength(); ++i)
+ {
+ Attr attr = (Attr)attrs.item(i);
+ buf.append(' ')
+ .append(attr.getName())
+ .append('=')
+ .append('\'')
+ .append(attr.getValue())
+ .append('\'');
+ }
+ }
+
+ buf.append('>');
+
+ NodeList childNodes = e.getChildNodes();
+ boolean childElements = false;
+ for(int i = 0; i < childNodes.getLength(); ++i)
+ {
+ Node child = childNodes.item(i);
+ switch(child.getNodeType())
+ {
+ case Node.TEXT_NODE:
+ String chars = child.getNodeValue();
+ if(chars.trim().length() > 0)
+ {
+ buf.append(chars);
+ }
+ break;
+ case Node.ELEMENT_NODE:
+ append((Element)child, buf, depth + 1);
+ childElements = true;
+ break;
+ default:
+ throw new IllegalStateException("Node type is not supported: " + child.getNodeType());
+ }
+ }
+
+ if(reformat && childElements)
+ {
+ buf.append('\n');
+ for(int i = 0; i < depth; ++i)
+ {
+ buf.append(INDENT);
+ }
+ }
+
+ buf.append("</");
+ if(e.getPrefix() != null && e.getPrefix().length() > 0)
+ {
+ buf.append(e.getPrefix()).append(':');
+ }
+ buf.append(e.getLocalName())
+ .append('>');
+
+ return buf;
+ }
+
+ // Inner
+
+ private static final class MutableNodeList
+ implements NodeList
+ {
+ private List list = Collections.EMPTY_LIST;
+
+ public void add(Node node)
+ {
+ switch(list.size())
+ {
+ case 0:
+ list = Collections.singletonList(node);
+ break;
+ case 1:
+ list = new ArrayList(list);
+ default:
+ list.add(node);
+ }
+ }
+
+ public int getLength()
+ {
+ return list.size();
+ }
+
+ public Node item(int index)
+ {
+ return (Node)list.get(index);
+ }
+ }
+
+ public static final class DefErrorHandler
+ implements ErrorHandler
+ {
+ public static final byte IGNORE = 0;
+ public static final byte LOG = 1;
+ public static final byte FAIL = 3;
+
+ private byte warnEvent = IGNORE;
+ private byte errorEvent = IGNORE;
+ private byte fatalEvent = FAIL;
+
+ public void error(SAXParseException e) throws SAXException
+ {
+ handleEvent(warnEvent, e);
+ }
+
+ public void fatalError(SAXParseException e) throws SAXException
+ {
+ handleEvent(errorEvent, e);
+ }
+
+ public void warning(SAXParseException e) throws SAXException
+ {
+ handleEvent(fatalEvent, e);
+ }
+
+ private void handleEvent(byte event, SAXParseException e)
+ throws SAXException
+ {
+ switch(event)
+ {
+ case IGNORE:
+ break;
+ case LOG:
+ System.out.println(formatMessage(e));
+ break;
+ case FAIL:
+ String msg = formatMessage(e);
+ throw new SAXException(msg);
+ }
+ }
+ }
+
+ private static String formatMessage(SAXParseException exception)
+ {
+ StringBuffer buffer = new StringBuffer(50);
+ buffer.append(exception.getMessage()).append(" @ ");
+ String location = exception.getPublicId();
+ if(location != null)
+ {
+ buffer.append(location);
+ }
+ else
+ {
+ location = exception.getSystemId();
+ if(location != null)
+ {
+ buffer.append(location);
+ }
+ else
+ {
+ buffer.append("*unknown*");
+ }
+ }
+ buffer.append('[');
+ buffer.append(exception.getLineNumber()).append(',');
+ buffer.append(exception.getColumnNumber()).append(']');
+ return buffer.toString();
+ }
+}
Added: jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xml
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xml 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xml 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<top xmlns='http://www.jboss.org/test/xml/repeatableterms'>
+ <item>item1</item>
+ <item>item2</item>
+ <item>item3</item>
+
+ <sequenceChoice1>sequenceChoice1_1</sequenceChoice1>
+ <sequenceChoice2>sequenceChoice2_1</sequenceChoice2>
+ <sequenceChoice1>sequenceChoice1_2</sequenceChoice1>
+ <sequenceChoice1>sequenceChoice1_3</sequenceChoice1>
+ <sequenceChoice2>sequenceChoice2_2</sequenceChoice2>
+
+ <choiceChoice1>choiceChoice1_1</choiceChoice1>
+ <choiceChoice1>choiceChoice1_2</choiceChoice1>
+
+ <choiceChoice2>choiceChoice2_1</choiceChoice2>
+ <choiceChoice2>choiceChoice2_2</choiceChoice2>
+
+ <choiceChoice1>choiceChoice1_3</choiceChoice1>
+ <choiceChoice1>choiceChoice1_4</choiceChoice1>
+</top>
Added: jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xsd
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xsd 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal1.xsd 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.jboss.org/test/xml/repeatableterms"
+ xmlns="http://www.jboss.org/test/xml/repeatableterms"
+ xmlns:jbxb="http://www.jboss.org/xml/ns/jbxb"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <xsd:element name="top">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <jbxb:class impl="org.jboss.test.xml.RepeatableTermsUnitTestCase$Top"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="item" type="xsd:string" maxOccurs="unbounded"/>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <jbxb:class impl="org.jboss.test.xml.RepeatableTermsUnitTestCase$Sequence"/>
+ <jbxb:property name="sequence"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:choice>
+ <xsd:element name="sequenceChoice1" type="xsd:string"/>
+ <xsd:element name="sequenceChoice2" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <jbxb:class impl="org.jboss.test.xml.RepeatableTermsUnitTestCase$Choice"/>
+ <jbxb:property name="choice"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:element name="choiceChoice1" type="xsd:string" maxOccurs="unbounded"/>
+ <xsd:element name="choiceChoice2" type="xsd:string" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
Added: jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xml
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xml 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xml 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<top xmlns='http://www.jboss.org/test/xml/repeatableterms'>
+ <item1>item1</item1>
+ <item2>item2</item2>
+</top>
Added: jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xsd
===================================================================
--- jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xsd 2006-09-20 21:34:53 UTC (rev 2047)
+++ jbossxb/trunk/src/test/resources/org/jboss/test/xml/RepeatableTermsUnitTestCase_testUnmarshal2.xsd 2006-09-21 07:19:23 UTC (rev 2048)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.jboss.org/test/xml/repeatableterms"
+ xmlns="http://www.jboss.org/test/xml/repeatableterms"
+ xmlns:jbxb="http://www.jboss.org/xml/ns/jbxb"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <xsd:element name="top">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <jbxb:class impl="org.jboss.test.xml.RepeatableTermsUnitTestCase$Top"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="item1" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:sequence maxOccurs="unbounded">
+ <xsd:element name="item2" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>
More information about the jboss-svn-commits
mailing list