[jboss-svn-commits] JBoss Common SVN: r2490 - in jbossxb/tags: jbossxb-1.0.0.CR11 and 8 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Aug 15 07:51:10 EDT 2007
Author: alex.loubyansky at jboss.com
Date: 2007-08-15 07:51:08 -0400 (Wed, 15 Aug 2007)
New Revision: 2490
Added:
jbossxb/tags/jbossxb-1.0.0.CR11/
jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml
Removed:
jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
Log:
[maven-scm] copy for tag jbossxb-1.0.0.CR11
Copied: jbossxb/tags/jbossxb-1.0.0.CR11 (from rev 2419, jbossxb/branches/1_0)
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml
===================================================================
--- jbossxb/branches/1_0/pom.xml 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,142 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>jboss</groupId>
- <artifactId>jboss-parent</artifactId>
- <version>1</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <groupId>jboss.jbossxb</groupId>
- <artifactId>jbossxb</artifactId>
- <packaging>jar</packaging>
- <version>1.0.0.SNAPSHOT</version>
- <name>JBoss XML Binding</name>
- <url>http://www.jboss.org</url>
- <description>JBoss XML Binding</description>
- <licenses>
- <license>
- <name>lgpl</name>
- <url>http://repository.jboss.com/licenses/lgpl.txt</url>
- </license>
- </licenses>
- <organization>
- <name>JBoss Inc.</name>
- <url>http://www.jboss.org</url>
- </organization>
-
- <repositories>
- <repository>
- <id>jboss</id>
- <name>JBoss Inc. Repository</name>
- <layout>default</layout>
- <url>http://repository.jboss.com/maven2/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- </repository>
- </repositories>
-
- <build>
- <finalName>jboss-xml-binding</finalName>
- <plugins>
- <!-- define how we want compilation to take place
- here, we accept most of the defaults but say that we want the
- optimization flag set, and define the source and target to be 1.4,
- these setting will be inherited by child projects -->
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.0</version>
- <configuration>
- <optimize>true</optimize>
- <source>1.4</source>
- <target>1.4</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <printSummary>true</printSummary>
- <disableXmlReport>false</disableXmlReport>
- <testFailureIgnore>true</testFailureIgnore>
- <includes>
- <include>**/**TestCase.java</include>
- </includes>
- <forkMode>pertest</forkMode> <!-- required to correctly run the PojoServer tests -->
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-report-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>jboss.logging</groupId>
- <artifactId>jboss-logging-spi</artifactId>
- <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>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>oswego-concurrent</groupId>
- <artifactId>concurrent</artifactId>
- <version>1.3.4</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>apache-slide</groupId>
- <artifactId>webdavlib</artifactId>
- <version>2.0</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>sun-jaf</groupId>
- <artifactId>activation</artifactId>
- <version>1.0.2</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>apache-xerces</groupId>
- <artifactId>xercesImpl</artifactId>
- <version>2.7.1</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>wutka-dtdparser</groupId>
- <artifactId>dtdparser121</artifactId>
- <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>
- <distributionManagement>
- <repository>
- <id>cvs-file-repository</id>
- <!-- Set maven.cvs.root in your settings.xml -->
- <url>file://${maven.cvs.root}</url>
- </repository>
- </distributionManagement>
-</project>
-
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml (from rev 2489, jbossxb/branches/1_0/pom.xml)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/pom.xml 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,155 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.jboss</groupId>
+ <artifactId>jboss-parent</artifactId>
+ <version>3</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>jbossxb</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0.0.CR11</version>
+ <name>JBoss XML Binding</name>
+ <url>http://www.jboss.org</url>
+ <description>JBoss XML Binding</description>
+ <licenses>
+ <license>
+ <name>lgpl</name>
+ <url>http://repository.jboss.com/licenses/lgpl.txt</url>
+ </license>
+ </licenses>
+ <organization>
+ <name>JBoss Inc.</name>
+ <url>http://www.jboss.org</url>
+ </organization>
+
+ <scm>
+ <connection>scm:svn:https://svn.jboss.org/repos/common/jbossxb/tags/jbossxb-1.0.0.CR11</connection>
+ </scm>
+
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <name>JBoss Inc. Repository</name>
+ <layout>default</layout>
+ <url>http://repository.jboss.com/maven2/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>snapshots.jboss.org</id>
+ <name>JBoss Snapshot Repository</name>
+ <layout>default</layout>
+ <url>http://snapshots.jboss.org/maven2/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <build>
+ <finalName>jboss-xml-binding</finalName>
+ <plugins>
+ <!-- define how we want compilation to take place
+ here, we accept most of the defaults but say that we want the
+ optimization flag set, and define the source and target to be 1.4,
+ these setting will be inherited by child projects -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0</version>
+ <configuration>
+ <optimize>true</optimize>
+ <source>1.4</source>
+ <target>1.4</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <printSummary>true</printSummary>
+ <disableXmlReport>false</disableXmlReport>
+ <testFailureIgnore>true</testFailureIgnore>
+ <includes>
+ <include>**/**TestCase.java</include>
+ </includes>
+ <forkMode>pertest</forkMode> <!-- required to correctly run the PojoServer tests -->
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.jboss.org/repos/common/jbossxb/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>jboss.logging</groupId>
+ <artifactId>jboss-logging-spi</artifactId>
+ <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>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>apache-slide</groupId>
+ <artifactId>webdavlib</artifactId>
+ <version>2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>sun-jaf</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.0.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>apache-xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ <version>2.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>wutka-dtdparser</groupId>
+ <artifactId>dtdparser121</artifactId>
+ <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>
+ <distributionManagement>
+ <repository>
+ <id>cvs-file-repository</id>
+ <!-- Set maven.cvs.root in your settings.xml -->
+ <url>file://${maven.cvs.root}</url>
+ </repository>
+ </distributionManagement>
+</project>
\ No newline at end of file
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/Content.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,393 +0,0 @@
-/*
- * 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.xb.binding;
-
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import org.jboss.logging.Logger;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-
-/**
- * An instance of this class represents XML content.
- * It is populated on unmarshalling with org.jboss.xb.binding.ContentPopulator and used
- * to implement content navigation in object model factories.
- * And on marshalling, first, an instance of this class is created and then it
- * is serialized into XML content with org.jboss.xb.binding.ContentWriter.
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class Content
-{
- private static Logger log = Logger.getLogger(Content.class);
-
- private List content = new ArrayList();
- private final boolean trace = log.isTraceEnabled();
-
- // Public
-
- public String getChildContent(String namespaceURI, String qName)
- {
- StartElement current = ((StartElement)content.get(index));
-
- boolean lookingForStart = true;
- StartElement start = null;
- boolean childFound = false;
- StringBuffer value = new StringBuffer();
-
- int i = index + 1;
- Object next = content.get(i++);
- while(!current.isMyEnd(next))
- {
- if(lookingForStart)
- {
- if(next instanceof StartElement)
- {
- start = (StartElement)next;
- lookingForStart = false;
-
- if(qName.equals(start.qName) &&
- (namespaceURI == null ? start.namespaceURI == null : namespaceURI.equals(start.namespaceURI)))
- {
- childFound = true;
- }
- }
- }
- else if(next instanceof EndElement)
- {
- if(start.isMyEnd(next))
- {
- if(childFound)
- {
- break;
- }
- else
- {
- lookingForStart = true;
- }
- }
- }
- else if(childFound && next instanceof Characters)
- {
- Characters chars = (Characters)next;
- value.append(chars.ch, chars.start, chars.length);
- }
- next = content.get(i++);
- }
- return value.toString().trim();
- }
-
- public void handleContent(ContentHandler handler) throws SAXException
- {
- handler.startDocument();
-
- for(Iterator i = content.iterator(); i.hasNext();)
- {
- Object item = i.next();
- if(item instanceof StartElement)
- {
- StartElement start = (StartElement)item;
- handler.startElement(start.namespaceURI, start.localName, start.qName, start.attrs);
- }
- else if(item instanceof EndElement)
- {
- EndElement end = (EndElement)item;
- handler.endElement(end.namespaceURI, end.localName, end.qName);
- }
- else if(item instanceof Characters)
- {
- Characters ch = (Characters)item;
- handler.characters(ch.ch, ch.start, ch.length);
- }
- else if(item instanceof StartPrefixMapping)
- {
-/*
- if(trace)
- {
- StartPrefixMapping startPrefix = (StartPrefixMapping)item;
- log.trace("start prefix mapping: " + startPrefix.prefix + "=" + startPrefix.uri);
- }
-*/
- }
- else if(item instanceof EndPrefixMapping)
- {
-/*
- if(trace)
- {
- EndPrefixMapping endPrefix = (EndPrefixMapping)item;
- log.trace("end prefix mapping: " + endPrefix.prefix);
- }
-*/
- }
- else
- {
- throw new IllegalStateException("Unexpected element type: " + item);
- }
- }
-
- handler.endDocument();
- }
-
- public String toString()
- {
- StringWriter writer = new StringWriter();
- try
- {
- ContentWriter contentWriter = new ContentWriter(writer, true);
- handleContent(contentWriter);
- }
- catch(SAXException e)
- {
- writer.write(e.getMessage());
- }
- return writer.getBuffer().toString();
- }
-
- // Methods that populate the content
-
- public void startDocument()
- {
- content.clear();
- }
-
- public void endDocument()
- {
- }
-
- public void startPrefixMapping(String prefix, String uri)
- {
- StartPrefixMapping node = new StartPrefixMapping(prefix, uri);
- content.add(node);
- }
-
- public void endPrefixMapping(String prefix)
- {
- EndPrefixMapping node = new EndPrefixMapping(prefix);
- content.add(node);
- }
-
- public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
- {
- StartElement startElement = new StartElement(namespaceURI, localName, qName, atts);
- content.add(startElement);
-
- if(trace)
- {
- log.trace("startElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName + ", attrs=" + atts);
- }
- }
-
- public void endElement(String namespaceURI, String localName, String qName)
- {
- EndElement endElement = new EndElement(namespaceURI, localName, qName);
- content.add(endElement);
-
- if(trace)
- {
- log.trace("endElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName);
- }
- }
-
- public void characters(char[] ch, int start, int length)
- {
- Characters characters = new Characters(ch, start, length);
- // ignore whitespace-only characters
- if(characters.toString().trim().length() > 0)
- {
- content.add(characters);
-
- if(trace)
- {
- log.trace("characters> " + characters);
- }
- }
- }
-
- // Methods that navigate through the content
-
- private int index;
-
- public void append(Content content)
- {
- for(Iterator i = content.content.iterator(); i.hasNext();)
- {
- this.content.add(i.next());
- }
- }
-
- // Inner
-
- private static interface Node
- {
- }
-
- public static class Characters
- implements Node
- {
- private final char[] ch;
- private final int start;
- private final int length;
-
- public Characters(char[] ch, int start, int length)
- {
- /*
- this.ch = ch;
- this.start = start;
- this.length = length;
- */
- this.ch = new char[length];
- System.arraycopy(ch, start, this.ch, 0, length);
- this.start = 0;
- this.length = length;
- }
-
- public String toString()
- {
- return String.valueOf(ch, start, length);
- }
- }
-
- public static class EndElement
- implements Node
- {
- private final String namespaceURI;
- private final String localName;
- private final String qName;
-
- public EndElement(String namespaceURI, String localName, String qName)
- {
- this.namespaceURI = namespaceURI;
- this.localName = localName;
- this.qName = qName;
- }
-
- public String toString()
- {
- return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
- }
- }
-
- public static class StartElement
- implements Node
- {
- private final String namespaceURI;
- private final String localName;
- private final String qName;
- private final Attributes attrs;
-
- public StartElement(String namespaceURI, String localName, String qName, Attributes attrs)
- {
- this.namespaceURI = namespaceURI;
- this.localName = localName;
- this.qName = qName;
- this.attrs = new AttributesImpl(attrs);
- }
-
- public boolean isMyEnd(Object element)
- {
- boolean itis = false;
- if(element instanceof EndElement)
- {
- EndElement end = (EndElement)element;
- itis = (namespaceURI == null ? end.namespaceURI == null : namespaceURI.equals(end.namespaceURI))
- && qName.equals(end.qName);
- }
- return itis;
- }
-
- public String toString()
- {
- return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
- }
- }
-
- public static class StartPrefixMapping
- implements Node
- {
- public final String prefix;
- public final String uri;
-
- public StartPrefixMapping(String prefix, String uri)
- {
- this.prefix = prefix;
- this.uri = uri;
- }
-
- public void read(ObjectModelBuilder builder)
- {
- builder.startPrefixMapping(prefix, uri);
- }
-
- public boolean equals(Object o)
- {
- if(this == o)
- {
- return true;
- }
- if(!(o instanceof StartPrefixMapping))
- {
- return false;
- }
-
- final StartPrefixMapping startPrefixMapping = (StartPrefixMapping)o;
-
- if(prefix != null ? !prefix.equals(startPrefixMapping.prefix) : startPrefixMapping.prefix != null)
- {
- return false;
- }
- if(uri != null ? !uri.equals(startPrefixMapping.uri) : startPrefixMapping.uri != null)
- {
- return false;
- }
-
- return true;
- }
-
- public int hashCode()
- {
- int result;
- result = (prefix != null ? prefix.hashCode() : 0);
- result = 29 * result + (uri != null ? uri.hashCode() : 0);
- return result;
- }
- }
-
- public static class EndPrefixMapping
- implements Node
- {
- public final String prefix;
-
- public EndPrefixMapping(String prefix)
- {
- this.prefix = prefix;
- }
-
- public void read(ObjectModelBuilder builder)
- {
- builder.endPrefixMapping(prefix);
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java (from rev 2434, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/Content.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/Content.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,393 @@
+/*
+ * 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.xb.binding;
+
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import org.jboss.logging.Logger;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * An instance of this class represents XML content.
+ * It is populated on unmarshalling with org.jboss.xb.binding.ContentPopulator and used
+ * to implement content navigation in object model factories.
+ * And on marshalling, first, an instance of this class is created and then it
+ * is serialized into XML content with org.jboss.xb.binding.ContentWriter.
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class Content
+{
+ private static Logger log = Logger.getLogger(Content.class);
+
+ private List content = new ArrayList();
+ private final boolean trace = log.isTraceEnabled();
+
+ // Public
+
+ public String getChildContent(String namespaceURI, String qName)
+ {
+ StartElement current = ((StartElement)content.get(index));
+
+ boolean lookingForStart = true;
+ StartElement start = null;
+ boolean childFound = false;
+ StringBuffer value = new StringBuffer();
+
+ int i = index + 1;
+ Object next = content.get(i++);
+ while(!current.isMyEnd(next))
+ {
+ if(lookingForStart)
+ {
+ if(next instanceof StartElement)
+ {
+ start = (StartElement)next;
+ lookingForStart = false;
+
+ if(qName.equals(start.qName) &&
+ (namespaceURI == null ? start.namespaceURI == null : namespaceURI.equals(start.namespaceURI)))
+ {
+ childFound = true;
+ }
+ }
+ }
+ else if(next instanceof EndElement)
+ {
+ if(start.isMyEnd(next))
+ {
+ if(childFound)
+ {
+ break;
+ }
+ else
+ {
+ lookingForStart = true;
+ }
+ }
+ }
+ else if(childFound && next instanceof Characters)
+ {
+ Characters chars = (Characters)next;
+ value.append(chars.ch, chars.start, chars.length);
+ }
+ next = content.get(i++);
+ }
+ return value.toString().trim();
+ }
+
+ public void handleContent(ContentHandler handler) throws SAXException
+ {
+ handler.startDocument();
+
+ for(Iterator i = content.iterator(); i.hasNext();)
+ {
+ Object item = i.next();
+ if(item instanceof StartElement)
+ {
+ StartElement start = (StartElement)item;
+ handler.startElement(start.namespaceURI, start.localName, start.qName, start.attrs);
+ }
+ else if(item instanceof EndElement)
+ {
+ EndElement end = (EndElement)item;
+ handler.endElement(end.namespaceURI, end.localName, end.qName);
+ }
+ else if(item instanceof Characters)
+ {
+ Characters ch = (Characters)item;
+ handler.characters(ch.ch, ch.start, ch.length);
+ }
+ else if(item instanceof StartPrefixMapping)
+ {
+/*
+ if(trace)
+ {
+ StartPrefixMapping startPrefix = (StartPrefixMapping)item;
+ log.trace("start prefix mapping: " + startPrefix.prefix + "=" + startPrefix.uri);
+ }
+*/
+ }
+ else if(item instanceof EndPrefixMapping)
+ {
+/*
+ if(trace)
+ {
+ EndPrefixMapping endPrefix = (EndPrefixMapping)item;
+ log.trace("end prefix mapping: " + endPrefix.prefix);
+ }
+*/
+ }
+ else
+ {
+ throw new IllegalStateException("Unexpected element type: " + item);
+ }
+ }
+
+ handler.endDocument();
+ }
+
+ public String toString()
+ {
+ StringWriter writer = new StringWriter();
+ try
+ {
+ ContentWriter contentWriter = new ContentWriter(writer, true);
+ handleContent(contentWriter);
+ }
+ catch(SAXException e)
+ {
+ writer.write(e.getMessage());
+ }
+ return writer.getBuffer().toString();
+ }
+
+ // Methods that populate the content
+
+ public void startDocument()
+ {
+ content.clear();
+ }
+
+ public void endDocument()
+ {
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ {
+ StartPrefixMapping node = new StartPrefixMapping(prefix, uri);
+ content.add(node);
+ }
+
+ public void endPrefixMapping(String prefix)
+ {
+ EndPrefixMapping node = new EndPrefixMapping(prefix);
+ content.add(node);
+ }
+
+ public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+ {
+ StartElement startElement = new StartElement(namespaceURI, localName, qName, atts);
+ content.add(startElement);
+
+ if(trace)
+ {
+ log.trace("startElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName + ", attrs=" + atts);
+ }
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName)
+ {
+ EndElement endElement = new EndElement(namespaceURI, localName, qName);
+ content.add(endElement);
+
+ if(trace)
+ {
+ log.trace("endElement> uri=" + namespaceURI + ", local=" + localName + ", qn=" + qName);
+ }
+ }
+
+ public void characters(char[] ch, int start, int length)
+ {
+ Characters characters = new Characters(ch, start, length);
+ // DON'T ignore whitespace-only characters
+ //if(characters.toString().trim().length() > 0)
+ //{
+ content.add(characters);
+
+ if(trace)
+ {
+ log.trace("characters> " + characters);
+ }
+ //}
+ }
+
+ // Methods that navigate through the content
+
+ private int index;
+
+ public void append(Content content)
+ {
+ for(Iterator i = content.content.iterator(); i.hasNext();)
+ {
+ this.content.add(i.next());
+ }
+ }
+
+ // Inner
+
+ private static interface Node
+ {
+ }
+
+ public static class Characters
+ implements Node
+ {
+ private final char[] ch;
+ private final int start;
+ private final int length;
+
+ public Characters(char[] ch, int start, int length)
+ {
+ /*
+ this.ch = ch;
+ this.start = start;
+ this.length = length;
+ */
+ this.ch = new char[length];
+ System.arraycopy(ch, start, this.ch, 0, length);
+ this.start = 0;
+ this.length = length;
+ }
+
+ public String toString()
+ {
+ return String.valueOf(ch, start, length);
+ }
+ }
+
+ public static class EndElement
+ implements Node
+ {
+ private final String namespaceURI;
+ private final String localName;
+ private final String qName;
+
+ public EndElement(String namespaceURI, String localName, String qName)
+ {
+ this.namespaceURI = namespaceURI;
+ this.localName = localName;
+ this.qName = qName;
+ }
+
+ public String toString()
+ {
+ return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
+ }
+ }
+
+ public static class StartElement
+ implements Node
+ {
+ private final String namespaceURI;
+ private final String localName;
+ private final String qName;
+ private final Attributes attrs;
+
+ public StartElement(String namespaceURI, String localName, String qName, Attributes attrs)
+ {
+ this.namespaceURI = namespaceURI;
+ this.localName = localName;
+ this.qName = qName;
+ this.attrs = new AttributesImpl(attrs);
+ }
+
+ public boolean isMyEnd(Object element)
+ {
+ boolean itis = false;
+ if(element instanceof EndElement)
+ {
+ EndElement end = (EndElement)element;
+ itis = (namespaceURI == null ? end.namespaceURI == null : namespaceURI.equals(end.namespaceURI))
+ && qName.equals(end.qName);
+ }
+ return itis;
+ }
+
+ public String toString()
+ {
+ return '[' + namespaceURI + ',' + localName + ',' + qName + ']';
+ }
+ }
+
+ public static class StartPrefixMapping
+ implements Node
+ {
+ public final String prefix;
+ public final String uri;
+
+ public StartPrefixMapping(String prefix, String uri)
+ {
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+
+ public void read(ObjectModelBuilder builder)
+ {
+ builder.startPrefixMapping(prefix, uri);
+ }
+
+ public boolean equals(Object o)
+ {
+ if(this == o)
+ {
+ return true;
+ }
+ if(!(o instanceof StartPrefixMapping))
+ {
+ return false;
+ }
+
+ final StartPrefixMapping startPrefixMapping = (StartPrefixMapping)o;
+
+ if(prefix != null ? !prefix.equals(startPrefixMapping.prefix) : startPrefixMapping.prefix != null)
+ {
+ return false;
+ }
+ if(uri != null ? !uri.equals(startPrefixMapping.uri) : startPrefixMapping.uri != null)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result;
+ result = (prefix != null ? prefix.hashCode() : 0);
+ result = 29 * result + (uri != null ? uri.hashCode() : 0);
+ return result;
+ }
+ }
+
+ public static class EndPrefixMapping
+ implements Node
+ {
+ public final String prefix;
+
+ public EndPrefixMapping(String prefix)
+ {
+ this.prefix = prefix;
+ }
+
+ public void read(ObjectModelBuilder builder)
+ {
+ builder.endPrefixMapping(prefix);
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,557 +0,0 @@
-/*
- * 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.xb.binding;
-
-import org.xml.sax.Attributes;
-import org.jboss.logging.Logger;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.apache.xerces.xs.XSTypeDefinition;
-
-import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.StringTokenizer;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * An instance of this class translates SAX events into org.jboss.xml.binding.GenericObjectModelFactory calls
- * such as newChild, addChild and setValue.
- * WARN: this implementation is not thread-safe!
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class ObjectModelBuilder
- implements UnmarshallingContext, JBossXBParser.ContentHandler
-{
- /**
- * logger
- */
- private static final Logger log = Logger.getLogger(ObjectModelBuilder.class);
-
- /**
- * The object that represents an ignored by the object model factory XML element, i.e. the factory returned null
- * from its newChild method
- */
- private static final Object IGNORED = new Object();
-
- /**
- * The root of the unmarshalled object graph
- */
- private Object root;
-
- /**
- * the stack of all the objects including IGNORED
- */
- private Stack all = new StackImpl();
-
- /**
- * the stack of only accepted objects (all - IGNORED)
- */
- private Stack accepted = new StackImpl();
-
- private GenericObjectModelFactory curFactory;
- private String curNameSwitchingFactory;
- private String curNsSwitchingFactory;
- private Stack nameSwitchingFactory;
- private Stack nsSwitchingFactory;
-
- /**
- * default object model factory
- */
- private GenericObjectModelFactory defaultFactory;
-
- /**
- * factories mapped to namespace URIs
- */
- private Map factoriesToNs = Collections.EMPTY_MAP;
-
- /**
- * NamespaceContext implementation
- */
- private final NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
- private XSTypeDefinition currentType;
-
- private boolean trace = log.isTraceEnabled();
-
- // Public
-
- public void mapFactoryToNamespace(ObjectModelFactory factory, String namespaceUri)
- {
- if(factoriesToNs == Collections.EMPTY_MAP)
- {
- factoriesToNs = new HashMap();
- }
- factoriesToNs.put(namespaceUri, getGenericObjectModelFactory(factory));
- }
-
- public void init(ObjectModelFactory defaultFactory, Object root)
- {
- this.defaultFactory = getGenericObjectModelFactory(defaultFactory);
- all.clear();
- accepted.clear();
- this.root = root;
- }
-
- public void pushFactory(String namespaceURI, String localName, GenericObjectModelFactory factory)
- {
- if(curNsSwitchingFactory != null)
- {
- if(nsSwitchingFactory == null)
- {
- nsSwitchingFactory = new StackImpl();
- nameSwitchingFactory = new StackImpl();
- }
- nsSwitchingFactory.push(curNsSwitchingFactory);
- nameSwitchingFactory.push(curNameSwitchingFactory);
- }
- curNsSwitchingFactory = namespaceURI;
- curNameSwitchingFactory = localName;
- curFactory = factory;
- }
-
- public void popFactory()
- {
- if(nsSwitchingFactory == null || nsSwitchingFactory.isEmpty())
- {
- curNameSwitchingFactory = null;
- curNsSwitchingFactory = null;
- }
- else
- {
- curNameSwitchingFactory = (String)nameSwitchingFactory.pop();
- curNsSwitchingFactory = (String)nsSwitchingFactory.pop();
- }
-
- curFactory = getFactory(curNsSwitchingFactory);
- }
-
- // UnmarshallingContext implementation
-
- public Iterator getNamespaceURIs()
- {
- return nsRegistry.getRegisteredURIs();
- }
-
- public NamespaceContext getNamespaceContext()
- {
- return nsRegistry;
- }
-
- /**
- * Construct a QName from a value
- *
- * @param value A value that is of the form [prefix:]localpart
- */
- public QName resolveQName(String value)
- {
- StringTokenizer st = new StringTokenizer(value, ":");
- if(st.countTokens() == 1)
- return new QName(value);
-
- if(st.countTokens() != 2)
- throw new IllegalArgumentException("Illegal QName: " + value);
-
- String prefix = st.nextToken();
- String local = st.nextToken();
- String nsURI = nsRegistry.getNamespaceURI(prefix);
- if (nsURI == null)
- throw new IllegalStateException("Cannot obtain namespace URI for prefix: " + prefix);
-
- return new QName(nsURI, local, prefix);
- }
-
- public String getChildContent(String namespaceURI, String qName)
- {
- // todo reimplement later
- throw new UnsupportedOperationException();
- //return content.getChildContent(namespaceURI, qName);
- }
-
- public XSTypeDefinition getType()
- {
- return currentType;
- }
-
- // Public
-
- public void startPrefixMapping(String prefix, String uri)
- {
- nsRegistry.addPrefixMapping(prefix, uri);
- }
-
- public void endPrefixMapping(String prefix)
- {
- nsRegistry.removePrefixMapping(prefix);
- }
-
- public void processingInstruction(String target, String data)
- {
- if(!"jbossxb".equals(target))
- {
- return;
- }
-
- int i = data.indexOf("factory=\"");
- if(i != -1)
- {
- int end = data.indexOf('\"', i + 9);
- if(end == -1)
- {
- throw new JBossXBRuntimeException(
- "Property 'factory' is not terminated with '\"' in processing instruction: " + data
- );
- }
-
- String factoryProp = data.substring(i + 9, end);
- Class factoryCls;
- try
- {
- factoryCls = Thread.currentThread().getContextClassLoader().loadClass(factoryProp);
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException("Failed to load factory class : " + e.getMessage(), e);
- }
-
- ObjectModelFactory factory;
- try
- {
- factory = (ObjectModelFactory)factoryCls.newInstance();
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("Failed to instantiate factory " + factoryProp + ": " + e.getMessage(),
- e
- );
- }
-
- i = data.indexOf("ns=\"");
- if(i == -1)
- {
- throw new JBossXBRuntimeException(
- "Property 'ns' not found in factory mapping processing instruction: " + data
- );
- }
-
- end = data.indexOf("\"", i + 4);
- if(end == -1)
- {
- throw new JBossXBRuntimeException(
- "Property 'ns' is not terminated with '\"' in processing instruction: " + data
- );
- }
-
- String nsProp = data.substring(i + 4, end);
- mapFactoryToNamespace(factory, nsProp);
- }
- else
- {
- throw new JBossXBRuntimeException(
- "Unexpected data in processing instruction: target=" + target + ", data=" + data
- );
- }
- }
-
- public Object getRoot()
- {
- if(!all.isEmpty())
- {
- popAll();
- popAccepted();
- }
- return root;
- }
-
- public void startElement(String namespaceURI,
- String localName,
- String qName,
- Attributes atts,
- XSTypeDefinition type)
- {
- Object parent = accepted.isEmpty() ? root : peekAccepted();
-
- // todo currentType assignment
- currentType = type;
-
- Object element;
- if(!namespaceURI.equals(curNsSwitchingFactory))
- {
- GenericObjectModelFactory newFactory = getFactory(namespaceURI);
- if(newFactory != curFactory)
- {
- element = newFactory.newRoot(parent, this, namespaceURI, localName, atts);
- }
- else
- {
- element = newFactory.newChild(parent, this, namespaceURI, localName, atts);
- }
-
- // still have to push since curNsSwitchingFactory needs to be updated to prevent
- // newRoot calls for the children
- pushFactory(namespaceURI, localName, newFactory);
- }
- else
- {
- element = curFactory.newChild(parent, this, namespaceURI, localName, atts);
- }
-
- if(element == null)
- {
- pushAll(IGNORED);
-
- if(trace)
- {
- log.trace("ignored " + namespaceURI + ':' + qName);
- }
- }
- else
- {
- pushAll(element);
- pushAccepted(element);
-
- if(trace)
- {
- log.trace("accepted " + namespaceURI + ':' + qName);
- }
- }
- }
-
- public void endElement(String namespaceURI, String localName, String qName)
- {
- AllElement element = popAll();
-
- if(!accepted.isEmpty())
- {
- Object acceptedElement = peekAccepted();
- if(element.characters != null && element.characters.length() > 0)
- {
- String characters = element.characters.toString().trim();
- if(characters.length() > 0)
- {
- curFactory.setValue(acceptedElement, this, namespaceURI, localName, characters);
- }
- }
- }
-
- if(localName.equals(curNameSwitchingFactory) && namespaceURI.equals(curNsSwitchingFactory))
- {
- popFactory();
- }
-
- if(element.element != IGNORED)
- {
- popAccepted();
- Object parent = (accepted.isEmpty() ? null : peekAccepted());
-
- if(parent != null)
- {
- curFactory.addChild(parent, element.element, this, namespaceURI, localName);
- }
- else
- {
- root = curFactory.completeRoot(element.element, this, namespaceURI, localName);
- }
- }
- }
-
- public void characters(char[] ch, int start, int length)
- {
- if(!accepted.isEmpty())
- {
- String str = String.valueOf(ch, start, length);
- AllElement allElement = peekAll();
- if(allElement.characters == null)
- {
- allElement.characters = new StringBuffer(str);
- }
- else
- {
- allElement.characters.append(str);
- }
- }
- }
-
- // Private
-
- private GenericObjectModelFactory getFactory(String namespaceUri)
- {
- GenericObjectModelFactory factory = (GenericObjectModelFactory)factoriesToNs.get(namespaceUri);
- if(factory == null)
- {
- factory = defaultFactory;
- }
- return factory;
- }
-
- static Object invokeFactory(Object factory, Method method, Object[] args)
- {
- try
- {
- return method.invoke(factory, args);
- }
- catch(InvocationTargetException e)
- {
- Throwable te = e.getCause();
- if(te instanceof RuntimeException)
- {
- throw (RuntimeException)te;
- }
-
- String msg = "Failed to invoke method " + method + ", factory=" + factory;
- log.error(msg, e.getTargetException());
-
- IllegalStateException ise = new IllegalStateException(msg);
- ise.initCause(te);
- throw ise;
- }
- catch(Exception e)
- {
- String msg = "Failed to invoke method " + method.getName() + ", factory=" + factory;
- log.error(msg, e);
- IllegalStateException ise = new IllegalStateException(msg);
- ise.initCause(e);
- throw ise;
- }
- }
-
- static Method getMethodForElement(Object factory, String name, Class[] params)
- {
- Method method = null;
- try
- {
- method = factory.getClass().getMethod(name, params);
- }
- catch(NoSuchMethodException e)
- {
- }
- catch(SecurityException e)
- {
- throw e;
- }
-
- return method;
- }
-
- static final GenericObjectModelFactory getGenericObjectModelFactory(ObjectModelFactory factory)
- {
- if(!(factory instanceof GenericObjectModelFactory))
- {
- factory = new DelegatingObjectModelFactory(factory);
- }
- return factory instanceof GenericObjectModelFactory ?
- (GenericObjectModelFactory)factory :
- new DelegatingObjectModelFactory(factory);
- }
-
- private void pushAccepted(Object o)
- {
- accepted.push(o);
- }
-
- private Object popAccepted()
- {
- return accepted.pop();
- }
-
- private Object peekAccepted()
- {
- return accepted.peek();
- }
-
- private void pushAll(Object o)
- {
- all.push(new AllElement(o));
- }
-
- private AllElement popAll()
- {
- return (AllElement)all.pop();
- }
-
- private AllElement peekAll()
- {
- return (AllElement)all.peek();
- }
-
- private static final class AllElement
- {
- public final Object element;
- public StringBuffer characters;
-
- public AllElement(Object element)
- {
- this.element = element;
- }
- }
-
- private static interface Stack
- {
- void clear();
-
- void push(Object o);
-
- Object pop();
-
- Object peek();
-
- boolean isEmpty();
- }
-
- private static class StackImpl
- implements Stack
- {
- private List list = new ArrayList();
-
- public void clear()
- {
- list.clear();
- }
-
- public void push(Object o)
- {
- list.add(o);
- }
-
- public Object pop()
- {
- return list.remove(list.size() - 1);
- }
-
- public Object peek()
- {
- return list.get(list.size() - 1);
- }
-
- public boolean isEmpty()
- {
- return list.isEmpty();
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/ObjectModelBuilder.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,577 @@
+/*
+ * 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.xb.binding;
+
+import org.xml.sax.Attributes;
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.apache.xerces.xs.XSTypeDefinition;
+
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.StringTokenizer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * An instance of this class translates SAX events into org.jboss.xml.binding.GenericObjectModelFactory calls
+ * such as newChild, addChild and setValue.
+ * WARN: this implementation is not thread-safe!
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class ObjectModelBuilder
+ implements UnmarshallingContext, JBossXBParser.ContentHandler
+{
+ /**
+ * logger
+ */
+ private static final Logger log = Logger.getLogger(ObjectModelBuilder.class);
+
+ /**
+ * The object that represents an ignored by the object model factory XML element, i.e. the factory returned null
+ * from its newChild method
+ */
+ private static final Object IGNORED = new Object();
+
+ /**
+ * The root of the unmarshalled object graph
+ */
+ private Object root;
+
+ /**
+ * the stack of all the objects including IGNORED
+ */
+ private Stack all = new StackImpl();
+
+ /**
+ * the stack of only accepted objects (all - IGNORED)
+ */
+ private Stack accepted = new StackImpl();
+
+ private GenericObjectModelFactory curFactory;
+ private String curNameSwitchingFactory;
+ private String curNsSwitchingFactory;
+ private Stack nameSwitchingFactory;
+ private Stack nsSwitchingFactory;
+
+ /**
+ * default object model factory
+ */
+ private GenericObjectModelFactory defaultFactory;
+
+ /**
+ * factories mapped to namespace URIs
+ */
+ private Map factoriesToNs = Collections.EMPTY_MAP;
+
+ /**
+ * NamespaceContext implementation
+ */
+ private final NamespaceRegistry nsRegistry = new NamespaceRegistry();
+
+ // whether text content should be trimmed before it is set
+ private boolean trimTextContent = true; // for backwards compatibility
+
+ private XSTypeDefinition currentType;
+
+ private boolean trace = log.isTraceEnabled();
+
+ // Public
+
+ public void mapFactoryToNamespace(ObjectModelFactory factory, String namespaceUri)
+ {
+ if(factoriesToNs == Collections.EMPTY_MAP)
+ {
+ factoriesToNs = new HashMap();
+ }
+ factoriesToNs.put(namespaceUri, getGenericObjectModelFactory(factory));
+ }
+
+ public void init(ObjectModelFactory defaultFactory, Object root)
+ {
+ this.defaultFactory = getGenericObjectModelFactory(defaultFactory);
+ all.clear();
+ accepted.clear();
+ this.root = root;
+ }
+
+ public void pushFactory(String namespaceURI, String localName, GenericObjectModelFactory factory)
+ {
+ if(curNsSwitchingFactory != null)
+ {
+ if(nsSwitchingFactory == null)
+ {
+ nsSwitchingFactory = new StackImpl();
+ nameSwitchingFactory = new StackImpl();
+ }
+ nsSwitchingFactory.push(curNsSwitchingFactory);
+ nameSwitchingFactory.push(curNameSwitchingFactory);
+ }
+ curNsSwitchingFactory = namespaceURI;
+ curNameSwitchingFactory = localName;
+ curFactory = factory;
+ }
+
+ public void popFactory()
+ {
+ if(nsSwitchingFactory == null || nsSwitchingFactory.isEmpty())
+ {
+ curNameSwitchingFactory = null;
+ curNsSwitchingFactory = null;
+ }
+ else
+ {
+ curNameSwitchingFactory = (String)nameSwitchingFactory.pop();
+ curNsSwitchingFactory = (String)nsSwitchingFactory.pop();
+ }
+
+ curFactory = getFactory(curNsSwitchingFactory);
+ }
+
+ // UnmarshallingContext implementation
+
+ public Iterator getNamespaceURIs()
+ {
+ return nsRegistry.getRegisteredURIs();
+ }
+
+ public NamespaceContext getNamespaceContext()
+ {
+ return nsRegistry;
+ }
+
+ public boolean isTrimTextContent()
+ {
+ return trimTextContent;
+ }
+
+ public void setTrimTextContent(boolean trimTextContent)
+ {
+ this.trimTextContent = trimTextContent;
+ }
+
+ /**
+ * Construct a QName from a value
+ *
+ * @param value A value that is of the form [prefix:]localpart
+ */
+ public QName resolveQName(String value)
+ {
+ StringTokenizer st = new StringTokenizer(value, ":");
+ if(st.countTokens() == 1)
+ return new QName(value);
+
+ if(st.countTokens() != 2)
+ throw new IllegalArgumentException("Illegal QName: " + value);
+
+ String prefix = st.nextToken();
+ String local = st.nextToken();
+ String nsURI = nsRegistry.getNamespaceURI(prefix);
+ if (nsURI == null)
+ throw new IllegalStateException("Cannot obtain namespace URI for prefix: " + prefix);
+
+ return new QName(nsURI, local, prefix);
+ }
+
+ public String getChildContent(String namespaceURI, String qName)
+ {
+ // todo reimplement later
+ throw new UnsupportedOperationException();
+ //return content.getChildContent(namespaceURI, qName);
+ }
+
+ public XSTypeDefinition getType()
+ {
+ return currentType;
+ }
+
+ // Public
+
+ public void startPrefixMapping(String prefix, String uri)
+ {
+ nsRegistry.addPrefixMapping(prefix, uri);
+ }
+
+ public void endPrefixMapping(String prefix)
+ {
+ nsRegistry.removePrefixMapping(prefix);
+ }
+
+ public void processingInstruction(String target, String data)
+ {
+ if(!"jbossxb".equals(target))
+ {
+ return;
+ }
+
+ int i = data.indexOf("factory=\"");
+ if(i != -1)
+ {
+ int end = data.indexOf('\"', i + 9);
+ if(end == -1)
+ {
+ throw new JBossXBRuntimeException(
+ "Property 'factory' is not terminated with '\"' in processing instruction: " + data
+ );
+ }
+
+ String factoryProp = data.substring(i + 9, end);
+ Class factoryCls;
+ try
+ {
+ factoryCls = Thread.currentThread().getContextClassLoader().loadClass(factoryProp);
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException("Failed to load factory class : " + e.getMessage(), e);
+ }
+
+ ObjectModelFactory factory;
+ try
+ {
+ factory = (ObjectModelFactory)factoryCls.newInstance();
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("Failed to instantiate factory " + factoryProp + ": " + e.getMessage(),
+ e
+ );
+ }
+
+ i = data.indexOf("ns=\"");
+ if(i == -1)
+ {
+ throw new JBossXBRuntimeException(
+ "Property 'ns' not found in factory mapping processing instruction: " + data
+ );
+ }
+
+ end = data.indexOf("\"", i + 4);
+ if(end == -1)
+ {
+ throw new JBossXBRuntimeException(
+ "Property 'ns' is not terminated with '\"' in processing instruction: " + data
+ );
+ }
+
+ String nsProp = data.substring(i + 4, end);
+ mapFactoryToNamespace(factory, nsProp);
+ }
+ else
+ {
+ throw new JBossXBRuntimeException(
+ "Unexpected data in processing instruction: target=" + target + ", data=" + data
+ );
+ }
+ }
+
+ public Object getRoot()
+ {
+ if(!all.isEmpty())
+ {
+ popAll();
+ popAccepted();
+ }
+ return root;
+ }
+
+ public void startElement(String namespaceURI,
+ String localName,
+ String qName,
+ Attributes atts,
+ XSTypeDefinition type)
+ {
+ Object parent = accepted.isEmpty() ? root : peekAccepted();
+
+ // todo currentType assignment
+ currentType = type;
+
+ Object element;
+ if(!namespaceURI.equals(curNsSwitchingFactory))
+ {
+ GenericObjectModelFactory newFactory = getFactory(namespaceURI);
+ if(newFactory != curFactory)
+ {
+ element = newFactory.newRoot(parent, this, namespaceURI, localName, atts);
+ }
+ else
+ {
+ element = newFactory.newChild(parent, this, namespaceURI, localName, atts);
+ }
+
+ // still have to push since curNsSwitchingFactory needs to be updated to prevent
+ // newRoot calls for the children
+ pushFactory(namespaceURI, localName, newFactory);
+ }
+ else
+ {
+ element = curFactory.newChild(parent, this, namespaceURI, localName, atts);
+ }
+
+ if(element == null)
+ {
+ pushAll(IGNORED);
+
+ if(trace)
+ {
+ log.trace("ignored " + namespaceURI + ':' + qName);
+ }
+ }
+ else
+ {
+ pushAll(element);
+ pushAccepted(element);
+
+ if(trace)
+ {
+ log.trace("accepted " + namespaceURI + ':' + qName);
+ }
+ }
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName)
+ {
+ AllElement element = popAll();
+
+ if(!accepted.isEmpty())
+ {
+ Object acceptedElement = peekAccepted();
+ if(element.characters != null && element.characters.length() > 0)
+ {
+ if(trimTextContent)
+ {
+ String characters = element.characters.toString().trim();
+ if (characters.length() > 0)
+ {
+ curFactory.setValue(acceptedElement, this, namespaceURI, localName, characters);
+ }
+ }
+ else
+ {
+ curFactory.setValue(acceptedElement, this, namespaceURI, localName, element.characters.toString());
+ }
+ }
+ }
+
+ if(localName.equals(curNameSwitchingFactory) && namespaceURI.equals(curNsSwitchingFactory))
+ {
+ popFactory();
+ }
+
+ if(element.element != IGNORED)
+ {
+ popAccepted();
+ Object parent = (accepted.isEmpty() ? null : peekAccepted());
+
+ if(parent != null)
+ {
+ curFactory.addChild(parent, element.element, this, namespaceURI, localName);
+ }
+ else
+ {
+ root = curFactory.completeRoot(element.element, this, namespaceURI, localName);
+ }
+ }
+ }
+
+ public void characters(char[] ch, int start, int length)
+ {
+ if(!accepted.isEmpty())
+ {
+ String str = String.valueOf(ch, start, length);
+ AllElement allElement = peekAll();
+ if(allElement.characters == null)
+ {
+ allElement.characters = new StringBuffer(str);
+ }
+ else
+ {
+ allElement.characters.append(str);
+ }
+ }
+ }
+
+ // Private
+
+ private GenericObjectModelFactory getFactory(String namespaceUri)
+ {
+ GenericObjectModelFactory factory = (GenericObjectModelFactory)factoriesToNs.get(namespaceUri);
+ if(factory == null)
+ {
+ factory = defaultFactory;
+ }
+ return factory;
+ }
+
+ static Object invokeFactory(Object factory, Method method, Object[] args)
+ {
+ try
+ {
+ return method.invoke(factory, args);
+ }
+ catch(InvocationTargetException e)
+ {
+ Throwable te = e.getCause();
+ if(te instanceof RuntimeException)
+ {
+ throw (RuntimeException)te;
+ }
+
+ String msg = "Failed to invoke method " + method + ", factory=" + factory;
+ log.error(msg, e.getTargetException());
+
+ IllegalStateException ise = new IllegalStateException(msg);
+ ise.initCause(te);
+ throw ise;
+ }
+ catch(Exception e)
+ {
+ String msg = "Failed to invoke method " + method.getName() + ", factory=" + factory;
+ log.error(msg, e);
+ IllegalStateException ise = new IllegalStateException(msg);
+ ise.initCause(e);
+ throw ise;
+ }
+ }
+
+ static Method getMethodForElement(Object factory, String name, Class[] params)
+ {
+ Method method = null;
+ try
+ {
+ method = factory.getClass().getMethod(name, params);
+ }
+ catch(NoSuchMethodException e)
+ {
+ }
+ catch(SecurityException e)
+ {
+ throw e;
+ }
+
+ return method;
+ }
+
+ static final GenericObjectModelFactory getGenericObjectModelFactory(ObjectModelFactory factory)
+ {
+ if(!(factory instanceof GenericObjectModelFactory))
+ {
+ factory = new DelegatingObjectModelFactory(factory);
+ }
+ return factory instanceof GenericObjectModelFactory ?
+ (GenericObjectModelFactory)factory :
+ new DelegatingObjectModelFactory(factory);
+ }
+
+ private void pushAccepted(Object o)
+ {
+ accepted.push(o);
+ }
+
+ private Object popAccepted()
+ {
+ return accepted.pop();
+ }
+
+ private Object peekAccepted()
+ {
+ return accepted.peek();
+ }
+
+ private void pushAll(Object o)
+ {
+ all.push(new AllElement(o));
+ }
+
+ private AllElement popAll()
+ {
+ return (AllElement)all.pop();
+ }
+
+ private AllElement peekAll()
+ {
+ return (AllElement)all.peek();
+ }
+
+ private static final class AllElement
+ {
+ public final Object element;
+ public StringBuffer characters;
+
+ public AllElement(Object element)
+ {
+ this.element = element;
+ }
+ }
+
+ private static interface Stack
+ {
+ void clear();
+
+ void push(Object o);
+
+ Object pop();
+
+ Object peek();
+
+ boolean isEmpty();
+ }
+
+ private static class StackImpl
+ implements Stack
+ {
+ private List list = new ArrayList();
+
+ public void clear()
+ {
+ list.clear();
+ }
+
+ public void push(Object o)
+ {
+ list.add(o);
+ }
+
+ public Object pop()
+ {
+ return list.remove(list.size() - 1);
+ }
+
+ public Object peek()
+ {
+ return list.get(list.size() - 1);
+ }
+
+ public boolean isEmpty()
+ {
+ return list.isEmpty();
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,67 +0,0 @@
-/*
- * 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.xb.binding;
-
-import org.apache.xerces.xs.XSTypeDefinition;
-
-import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
-import java.util.Iterator;
-
-/**
- * An interface for content navigation. At the moment it has only one method to get child's content.
- * But it could also implement XPath navigation.
- *
- * @version <tt>$Revision$</tt>
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- */
-public interface UnmarshallingContext
-{
- /** Construct a QName from a value
- * @param value A value that is of the form [prefix:]localpart
- */
- QName resolveQName(String value);
-
- /**
- * @return all the known namespace URIs
- */
- Iterator getNamespaceURIs();
-
- /**
- * @return NamespaceContext instance
- */
- NamespaceContext getNamespaceContext();
-
- /**
- * Returns child's content.
- * todo consider deprecating this method
- * @param namespaceURI
- * @param qName
- * @return
- */
- String getChildContent(String namespaceURI, String qName);
-
- /**
- * @return current element's type definition or null if this info is not available
- */
- XSTypeDefinition getType();
-}
\ No newline at end of file
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/UnmarshallingContext.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,79 @@
+/*
+ * 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.xb.binding;
+
+import org.apache.xerces.xs.XSTypeDefinition;
+
+import javax.xml.namespace.QName;
+import javax.xml.namespace.NamespaceContext;
+import java.util.Iterator;
+
+/**
+ * An interface for content navigation. At the moment it has only one method to get child's content.
+ * But it could also implement XPath navigation.
+ *
+ * @version <tt>$Revision$</tt>
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ */
+public interface UnmarshallingContext
+{
+ /** Construct a QName from a value
+ * @param value A value that is of the form [prefix:]localpart
+ */
+ QName resolveQName(String value);
+
+ /**
+ * @return all the known namespace URIs
+ */
+ Iterator getNamespaceURIs();
+
+ /**
+ * @return NamespaceContext instance
+ */
+ NamespaceContext getNamespaceContext();
+
+ /**
+ * @return true if the text content passed to the setValue(...) method
+ * is automatically trimmed (the default).
+ */
+ boolean isTrimTextContent();
+
+ /**
+ * Should the text content be automatically trimmed before setValue(...) is called.
+ * @param trimTextContent
+ */
+ void setTrimTextContent(boolean trimTextContent);
+
+ /**
+ * Returns child's content.
+ * todo consider deprecating this method
+ * @param namespaceURI
+ * @param qName
+ * @return
+ */
+ String getChildContent(String namespaceURI, String qName);
+
+ /**
+ * @return current element's type definition or null if this info is not available
+ */
+ XSTypeDefinition getType();
+}
\ No newline at end of file
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,128 +0,0 @@
-/*
- * 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.xb.binding.introspection;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.util.Map;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: $</tt>
- */
-public class ClassInfo
-{
- private static final Object FIELD_INFO_NA = new Object();
- private final Class type;
- private Map fields = new ConcurrentHashMap();
- private boolean introspected;
-
- public ClassInfo(Class cls)
- {
- this.type = cls;
- }
-
- public Class getType()
- {
- return type;
- }
-
- /**
- * @param name the name of the field
- * @param required if true never returns null (if the FieldInfo is not available, an exception will be thrown).
- * If false and FieldInfo is not available then null will be returned.
- * @return an instance of FieldInfo or null
- */
- public FieldInfo getFieldInfo(String name, boolean required)
- {
- Object o = fields.get(name);
- if(o == null)
- {
- FieldInfo fieldInfo = FieldInfo.getFieldInfo(this, name);
- if(fieldInfo == null)
- {
- fields.put(name, FIELD_INFO_NA);
- }
- else
- {
- return fieldInfo;
- }
- }
- else if(o != FIELD_INFO_NA)
- {
- return (FieldInfo)o;
- }
-
- if(required)
- {
- throw new JBossXBRuntimeException(
- "Failed to find read method or field for property '" + name + "' in " + type
- );
- }
-
- return null;
- }
-
- void addFieldInfo(FieldInfo fieldInfo)
- {
- fields.put(fieldInfo.getName(), fieldInfo);
- }
-
- FieldInfo introspect(String name)
- {
- if(introspected)
- {
- return null;
- }
-
- try
- {
- BeanInfo info = java.beans.Introspector.getBeanInfo(type);
- PropertyDescriptor[] props = info.getPropertyDescriptors();
- if(props != null)
- {
- for(int i = 0; i < props.length; ++i)
- {
- PropertyDescriptor prop = props[i];
- Method readMethod = prop.getReadMethod();
- // todo: there are issues with null readMethod, e.g. scale in BigDecimal...
- if(readMethod != null)
- {
- Method writeMethod = prop.getWriteMethod();
- FieldInfo fieldInfo = new FieldInfo(type, prop.getName(), readMethod, writeMethod);
- addFieldInfo(fieldInfo);
- }
- }
- }
- }
- catch(IntrospectionException e)
- {
- }
-
- introspected = true;
- return getFieldInfo(name, false);
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java (from rev 2482, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfo.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,129 @@
+/*
+ * 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.xb.binding.introspection;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.xb.binding.JBossXBRuntimeException;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: $</tt>
+ */
+public class ClassInfo
+{
+ private static final Object FIELD_INFO_NA = new Object();
+ private final Class type;
+ private Map fields = new ConcurrentHashMap();
+ private boolean introspected;
+
+ public ClassInfo(Class cls)
+ {
+ this.type = cls;
+ }
+
+ public Class getType()
+ {
+ return type;
+ }
+
+ /**
+ * @param name the name of the field
+ * @param required if true never returns null (if the FieldInfo is not available, an exception will be thrown).
+ * If false and FieldInfo is not available then null will be returned.
+ * @return an instance of FieldInfo or null
+ */
+ public FieldInfo getFieldInfo(String name, boolean required)
+ {
+ Object o = fields.get(name);
+ if(o == null)
+ {
+ FieldInfo fieldInfo = FieldInfo.getFieldInfo(this, name);
+ if(fieldInfo == null)
+ {
+ fields.put(name, FIELD_INFO_NA);
+ }
+ else
+ {
+ return fieldInfo;
+ }
+ }
+ else if(o != FIELD_INFO_NA)
+ {
+ return (FieldInfo)o;
+ }
+
+ if(required)
+ {
+ throw new JBossXBRuntimeException(
+ "Failed to find read method or field for property '" + name + "' in " + type
+ );
+ }
+
+ return null;
+ }
+
+ void addFieldInfo(FieldInfo fieldInfo)
+ {
+ fields.put(fieldInfo.getName(), fieldInfo);
+ }
+
+ FieldInfo introspect(String name)
+ {
+ if(introspected)
+ {
+ return null;
+ }
+
+ try
+ {
+ BeanInfo info = java.beans.Introspector.getBeanInfo(type);
+ PropertyDescriptor[] props = info.getPropertyDescriptors();
+ if(props != null)
+ {
+ for(int i = 0; i < props.length; ++i)
+ {
+ PropertyDescriptor prop = props[i];
+ Method readMethod = prop.getReadMethod();
+ // todo: there are issues with null readMethod, e.g. scale in BigDecimal...
+ if(readMethod != null)
+ {
+ Method writeMethod = prop.getWriteMethod();
+ FieldInfo fieldInfo = new FieldInfo(type, prop.getName(), readMethod, writeMethod);
+ addFieldInfo(fieldInfo);
+ }
+ }
+ }
+ }
+ catch(IntrospectionException e)
+ {
+ }
+
+ introspected = true;
+ return getFieldInfo(name, false);
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,174 +0,0 @@
-/*
- * 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.xb.binding.introspection;
-
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.lang.ref.WeakReference;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.util.NoopMap;
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: $</tt>
- */
-public class ClassInfos
-{
- private static Map classloaderCache = new WeakHashMap();
-
- /**
- * Disables caching of ClassInfo's. Already cached ClassInfo's will be lost after
- * the method returns.
- */
- public static void disableCache()
- {
- synchronized(classloaderCache)
- {
- classloaderCache = NoopMap.INSTANCE;
- }
- }
-
- /**
- * Enables caching of ClassInfo's unless caching is already enabled.
- */
- public static void enableCache()
- {
- synchronized(classloaderCache)
- {
- if(!isCacheEnabled())
- {
- classloaderCache = new WeakHashMap();
- }
- }
- }
-
- /**
- * @return true if caching is enabled, false otherwise.
- */
- public static boolean isCacheEnabled()
- {
- synchronized(classloaderCache)
- {
- return classloaderCache != NoopMap.INSTANCE;
- }
- }
-
- /**
- * Flushes all the cached ClassInfo's.
- */
- public static void flushCache()
- {
- synchronized(classloaderCache)
- {
- classloaderCache.clear();
- }
- }
-
- /**
- * Evicts ClassInfo for a specific class.
- * @param cls fully qualified class name of the class
- */
- public static void flushCache(String cls)
- {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- Map classLoaderCache = getClassLoaderCache(cl);
- classLoaderCache.remove(cls);
- }
-
- /**
- * Evicts ClassInfo for a specific class.
- * @param cls the class to remove the ClassInfo for
- */
- public static void flushCache(Class cls)
- {
- Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
- classLoaderCache.remove(cls.getName());
- }
-
- public static ClassInfo getClassInfo(Class cls)
- {
- Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
-
- WeakReference weak = (WeakReference)classLoaderCache.get(cls.getName());
- if(weak != null)
- {
- Object result = weak.get();
- if(result != null)
- {
- return (ClassInfo)result;
- }
- }
-
- ClassInfo clsInfo = new ClassInfo(cls);
- weak = new WeakReference(clsInfo);
- classLoaderCache.put(cls.getName(), weak);
- return clsInfo;
- }
-
- public static ClassInfo getClassInfo(String name, boolean required)
- {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- Map classLoaderCache = getClassLoaderCache(cl);
-
- WeakReference weak = (WeakReference)classLoaderCache.get(name);
- if(weak != null)
- {
- Object result = weak.get();
- if(result != null)
- {
- return (ClassInfo)result;
- }
- }
-
- try
- {
- ClassInfo clsInfo = new ClassInfo(cl.loadClass(name));
- weak = new WeakReference(clsInfo);
- classLoaderCache.put(name, weak);
- return clsInfo;
- }
- catch(ClassNotFoundException e)
- {
- if(required)
- {
- throw new JBossXBRuntimeException("Failed to load class " + name);
- }
- }
-
- return null;
- }
-
- private static Map getClassLoaderCache(ClassLoader cl)
- {
- synchronized(classloaderCache)
- {
- Map result = (Map) classloaderCache.get(cl);
- if (result == null)
- {
- result = new ConcurrentHashMap();
- classloaderCache.put(cl, result);
- }
- return result;
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java (from rev 2482, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/introspection/ClassInfos.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,175 @@
+/*
+ * 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.xb.binding.introspection;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.util.NoopMap;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: $</tt>
+ */
+public class ClassInfos
+{
+ private static Map classloaderCache = new WeakHashMap();
+
+ /**
+ * Disables caching of ClassInfo's. Already cached ClassInfo's will be lost after
+ * the method returns.
+ */
+ public static void disableCache()
+ {
+ synchronized(classloaderCache)
+ {
+ classloaderCache = NoopMap.INSTANCE;
+ }
+ }
+
+ /**
+ * Enables caching of ClassInfo's unless caching is already enabled.
+ */
+ public static void enableCache()
+ {
+ synchronized(classloaderCache)
+ {
+ if(!isCacheEnabled())
+ {
+ classloaderCache = new WeakHashMap();
+ }
+ }
+ }
+
+ /**
+ * @return true if caching is enabled, false otherwise.
+ */
+ public static boolean isCacheEnabled()
+ {
+ synchronized(classloaderCache)
+ {
+ return classloaderCache != NoopMap.INSTANCE;
+ }
+ }
+
+ /**
+ * Flushes all the cached ClassInfo's.
+ */
+ public static void flushCache()
+ {
+ synchronized(classloaderCache)
+ {
+ classloaderCache.clear();
+ }
+ }
+
+ /**
+ * Evicts ClassInfo for a specific class.
+ * @param cls fully qualified class name of the class
+ */
+ public static void flushCache(String cls)
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ Map classLoaderCache = getClassLoaderCache(cl);
+ classLoaderCache.remove(cls);
+ }
+
+ /**
+ * Evicts ClassInfo for a specific class.
+ * @param cls the class to remove the ClassInfo for
+ */
+ public static void flushCache(Class cls)
+ {
+ Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
+ classLoaderCache.remove(cls.getName());
+ }
+
+ public static ClassInfo getClassInfo(Class cls)
+ {
+ Map classLoaderCache = getClassLoaderCache(cls.getClassLoader());
+
+ WeakReference weak = (WeakReference)classLoaderCache.get(cls.getName());
+ if(weak != null)
+ {
+ Object result = weak.get();
+ if(result != null)
+ {
+ return (ClassInfo)result;
+ }
+ }
+
+ ClassInfo clsInfo = new ClassInfo(cls);
+ weak = new WeakReference(clsInfo);
+ classLoaderCache.put(cls.getName(), weak);
+ return clsInfo;
+ }
+
+ public static ClassInfo getClassInfo(String name, boolean required)
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ Map classLoaderCache = getClassLoaderCache(cl);
+
+ WeakReference weak = (WeakReference)classLoaderCache.get(name);
+ if(weak != null)
+ {
+ Object result = weak.get();
+ if(result != null)
+ {
+ return (ClassInfo)result;
+ }
+ }
+
+ try
+ {
+ ClassInfo clsInfo = new ClassInfo(cl.loadClass(name));
+ weak = new WeakReference(clsInfo);
+ classLoaderCache.put(name, weak);
+ return clsInfo;
+ }
+ catch(ClassNotFoundException e)
+ {
+ if(required)
+ {
+ throw new JBossXBRuntimeException("Failed to load class " + name);
+ }
+ }
+
+ return null;
+ }
+
+ private static Map getClassLoaderCache(ClassLoader cl)
+ {
+ synchronized(classloaderCache)
+ {
+ Map result = (Map) classloaderCache.get(cl);
+ if (result == null)
+ {
+ result = new ConcurrentHashMap();
+ classloaderCache.put(cl, result);
+ }
+ return result;
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,384 +0,0 @@
-/*
- * 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.xb.binding.parser.sax;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.lang.reflect.Method;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import org.jboss.logging.Logger;
-import org.jboss.util.JBossStringBuilder;
-import org.jboss.util.xml.JBossEntityResolver;
-import org.jboss.xb.binding.JBossXBException;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.xml.sax.Attributes;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SaxJBossXBParser
- implements JBossXBParser
-{
- private static final Logger log = Logger.getLogger(SaxJBossXBParser.class);
-
- private static final SAXParserFactory saxFactory = SAXParserFactory.newInstance();
- static
- {
- saxFactory.setValidating(true);
- saxFactory.setNamespaceAware(true);
- enableXInclude();
- }
-
- private final XMLReader reader;
- private JBossXBParser.ContentHandler contentHandler;
- private DelegatingContentHandler delegateHandler;
- private boolean trace;
-
- /**
- * Enables XInclude if the saxFactory supports it.<p>
- *
- * NOTE: Checks the real factory class, not the JAXP interface.
- */
- private static void enableXInclude()
- {
- try
- {
- Class clazz = saxFactory.getClass();
- Method method = clazz.getMethod("setXIncludeAware", new Class[] { Boolean.TYPE });
- method.invoke(saxFactory, new Object[] { Boolean.TRUE });
- }
- catch (Exception e)
- {
- log.trace("Not setting XIncludeAware", e);
- }
- }
-
- public SaxJBossXBParser()
- throws JBossXBException
- {
- SAXParser parser;
- try
- {
- parser = saxFactory.newSAXParser();
- }
- catch(Exception e)
- {
- throw new JBossXBException("Failed to create a new SAX parser", e);
- }
-
- try
- {
- reader = parser.getXMLReader();
- }
- catch(SAXException e1)
- {
- throw new JBossXBRuntimeException("Failed to get parser's XMLReader", e1);
- }
-
- delegateHandler = new DelegatingContentHandler();
- reader.setContentHandler(delegateHandler);
- reader.setErrorHandler(MetaDataErrorHandler.INSTANCE);
- reader.setEntityResolver(new JBossEntityResolver());
-
-/*
- setFeature(Unmarshaller.VALIDATION, true);
- setFeature(Unmarshaller.SCHEMA_VALIDATION, true);
- setFeature(Unmarshaller.SCHEMA_FULL_CHECKING, true);
- setFeature(Unmarshaller.DYNAMIC_VALIDATION, true);
- setFeature(Unmarshaller.NAMESPACES, true);
-*/
- }
-
- // JBossXBParser implementation
-
- public void setEntityResolver(EntityResolver entityResolver)
- throws JBossXBException
- {
- reader.setEntityResolver(entityResolver);
- }
-
- public void setProperty(String name, Object value)
- {
- try
- {
- reader.setProperty(name, value);
- }
- catch(SAXException e)
- {
- throw new JBossXBRuntimeException("Failed to set property on the XML reader", e);
- }
- }
-
- public void setFeature(String name, boolean value)
- {
- try
- {
- reader.setFeature(name, value);
- }
- catch(SAXException e)
- {
- throw new JBossXBRuntimeException("Failed to set feature on the XMLReader", e);
- }
- }
-
- public void parse(String systemId, ContentHandler handler) throws JBossXBException
- {
- this.contentHandler = handler;
- trace = log.isTraceEnabled();
- try
- {
- reader.parse(systemId);
- }
- catch(Exception e)
- {
- throw new JBossXBException("Failed to parse source: " + getLocationAsString(systemId), e);
- }
- }
-
- public void parse(InputStream is, ContentHandler handler) throws JBossXBException
- {
- this.contentHandler = handler;
- trace = log.isTraceEnabled();
- try
- {
- reader.parse(new InputSource(is));
- }
- catch(Exception e)
- {
- throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
- }
- }
-
- public void parse(Reader reader, ContentHandler handler) throws JBossXBException
- {
- this.contentHandler = handler;
- trace = log.isTraceEnabled();
- try
- {
- this.reader.parse(new InputSource(reader));
- }
- catch(Exception e)
- {
- throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
- }
- }
-
- public String getLocationAsString(String fileName)
- {
- Locator locator = delegateHandler.getDocumentLocator();
- if (locator == null)
- return fileName;
- else
- {
- JBossStringBuilder buffer = new JBossStringBuilder();
- String id = locator.getSystemId();
- if (id == null)
- id = locator.getPublicId();
- buffer.append(id).append('@');
- buffer.append(locator.getLineNumber());
- buffer.append(',');
- buffer.append(locator.getColumnNumber());
- return buffer.toString();
- }
- }
-
- // Inner
-
- private final class DelegatingContentHandler
- implements org.xml.sax.ContentHandler
- {
- Locator locator;
-
- public void endDocument()
- {
- }
-
- public void startDocument()
- {
- }
-
- public void characters(char ch[], int start, int length)
- {
- // todo look at this later
- // do not notify content handler if these are just whitespaces
- int i = start;
- while(i < start + length)
- {
- if(!Character.isWhitespace(ch[i++]))
- {
- contentHandler.characters(ch, start, length);
- break;
- }
- }
- }
-
- public void ignorableWhitespace(char ch[], int start, int length)
- {
- }
-
- public void endPrefixMapping(String prefix)
- {
- contentHandler.endPrefixMapping(prefix);
- }
-
- public void skippedEntity(String name)
- {
- }
-
- public Locator getDocumentLocator()
- {
- return locator;
- }
-
- public void setDocumentLocator(Locator locator)
- {
- this.locator = locator;
- }
-
- public void processingInstruction(String target, String data)
- {
- contentHandler.processingInstruction(target, data);
- }
-
- public void startPrefixMapping(String prefix, String uri)
- {
- contentHandler.startPrefixMapping(prefix, uri);
- }
-
- public void endElement(String namespaceURI, String localName, String qName)
- {
- String name = null;
- if(trace)
- {
- if(localName.length() == 0)
- {
- name = qName;
- }
- else
- {
- name = namespaceURI + ':' + localName;
- }
- log.trace("Enter endElement " + name);
- }
- try
- {
- contentHandler.endElement(namespaceURI, localName, qName);
- }
- finally
- {
- if(trace)
- {
- log.trace("Exit endElement " + name);
- }
- }
- }
-
- public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
- {
- String name = null;
- if(trace)
- {
- if(localName.length() == 0)
- {
- name = qName;
- }
- else
- {
- name = namespaceURI + ':' + localName;
- }
- log.trace("Enter startElement " + name);
- }
- try
- {
- contentHandler.startElement(namespaceURI, localName, qName, atts, null);
- }
- finally
- {
- if(trace)
- {
- log.trace("Exit startElement " + name);
- }
- }
- }
- }
-
- private static final class MetaDataErrorHandler
- implements ErrorHandler
- {
- public static final ErrorHandler INSTANCE = new MetaDataErrorHandler();
-
- public void warning(SAXParseException exception)
- {
- log.warn(formatMessage(exception));
- }
-
- public void error(SAXParseException exception)
- throws SAXException
- {
- throw new SAXException(formatMessage(exception));
- }
-
- public void fatalError(SAXParseException exception)
- throws SAXException
- {
- throw new SAXException(formatMessage(exception));
- }
-
- public 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();
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/parser/sax/SaxJBossXBParser.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,385 @@
+/*
+ * 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.xb.binding.parser.sax;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Method;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import org.jboss.logging.Logger;
+import org.jboss.util.JBossStringBuilder;
+import org.jboss.util.xml.JBossEntityResolver;
+import org.jboss.xb.binding.JBossXBException;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SaxJBossXBParser
+ implements JBossXBParser
+{
+ private static final Logger log = Logger.getLogger(SaxJBossXBParser.class);
+
+ private static final SAXParserFactory saxFactory = SAXParserFactory.newInstance();
+ static
+ {
+ saxFactory.setValidating(true);
+ saxFactory.setNamespaceAware(true);
+ enableXInclude();
+ }
+
+ private final XMLReader reader;
+ private JBossXBParser.ContentHandler contentHandler;
+ private DelegatingContentHandler delegateHandler;
+ private boolean trace;
+
+ /**
+ * Enables XInclude if the saxFactory supports it.<p>
+ *
+ * NOTE: Checks the real factory class, not the JAXP interface.
+ */
+ private static void enableXInclude()
+ {
+ try
+ {
+ Class clazz = saxFactory.getClass();
+ Method method = clazz.getMethod("setXIncludeAware", new Class[] { Boolean.TYPE });
+ method.invoke(saxFactory, new Object[] { Boolean.TRUE });
+ }
+ catch (Exception e)
+ {
+ log.trace("Not setting XIncludeAware", e);
+ }
+ }
+
+ public SaxJBossXBParser()
+ throws JBossXBException
+ {
+ SAXParser parser;
+ try
+ {
+ parser = saxFactory.newSAXParser();
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBException("Failed to create a new SAX parser", e);
+ }
+
+ try
+ {
+ reader = parser.getXMLReader();
+ }
+ catch(SAXException e1)
+ {
+ throw new JBossXBRuntimeException("Failed to get parser's XMLReader", e1);
+ }
+
+ delegateHandler = new DelegatingContentHandler();
+ reader.setContentHandler(delegateHandler);
+ reader.setErrorHandler(MetaDataErrorHandler.INSTANCE);
+ reader.setEntityResolver(new JBossEntityResolver());
+
+/*
+ setFeature(Unmarshaller.VALIDATION, true);
+ setFeature(Unmarshaller.SCHEMA_VALIDATION, true);
+ setFeature(Unmarshaller.SCHEMA_FULL_CHECKING, true);
+ setFeature(Unmarshaller.DYNAMIC_VALIDATION, true);
+ setFeature(Unmarshaller.NAMESPACES, true);
+*/
+ }
+
+ // JBossXBParser implementation
+
+ public void setEntityResolver(EntityResolver entityResolver)
+ throws JBossXBException
+ {
+ reader.setEntityResolver(entityResolver);
+ }
+
+ public void setProperty(String name, Object value)
+ {
+ try
+ {
+ reader.setProperty(name, value);
+ }
+ catch(SAXException e)
+ {
+ throw new JBossXBRuntimeException("Failed to set property on the XML reader", e);
+ }
+ }
+
+ public void setFeature(String name, boolean value)
+ {
+ try
+ {
+ reader.setFeature(name, value);
+ }
+ catch(SAXException e)
+ {
+ throw new JBossXBRuntimeException("Failed to set feature on the XMLReader", e);
+ }
+ }
+
+ public void parse(String systemId, ContentHandler handler) throws JBossXBException
+ {
+ this.contentHandler = handler;
+ trace = log.isTraceEnabled();
+ try
+ {
+ reader.parse(systemId);
+ }
+ catch(Exception e)
+ {
+e.printStackTrace();
+ throw new JBossXBException("Failed to parse source: " + getLocationAsString(systemId), e);
+ }
+ }
+
+ public void parse(InputStream is, ContentHandler handler) throws JBossXBException
+ {
+ this.contentHandler = handler;
+ trace = log.isTraceEnabled();
+ try
+ {
+ reader.parse(new InputSource(is));
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
+ }
+ }
+
+ public void parse(Reader reader, ContentHandler handler) throws JBossXBException
+ {
+ this.contentHandler = handler;
+ trace = log.isTraceEnabled();
+ try
+ {
+ this.reader.parse(new InputSource(reader));
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBException("Failed to parse source: " + e.getMessage(), e);
+ }
+ }
+
+ public String getLocationAsString(String fileName)
+ {
+ Locator locator = delegateHandler.getDocumentLocator();
+ if (locator == null)
+ return fileName;
+ else
+ {
+ JBossStringBuilder buffer = new JBossStringBuilder();
+ String id = locator.getSystemId();
+ if (id == null)
+ id = locator.getPublicId();
+ buffer.append(id).append('@');
+ buffer.append(locator.getLineNumber());
+ buffer.append(',');
+ buffer.append(locator.getColumnNumber());
+ return buffer.toString();
+ }
+ }
+
+ // Inner
+
+ private final class DelegatingContentHandler
+ implements org.xml.sax.ContentHandler
+ {
+ Locator locator;
+
+ public void endDocument()
+ {
+ }
+
+ public void startDocument()
+ {
+ }
+
+ public void characters(char ch[], int start, int length)
+ {
+ // todo look at this later
+ // do not notify content handler if these are just whitespaces
+ //int i = start;
+ //while(i < start + length)
+ //{
+ // if(!Character.isWhitespace(ch[i++]))
+ // {
+ contentHandler.characters(ch, start, length);
+ // break;
+ // }
+ //}
+ }
+
+ public void ignorableWhitespace(char ch[], int start, int length)
+ {
+ }
+
+ public void endPrefixMapping(String prefix)
+ {
+ contentHandler.endPrefixMapping(prefix);
+ }
+
+ public void skippedEntity(String name)
+ {
+ }
+
+ public Locator getDocumentLocator()
+ {
+ return locator;
+ }
+
+ public void setDocumentLocator(Locator locator)
+ {
+ this.locator = locator;
+ }
+
+ public void processingInstruction(String target, String data)
+ {
+ contentHandler.processingInstruction(target, data);
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ {
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName)
+ {
+ String name = null;
+ if(trace)
+ {
+ if(localName.length() == 0)
+ {
+ name = qName;
+ }
+ else
+ {
+ name = namespaceURI + ':' + localName;
+ }
+ log.trace("Enter endElement " + name);
+ }
+ try
+ {
+ contentHandler.endElement(namespaceURI, localName, qName);
+ }
+ finally
+ {
+ if(trace)
+ {
+ log.trace("Exit endElement " + name);
+ }
+ }
+ }
+
+ public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+ {
+ String name = null;
+ if(trace)
+ {
+ if(localName.length() == 0)
+ {
+ name = qName;
+ }
+ else
+ {
+ name = namespaceURI + ':' + localName;
+ }
+ log.trace("Enter startElement " + name);
+ }
+ try
+ {
+ contentHandler.startElement(namespaceURI, localName, qName, atts, null);
+ }
+ finally
+ {
+ if(trace)
+ {
+ log.trace("Exit startElement " + name);
+ }
+ }
+ }
+ }
+
+ private static final class MetaDataErrorHandler
+ implements ErrorHandler
+ {
+ public static final ErrorHandler INSTANCE = new MetaDataErrorHandler();
+
+ public void warning(SAXParseException exception)
+ {
+ log.warn(formatMessage(exception));
+ }
+
+ public void error(SAXParseException exception)
+ throws SAXException
+ {
+ throw new SAXException(formatMessage(exception));
+ }
+
+ public void fatalError(SAXParseException exception)
+ throws SAXException
+ {
+ throw new SAXException(formatMessage(exception));
+ }
+
+ public 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();
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,437 +0,0 @@
-/*
- * 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.xb.binding.sunday.unmarshalling;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.xml.namespace.QName;
-
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
-import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.util.DomCharactersHandler;
-import org.jboss.xb.util.DomLocalMarshaller;
-import org.jboss.xb.util.DomParticleHandler;
-
-
-/**
- * A SchemaBinding is a collection of binding objects (TypeBinding,
- * ChoiceBinding, ElementBinding, ModelGroupBinding, SequenceBinding, WildcardBinding)
- * for a single namespace keyed by the QNames of the schema components.
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SchemaBinding
-{
- private static final ValueAdapter DATE_ADAPTER = new ValueAdapter()
- {
- public Object cast(Object o, Class c)
- {
- if (o != null && java.util.Date.class.isAssignableFrom(c))
- {
- o = ((java.util.Calendar) o).getTime();
- }
- return o;
- }
- };
-
- /** The namespaces Set<String> */
- private Set namespaces = Collections.EMPTY_SET;
- /** Map<QName, TypeBinding> for simple/complex types */
- private Map types = new HashMap();
- /** Map<QName, ParticleBinding> for */
- private Map elements = new HashMap();
- /** The default package information */
- private PackageMetaData packageMetaData;
- /** Schema resolver to use for foreign namespaces */
- private SchemaBindingResolver schemaResolver;
- /** Must all content have a valid binding */
- private boolean strictSchema = true;
- /** Should child elements be ignored if they don't map to a parent field */
- private boolean ignoreUnresolvedFieldOrClass = true;
- /** Should '_' be considered as a word separator or part of Java identifier */
- private boolean ignoreLowLine = true;
- /** Should ${x} references be replaced with x system property */
- private boolean replacePropertyRefs = true;
- /** Should list xml types be unmarshalled as arrays */
- private boolean unmarshalListsToArrays;
- /** Should the default no-arg ctor be used to create the java instance */
- private boolean useNoArgCtorIfFound;
- /** The default property name to use for simple content bindings */
- private String simpleContentProperty = "value";
-
- /** default XOP unmarshaller */
- private XOPUnmarshaller xopUnmarshaller;
- /** default XOP marshaller */
- private XOPMarshaller xopMarshaller;
-
- public SchemaBinding()
- {
- addType(new SimpleTypeBinding(Constants.QNAME_ANYSIMPLETYPE));
- addType(new SimpleTypeBinding(Constants.QNAME_STRING));
- addType(new SimpleTypeBinding(Constants.QNAME_BOOLEAN));
- addType(new SimpleTypeBinding(Constants.QNAME_DECIMAL));
- addType(new SimpleTypeBinding(Constants.QNAME_FLOAT));
- addType(new SimpleTypeBinding(Constants.QNAME_DOUBLE));
- addType(new SimpleTypeBinding(Constants.QNAME_DURATION));
- addType(new SimpleTypeBinding(Constants.QNAME_DATETIME, DATE_ADAPTER));
- addType(new SimpleTypeBinding(Constants.QNAME_TIME, DATE_ADAPTER));
- addType(new SimpleTypeBinding(Constants.QNAME_DATE, DATE_ADAPTER));
- addType(new SimpleTypeBinding(Constants.QNAME_GYEARMONTH));
- addType(new SimpleTypeBinding(Constants.QNAME_GYEAR));
- addType(new SimpleTypeBinding(Constants.QNAME_GMONTHDAY));
- addType(new SimpleTypeBinding(Constants.QNAME_GDAY));
- addType(new SimpleTypeBinding(Constants.QNAME_GMONTH));
- addType(new SimpleTypeBinding(Constants.QNAME_HEXBINARY));
- addType(new SimpleTypeBinding(Constants.QNAME_BASE64BINARY));
- addType(new SimpleTypeBinding(Constants.QNAME_ANYURI));
- addType(new SimpleTypeBinding(Constants.QNAME_QNAME));
- addType(new SimpleTypeBinding(Constants.QNAME_NOTATION));
- addType(new SimpleTypeBinding(Constants.QNAME_NORMALIZEDSTRING));
- addType(new SimpleTypeBinding(Constants.QNAME_TOKEN));
- addType(new SimpleTypeBinding(Constants.QNAME_LANGUAGE));
- addType(new SimpleTypeBinding(Constants.QNAME_NMTOKEN));
- addType(new SimpleTypeBinding(Constants.QNAME_NMTOKENS));
- addType(new SimpleTypeBinding(Constants.QNAME_NAME));
- addType(new SimpleTypeBinding(Constants.QNAME_NCNAME));
- addType(new SimpleTypeBinding(Constants.QNAME_ID));
- addType(new SimpleTypeBinding(Constants.QNAME_IDREF));
- addType(new SimpleTypeBinding(Constants.QNAME_IDREFS));
- addType(new SimpleTypeBinding(Constants.QNAME_ENTITY));
- addType(new SimpleTypeBinding(Constants.QNAME_ENTITIES));
- addType(new SimpleTypeBinding(Constants.QNAME_INTEGER));
- addType(new SimpleTypeBinding(Constants.QNAME_NONPOSITIVEINTEGER));
- addType(new SimpleTypeBinding(Constants.QNAME_NEGATIVEINTEGER));
- addType(new SimpleTypeBinding(Constants.QNAME_LONG));
- addType(new SimpleTypeBinding(Constants.QNAME_INT));
- addType(new SimpleTypeBinding(Constants.QNAME_SHORT));
- addType(new SimpleTypeBinding(Constants.QNAME_BYTE));
- addType(new SimpleTypeBinding(Constants.QNAME_NONNEGATIVEINTEGER));
- addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDLONG));
- addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDINT));
- addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDSHORT));
- addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDBYTE));
- addType(new SimpleTypeBinding(Constants.QNAME_POSITIVEINTEGER));
- }
-
- /**
- * Get the namespaces.
- *
- * @return the namespaces.
- */
- public Set getNamespaces()
- {
- return namespaces;
- }
-
- /**
- * Set the namespaces.
- *
- * @param namespaces the namespaces.
- * @throws IllegalArgumentException for null spaces
- */
- public void setNamespaces(Set namespaces)
- {
- if (namespaces == null)
- throw new IllegalArgumentException("Null namespaces");
- this.namespaces = namespaces;
- }
-
- public TypeBinding getType(QName qName)
- {
- return (TypeBinding)types.get(qName);
- }
-
- public void addType(TypeBinding type)
- {
- QName qName = type.getQName();
- if(qName == null)
- {
- throw new JBossXBRuntimeException("Global type must have a name.");
- }
- types.put(qName, type);
- }
-
- public ElementBinding getElement(QName name)
- {
- ParticleBinding particle = (ParticleBinding)elements.get(name);
- ElementBinding element = (ElementBinding)(particle == null ? null : particle.getTerm());
- return element;
- }
-
- public ParticleBinding getElementParticle(QName name)
- {
- return (ParticleBinding)elements.get(name);
- }
-
- public void addElement(ElementBinding element)
- {
- ParticleBinding particle = new ParticleBinding(element);
- elements.put(element.getQName(), particle);
- }
-
- public ElementBinding addElement(QName name, TypeBinding type)
- {
- ElementBinding element = new ElementBinding(this, name, type);
- addElement(element);
- return element;
- }
-
- public Iterator getElements()
- {
- return new Iterator()
- {
- private Iterator particleIterator = elements.values().iterator();
-
- public boolean hasNext()
- {
- return particleIterator.hasNext();
- }
-
- public Object next()
- {
- ParticleBinding particle = (ParticleBinding)particleIterator.next();
- return particle.getTerm();
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException("remove is not implemented.");
- }
- };
- }
-
- public Iterator getElementParticles()
- {
- return elements.values().iterator();
- }
-
- public Iterator getTypes()
- {
- return Collections.unmodifiableCollection(types.values()).iterator();
- }
-
- public PackageMetaData getPackageMetaData()
- {
- return packageMetaData;
- }
-
- public void setPackageMetaData(PackageMetaData packageMetaData)
- {
- this.packageMetaData = packageMetaData;
- }
-
- public SchemaBindingResolver getSchemaResolver()
- {
- return schemaResolver;
- }
-
- public void setSchemaResolver(SchemaBindingResolver schemaResolver)
- {
- this.schemaResolver = schemaResolver;
- }
-
- public boolean isStrictSchema()
- {
- return strictSchema;
- }
-
- /**
- * If strict-schema is true then all the elements and attributes in XML content being parsed must be bound
- * in this instance of SchemaBinding (except attributes from xmlns and xsi namespaces),
- * otherwise a runtime exception is thrown. The default value for this property is true.
- */
- public void setStrictSchema(boolean strictSchema)
- {
- this.strictSchema = strictSchema;
- }
-
- public boolean isIgnoreUnresolvedFieldOrClass()
- {
- return ignoreUnresolvedFieldOrClass;
- }
-
- /**
- * If a field is not found in the parent class to set child value on or
- * a class an element is bound to
- * an exception will be thrown if this property is false. Otherwise,
- * the process will just go on (the default for now).
- */
- public void setIgnoreUnresolvedFieldOrClass(boolean ignoreUnresolvedFieldOrClass)
- {
- this.ignoreUnresolvedFieldOrClass = ignoreUnresolvedFieldOrClass;
- }
-
- public boolean isReplacePropertyRefs()
- {
- return replacePropertyRefs;
- }
- /**
- *
- * @param flag
- */
- public void setReplacePropertyRefs(boolean flag)
- {
- this.replacePropertyRefs = flag;
- }
-
- public boolean isIgnoreLowLine()
- {
- return ignoreLowLine;
- }
-
- /**
- * Where '_' should be considered as a word separator or a part of the Java identifier
- * when mapping XML names to Java identifiers.
- */
- public void setIgnoreLowLine(boolean ignoreLowLine)
- {
- this.ignoreLowLine = ignoreLowLine;
- }
-
- public boolean isUnmarshalListsToArrays()
- {
- return unmarshalListsToArrays;
- }
-
- /**
- * Should list xml types be unmarshalled as arrays
- * @param unmarshalListsToArrays
- */
- public void setUnmarshalListsToArrays(boolean unmarshalListsToArrays)
- {
- this.unmarshalListsToArrays = unmarshalListsToArrays;
- }
-
- public boolean isUseNoArgCtorIfFound()
- {
- return useNoArgCtorIfFound;
- }
-
- /**
- * Should the default no-arg ctor be used to create the java instance
- * @param useNoArgCtorIfFound
- */
- public void setUseNoArgCtorIfFound(boolean useNoArgCtorIfFound)
- {
- this.useNoArgCtorIfFound = useNoArgCtorIfFound;
- }
-
- public String getSimpleContentProperty()
- {
- return simpleContentProperty;
- }
-
- /**
- * Set the default property name to use for simple content bindings
- * @param simpleContentProperty
- */
- public void setSimpleContentProperty(String simpleContentProperty)
- {
- this.simpleContentProperty = simpleContentProperty;
- }
-
- /**
- * @return schema default XOP unmarshaller
- */
- public XOPUnmarshaller getXopUnmarshaller()
- {
- return xopUnmarshaller;
- }
-
- /**
- * @param xopUnmarshaller schema default XOP unmarshaller
- */
- public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
- {
- this.xopUnmarshaller = xopUnmarshaller;
- }
-
- /**
- * @return schema default XOP marshaller
- */
- public XOPMarshaller getXopMarshaller()
- {
- return xopMarshaller;
- }
-
- /**
- * @param xopMarshaller schema default XOP marshaller
- */
- public void setXopMarshaller(XOPMarshaller xopMarshaller)
- {
- this.xopMarshaller = xopMarshaller;
- }
-
- public void setUnresolvedContentBoundToDOM(boolean toDom)
- {
- TypeBinding type = getType(Constants.QNAME_ANYTYPE);
- if(type == null)
- {
- // ignore, there is no use of the anyType in the schema
- return;
- //throw new JBossXBRuntimeException("anyType is not bound.");
- }
-
- WildcardBinding wildcard = type.getWildcard();
- if(toDom)
- {
- wildcard.setUnresolvedCharactersHandler(DomCharactersHandler.INSTANCE);
- wildcard.setUnresolvedElementHandler(DomParticleHandler.INSTANCE);
- wildcard.setUnresolvedMarshaller(DomLocalMarshaller.INSTANCE);
- }
- else
- {
- wildcard.setUnresolvedCharactersHandler(null);
- wildcard.setUnresolvedElementHandler(null);
- wildcard.setUnresolvedMarshaller(null);
- }
- }
-
- public boolean isUnresolvedContentBoundToDOM()
- {
- TypeBinding type = getType(Constants.QNAME_ANYTYPE);
- if(type == null)
- {
- // there is no use of the anyType in the schema
- return false;
- //throw new JBossXBRuntimeException("anyType is not bound.");
- }
-
- WildcardBinding wildcard = type.getWildcard();
- return wildcard.getUnresolvedCharactersHandler() instanceof DomCharactersHandler
- && wildcard.getUnresolvedElementHandler() instanceof DomParticleHandler
- && wildcard.getUnresolvedMarshaller() instanceof DomLocalMarshaller;
- }
-
- void addElementParticle(ParticleBinding particle)
- {
- ElementBinding element = (ElementBinding)particle.getTerm();
- elements.put(element.getQName(), particle);
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SchemaBinding.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,452 @@
+/*
+ * 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.xb.binding.sunday.unmarshalling;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
+import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.util.DomCharactersHandler;
+import org.jboss.xb.util.DomLocalMarshaller;
+import org.jboss.xb.util.DomParticleHandler;
+
+
+/**
+ * A SchemaBinding is a collection of binding objects (TypeBinding,
+ * ChoiceBinding, ElementBinding, ModelGroupBinding, SequenceBinding, WildcardBinding)
+ * for a single namespace keyed by the QNames of the schema components.
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SchemaBinding
+{
+ private static final ValueAdapter DATE_ADAPTER = new ValueAdapter()
+ {
+ public Object cast(Object o, Class c)
+ {
+ if (o != null && java.util.Date.class.isAssignableFrom(c))
+ {
+ o = ((java.util.Calendar) o).getTime();
+ }
+ return o;
+ }
+ };
+
+ /** The namespaces Set<String> */
+ private Set namespaces = Collections.EMPTY_SET;
+ /** Map<QName, TypeBinding> for simple/complex types */
+ private Map types = new HashMap();
+ /** Map<QName, ParticleBinding> for */
+ private Map elements = new HashMap();
+ /** The default package information */
+ private PackageMetaData packageMetaData;
+ /** Schema resolver to use for foreign namespaces */
+ private SchemaBindingResolver schemaResolver;
+ /** Must all content have a valid binding */
+ private boolean strictSchema = true;
+ /** Should child elements be ignored if they don't map to a parent field */
+ private boolean ignoreUnresolvedFieldOrClass = true;
+ /** Should '_' be considered as a word separator or part of Java identifier */
+ private boolean ignoreLowLine = true;
+ /** Should ${x} references be replaced with x system property */
+ private boolean replacePropertyRefs = true;
+ /** Should list xml types be unmarshalled as arrays */
+ private boolean unmarshalListsToArrays;
+ /** Should the default no-arg ctor be used to create the java instance */
+ private boolean useNoArgCtorIfFound;
+ /** The default property name to use for simple content bindings */
+ private String simpleContentProperty = "value";
+
+ /** if all the characters in the mixed content are whitespaces
+ * should they be considered indentation and ignored?
+ * the default is true for the backwards compatibility */
+ private boolean ignoreWhitespacesInMixedContent = true;
+
+ /** default XOP unmarshaller */
+ private XOPUnmarshaller xopUnmarshaller;
+ /** default XOP marshaller */
+ private XOPMarshaller xopMarshaller;
+
+ public SchemaBinding()
+ {
+ addType(new SimpleTypeBinding(Constants.QNAME_ANYSIMPLETYPE));
+ addType(new SimpleTypeBinding(Constants.QNAME_STRING));
+ addType(new SimpleTypeBinding(Constants.QNAME_BOOLEAN));
+ addType(new SimpleTypeBinding(Constants.QNAME_DECIMAL));
+ addType(new SimpleTypeBinding(Constants.QNAME_FLOAT));
+ addType(new SimpleTypeBinding(Constants.QNAME_DOUBLE));
+ addType(new SimpleTypeBinding(Constants.QNAME_DURATION));
+ addType(new SimpleTypeBinding(Constants.QNAME_DATETIME, DATE_ADAPTER));
+ addType(new SimpleTypeBinding(Constants.QNAME_TIME, DATE_ADAPTER));
+ addType(new SimpleTypeBinding(Constants.QNAME_DATE, DATE_ADAPTER));
+ addType(new SimpleTypeBinding(Constants.QNAME_GYEARMONTH));
+ addType(new SimpleTypeBinding(Constants.QNAME_GYEAR));
+ addType(new SimpleTypeBinding(Constants.QNAME_GMONTHDAY));
+ addType(new SimpleTypeBinding(Constants.QNAME_GDAY));
+ addType(new SimpleTypeBinding(Constants.QNAME_GMONTH));
+ addType(new SimpleTypeBinding(Constants.QNAME_HEXBINARY));
+ addType(new SimpleTypeBinding(Constants.QNAME_BASE64BINARY));
+ addType(new SimpleTypeBinding(Constants.QNAME_ANYURI));
+ addType(new SimpleTypeBinding(Constants.QNAME_QNAME));
+ addType(new SimpleTypeBinding(Constants.QNAME_NOTATION));
+ addType(new SimpleTypeBinding(Constants.QNAME_NORMALIZEDSTRING));
+ addType(new SimpleTypeBinding(Constants.QNAME_TOKEN));
+ addType(new SimpleTypeBinding(Constants.QNAME_LANGUAGE));
+ addType(new SimpleTypeBinding(Constants.QNAME_NMTOKEN));
+ addType(new SimpleTypeBinding(Constants.QNAME_NMTOKENS));
+ addType(new SimpleTypeBinding(Constants.QNAME_NAME));
+ addType(new SimpleTypeBinding(Constants.QNAME_NCNAME));
+ addType(new SimpleTypeBinding(Constants.QNAME_ID));
+ addType(new SimpleTypeBinding(Constants.QNAME_IDREF));
+ addType(new SimpleTypeBinding(Constants.QNAME_IDREFS));
+ addType(new SimpleTypeBinding(Constants.QNAME_ENTITY));
+ addType(new SimpleTypeBinding(Constants.QNAME_ENTITIES));
+ addType(new SimpleTypeBinding(Constants.QNAME_INTEGER));
+ addType(new SimpleTypeBinding(Constants.QNAME_NONPOSITIVEINTEGER));
+ addType(new SimpleTypeBinding(Constants.QNAME_NEGATIVEINTEGER));
+ addType(new SimpleTypeBinding(Constants.QNAME_LONG));
+ addType(new SimpleTypeBinding(Constants.QNAME_INT));
+ addType(new SimpleTypeBinding(Constants.QNAME_SHORT));
+ addType(new SimpleTypeBinding(Constants.QNAME_BYTE));
+ addType(new SimpleTypeBinding(Constants.QNAME_NONNEGATIVEINTEGER));
+ addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDLONG));
+ addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDINT));
+ addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDSHORT));
+ addType(new SimpleTypeBinding(Constants.QNAME_UNSIGNEDBYTE));
+ addType(new SimpleTypeBinding(Constants.QNAME_POSITIVEINTEGER));
+ }
+
+ /**
+ * Get the namespaces.
+ *
+ * @return the namespaces.
+ */
+ public Set getNamespaces()
+ {
+ return namespaces;
+ }
+
+ /**
+ * Set the namespaces.
+ *
+ * @param namespaces the namespaces.
+ * @throws IllegalArgumentException for null spaces
+ */
+ public void setNamespaces(Set namespaces)
+ {
+ if (namespaces == null)
+ throw new IllegalArgumentException("Null namespaces");
+ this.namespaces = namespaces;
+ }
+
+ public TypeBinding getType(QName qName)
+ {
+ return (TypeBinding)types.get(qName);
+ }
+
+ public void addType(TypeBinding type)
+ {
+ QName qName = type.getQName();
+ if(qName == null)
+ {
+ throw new JBossXBRuntimeException("Global type must have a name.");
+ }
+ types.put(qName, type);
+ }
+
+ public ElementBinding getElement(QName name)
+ {
+ ParticleBinding particle = (ParticleBinding)elements.get(name);
+ ElementBinding element = (ElementBinding)(particle == null ? null : particle.getTerm());
+ return element;
+ }
+
+ public ParticleBinding getElementParticle(QName name)
+ {
+ return (ParticleBinding)elements.get(name);
+ }
+
+ public void addElement(ElementBinding element)
+ {
+ ParticleBinding particle = new ParticleBinding(element);
+ elements.put(element.getQName(), particle);
+ }
+
+ public ElementBinding addElement(QName name, TypeBinding type)
+ {
+ ElementBinding element = new ElementBinding(this, name, type);
+ addElement(element);
+ return element;
+ }
+
+ public Iterator getElements()
+ {
+ return new Iterator()
+ {
+ private Iterator particleIterator = elements.values().iterator();
+
+ public boolean hasNext()
+ {
+ return particleIterator.hasNext();
+ }
+
+ public Object next()
+ {
+ ParticleBinding particle = (ParticleBinding)particleIterator.next();
+ return particle.getTerm();
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("remove is not implemented.");
+ }
+ };
+ }
+
+ public Iterator getElementParticles()
+ {
+ return elements.values().iterator();
+ }
+
+ public Iterator getTypes()
+ {
+ return Collections.unmodifiableCollection(types.values()).iterator();
+ }
+
+ public PackageMetaData getPackageMetaData()
+ {
+ return packageMetaData;
+ }
+
+ public void setPackageMetaData(PackageMetaData packageMetaData)
+ {
+ this.packageMetaData = packageMetaData;
+ }
+
+ public SchemaBindingResolver getSchemaResolver()
+ {
+ return schemaResolver;
+ }
+
+ public void setSchemaResolver(SchemaBindingResolver schemaResolver)
+ {
+ this.schemaResolver = schemaResolver;
+ }
+
+ public boolean isStrictSchema()
+ {
+ return strictSchema;
+ }
+
+ /**
+ * If strict-schema is true then all the elements and attributes in XML content being parsed must be bound
+ * in this instance of SchemaBinding (except attributes from xmlns and xsi namespaces),
+ * otherwise a runtime exception is thrown. The default value for this property is true.
+ */
+ public void setStrictSchema(boolean strictSchema)
+ {
+ this.strictSchema = strictSchema;
+ }
+
+ public boolean isIgnoreUnresolvedFieldOrClass()
+ {
+ return ignoreUnresolvedFieldOrClass;
+ }
+
+ /**
+ * If a field is not found in the parent class to set child value on or
+ * a class an element is bound to
+ * an exception will be thrown if this property is false. Otherwise,
+ * the process will just go on (the default for now).
+ */
+ public void setIgnoreUnresolvedFieldOrClass(boolean ignoreUnresolvedFieldOrClass)
+ {
+ this.ignoreUnresolvedFieldOrClass = ignoreUnresolvedFieldOrClass;
+ }
+
+ public boolean isReplacePropertyRefs()
+ {
+ return replacePropertyRefs;
+ }
+ /**
+ *
+ * @param flag
+ */
+ public void setReplacePropertyRefs(boolean flag)
+ {
+ this.replacePropertyRefs = flag;
+ }
+
+ public boolean isIgnoreLowLine()
+ {
+ return ignoreLowLine;
+ }
+
+ /**
+ * Where '_' should be considered as a word separator or a part of the Java identifier
+ * when mapping XML names to Java identifiers.
+ */
+ public void setIgnoreLowLine(boolean ignoreLowLine)
+ {
+ this.ignoreLowLine = ignoreLowLine;
+ }
+
+ public boolean isUnmarshalListsToArrays()
+ {
+ return unmarshalListsToArrays;
+ }
+
+ /**
+ * Should list xml types be unmarshalled as arrays
+ * @param unmarshalListsToArrays
+ */
+ public void setUnmarshalListsToArrays(boolean unmarshalListsToArrays)
+ {
+ this.unmarshalListsToArrays = unmarshalListsToArrays;
+ }
+
+ public boolean isUseNoArgCtorIfFound()
+ {
+ return useNoArgCtorIfFound;
+ }
+
+ /**
+ * Should the default no-arg ctor be used to create the java instance
+ * @param useNoArgCtorIfFound
+ */
+ public void setUseNoArgCtorIfFound(boolean useNoArgCtorIfFound)
+ {
+ this.useNoArgCtorIfFound = useNoArgCtorIfFound;
+ }
+
+ public String getSimpleContentProperty()
+ {
+ return simpleContentProperty;
+ }
+
+ /**
+ * Set the default property name to use for simple content bindings
+ * @param simpleContentProperty
+ */
+ public void setSimpleContentProperty(String simpleContentProperty)
+ {
+ this.simpleContentProperty = simpleContentProperty;
+ }
+
+ /**
+ * @return schema default XOP unmarshaller
+ */
+ public XOPUnmarshaller getXopUnmarshaller()
+ {
+ return xopUnmarshaller;
+ }
+
+ /**
+ * @param xopUnmarshaller schema default XOP unmarshaller
+ */
+ public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
+ {
+ this.xopUnmarshaller = xopUnmarshaller;
+ }
+
+ /**
+ * @return schema default XOP marshaller
+ */
+ public XOPMarshaller getXopMarshaller()
+ {
+ return xopMarshaller;
+ }
+
+ /**
+ * @param xopMarshaller schema default XOP marshaller
+ */
+ public void setXopMarshaller(XOPMarshaller xopMarshaller)
+ {
+ this.xopMarshaller = xopMarshaller;
+ }
+
+ public void setUnresolvedContentBoundToDOM(boolean toDom)
+ {
+ TypeBinding type = getType(Constants.QNAME_ANYTYPE);
+ if(type == null)
+ {
+ // ignore, there is no use of the anyType in the schema
+ return;
+ //throw new JBossXBRuntimeException("anyType is not bound.");
+ }
+
+ WildcardBinding wildcard = type.getWildcard();
+ if(toDom)
+ {
+ wildcard.setUnresolvedCharactersHandler(DomCharactersHandler.INSTANCE);
+ wildcard.setUnresolvedElementHandler(DomParticleHandler.INSTANCE);
+ wildcard.setUnresolvedMarshaller(DomLocalMarshaller.INSTANCE);
+ }
+ else
+ {
+ wildcard.setUnresolvedCharactersHandler(null);
+ wildcard.setUnresolvedElementHandler(null);
+ wildcard.setUnresolvedMarshaller(null);
+ }
+ }
+
+ public boolean isUnresolvedContentBoundToDOM()
+ {
+ TypeBinding type = getType(Constants.QNAME_ANYTYPE);
+ if(type == null)
+ {
+ // there is no use of the anyType in the schema
+ return false;
+ //throw new JBossXBRuntimeException("anyType is not bound.");
+ }
+
+ WildcardBinding wildcard = type.getWildcard();
+ return wildcard.getUnresolvedCharactersHandler() instanceof DomCharactersHandler
+ && wildcard.getUnresolvedElementHandler() instanceof DomParticleHandler
+ && wildcard.getUnresolvedMarshaller() instanceof DomLocalMarshaller;
+ }
+
+ public boolean isIgnoreWhitespacesInMixedContent()
+ {
+ return ignoreWhitespacesInMixedContent;
+ }
+
+ public void setIgnoreWhitespacesInMixedContent(boolean value)
+ {
+ this.ignoreWhitespacesInMixedContent = value;
+ }
+
+ void addElementParticle(ParticleBinding particle)
+ {
+ ElementBinding element = (ElementBinding)particle.getTerm();
+ elements.put(element.getQName(), particle);
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1291 +0,0 @@
-/*
- * 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.xb.binding.sunday.unmarshalling;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.ListIterator;
-import javax.xml.namespace.QName;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.jboss.logging.Logger;
-import org.jboss.util.StringPropertyReplacer;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.GenericValueContainer;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.NamespaceRegistry;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.group.ValueList;
-import org.jboss.xb.binding.group.ValueListHandler;
-import org.jboss.xb.binding.group.ValueListInitializer;
-import org.jboss.xb.binding.introspection.FieldInfo;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.parser.JBossXBParser;
-import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
-import org.xml.sax.Attributes;
-
-/**
- * ContentHandler that is used as a sandbox for JBXB-76
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class SundayContentHandler
- implements JBossXBParser.ContentHandler
-{
- private final static Logger log = Logger.getLogger(SundayContentHandler.class);
-
- private final static Object NIL = new Object();
-
- private final SchemaBinding schema;
- private final SchemaBindingResolver schemaResolver;
-
- private final StackImpl stack = new StackImpl();
-
- private Object root;
- private NamespaceRegistry nsRegistry = new NamespaceRegistry();
-
- private ParticleHandler defParticleHandler = DefaultHandlers.ELEMENT_HANDLER;
-
- private UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
-
- private final boolean trace = log.isTraceEnabled();
-
- public SundayContentHandler(SchemaBinding schema)
- {
- this.schema = schema;
- this.schemaResolver = null;
- }
-
- public SundayContentHandler(SchemaBindingResolver schemaResolver)
- {
- this.schemaResolver = schemaResolver;
- this.schema = null;
- }
-
- public void characters(char[] ch, int start, int length)
- {
- StackItem stackItem = stack.peek();
- if(stackItem.cursor == null)
- {
- if(stackItem.textContent == null)
- {
- stackItem.textContent = new StringBuffer();
- }
- stackItem.textContent.append(ch, start, length);
- }
- }
-
- public void endElement(String namespaceURI, String localName, String qName)
- {
- ElementBinding elementBinding = null;
- QName endName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
- StackItem item;
- while(true)
- {
- item = stack.peek();
- if(item.cursor == null)
- {
- if(item.ended)
- {
- pop();
- if(item.particle.isRepeatable())
- {
- endRepeatableParticle(item.particle);
- }
- }
- else
- {
- elementBinding = (ElementBinding)item.particle.getTerm();
- item.ended = true;
- break;
- }
- }
- else
- {
- if(!item.ended) // could be ended if it's a choice
- {
- endParticle(item, endName, 1);
- }
-
- ParticleBinding currentParticle = item.cursor.getCurrentParticle();
- TermBinding term = currentParticle.getTerm();
- if(term.isWildcard() && currentParticle.isRepeatable())
- {
- endRepeatableParticle(currentParticle);
- }
-
- pop();
- if(item.particle.isRepeatable())
- {
- endRepeatableParticle(item.particle);
- }
- }
- }
-
- if(elementBinding == null)
- {
- throw new JBossXBRuntimeException("Failed to endElement " + qName + ": binding not found");
- }
-
- if(!elementBinding.getQName().equals(endName))
- {
- throw new JBossXBRuntimeException("Failed to end element " +
- new QName(namespaceURI, localName) +
- ": element on the stack is " + elementBinding.getQName()
- );
- }
-
- endElement();
- }
-
- public void startElement(String namespaceURI,
- String localName,
- String qName,
- Attributes atts,
- XSTypeDefinition xercesType)
- {
- QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
- ParticleBinding particle = null;
- ParticleHandler handler = null;
- boolean repeated = false;
- boolean repeatedParticle = false;
- StackItem item = null;
- ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
- SchemaBinding schemaBinding = schema;
-
- if(stack.isEmpty())
- {
- if(schemaBinding != null)
- {
- particle = schemaBinding.getElementParticle(startName);
- }
- else if(schemaResolver != null)
- {
- String schemaLocation = atts == null ? null : Util.getSchemaLocation(atts, namespaceURI);
- schemaBinding = schemaResolver.resolve(namespaceURI, null, schemaLocation);
- if(schemaBinding != null)
- {
- particle = schemaBinding.getElementParticle(startName);
- }
- else
- {
- throw new JBossXBRuntimeException("Failed to resolve schema nsURI=" + namespaceURI + " location=" + schemaLocation);
- }
- }
- else
- {
- throw new JBossXBRuntimeException("Neither schema binding nor schema binding resolver is available!");
- }
- }
- else
- {
- while(!stack.isEmpty())
- {
- item = stack.peek();
- if(item.cursor == null)
- {
- TermBinding term = item.particle.getTerm();
- ElementBinding element = (ElementBinding)term;
- if(item.ended)
- {
- if(element.getQName().equals(startName))
- {
- particle = item.particle;
- repeated = true;
- item.reset();
-
- if(!particle.isRepeatable())
- {
- endRepeatableParent(startName);
- }
- }
- else
- {
- pop();
- if(item.particle.isRepeatable())
- {
- endRepeatableParticle(item.particle);
- }
- continue;
- }
- }
- else
- {
- ParticleBinding typeParticle = element.getType().getParticle();
- ModelGroupBinding modelGroup = typeParticle == null ?
- null :
- (ModelGroupBinding)typeParticle.getTerm();
- if(modelGroup == null)
- {
- if(startName.equals(Constants.QNAME_XOP_INCLUDE))
- {
- TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
- if(anyUriType == null)
- {
- log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
- }
-
- TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
- xopIncludeType.setSchemaBinding(schema);
- xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
- xopIncludeType.setHandler(new XOPIncludeHandler(element.getType(), schema.getXopUnmarshaller()));
-
- ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
-
- particle = new ParticleBinding(xopInclude);
-
- ElementBinding parentElement = (ElementBinding) item.particle.getTerm();
- parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
-
- item.handler = DefaultHandlers.XOP_HANDLER;
- item.ignoreCharacters = true;
- item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
- break;
- }
-
- QName typeName = element.getType().getQName();
- throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
- " type of element " +
- element.getQName() +
- " should be complex and contain " + startName + " as a child element."
- );
- }
-
- cursor = modelGroup.newCursor(typeParticle);
- List newCursors = cursor.startElement(startName, atts);
- if(newCursors.isEmpty())
- {
- throw new JBossXBRuntimeException(startName +
- " not found as a child of " +
- ((ElementBinding)term).getQName()
- );
- }
- else
- {
- Object o = item.o;
- // push all except the last one
- for(int i = newCursors.size() - 1; i >= 0; --i)
- {
- cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
- ParticleBinding modelGroupParticle = cursor.getParticle();
- if(modelGroupParticle.isRepeatable())
- {
- startRepeatableParticle(startName, modelGroupParticle);
- }
-
- handler = getHandler(modelGroupParticle);
- o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
- push(cursor, o, handler);
- }
- particle = cursor.getCurrentParticle();
- }
- }
- break;
- }
- else
- {
- cursor = item.cursor;
- if(cursor == null)
- {
- throw new JBossXBRuntimeException("No cursor for " + startName);
- }
-
- // todo review
- if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
- {
- endParticle(item, startName, 1);
- if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
- {
- pop();
- }
- continue;
- }
-
- //int prevOccurence = cursor.getOccurence();
- ParticleBinding prevParticle = cursor.isPositioned() ? cursor.getCurrentParticle() : null;
- List newCursors = cursor.startElement(startName, atts);
- if(newCursors.isEmpty())
- {
- if(!item.ended) // this is for choices
- {
- endParticle(item, startName, 1);
- }
- pop();
- }
- else
- {
- if(item.ended) // for repeatable choices
- {
- if(!item.particle.isRepeatable())
- {
- throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
- }
- item.reset();
-
- handler = getHandler(item.particle);
- item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
- }
-
- ParticleBinding curParticle = cursor.getCurrentParticle();
- if(curParticle != prevParticle)
- {
- if(prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
- {
- endRepeatableParticle(prevParticle);
- }
-
- if(newCursors.size() > 1 && curParticle.isRepeatable())
- {
- startRepeatableParticle(startName, curParticle);
- }
- }
- else
- {
- repeatedParticle = true;
- }
-
- // push all except the last one
- Object o = item.o;
- for(int i = newCursors.size() - 2; i >= 0; --i)
- {
- cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
-
- ParticleBinding modelGroupParticle = cursor.getParticle();
- handler = getHandler(modelGroupParticle);
- o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
- push(cursor, o, handler);
- }
- cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
- particle = cursor.getCurrentParticle();
- break;
- }
- }
- }
- }
-
- Object o = null;
- if(particle != null)
- {
- Object parent = stack.isEmpty() ? null :
- (repeated ? stack.peek(1).o : stack.peek().o);
- if(particle.getTerm() instanceof WildcardBinding)
- {
- /*
- WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
- ElementBinding element = wildcard.getElement(startName, atts);
- */
- ElementBinding element = cursor.getElement();
- if(element == null)
- {
- throw new JBossXBRuntimeException("Failed to resolve element " +
- startName + " for wildcard."
- );
- }
-
- if(!repeatedParticle && particle.isRepeatable())
- {
- startRepeatableParticle(startName, particle);
- }
- particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
- }
-
- ElementBinding element = (ElementBinding)particle.getTerm();
-
- // todo xsi:type support should be implemented in a better way
- String xsiType = atts.getValue("xsi:type");
- if(xsiType != null)
- {
- if(trace)
- {
- log.trace(element.getQName() + " uses xsi:type " + xsiType);
- }
-
- String xsiTypePrefix;
- String xsiTypeLocal;
- int colon = xsiType.indexOf(':');
- if(colon == -1)
- {
- xsiTypePrefix = "";
- xsiTypeLocal = xsiType;
- }
- else
- {
- xsiTypePrefix = xsiType.substring(0, colon);
- xsiTypeLocal = xsiType.substring(colon + 1);
- }
-
- String xsiTypeNs = nsRegistry.getNamespaceURI(xsiTypePrefix);
- QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
-
- TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
- if(xsiTypeBinding == null)
- {
- throw new JBossXBRuntimeException("Type binding not found for type " +
- xsiTypeQName +
- " specified with xsi:type for element " + startName
- );
- }
-
- element = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
- particle =
- new ParticleBinding(element,
- particle.getMinOccurs(),
- particle.getMaxOccurs(),
- particle.getMaxOccursUnbounded()
- );
- }
-
- if(!repeated && particle.isRepeatable())
- {
- startRepeatableParticle(startName, particle);
- }
-
- TypeBinding type = element.getType();
- if(type == null)
- {
- throw new JBossXBRuntimeException("No type for element " + element);
- }
-
- handler = type.getHandler();
- if(handler == null)
- {
- handler = defParticleHandler;
- }
-
- List interceptors = element.getInterceptors();
- if(!interceptors.isEmpty())
- {
- if (repeated)
- {
- pop();
- }
-
- for (int i = 0; i < interceptors.size(); ++i)
- {
- ElementInterceptor interceptor = (ElementInterceptor) interceptors.get(i);
- parent = interceptor.startElement(parent, startName, type);
- push(startName, particle, parent, handler);
- interceptor.attributes(parent, startName, type, atts, nsRegistry);
- }
-
- if (repeated)
- {
- // to have correct endRepeatableParticle calls
- stack.push(item);
- }
- }
-
- String nil = atts.getValue("xsi:nil");
- if(nil == null || !("1".equals(nil) || "true".equals(nil)))
- {
- o = handler.startParticle(parent, startName, particle, atts, nsRegistry);
- }
- else
- {
- o = NIL;
- }
- }
- else
- {
- ElementBinding parentBinding = null;
- if(!stack.isEmpty())
- {
- ParticleBinding stackParticle = repeated ? stack.peek(1).particle : stack.peek().particle;
- if(stackParticle != null)
- {
- parentBinding = (ElementBinding)stackParticle.getTerm();
- }
- }
-
- if(parentBinding != null && parentBinding.getSchema() != null)
- {
- schemaBinding = parentBinding.getSchema();
- }
-
- String msg = "Element " +
- startName +
- " is not bound " +
- (parentBinding == null ? "as a global element." : "in type " + parentBinding.getType().getQName());
- if(schemaBinding != null && schemaBinding.isStrictSchema())
- {
- throw new JBossXBRuntimeException(msg);
- }
- else if(trace)
- {
- log.trace(msg);
- }
- }
-
- if(repeated)
- {
- item.o = o;
- // in case of collection of abstract types
- item.particle = particle;
- }
- else
- {
- push(startName, particle, o, handler);
- }
- }
-
- private ParticleHandler getHandler(ParticleBinding modelGroupParticle)
- {
- ParticleHandler handler = ((ModelGroupBinding)modelGroupParticle.getTerm()).getHandler();
- return handler == null ? defParticleHandler : handler;
- }
-
- private void endRepeatableParent(QName startName)
- {
- int parentPos = 1;
- StackItem parentItem;
- ParticleBinding parentParticle = null;
- while(true)
- {
- parentItem = stack.peek(parentPos);
- if(parentItem.cursor == null)
- {
- throw new JBossXBRuntimeException(
- "Failed to start " + startName +
- ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
- ((ElementBinding)parentItem.particle.getTerm()).getQName()
- );
- }
-
- parentParticle = parentItem.particle;
- if(parentParticle.isRepeatable())
- {
- break;
- }
-
- endParticle(parentItem, startName, ++parentPos);
- }
-
- if(!parentParticle.isRepeatable())
- {
- StringBuffer msg = new StringBuffer();
-
- StackItem item = stack.peek();
- ParticleBinding currentParticle = item.particle;
- msg.append("Failed to start ").append(startName).append(": ")
- .append(currentParticle.getTerm())
- .append(" is not repeatable.")
- .append(" Its parent ")
- .append(parentParticle.getTerm())
- .append(" expected to be repeatable!")
- .append("\ncurrent stack: ");
-
- for(int i = stack.size() - 1; i >= 0; --i)
- {
- item = stack.peek(i);
- ParticleBinding particle = item.particle;
- TermBinding term = particle.getTerm();
- if(term.isModelGroup())
- {
- if(term instanceof SequenceBinding)
- {
- msg.append("sequence");
- }
- else if(term instanceof ChoiceBinding)
- {
- msg.append("choice");
- }
- else
- {
- msg.append("all");
- }
- }
- else if(term.isWildcard())
- {
- msg.append("wildcard");
- }
- else
- {
- msg.append(((ElementBinding)term).getQName());
- }
- msg.append("\\");
- }
-
- throw new JBossXBRuntimeException(msg.toString());
- }
-
- // todo startName is wrong here
- endParticle(parentItem, startName, parentPos + 1);
-
- parentItem = stack.peek(parentPos + 1);
- while(parentPos > 0)
- {
- StackItem item = stack.peek(parentPos--);
- ParticleHandler handler = getHandler(item.particle);
- item.reset();
- item.o = handler.startParticle(parentItem.o, startName, item.particle, null, nsRegistry);
- parentItem = item;
- }
- }
-
- private void startRepeatableParticle(QName startName, ParticleBinding particle)
- {
- //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
-
- TermBinding term = particle.getTerm();
- if(term.isSkip())
- {
- return;
- }
-
- StackItem item = stack.peek();
- if(item.o != null &&
- !(item.o instanceof GenericValueContainer) &&
- term.getAddMethodMetaData() == null &&
- term.getMapEntryMetaData() == null &&
- term.getPutMethodMetaData() == null)
- {
- ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
- Class cls = item.o.getClass();
- item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
- }
- }
-
- private void endRepeatableParticle(ParticleBinding particle)
- {
- //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
-
- StackItem item = stack.peek();
- ValueList valueList = item.repeatableParticleValue;
- if(valueList != null)
- {
- item.repeatableParticleValue = null;
- if(valueList.size() == 0)
- {
- return;
- }
-
- if(particle.getTerm().isWildcard())
- {
- ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
- if(handler == null)
- {
- handler = defParticleHandler;
- }
-
- // that's not good. some elements can be handled as "unresolved" and some as "resolved"
- QName qName = valueList.getValue(0).qName;
- Collection col = new ArrayList();
- for(int i = 0; i < valueList.size(); ++i)
- {
- col.add(valueList.getValue(i).value);
- }
- StackItem parentItem = stack.peek(1);
- handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
- }
- else
- {
- valueList.getHandler().newInstance(particle, valueList);
- }
- }
- }
-
- private void endParticle(StackItem item, QName qName, int parentStackPos)
- {
- if(item.ended)
- {
- throw new JBossXBRuntimeException(item.particle.getTerm() + " has already been ended.");
- }
-
- ParticleBinding modelGroupParticle = item.particle;
- ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
-
- Object o;
- if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
- {
- if(trace)
- {
- log.trace("endParticle " + modelGroupParticle.getTerm() + " valueList");
- }
- ValueList valueList = (ValueList)item.o;
- o = valueList.getHandler().newInstance(modelGroupParticle, valueList);
- }
- else
- {
- o = handler.endParticle(item.o, qName, modelGroupParticle);
- }
-
- item.ended = true;
-
- // model group should always have parent particle
- item = (StackItem)stack.peek(parentStackPos);
- if(item.o != null)
- {
- ParticleBinding parentParticle = getParentParticle();//item.particle;
- if(parentParticle == null)
- {
- parentParticle = item.particle;
- }
- setParent(handler,
- item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
- o, qName, modelGroupParticle, parentParticle);
- }
- }
-
- public void startPrefixMapping(String prefix, String uri)
- {
- nsRegistry.addPrefixMapping(prefix, uri);
- }
-
- public void endPrefixMapping(String prefix)
- {
- nsRegistry.removePrefixMapping(prefix);
- }
-
- public void processingInstruction(String target, String data)
- {
- }
-
- public Object getRoot()
- {
- return root;
- }
-
- // Private
-
- private ParticleBinding getParentParticle()
- {
- ListIterator iter = stack.prevIterator();
- while(iter.hasPrevious())
- {
- StackItem prev = (StackItem)iter.previous();
- ParticleBinding peeked = prev.particle;
-
- TermBinding term = peeked.getTerm();
- if(!term.isSkip())
- {
- return peeked;
- }
- }
- return null;
- }
-
- private void endElement()
- {
- StackItem item = stack.peek();
- Object o = item.o;
- ParticleBinding particle = item.particle;
-
- ElementBinding element = (ElementBinding)particle.getTerm();
- QName endName = element.getQName();
- TypeBinding type = element.getType();
- List interceptors = element.getInterceptors();
- int interceptorsTotal = interceptors.size();
-
- if(o != NIL)
- {
- //
- // characters
- //
-
- TypeBinding charType = type.getSimpleType();
- if(charType == null)
- {
- charType = type;
- }
-
- CharactersHandler charHandler = item.ignoreCharacters ? null : charType.getCharactersHandler();
-
- /**
- * If there is text content then unmarshal it and set.
- * If there is no text content and the type is simple and
- * its characters handler is not null then unmarshal and set.
- * If the type is complex and there is no text data then the unmarshalled value
- * of the empty text content is assumed to be null
- * (in case of simple types that's not always true and depends on nillable attribute).
- */
- String textContent = item.textContent == null ? "" : item.textContent.toString();
- if(textContent.length() > 0 || charHandler != null && type.isSimple())
- {
- String dataContent;
- SchemaBinding schema = element.getSchema();
- if(textContent.length() == 0)
- {
- dataContent = null;
- }
- else
- {
- dataContent = textContent.toString();
- if(schema != null && schema.isReplacePropertyRefs())
- {
- dataContent = StringPropertyReplacer.replaceProperties(dataContent);
- }
- }
-
- Object unmarshalled;
-
- if(charHandler == null)
- {
- if(!type.isSimple() &&
- schema != null &&
- schema.isStrictSchema()
- // todo this isSkip() doesn't look nice here
- && !element.isSkip())
- {
- throw new JBossXBRuntimeException("Element " +
- endName +
- " with type binding " +
- type.getQName() +
- " does not include text content binding: " + dataContent
- );
- }
- unmarshalled = dataContent;
- }
- else
- {
- ValueMetaData valueMetaData = element.getValueMetaData();
- if(valueMetaData == null)
- {
- CharactersMetaData charactersMetaData = type.getCharactersMetaData();
- if(charactersMetaData != null)
- {
- valueMetaData = charactersMetaData.getValue();
- }
- }
-
- // todo valueMetaData is available from type
- unmarshalled = dataContent == null ?
- charHandler.unmarshalEmpty(endName, charType, nsRegistry, valueMetaData) :
- charHandler.unmarshal(endName, charType, nsRegistry, valueMetaData, dataContent);
- }
-
- if(unmarshalled != null)
- {
- // if startElement returned null, we use characters as the object for this element
- if(o == null)
- {
- o = unmarshalled;
- }
- else if(charHandler != null)
- {
- TermBeforeSetParentCallback beforeSetParent = charType.getBeforeSetParentCallback();
- if(beforeSetParent != null)
- {
- ctx.parent = o;
- ctx.particle = particle;
- ctx.parentParticle = getParentParticle();
- unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
- ctx.clear();
- }
-
- if(o instanceof ValueList)
- {
- ValueList valueList = (ValueList)o;
- if(type.isSimple())
- {
- valueList.getInitializer().addTermValue(endName,
- particle,
- charHandler,
- valueList,
- unmarshalled,
- null
- );
- }
- else
- {
- valueList.getInitializer().addTextValue(endName,
- particle,
- charHandler,
- valueList,
- unmarshalled
- );
- }
- }
- else
- {
- charHandler.setValue(endName, element, o, unmarshalled);
- }
- }
- }
-
- for(int i = interceptorsTotal - 1; i >= 0; --i)
- {
- ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
- interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
- endName, type, nsRegistry, dataContent
- );
- }
- }
- }
- else
- {
- o = null;
- }
-
- //
- // endElement
- //
-
- StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
- Object parent = parentItem == null ? null : parentItem.o;
- ParticleHandler handler = stack.peek().handler;
-
- if(o instanceof ValueList && !particle.getTerm().isSkip())
- {
- if(trace)
- {
- log.trace("endParticle " + endName + " valueList");
- }
- ValueList valueList = (ValueList)o;
- o = valueList.getHandler().newInstance(particle, valueList);
- }
- else
- {
- o = handler.endParticle(o, endName, particle);
- }
-
- for(int i = interceptorsTotal - 1; i >= 0; --i)
- {
- ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
- interceptor.endElement(((StackItem)stack.peek(interceptorsTotal - i)).o, endName, type);
- }
-
- //
- // setParent
- //
-
- if(interceptorsTotal == 0)
- {
- ParticleBinding parentParticle = getParentParticle();
- boolean hasWildcard = false;
- ParticleHandler wildcardHandler = null;
-
- if (parentParticle != null && parentParticle.getTerm().isElement())
- {
- WildcardBinding wildcard = ((ElementBinding) parentParticle.getTerm()).getType().getWildcard();
- if (wildcard != null)
- {
- hasWildcard = true;
- wildcardHandler = wildcard.getWildcardHandler();
- }
- }
-
- if(parent != null)
- {
- /*if(o == null)
- {
- throw new JBossXBRuntimeException(endName + " is null!");
- } */
- if(wildcardHandler != null)
- {
- setParent(wildcardHandler,
- parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
- o, endName, particle, parentParticle);
- }
- else
- {
- setParent(handler,
- parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
- o, endName, particle, parentParticle);
- }
- }
- else if(parentParticle != null && hasWildcard && stack.size() > 1)
- {
- // the parent has anyType, so it gets the value of its child
- ListIterator iter = stack.prevIterator();
- while(iter.hasPrevious())
- {
- StackItem peeked = (StackItem)iter.previous();
- peeked.o = o;
- if(peeked.cursor == null)
- {
- break;
- }
- }
-
- if(trace)
- {
- log.trace("Value of " + endName + " " + o + " is promoted as the value of its parent element.");
- }
- }
- }
- else
- {
- StackItem popped = pop();
- for(int i = interceptorsTotal - 1; i >= 0; --i)
- {
- ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
- parent = pop().o;
- interceptor.add(parent, o, endName);
- o = parent;
- }
- // need to have correst endRepeatableParticle events
- stack.push(popped);
- }
-
- if(stack.size() == 1)
- {
- root = o;
- stack.clear();
- }
- }
-
- private void setParent(ParticleHandler handler,
- Object parent,
- Object o,
- QName endName,
- ParticleBinding particle,
- ParticleBinding parentParticle)
- {
- TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
- if(beforeSetParent != null)
- {
- ctx.parent = parent;
- ctx.particle = particle;
- ctx.parentParticle = parentParticle;
- o = beforeSetParent.beforeSetParent(o, ctx);
- ctx.clear();
- }
-
- if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
- {
- if(parent == o)
- {
- return;
- }
- ValueList valueList = (ValueList)parent;
- valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
- }
- else
- {
- handler.setParent(parent, o, endName, particle, parentParticle);
- }
- }
-
- private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
- {
- StackItem item = new StackItem(particle, o, handler);
- stack.push(item);
- if(trace)
- {
- Object binding = null;
- if(particle != null)
- {
- binding = particle.getTerm();
- }
- log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
- }
- }
-
- private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
- {
- StackItem item = new StackItem(cursor, o, handler);
- stack.push(item);
- if(trace)
- {
- log.trace("pushed cursor " + cursor + ", o=" + o);
- }
- }
-
- private StackItem pop()
- {
- StackItem item = stack.pop();
- if(trace)
- {
- if(item.cursor == null)
- {
- log.trace("poped " + ((ElementBinding)item.particle.getTerm()).getQName() + "=" + item.particle);
- }
- else
- {
- log.trace("poped " + item.cursor.getCurrentParticle().getTerm());
- }
- }
- return item;
- }
-
- // Inner
-
- private static class StackItem
- {
- final ModelGroupBinding.Cursor cursor;
- ParticleBinding particle;
- ParticleHandler handler;
- boolean ignoreCharacters;
- Object o;
- ValueList repeatableParticleValue;
- StringBuffer textContent;
- boolean ended;
-
- public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
- {
- if (cursor == null)
- throw new IllegalArgumentException("Null cursor");
- // this is modelgroup particle
- this.cursor = cursor;
- this.particle = cursor.getParticle();
- this.o = o;
- this.handler = handler;
- }
-
- public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
- {
- if (particle == null)
- throw new IllegalArgumentException("Null particle");
- // this is element particle
- this.cursor = null;
- this.particle = particle;
- this.o = o;
- this.handler = handler;
- }
-
- void reset()
- {
- if(!ended)
- {
- throw new JBossXBRuntimeException(
- "Attempt to reset a particle that has already been reset: " + particle.getTerm()
- );
- }
-
- ended = false;
- o = null;
- if(textContent != null)
- {
- textContent.delete(0, textContent.length());
- }
- }
- }
-
- static class StackImpl
- {
- private List list = new ArrayList();
-
- public void clear()
- {
- list.clear();
- }
-
- public void push(Object o)
- {
- list.add(o);
- }
-
- public StackItem pop()
- {
- return (StackItem)list.remove(list.size() - 1);
- }
-
- public ListIterator prevIterator()
- {
- return list.listIterator(list.size() - 1);
- }
-
- public StackItem peek()
- {
- return (StackItem)list.get(list.size() - 1);
- }
-
- public StackItem peek(int i)
- {
- return (StackItem)list.get(list.size() - 1 - i);
- }
-
- public boolean isEmpty()
- {
- return list.isEmpty();
- }
-
- public int size()
- {
- return list.size();
- }
- }
-
- private class UnmarshallingContextImpl implements UnmarshallingContext
- {
- Object parent;
- ParticleBinding particle;
- ParticleBinding parentParticle;
-
- public Object getParentValue()
- {
- return parent;
- }
-
- public ParticleBinding getParticle()
- {
- return particle;
- }
-
- public ParticleBinding getParentParticle()
- {
- return parentParticle;
- }
-
- public String resolvePropertyName()
- {
- TermBinding term = particle.getTerm();
- PropertyMetaData propertyMetaData = term.getPropertyMetaData();
- String prop = propertyMetaData == null ? null : propertyMetaData.getName();
-
- if(prop != null)
- {
- return prop;
- }
-
- if(term.isElement())
- {
- QName name = ((ElementBinding)term).getQName();
- prop = Util.xmlNameToFieldName(name.getLocalPart(), term.getSchema().isIgnoreLowLine());
- }
-
- return prop;
- }
-
- public Class resolvePropertyType()
- {
- if(parent == null)
- {
- return null;
- }
-
- String prop = resolvePropertyName();
- if(prop != null)
- {
- FieldInfo fieldInfo = FieldInfo.getFieldInfo(parent.getClass(), prop, false);
- if (fieldInfo != null)
- {
- return fieldInfo.getType();
- }
- }
- return null;
- }
-
- // private
-
- void clear()
- {
- ctx.parent = null;
- ctx.particle = null;
- ctx.parentParticle = null;
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/SundayContentHandler.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1407 @@
+/*
+ * 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.xb.binding.sunday.unmarshalling;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ListIterator;
+import javax.xml.namespace.QName;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.jboss.logging.Logger;
+import org.jboss.util.StringPropertyReplacer;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.GenericValueContainer;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.NamespaceRegistry;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.group.ValueList;
+import org.jboss.xb.binding.group.ValueListHandler;
+import org.jboss.xb.binding.group.ValueListInitializer;
+import org.jboss.xb.binding.introspection.FieldInfo;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.parser.JBossXBParser;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
+import org.xml.sax.Attributes;
+
+/**
+ * ContentHandler that is used as a sandbox for JBXB-76
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class SundayContentHandler
+ implements JBossXBParser.ContentHandler
+{
+ private final static Logger log = Logger.getLogger(SundayContentHandler.class);
+
+ private final static Object NIL = new Object();
+
+ private final SchemaBinding schema;
+ private final SchemaBindingResolver schemaResolver;
+
+ private final StackImpl stack = new StackImpl();
+
+ private Object root;
+ private NamespaceRegistry nsRegistry = new NamespaceRegistry();
+
+ private ParticleHandler defParticleHandler = DefaultHandlers.ELEMENT_HANDLER;
+
+ private UnmarshallingContextImpl ctx = new UnmarshallingContextImpl();
+
+ private final boolean trace = log.isTraceEnabled();
+
+ public SundayContentHandler(SchemaBinding schema)
+ {
+ this.schema = schema;
+ this.schemaResolver = null;
+ }
+
+ public SundayContentHandler(SchemaBindingResolver schemaResolver)
+ {
+ this.schemaResolver = schemaResolver;
+ this.schema = null;
+ }
+
+ public void characters(char[] ch, int start, int length)
+ {
+ StackItem stackItem = stack.peek();
+ if(stackItem.cursor != null)
+ {
+ return;
+ }
+
+ ElementBinding e = (ElementBinding) stackItem.particle.getTerm();
+/* if(!stackItem.ended && e.getType().isTextContentAllowed())
+ {
+ int i = start;
+ while (i < start + length)
+ {
+ if(ch[i] == 0x0a)
+ {
+ stackItem.indentation = true;
+ }
+ else
+ {
+ if (ch[i] == ' ' || ch[i] == 0x0d)
+ {
+ }
+ else
+ {
+ stackItem.indentation = false;
+ break;
+ }
+ }
+ ++i;
+ }
+
+ if(!stackItem.indentation)
+ {
+ if (stackItem.textContent == null)
+ {
+ stackItem.textContent = new StringBuffer();
+ }
+ stackItem.textContent.append(ch, start, length);
+ }
+ }
+*/
+ // if current is ended the characters belong to its parent
+ if(stackItem.ended)
+ {
+ int i = 0;
+ do
+ {
+ stackItem = stack.peek(++i);
+ }
+ while(stackItem.cursor != null && i < stack.size());
+
+ e = (ElementBinding) stackItem.particle.getTerm();
+ }
+
+ // collect characters only if they are allowed content
+ if(e.getType().isTextContentAllowed())
+ {
+ if(stackItem.indentation != Boolean.FALSE)
+ {
+ if(e.getType().isSimple())
+ {
+ // simple content is not analyzed
+ stackItem.indentation = Boolean.FALSE;
+ stackItem.ignorableCharacters = false;
+ }
+ else if(e.getSchema() != null && !e.getSchema().isIgnoreWhitespacesInMixedContent())
+ {
+ stackItem.indentation = Boolean.FALSE;
+ stackItem.ignorableCharacters = false;
+ }
+ else
+ {
+ // the indentation is currently defined as whitespaces with next line characters
+ // this should probably be externalized in the form of a filter or something
+ for (int i = start; i < start + length; ++i)
+ {
+ if(ch[i] == 0x0a)
+ {
+ stackItem.indentation = Boolean.TRUE;
+ }
+ else if (!Character.isWhitespace(ch[i]))
+ {
+ stackItem.indentation = Boolean.FALSE;
+ stackItem.ignorableCharacters = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (stackItem.textContent == null)
+ {
+ stackItem.textContent = new StringBuffer();
+ }
+ stackItem.textContent.append(ch, start, length);
+ }
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName)
+ {
+ ElementBinding elementBinding = null;
+ QName endName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
+ StackItem item;
+ while(true)
+ {
+ item = stack.peek();
+ if(item.cursor == null)
+ {
+ if(item.ended)
+ {
+ pop();
+ if(item.particle.isRepeatable())
+ {
+ endRepeatableParticle(item.particle);
+ }
+ }
+ else
+ {
+ elementBinding = (ElementBinding)item.particle.getTerm();
+ item.ended = true;
+ break;
+ }
+ }
+ else
+ {
+ if(!item.ended) // could be ended if it's a choice
+ {
+ endParticle(item, endName, 1);
+ }
+
+ ParticleBinding currentParticle = item.cursor.getCurrentParticle();
+ TermBinding term = currentParticle.getTerm();
+ if(term.isWildcard() && currentParticle.isRepeatable())
+ {
+ endRepeatableParticle(currentParticle);
+ }
+
+ pop();
+ if(item.particle.isRepeatable())
+ {
+ endRepeatableParticle(item.particle);
+ }
+ }
+ }
+
+ if(elementBinding == null)
+ {
+ throw new JBossXBRuntimeException("Failed to endElement " + qName + ": binding not found");
+ }
+
+ if(!elementBinding.getQName().equals(endName))
+ {
+ throw new JBossXBRuntimeException("Failed to end element " +
+ new QName(namespaceURI, localName) +
+ ": element on the stack is " + elementBinding.getQName()
+ );
+ }
+
+ endElement();
+ }
+
+ public void startElement(String namespaceURI,
+ String localName,
+ String qName,
+ Attributes atts,
+ XSTypeDefinition xercesType)
+ {
+ QName startName = localName.length() == 0 ? new QName(qName) : new QName(namespaceURI, localName);
+ ParticleBinding particle = null;
+ ParticleHandler handler = null;
+ boolean repeated = false;
+ boolean repeatedParticle = false;
+ StackItem item = null;
+ ModelGroupBinding.Cursor cursor = null; // used only when particle is a wildcard
+ SchemaBinding schemaBinding = schema;
+
+ if(stack.isEmpty())
+ {
+ if(schemaBinding != null)
+ {
+ particle = schemaBinding.getElementParticle(startName);
+ }
+ else if(schemaResolver != null)
+ {
+ String schemaLocation = atts == null ? null : Util.getSchemaLocation(atts, namespaceURI);
+ schemaBinding = schemaResolver.resolve(namespaceURI, null, schemaLocation);
+ if(schemaBinding != null)
+ {
+ particle = schemaBinding.getElementParticle(startName);
+ }
+ else
+ {
+ throw new JBossXBRuntimeException("Failed to resolve schema nsURI=" + namespaceURI + " location=" + schemaLocation);
+ }
+ }
+ else
+ {
+ throw new JBossXBRuntimeException("Neither schema binding nor schema binding resolver is available!");
+ }
+ }
+ else
+ {
+ while(!stack.isEmpty())
+ {
+ item = stack.peek();
+ if(item.cursor == null)
+ {
+ TermBinding term = item.particle.getTerm();
+ ElementBinding element = (ElementBinding)term;
+ if(item.ended)
+ {
+ if(element.getQName().equals(startName))
+ {
+ particle = item.particle;
+ repeated = true;
+ item.reset();
+
+ if(!particle.isRepeatable())
+ {
+ endRepeatableParent(startName);
+ }
+ }
+ else
+ {
+ pop();
+ if(item.particle.isRepeatable())
+ {
+ endRepeatableParticle(item.particle);
+ }
+ continue;
+ }
+ }
+ else
+ {
+ ParticleBinding typeParticle = element.getType().getParticle();
+ ModelGroupBinding modelGroup = typeParticle == null ?
+ null :
+ (ModelGroupBinding)typeParticle.getTerm();
+ if(modelGroup == null)
+ {
+ if(startName.equals(Constants.QNAME_XOP_INCLUDE))
+ {
+ TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+ if(anyUriType == null)
+ {
+ log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+ }
+
+ TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
+ xopIncludeType.setSchemaBinding(schema);
+ xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
+ xopIncludeType.setHandler(new XOPIncludeHandler(element.getType(), schema.getXopUnmarshaller()));
+
+ ElementBinding xopInclude = new ElementBinding(schema, Constants.QNAME_XOP_INCLUDE, xopIncludeType);
+
+ particle = new ParticleBinding(xopInclude);
+
+ ElementBinding parentElement = (ElementBinding) item.particle.getTerm();
+ parentElement.setXopUnmarshaller(schema.getXopUnmarshaller());
+
+ flushIgnorableCharacters();
+ item.handler = DefaultHandlers.XOP_HANDLER;
+ item.ignoreCharacters = true;
+ item.o = item.handler.startParticle(stack.peek().o, startName, stack.peek().particle, null, nsRegistry);
+ break;
+ }
+
+ QName typeName = element.getType().getQName();
+ throw new JBossXBRuntimeException((typeName == null ? "Anonymous" : typeName.toString()) +
+ " type of element " +
+ element.getQName() +
+ " should be complex and contain " + startName + " as a child element."
+ );
+ }
+
+ cursor = modelGroup.newCursor(typeParticle);
+ List newCursors = cursor.startElement(startName, atts);
+ if(newCursors.isEmpty())
+ {
+ throw new JBossXBRuntimeException(startName +
+ " not found as a child of " +
+ ((ElementBinding)term).getQName()
+ );
+ }
+ else
+ {
+ flushIgnorableCharacters();
+
+ Object o = item.o;
+ // push all except the last one
+ for(int i = newCursors.size() - 1; i >= 0; --i)
+ {
+ cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
+
+ ParticleBinding modelGroupParticle = cursor.getParticle();
+ if(modelGroupParticle.isRepeatable())
+ {
+ startRepeatableParticle(startName, modelGroupParticle);
+ }
+
+ handler = getHandler(modelGroupParticle);
+ o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
+ push(cursor, o, handler);
+ }
+ particle = cursor.getCurrentParticle();
+ }
+ }
+ break;
+ }
+ else
+ {
+ cursor = item.cursor;
+ if(cursor == null)
+ {
+ throw new JBossXBRuntimeException("No cursor for " + startName);
+ }
+
+ // todo review
+ if(!item.ended && cursor.isPositioned() && cursor.getParticle().getTerm() instanceof ChoiceBinding)
+ {
+ endParticle(item, startName, 1);
+ if(!item.particle.isRepeatable()) // this is for repeatable choices that should stay on the stack
+ {
+ pop();
+ }
+ continue;
+ }
+
+ //int prevOccurence = cursor.getOccurence();
+ ParticleBinding prevParticle = cursor.isPositioned() ? cursor.getCurrentParticle() : null;
+ List newCursors = cursor.startElement(startName, atts);
+ if(newCursors.isEmpty())
+ {
+ if(!item.ended) // this is for choices
+ {
+ endParticle(item, startName, 1);
+ }
+ pop();
+ }
+ else
+ {
+ if(item.ended) // for repeatable choices
+ {
+ if(!item.particle.isRepeatable())
+ {
+ throw new JBossXBRuntimeException("The particle expected to be repeatable but it's not: " + item.particle.getTerm());
+ }
+ item.reset();
+
+ handler = getHandler(item.particle);
+ item.o = handler.startParticle(stack.peek(1).o, startName, item.particle, atts, nsRegistry);
+ }
+
+ ParticleBinding curParticle = cursor.getCurrentParticle();
+ if(curParticle != prevParticle)
+ {
+ if(prevParticle != null && prevParticle.isRepeatable() && prevParticle.getTerm().isModelGroup())
+ {
+ endRepeatableParticle(prevParticle);
+ }
+
+ if(newCursors.size() > 1 && curParticle.isRepeatable())
+ {
+ startRepeatableParticle(startName, curParticle);
+ }
+ }
+ else
+ {
+ repeatedParticle = true;
+ }
+
+ // push all except the last one
+ Object o = item.o;
+ for(int i = newCursors.size() - 2; i >= 0; --i)
+ {
+ cursor = (ModelGroupBinding.Cursor)newCursors.get(i);
+
+ ParticleBinding modelGroupParticle = cursor.getParticle();
+ handler = getHandler(modelGroupParticle);
+ o = handler.startParticle(o, startName, modelGroupParticle, atts, nsRegistry);
+ push(cursor, o, handler);
+ }
+ cursor = (ModelGroupBinding.Cursor)newCursors.get(0);
+ particle = cursor.getCurrentParticle();
+ break;
+ }
+ }
+ }
+ }
+
+ Object o = null;
+ if(particle != null)
+ {
+ Object parent = stack.isEmpty() ? null :
+ (repeated ? stack.peek(1).o : stack.peek().o);
+ if(particle.getTerm() instanceof WildcardBinding)
+ {
+ /*
+ WildcardBinding wildcard = (WildcardBinding)particle.getTerm();
+ ElementBinding element = wildcard.getElement(startName, atts);
+ */
+ ElementBinding element = cursor.getElement();
+ if(element == null)
+ {
+ throw new JBossXBRuntimeException("Failed to resolve element " +
+ startName + " for wildcard."
+ );
+ }
+
+ if(!repeatedParticle && particle.isRepeatable())
+ {
+ startRepeatableParticle(startName, particle);
+ }
+ particle = new ParticleBinding(element/*, particle.getMinOccurs(), particle.getMaxOccurs(), particle.getMaxOccursUnbounded()*/);
+ }
+
+ ElementBinding element = (ElementBinding)particle.getTerm();
+
+ // todo xsi:type support should be implemented in a better way
+ String xsiType = atts.getValue("xsi:type");
+ if(xsiType != null)
+ {
+ if(trace)
+ {
+ log.trace(element.getQName() + " uses xsi:type " + xsiType);
+ }
+
+ String xsiTypePrefix;
+ String xsiTypeLocal;
+ int colon = xsiType.indexOf(':');
+ if(colon == -1)
+ {
+ xsiTypePrefix = "";
+ xsiTypeLocal = xsiType;
+ }
+ else
+ {
+ xsiTypePrefix = xsiType.substring(0, colon);
+ xsiTypeLocal = xsiType.substring(colon + 1);
+ }
+
+ String xsiTypeNs = nsRegistry.getNamespaceURI(xsiTypePrefix);
+ QName xsiTypeQName = new QName(xsiTypeNs, xsiTypeLocal);
+
+ TypeBinding xsiTypeBinding = schemaBinding.getType(xsiTypeQName);
+ if(xsiTypeBinding == null)
+ {
+ throw new JBossXBRuntimeException("Type binding not found for type " +
+ xsiTypeQName +
+ " specified with xsi:type for element " + startName
+ );
+ }
+
+ element = new ElementBinding(schemaBinding, startName, xsiTypeBinding);
+ particle =
+ new ParticleBinding(element,
+ particle.getMinOccurs(),
+ particle.getMaxOccurs(),
+ particle.getMaxOccursUnbounded()
+ );
+ }
+
+ if(!repeated && particle.isRepeatable())
+ {
+ startRepeatableParticle(startName, particle);
+ }
+
+ TypeBinding type = element.getType();
+ if(type == null)
+ {
+ throw new JBossXBRuntimeException("No type for element " + element);
+ }
+
+ handler = type.getHandler();
+ if(handler == null)
+ {
+ handler = defParticleHandler;
+ }
+
+ List interceptors = element.getInterceptors();
+ if(!interceptors.isEmpty())
+ {
+ if (repeated)
+ {
+ pop();
+ }
+
+ for (int i = 0; i < interceptors.size(); ++i)
+ {
+ ElementInterceptor interceptor = (ElementInterceptor) interceptors.get(i);
+ parent = interceptor.startElement(parent, startName, type);
+ push(startName, particle, parent, handler);
+ interceptor.attributes(parent, startName, type, atts, nsRegistry);
+ }
+
+ if (repeated)
+ {
+ // to have correct endRepeatableParticle calls
+ stack.push(item);
+ }
+ }
+
+ String nil = atts.getValue("xsi:nil");
+ if(nil == null || !("1".equals(nil) || "true".equals(nil)))
+ {
+ o = handler.startParticle(parent, startName, particle, atts, nsRegistry);
+ }
+ else
+ {
+ o = NIL;
+ }
+ }
+ else
+ {
+ ElementBinding parentBinding = null;
+ if(!stack.isEmpty())
+ {
+ ParticleBinding stackParticle = repeated ? stack.peek(1).particle : stack.peek().particle;
+ if(stackParticle != null)
+ {
+ parentBinding = (ElementBinding)stackParticle.getTerm();
+ }
+ }
+
+ if(parentBinding != null && parentBinding.getSchema() != null)
+ {
+ schemaBinding = parentBinding.getSchema();
+ }
+
+ String msg = "Element " +
+ startName +
+ " is not bound " +
+ (parentBinding == null ? "as a global element." : "in type " + parentBinding.getType().getQName());
+ if(schemaBinding != null && schemaBinding.isStrictSchema())
+ {
+ throw new JBossXBRuntimeException(msg);
+ }
+ else if(trace)
+ {
+ log.trace(msg);
+ }
+ }
+
+ if(repeated)
+ {
+ item.o = o;
+ // in case of collection of abstract types
+ item.particle = particle;
+ }
+ else
+ {
+ push(startName, particle, o, handler);
+ }
+ }
+
+ private ParticleHandler getHandler(ParticleBinding modelGroupParticle)
+ {
+ ParticleHandler handler = ((ModelGroupBinding)modelGroupParticle.getTerm()).getHandler();
+ return handler == null ? defParticleHandler : handler;
+ }
+
+ private void endRepeatableParent(QName startName)
+ {
+ int parentPos = 1;
+ StackItem parentItem;
+ ParticleBinding parentParticle = null;
+ while(true)
+ {
+ parentItem = stack.peek(parentPos);
+ if(parentItem.cursor == null)
+ {
+ throw new JBossXBRuntimeException(
+ "Failed to start " + startName +
+ ": the element is not repeatable, repeatable parent expected to be a model group but got element " +
+ ((ElementBinding)parentItem.particle.getTerm()).getQName()
+ );
+ }
+
+ parentParticle = parentItem.particle;
+ if(parentParticle.isRepeatable())
+ {
+ break;
+ }
+
+ endParticle(parentItem, startName, ++parentPos);
+ }
+
+ if(!parentParticle.isRepeatable())
+ {
+ StringBuffer msg = new StringBuffer();
+
+ StackItem item = stack.peek();
+ ParticleBinding currentParticle = item.particle;
+ msg.append("Failed to start ").append(startName).append(": ")
+ .append(currentParticle.getTerm())
+ .append(" is not repeatable.")
+ .append(" Its parent ")
+ .append(parentParticle.getTerm())
+ .append(" expected to be repeatable!")
+ .append("\ncurrent stack: ");
+
+ for(int i = stack.size() - 1; i >= 0; --i)
+ {
+ item = stack.peek(i);
+ ParticleBinding particle = item.particle;
+ TermBinding term = particle.getTerm();
+ if(term.isModelGroup())
+ {
+ if(term instanceof SequenceBinding)
+ {
+ msg.append("sequence");
+ }
+ else if(term instanceof ChoiceBinding)
+ {
+ msg.append("choice");
+ }
+ else
+ {
+ msg.append("all");
+ }
+ }
+ else if(term.isWildcard())
+ {
+ msg.append("wildcard");
+ }
+ else
+ {
+ msg.append(((ElementBinding)term).getQName());
+ }
+ msg.append("\\");
+ }
+
+ throw new JBossXBRuntimeException(msg.toString());
+ }
+
+ // todo startName is wrong here
+ endParticle(parentItem, startName, parentPos + 1);
+
+ parentItem = stack.peek(parentPos + 1);
+ while(parentPos > 0)
+ {
+ StackItem item = stack.peek(parentPos--);
+ ParticleHandler handler = getHandler(item.particle);
+ item.reset();
+ item.o = handler.startParticle(parentItem.o, startName, item.particle, null, nsRegistry);
+ parentItem = item;
+ }
+ }
+
+ private void startRepeatableParticle(QName startName, ParticleBinding particle)
+ {
+ //System.out.println(" start repeatable (" + stack.size() + "): " + particle.getTerm());
+
+ TermBinding term = particle.getTerm();
+ if(term.isSkip())
+ {
+ return;
+ }
+
+ StackItem item = stack.peek();
+ if(item.o != null &&
+ !(item.o instanceof GenericValueContainer) &&
+ term.getAddMethodMetaData() == null &&
+ term.getMapEntryMetaData() == null &&
+ term.getPutMethodMetaData() == null)
+ {
+ ValueListHandler handler = ValueListHandler.FACTORY.lazy(item.o);
+ Class cls = item.o.getClass();
+ item.repeatableParticleValue = new ValueListInitializer().newValueList(handler, cls);
+ }
+ }
+
+ private void endRepeatableParticle(ParticleBinding particle)
+ {
+ //System.out.println(" end repeatable (" + stack.size() + "): " + particle.getTerm());
+
+ StackItem item = stack.peek();
+ ValueList valueList = item.repeatableParticleValue;
+ if(valueList != null)
+ {
+ item.repeatableParticleValue = null;
+ if(valueList.size() == 0)
+ {
+ return;
+ }
+
+ if(particle.getTerm().isWildcard())
+ {
+ ParticleHandler handler = ((WildcardBinding)particle.getTerm()).getWildcardHandler();
+ if(handler == null)
+ {
+ handler = defParticleHandler;
+ }
+
+ // that's not good. some elements can be handled as "unresolved" and some as "resolved"
+ QName qName = valueList.getValue(0).qName;
+ Collection col = new ArrayList();
+ for(int i = 0; i < valueList.size(); ++i)
+ {
+ col.add(valueList.getValue(i).value);
+ }
+ StackItem parentItem = stack.peek(1);
+ handler.setParent(parentItem.o, col, qName, particle, parentItem.particle);
+ }
+ else
+ {
+ valueList.getHandler().newInstance(particle, valueList);
+ }
+ }
+ }
+
+ private void endParticle(StackItem item, QName qName, int parentStackPos)
+ {
+ if(item.ended)
+ {
+ throw new JBossXBRuntimeException(item.particle.getTerm() + " has already been ended.");
+ }
+
+ ParticleBinding modelGroupParticle = item.particle;
+ ParticleHandler handler = item.handler;//getHandler(modelGroupParticle);
+
+ Object o;
+ if(item.o instanceof ValueList && !modelGroupParticle.getTerm().isSkip())
+ {
+ if(trace)
+ {
+ log.trace("endParticle " + modelGroupParticle.getTerm() + " valueList");
+ }
+ ValueList valueList = (ValueList)item.o;
+ o = valueList.getHandler().newInstance(modelGroupParticle, valueList);
+ }
+ else
+ {
+ o = handler.endParticle(item.o, qName, modelGroupParticle);
+ }
+
+ item.ended = true;
+
+ // model group should always have parent particle
+ item = (StackItem)stack.peek(parentStackPos);
+ if(item.o != null)
+ {
+ ParticleBinding parentParticle = getParentParticle();//item.particle;
+ if(parentParticle == null)
+ {
+ parentParticle = item.particle;
+ }
+ setParent(handler,
+ item.repeatableParticleValue == null ? item.o : item.repeatableParticleValue,
+ o, qName, modelGroupParticle, parentParticle);
+ }
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ {
+ nsRegistry.addPrefixMapping(prefix, uri);
+ }
+
+ public void endPrefixMapping(String prefix)
+ {
+ nsRegistry.removePrefixMapping(prefix);
+ }
+
+ public void processingInstruction(String target, String data)
+ {
+ }
+
+ public Object getRoot()
+ {
+ return root;
+ }
+
+ // Private
+
+ private void flushIgnorableCharacters()
+ {
+ StackItem stackItem = stack.peek();
+ if(stackItem.cursor != null || stackItem.textContent == null)
+ {
+ return;
+ }
+
+ if(stackItem.indentation == Boolean.TRUE || stackItem.ignorableCharacters)
+ {
+ if(log.isTraceEnabled())
+ {
+ log.trace("ignored characters: " + ((ElementBinding) stackItem.particle.getTerm()).getQName() + " '"
+ + stackItem.textContent + "'");
+ }
+ stackItem.textContent = null;
+ stackItem.indentation = null;
+ }
+ }
+
+ private ParticleBinding getParentParticle()
+ {
+ ListIterator iter = stack.prevIterator();
+ while(iter.hasPrevious())
+ {
+ StackItem prev = (StackItem)iter.previous();
+ ParticleBinding peeked = prev.particle;
+
+ TermBinding term = peeked.getTerm();
+ if(!term.isSkip())
+ {
+ return peeked;
+ }
+ }
+ return null;
+ }
+
+ private void endElement()
+ {
+ StackItem item = stack.peek();
+ Object o = item.o;
+ ParticleBinding particle = item.particle;
+
+ ElementBinding element = (ElementBinding)particle.getTerm();
+ QName endName = element.getQName();
+ TypeBinding type = element.getType();
+ List interceptors = element.getInterceptors();
+ int interceptorsTotal = interceptors.size();
+
+ if(o != NIL)
+ {
+ //
+ // characters
+ //
+
+ flushIgnorableCharacters();
+
+ TypeBinding charType = type.getSimpleType();
+ if(charType == null)
+ {
+ charType = type;
+ }
+
+ CharactersHandler charHandler = item.ignoreCharacters ? null : charType.getCharactersHandler();
+
+ /**
+ * If there is text content then unmarshal it and set.
+ * If there is no text content and the type is simple and
+ * its characters handler is not null then unmarshal and set.
+ * If the type is complex and there is no text data then the unmarshalled value
+ * of the empty text content is assumed to be null
+ * (in case of simple types that's not always true and depends on nillable attribute).
+ */
+ String textContent = item.textContent == null ? "" : item.textContent.toString();
+ if(textContent.length() > 0 || charHandler != null && type.isSimple())
+ {
+ String dataContent;
+ SchemaBinding schema = element.getSchema();
+ if(textContent.length() == 0)
+ {
+ dataContent = null;
+ }
+ else
+ {
+ dataContent = textContent.toString();
+ if(schema != null && schema.isReplacePropertyRefs())
+ {
+ dataContent = StringPropertyReplacer.replaceProperties(dataContent);
+ }
+ }
+
+ Object unmarshalled;
+
+ if(charHandler == null)
+ {
+ if(!type.isSimple() &&
+ schema != null &&
+ schema.isStrictSchema()
+ // todo this isSkip() doesn't look nice here
+ && !element.isSkip())
+ {
+ throw new JBossXBRuntimeException("Element " +
+ endName +
+ " with type binding " +
+ type.getQName() +
+ " does not include text content binding: " + dataContent
+ );
+ }
+ unmarshalled = dataContent;
+ }
+ else
+ {
+ ValueMetaData valueMetaData = element.getValueMetaData();
+ if(valueMetaData == null)
+ {
+ CharactersMetaData charactersMetaData = type.getCharactersMetaData();
+ if(charactersMetaData != null)
+ {
+ valueMetaData = charactersMetaData.getValue();
+ }
+ }
+
+ // todo valueMetaData is available from type
+ unmarshalled = dataContent == null ?
+ charHandler.unmarshalEmpty(endName, charType, nsRegistry, valueMetaData) :
+ charHandler.unmarshal(endName, charType, nsRegistry, valueMetaData, dataContent);
+ }
+
+ if(unmarshalled != null)
+ {
+ // if startElement returned null, we use characters as the object for this element
+ if(o == null)
+ {
+ o = unmarshalled;
+ }
+ else if(charHandler != null)
+ {
+ TermBeforeSetParentCallback beforeSetParent = charType.getBeforeSetParentCallback();
+ if(beforeSetParent != null)
+ {
+ ctx.parent = o;
+ ctx.particle = particle;
+ ctx.parentParticle = getParentParticle();
+ unmarshalled = beforeSetParent.beforeSetParent(unmarshalled, ctx);
+ ctx.clear();
+ }
+
+ if(o instanceof ValueList)
+ {
+ ValueList valueList = (ValueList)o;
+ if(type.isSimple())
+ {
+ valueList.getInitializer().addTermValue(endName,
+ particle,
+ charHandler,
+ valueList,
+ unmarshalled,
+ null
+ );
+ }
+ else
+ {
+ valueList.getInitializer().addTextValue(endName,
+ particle,
+ charHandler,
+ valueList,
+ unmarshalled
+ );
+ }
+ }
+ else
+ {
+ charHandler.setValue(endName, element, o, unmarshalled);
+ }
+ }
+ }
+
+ for(int i = interceptorsTotal - 1; i >= 0; --i)
+ {
+ ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+ interceptor.characters(((StackItem)stack.peek(interceptorsTotal - i)).o,
+ endName, type, nsRegistry, dataContent
+ );
+ }
+ }
+ }
+ else
+ {
+ o = null;
+ }
+
+ //
+ // endElement
+ //
+
+ StackItem parentItem = stack.size() == 1 ? null : stack.peek(1);
+ Object parent = parentItem == null ? null : parentItem.o;
+ ParticleHandler handler = stack.peek().handler;
+
+ if(o instanceof ValueList && !particle.getTerm().isSkip())
+ {
+ if(trace)
+ {
+ log.trace("endParticle " + endName + " valueList");
+ }
+ ValueList valueList = (ValueList)o;
+ o = valueList.getHandler().newInstance(particle, valueList);
+ }
+ else
+ {
+ o = handler.endParticle(o, endName, particle);
+ }
+
+ for(int i = interceptorsTotal - 1; i >= 0; --i)
+ {
+ ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+ interceptor.endElement(((StackItem)stack.peek(interceptorsTotal - i)).o, endName, type);
+ }
+
+ //
+ // setParent
+ //
+
+ if(interceptorsTotal == 0)
+ {
+ ParticleBinding parentParticle = getParentParticle();
+ boolean hasWildcard = false;
+ ParticleHandler wildcardHandler = null;
+
+ if (parentParticle != null && parentParticle.getTerm().isElement())
+ {
+ WildcardBinding wildcard = ((ElementBinding) parentParticle.getTerm()).getType().getWildcard();
+ if (wildcard != null)
+ {
+ hasWildcard = true;
+ wildcardHandler = wildcard.getWildcardHandler();
+ }
+ }
+
+ if(parent != null)
+ {
+ /*if(o == null)
+ {
+ throw new JBossXBRuntimeException(endName + " is null!");
+ } */
+ if(wildcardHandler != null)
+ {
+ setParent(wildcardHandler,
+ parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+ o, endName, particle, parentParticle);
+ }
+ else
+ {
+ setParent(handler,
+ parentItem.repeatableParticleValue == null ? parent : parentItem.repeatableParticleValue,
+ o, endName, particle, parentParticle);
+ }
+ }
+ else if(parentParticle != null && hasWildcard && stack.size() > 1)
+ {
+ // the parent has anyType, so it gets the value of its child
+ ListIterator iter = stack.prevIterator();
+ while(iter.hasPrevious())
+ {
+ StackItem peeked = (StackItem)iter.previous();
+ peeked.o = o;
+ if(peeked.cursor == null)
+ {
+ break;
+ }
+ }
+
+ if(trace)
+ {
+ log.trace("Value of " + endName + " " + o + " is promoted as the value of its parent element.");
+ }
+ }
+ }
+ else
+ {
+ StackItem popped = pop();
+ for(int i = interceptorsTotal - 1; i >= 0; --i)
+ {
+ ElementInterceptor interceptor = (ElementInterceptor)interceptors.get(i);
+ parent = pop().o;
+ interceptor.add(parent, o, endName);
+ o = parent;
+ }
+ // need to have correst endRepeatableParticle events
+ stack.push(popped);
+ }
+
+ if(stack.size() == 1)
+ {
+ root = o;
+ stack.clear();
+ }
+ }
+
+ private void setParent(ParticleHandler handler,
+ Object parent,
+ Object o,
+ QName endName,
+ ParticleBinding particle,
+ ParticleBinding parentParticle)
+ {
+ TermBeforeSetParentCallback beforeSetParent = particle.getTerm().getBeforeSetParentCallback();
+ if(beforeSetParent != null)
+ {
+ ctx.parent = parent;
+ ctx.particle = particle;
+ ctx.parentParticle = parentParticle;
+ o = beforeSetParent.beforeSetParent(o, ctx);
+ ctx.clear();
+ }
+
+ if(parent instanceof ValueList /*&& !particle.getTerm().isSkip()*/)
+ {
+ if(parent == o)
+ {
+ return;
+ }
+ ValueList valueList = (ValueList)parent;
+ valueList.getInitializer().addTermValue(endName, particle, handler, valueList, o, parentParticle);
+ }
+ else
+ {
+ handler.setParent(parent, o, endName, particle, parentParticle);
+ }
+ }
+
+ private void push(QName qName, ParticleBinding particle, Object o, ParticleHandler handler)
+ {
+ StackItem item = new StackItem(particle, o, handler);
+ stack.push(item);
+ if(trace)
+ {
+ Object binding = null;
+ if(particle != null)
+ {
+ binding = particle.getTerm();
+ }
+ log.trace("pushed " + qName + "=" + o + ", binding=" + binding);
+ }
+ }
+
+ private void push(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+ {
+ StackItem item = new StackItem(cursor, o, handler);
+ stack.push(item);
+ if(trace)
+ {
+ log.trace("pushed cursor " + cursor + ", o=" + o);
+ }
+ }
+
+ private StackItem pop()
+ {
+ StackItem item = stack.pop();
+ if(trace)
+ {
+ if(item.cursor == null)
+ {
+ log.trace("poped " + ((ElementBinding)item.particle.getTerm()).getQName() + "=" + item.particle);
+ }
+ else
+ {
+ log.trace("poped " + item.cursor.getCurrentParticle().getTerm());
+ }
+ }
+ return item;
+ }
+
+ // Inner
+
+ private static class StackItem
+ {
+ final ModelGroupBinding.Cursor cursor;
+ ParticleBinding particle;
+ ParticleHandler handler;
+ boolean ignoreCharacters;
+ Object o;
+ ValueList repeatableParticleValue;
+ StringBuffer textContent;
+ Boolean indentation;
+ boolean ignorableCharacters = true;
+ boolean ended;
+
+ public StackItem(ModelGroupBinding.Cursor cursor, Object o, ParticleHandler handler)
+ {
+ if (cursor == null)
+ throw new IllegalArgumentException("Null cursor");
+ // this is modelgroup particle
+ this.cursor = cursor;
+ this.particle = cursor.getParticle();
+ this.o = o;
+ this.handler = handler;
+ }
+
+ public StackItem(ParticleBinding particle, Object o, ParticleHandler handler)
+ {
+ if (particle == null)
+ throw new IllegalArgumentException("Null particle");
+ // this is element particle
+ this.cursor = null;
+ this.particle = particle;
+ this.o = o;
+ this.handler = handler;
+ }
+
+ void reset()
+ {
+ if(!ended)
+ {
+ throw new JBossXBRuntimeException(
+ "Attempt to reset a particle that has already been reset: " + particle.getTerm()
+ );
+ }
+
+ ended = false;
+ o = null;
+ if(textContent != null)
+ {
+ textContent.delete(0, textContent.length());
+ }
+
+ indentation = null;
+ ignorableCharacters = true;
+ }
+ }
+
+ static class StackImpl
+ {
+ private List list = new ArrayList();
+
+ public void clear()
+ {
+ list.clear();
+ }
+
+ public void push(Object o)
+ {
+ list.add(o);
+ }
+
+ public StackItem pop()
+ {
+ return (StackItem)list.remove(list.size() - 1);
+ }
+
+ public ListIterator prevIterator()
+ {
+ return list.listIterator(list.size() - 1);
+ }
+
+ public StackItem peek()
+ {
+ return (StackItem)list.get(list.size() - 1);
+ }
+
+ public StackItem peek(int i)
+ {
+ return (StackItem)list.get(list.size() - 1 - i);
+ }
+
+ public boolean isEmpty()
+ {
+ return list.isEmpty();
+ }
+
+ public int size()
+ {
+ return list.size();
+ }
+ }
+
+ private class UnmarshallingContextImpl implements UnmarshallingContext
+ {
+ Object parent;
+ ParticleBinding particle;
+ ParticleBinding parentParticle;
+
+ public Object getParentValue()
+ {
+ return parent;
+ }
+
+ public ParticleBinding getParticle()
+ {
+ return particle;
+ }
+
+ public ParticleBinding getParentParticle()
+ {
+ return parentParticle;
+ }
+
+ public String resolvePropertyName()
+ {
+ TermBinding term = particle.getTerm();
+ PropertyMetaData propertyMetaData = term.getPropertyMetaData();
+ String prop = propertyMetaData == null ? null : propertyMetaData.getName();
+
+ if(prop != null)
+ {
+ return prop;
+ }
+
+ if(term.isElement())
+ {
+ QName name = ((ElementBinding)term).getQName();
+ prop = Util.xmlNameToFieldName(name.getLocalPart(), term.getSchema().isIgnoreLowLine());
+ }
+
+ return prop;
+ }
+
+ public Class resolvePropertyType()
+ {
+ if(parent == null)
+ {
+ return null;
+ }
+
+ String prop = resolvePropertyName();
+ if(prop != null)
+ {
+ FieldInfo fieldInfo = FieldInfo.getFieldInfo(parent.getClass(), prop, false);
+ if (fieldInfo != null)
+ {
+ return fieldInfo.getType();
+ }
+ }
+ return null;
+ }
+
+ // private
+
+ void clear()
+ {
+ ctx.parent = null;
+ ctx.particle = null;
+ ctx.parentParticle = null;
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,630 +0,0 @@
-/*
- * 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.xb.binding.sunday.unmarshalling;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
-import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
-import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
-import org.xml.sax.Attributes;
-import org.xml.sax.helpers.AttributesImpl;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class TypeBinding
-{
- protected QName qName;
- /** Map<QName, AttributeBinding> */
- private Map attrs = Collections.EMPTY_MAP;
- private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
- //private ParticleHandler handler = DefaultHandlers.ELEMENT_HANDLER;
- private CharactersHandler charactersHandler;
- private ClassMetaData classMetaData;
- private ValueMetaData valueMetaData;
- private PropertyMetaData propertyMetaData;
- private MapEntryMetaData mapEntryMetaData;
- private SchemaBinding schemaBinding; // todo it's optional for now...
- private TypeBinding baseType;
- private boolean skip;
- private CharactersMetaData charMetaData;
- private AddMethodMetaData addMethodMetaData;
- private ValueAdapter valueAdapter = ValueAdapter.NOOP;
- private TermBeforeMarshallingCallback beforeMarshallingCallback;
- private TermBeforeSetParentCallback beforeSetParentCallback;
- private Boolean startElementCreatesObject;
- private Boolean simple;
-
- private WildcardBinding wildcard;
- private ParticleBinding particle;
-
- private List patternValues;
- private List enumValues;
- private TypeBinding itemType; // the type is a list type with this item type
- private TypeBinding simpleType;
-
- private XOPUnmarshaller xopUnmarshaller;
- private XOPMarshaller xopMarshaller;
-
- public TypeBinding()
- {
- this.qName = null;
- }
-
- public TypeBinding(QName qName)
- {
- //this(qName, (CharactersHandler)null);
- this(qName, DefaultHandlers.CHARACTERS_HANDLER);
- }
-
- public TypeBinding(CharactersHandler charactersHandler)
- {
- this(null, charactersHandler);
- }
-
- public TypeBinding(QName qName, CharactersHandler charactersHandler)
- {
- this.qName = qName;
- this.charactersHandler = charactersHandler;
- }
-
- public TypeBinding(QName qName, TypeBinding baseType)
- {
- this(qName, baseType.charactersHandler);
-
- if(baseType.particle != null)
- {
- // todo
- this.particle = baseType.particle;
- }
-
- this.attrs = new HashMap(baseType.attrs);
- this.classMetaData = baseType.classMetaData;
- this.valueMetaData = baseType.valueMetaData;
- this.propertyMetaData = baseType.propertyMetaData;
- this.mapEntryMetaData = baseType.mapEntryMetaData;
- this.schemaBinding = baseType.schemaBinding;
- this.baseType = baseType;
-
- if(!baseType.isStartElementCreatesObject())
- {
- this.handler = baseType.handler;
- }
- }
-
- public QName getQName()
- {
- return qName;
- }
-
- public ElementBinding getElement(QName name)
- {
- return getElement(name, true);
- }
-
- private ElementBinding getElement(QName name, boolean ignoreWildcards)
- {
- ElementBinding element = null;
- if(particle != null)
- {
- ModelGroupBinding modelGroup = (ModelGroupBinding)particle.getTerm();
- element = modelGroup.newCursor(particle).getElement(name, null, ignoreWildcards);
- }
-
- if(element == null && !ignoreWildcards && wildcard != null)
- {
- element = wildcard.getElement(name, null);
- }
- return element;
- }
-
- public void addParticle(ParticleBinding particle)
- {
- ModelGroupBinding modelGroup;
- if(this.particle == null)
- {
- modelGroup = new AllBinding(schemaBinding);
- this.particle = new ParticleBinding(modelGroup);
- }
- else
- {
- modelGroup = (ModelGroupBinding)this.particle.getTerm();
- }
- modelGroup.addParticle(particle);
- }
-
- public void addElement(ElementBinding element)
- {
- addElement(element, 1, false);
- }
-
- public void addElement(ElementBinding element, int minOccurs, boolean unbounded)
- {
- ParticleBinding particle = new ParticleBinding(element);
- particle.setMinOccurs(minOccurs);
- particle.setMaxOccursUnbounded(unbounded);
- addParticle(particle);
- }
-
- public ElementBinding addElement(QName name, TypeBinding type)
- {
- return addElement(name, type, 1, false);
- }
-
- public ElementBinding addElement(QName name, TypeBinding type, int minOccurs, boolean unbounded)
- {
- ElementBinding el = new ElementBinding(schemaBinding, name, type);
- addElement(el, minOccurs, unbounded);
- return el;
- }
-
- public void addGroup(Map group)
- {
- for(Iterator i = group.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry entry = (Map.Entry)i.next();
- QName name = (QName)entry.getKey();
- TypeBinding type = (TypeBinding)entry.getValue();
- addElement(name, type);
- }
- }
-
- public AttributeBinding getAttribute(QName qName)
- {
- return (AttributeBinding)attrs.get(qName);
- }
-
- /**
- * Go through the type attributes to see if there are any with defaults
- * that do not appears in the attrs list.
- *
- * @param attrs - the attributes seen in the document
- * @return a possibly augmented list that includes unspecified attributes
- * with default values.
- */
- public Attributes expandWithDefaultAttributes(Attributes attrs)
- {
- if(this.attrs.size() == 0)
- {
- return attrs;
- }
-
- // Map<QName, AttributeBinding>
- HashMap attrsNotSeen = new HashMap(this.attrs);
- for(int n = 0; n < attrs.getLength(); n ++)
- {
- QName name = new QName(attrs.getURI(n), attrs.getLocalName(n));
- attrsNotSeen.remove(name);
- }
-
- Attributes expandedAttrs = attrs;
- if( attrsNotSeen.size() > 0 )
- {
- AttributesImpl tmp = new AttributesImpl(attrs);
- Iterator iter = attrsNotSeen.entrySet().iterator();
- while( iter.hasNext() )
- {
- Map.Entry entry = (Map.Entry) iter.next();
- QName name = (QName) entry.getKey();
- AttributeBinding binding = (AttributeBinding) entry.getValue();
- String constraint = binding.getDefaultConstraint();
- if( constraint != null )
- {
- // the Javadoc for Attributes.getType(i) says:
- // "The attribute type is one of the strings
- // "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
- // or "NOTATION" (always in upper case)."
- tmp.addAttribute(name.getNamespaceURI(), name.getLocalPart(),
- name.toString(), "CDATA", constraint);
- }
- }
- expandedAttrs = tmp;
- }
-
- return expandedAttrs;
- }
-
- public AttributeBinding addAttribute(QName name, TypeBinding type, AttributeHandler handler)
- {
- AttributeBinding attr = new AttributeBinding(schemaBinding, name, type, handler);
- addAttribute(attr);
- return attr;
- }
-
- public void addAttribute(AttributeBinding attr)
- {
- switch(attrs.size())
- {
- case 0:
- attrs = Collections.singletonMap(attr.getQName(), attr);
- break;
- case 1:
- attrs = new HashMap(attrs);
- default:
- attrs.put(attr.getQName(), attr);
- }
- }
-
- public Collection getAttributes()
- {
- return attrs.values();
- }
-
- public CharactersHandler getCharactersHandler()
- {
- return charactersHandler;
- }
-
- /**
- * This method will create a new simple type binding with the passed in characters handler
- * and set this simple type as the simple type of the complex type the method was invoked on.
- * @param charactersHandler
- */
- public void setSimpleType(CharactersHandler charactersHandler)
- {
- setSimpleType(new TypeBinding(charactersHandler));
- }
-
- public TypeBinding getSimpleType()
- {
- return simpleType;
- }
-
- public void setSimpleType(TypeBinding simpleType)
- {
- this.simpleType = simpleType;
- }
-
- public void setHandler(ParticleHandler handler)
- {
- this.handler = handler;
- }
-
- public ParticleHandler getHandler()
- {
- return handler;
- }
-
- public void pushInterceptor(QName qName, ElementInterceptor interceptor)
- {
- ElementBinding el = getElement(qName);
- if(el == null)
- {
- el = addElement(qName, new TypeBinding());
- }
- el.pushInterceptor(interceptor);
- }
-
- public TypeBinding getBaseType()
- {
- return baseType;
- }
-
- public void setBaseType(TypeBinding baseType)
- {
- this.baseType = baseType;
- }
-
- public boolean isSimple()
- {
- return simple == null ? particle == null && attrs.isEmpty() : simple.booleanValue();
- }
-
- public void setSimple(boolean simple)
- {
- this.simple = simple ? Boolean.TRUE : Boolean.FALSE;
- }
-
- public ClassMetaData getClassMetaData()
- {
- return classMetaData;
- }
-
- public void setClassMetaData(ClassMetaData classMetaData)
- {
- this.classMetaData = classMetaData;
- }
-
- public SchemaBinding getSchemaBinding()
- {
- return schemaBinding;
- }
-
- public void setSchemaBinding(SchemaBinding schemaBinding)
- {
- this.schemaBinding = schemaBinding;
- }
-
- public void setValueMetaData(ValueMetaData valueMetaData)
- {
- this.valueMetaData = valueMetaData;
- }
-
- public ValueMetaData getValueMetaData()
- {
- return valueMetaData;
- }
-
- public PropertyMetaData getPropertyMetaData()
- {
- return propertyMetaData;
- }
-
- public void setPropertyMetaData(PropertyMetaData propertyMetaData)
- {
- this.propertyMetaData = propertyMetaData;
- }
-
- public MapEntryMetaData getMapEntryMetaData()
- {
- return mapEntryMetaData;
- }
-
- public void setMapEntryMetaData(MapEntryMetaData mapEntryMetaData)
- {
- this.mapEntryMetaData = mapEntryMetaData;
- }
-
- public void setSkip(boolean skip)
- {
- this.skip = skip;
- }
-
- public boolean isSkip()
- {
- return skip;
- }
-
- public CharactersMetaData getCharactersMetaData()
- {
- return charMetaData;
- }
-
- public void setCharactersMetaData(CharactersMetaData charMetaData)
- {
- this.charMetaData = charMetaData;
- }
-
- public void setAddMethodMetaData(AddMethodMetaData addMethodMetaData)
- {
- this.addMethodMetaData = addMethodMetaData;
- }
-
- public AddMethodMetaData getAddMethodMetaData()
- {
- return addMethodMetaData;
- }
-
- public ValueAdapter getValueAdapter()
- {
- return valueAdapter;
- }
-
- public void setValueAdapter(ValueAdapter valueAdapter)
- {
- this.valueAdapter = valueAdapter;
- }
-
- public boolean isStartElementCreatesObject()
- {
- return startElementCreatesObject == null ?
- particle != null || !attrs.isEmpty() : startElementCreatesObject.booleanValue();
- }
-
- public void setStartElementCreatesObject(boolean startElementCreatesObject)
- {
- this.startElementCreatesObject = startElementCreatesObject ? Boolean.TRUE : Boolean.FALSE;
- }
-
- private boolean initializedWildcard;
- public WildcardBinding getWildcard()
- {
- if(initializedWildcard)
- {
- return wildcard;
- }
-
- if(particle != null)
- {
- wildcard = getWildcard(particle.getTerm());
- initializedWildcard = true;
- }
-
- return wildcard;
- }
-
- public ParticleBinding getParticle()
- {
- return particle;
- }
-
- public void setParticle(ParticleBinding particle)
- {
- this.particle = particle;
- }
-
- public List getLexicalPattern()
- {
- return patternValues;
- }
-
- public void addLexicalPattern(String patternValue)
- {
- if(patternValues == null)
- {
- patternValues = Collections.singletonList(patternValue);
- }
- else
- {
- if(patternValues.size() == 1)
- {
- patternValues = new ArrayList(patternValues);
- }
- patternValues.add(patternValue);
- }
- }
-
- public List getLexicalEnumeration()
- {
- return enumValues;
- }
-
- public void addEnumValue(String value)
- {
- if(enumValues == null)
- {
- enumValues = Collections.singletonList(value);
- }
- else
- {
- if(enumValues.size() == 1)
- {
- enumValues = new ArrayList(enumValues);
- }
- enumValues.add(value);
- }
- }
-
- public void setItemType(TypeBinding itemType)
- {
- this.itemType = itemType;
- }
-
- public TypeBinding getItemType()
- {
- return itemType;
- }
-
- public XOPUnmarshaller getXopUnmarshaller()
- {
- return xopUnmarshaller == null ?
- (schemaBinding == null ? null : schemaBinding.getXopUnmarshaller()) : xopUnmarshaller;
- }
-
- public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
- {
- this.xopUnmarshaller = xopUnmarshaller;
- }
-
- public XOPMarshaller getXopMarshaller()
- {
- return xopMarshaller == null ?
- (schemaBinding == null ? null : schemaBinding.getXopMarshaller()) : xopMarshaller;
- }
-
- public void setXopMarshaller(XOPMarshaller xopMarshaller)
- {
- this.xopMarshaller = xopMarshaller;
- }
-
- public boolean hasOnlyXmlMimeAttributes()
- {
- if(attrs.isEmpty())
- {
- return false;
- }
- else
- {
- Iterator iter = attrs.keySet().iterator();
- while(iter.hasNext())
- {
- QName qName = (QName)iter.next();
- if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
- {
- return false;
- }
- }
- }
- return true;
- }
-
- public void setBeforeMarshallingCallback(TermBeforeMarshallingCallback marshallingHandler)
- {
- this.beforeMarshallingCallback = marshallingHandler;
- }
-
- public TermBeforeMarshallingCallback getBeforeMarshallingCallback()
- {
- return beforeMarshallingCallback;
- }
-
- public void setBeforeSetParentCallback(TermBeforeSetParentCallback beforeSetParent)
- {
- this.beforeSetParentCallback = beforeSetParent;
- }
-
- public TermBeforeSetParentCallback getBeforeSetParentCallback()
- {
- return beforeSetParentCallback;
- }
-
- public String toString()
- {
- return super.toString() + "[" + qName + "]";
- }
-
- private static WildcardBinding getWildcard(TermBinding term)
- {
- if(term.isWildcard())
- {
- return (WildcardBinding) term;
- }
-
- if(term.isModelGroup())
- {
- ModelGroupBinding group = (ModelGroupBinding) term;
- for(Iterator i = group.getParticles().iterator(); i.hasNext();)
- {
- term = ((ParticleBinding)i.next()).getTerm();
- if(term.isWildcard())
- {
- return (WildcardBinding)term;
- }
- else if(term.isModelGroup())
- {
- WildcardBinding wc = getWildcard(term);
- if (wc != null)
- return wc;
- }
- }
- }
-
- return null;
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/TypeBinding.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,635 @@
+/*
+ * 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.xb.binding.sunday.unmarshalling;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.sunday.marshalling.TermBeforeMarshallingCallback;
+import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller;
+import org.jboss.xb.binding.sunday.xop.XOPMarshaller;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class TypeBinding
+{
+ protected QName qName;
+ /** Map<QName, AttributeBinding> */
+ private Map attrs = Collections.EMPTY_MAP;
+ private ParticleHandler handler;//todo default handler is now in SundayContentHandler.
+ //private ParticleHandler handler = DefaultHandlers.ELEMENT_HANDLER;
+ private CharactersHandler charactersHandler;
+ private ClassMetaData classMetaData;
+ private ValueMetaData valueMetaData;
+ private PropertyMetaData propertyMetaData;
+ private MapEntryMetaData mapEntryMetaData;
+ private SchemaBinding schemaBinding; // todo it's optional for now...
+ private TypeBinding baseType;
+ private boolean skip;
+ private CharactersMetaData charMetaData;
+ private AddMethodMetaData addMethodMetaData;
+ private ValueAdapter valueAdapter = ValueAdapter.NOOP;
+ private TermBeforeMarshallingCallback beforeMarshallingCallback;
+ private TermBeforeSetParentCallback beforeSetParentCallback;
+ private Boolean startElementCreatesObject;
+ private Boolean simple;
+
+ private WildcardBinding wildcard;
+ private ParticleBinding particle;
+
+ private List patternValues;
+ private List enumValues;
+ private TypeBinding itemType; // the type is a list type with this item type
+ private TypeBinding simpleType;
+
+ private XOPUnmarshaller xopUnmarshaller;
+ private XOPMarshaller xopMarshaller;
+
+ public TypeBinding()
+ {
+ this.qName = null;
+ }
+
+ public TypeBinding(QName qName)
+ {
+ //this(qName, (CharactersHandler)null);
+ this(qName, DefaultHandlers.CHARACTERS_HANDLER);
+ }
+
+ public TypeBinding(CharactersHandler charactersHandler)
+ {
+ this(null, charactersHandler);
+ }
+
+ public TypeBinding(QName qName, CharactersHandler charactersHandler)
+ {
+ this.qName = qName;
+ this.charactersHandler = charactersHandler;
+ }
+
+ public TypeBinding(QName qName, TypeBinding baseType)
+ {
+ this(qName, baseType.charactersHandler);
+
+ if(baseType.particle != null)
+ {
+ // todo
+ this.particle = baseType.particle;
+ }
+
+ this.attrs = new HashMap(baseType.attrs);
+ this.classMetaData = baseType.classMetaData;
+ this.valueMetaData = baseType.valueMetaData;
+ this.propertyMetaData = baseType.propertyMetaData;
+ this.mapEntryMetaData = baseType.mapEntryMetaData;
+ this.schemaBinding = baseType.schemaBinding;
+ this.baseType = baseType;
+
+ if(!baseType.isStartElementCreatesObject())
+ {
+ this.handler = baseType.handler;
+ }
+ }
+
+ public QName getQName()
+ {
+ return qName;
+ }
+
+ public ElementBinding getElement(QName name)
+ {
+ return getElement(name, true);
+ }
+
+ private ElementBinding getElement(QName name, boolean ignoreWildcards)
+ {
+ ElementBinding element = null;
+ if(particle != null)
+ {
+ ModelGroupBinding modelGroup = (ModelGroupBinding)particle.getTerm();
+ element = modelGroup.newCursor(particle).getElement(name, null, ignoreWildcards);
+ }
+
+ if(element == null && !ignoreWildcards && wildcard != null)
+ {
+ element = wildcard.getElement(name, null);
+ }
+ return element;
+ }
+
+ public void addParticle(ParticleBinding particle)
+ {
+ ModelGroupBinding modelGroup;
+ if(this.particle == null)
+ {
+ modelGroup = new AllBinding(schemaBinding);
+ this.particle = new ParticleBinding(modelGroup);
+ }
+ else
+ {
+ modelGroup = (ModelGroupBinding)this.particle.getTerm();
+ }
+ modelGroup.addParticle(particle);
+ }
+
+ public void addElement(ElementBinding element)
+ {
+ addElement(element, 1, false);
+ }
+
+ public void addElement(ElementBinding element, int minOccurs, boolean unbounded)
+ {
+ ParticleBinding particle = new ParticleBinding(element);
+ particle.setMinOccurs(minOccurs);
+ particle.setMaxOccursUnbounded(unbounded);
+ addParticle(particle);
+ }
+
+ public ElementBinding addElement(QName name, TypeBinding type)
+ {
+ return addElement(name, type, 1, false);
+ }
+
+ public ElementBinding addElement(QName name, TypeBinding type, int minOccurs, boolean unbounded)
+ {
+ ElementBinding el = new ElementBinding(schemaBinding, name, type);
+ addElement(el, minOccurs, unbounded);
+ return el;
+ }
+
+ public void addGroup(Map group)
+ {
+ for(Iterator i = group.entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ QName name = (QName)entry.getKey();
+ TypeBinding type = (TypeBinding)entry.getValue();
+ addElement(name, type);
+ }
+ }
+
+ public AttributeBinding getAttribute(QName qName)
+ {
+ return (AttributeBinding)attrs.get(qName);
+ }
+
+ /**
+ * Go through the type attributes to see if there are any with defaults
+ * that do not appears in the attrs list.
+ *
+ * @param attrs - the attributes seen in the document
+ * @return a possibly augmented list that includes unspecified attributes
+ * with default values.
+ */
+ public Attributes expandWithDefaultAttributes(Attributes attrs)
+ {
+ if(this.attrs.size() == 0)
+ {
+ return attrs;
+ }
+
+ // Map<QName, AttributeBinding>
+ HashMap attrsNotSeen = new HashMap(this.attrs);
+ for(int n = 0; n < attrs.getLength(); n ++)
+ {
+ QName name = new QName(attrs.getURI(n), attrs.getLocalName(n));
+ attrsNotSeen.remove(name);
+ }
+
+ Attributes expandedAttrs = attrs;
+ if( attrsNotSeen.size() > 0 )
+ {
+ AttributesImpl tmp = new AttributesImpl(attrs);
+ Iterator iter = attrsNotSeen.entrySet().iterator();
+ while( iter.hasNext() )
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ QName name = (QName) entry.getKey();
+ AttributeBinding binding = (AttributeBinding) entry.getValue();
+ String constraint = binding.getDefaultConstraint();
+ if( constraint != null )
+ {
+ // the Javadoc for Attributes.getType(i) says:
+ // "The attribute type is one of the strings
+ // "CDATA", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES",
+ // or "NOTATION" (always in upper case)."
+ tmp.addAttribute(name.getNamespaceURI(), name.getLocalPart(),
+ name.toString(), "CDATA", constraint);
+ }
+ }
+ expandedAttrs = tmp;
+ }
+
+ return expandedAttrs;
+ }
+
+ public AttributeBinding addAttribute(QName name, TypeBinding type, AttributeHandler handler)
+ {
+ AttributeBinding attr = new AttributeBinding(schemaBinding, name, type, handler);
+ addAttribute(attr);
+ return attr;
+ }
+
+ public void addAttribute(AttributeBinding attr)
+ {
+ switch(attrs.size())
+ {
+ case 0:
+ attrs = Collections.singletonMap(attr.getQName(), attr);
+ break;
+ case 1:
+ attrs = new HashMap(attrs);
+ default:
+ attrs.put(attr.getQName(), attr);
+ }
+ }
+
+ public Collection getAttributes()
+ {
+ return attrs.values();
+ }
+
+ public CharactersHandler getCharactersHandler()
+ {
+ return charactersHandler;
+ }
+
+ /**
+ * This method will create a new simple type binding with the passed in characters handler
+ * and set this simple type as the simple type of the complex type the method was invoked on.
+ * @param charactersHandler
+ */
+ public void setSimpleType(CharactersHandler charactersHandler)
+ {
+ setSimpleType(new TypeBinding(charactersHandler));
+ }
+
+ public TypeBinding getSimpleType()
+ {
+ return simpleType;
+ }
+
+ public void setSimpleType(TypeBinding simpleType)
+ {
+ this.simpleType = simpleType;
+ }
+
+ public void setHandler(ParticleHandler handler)
+ {
+ this.handler = handler;
+ }
+
+ public ParticleHandler getHandler()
+ {
+ return handler;
+ }
+
+ public void pushInterceptor(QName qName, ElementInterceptor interceptor)
+ {
+ ElementBinding el = getElement(qName);
+ if(el == null)
+ {
+ el = addElement(qName, new TypeBinding());
+ }
+ el.pushInterceptor(interceptor);
+ }
+
+ public TypeBinding getBaseType()
+ {
+ return baseType;
+ }
+
+ public void setBaseType(TypeBinding baseType)
+ {
+ this.baseType = baseType;
+ }
+
+ public boolean isSimple()
+ {
+ return simple == null ? particle == null && attrs.isEmpty() : simple.booleanValue();
+ }
+
+ public void setSimple(boolean simple)
+ {
+ this.simple = simple ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public boolean isTextContentAllowed()
+ {
+ return simpleType != null || isSimple();
+ }
+
+ public ClassMetaData getClassMetaData()
+ {
+ return classMetaData;
+ }
+
+ public void setClassMetaData(ClassMetaData classMetaData)
+ {
+ this.classMetaData = classMetaData;
+ }
+
+ public SchemaBinding getSchemaBinding()
+ {
+ return schemaBinding;
+ }
+
+ public void setSchemaBinding(SchemaBinding schemaBinding)
+ {
+ this.schemaBinding = schemaBinding;
+ }
+
+ public void setValueMetaData(ValueMetaData valueMetaData)
+ {
+ this.valueMetaData = valueMetaData;
+ }
+
+ public ValueMetaData getValueMetaData()
+ {
+ return valueMetaData;
+ }
+
+ public PropertyMetaData getPropertyMetaData()
+ {
+ return propertyMetaData;
+ }
+
+ public void setPropertyMetaData(PropertyMetaData propertyMetaData)
+ {
+ this.propertyMetaData = propertyMetaData;
+ }
+
+ public MapEntryMetaData getMapEntryMetaData()
+ {
+ return mapEntryMetaData;
+ }
+
+ public void setMapEntryMetaData(MapEntryMetaData mapEntryMetaData)
+ {
+ this.mapEntryMetaData = mapEntryMetaData;
+ }
+
+ public void setSkip(boolean skip)
+ {
+ this.skip = skip;
+ }
+
+ public boolean isSkip()
+ {
+ return skip;
+ }
+
+ public CharactersMetaData getCharactersMetaData()
+ {
+ return charMetaData;
+ }
+
+ public void setCharactersMetaData(CharactersMetaData charMetaData)
+ {
+ this.charMetaData = charMetaData;
+ }
+
+ public void setAddMethodMetaData(AddMethodMetaData addMethodMetaData)
+ {
+ this.addMethodMetaData = addMethodMetaData;
+ }
+
+ public AddMethodMetaData getAddMethodMetaData()
+ {
+ return addMethodMetaData;
+ }
+
+ public ValueAdapter getValueAdapter()
+ {
+ return valueAdapter;
+ }
+
+ public void setValueAdapter(ValueAdapter valueAdapter)
+ {
+ this.valueAdapter = valueAdapter;
+ }
+
+ public boolean isStartElementCreatesObject()
+ {
+ return startElementCreatesObject == null ?
+ particle != null || !attrs.isEmpty() : startElementCreatesObject.booleanValue();
+ }
+
+ public void setStartElementCreatesObject(boolean startElementCreatesObject)
+ {
+ this.startElementCreatesObject = startElementCreatesObject ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ private boolean initializedWildcard;
+ public WildcardBinding getWildcard()
+ {
+ if(initializedWildcard)
+ {
+ return wildcard;
+ }
+
+ if(particle != null)
+ {
+ wildcard = getWildcard(particle.getTerm());
+ initializedWildcard = true;
+ }
+
+ return wildcard;
+ }
+
+ public ParticleBinding getParticle()
+ {
+ return particle;
+ }
+
+ public void setParticle(ParticleBinding particle)
+ {
+ this.particle = particle;
+ }
+
+ public List getLexicalPattern()
+ {
+ return patternValues;
+ }
+
+ public void addLexicalPattern(String patternValue)
+ {
+ if(patternValues == null)
+ {
+ patternValues = Collections.singletonList(patternValue);
+ }
+ else
+ {
+ if(patternValues.size() == 1)
+ {
+ patternValues = new ArrayList(patternValues);
+ }
+ patternValues.add(patternValue);
+ }
+ }
+
+ public List getLexicalEnumeration()
+ {
+ return enumValues;
+ }
+
+ public void addEnumValue(String value)
+ {
+ if(enumValues == null)
+ {
+ enumValues = Collections.singletonList(value);
+ }
+ else
+ {
+ if(enumValues.size() == 1)
+ {
+ enumValues = new ArrayList(enumValues);
+ }
+ enumValues.add(value);
+ }
+ }
+
+ public void setItemType(TypeBinding itemType)
+ {
+ this.itemType = itemType;
+ }
+
+ public TypeBinding getItemType()
+ {
+ return itemType;
+ }
+
+ public XOPUnmarshaller getXopUnmarshaller()
+ {
+ return xopUnmarshaller == null ?
+ (schemaBinding == null ? null : schemaBinding.getXopUnmarshaller()) : xopUnmarshaller;
+ }
+
+ public void setXopUnmarshaller(XOPUnmarshaller xopUnmarshaller)
+ {
+ this.xopUnmarshaller = xopUnmarshaller;
+ }
+
+ public XOPMarshaller getXopMarshaller()
+ {
+ return xopMarshaller == null ?
+ (schemaBinding == null ? null : schemaBinding.getXopMarshaller()) : xopMarshaller;
+ }
+
+ public void setXopMarshaller(XOPMarshaller xopMarshaller)
+ {
+ this.xopMarshaller = xopMarshaller;
+ }
+
+ public boolean hasOnlyXmlMimeAttributes()
+ {
+ if(attrs.isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ Iterator iter = attrs.keySet().iterator();
+ while(iter.hasNext())
+ {
+ QName qName = (QName)iter.next();
+ if(!Constants.NS_XML_MIME.equals(qName.getNamespaceURI()))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void setBeforeMarshallingCallback(TermBeforeMarshallingCallback marshallingHandler)
+ {
+ this.beforeMarshallingCallback = marshallingHandler;
+ }
+
+ public TermBeforeMarshallingCallback getBeforeMarshallingCallback()
+ {
+ return beforeMarshallingCallback;
+ }
+
+ public void setBeforeSetParentCallback(TermBeforeSetParentCallback beforeSetParent)
+ {
+ this.beforeSetParentCallback = beforeSetParent;
+ }
+
+ public TermBeforeSetParentCallback getBeforeSetParentCallback()
+ {
+ return beforeSetParentCallback;
+ }
+
+ public String toString()
+ {
+ return super.toString() + "[" + qName + "]";
+ }
+
+ private static WildcardBinding getWildcard(TermBinding term)
+ {
+ if(term.isWildcard())
+ {
+ return (WildcardBinding) term;
+ }
+
+ if(term.isModelGroup())
+ {
+ ModelGroupBinding group = (ModelGroupBinding) term;
+ for(Iterator i = group.getParticles().iterator(); i.hasNext();)
+ {
+ term = ((ParticleBinding)i.next()).getTerm();
+ if(term.isWildcard())
+ {
+ return (WildcardBinding)term;
+ }
+ else if(term.isModelGroup())
+ {
+ WildcardBinding wc = getWildcard(term);
+ if (wc != null)
+ return wc;
+ }
+ }
+ }
+
+ return null;
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1521 +0,0 @@
-/*
- * 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.xb.binding.sunday.unmarshalling;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.ListIterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-
-import javax.xml.namespace.QName;
-
-import org.apache.xerces.xs.StringList;
-import org.apache.xerces.xs.XSAnnotation;
-import org.apache.xerces.xs.XSAttributeDeclaration;
-import org.apache.xerces.xs.XSAttributeUse;
-import org.apache.xerces.xs.XSComplexTypeDefinition;
-import org.apache.xerces.xs.XSConstants;
-import org.apache.xerces.xs.XSElementDeclaration;
-import org.apache.xerces.xs.XSModel;
-import org.apache.xerces.xs.XSModelGroup;
-import org.apache.xerces.xs.XSModelGroupDefinition;
-import org.apache.xerces.xs.XSNamedMap;
-import org.apache.xerces.xs.XSObjectList;
-import org.apache.xerces.xs.XSParticle;
-import org.apache.xerces.xs.XSSimpleTypeDefinition;
-import org.apache.xerces.xs.XSTerm;
-import org.apache.xerces.xs.XSTypeDefinition;
-import org.apache.xerces.xs.XSWildcard;
-import org.jboss.logging.Logger;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.CharactersMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.PutMethodMetaData;
-import org.jboss.xb.binding.metadata.SchemaMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.metadata.XsdAnnotation;
-import org.jboss.xb.binding.metadata.XsdAppInfo;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class XsdBinder
-{
- static final Logger log = Logger.getLogger(XsdBinder.class);
-
- /**
- * Creates a new instance of the binder the user can use to tune
- * configuration before parsing the XSD.
- *
- * @return a new instance of the XsdBinder
- */
- public static XsdBinder newInstance()
- {
- return new XsdBinder();
- }
-
- /**
- * Create a SchemaBinding from and xsd url/uri.
- *
- * @param xsdUrl
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(String xsdUrl)
- {
- DefaultSchemaResolver resolver = new DefaultSchemaResolver();
- resolver.setBaseURI(xsdUrl);
- return bind(xsdUrl, resolver);
- }
-
- /**
- * Create a SchemaBinding from and xsd url/uri.
- *
- * @param xsdUrl
- * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
- * and also will be set on the returned instance of SchemaBinding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(String xsdUrl, SchemaBindingResolver resolver)
- {
- XSModel model = Util.loadSchema(xsdUrl, resolver);
- return bind(model, resolver);
- }
-
- public static SchemaBinding bind(InputStream xsdStream, String encoding)
- {
- return bind(xsdStream, encoding, new DefaultSchemaResolver());
- }
-
- /**
- * Create a SchemaBinding from and xsd stream.
- *
- * @param xsdStream - the xsd InputStream
- * @param encoding - optional stream encoding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI)
- {
- return bind(xsdStream, encoding, baseURI, true);
- }
-
- /**
- * Create a SchemaBinding from and xsd stream.
- *
- * @param xsdStream - the xsd InputStream
- * @param encoding - optional stream encoding
- * @param processAnnotations - process annotations
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI, boolean processAnnotations)
- {
- DefaultSchemaResolver resolver = new DefaultSchemaResolver();
- resolver.setBaseURI(baseURI);
- return bind(xsdStream, encoding, resolver, processAnnotations);
- }
-
- /**
- * Create a SchemaBinding from and xsd stream.
- *
- * @param xsdStream - the xsd InputStream
- * @param encoding - optional stream encoding
- * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
- * and also will be set on the returned instance of SchemaBinding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver)
- {
- return bind(xsdStream, encoding, resolver, true);
- }
-
- /**
- * Create a SchemaBinding from and xsd stream.
- *
- * @param xsdStream - the xsd InputStream
- * @param encoding - optional stream encoding
- * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
- * and also will be set on the returned instance of SchemaBinding
- * @param processAnnotations whether to process annotations
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver, boolean processAnnotations)
- {
- XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
- return bind(model, resolver, processAnnotations);
- }
-
- public static SchemaBinding bind(Reader xsdReader, String encoding)
- {
- return bind(xsdReader, encoding, new DefaultSchemaResolver());
- }
-
- /**
- * Create a SchemaBinding from and xsd reader.
- *
- * @param xsdReader - xsd reader
- * @param encoding - optional reader encoding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(Reader xsdReader, String encoding, String baseURI)
- {
- DefaultSchemaResolver resolver = new DefaultSchemaResolver();
- resolver.setBaseURI(baseURI);
- return bind(xsdReader, encoding, resolver);
- }
-
- /**
- * Create a SchemaBinding from and xsd reader.
- *
- * @param xsdReader - xsd reader
- * @param encoding - optional reader encoding
- * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
- * and also will be set on the returned instance of SchemaBinding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(Reader xsdReader, String encoding, SchemaBindingResolver resolver)
- {
- XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
- return bind(model, resolver);
- }
-
- /**
- * Create a SchemaBinding from and xsd string.
- *
- * @param xsd - xsd string
- * @param encoding - optional string encoding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(String xsd, String encoding)
- {
- return bind(xsd, encoding, new DefaultSchemaResolver());
- }
-
- /**
- * Create a SchemaBinding from and xsd string.
- *
- * @param xsd - xsd string
- * @param encoding - optional string encoding
- * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
- * and also will be set on the returned instance of SchemaBinding
- * @return SchemaBinding mapping
- */
- public static SchemaBinding bind(String xsd, String encoding, SchemaBindingResolver resolver)
- {
- XSModel model = Util.loadSchema(xsd, encoding);
- return bind(model, resolver);
- }
-
- public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver)
- {
- return bind(model,resolver, true);
- }
-
- public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver, boolean processAnnotations)
- {
- XsdBinder binder = new XsdBinder();
- binder.setProcessAnnotations(processAnnotations);
- binder.setSchemaResolver(resolver);
- return binder.parse(model);
- }
-
- /**
- * @param schema schema binding the type should be added to
- * @param type type definition to be bound
- * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
- * It will be removed when anonymous type binding in JBossWS is implemented properly.
- * No one else should use this method.</i>
- *
- * <p>This method binds a type definition and adds it as a global type to the passed in schema binding.
- */
- public static void bindType(SchemaBinding schema, XSTypeDefinition type)
- {
- TypeBinding typeBinding = bindType(new Context(schema), type);
- schema.addType(typeBinding);
- }
-
- /**
- * @param schema schema binding the type should be added to
- * @param element element declaration to be bound
- * @param minOccurs
- * @param maxOccurs
- * @param maxOccursUnbounded
- * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
- * It will be removed when anonymous type binding in JBossWS is implemented properly.
- * No one else should use this method.</i>
- *
- * <p>This method binds an element declaration and adds it as a global element to the passed in schema binding.
- */
- public static void bindElement(SchemaBinding schema,
- XSElementDeclaration element,
- int minOccurs,
- int maxOccurs,
- boolean maxOccursUnbounded)
- {
- ParticleBinding particle = bindElement(new Context(schema),
- element,
- minOccurs,
- maxOccurs,
- maxOccursUnbounded
- );
- schema.addElementParticle(particle);
- }
-
- // Exposed attributes
-
- private boolean processAnnotations = true;
- private SchemaBindingResolver resolver;
- private boolean simpleContentWithIdAsSimpleType = true;
- private boolean unresolvedContentBoundToDOM = true;
-
- // Internal attributes
-
- private boolean trace = log.isTraceEnabled();
- private final SchemaBinding schema;
- private SharedElements sharedElements = new SharedElements();
- private final List typeGroupStack = new ArrayList();
-
- // Ctors
-
- private XsdBinder()
- {
- this(new SchemaBinding());
- }
-
- private XsdBinder(SchemaBinding schema)
- {
- this.schema = schema;
- }
-
- // Public
-
- public void setProcessAnnotations(boolean processAnnotations)
- {
- this.processAnnotations = processAnnotations;
- }
-
- public boolean isProcessAnnotations()
- {
- return processAnnotations;
- }
-
- public void setSchemaResolver(SchemaBindingResolver resolver)
- {
- this.resolver = resolver;
- }
-
- public SchemaBindingResolver getSchemaResolver()
- {
- return resolver;
- }
-
- public void setSimpleContentWithIdAsSimpleType(boolean simpleContentWithIdAsSimpleType)
- {
- this.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
- }
-
- public boolean isSimpleContentWithIdAsSimpleType()
- {
- return simpleContentWithIdAsSimpleType;
- }
-
- public void setUnresolvedContentBoundToDOM(boolean toDOM)
- {
- this.unresolvedContentBoundToDOM = toDOM;
- }
-
- public boolean isUnresolvedContentBoundToDOM()
- {
- return this.unresolvedContentBoundToDOM;
- }
-
- public SchemaBinding parse(String xsdUrl)
- {
- if(resolver == null)
- {
- resolver = new DefaultSchemaResolver();
- }
-
- XSModel model = Util.loadSchema(xsdUrl, resolver);
- return parse(model);
- }
-
- public SchemaBinding parse(InputStream xsdStream, String encoding)
- {
- if(resolver == null)
- {
- resolver = new DefaultSchemaResolver();
- }
-
- XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
- return parse(model);
- }
-
- public SchemaBinding parse(Reader xsdReader, String encoding)
- {
- if(resolver == null)
- {
- resolver = new DefaultSchemaResolver();
- }
-
- XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
- return parse(model);
- }
-
-
- // Private
-
- public SchemaBinding parse(XSModel model)
- {
- Context ctx = new Context();
- ctx.processAnnotations = processAnnotations;
- SchemaBinding schema = ctx.schema;
- schema.setSchemaResolver(resolver);
-
- // read annotations. for now just log the ones that are going to be used
- if (ctx.processAnnotations)
- {
- XSObjectList annotations = model.getAnnotations();
- if (ctx.trace)
- {
- log.trace("started binding schema " + schema);
- log.trace("Schema annotations: " + annotations.getLength());
- }
-
- for(int i = 0; i < annotations.getLength(); ++i)
- {
- XSAnnotation annotation = (XSAnnotation)annotations.item(i);
- XsdAnnotation an = XsdAnnotation.unmarshal(annotation.getAnnotationString());
- XsdAppInfo appinfo = an.getAppInfo();
- if(appinfo != null)
- {
- SchemaMetaData schemaBindings = appinfo.getSchemaMetaData();
- if(schemaBindings != null)
- {
- // Get the ignoreUnresolvedFieldOrClass
- schema.setIgnoreUnresolvedFieldOrClass(schemaBindings.isIgnoreUnresolvedFieldOrClass());
- // Get the ignoreUnresolvedFieldOrClass
- schema.setReplacePropertyRefs(schemaBindings.isReplacePropertyRefs());
- // Get the default package
- PackageMetaData packageMetaData = schemaBindings.getPackage();
- if(packageMetaData != null)
- {
- if (ctx.trace)
- log.trace("schema default package: " + packageMetaData.getName());
- schema.setPackageMetaData(packageMetaData);
- }
- }
- }
- }
- }
-
- StringList namespaceList = model.getNamespaces();
- Set namespaces = new LinkedHashSet(namespaceList.getLength());
- for (int i = 0; i < namespaceList.getLength(); ++i)
- namespaces.add(namespaceList.item(i));
- schema.setNamespaces(namespaces);
-
- XSNamedMap groups = model.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
- if (ctx.trace)
- log.trace("Model groups: " + groups.getLength());
- for(int i = 0; i < groups.getLength(); ++i)
- {
- XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
- bindGlobalGroup(groupDef.getModelGroup(), ctx.sharedElements);
- }
-
- XSNamedMap types = model.getComponents(XSConstants.TYPE_DEFINITION);
- if (ctx.trace)
- log.trace("Model types: " + types.getLength());
- for(int i = 0; i < types.getLength(); ++i)
- {
- XSTypeDefinition type = (XSTypeDefinition)types.item(i);
- if(!Constants.NS_XML_SCHEMA.equals(type.getNamespace()))
- {
- bindType(ctx, type);
- }
- }
-
- XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
- if (ctx.trace)
- log.trace("Model elements: " + types.getLength());
- for(int i = 0; i < elements.getLength(); ++i)
- {
- XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
- bindElement(ctx, element, 1, 0, false);
- }
-
- schema.setUnresolvedContentBoundToDOM(true);
-
- if (ctx.trace)
- {
- log.trace("finished binding schema " + schema);
- }
-
- return schema;
- }
-
- private static TypeBinding bindType(Context ctx, XSTypeDefinition type)
- {
- TypeBinding binding;
- switch(type.getTypeCategory())
- {
- case XSTypeDefinition.SIMPLE_TYPE:
- binding = bindSimpleType(ctx, (XSSimpleTypeDefinition)type);
- break;
- case XSTypeDefinition.COMPLEX_TYPE:
- binding = bindComplexType(ctx, (XSComplexTypeDefinition)type);
- break;
- default:
- throw new JBossXBRuntimeException("Unexpected type category: " + type.getTypeCategory());
- }
- return binding;
- }
-
- private static TypeBinding bindSimpleType(Context ctx, XSSimpleTypeDefinition type)
- {
- QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
- TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
- if(binding != null)
- {
- return binding;
- }
-
- if(ctx.trace)
- {
- log.trace("binding simple type " + typeName);
- }
-
- XSTypeDefinition baseTypeDef = type.getBaseType();
- TypeBinding baseType = baseTypeDef == null ? null : bindType(ctx, baseTypeDef);
-
- binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeName, baseType);
-
- StringList strList = type.getLexicalPattern();
- if(strList != null && strList.getLength() > 0)
- {
- for(int i = 0; i < strList.getLength(); ++i)
- {
- binding.addLexicalPattern(strList.item(i));
- }
- }
-
- strList = type.getLexicalEnumeration();
- if(strList != null && strList.getLength() > 0)
- {
- for(int i = 0; i < strList.getLength(); ++i)
- {
- binding.addEnumValue(strList.item(i));
- }
- }
-
- if(type.getItemType() != null)
- {
- TypeBinding itemType = bindSimpleType(ctx, type.getItemType());
- binding.setItemType(itemType);
- }
-
- if(typeName != null)
- {
- ctx.schema.addType(binding);
- }
-
- if(ctx.trace)
- {
- String msg = typeName == null ? "bound simple anonymous type" : "bound simple type " + typeName;
- if(baseType != null)
- {
- msg += " inherited binding metadata from " + baseType.getQName();
- }
- log.trace(msg);
- }
-
- // customize binding with annotations
- if(ctx.processAnnotations)
- {
- XSObjectList annotations = type.getAnnotations();
- if(annotations != null)
- {
- if(ctx.trace)
- {
- log.trace(typeName + " annotations " + annotations.getLength());
- }
- for(int i = 0; i < annotations.getLength(); ++i)
- {
- XSAnnotation an = (XSAnnotation)annotations.item(i);
- XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
- XsdAppInfo appInfo = xsdAn.getAppInfo();
- if(appInfo != null)
- {
- ClassMetaData classMetaData = appInfo.getClassMetaData();
- if(classMetaData != null)
- {
- if(ctx.trace)
- {
- log.trace("simple type " +
- type.getName() +
- ": impl=" +
- classMetaData.getImpl());
- }
- binding.setClassMetaData(classMetaData);
- }
-
- ValueMetaData valueMetaData = appInfo.getValueMetaData();
- if(valueMetaData != null)
- {
- if(ctx.trace)
- {
- log.trace("simple type " +
- type.getName() +
- ": unmarshalMethod=" +
- valueMetaData.getUnmarshalMethod() +
- ", marshalMethod=" +
- valueMetaData.getMarshalMethod());
- }
- binding.setValueMetaData(valueMetaData);
- }
- }
- }
- }
- }
-
- binding.setSchemaBinding(ctx.schema);
-
- return binding;
- }
-
- private static TypeBinding bindComplexType(Context ctx, XSComplexTypeDefinition type)
- {
- QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
- TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
- if(binding != null)
- {
- return binding;
- }
-
- XSTypeDefinition baseTypeDef = type.getBaseType();
- // anyType is the parent of all the types, even the parent of itself according to xerces :)
- TypeBinding baseType = null;
- if(baseTypeDef != null && !Constants.QNAME_ANYTYPE.equals(typeName))
- {
- baseType = bindType(ctx, baseTypeDef);
- // sometimes binding the base type can lead to another request
- // to bind the type being bound here
- if(typeName != null)
- {
- binding = ctx.schema.getType(typeName);
- if(binding != null)
- {
- return binding;
- }
- }
- }
-
- if (ctx.trace)
- log.trace("binding complex " + (typeName == null ? "anonymous type" : "type " + typeName));
-
- binding = new TypeBinding(typeName);
- binding.setBaseType(baseType);
- binding.setStartElementCreatesObject(true);
- binding.setSimple(false);
-
- if(type.getSimpleType() != null)
- {
- TypeBinding simpleType = bindSimpleType(ctx, type.getSimpleType());
- binding.setSimpleType(simpleType);
- }
- else if(type.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED)
- {
- TypeBinding stringType = ctx.schema.getType(Constants.QNAME_STRING);
- if(stringType == null)
- {
- throw new JBossXBRuntimeException("xsd:string has not been bound yet!");
- }
- binding.setSimpleType(stringType);
- }
-
- if(typeName != null)
- {
- ctx.schema.addType(binding);
- }
-
- binding.setSchemaBinding(ctx.schema);
-
- XSObjectList attrs = type.getAttributeUses();
- if (ctx.trace)
- log.trace(typeName + " attributes " + attrs.getLength());
- for(int i = 0; i < attrs.getLength(); ++i)
- {
- XSAttributeUse attr = (XSAttributeUse)attrs.item(i);
- bindAttributes(ctx, binding, attr);
- }
-
- // customize binding with xsd annotations
- if (ctx.processAnnotations)
- {
- XSObjectList annotations = type.getAnnotations();
- if(annotations != null)
- {
- if (ctx.trace)
- log.trace(typeName + " annotations " + annotations.getLength());
- for(int i = 0; i < annotations.getLength(); ++i)
- {
- XSAnnotation an = (XSAnnotation)annotations.item(i);
- XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
- XsdAppInfo appInfo = xsdAn.getAppInfo();
- if(appInfo != null)
- {
- ClassMetaData classMetaData = appInfo.getClassMetaData();
- if(classMetaData != null)
- {
- if (ctx.trace)
- {
- log.trace("complex type " +
- type.getName() +
- ": impl=" +
- classMetaData.getImpl()
- );
- }
- binding.setClassMetaData(classMetaData);
- }
-
- CharactersMetaData charactersMetaData = appInfo.getCharactersMetaData();
- if(charactersMetaData != null)
- {
- if (ctx.trace)
- {
- PropertyMetaData propertyMetaData = charactersMetaData.getProperty();
- if(propertyMetaData != null)
- {
- log.trace("complex type " +
- type.getName() +
- ": characters bound to " + propertyMetaData.getName()
- );
- }
-
- ValueMetaData valueMetaData = charactersMetaData.getValue();
- if(valueMetaData != null)
- {
- log.trace("complex type " +
- type.getName() +
- ": characters unmarshalMethod=" +
- valueMetaData.getUnmarshalMethod() +
- ", marshalMethod=" + valueMetaData.getMarshalMethod()
- );
- }
-
- boolean mapEntryKey = appInfo.isMapEntryKey();
- if(mapEntryKey)
- {
- log.trace("complex type " +
- type.getName() +
- ": characters are bound as a key in a map entry"
- );
- }
-
- boolean mapEntryValue = appInfo.isMapEntryValue();
- if(mapEntryValue)
- {
- log.trace("complex type " +
- type.getName() +
- ": characters are bound as a value in a map entry"
- );
- }
- }
- binding.setCharactersMetaData(charactersMetaData);
- }
-
- MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
- if(mapEntryMetaData != null)
- {
- if (ctx.trace)
- {
- log.trace("complex type " +
- type.getName() +
- " is bound to a map entry: impl=" +
- mapEntryMetaData.getImpl() +
- ", getKeyMethod=" +
- mapEntryMetaData.getGetKeyMethod() +
- ", setKeyMethod=" +
- mapEntryMetaData.getSetKeyMethod() +
- ", getValueMethod=" +
- mapEntryMetaData.getGetValueMethod() +
- ", setValueMethod=" +
- mapEntryMetaData.getSetValueMethod() +
- ", valueType=" +
- mapEntryMetaData.getValueType() +
- ", nonNullValue=" + mapEntryMetaData.isNonNullValue()
- );
- }
-
- if(classMetaData != null)
- {
- throw new JBossXBRuntimeException("Illegal binding: both jbxb:class and jbxb:mapEntry are specified for complex type " +
- type.getName()
- );
- }
- binding.setMapEntryMetaData(mapEntryMetaData);
- }
-
- boolean skip = appInfo.isSkip();
- if(skip)
- {
- if (ctx.trace)
- {
- log.trace("complex type " +
- type.getName() +
- ": elements of this type will be skipped; their attrs, character content " +
- "and elements will be set the parent."
- );
- }
- binding.setSkip(skip);
- }
-
- PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
- if(propertyMetaData != null)
- {
- if (ctx.trace)
- {
- log.trace("complex type " +
- type.getName() +
- ": the content of elements of this type is bound to property " + propertyMetaData.getName()
- );
- }
- binding.setPropertyMetaData(propertyMetaData);
- }
-
- AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
- if(addMethodMetaData != null)
- {
- if (ctx.trace)
- {
- log.trace("complex type " +
- type.getName() +
- ": elements of this type will be added to parent objects with addMethod=" +
- addMethodMetaData.getMethodName() + ", valueType=" + addMethodMetaData.getValueType()
- );
- }
- binding.setAddMethodMetaData(addMethodMetaData);
- }
- }
- }
- }
- }
-
- XSParticle particle = type.getParticle();
- if(particle != null)
- {
- ctx.pushType(binding);
- bindParticle(ctx, particle);
- ctx.popType();
- }
-
- if(binding.hasOnlyXmlMimeAttributes())
- {
- addXOPInclude(binding, ctx.schema);
- }
-
- if(ctx.trace)
- {
- log.trace(typeName == null ? "bound complex anonymous type" : "bound complex type " + typeName);
- }
-
- return binding;
- }
-
- private static void bindAttributes(Context ctx, TypeBinding type, XSAttributeUse attrUse)
- {
- XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
- QName attrName = new QName(attr.getNamespace(), attr.getName());
-
- if (ctx.trace)
- {
- log.trace("binding attribute " + attrName + " for " + type.getQName() + ", required=" + attrUse.getRequired());
- }
-
- XSSimpleTypeDefinition attrType = attr.getTypeDefinition();
- TypeBinding typeBinding = bindSimpleType(ctx, attrType);
- AttributeBinding binding = type.addAttribute(attrName, typeBinding, DefaultHandlers.ATTRIBUTE_HANDLER);
- binding.setRequired(attrUse.getRequired());
- if(attrUse.getConstraintType() == XSConstants.VC_DEFAULT)
- {
- // Associate the default value with the binding
- binding.setDefaultConstraint(attrUse.getConstraintValue());
- }
-
- if (ctx.processAnnotations)
- {
- XSAnnotation an = attr.getAnnotation();
- if(an != null)
- {
- if (ctx.trace)
- {
- log.trace(attrName + " attribute annotation");
- }
-
- XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
- XsdAppInfo appInfo = xsdAn.getAppInfo();
- if(appInfo != null)
- {
- PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
- if(propertyMetaData != null)
- {
- binding.setPropertyMetaData(propertyMetaData);
- }
-
- boolean mapEntryKey = appInfo.isMapEntryKey();
- if(mapEntryKey)
- {
- binding.setMapEntryKey(mapEntryKey);
- }
-
- boolean mapEntryValue = appInfo.isMapEntryValue();
- if(mapEntryValue)
- {
- binding.setMapEntryValue(mapEntryValue);
- }
- }
- }
- }
-
-
- if (ctx.trace)
- {
- String msg = "bound attribute " + attrName;
-
- if(binding.getPropertyMetaData() != null)
- {
- msg += " property=" +
- binding.getPropertyMetaData().getName() +
- ", collectionType=" + binding.getPropertyMetaData().getCollectionType();
- }
- else if(binding.isMapEntryKey())
- {
- msg += "bound as a key in a map entry";
- }
- else if(binding.isMapEntryValue())
- {
- msg += "bound as a value in a map entry";
- }
- else
- {
- msg += " type=" + attrType.getName() + ", owner type=" + type.getQName();
- }
-
- if(binding.getDefaultConstraint() != null)
- {
- msg += ", default=" + binding.getDefaultConstraint();
- }
-
- log.trace(msg);
- }
- }
-
- private static void bindParticle(Context ctx, XSParticle particle)
- {
- XSTerm term = particle.getTerm();
- switch(term.getType())
- {
- case XSConstants.MODEL_GROUP:
- XSModelGroup modelGroup = (XSModelGroup)term;
- // todo: investigate this
- if(modelGroup.getParticles().getLength() > 0)
- {
- ModelGroupBinding groupBinding;
- switch(modelGroup.getCompositor())
- {
- case XSModelGroup.COMPOSITOR_ALL:
- groupBinding = new AllBinding(ctx.schema);
- break;
- case XSModelGroup.COMPOSITOR_CHOICE:
- groupBinding = new ChoiceBinding(ctx.schema);
- break;
- case XSModelGroup.COMPOSITOR_SEQUENCE:
- groupBinding = new SequenceBinding(ctx.schema);
- break;
- default:
- throw new JBossXBRuntimeException("Unexpected model group: " + modelGroup.getCompositor());
- }
-
- ParticleBinding particleBinding = new ParticleBinding(groupBinding);
- particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
- particleBinding.setMinOccurs(particle.getMinOccurs());
- particleBinding.setMaxOccurs(particle.getMaxOccurs());
-
- if (ctx.trace)
- {
- log.trace("created model group " + groupBinding);
- }
-
- if (ctx.processAnnotations)
- {
- XSAnnotation annotation = modelGroup.getAnnotation();
- if(annotation != null)
- {
- customizeTerm(annotation, groupBinding, ctx.trace);
- }
- }
-
- Object o = ctx.peekTypeOrGroup();
- if(o instanceof ModelGroupBinding)
- {
- ModelGroupBinding parentGroup = (ModelGroupBinding)o;
- parentGroup.addParticle(particleBinding);
- if (ctx.trace)
- {
- log.trace("added " + groupBinding + " to " + parentGroup);
- }
- }
- else if(o instanceof TypeBinding)
- {
- TypeBinding typeBinding = (TypeBinding)o;
- typeBinding.setParticle(particleBinding);
- if (ctx.trace)
- {
- log.trace("added " + groupBinding + " to type " + typeBinding.getQName());
- }
- }
-
- ctx.pushModelGroup(groupBinding);
- bindModelGroup(ctx, modelGroup);
- ctx.popModelGroup();
- }
- break;
- case XSConstants.WILDCARD:
- bindWildcard(ctx, particle);
- break;
- case XSConstants.ELEMENT_DECLARATION:
- bindElement(ctx,
- (XSElementDeclaration)term,
- particle.getMinOccurs(),
- particle.getMaxOccurs(),
- particle.getMaxOccursUnbounded()
- );
- break;
- default:
- throw new IllegalStateException("Unexpected term type: " + term.getType());
- }
- }
-
- private static void bindWildcard(Context ctx, XSParticle particle)
- {
- WildcardBinding binding = new WildcardBinding(ctx.schema);
-
- ModelGroupBinding group = (ModelGroupBinding)ctx.peekTypeOrGroup();
- ParticleBinding particleBinding = new ParticleBinding(binding);
- particleBinding.setMaxOccurs(particle.getMaxOccurs());
- particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
- particleBinding.setMinOccurs(particle.getMinOccurs());
- group.addParticle(particleBinding);
-
- XSWildcard wildcard = (XSWildcard)particle.getTerm();
- if(wildcard.getName() != null)
- {
- binding.setQName(new QName(wildcard.getNamespace(), wildcard.getName()));
- }
-
- binding.setProcessContents(wildcard.getProcessContents());
-
- if (ctx.processAnnotations)
- {
- XSAnnotation annotation = wildcard.getAnnotation();
- if(annotation != null)
- {
- customizeTerm(annotation, binding, ctx.trace);
- }
- }
- }
-
- private static ParticleBinding bindElement(Context ctx,
- XSElementDeclaration elementDec,
- int minOccurs,
- int maxOccurs,
- boolean maxOccursUnbounded)
- {
- QName qName = new QName(elementDec.getNamespace(), elementDec.getName());
-
- ModelGroupBinding parentGroup = (ModelGroupBinding)ctx.peekTypeOrGroup();
-
- boolean global = elementDec.getScope() == XSConstants.SCOPE_GLOBAL;
- ElementBinding element = ctx.schema.getElement(qName);
- ParticleBinding particle;
- if(global && element != null)
- {
- particle = new ParticleBinding(element);
- if(parentGroup != null)
- {
- parentGroup.addParticle(particle);
- }
-
- particle.setMinOccurs(minOccurs);
- if(maxOccursUnbounded)
- {
- particle.setMaxOccursUnbounded(maxOccursUnbounded);
- }
- else
- {
- particle.setMaxOccurs(maxOccurs);
- }
-
- return particle;
- }
-
- TypeBinding type = null;
-
- boolean shared = ctx.sharedElements.isShared(elementDec);
- if(shared)
- {
- type = ctx.sharedElements.getTypeBinding(elementDec);
- }
-
- if(type == null)
- {
- type = bindType(ctx, elementDec.getTypeDefinition());
- if(shared)
- {
- ctx.sharedElements.setTypeBinding(elementDec, type);
- }
- }
-
- element = new ElementBinding(ctx.schema, qName, type);
- element.setNillable(elementDec.getNillable());
- particle = new ParticleBinding(element);
- particle.setMinOccurs(minOccurs);
- particle.setMaxOccurs(maxOccurs);
- particle.setMaxOccursUnbounded(maxOccursUnbounded);
- if(global)
- {
- ctx.schema.addElementParticle(particle);
- }
-
- if(parentGroup != null)
- {
- parentGroup.addParticle(particle);
- if (ctx.trace)
- {
- log.trace("Element " + element.getQName() + " added to " + parentGroup);
- }
- }
-
- if (ctx.trace)
- {
- TypeBinding parentType = ctx.peekType();
- log.trace("element: name=" +
- qName +
- ", type=" +
- type.getQName() +
- ", repeatable=" +
- particle.isRepeatable() +
- ", nillable=" +
- element.isNillable() +
- ", minOccurs=" + minOccurs +
- ", maxOccurs=" + (maxOccursUnbounded ? "unbounded" : "" + maxOccurs) +
- ", " + (global ? "global scope" : " owner type=" + parentType.getQName())
- );
- }
-
- // customize element with annotations
- if (ctx.processAnnotations)
- {
- XSAnnotation an = elementDec.getAnnotation();
- if(an != null)
- {
- customizeTerm(an, element, ctx.trace);
- }
- }
- return particle;
- }
-
- private static void bindModelGroup(Context ctx, XSModelGroup modelGroup)
- {
- XSObjectList particles = modelGroup.getParticles();
- for(int i = 0; i < particles.getLength(); ++i)
- {
- XSParticle particle = (XSParticle)particles.item(i);
- bindParticle(ctx, particle);
- }
- }
-
- // Private
-
- private static void addXOPInclude(TypeBinding binding, SchemaBinding schema)
- {
- binding.setHandler(DefaultHandlers.XOP_HANDLER);
- if(binding.getParticle() != null)
- {
- throw new JBossXBRuntimeException(
- "XOP optimizable type has a particle which is unexpected, please, open a JIRA issue!"
- );
- }
-
- TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
- if(anyUriType == null)
- {
- log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
- }
-
- TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
- xopIncludeType.setSchemaBinding(schema);
- xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
- xopIncludeType.setHandler(new XOPIncludeHandler(binding));
-
- ElementBinding xopInclude = new ElementBinding(schema, new QName(Constants.NS_XOP_INCLUDE, "Include"), xopIncludeType);
-
- ParticleBinding particleBinding = new ParticleBinding(xopInclude);
- particleBinding.setMinOccurs(0);
-
- binding.addParticle(particleBinding);
- }
-
- private static void customizeTerm(XSAnnotation an, TermBinding term, boolean trace)
- {
- XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
- XsdAppInfo appInfo = xsdAn.getAppInfo();
- if(appInfo != null)
- {
- Boolean skip = null;
-
- ClassMetaData classMetaData = appInfo.getClassMetaData();
- if(classMetaData != null)
- {
- if (trace)
- {
- String msg;
- if(term.isModelGroup())
- {
- msg = term + " bound to ";
- }
- else if(term.isWildcard())
- {
- msg = " wildcard bound to ";
- }
- else
- {
- msg = "element: name=" + ((ElementBinding)term).getQName() + ", class=";
- }
-
- msg += classMetaData.getImpl();
- log.trace(msg);
- }
- term.setClassMetaData(classMetaData);
- skip = Boolean.FALSE;
- }
-
- PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
- if(propertyMetaData != null)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term + " " : "element: name=" +
- ((ElementBinding)term).getQName() + ", ";
- msg += " property=" +
- propertyMetaData.getName() +
- ", collectionType=" + propertyMetaData.getCollectionType();
- log.trace(msg);
- }
- term.setPropertyMetaData(propertyMetaData);
- }
-
- MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
- if(mapEntryMetaData != null)
- {
- if(propertyMetaData != null)
- {
- String msg = "A term can be bound either as a property or as a map" +
- " entry but not both: " +
- (term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
- throw new JBossXBRuntimeException(msg);
- }
-
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
- ((ElementBinding)term).getQName();
-
- msg += " is bound to a map entry: impl=" +
- mapEntryMetaData.getImpl() +
- ", getKeyMethod=" +
- mapEntryMetaData.getGetKeyMethod() +
- ", setKeyMethod=" +
- mapEntryMetaData.getSetKeyMethod() +
- ", getValueMethod=" +
- mapEntryMetaData.getGetValueMethod() +
- ", setValueMethod=" +
- mapEntryMetaData.getSetValueMethod() +
- ", valueType=" +
- mapEntryMetaData.getValueType() +
- ", nonNullValue=" + mapEntryMetaData.isNonNullValue();
- log.trace(msg);
- }
-
- if(classMetaData != null)
- {
- String msg = "Invalid customization: both jbxb:class and jbxb:mapEntry are specified for term " +
- (term.isWildcard() || term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
- throw new JBossXBRuntimeException(msg);
- }
- term.setMapEntryMetaData(mapEntryMetaData);
- skip = Boolean.FALSE;
- }
-
- PutMethodMetaData putMethodMetaData = appInfo.getPutMethodMetaData();
- if(putMethodMetaData != null)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
- ((ElementBinding)term).getQName() + ",";
-
- msg += " putMethod=" +
- putMethodMetaData.getName() +
- ", keyType=" +
- putMethodMetaData.getKeyType() +
- ", valueType=" + putMethodMetaData.getValueType();
- log.trace(msg);
- }
- term.setPutMethodMetaData(putMethodMetaData);
- }
-
- AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
- if(addMethodMetaData != null)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
- ((ElementBinding)term).getQName() + ",";
- msg += " addMethod=" +
- addMethodMetaData.getMethodName() +
- ", valueType=" +
- addMethodMetaData.getValueType() +
- ", isChildType=" + addMethodMetaData.isChildType();
- log.trace(msg);
- }
- term.setAddMethodMetaData(addMethodMetaData);
- }
-
- ValueMetaData valueMetaData = appInfo.getValueMetaData();
- if(valueMetaData != null)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element " +
- ((ElementBinding)term).getQName();
- msg += ": unmarshalMethod=" + valueMetaData.getUnmarshalMethod();
- log.trace(msg);
- }
- term.setValueMetaData(valueMetaData);
- }
-
- boolean mapEntryKey = appInfo.isMapEntryKey();
- if(mapEntryKey)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
- ((ElementBinding)term).getQName();
- msg += ": is bound to a key in a map entry";
- log.trace(msg);
- }
- term.setMapEntryKey(mapEntryKey);
- skip = Boolean.FALSE;
- }
-
- boolean mapEntryValue = appInfo.isMapEntryValue();
- if(mapEntryValue)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
- ((ElementBinding)term).getQName();
- msg += ": is bound to a value in a map entry";
- log.trace(msg);
- }
- term.setMapEntryValue(mapEntryValue);
- skip = Boolean.FALSE;
- }
-
- boolean skipAnnotation = appInfo.isSkip();
- if(skip != null)
- {
- term.setSkip(skip);
- }
- else if(skipAnnotation)
- {
- if (trace)
- {
- String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
- ((ElementBinding)term).getQName();
- msg += ": will be skipped, it's attributes, character content and children will be set on the parent";
- log.trace(msg);
- }
- term.setSkip(skipAnnotation ? Boolean.TRUE : Boolean.FALSE);
- }
- }
- }
-
- private static void bindGlobalGroup(XSModelGroup group, SharedElements sharedElements)
- {
- XSObjectList particles = group.getParticles();
- for(int j = 0; j < particles.getLength(); ++j)
- {
- XSParticle particle = (XSParticle)particles.item(j);
- XSTerm term = particle.getTerm();
- switch(term.getType())
- {
- case XSConstants.ELEMENT_DECLARATION:
- XSElementDeclaration element = ((XSElementDeclaration)term);
- sharedElements.add(element);
- break;
- case XSConstants.WILDCARD:
- // todo is it actually possible?
- break;
- case XSConstants.MODEL_GROUP:
- bindGlobalGroup((XSModelGroup)term, sharedElements);
- }
- }
- }
-
-
- // Inner
-
- private static final class SharedElements
- {
- private Map elements = Collections.EMPTY_MAP;
-
- public void add(XSElementDeclaration element)
- {
- switch(elements.size())
- {
- case 0:
- elements = Collections.singletonMap(element, null);
- break;
- case 1:
- elements = new HashMap(elements);
- default:
- elements.put(element, null);
- }
- }
-
- public boolean isShared(XSElementDeclaration element)
- {
- return elements.containsKey(element);
- }
-
- public TypeBinding getTypeBinding(XSElementDeclaration element)
- {
- return (TypeBinding)elements.get(element);
- }
-
- public void setTypeBinding(XSElementDeclaration element, TypeBinding type)
- {
- switch(elements.size())
- {
- case 0:
- elements = Collections.singletonMap(element, type);
- break;
- case 1:
- elements = new HashMap(elements);
- default:
- elements.put(element, type);
- }
- }
- }
-
- private static final class Context
- {
- public final SchemaBinding schema;
- public SharedElements sharedElements = new SharedElements();
- public boolean processAnnotations = true;
- public boolean trace = log.isTraceEnabled();
- private final List typeGroupStack = new ArrayList();
-
- public Context()
- {
- this(new SchemaBinding());
- }
-
- public Context(SchemaBinding schema)
- {
- this.schema = schema;
- }
-
- public void popType()
- {
- Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
- if(!(o instanceof TypeBinding))
- {
- throw new JBossXBRuntimeException("Should have poped type binding but got " + o);
- }
- }
-
- public void pushType(TypeBinding binding)
- {
- typeGroupStack.add(binding);
- }
-
- public void popModelGroup()
- {
- Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
- if(!(o instanceof ModelGroupBinding))
- {
- throw new JBossXBRuntimeException("Should have poped model group binding but got " + o);
- }
- }
-
- public void pushModelGroup(ModelGroupBinding binding)
- {
- typeGroupStack.add(binding);
- }
-
- public Object peekTypeOrGroup()
- {
- return typeGroupStack.isEmpty() ? null : typeGroupStack.get(typeGroupStack.size() - 1);
- }
-
- public TypeBinding peekType()
- {
- TypeBinding binding = null;
- for(ListIterator i = typeGroupStack.listIterator(typeGroupStack.size()); i.hasPrevious();)
- {
- Object o = i.previous();
- if(o instanceof TypeBinding)
- {
- binding = (TypeBinding)o;
- break;
- }
- }
- return binding;
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/XsdBinder.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1542 @@
+/*
+ * 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.xb.binding.sunday.unmarshalling;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.ListIterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.xerces.xs.StringList;
+import org.apache.xerces.xs.XSAnnotation;
+import org.apache.xerces.xs.XSAttributeDeclaration;
+import org.apache.xerces.xs.XSAttributeUse;
+import org.apache.xerces.xs.XSComplexTypeDefinition;
+import org.apache.xerces.xs.XSConstants;
+import org.apache.xerces.xs.XSElementDeclaration;
+import org.apache.xerces.xs.XSModel;
+import org.apache.xerces.xs.XSModelGroup;
+import org.apache.xerces.xs.XSModelGroupDefinition;
+import org.apache.xerces.xs.XSNamedMap;
+import org.apache.xerces.xs.XSObjectList;
+import org.apache.xerces.xs.XSParticle;
+import org.apache.xerces.xs.XSSimpleTypeDefinition;
+import org.apache.xerces.xs.XSTerm;
+import org.apache.xerces.xs.XSTypeDefinition;
+import org.apache.xerces.xs.XSWildcard;
+import org.jboss.logging.Logger;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.sunday.xop.XOPIncludeHandler;
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.CharactersMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.PutMethodMetaData;
+import org.jboss.xb.binding.metadata.SchemaMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.metadata.XsdAnnotation;
+import org.jboss.xb.binding.metadata.XsdAppInfo;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class XsdBinder
+{
+ static final Logger log = Logger.getLogger(XsdBinder.class);
+
+ /**
+ * Creates a new instance of the binder the user can use to tune
+ * configuration before parsing the XSD.
+ *
+ * @return a new instance of the XsdBinder
+ */
+ public static XsdBinder newInstance()
+ {
+ return new XsdBinder();
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd url/uri.
+ *
+ * @param xsdUrl
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(String xsdUrl)
+ {
+ DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+ resolver.setBaseURI(xsdUrl);
+ return bind(xsdUrl, resolver);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd url/uri.
+ *
+ * @param xsdUrl
+ * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+ * and also will be set on the returned instance of SchemaBinding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(String xsdUrl, SchemaBindingResolver resolver)
+ {
+ XSModel model = Util.loadSchema(xsdUrl, resolver);
+ return bind(model, resolver);
+ }
+
+ public static SchemaBinding bind(InputStream xsdStream, String encoding)
+ {
+ return bind(xsdStream, encoding, new DefaultSchemaResolver());
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd stream.
+ *
+ * @param xsdStream - the xsd InputStream
+ * @param encoding - optional stream encoding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI)
+ {
+ return bind(xsdStream, encoding, baseURI, true);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd stream.
+ *
+ * @param xsdStream - the xsd InputStream
+ * @param encoding - optional stream encoding
+ * @param processAnnotations - process annotations
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(InputStream xsdStream, String encoding, String baseURI, boolean processAnnotations)
+ {
+ DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+ resolver.setBaseURI(baseURI);
+ return bind(xsdStream, encoding, resolver, processAnnotations);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd stream.
+ *
+ * @param xsdStream - the xsd InputStream
+ * @param encoding - optional stream encoding
+ * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+ * and also will be set on the returned instance of SchemaBinding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver)
+ {
+ return bind(xsdStream, encoding, resolver, true);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd stream.
+ *
+ * @param xsdStream - the xsd InputStream
+ * @param encoding - optional stream encoding
+ * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+ * and also will be set on the returned instance of SchemaBinding
+ * @param processAnnotations whether to process annotations
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(InputStream xsdStream, String encoding, SchemaBindingResolver resolver, boolean processAnnotations)
+ {
+ XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
+ return bind(model, resolver, processAnnotations);
+ }
+
+ public static SchemaBinding bind(Reader xsdReader, String encoding)
+ {
+ return bind(xsdReader, encoding, new DefaultSchemaResolver());
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd reader.
+ *
+ * @param xsdReader - xsd reader
+ * @param encoding - optional reader encoding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(Reader xsdReader, String encoding, String baseURI)
+ {
+ DefaultSchemaResolver resolver = new DefaultSchemaResolver();
+ resolver.setBaseURI(baseURI);
+ return bind(xsdReader, encoding, resolver);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd reader.
+ *
+ * @param xsdReader - xsd reader
+ * @param encoding - optional reader encoding
+ * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+ * and also will be set on the returned instance of SchemaBinding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(Reader xsdReader, String encoding, SchemaBindingResolver resolver)
+ {
+ XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
+ return bind(model, resolver);
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd string.
+ *
+ * @param xsd - xsd string
+ * @param encoding - optional string encoding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(String xsd, String encoding)
+ {
+ return bind(xsd, encoding, new DefaultSchemaResolver());
+ }
+
+ /**
+ * Create a SchemaBinding from and xsd string.
+ *
+ * @param xsd - xsd string
+ * @param encoding - optional string encoding
+ * @param resolver the resolver will be used to resolve imported schemas in the schema being loaded
+ * and also will be set on the returned instance of SchemaBinding
+ * @return SchemaBinding mapping
+ */
+ public static SchemaBinding bind(String xsd, String encoding, SchemaBindingResolver resolver)
+ {
+ XSModel model = Util.loadSchema(xsd, encoding);
+ return bind(model, resolver);
+ }
+
+ public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver)
+ {
+ return bind(model,resolver, true);
+ }
+
+ public static SchemaBinding bind(XSModel model, SchemaBindingResolver resolver, boolean processAnnotations)
+ {
+ XsdBinder binder = new XsdBinder();
+ binder.setProcessAnnotations(processAnnotations);
+ binder.setSchemaResolver(resolver);
+ return binder.parse(model);
+ }
+
+ /**
+ * @param schema schema binding the type should be added to
+ * @param type type definition to be bound
+ * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
+ * It will be removed when anonymous type binding in JBossWS is implemented properly.
+ * No one else should use this method.</i>
+ *
+ * <p>This method binds a type definition and adds it as a global type to the passed in schema binding.
+ */
+ public static void bindType(SchemaBinding schema, XSTypeDefinition type)
+ {
+ TypeBinding typeBinding = bindType(new Context(schema), type);
+ schema.addType(typeBinding);
+ }
+
+ /**
+ * @param schema schema binding the type should be added to
+ * @param element element declaration to be bound
+ * @param minOccurs
+ * @param maxOccurs
+ * @param maxOccursUnbounded
+ * @deprecated <i>This method is added temporary to get anonymous type binding working in JBossWS.
+ * It will be removed when anonymous type binding in JBossWS is implemented properly.
+ * No one else should use this method.</i>
+ *
+ * <p>This method binds an element declaration and adds it as a global element to the passed in schema binding.
+ */
+ public static void bindElement(SchemaBinding schema,
+ XSElementDeclaration element,
+ int minOccurs,
+ int maxOccurs,
+ boolean maxOccursUnbounded)
+ {
+ ParticleBinding particle = bindElement(new Context(schema),
+ element,
+ minOccurs,
+ maxOccurs,
+ maxOccursUnbounded
+ );
+ schema.addElementParticle(particle);
+ }
+
+ // Exposed attributes
+
+ private boolean processAnnotations = true;
+ private SchemaBindingResolver resolver;
+ private boolean simpleContentWithIdAsSimpleType = true;
+ private boolean unresolvedContentBoundToDOM = true;
+
+ // Internal attributes
+
+ private boolean trace = log.isTraceEnabled();
+ private final SchemaBinding schema;
+ private SharedElements sharedElements = new SharedElements();
+ private final List typeGroupStack = new ArrayList();
+
+ // Ctors
+
+ private XsdBinder()
+ {
+ this(new SchemaBinding());
+ }
+
+ private XsdBinder(SchemaBinding schema)
+ {
+ this.schema = schema;
+ }
+
+ // Public
+
+ public void setProcessAnnotations(boolean processAnnotations)
+ {
+ this.processAnnotations = processAnnotations;
+ }
+
+ public boolean isProcessAnnotations()
+ {
+ return processAnnotations;
+ }
+
+ public void setSchemaResolver(SchemaBindingResolver resolver)
+ {
+ this.resolver = resolver;
+ }
+
+ public SchemaBindingResolver getSchemaResolver()
+ {
+ return resolver;
+ }
+
+ public void setSimpleContentWithIdAsSimpleType(boolean simpleContentWithIdAsSimpleType)
+ {
+ this.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
+ }
+
+ public boolean isSimpleContentWithIdAsSimpleType()
+ {
+ return simpleContentWithIdAsSimpleType;
+ }
+
+ public void setUnresolvedContentBoundToDOM(boolean toDOM)
+ {
+ this.unresolvedContentBoundToDOM = toDOM;
+ }
+
+ public boolean isUnresolvedContentBoundToDOM()
+ {
+ return this.unresolvedContentBoundToDOM;
+ }
+
+ public SchemaBinding parse(String xsdUrl)
+ {
+ if(resolver == null)
+ {
+ resolver = new DefaultSchemaResolver();
+ }
+
+ XSModel model = Util.loadSchema(xsdUrl, resolver);
+ return parse(model);
+ }
+
+ public SchemaBinding parse(InputStream xsdStream, String encoding)
+ {
+ if(resolver == null)
+ {
+ resolver = new DefaultSchemaResolver();
+ }
+
+ XSModel model = Util.loadSchema(xsdStream, encoding, resolver);
+ return parse(model);
+ }
+
+ public SchemaBinding parse(Reader xsdReader, String encoding)
+ {
+ if(resolver == null)
+ {
+ resolver = new DefaultSchemaResolver();
+ }
+
+ XSModel model = Util.loadSchema(xsdReader, encoding, resolver);
+ return parse(model);
+ }
+
+
+ // Private
+
+ public SchemaBinding parse(XSModel model)
+ {
+ Context ctx = new Context();
+ ctx.processAnnotations = processAnnotations;
+ ctx.simpleContentWithIdAsSimpleType = simpleContentWithIdAsSimpleType;
+ SchemaBinding schema = ctx.schema;
+ schema.setSchemaResolver(resolver);
+
+ // read annotations. for now just log the ones that are going to be used
+ if (ctx.processAnnotations)
+ {
+ XSObjectList annotations = model.getAnnotations();
+ if (ctx.trace)
+ {
+ log.trace("started binding schema " + schema);
+ log.trace("Schema annotations: " + annotations.getLength());
+ }
+
+ for(int i = 0; i < annotations.getLength(); ++i)
+ {
+ XSAnnotation annotation = (XSAnnotation)annotations.item(i);
+ XsdAnnotation an = XsdAnnotation.unmarshal(annotation.getAnnotationString());
+ XsdAppInfo appinfo = an.getAppInfo();
+ if(appinfo != null)
+ {
+ SchemaMetaData schemaBindings = appinfo.getSchemaMetaData();
+ if(schemaBindings != null)
+ {
+ // Get the ignoreUnresolvedFieldOrClass
+ schema.setIgnoreUnresolvedFieldOrClass(schemaBindings.isIgnoreUnresolvedFieldOrClass());
+ // Get the ignoreUnresolvedFieldOrClass
+ schema.setReplacePropertyRefs(schemaBindings.isReplacePropertyRefs());
+ // Get the default package
+ PackageMetaData packageMetaData = schemaBindings.getPackage();
+ if(packageMetaData != null)
+ {
+ if (ctx.trace)
+ log.trace("schema default package: " + packageMetaData.getName());
+ schema.setPackageMetaData(packageMetaData);
+ }
+ }
+ }
+ }
+ }
+
+ StringList namespaceList = model.getNamespaces();
+ Set namespaces = new LinkedHashSet(namespaceList.getLength());
+ for (int i = 0; i < namespaceList.getLength(); ++i)
+ namespaces.add(namespaceList.item(i));
+ schema.setNamespaces(namespaces);
+
+ XSNamedMap groups = model.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
+ if (ctx.trace)
+ log.trace("Model groups: " + groups.getLength());
+ for(int i = 0; i < groups.getLength(); ++i)
+ {
+ XSModelGroupDefinition groupDef = (XSModelGroupDefinition)groups.item(i);
+ bindGlobalGroup(groupDef.getModelGroup(), ctx.sharedElements);
+ }
+
+ XSNamedMap types = model.getComponents(XSConstants.TYPE_DEFINITION);
+ if (ctx.trace)
+ log.trace("Model types: " + types.getLength());
+ for(int i = 0; i < types.getLength(); ++i)
+ {
+ XSTypeDefinition type = (XSTypeDefinition)types.item(i);
+ if(!Constants.NS_XML_SCHEMA.equals(type.getNamespace()))
+ {
+ bindType(ctx, type);
+ }
+ }
+
+ XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION);
+ if (ctx.trace)
+ log.trace("Model elements: " + types.getLength());
+ for(int i = 0; i < elements.getLength(); ++i)
+ {
+ XSElementDeclaration element = (XSElementDeclaration)elements.item(i);
+ bindElement(ctx, element, 1, 0, false);
+ }
+
+ schema.setUnresolvedContentBoundToDOM(true);
+
+ if (ctx.trace)
+ {
+ log.trace("finished binding schema " + schema);
+ }
+
+ return schema;
+ }
+
+ private static TypeBinding bindType(Context ctx, XSTypeDefinition type)
+ {
+ TypeBinding binding;
+ switch(type.getTypeCategory())
+ {
+ case XSTypeDefinition.SIMPLE_TYPE:
+ binding = bindSimpleType(ctx, (XSSimpleTypeDefinition)type);
+ break;
+ case XSTypeDefinition.COMPLEX_TYPE:
+ binding = bindComplexType(ctx, (XSComplexTypeDefinition)type);
+ break;
+ default:
+ throw new JBossXBRuntimeException("Unexpected type category: " + type.getTypeCategory());
+ }
+ return binding;
+ }
+
+ private static TypeBinding bindSimpleType(Context ctx, XSSimpleTypeDefinition type)
+ {
+ QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
+ TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
+ if(binding != null)
+ {
+ return binding;
+ }
+
+ if(ctx.trace)
+ {
+ log.trace("binding simple type " + typeName);
+ }
+
+ XSTypeDefinition baseTypeDef = type.getBaseType();
+ TypeBinding baseType = baseTypeDef == null ? null : bindType(ctx, baseTypeDef);
+
+ binding = baseType == null ? new TypeBinding(typeName) : new TypeBinding(typeName, baseType);
+
+ StringList strList = type.getLexicalPattern();
+ if(strList != null && strList.getLength() > 0)
+ {
+ for(int i = 0; i < strList.getLength(); ++i)
+ {
+ binding.addLexicalPattern(strList.item(i));
+ }
+ }
+
+ strList = type.getLexicalEnumeration();
+ if(strList != null && strList.getLength() > 0)
+ {
+ for(int i = 0; i < strList.getLength(); ++i)
+ {
+ binding.addEnumValue(strList.item(i));
+ }
+ }
+
+ if(type.getItemType() != null)
+ {
+ TypeBinding itemType = bindSimpleType(ctx, type.getItemType());
+ binding.setItemType(itemType);
+ }
+
+ if(typeName != null)
+ {
+ ctx.schema.addType(binding);
+ }
+
+ if(ctx.trace)
+ {
+ String msg = typeName == null ? "bound simple anonymous type" : "bound simple type " + typeName;
+ if(baseType != null)
+ {
+ msg += " inherited binding metadata from " + baseType.getQName();
+ }
+ log.trace(msg);
+ }
+
+ // customize binding with annotations
+ if(ctx.processAnnotations)
+ {
+ XSObjectList annotations = type.getAnnotations();
+ if(annotations != null)
+ {
+ if(ctx.trace)
+ {
+ log.trace(typeName + " annotations " + annotations.getLength());
+ }
+ for(int i = 0; i < annotations.getLength(); ++i)
+ {
+ XSAnnotation an = (XSAnnotation)annotations.item(i);
+ XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+ XsdAppInfo appInfo = xsdAn.getAppInfo();
+ if(appInfo != null)
+ {
+ ClassMetaData classMetaData = appInfo.getClassMetaData();
+ if(classMetaData != null)
+ {
+ if(ctx.trace)
+ {
+ log.trace("simple type " +
+ type.getName() +
+ ": impl=" +
+ classMetaData.getImpl());
+ }
+ binding.setClassMetaData(classMetaData);
+ }
+
+ ValueMetaData valueMetaData = appInfo.getValueMetaData();
+ if(valueMetaData != null)
+ {
+ if(ctx.trace)
+ {
+ log.trace("simple type " +
+ type.getName() +
+ ": unmarshalMethod=" +
+ valueMetaData.getUnmarshalMethod() +
+ ", marshalMethod=" +
+ valueMetaData.getMarshalMethod());
+ }
+ binding.setValueMetaData(valueMetaData);
+ }
+ }
+ }
+ }
+ }
+
+ binding.setSchemaBinding(ctx.schema);
+
+ return binding;
+ }
+
+ private static TypeBinding bindComplexType(Context ctx, XSComplexTypeDefinition type)
+ {
+ QName typeName = type.getName() == null ? null : new QName(type.getNamespace(), type.getName());
+ TypeBinding binding = typeName == null ? null : ctx.schema.getType(typeName);
+ if(binding != null)
+ {
+ return binding;
+ }
+
+ XSTypeDefinition baseTypeDef = type.getBaseType();
+ // anyType is the parent of all the types, even the parent of itself according to xerces :)
+ TypeBinding baseType = null;
+ if(baseTypeDef != null && !Constants.QNAME_ANYTYPE.equals(typeName))
+ {
+ baseType = bindType(ctx, baseTypeDef);
+ // sometimes binding the base type can lead to another request
+ // to bind the type being bound here
+ if(typeName != null)
+ {
+ binding = ctx.schema.getType(typeName);
+ if(binding != null)
+ {
+ return binding;
+ }
+ }
+ }
+
+ if (ctx.trace)
+ log.trace("binding complex " + (typeName == null ? "anonymous type" : "type " + typeName));
+
+ binding = new TypeBinding(typeName);
+ binding.setBaseType(baseType);
+ binding.setStartElementCreatesObject(true);
+ binding.setSimple(false);
+
+ if(type.getSimpleType() != null)
+ {
+ TypeBinding simpleType = bindSimpleType(ctx, type.getSimpleType());
+ binding.setSimpleType(simpleType);
+ }
+ else if(type.getContentType() == XSComplexTypeDefinition.CONTENTTYPE_MIXED)
+ {
+ TypeBinding stringType = ctx.schema.getType(Constants.QNAME_STRING);
+ if(stringType == null)
+ {
+ throw new JBossXBRuntimeException("xsd:string has not been bound yet!");
+ }
+ binding.setSimpleType(stringType);
+ }
+
+ if(typeName != null)
+ {
+ ctx.schema.addType(binding);
+ }
+
+ binding.setSchemaBinding(ctx.schema);
+
+ XSObjectList attrs = type.getAttributeUses();
+ if (ctx.trace)
+ log.trace(typeName + " attributes " + attrs.getLength());
+
+ boolean hasOnlyIdAttrs = true;
+ for(int i = 0; i < attrs.getLength(); ++i)
+ {
+ XSAttributeUse attr = (XSAttributeUse)attrs.item(i);
+ AttributeBinding attrBinding = bindAttributes(ctx, binding, attr);
+ if(hasOnlyIdAttrs && !Constants.QNAME_ID.equals(attrBinding.getType().getQName()))
+ {
+ hasOnlyIdAttrs = false;
+ }
+ }
+
+ // customize binding with xsd annotations
+ if (ctx.processAnnotations)
+ {
+ XSObjectList annotations = type.getAnnotations();
+ if(annotations != null)
+ {
+ if (ctx.trace)
+ log.trace(typeName + " annotations " + annotations.getLength());
+ for(int i = 0; i < annotations.getLength(); ++i)
+ {
+ XSAnnotation an = (XSAnnotation)annotations.item(i);
+ XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+ XsdAppInfo appInfo = xsdAn.getAppInfo();
+ if(appInfo != null)
+ {
+ ClassMetaData classMetaData = appInfo.getClassMetaData();
+ if(classMetaData != null)
+ {
+ if (ctx.trace)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": impl=" +
+ classMetaData.getImpl()
+ );
+ }
+ binding.setClassMetaData(classMetaData);
+ }
+
+ CharactersMetaData charactersMetaData = appInfo.getCharactersMetaData();
+ if(charactersMetaData != null)
+ {
+ if (ctx.trace)
+ {
+ PropertyMetaData propertyMetaData = charactersMetaData.getProperty();
+ if(propertyMetaData != null)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": characters bound to " + propertyMetaData.getName()
+ );
+ }
+
+ ValueMetaData valueMetaData = charactersMetaData.getValue();
+ if(valueMetaData != null)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": characters unmarshalMethod=" +
+ valueMetaData.getUnmarshalMethod() +
+ ", marshalMethod=" + valueMetaData.getMarshalMethod()
+ );
+ }
+
+ boolean mapEntryKey = appInfo.isMapEntryKey();
+ if(mapEntryKey)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": characters are bound as a key in a map entry"
+ );
+ }
+
+ boolean mapEntryValue = appInfo.isMapEntryValue();
+ if(mapEntryValue)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": characters are bound as a value in a map entry"
+ );
+ }
+ }
+ binding.setCharactersMetaData(charactersMetaData);
+ }
+
+ MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
+ if(mapEntryMetaData != null)
+ {
+ if (ctx.trace)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ " is bound to a map entry: impl=" +
+ mapEntryMetaData.getImpl() +
+ ", getKeyMethod=" +
+ mapEntryMetaData.getGetKeyMethod() +
+ ", setKeyMethod=" +
+ mapEntryMetaData.getSetKeyMethod() +
+ ", getValueMethod=" +
+ mapEntryMetaData.getGetValueMethod() +
+ ", setValueMethod=" +
+ mapEntryMetaData.getSetValueMethod() +
+ ", valueType=" +
+ mapEntryMetaData.getValueType() +
+ ", nonNullValue=" + mapEntryMetaData.isNonNullValue()
+ );
+ }
+
+ if(classMetaData != null)
+ {
+ throw new JBossXBRuntimeException("Illegal binding: both jbxb:class and jbxb:mapEntry are specified for complex type " +
+ type.getName()
+ );
+ }
+ binding.setMapEntryMetaData(mapEntryMetaData);
+ }
+
+ boolean skip = appInfo.isSkip();
+ if(skip)
+ {
+ if (ctx.trace)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": elements of this type will be skipped; their attrs, character content " +
+ "and elements will be set the parent."
+ );
+ }
+ binding.setSkip(skip);
+ }
+
+ PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+ if(propertyMetaData != null)
+ {
+ if (ctx.trace)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": the content of elements of this type is bound to property " + propertyMetaData.getName()
+ );
+ }
+ binding.setPropertyMetaData(propertyMetaData);
+ }
+
+ AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
+ if(addMethodMetaData != null)
+ {
+ if (ctx.trace)
+ {
+ log.trace("complex type " +
+ type.getName() +
+ ": elements of this type will be added to parent objects with addMethod=" +
+ addMethodMetaData.getMethodName() + ", valueType=" + addMethodMetaData.getValueType()
+ );
+ }
+ binding.setAddMethodMetaData(addMethodMetaData);
+ }
+ }
+ }
+ }
+ }
+
+ XSParticle particle = type.getParticle();
+ if(particle != null)
+ {
+ ctx.pushType(binding);
+ bindParticle(ctx, particle);
+ ctx.popType();
+ }
+
+ if(binding.getClassMetaData() == null &&
+ ctx.simpleContentWithIdAsSimpleType &&
+ particle == null && hasOnlyIdAttrs)
+ {
+ binding.setStartElementCreatesObject(false);System.out.println("no object for " + binding.getQName());
+ }
+ else
+ {
+ binding.setStartElementCreatesObject(true);
+ }
+
+ if(binding.hasOnlyXmlMimeAttributes())
+ {
+ addXOPInclude(binding, ctx.schema);
+ }
+
+ if(ctx.trace)
+ {
+ log.trace(typeName == null ? "bound complex anonymous type" : "bound complex type " + typeName);
+ }
+
+ return binding;
+ }
+
+ private static AttributeBinding bindAttributes(Context ctx, TypeBinding type, XSAttributeUse attrUse)
+ {
+ XSAttributeDeclaration attr = attrUse.getAttrDeclaration();
+ QName attrName = new QName(attr.getNamespace(), attr.getName());
+
+ if (ctx.trace)
+ {
+ log.trace("binding attribute " + attrName + " for " + type.getQName() + ", required=" + attrUse.getRequired());
+ }
+
+ XSSimpleTypeDefinition attrType = attr.getTypeDefinition();
+ TypeBinding typeBinding = bindSimpleType(ctx, attrType);
+ AttributeBinding binding = type.addAttribute(attrName, typeBinding, DefaultHandlers.ATTRIBUTE_HANDLER);
+ binding.setRequired(attrUse.getRequired());
+ if(attrUse.getConstraintType() == XSConstants.VC_DEFAULT)
+ {
+ // Associate the default value with the binding
+ binding.setDefaultConstraint(attrUse.getConstraintValue());
+ }
+
+ if (ctx.processAnnotations)
+ {
+ XSAnnotation an = attr.getAnnotation();
+ if(an != null)
+ {
+ if (ctx.trace)
+ {
+ log.trace(attrName + " attribute annotation");
+ }
+
+ XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+ XsdAppInfo appInfo = xsdAn.getAppInfo();
+ if(appInfo != null)
+ {
+ PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+ if(propertyMetaData != null)
+ {
+ binding.setPropertyMetaData(propertyMetaData);
+ }
+
+ boolean mapEntryKey = appInfo.isMapEntryKey();
+ if(mapEntryKey)
+ {
+ binding.setMapEntryKey(mapEntryKey);
+ }
+
+ boolean mapEntryValue = appInfo.isMapEntryValue();
+ if(mapEntryValue)
+ {
+ binding.setMapEntryValue(mapEntryValue);
+ }
+ }
+ }
+ }
+
+
+ if (ctx.trace)
+ {
+ String msg = "bound attribute " + attrName;
+
+ if(binding.getPropertyMetaData() != null)
+ {
+ msg += " property=" +
+ binding.getPropertyMetaData().getName() +
+ ", collectionType=" + binding.getPropertyMetaData().getCollectionType();
+ }
+ else if(binding.isMapEntryKey())
+ {
+ msg += "bound as a key in a map entry";
+ }
+ else if(binding.isMapEntryValue())
+ {
+ msg += "bound as a value in a map entry";
+ }
+ else
+ {
+ msg += " type=" + attrType.getName() + ", owner type=" + type.getQName();
+ }
+
+ if(binding.getDefaultConstraint() != null)
+ {
+ msg += ", default=" + binding.getDefaultConstraint();
+ }
+
+ log.trace(msg);
+ }
+
+ return binding;
+ }
+
+ private static void bindParticle(Context ctx, XSParticle particle)
+ {
+ XSTerm term = particle.getTerm();
+ switch(term.getType())
+ {
+ case XSConstants.MODEL_GROUP:
+ XSModelGroup modelGroup = (XSModelGroup)term;
+ // todo: investigate this
+ if(modelGroup.getParticles().getLength() > 0)
+ {
+ ModelGroupBinding groupBinding;
+ switch(modelGroup.getCompositor())
+ {
+ case XSModelGroup.COMPOSITOR_ALL:
+ groupBinding = new AllBinding(ctx.schema);
+ break;
+ case XSModelGroup.COMPOSITOR_CHOICE:
+ groupBinding = new ChoiceBinding(ctx.schema);
+ break;
+ case XSModelGroup.COMPOSITOR_SEQUENCE:
+ groupBinding = new SequenceBinding(ctx.schema);
+ break;
+ default:
+ throw new JBossXBRuntimeException("Unexpected model group: " + modelGroup.getCompositor());
+ }
+
+ ParticleBinding particleBinding = new ParticleBinding(groupBinding);
+ particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
+ particleBinding.setMinOccurs(particle.getMinOccurs());
+ particleBinding.setMaxOccurs(particle.getMaxOccurs());
+
+ if (ctx.trace)
+ {
+ log.trace("created model group " + groupBinding);
+ }
+
+ if (ctx.processAnnotations)
+ {
+ XSAnnotation annotation = modelGroup.getAnnotation();
+ if(annotation != null)
+ {
+ customizeTerm(annotation, groupBinding, ctx.trace);
+ }
+ }
+
+ Object o = ctx.peekTypeOrGroup();
+ if(o instanceof ModelGroupBinding)
+ {
+ ModelGroupBinding parentGroup = (ModelGroupBinding)o;
+ parentGroup.addParticle(particleBinding);
+ if (ctx.trace)
+ {
+ log.trace("added " + groupBinding + " to " + parentGroup);
+ }
+ }
+ else if(o instanceof TypeBinding)
+ {
+ TypeBinding typeBinding = (TypeBinding)o;
+ typeBinding.setParticle(particleBinding);
+ if (ctx.trace)
+ {
+ log.trace("added " + groupBinding + " to type " + typeBinding.getQName());
+ }
+ }
+
+ ctx.pushModelGroup(groupBinding);
+ bindModelGroup(ctx, modelGroup);
+ ctx.popModelGroup();
+ }
+ break;
+ case XSConstants.WILDCARD:
+ bindWildcard(ctx, particle);
+ break;
+ case XSConstants.ELEMENT_DECLARATION:
+ bindElement(ctx,
+ (XSElementDeclaration)term,
+ particle.getMinOccurs(),
+ particle.getMaxOccurs(),
+ particle.getMaxOccursUnbounded()
+ );
+ break;
+ default:
+ throw new IllegalStateException("Unexpected term type: " + term.getType());
+ }
+ }
+
+ private static void bindWildcard(Context ctx, XSParticle particle)
+ {
+ WildcardBinding binding = new WildcardBinding(ctx.schema);
+
+ ModelGroupBinding group = (ModelGroupBinding)ctx.peekTypeOrGroup();
+ ParticleBinding particleBinding = new ParticleBinding(binding);
+ particleBinding.setMaxOccurs(particle.getMaxOccurs());
+ particleBinding.setMaxOccursUnbounded(particle.getMaxOccursUnbounded());
+ particleBinding.setMinOccurs(particle.getMinOccurs());
+ group.addParticle(particleBinding);
+
+ XSWildcard wildcard = (XSWildcard)particle.getTerm();
+ if(wildcard.getName() != null)
+ {
+ binding.setQName(new QName(wildcard.getNamespace(), wildcard.getName()));
+ }
+
+ binding.setProcessContents(wildcard.getProcessContents());
+
+ if (ctx.processAnnotations)
+ {
+ XSAnnotation annotation = wildcard.getAnnotation();
+ if(annotation != null)
+ {
+ customizeTerm(annotation, binding, ctx.trace);
+ }
+ }
+ }
+
+ private static ParticleBinding bindElement(Context ctx,
+ XSElementDeclaration elementDec,
+ int minOccurs,
+ int maxOccurs,
+ boolean maxOccursUnbounded)
+ {
+ QName qName = new QName(elementDec.getNamespace(), elementDec.getName());
+
+ ModelGroupBinding parentGroup = (ModelGroupBinding)ctx.peekTypeOrGroup();
+
+ boolean global = elementDec.getScope() == XSConstants.SCOPE_GLOBAL;
+ ElementBinding element = ctx.schema.getElement(qName);
+ ParticleBinding particle;
+ if(global && element != null)
+ {
+ particle = new ParticleBinding(element);
+ if(parentGroup != null)
+ {
+ parentGroup.addParticle(particle);
+ }
+
+ particle.setMinOccurs(minOccurs);
+ if(maxOccursUnbounded)
+ {
+ particle.setMaxOccursUnbounded(maxOccursUnbounded);
+ }
+ else
+ {
+ particle.setMaxOccurs(maxOccurs);
+ }
+
+ return particle;
+ }
+
+ TypeBinding type = null;
+
+ boolean shared = ctx.sharedElements.isShared(elementDec);
+ if(shared)
+ {
+ type = ctx.sharedElements.getTypeBinding(elementDec);
+ }
+
+ if(type == null)
+ {
+ type = bindType(ctx, elementDec.getTypeDefinition());
+ if(shared)
+ {
+ ctx.sharedElements.setTypeBinding(elementDec, type);
+ }
+ }
+
+ element = new ElementBinding(ctx.schema, qName, type);
+ element.setNillable(elementDec.getNillable());
+ particle = new ParticleBinding(element);
+ particle.setMinOccurs(minOccurs);
+ particle.setMaxOccurs(maxOccurs);
+ particle.setMaxOccursUnbounded(maxOccursUnbounded);
+ if(global)
+ {
+ ctx.schema.addElementParticle(particle);
+ }
+
+ if(parentGroup != null)
+ {
+ parentGroup.addParticle(particle);
+ if (ctx.trace)
+ {
+ log.trace("Element " + element.getQName() + " added to " + parentGroup);
+ }
+ }
+
+ if (ctx.trace)
+ {
+ TypeBinding parentType = ctx.peekType();
+ log.trace("element: name=" +
+ qName +
+ ", type=" +
+ type.getQName() +
+ ", repeatable=" +
+ particle.isRepeatable() +
+ ", nillable=" +
+ element.isNillable() +
+ ", minOccurs=" + minOccurs +
+ ", maxOccurs=" + (maxOccursUnbounded ? "unbounded" : "" + maxOccurs) +
+ ", " + (global ? "global scope" : " owner type=" + parentType.getQName())
+ );
+ }
+
+ // customize element with annotations
+ if (ctx.processAnnotations)
+ {
+ XSAnnotation an = elementDec.getAnnotation();
+ if(an != null)
+ {
+ customizeTerm(an, element, ctx.trace);
+ }
+ }
+ return particle;
+ }
+
+ private static void bindModelGroup(Context ctx, XSModelGroup modelGroup)
+ {
+ XSObjectList particles = modelGroup.getParticles();
+ for(int i = 0; i < particles.getLength(); ++i)
+ {
+ XSParticle particle = (XSParticle)particles.item(i);
+ bindParticle(ctx, particle);
+ }
+ }
+
+ // Private
+
+ private static void addXOPInclude(TypeBinding binding, SchemaBinding schema)
+ {
+ binding.setHandler(DefaultHandlers.XOP_HANDLER);
+ if(binding.getParticle() != null)
+ {
+ throw new JBossXBRuntimeException(
+ "XOP optimizable type has a particle which is unexpected, please, open a JIRA issue!"
+ );
+ }
+
+ TypeBinding anyUriType = schema.getType(Constants.QNAME_ANYURI);
+ if(anyUriType == null)
+ {
+ log.warn("Type " + Constants.QNAME_ANYURI + " not bound.");
+ }
+
+ TypeBinding xopIncludeType = new TypeBinding(new QName(Constants.NS_XOP_INCLUDE, "Include"));
+ xopIncludeType.setSchemaBinding(schema);
+ xopIncludeType.addAttribute(new QName("href"), anyUriType, DefaultHandlers.ATTRIBUTE_HANDLER);
+ xopIncludeType.setHandler(new XOPIncludeHandler(binding));
+
+ ElementBinding xopInclude = new ElementBinding(schema, new QName(Constants.NS_XOP_INCLUDE, "Include"), xopIncludeType);
+
+ ParticleBinding particleBinding = new ParticleBinding(xopInclude);
+ particleBinding.setMinOccurs(0);
+
+ binding.addParticle(particleBinding);
+ }
+
+ private static void customizeTerm(XSAnnotation an, TermBinding term, boolean trace)
+ {
+ XsdAnnotation xsdAn = XsdAnnotation.unmarshal(an.getAnnotationString());
+ XsdAppInfo appInfo = xsdAn.getAppInfo();
+ if(appInfo != null)
+ {
+ Boolean skip = null;
+
+ ClassMetaData classMetaData = appInfo.getClassMetaData();
+ if(classMetaData != null)
+ {
+ if (trace)
+ {
+ String msg;
+ if(term.isModelGroup())
+ {
+ msg = term + " bound to ";
+ }
+ else if(term.isWildcard())
+ {
+ msg = " wildcard bound to ";
+ }
+ else
+ {
+ msg = "element: name=" + ((ElementBinding)term).getQName() + ", class=";
+ }
+
+ msg += classMetaData.getImpl();
+ log.trace(msg);
+ }
+ term.setClassMetaData(classMetaData);
+ skip = Boolean.FALSE;
+ }
+
+ PropertyMetaData propertyMetaData = appInfo.getPropertyMetaData();
+ if(propertyMetaData != null)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term + " " : "element: name=" +
+ ((ElementBinding)term).getQName() + ", ";
+ msg += " property=" +
+ propertyMetaData.getName() +
+ ", collectionType=" + propertyMetaData.getCollectionType();
+ log.trace(msg);
+ }
+ term.setPropertyMetaData(propertyMetaData);
+ }
+
+ MapEntryMetaData mapEntryMetaData = appInfo.getMapEntryMetaData();
+ if(mapEntryMetaData != null)
+ {
+ if(propertyMetaData != null)
+ {
+ String msg = "A term can be bound either as a property or as a map" +
+ " entry but not both: " +
+ (term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
+ throw new JBossXBRuntimeException(msg);
+ }
+
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+ ((ElementBinding)term).getQName();
+
+ msg += " is bound to a map entry: impl=" +
+ mapEntryMetaData.getImpl() +
+ ", getKeyMethod=" +
+ mapEntryMetaData.getGetKeyMethod() +
+ ", setKeyMethod=" +
+ mapEntryMetaData.getSetKeyMethod() +
+ ", getValueMethod=" +
+ mapEntryMetaData.getGetValueMethod() +
+ ", setValueMethod=" +
+ mapEntryMetaData.getSetValueMethod() +
+ ", valueType=" +
+ mapEntryMetaData.getValueType() +
+ ", nonNullValue=" + mapEntryMetaData.isNonNullValue();
+ log.trace(msg);
+ }
+
+ if(classMetaData != null)
+ {
+ String msg = "Invalid customization: both jbxb:class and jbxb:mapEntry are specified for term " +
+ (term.isWildcard() || term.isModelGroup() ? term.toString() : ((ElementBinding)term).getQName().toString());
+ throw new JBossXBRuntimeException(msg);
+ }
+ term.setMapEntryMetaData(mapEntryMetaData);
+ skip = Boolean.FALSE;
+ }
+
+ PutMethodMetaData putMethodMetaData = appInfo.getPutMethodMetaData();
+ if(putMethodMetaData != null)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
+ ((ElementBinding)term).getQName() + ",";
+
+ msg += " putMethod=" +
+ putMethodMetaData.getName() +
+ ", keyType=" +
+ putMethodMetaData.getKeyType() +
+ ", valueType=" + putMethodMetaData.getValueType();
+ log.trace(msg);
+ }
+ term.setPutMethodMetaData(putMethodMetaData);
+ }
+
+ AddMethodMetaData addMethodMetaData = appInfo.getAddMethodMetaData();
+ if(addMethodMetaData != null)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element: name=" +
+ ((ElementBinding)term).getQName() + ",";
+ msg += " addMethod=" +
+ addMethodMetaData.getMethodName() +
+ ", valueType=" +
+ addMethodMetaData.getValueType() +
+ ", isChildType=" + addMethodMetaData.isChildType();
+ log.trace(msg);
+ }
+ term.setAddMethodMetaData(addMethodMetaData);
+ }
+
+ ValueMetaData valueMetaData = appInfo.getValueMetaData();
+ if(valueMetaData != null)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element " +
+ ((ElementBinding)term).getQName();
+ msg += ": unmarshalMethod=" + valueMetaData.getUnmarshalMethod();
+ log.trace(msg);
+ }
+ term.setValueMetaData(valueMetaData);
+ }
+
+ boolean mapEntryKey = appInfo.isMapEntryKey();
+ if(mapEntryKey)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+ ((ElementBinding)term).getQName();
+ msg += ": is bound to a key in a map entry";
+ log.trace(msg);
+ }
+ term.setMapEntryKey(mapEntryKey);
+ skip = Boolean.FALSE;
+ }
+
+ boolean mapEntryValue = appInfo.isMapEntryValue();
+ if(mapEntryValue)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+ ((ElementBinding)term).getQName();
+ msg += ": is bound to a value in a map entry";
+ log.trace(msg);
+ }
+ term.setMapEntryValue(mapEntryValue);
+ skip = Boolean.FALSE;
+ }
+
+ boolean skipAnnotation = appInfo.isSkip();
+ if(skip != null)
+ {
+ term.setSkip(skip);
+ }
+ else if(skipAnnotation)
+ {
+ if (trace)
+ {
+ String msg = term.isWildcard() || term.isModelGroup() ? term.toString() : "element name=" +
+ ((ElementBinding)term).getQName();
+ msg += ": will be skipped, it's attributes, character content and children will be set on the parent";
+ log.trace(msg);
+ }
+ term.setSkip(skipAnnotation ? Boolean.TRUE : Boolean.FALSE);
+ }
+ }
+ }
+
+ private static void bindGlobalGroup(XSModelGroup group, SharedElements sharedElements)
+ {
+ XSObjectList particles = group.getParticles();
+ for(int j = 0; j < particles.getLength(); ++j)
+ {
+ XSParticle particle = (XSParticle)particles.item(j);
+ XSTerm term = particle.getTerm();
+ switch(term.getType())
+ {
+ case XSConstants.ELEMENT_DECLARATION:
+ XSElementDeclaration element = ((XSElementDeclaration)term);
+ sharedElements.add(element);
+ break;
+ case XSConstants.WILDCARD:
+ // todo is it actually possible?
+ break;
+ case XSConstants.MODEL_GROUP:
+ bindGlobalGroup((XSModelGroup)term, sharedElements);
+ }
+ }
+ }
+
+
+ // Inner
+
+ private static final class SharedElements
+ {
+ private Map elements = Collections.EMPTY_MAP;
+
+ public void add(XSElementDeclaration element)
+ {
+ switch(elements.size())
+ {
+ case 0:
+ elements = Collections.singletonMap(element, null);
+ break;
+ case 1:
+ elements = new HashMap(elements);
+ default:
+ elements.put(element, null);
+ }
+ }
+
+ public boolean isShared(XSElementDeclaration element)
+ {
+ return elements.containsKey(element);
+ }
+
+ public TypeBinding getTypeBinding(XSElementDeclaration element)
+ {
+ return (TypeBinding)elements.get(element);
+ }
+
+ public void setTypeBinding(XSElementDeclaration element, TypeBinding type)
+ {
+ switch(elements.size())
+ {
+ case 0:
+ elements = Collections.singletonMap(element, type);
+ break;
+ case 1:
+ elements = new HashMap(elements);
+ default:
+ elements.put(element, type);
+ }
+ }
+ }
+
+ private static final class Context
+ {
+ public final SchemaBinding schema;
+ public SharedElements sharedElements = new SharedElements();
+ public boolean processAnnotations = true;
+ public boolean simpleContentWithIdAsSimpleType = true;
+ public boolean trace = log.isTraceEnabled();
+ private final List typeGroupStack = new ArrayList();
+
+ public Context()
+ {
+ this(new SchemaBinding());
+ }
+
+ public Context(SchemaBinding schema)
+ {
+ this.schema = schema;
+ }
+
+ public void popType()
+ {
+ Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
+ if(!(o instanceof TypeBinding))
+ {
+ throw new JBossXBRuntimeException("Should have poped type binding but got " + o);
+ }
+ }
+
+ public void pushType(TypeBinding binding)
+ {
+ typeGroupStack.add(binding);
+ }
+
+ public void popModelGroup()
+ {
+ Object o = typeGroupStack.remove(typeGroupStack.size() - 1);
+ if(!(o instanceof ModelGroupBinding))
+ {
+ throw new JBossXBRuntimeException("Should have poped model group binding but got " + o);
+ }
+ }
+
+ public void pushModelGroup(ModelGroupBinding binding)
+ {
+ typeGroupStack.add(binding);
+ }
+
+ public Object peekTypeOrGroup()
+ {
+ return typeGroupStack.isEmpty() ? null : typeGroupStack.get(typeGroupStack.size() - 1);
+ }
+
+ public TypeBinding peekType()
+ {
+ TypeBinding binding = null;
+ for(ListIterator i = typeGroupStack.listIterator(typeGroupStack.size()); i.hasPrevious();)
+ {
+ Object o = i.previous();
+ if(o instanceof TypeBinding)
+ {
+ binding = (TypeBinding)o;
+ break;
+ }
+ }
+ return binding;
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java
===================================================================
--- jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,1445 +0,0 @@
-/*
- * 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.xb.binding.sunday.unmarshalling.impl.runtime;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Map;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.namespace.QName;
-import org.jboss.logging.Logger;
-import org.jboss.util.Classes;
-import org.jboss.xb.binding.Constants;
-import org.jboss.xb.binding.GenericValueContainer;
-import org.jboss.xb.binding.JBossXBRuntimeException;
-import org.jboss.xb.binding.SimpleTypeBindings;
-import org.jboss.xb.binding.Util;
-import org.jboss.xb.binding.introspection.FieldInfo;
-import org.jboss.xb.binding.group.ValueList;
-import org.jboss.xb.binding.group.ValueListHandler;
-import org.jboss.xb.binding.group.ValueListInitializer;
-import org.jboss.xb.binding.metadata.AddMethodMetaData;
-import org.jboss.xb.binding.metadata.ClassMetaData;
-import org.jboss.xb.binding.metadata.MapEntryMetaData;
-import org.jboss.xb.binding.metadata.PackageMetaData;
-import org.jboss.xb.binding.metadata.PropertyMetaData;
-import org.jboss.xb.binding.metadata.PutMethodMetaData;
-import org.jboss.xb.binding.metadata.ValueMetaData;
-import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
-import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
-import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
-import org.xml.sax.Attributes;
-
-/**
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision$</tt>
- */
-public class RtElementHandler
- implements ParticleHandler
-{
- private static final Logger log = Logger.getLogger(RtElementHandler.class);
-
- public static final RtElementHandler INSTANCE = new RtElementHandler();
-
- // ParticleHandler impl
-
- /**
- * TODO: it seems like for correct type resolution in startParticle
- * I should take into account the way the object is going to be added
- * to the parent in setParent (and, hence, do some steps that are done in setParticle).
- * In setParent then I should reuse the results of what has been done in startParticle.
- */
- public Object startParticle(Object parent,
- QName elementName,
- ParticleBinding particle,
- Attributes attrs,
- NamespaceContext nsCtx)
- {
- TermBinding term = particle.getTerm();
- Object o = startElement(parent, elementName, particle);
- if(!term.isModelGroup())
- {
- ElementBinding element = (ElementBinding)term;
- if(o != null)
- {
- attrs = element.getType().expandWithDefaultAttributes(attrs);
- attributes(o, elementName, element, attrs, nsCtx);
- }
- }
- return o;
- }
-
- public void setParent(Object parent,
- Object o,
- QName qName,
- ParticleBinding particle,
- ParticleBinding parentParticle)
- {
- TermBinding term = particle.getTerm();
- if(term.isSkip())
- {
- return;
- }
-
- boolean trace = log.isTraceEnabled();
- if(trace)
- {
- log.trace("setParent " + qName + " parent=" + parent + " object=" + o + " term=" + term);
- }
-
- TermBinding parentTerm = parentParticle.getTerm();
-
- if(term.isMapEntryKey())
- {
- if(trace)
- {
- log.trace("setParent " + qName + " mapKey");
- }
-
- if(parent instanceof MapEntry)
- {
- MapEntry mapEntry = (MapEntry)parent;
- mapEntry.setKey(o);
- }
- else if(parentTerm != null)
- {
- MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
-
- String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
- if(getKeyMethodName == null)
- {
- getKeyMethodName = "getKey";
- }
-
- String setKeyMethodName = mapEntryMetaData.getSetKeyMethod();
- if(setKeyMethodName == null)
- {
- setKeyMethodName = "setKey";
- }
-
- Class parentCls = parent.getClass();
- Method setKeyMethod = getSetMethod(parentCls, getKeyMethodName, setKeyMethodName);
- invokeSetter(setKeyMethod, parent, o, setKeyMethodName);
- }
- else
- {
- throw new JBossXBRuntimeException(
- "Element " +
- qName +
- " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
- );
- }
- }
- else if(term.isMapEntryValue())
- {
- if(trace)
- {
- log.trace("setParent " + qName + " mapValue");
- }
-
- if(parent instanceof MapEntry)
- {
- MapEntry mapEntry = (MapEntry)parent;
- mapEntry.setValue(o);
- }
- else if(parentTerm != null)
- {
- MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
- setMapEntryValue(mapEntryMetaData, parent, o);
- }
- else
- {
- throw new JBossXBRuntimeException(
- "Element " +
- qName +
- " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
- );
- }
- }
- else
- {
- Object owner = parent;
- if(parent instanceof MapEntry)
- {
- if(trace)
- {
- log.trace("setParent " + qName + " mapEntry");
- }
-
- MapEntry mapEntry = (MapEntry)parent;
- owner = mapEntry.getValue();
- if(owner == null)
- {
- if(parentTerm == null)
- {
- throw new JBossXBRuntimeException("Binding metadata needed for lazy map entry value instantiation is not available " +
- "for parent element of element " +
- qName
- );
- }
-
- MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
- String valueType = mapEntryMetaData.getValueType();
- if(valueType == null)
- {
- throw new JBossXBRuntimeException("Element " +
- qName +
- " is supposed to be bound as map entry value with lazy value instantiation " +
- "but value type is not specified in its map entry metadata."
- );
- }
-
- Class valueCls;
- try
- {
- valueCls = Thread.currentThread().getContextClassLoader().loadClass(valueType);
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException(
- "Failed to load value type specified in the map entry metadata: " + valueType
- );
- }
-
- try
- {
- owner = valueCls.newInstance();
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException(
- "Failed to create an instance of value type " + valueType + ": " + e.getMessage()
- );
- }
-
- setMapEntryValue(mapEntryMetaData, parent, owner);
- }
- }
-
- // the wildcard this element is a content of
- WildcardBinding wildcard = null;
- if(parentTerm != null && !parentTerm.isModelGroup())
- {
- ElementBinding parentElement = (ElementBinding)parentTerm;
- TypeBinding parentType = parentElement.getType();
- wildcard = parentType.getWildcard();
- // there should be a better way of checking this
- if(wildcard != null && parentType.getElement(qName) != null)
- {
- wildcard = null;
- }
- }
-
- if(tryPut(owner, o, qName, term, trace))
- {
- }
- else if(tryAdd(owner, o, qName, term, wildcard, trace))
- {
- }
- else if (owner instanceof GenericValueContainer)
- {
- if (trace)
- {
- log.trace("setParent " + qName + " addChild");
- }
- ((GenericValueContainer) owner).addChild(qName, o);
- }
- else if (owner instanceof Collection)
- {
- if (trace)
- {
- log.trace("setParent " + qName + " collection.add()");
- }
- ((Collection) owner).add(o);
- }
- else
- {
- PropertyMetaData propertyMetaData = wildcard == null ? null : wildcard.getPropertyMetaData();
- if (propertyMetaData == null)
- {
- propertyMetaData = term.getPropertyMetaData();
- }
-
- String propName = null;
- String colType = null;
- if (propertyMetaData != null)
- {
- propName = propertyMetaData.getName();
- colType = propertyMetaData.getCollectionType();
- }
-
- if (propName == null)
- {
- propName = Util.xmlNameToFieldName(qName.getLocalPart(), term.getSchema().isIgnoreLowLine());
- }
-
- if (trace)
- {
- log.trace("setParent " + qName + " metadata set " + propName);
- }
-
- /*if(particle.isRepeatable())
- {
- RtUtil.add(owner, o, propName, colType,
- term.getSchema().isIgnoreUnresolvedFieldOrClass(),
- term.getValueAdapter()
- );
- }
- else
- {*/
- RtUtil.set(owner, o, propName, colType,
- term.getSchema().isIgnoreUnresolvedFieldOrClass(),
- term.getValueAdapter());
- //}
- }
- }
- }
-
- public Object endParticle(Object o, QName elementName, ParticleBinding particle)
- {
- TermBinding term = particle.getTerm();
- if(term.isSkip())
- {
- return o;
- }
-
- boolean trace = log.isTraceEnabled();
- if(trace)
- {
- log.trace("endParticle " + elementName + " object=" + o + " term=" + term);
- }
-
- if(o instanceof GenericValueContainer)
- {
- try
- {
- if(trace)
- {
- log.trace("endParticle " + elementName + " instantiate()");
- }
- o = ((GenericValueContainer)o).instantiate();
- }
- catch(JBossXBRuntimeException e)
- {
- throw e;
- }
- catch(RuntimeException e)
- {
- throw new JBossXBRuntimeException("Container failed to create an instance for " +
- elementName +
- ": " + e.getMessage(), e
- );
- }
- }
-
- return o;
- }
-
- // Private
-
- private Object startElement(Object parent, QName elementName, ParticleBinding particle)
- {
- TermBinding term = particle.getTerm();
- if(term.isSkip())
- {
- return parent;
- }
-
- boolean trace = log.isTraceEnabled();
- if(trace)
- {
- log.trace("startElement " + elementName + " parent=" + parent + " term=" + term);
- }
-
- ClassMetaData classMetaData = term.getClassMetaData();
- MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
-
- if(!term.isModelGroup())
- {
- TypeBinding type = ((ElementBinding)term).getType();
- if(!type.isStartElementCreatesObject() ||
- classMetaData == null && mapEntryMetaData == null && Constants.QNAME_ANYTYPE.equals(type.getQName()))
- {
- if(trace)
- {
- log.trace("startElement " + elementName + " does not create an object");
- }
- return null;
- }
- }
-
- Object o = null;
-
- // if addMethod is specified, it's probably some collection field
- // but should not be set as a property. Instead, items are added to it using the addMethod
- ElementBinding arrayItem = null;
- if(!term.isModelGroup())
- {
- TypeBinding type = ((ElementBinding)term).getType();
- if(type.getAttributes().isEmpty())
- {
- ParticleBinding typeParticle = type.getParticle();
- ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
- arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
-
- // todo refactor later (move it to modelGroup.getArrayItem()?)
- if(arrayItem != null &&
- (arrayItem.isSkip() ||
- arrayItem.getMapEntryMetaData() != null ||
- arrayItem.getPutMethodMetaData() != null ||
- arrayItem.getAddMethodMetaData() != null
- ))
- {
- arrayItem = null;
- }
- }
- }
-
- if(arrayItem != null)
- {
- Class wrapperType = null;
- if(classMetaData != null)
- {
- wrapperType = loadClassForTerm(classMetaData.getImpl(),
- term.getSchema().isIgnoreUnresolvedFieldOrClass(),
- elementName
- );
-
- if(GenericValueContainer.class.isAssignableFrom(wrapperType) ||
- Collection.class.isAssignableFrom(wrapperType) ||
- Map.class.isAssignableFrom(wrapperType))
- {
- return newInstance(wrapperType, elementName, term.getSchema().isUseNoArgCtorIfFound());
- }
- }
-
- if(wrapperType == null && parent == null)
- {
- Class itemType = classForElement(arrayItem, null);
- if(itemType != null)
- {
- if(trace)
- {
- log.trace("startElement " + elementName + " new array " + itemType.getName());
- }
- o = GenericValueContainer.FACTORY.array(itemType);
- }
- }
- else
- {
- PropertyMetaData propertyMetaData = wrapperType == null ?
- term.getPropertyMetaData() : arrayItem.getPropertyMetaData();
-
- String propName;
- if(propertyMetaData == null)
- {
- propName = Util.xmlNameToFieldName(
- wrapperType == null ? elementName.getLocalPart() : arrayItem.getQName().getLocalPart(),
- term.getSchema().isIgnoreLowLine()
- );
- }
- else
- {
- propName = propertyMetaData.getName();
- }
-
- if(trace)
- {
- log.trace("startElement " + elementName + " property=" + propName);
- }
-
- Class parentClass = wrapperType;
- if(wrapperType == null)
- {
- if(parent instanceof GenericValueContainer)
- {
- parentClass = ((GenericValueContainer)parent).getTargetClass();
- }
- else if(parent instanceof ValueList)
- {
- parentClass = ((ValueList)parent).getTargetClass();
- }
- else
- {
- parentClass = parent.getClass();
- }
- }
-
- Class fieldType;
- if(parentClass.isArray())
- {
- fieldType = parentClass.getComponentType();
- }
- else
- {
- fieldType = FieldInfo.getFieldInfo(parentClass, propName, true).getType();
- if(particle.isRepeatable() && fieldType.isArray())
- {
- fieldType = fieldType.getComponentType();
- }
- }
-
- if(fieldType.isArray())
- {
- o = GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType.getComponentType());
- }
- else if(Collection.class.isAssignableFrom(fieldType))
- {
- //System.out.println("GeenericValueContainer.child: " + elementName);
- o = new ValueListInitializer().newValueList(ValueListHandler.FACTORY.child(), Collection.class);
- //o = new ArrayList();
- }
- else
- {
- o = GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType);
- }
- }
- }
- else
- {
- if(mapEntryMetaData != null)
- {
- if(mapEntryMetaData.getImpl() != null)
- {
- Class cls = loadClassForTerm(mapEntryMetaData.getImpl(),
- term.getSchema().isIgnoreUnresolvedFieldOrClass(),
- elementName
- );
-
- if(trace)
- {
- log.trace("startElement " + elementName + " new map entry " + cls.getName());
- }
-
- o = newInstance(cls, elementName, term.getSchema().isUseNoArgCtorIfFound());
- }
- else
- {
- o = new MapEntry();
- if(trace)
- {
- log.trace("startElement " + elementName + " new map entry");
- }
- }
-
- if(mapEntryMetaData.isNonNullValue() && mapEntryMetaData.getValueType() != null)
- {
- Class mapValueType;
- try
- {
- mapValueType =
- Thread.currentThread().getContextClassLoader().loadClass(mapEntryMetaData.getValueType());
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException("startElement failed for " +
- elementName +
- ": failed to load class " +
- mapEntryMetaData.getValueType() +
- " for map entry value."
- );
- }
-
- Object value;
- try
- {
- if(trace)
- {
- log.trace("startElement " + elementName + " map value type " + mapEntryMetaData.getValueType());
- }
- value = mapValueType.newInstance();
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("startElement failed for " +
- elementName +
- ": failed to create an instance of " +
- mapValueType +
- " for map entry value."
- );
- }
-
- if(o instanceof MapEntry)
- {
- ((MapEntry)o).setValue(value);
- }
- else
- {
- String getValueMethodName = mapEntryMetaData.getGetValueMethod();
- if(getValueMethodName == null)
- {
- getValueMethodName = "getValue";
- }
-
- String setValueMethodName = mapEntryMetaData.getSetValueMethod();
- if(setValueMethodName == null)
- {
- setValueMethodName = "setValue";
- }
-
- Method getValueMethod;
- try
- {
- getValueMethod = o.getClass().getMethod(getValueMethodName, null);
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("getValueMethod=" +
- getValueMethodName +
- " is not found in map entry " + o.getClass()
- );
- }
-
- Method setValueMethod;
- try
- {
- setValueMethod =
- o.getClass().getMethod(setValueMethodName, new Class[]{getValueMethod.getReturnType()});
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("setValueMethod=" +
- setValueMethodName +
- "(" +
- getValueMethod.getReturnType().getName() +
- " value) is not found in map entry " + o.getClass()
- );
- }
-
- try
- {
- setValueMethod.invoke(o, new Object[]{value});
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("setValueMethod=" +
- setValueMethodName +
- " failed: owner=" +
- o +
- ", value=" + value + ", msg=" + e.getMessage(), e
- );
- }
- }
- }
- }
- else
- {
- // todo: for now we require metadata for model groups to be bound
- // todo 2: parent.getClass() is not going to work for containers
- Class parentClass = null;
- if(parent != null)
- {
- if(parent instanceof GenericValueContainer)
- {
- parentClass = ((GenericValueContainer)parent).getTargetClass();
- }
- else if(parent instanceof ValueList)
- {
- parentClass = ((ValueList)parent).getTargetClass();
- }
- else
- {
- parentClass = parent.getClass();
- }
- }
-
- Class cls;
- if(term.isModelGroup())
- {
- if(classMetaData == null)
- {
- throw new JBossXBRuntimeException(
- "Model groups should be annotated with 'class' annotation to be bound."
- );
- }
- cls = loadClassForTerm(classMetaData.getImpl(),
- term.getSchema().isIgnoreUnresolvedFieldOrClass(),
- elementName
- );
- }
- else
- {
- ElementBinding element = (ElementBinding)term;
- cls = classForNonArrayItem(element, parentClass);
- if(cls != null)
- {
- // todo: before that, the type should be checked for required attributes and elements
- TypeBinding simpleType = element.getType().getSimpleType();
- if(simpleType != null)
- {
- Class simpleCls = classForSimpleType(simpleType, element.isNillable());
- if(cls.equals(simpleCls) ||
- cls.isPrimitive() && Classes.getPrimitiveWrapper(cls) == simpleCls ||
- simpleCls.isPrimitive() && Classes.getPrimitiveWrapper(simpleCls) == cls)
- {
- cls = null;
- }
- }
- }
- }
-
- if(cls != null)
- {
- boolean noArgCtor;
- if(classMetaData == null)
- {
- noArgCtor = term.getSchema().isUseNoArgCtorIfFound();
- }
- else
- {
- Boolean termUsesNoArgCtor = classMetaData.isUseNoArgCtor();
- noArgCtor = termUsesNoArgCtor == null ?
- term.getSchema().isUseNoArgCtorIfFound() : termUsesNoArgCtor.booleanValue(); }
-
- if(trace)
- {
- log.trace("startElement " + elementName + " new " + cls.getName() + ", noArgCtor=" + noArgCtor);
- }
- o = newInstance(cls, elementName, noArgCtor);
- }
- }
- }
- return o;
- }
-
- private void attributes(Object o,
- QName elementName,
- ElementBinding element,
- Attributes attrs,
- NamespaceContext nsCtx)
- {
- TypeBinding type = element.getType();
- for(int i = 0; i < attrs.getLength(); ++i)
- {
- QName attrName = new QName(attrs.getURI(i), attrs.getLocalName(i));
- AttributeBinding binding = type.getAttribute(attrName);
- if(binding != null)
- {
- AttributeHandler handler = binding.getHandler();
- if(handler != null)
- {
- Object value = handler.unmarshal(elementName, attrName, binding, nsCtx, attrs.getValue(i));
- handler.attribute(elementName, attrName, binding, o, value);
- }
- else
- {
- throw new JBossXBRuntimeException(
- "Attribute binding present but has no handler: element=" + elementName + ", attrinute=" + attrName
- );
- }
- }
- else
- {
- if(!Constants.NS_XML_SCHEMA_INSTANCE.equals(attrs.getURI(i)))
- {
- CharactersHandler simpleType = type.getCharactersHandler();
- Object value;
- if(simpleType == null)
- {
- value = attrs.getValue(i);
- RtUtil.set(o, attrName, value, element.getSchema().isIgnoreLowLine());
- }
- }
- }
- }
- }
-
- private boolean tryAdd(Object owner,
- Object o,
- QName qName,
- TermBinding term,
- WildcardBinding wildcard,
- boolean trace)
- {
- AddMethodMetaData addMetaData = wildcard == null ? null : wildcard.getAddMethodMetaData();
- if(addMetaData == null)
- {
- addMetaData = term.getAddMethodMetaData();
- }
-
- if(addMetaData == null)
- {
- return false;
- }
-
- if(trace)
- {
- log.trace("setParent " + qName + " add");
- }
- invokeAdd(qName, addMetaData, owner, o);
- return true;
- }
-
- private boolean tryPut(Object owner, Object o, QName qName, TermBinding term, boolean trace)
- {
- if(term.getPutMethodMetaData() != null ||
- term.getMapEntryMetaData() != null && owner instanceof Map)
- {
- if(trace)
- {
- log.trace("setParent " + qName + " mapPut");
- }
- invokePut(qName, term, owner, o);
- return true;
- }
- return false;
- }
-
- private Class classForElement(ElementBinding element, Class parentClass)
- {
- Class cls;
- TypeBinding type = element.getType();
- QName typeQName = type.getQName();
- if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
- {
- cls = SimpleTypeBindings.classForType(type.getQName().getLocalPart(), element.isNillable());
- }
- else
- {
- ElementBinding arrayItem = null;
- if(!type.isSimple() && type.getAttributes().isEmpty())
- {
- ParticleBinding typeParticle = type.getParticle();
- ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
- arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
- }
-
- if(arrayItem != null)
- {
- cls = classForElement(arrayItem, parentClass);
- // todo: what's the best way to get an array class having the item class
- cls = Array.newInstance(cls, 0).getClass();
- }
- else
- {
- cls = classForNonArrayItem(element, parentClass);
- }
- }
- return cls;
- }
-
- private static void setMapEntryValue(MapEntryMetaData mapEntryMetaData, Object parent, Object o)
- {
- String getValueMethodName = mapEntryMetaData.getGetValueMethod();
- if(getValueMethodName == null)
- {
- getValueMethodName = "getValue";
- }
-
- String setValueMethodName = mapEntryMetaData.getSetValueMethod();
- if(setValueMethodName == null)
- {
- setValueMethodName = "setValue";
- }
-
- Class parentCls = parent.getClass();
- Method setValueMethod = getSetMethod(parentCls, getValueMethodName, setValueMethodName);
- invokeSetter(setValueMethod, parent, o, setValueMethodName);
- }
-
- private static void invokeSetter(Method setValueMethod, Object parent, Object o, String setValueMethodName)
- {
- try
- {
- setValueMethod.invoke(parent, new Object[]{o});
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("Failed to invoke " +
- setValueMethodName +
- " on " +
- parent +
- " with parameter " +
- o +
- ": " +
- e.getMessage()
- );
- }
- }
-
- private static Method getSetMethod(Class cls, String getMethodName, String setMethodName)
- {
- Method getKeyMethod;
- try
- {
- getKeyMethod = cls.getMethod(getMethodName, null);
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("Method " + getMethodName + " not found in " + cls);
- }
-
- Method setKeyMethod;
- try
- {
- setKeyMethod = cls.getMethod(setMethodName, new Class[]{getKeyMethod.getReturnType()});
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("Method " +
- setMethodName +
- "(" +
- getKeyMethod.getReturnType().getName() +
- " p) not found in " +
- cls
- );
- }
- return setKeyMethod;
- }
-
- private static MapEntryMetaData getMapEntryMetaData(TermBinding term, QName qName)
- {
- MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
- if(mapEntryMetaData == null)
- {
- String msg;
- if(term.isModelGroup())
- {
- msg = "Term " +
- qName +
- " bound as map entry key or value but map entry metadata is not available for its parent term.";
- }
- else
- {
- ElementBinding element = (ElementBinding)term;
- msg = "Element " +
- qName +
- " bound as map entry key or value but map entry metadata is not available for its parent element nor its " +
- (element.getType().getQName() == null ?
- "annonymous" :
- element.getType().getQName().toString()
- ) +
- " type.";
- }
- throw new JBossXBRuntimeException(msg);
- }
- return mapEntryMetaData;
- }
-
- private static Object newInstance(Class cls, QName elementName, boolean useNoArgCtorIfFound)
- {
- Object o;
- if(cls.isArray())
- {
- o = GenericValueContainer.FACTORY.array(cls.getComponentType());
- }
- else
- {
- Constructor[] ctors = cls.getConstructors();
- if(ctors.length == 0)
- {
- throw new JBossXBRuntimeException(
- "Class " + cls.getName() + " has no public constructors or the class reflects a primitive type or void"
- );
- }
-
- if(useNoArgCtorIfFound)
- {
- try
- {
- Constructor ctor = cls.getConstructor(null);
- o = ctor.newInstance(null);
- }
- catch(NoSuchMethodException e)
- {
- o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("Failed to create an instance of " +
- cls +
- " using default constructor for element " +
- elementName + ": " + e.getMessage(), e
- );
- }
- }
- else if(ctors.length > 1 || ctors[0].getParameterTypes().length > 0)
- {
- o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
- }
- else
- {
- try
- {
- o = ctors[0].newInstance(null);
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("Failed to create an instance of " +
- cls +
- " using default constructor for element " +
- elementName + ": " + e.getMessage(), e
- );
- }
- }
- }
- return o;
- }
-
- private static Class loadClassForTerm(String className,
- boolean ignoreCNFE,
- QName elementName)
- {
- if(className == null)
- {
- throw new JBossXBRuntimeException("No class for " + elementName);
- }
-
- Class cls = null;
- try
- {
- cls = Thread.currentThread().getContextClassLoader().loadClass(className);
- }
- catch(ClassNotFoundException e)
- {
- if(ignoreCNFE)
- {
- if(log.isTraceEnabled())
- {
- log.trace("Failed to resolve class for element " +
- elementName +
- ": " +
- className
- );
- }
- }
- else
- {
- throw new JBossXBRuntimeException("Failed to resolve class name for " +
- elementName +
- ": " +
- e.getMessage()
- );
- }
- }
- return cls;
- }
-
- private void invokeAdd(QName qName, AddMethodMetaData addMethodMetaData, Object owner, Object o)
- {
- Class valueType = Object.class;
- if(addMethodMetaData.getValueType() != null)
- {
- try
- {
- valueType = Thread.currentThread().getContextClassLoader().
- loadClass(addMethodMetaData.getValueType());
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException("Failed to load value type for addMethod.name=" +
- addMethodMetaData.getMethodName() +
- ", valueType=" +
- addMethodMetaData.getValueType() +
- ": " + e.getMessage(), e
- );
- }
- }
- else if(addMethodMetaData.isChildType())
- {
- if(o == null)
- {
- throw new JBossXBRuntimeException("addMethod=" +
- addMethodMetaData.getMethodName() +
- " for element " +
- qName +
- " is configured with valueType='child'. The valueType cannot be determined because" +
- " the child is null"
- );
- }
- valueType = o.getClass();
- }
-
- Class ownerClass = owner.getClass();
- Method addMethod;
- try
- {
- addMethod = ownerClass.getMethod(addMethodMetaData.getMethodName(), new Class[]{valueType});
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("Failed to find addMethod.name=" +
- addMethodMetaData.getMethodName() +
- ", addMethod.valueType=" +
- valueType.getName() +
- " in class " +
- ownerClass.getName() +
- ": " +
- e.getMessage(), e
- );
- }
-
- try
- {
- addMethod.invoke(owner, new Object[]{o});
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": addMethod=" +
- addMethodMetaData.getMethodName() +
- " threw an exception for owner=" +
- owner +
- ", value=" +
- o +
- ": " +
- e.getMessage(),
- e
- );
- }
- }
-
- private void invokePut(QName qName, TermBinding term, Object owner, Object o)
- {
- PutMethodMetaData putMethodMetaData = term.getPutMethodMetaData();
-
- MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
- if(mapEntryMetaData == null)
- {
- throw new JBossXBRuntimeException((putMethodMetaData == null ?
- "Parent object is an instance of java.util.Map" :
- "putMethod is specified for element " + qName
- ) +
- " but mapEntry is specified for neither element " +
- qName +
- " nor it's type."
- );
- }
-
- Class oClass = o.getClass();
- String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
- if(getKeyMethodName == null)
- {
- getKeyMethodName = "getKey";
- }
-
- Method keyMethod;
- try
- {
- keyMethod = oClass.getMethod(getKeyMethodName, null);
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": getKeyMethod=" +
- getKeyMethodName +
- " not found in " + oClass
- );
- }
-
- Object key;
- try
- {
- key = keyMethod.invoke(o, null);
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": getKeyMethod=" +
- getKeyMethodName +
- " threw an exception: " + e.getMessage(), e
- );
- }
-
- Class keyType = Object.class;
- Class valueType = Object.class;
- String putMethodName = "put";
- Class ownerClass = owner.getClass();
-
- if(putMethodMetaData != null)
- {
- if(putMethodMetaData.getKeyType() != null)
- {
- try
- {
- keyType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getKeyType());
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
- }
- }
-
- if(putMethodMetaData.getValueType() != null)
- {
- try
- {
- valueType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getValueType());
- }
- catch(ClassNotFoundException e)
- {
- throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
- }
- }
-
- String name = putMethodMetaData.getName();
- if(name != null)
- {
- putMethodName = name;
- }
- }
-
- Method putMethod;
- try
- {
- putMethod = ownerClass.getMethod(putMethodName, new Class[]{keyType, valueType});
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": putMethod=" +
- putMethodName +
- "(" + keyType.getName() + " key, " + valueType.getName() + " value) not found in " + ownerClass
- );
- }
-
- Object value = o;
- String valueMethodName = mapEntryMetaData.getGetValueMethod();
- if(valueMethodName != null)
- {
- Method valueMethod;
- try
- {
- valueMethod = oClass.getMethod(valueMethodName, null);
- }
- catch(NoSuchMethodException e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": getValueMethod=" +
- mapEntryMetaData.getGetValueMethod() +
- " not found in " + oClass
- );
- }
-
- try
- {
- value = valueMethod.invoke(o, null);
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": getValueMethod=" +
- mapEntryMetaData.getGetValueMethod() +
- " threw an exception: " + e.getMessage(), e
- );
- }
- }
- else if(o instanceof MapEntry)
- {
- value = ((MapEntry)o).getValue();
- }
-
- try
- {
- putMethod.invoke(owner, new Object[]{key, value});
- }
- catch(Exception e)
- {
- throw new JBossXBRuntimeException("setParent failed for " +
- qName +
- "=" +
- o +
- ": putMethod=" +
- putMethodName +
- " threw an exception for owner=" +
- owner +
- ", key=" +
- key +
- ", value=" +
- value +
- ": " +
- e.getMessage(),
- e
- );
- }
- }
-
- private Class classForNonArrayItem(ElementBinding element, Class parentClass)
- {
- String clsName;
-
- // first, class metadata and map entry metadata
- ClassMetaData clsMetaData = element.getClassMetaData();
- clsName = clsMetaData == null ? null : clsMetaData.getImpl();
- if(clsName == null)
- {
- MapEntryMetaData mapEntryMetaData = element.getMapEntryMetaData();
- if(mapEntryMetaData != null)
- {
- clsName = mapEntryMetaData.getImpl();
- if(clsName == null)
- {
- clsName = MapEntry.class.getName();
- }
- }
- }
-
- // second, property metadata and property type
- if(clsName == null)
- {
- if(parentClass == null)
- {
- clsName = classFromQName(element);
- }
- else
- {
- PropertyMetaData propertyMetaData = element.getPropertyMetaData();
- String propName = propertyMetaData == null ? null : propertyMetaData.getName();
- if(propName == null)
- {
- // if there is add or put method metadata then fallback to XML-name-to-class-name algorithm
- if(element.getAddMethodMetaData() == null && element.getPutMethodMetaData() == null)
- {
- propName =
- Util.xmlNameToFieldName(element.getQName().getLocalPart(), element.getSchema().isIgnoreLowLine());
- }
- }
-
- if(propName != null)
- {
- FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
- Class fieldType = fieldInfo == null ? null : fieldInfo.getType();
-
- if(fieldType == null ||
- Modifier.isAbstract(fieldType.getModifiers()) ||
- Modifier.isInterface(fieldType.getModifiers()) ||
- fieldType.isArray() ||
- Collection.class.isAssignableFrom(fieldType))
- {
- clsName = classFromQName(element);
- }
- else
- {
- return fieldType;
- }
- }
- }
- }
-
- return loadClassForTerm(clsName, element.getSchema().isIgnoreUnresolvedFieldOrClass(), element.getQName());
- }
-
- private String classFromQName(ElementBinding element)
- {
- String clsName;
- QName typeBase = element.getType().getQName();
- if(typeBase == null)
- {
- typeBase = element.getQName();
- }
-
- SchemaBinding schema = element.getSchema();
- PackageMetaData pkgMetaData = schema.getPackageMetaData();
- if(pkgMetaData == null)
- {
- clsName =
- Util.xmlNameToClassName(typeBase.getNamespaceURI(),
- typeBase.getLocalPart(),
- schema.isIgnoreLowLine()
- );
- }
- else
- {
- String pkg = pkgMetaData.getName();
- clsName =
- pkg == null || pkg.length() == 0 ?
- Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine()) :
- pkg + "." + Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine());
- }
- return clsName;
- }
-
- private static Class classForSimpleType(TypeBinding type, boolean nillable)
- {
- ValueMetaData valueMetaData = type.getValueMetaData();
- if(valueMetaData != null && valueMetaData.getUnmarshalMethod() != null)
- {
- return RtUtil.getUnmarshalMethod(type.getQName(), valueMetaData).getReturnType();
- }
- else if(type.getClassMetaData() != null && type.getClassMetaData().getImpl() != null)
- {
- return RtUtil.loadClass(type.getClassMetaData().getImpl(), true);
- }
-
- TypeBinding itemType = type.getItemType();
- if(itemType != null)
- {
- if(type.getSchemaBinding().isUnmarshalListsToArrays())
- {
- // todo: nillable not always should be propagated to the item
- Class itemClass = classForSimpleType(itemType, nillable);
- return Array.newInstance(itemClass, 0).getClass();
- }
- else
- {
- return java.util.List.class;
- }
- }
- else
- {
- QName qName = type.getQName();
- if(qName != null && Constants.NS_XML_SCHEMA.equals(qName.getNamespaceURI()))
- {
- return SimpleTypeBindings.classForType(qName.getLocalPart(), nillable);
- }
- else
- {
- TypeBinding baseType = type.getBaseType();
- if(baseType == null)
- {
- throw new JBossXBRuntimeException("Expected a base type here.");
- }
-
- return classForSimpleType(baseType, nillable);
- }
- }
- }
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java (from rev 2420, jbossxb/branches/1_0/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/main/java/org/jboss/xb/binding/sunday/unmarshalling/impl/runtime/RtElementHandler.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,1465 @@
+/*
+ * 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.xb.binding.sunday.unmarshalling.impl.runtime;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Map;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import org.jboss.logging.Logger;
+import org.jboss.util.Classes;
+import org.jboss.xb.binding.Constants;
+import org.jboss.xb.binding.GenericValueContainer;
+import org.jboss.xb.binding.JBossXBRuntimeException;
+import org.jboss.xb.binding.SimpleTypeBindings;
+import org.jboss.xb.binding.Util;
+import org.jboss.xb.binding.introspection.FieldInfo;
+import org.jboss.xb.binding.group.ValueList;
+import org.jboss.xb.binding.group.ValueListHandler;
+import org.jboss.xb.binding.group.ValueListInitializer;
+import org.jboss.xb.binding.metadata.AddMethodMetaData;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.metadata.MapEntryMetaData;
+import org.jboss.xb.binding.metadata.PackageMetaData;
+import org.jboss.xb.binding.metadata.PropertyMetaData;
+import org.jboss.xb.binding.metadata.PutMethodMetaData;
+import org.jboss.xb.binding.metadata.ValueMetaData;
+import org.jboss.xb.binding.sunday.unmarshalling.AttributeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.AttributeHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.CharactersHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ModelGroupBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ParticleBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.ParticleHandler;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TermBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.WildcardBinding;
+import org.xml.sax.Attributes;
+
+/**
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision$</tt>
+ */
+public class RtElementHandler
+ implements ParticleHandler
+{
+ private static final Logger log = Logger.getLogger(RtElementHandler.class);
+
+ public static final RtElementHandler INSTANCE = new RtElementHandler();
+
+ // ParticleHandler impl
+
+ /**
+ * TODO: it seems like for correct type resolution in startParticle
+ * I should take into account the way the object is going to be added
+ * to the parent in setParent (and, hence, do some steps that are done in setParticle).
+ * In setParent then I should reuse the results of what has been done in startParticle.
+ */
+ public Object startParticle(Object parent,
+ QName elementName,
+ ParticleBinding particle,
+ Attributes attrs,
+ NamespaceContext nsCtx)
+ {
+ TermBinding term = particle.getTerm();
+ Object o = startElement(parent, elementName, particle);
+ if(!term.isModelGroup())
+ {
+ ElementBinding element = (ElementBinding)term;
+ if(o != null)
+ {
+ attrs = element.getType().expandWithDefaultAttributes(attrs);
+ attributes(o, elementName, element, attrs, nsCtx);
+ }
+ }
+ return o;
+ }
+
+ public void setParent(Object parent,
+ Object o,
+ QName qName,
+ ParticleBinding particle,
+ ParticleBinding parentParticle)
+ {
+ TermBinding term = particle.getTerm();
+ if(term.isSkip())
+ {
+ return;
+ }
+
+ boolean trace = log.isTraceEnabled();
+ if(trace)
+ {
+ log.trace("setParent " + qName + " parent=" + parent + " object=" + o + " term=" + term);
+ }
+
+ TermBinding parentTerm = parentParticle.getTerm();
+
+ if(term.isMapEntryKey())
+ {
+ if(trace)
+ {
+ log.trace("setParent " + qName + " mapKey");
+ }
+
+ if(parent instanceof MapEntry)
+ {
+ MapEntry mapEntry = (MapEntry)parent;
+ mapEntry.setKey(o);
+ }
+ else if(parentTerm != null)
+ {
+ MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+
+ String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
+ if(getKeyMethodName == null)
+ {
+ getKeyMethodName = "getKey";
+ }
+
+ String setKeyMethodName = mapEntryMetaData.getSetKeyMethod();
+ if(setKeyMethodName == null)
+ {
+ setKeyMethodName = "setKey";
+ }
+
+ Class parentCls = parent.getClass();
+ Method setKeyMethod = getSetMethod(parentCls, getKeyMethodName, setKeyMethodName);
+ invokeSetter(setKeyMethod, parent, o, setKeyMethodName);
+ }
+ else
+ {
+ throw new JBossXBRuntimeException(
+ "Element " +
+ qName +
+ " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
+ );
+ }
+ }
+ else if(term.isMapEntryValue())
+ {
+ if(trace)
+ {
+ log.trace("setParent " + qName + " mapValue");
+ }
+
+ if(parent instanceof MapEntry)
+ {
+ MapEntry mapEntry = (MapEntry)parent;
+ mapEntry.setValue(o);
+ }
+ else if(parentTerm != null)
+ {
+ MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+ setMapEntryValue(mapEntryMetaData, parent, o);
+ }
+ else
+ {
+ throw new JBossXBRuntimeException(
+ "Element " +
+ qName +
+ " bound as map entry key but parent element is not recognized as map entry and its metadata is not available."
+ );
+ }
+ }
+ else
+ {
+ Object owner = parent;
+ if(parent instanceof MapEntry)
+ {
+ if(trace)
+ {
+ log.trace("setParent " + qName + " mapEntry");
+ }
+
+ MapEntry mapEntry = (MapEntry)parent;
+ owner = mapEntry.getValue();
+ if(owner == null)
+ {
+ if(parentTerm == null)
+ {
+ throw new JBossXBRuntimeException("Binding metadata needed for lazy map entry value instantiation is not available " +
+ "for parent element of element " +
+ qName
+ );
+ }
+
+ MapEntryMetaData mapEntryMetaData = getMapEntryMetaData(parentTerm, qName);
+ String valueType = mapEntryMetaData.getValueType();
+ if(valueType == null)
+ {
+ throw new JBossXBRuntimeException("Element " +
+ qName +
+ " is supposed to be bound as map entry value with lazy value instantiation " +
+ "but value type is not specified in its map entry metadata."
+ );
+ }
+
+ Class valueCls;
+ try
+ {
+ valueCls = Thread.currentThread().getContextClassLoader().loadClass(valueType);
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException(
+ "Failed to load value type specified in the map entry metadata: " + valueType
+ );
+ }
+
+ try
+ {
+ owner = valueCls.newInstance();
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException(
+ "Failed to create an instance of value type " + valueType + ": " + e.getMessage()
+ );
+ }
+
+ setMapEntryValue(mapEntryMetaData, parent, owner);
+ }
+ }
+
+ // the wildcard this element is a content of
+ WildcardBinding wildcard = null;
+ if(parentTerm != null && !parentTerm.isModelGroup())
+ {
+ ElementBinding parentElement = (ElementBinding)parentTerm;
+ TypeBinding parentType = parentElement.getType();
+ wildcard = parentType.getWildcard();
+ // there should be a better way of checking this
+ if(wildcard != null && parentType.getElement(qName) != null)
+ {
+ wildcard = null;
+ }
+ }
+
+ if(tryPut(owner, o, qName, term, trace))
+ {
+ }
+ else if(tryAdd(owner, o, qName, term, wildcard, trace))
+ {
+ }
+ else if (owner instanceof GenericValueContainer)
+ {
+ if (trace)
+ {
+ log.trace("setParent " + qName + " addChild");
+ }
+ ((GenericValueContainer) owner).addChild(qName, o);
+ }
+ else if (owner instanceof Collection)
+ {
+ if (trace)
+ {
+ log.trace("setParent " + qName + " collection.add()");
+ }
+ ((Collection) owner).add(o);
+ }
+ else
+ {
+ PropertyMetaData propertyMetaData = wildcard == null ? null : wildcard.getPropertyMetaData();
+ if (propertyMetaData == null)
+ {
+ propertyMetaData = term.getPropertyMetaData();
+ }
+
+ String propName = null;
+ String colType = null;
+ if (propertyMetaData != null)
+ {
+ propName = propertyMetaData.getName();
+ colType = propertyMetaData.getCollectionType();
+ }
+
+ if (propName == null)
+ {
+ propName = Util.xmlNameToFieldName(qName.getLocalPart(), term.getSchema().isIgnoreLowLine());
+ }
+
+ if (trace)
+ {
+ log.trace("setParent " + qName + " metadata set " + propName);
+ }
+
+ /*if(particle.isRepeatable())
+ {
+ RtUtil.add(owner, o, propName, colType,
+ term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+ term.getValueAdapter()
+ );
+ }
+ else
+ {*/
+ RtUtil.set(owner, o, propName, colType,
+ term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+ term.getValueAdapter());
+ //}
+ }
+ }
+ }
+
+ public Object endParticle(Object o, QName elementName, ParticleBinding particle)
+ {
+ TermBinding term = particle.getTerm();
+ if(term.isSkip())
+ {
+ return o;
+ }
+
+ boolean trace = log.isTraceEnabled();
+ if(trace)
+ {
+ log.trace("endParticle " + elementName + " object=" + o + " term=" + term);
+ }
+
+ if(o instanceof GenericValueContainer)
+ {
+ try
+ {
+ if(trace)
+ {
+ log.trace("endParticle " + elementName + " instantiate()");
+ }
+ o = ((GenericValueContainer)o).instantiate();
+ }
+ catch(JBossXBRuntimeException e)
+ {
+ throw e;
+ }
+ catch(RuntimeException e)
+ {
+ throw new JBossXBRuntimeException("Container failed to create an instance for " +
+ elementName +
+ ": " + e.getMessage(), e
+ );
+ }
+ }
+
+ return o;
+ }
+
+ // Private
+
+ private Object startElement(Object parent, QName elementName, ParticleBinding particle)
+ {
+ TermBinding term = particle.getTerm();
+ if(term.isSkip())
+ {
+ return parent;
+ }
+
+ boolean trace = log.isTraceEnabled();
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " parent=" + parent + " term=" + term);
+ }
+
+ ClassMetaData classMetaData = term.getClassMetaData();
+ MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+
+ if(!term.isModelGroup())
+ {
+ TypeBinding type = ((ElementBinding)term).getType();
+ if(type.isSimple() ||
+ classMetaData == null && mapEntryMetaData == null &&
+ (!type.isStartElementCreatesObject() ||
+ Constants.QNAME_ANYTYPE.equals(type.getQName())))
+ {
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " does not create an object");
+ }
+ return null;
+ }
+ }
+
+ // if addMethod is specified, it's probably some collection field
+ // but should not be set as a property. Instead, items are added to it using the addMethod
+ ElementBinding arrayItem = null;
+ if(!term.isModelGroup())
+ {
+ TypeBinding type = ((ElementBinding)term).getType();
+ if(type.getAttributes().isEmpty())
+ {
+ ParticleBinding typeParticle = type.getParticle();
+ ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
+ arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
+
+ // todo refactor later (move it to modelGroup.getArrayItem()?)
+ if(arrayItem != null &&
+ (arrayItem.isSkip() ||
+ arrayItem.getMapEntryMetaData() != null ||
+ arrayItem.getPutMethodMetaData() != null ||
+ arrayItem.getAddMethodMetaData() != null
+ ))
+ {
+ arrayItem = null;
+ }
+ }
+ }
+
+ if(arrayItem != null)
+ {
+ Class wrapperType = null;
+ if(classMetaData != null)
+ {
+ wrapperType = loadClassForTerm(classMetaData.getImpl(),
+ term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+ elementName
+ );
+
+ if(GenericValueContainer.class.isAssignableFrom(wrapperType) ||
+ Collection.class.isAssignableFrom(wrapperType) ||
+ Map.class.isAssignableFrom(wrapperType))
+ {
+ return newInstance(wrapperType, elementName, term.getSchema().isUseNoArgCtorIfFound());
+ }
+ }
+
+ if(wrapperType == null && parent == null)
+ {
+ Class itemType = classForElement(arrayItem, null);
+ if(itemType != null)
+ {
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " new array " + itemType.getName());
+ }
+ return GenericValueContainer.FACTORY.array(itemType);
+ }
+ }
+ else
+ {
+ PropertyMetaData propertyMetaData = wrapperType == null ?
+ term.getPropertyMetaData() : arrayItem.getPropertyMetaData();
+
+ String propName;
+ if(propertyMetaData == null)
+ {
+ propName = Util.xmlNameToFieldName(
+ wrapperType == null ? elementName.getLocalPart() : arrayItem.getQName().getLocalPart(),
+ term.getSchema().isIgnoreLowLine()
+ );
+ }
+ else
+ {
+ propName = propertyMetaData.getName();
+ }
+
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " property=" + propName);
+ }
+
+ Class parentClass = wrapperType;
+ if(wrapperType == null)
+ {
+ if(parent instanceof GenericValueContainer)
+ {
+ parentClass = ((GenericValueContainer)parent).getTargetClass();
+ }
+ else if(parent instanceof ValueList)
+ {
+ parentClass = ((ValueList)parent).getTargetClass();
+ }
+ else
+ {
+ parentClass = parent.getClass();
+ }
+ }
+
+ Class fieldType = null;
+ if(parentClass.isArray())
+ {
+ fieldType = parentClass.getComponentType();
+ }
+ else
+ {
+ //fieldType = FieldInfo.getFieldInfo(parentClass, propName, true).getType();
+ // this was changed to false because allow overriding of handler.setParent()
+ // with an interceptor.add(). See CollectionOverridePropertyUnitTestCase
+ // In other words, don't treat it as an array wrapper.
+ FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
+ if(fieldInfo != null)
+ {
+ fieldType = fieldInfo.getType();
+ if (particle.isRepeatable() && fieldType.isArray())
+ {
+ fieldType = fieldType.getComponentType();
+ }
+ }
+ else if(arrayItem.getInterceptors().isEmpty())
+ {
+ QName typeName = ((ElementBinding)term).getType().getQName();
+ throw new JBossXBRuntimeException(
+ "Couldn't apply 'array wrapper' pattern for element " +
+ elementName + " of type " +
+ (typeName == null ? "anonymous" : typeName.toString()) +
+ ": failed to resolve property " + propName +
+ " and no interceptors applied to override handler.setParent(...)");
+ }
+ }
+
+ if(fieldType.isArray())
+ {
+ return GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType.getComponentType());
+ }
+ else if(Collection.class.isAssignableFrom(fieldType))
+ {
+ if (wrapperType == null)
+ {
+ return new ValueListInitializer().newValueList(ValueListHandler.FACTORY.child(), Collection.class);
+ //o = ArrayList();
+ }
+ }
+ else
+ {
+ return GenericValueContainer.FACTORY.array(wrapperType, propName, fieldType);
+ }
+ }
+ }
+
+ Object o = null;
+ if(mapEntryMetaData != null)
+ {
+ if(mapEntryMetaData.getImpl() != null)
+ {
+ Class cls = loadClassForTerm(mapEntryMetaData.getImpl(),
+ term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+ elementName
+ );
+
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " new map entry " + cls.getName());
+ }
+
+ o = newInstance(cls, elementName, term.getSchema().isUseNoArgCtorIfFound());
+ }
+ else
+ {
+ o = new MapEntry();
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " new map entry");
+ }
+ }
+
+ if(mapEntryMetaData.isNonNullValue() && mapEntryMetaData.getValueType() != null)
+ {
+ Class mapValueType;
+ try
+ {
+ mapValueType =
+ Thread.currentThread().getContextClassLoader().loadClass(mapEntryMetaData.getValueType());
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException("startElement failed for " +
+ elementName +
+ ": failed to load class " +
+ mapEntryMetaData.getValueType() +
+ " for map entry value."
+ );
+ }
+
+ Object value;
+ try
+ {
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " map value type " + mapEntryMetaData.getValueType());
+ }
+ value = mapValueType.newInstance();
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("startElement failed for " +
+ elementName +
+ ": failed to create an instance of " +
+ mapValueType +
+ " for map entry value."
+ );
+ }
+
+ if(o instanceof MapEntry)
+ {
+ ((MapEntry)o).setValue(value);
+ }
+ else
+ {
+ String getValueMethodName = mapEntryMetaData.getGetValueMethod();
+ if(getValueMethodName == null)
+ {
+ getValueMethodName = "getValue";
+ }
+
+ String setValueMethodName = mapEntryMetaData.getSetValueMethod();
+ if(setValueMethodName == null)
+ {
+ setValueMethodName = "setValue";
+ }
+
+ Method getValueMethod;
+ try
+ {
+ getValueMethod = o.getClass().getMethod(getValueMethodName, null);
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("getValueMethod=" +
+ getValueMethodName +
+ " is not found in map entry " + o.getClass()
+ );
+ }
+
+ Method setValueMethod;
+ try
+ {
+ setValueMethod =
+ o.getClass().getMethod(setValueMethodName, new Class[]{getValueMethod.getReturnType()});
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("setValueMethod=" +
+ setValueMethodName +
+ "(" +
+ getValueMethod.getReturnType().getName() +
+ " value) is not found in map entry " + o.getClass()
+ );
+ }
+
+ try
+ {
+ setValueMethod.invoke(o, new Object[]{value});
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("setValueMethod=" +
+ setValueMethodName +
+ " failed: owner=" +
+ o +
+ ", value=" + value + ", msg=" + e.getMessage(), e
+ );
+ }
+ }
+ }
+ }
+ else
+ {
+ // todo: for now we require metadata for model groups to be bound
+ // todo 2: parent.getClass() is not going to work for containers
+ Class parentClass = null;
+ if(parent != null)
+ {
+ if(parent instanceof GenericValueContainer)
+ {
+ parentClass = ((GenericValueContainer)parent).getTargetClass();
+ }
+ else if(parent instanceof ValueList)
+ {
+ parentClass = ((ValueList)parent).getTargetClass();
+ }
+ else
+ {
+ parentClass = parent.getClass();
+ }
+ }
+
+ Class cls;
+ if(term.isModelGroup())
+ {
+ if(classMetaData == null)
+ {
+ throw new JBossXBRuntimeException(
+ "Model groups should be annotated with 'class' annotation to be bound."
+ );
+ }
+ cls = loadClassForTerm(classMetaData.getImpl(),
+ term.getSchema().isIgnoreUnresolvedFieldOrClass(),
+ elementName
+ );
+ }
+ else
+ {
+ ElementBinding element = (ElementBinding)term;
+ cls = classForNonArrayItem(element, parentClass);
+ if(cls != null)
+ {
+ // todo: before that, the type should be checked for required attributes and elements
+ TypeBinding simpleType = element.getType().getSimpleType();
+ if(simpleType != null)
+ {
+ Class simpleCls = classForSimpleType(simpleType, element.isNillable());
+ if(cls.equals(simpleCls) ||
+ cls.isPrimitive() && Classes.getPrimitiveWrapper(cls) == simpleCls ||
+ simpleCls.isPrimitive() && Classes.getPrimitiveWrapper(simpleCls) == cls)
+ {
+ cls = null;
+ }
+ }
+ }
+ }
+
+ if(cls != null)
+ {
+ boolean noArgCtor;
+ if(classMetaData == null)
+ {
+ noArgCtor = term.getSchema().isUseNoArgCtorIfFound();
+ }
+ else
+ {
+ Boolean termUsesNoArgCtor = classMetaData.isUseNoArgCtor();
+ noArgCtor = termUsesNoArgCtor == null ?
+ term.getSchema().isUseNoArgCtorIfFound() : termUsesNoArgCtor.booleanValue(); }
+
+ if(trace)
+ {
+ log.trace("startElement " + elementName + " new " + cls.getName() + ", noArgCtor=" + noArgCtor);
+ }
+ o = newInstance(cls, elementName, noArgCtor);
+ }
+ }
+
+ return o;
+ }
+
+ private void attributes(Object o,
+ QName elementName,
+ ElementBinding element,
+ Attributes attrs,
+ NamespaceContext nsCtx)
+ {
+ TypeBinding type = element.getType();
+ for(int i = 0; i < attrs.getLength(); ++i)
+ {
+ QName attrName = new QName(attrs.getURI(i), attrs.getLocalName(i));
+ AttributeBinding binding = type.getAttribute(attrName);
+ if(binding != null)
+ {
+ AttributeHandler handler = binding.getHandler();
+ if(handler != null)
+ {
+ Object value = handler.unmarshal(elementName, attrName, binding, nsCtx, attrs.getValue(i));
+ handler.attribute(elementName, attrName, binding, o, value);
+ }
+ else
+ {
+ throw new JBossXBRuntimeException(
+ "Attribute binding present but has no handler: element=" + elementName + ", attrinute=" + attrName
+ );
+ }
+ }
+ else
+ {
+ if(!Constants.NS_XML_SCHEMA_INSTANCE.equals(attrs.getURI(i)))
+ {
+ CharactersHandler simpleType = type.getCharactersHandler();
+ Object value;
+ if(simpleType == null)
+ {
+ value = attrs.getValue(i);
+ RtUtil.set(o, attrName, value, element.getSchema().isIgnoreLowLine());
+ }
+ }
+ }
+ }
+ }
+
+ private boolean tryAdd(Object owner,
+ Object o,
+ QName qName,
+ TermBinding term,
+ WildcardBinding wildcard,
+ boolean trace)
+ {
+ AddMethodMetaData addMetaData = wildcard == null ? null : wildcard.getAddMethodMetaData();
+ if(addMetaData == null)
+ {
+ addMetaData = term.getAddMethodMetaData();
+ }
+
+ if(addMetaData == null)
+ {
+ return false;
+ }
+
+ if(trace)
+ {
+ log.trace("setParent " + qName + " add");
+ }
+ invokeAdd(qName, addMetaData, owner, o);
+ return true;
+ }
+
+ private boolean tryPut(Object owner, Object o, QName qName, TermBinding term, boolean trace)
+ {
+ if(term.getPutMethodMetaData() != null ||
+ term.getMapEntryMetaData() != null && owner instanceof Map)
+ {
+ if(trace)
+ {
+ log.trace("setParent " + qName + " mapPut");
+ }
+ invokePut(qName, term, owner, o);
+ return true;
+ }
+ return false;
+ }
+
+ private Class classForElement(ElementBinding element, Class parentClass)
+ {
+ Class cls;
+ TypeBinding type = element.getType();
+ QName typeQName = type.getQName();
+ if(typeQName != null && Constants.NS_XML_SCHEMA.equals(typeQName.getNamespaceURI()))
+ {
+ cls = SimpleTypeBindings.classForType(type.getQName().getLocalPart(), element.isNillable());
+ }
+ else
+ {
+ ElementBinding arrayItem = null;
+ if(!type.isSimple() && type.getAttributes().isEmpty())
+ {
+ ParticleBinding typeParticle = type.getParticle();
+ ModelGroupBinding modelGroup = (ModelGroupBinding)(typeParticle == null ? null : typeParticle.getTerm());
+ arrayItem = modelGroup == null ? null : modelGroup.getArrayItem();
+ }
+
+ if(arrayItem != null)
+ {
+ cls = classForElement(arrayItem, parentClass);
+ // todo: what's the best way to get an array class having the item class
+ cls = Array.newInstance(cls, 0).getClass();
+ }
+ else
+ {
+ cls = classForNonArrayItem(element, parentClass);
+ }
+ }
+ return cls;
+ }
+
+ private static void setMapEntryValue(MapEntryMetaData mapEntryMetaData, Object parent, Object o)
+ {
+ String getValueMethodName = mapEntryMetaData.getGetValueMethod();
+ if(getValueMethodName == null)
+ {
+ getValueMethodName = "getValue";
+ }
+
+ String setValueMethodName = mapEntryMetaData.getSetValueMethod();
+ if(setValueMethodName == null)
+ {
+ setValueMethodName = "setValue";
+ }
+
+ Class parentCls = parent.getClass();
+ Method setValueMethod = getSetMethod(parentCls, getValueMethodName, setValueMethodName);
+ invokeSetter(setValueMethod, parent, o, setValueMethodName);
+ }
+
+ private static void invokeSetter(Method setValueMethod, Object parent, Object o, String setValueMethodName)
+ {
+ try
+ {
+ setValueMethod.invoke(parent, new Object[]{o});
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("Failed to invoke " +
+ setValueMethodName +
+ " on " +
+ parent +
+ " with parameter " +
+ o +
+ ": " +
+ e.getMessage()
+ );
+ }
+ }
+
+ private static Method getSetMethod(Class cls, String getMethodName, String setMethodName)
+ {
+ Method getKeyMethod;
+ try
+ {
+ getKeyMethod = cls.getMethod(getMethodName, null);
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("Method " + getMethodName + " not found in " + cls);
+ }
+
+ Method setKeyMethod;
+ try
+ {
+ setKeyMethod = cls.getMethod(setMethodName, new Class[]{getKeyMethod.getReturnType()});
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("Method " +
+ setMethodName +
+ "(" +
+ getKeyMethod.getReturnType().getName() +
+ " p) not found in " +
+ cls
+ );
+ }
+ return setKeyMethod;
+ }
+
+ private static MapEntryMetaData getMapEntryMetaData(TermBinding term, QName qName)
+ {
+ MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+ if(mapEntryMetaData == null)
+ {
+ String msg;
+ if(term.isModelGroup())
+ {
+ msg = "Term " +
+ qName +
+ " bound as map entry key or value but map entry metadata is not available for its parent term.";
+ }
+ else
+ {
+ ElementBinding element = (ElementBinding)term;
+ msg = "Element " +
+ qName +
+ " bound as map entry key or value but map entry metadata is not available for its parent element nor its " +
+ (element.getType().getQName() == null ?
+ "annonymous" :
+ element.getType().getQName().toString()
+ ) +
+ " type.";
+ }
+ throw new JBossXBRuntimeException(msg);
+ }
+ return mapEntryMetaData;
+ }
+
+ private static Object newInstance(Class cls, QName elementName, boolean useNoArgCtorIfFound)
+ {
+ Object o;
+ if(cls.isArray())
+ {
+ o = GenericValueContainer.FACTORY.array(cls.getComponentType());
+ }
+ else
+ {
+ Constructor[] ctors = cls.getConstructors();
+ if(ctors.length == 0)
+ {
+ throw new JBossXBRuntimeException(
+ "Class " + cls.getName() + " has no public constructors or the class reflects a primitive type or void"
+ );
+ }
+
+ if(useNoArgCtorIfFound)
+ {
+ try
+ {
+ Constructor ctor = cls.getConstructor(null);
+ o = ctor.newInstance(null);
+ }
+ catch(NoSuchMethodException e)
+ {
+ o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("Failed to create an instance of " +
+ cls +
+ " using default constructor for element " +
+ elementName + ": " + e.getMessage(), e
+ );
+ }
+ }
+ else if(ctors.length > 1 || ctors[0].getParameterTypes().length > 0)
+ {
+ o = new ValueListInitializer().newValueList(ValueListHandler.NON_DEFAULT_CTOR, cls);
+ }
+ else
+ {
+ try
+ {
+ o = ctors[0].newInstance(null);
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("Failed to create an instance of " +
+ cls +
+ " using default constructor for element " +
+ elementName + ": " + e.getMessage(), e
+ );
+ }
+ }
+ }
+ return o;
+ }
+
+ private static Class loadClassForTerm(String className,
+ boolean ignoreCNFE,
+ QName elementName)
+ {
+ if(className == null)
+ {
+ throw new JBossXBRuntimeException("No class for " + elementName);
+ }
+
+ Class cls = null;
+ try
+ {
+ cls = Thread.currentThread().getContextClassLoader().loadClass(className);
+ }
+ catch(ClassNotFoundException e)
+ {
+ if(ignoreCNFE)
+ {
+ if(log.isTraceEnabled())
+ {
+ log.trace("Failed to resolve class for element " +
+ elementName +
+ ": " +
+ className
+ );
+ }
+ }
+ else
+ {
+ throw new JBossXBRuntimeException("Failed to resolve class name for " +
+ elementName +
+ ": " +
+ e.getMessage()
+ );
+ }
+ }
+ return cls;
+ }
+
+ private void invokeAdd(QName qName, AddMethodMetaData addMethodMetaData, Object owner, Object o)
+ {
+ Class valueType = Object.class;
+ if(addMethodMetaData.getValueType() != null)
+ {
+ try
+ {
+ valueType = Thread.currentThread().getContextClassLoader().
+ loadClass(addMethodMetaData.getValueType());
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException("Failed to load value type for addMethod.name=" +
+ addMethodMetaData.getMethodName() +
+ ", valueType=" +
+ addMethodMetaData.getValueType() +
+ ": " + e.getMessage(), e
+ );
+ }
+ }
+ else if(addMethodMetaData.isChildType())
+ {
+ if(o == null)
+ {
+ throw new JBossXBRuntimeException("addMethod=" +
+ addMethodMetaData.getMethodName() +
+ " for element " +
+ qName +
+ " is configured with valueType='child'. The valueType cannot be determined because" +
+ " the child is null"
+ );
+ }
+ valueType = o.getClass();
+ }
+
+ Class ownerClass = owner.getClass();
+ Method addMethod;
+ try
+ {
+ addMethod = ownerClass.getMethod(addMethodMetaData.getMethodName(), new Class[]{valueType});
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("Failed to find addMethod.name=" +
+ addMethodMetaData.getMethodName() +
+ ", addMethod.valueType=" +
+ valueType.getName() +
+ " in class " +
+ ownerClass.getName() +
+ ": " +
+ e.getMessage(), e
+ );
+ }
+
+ try
+ {
+ addMethod.invoke(owner, new Object[]{o});
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": addMethod=" +
+ addMethodMetaData.getMethodName() +
+ " threw an exception for owner=" +
+ owner +
+ ", value=" +
+ o +
+ ": " +
+ e.getMessage(),
+ e
+ );
+ }
+ }
+
+ private void invokePut(QName qName, TermBinding term, Object owner, Object o)
+ {
+ PutMethodMetaData putMethodMetaData = term.getPutMethodMetaData();
+
+ MapEntryMetaData mapEntryMetaData = term.getMapEntryMetaData();
+ if(mapEntryMetaData == null)
+ {
+ throw new JBossXBRuntimeException((putMethodMetaData == null ?
+ "Parent object is an instance of java.util.Map" :
+ "putMethod is specified for element " + qName
+ ) +
+ " but mapEntry is specified for neither element " +
+ qName +
+ " nor it's type."
+ );
+ }
+
+ Class oClass = o.getClass();
+ String getKeyMethodName = mapEntryMetaData.getGetKeyMethod();
+ if(getKeyMethodName == null)
+ {
+ getKeyMethodName = "getKey";
+ }
+
+ Method keyMethod;
+ try
+ {
+ keyMethod = oClass.getMethod(getKeyMethodName, null);
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": getKeyMethod=" +
+ getKeyMethodName +
+ " not found in " + oClass
+ );
+ }
+
+ Object key;
+ try
+ {
+ key = keyMethod.invoke(o, null);
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": getKeyMethod=" +
+ getKeyMethodName +
+ " threw an exception: " + e.getMessage(), e
+ );
+ }
+
+ Class keyType = Object.class;
+ Class valueType = Object.class;
+ String putMethodName = "put";
+ Class ownerClass = owner.getClass();
+
+ if(putMethodMetaData != null)
+ {
+ if(putMethodMetaData.getKeyType() != null)
+ {
+ try
+ {
+ keyType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getKeyType());
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
+ }
+ }
+
+ if(putMethodMetaData.getValueType() != null)
+ {
+ try
+ {
+ valueType = Thread.currentThread().getContextClassLoader().loadClass(putMethodMetaData.getValueType());
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " + qName + ": " + e.getMessage(), e);
+ }
+ }
+
+ String name = putMethodMetaData.getName();
+ if(name != null)
+ {
+ putMethodName = name;
+ }
+ }
+
+ Method putMethod;
+ try
+ {
+ putMethod = ownerClass.getMethod(putMethodName, new Class[]{keyType, valueType});
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": putMethod=" +
+ putMethodName +
+ "(" + keyType.getName() + " key, " + valueType.getName() + " value) not found in " + ownerClass
+ );
+ }
+
+ Object value = o;
+ String valueMethodName = mapEntryMetaData.getGetValueMethod();
+ if(valueMethodName != null)
+ {
+ Method valueMethod;
+ try
+ {
+ valueMethod = oClass.getMethod(valueMethodName, null);
+ }
+ catch(NoSuchMethodException e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": getValueMethod=" +
+ mapEntryMetaData.getGetValueMethod() +
+ " not found in " + oClass
+ );
+ }
+
+ try
+ {
+ value = valueMethod.invoke(o, null);
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": getValueMethod=" +
+ mapEntryMetaData.getGetValueMethod() +
+ " threw an exception: " + e.getMessage(), e
+ );
+ }
+ }
+ else if(o instanceof MapEntry)
+ {
+ value = ((MapEntry)o).getValue();
+ }
+
+ try
+ {
+ putMethod.invoke(owner, new Object[]{key, value});
+ }
+ catch(Exception e)
+ {
+ throw new JBossXBRuntimeException("setParent failed for " +
+ qName +
+ "=" +
+ o +
+ ": putMethod=" +
+ putMethodName +
+ " threw an exception for owner=" +
+ owner +
+ ", key=" +
+ key +
+ ", value=" +
+ value +
+ ": " +
+ e.getMessage(),
+ e
+ );
+ }
+ }
+
+ private Class classForNonArrayItem(ElementBinding element, Class parentClass)
+ {
+ String clsName;
+
+ // first, class metadata and map entry metadata
+ ClassMetaData clsMetaData = element.getClassMetaData();
+ clsName = clsMetaData == null ? null : clsMetaData.getImpl();
+ if(clsName == null)
+ {
+ MapEntryMetaData mapEntryMetaData = element.getMapEntryMetaData();
+ if(mapEntryMetaData != null)
+ {
+ clsName = mapEntryMetaData.getImpl();
+ if(clsName == null)
+ {
+ clsName = MapEntry.class.getName();
+ }
+ }
+ }
+
+ // second, property metadata and property type
+ if(clsName == null)
+ {
+ if(parentClass == null)
+ {
+ clsName = classFromQName(element);
+ }
+ else
+ {
+ PropertyMetaData propertyMetaData = element.getPropertyMetaData();
+ String propName = propertyMetaData == null ? null : propertyMetaData.getName();
+ if(propName == null)
+ {
+ // if there is add or put method metadata then fallback to XML-name-to-class-name algorithm
+ if(element.getAddMethodMetaData() == null && element.getPutMethodMetaData() == null)
+ {
+ propName =
+ Util.xmlNameToFieldName(element.getQName().getLocalPart(), element.getSchema().isIgnoreLowLine());
+ }
+ }
+
+ if(propName != null)
+ {
+ FieldInfo fieldInfo = FieldInfo.getFieldInfo(parentClass, propName, false);
+ Class fieldType = fieldInfo == null ? null : fieldInfo.getType();
+
+ if(fieldType == null ||
+ Modifier.isAbstract(fieldType.getModifiers()) ||
+ Modifier.isInterface(fieldType.getModifiers()) ||
+ fieldType.isArray() ||
+ Collection.class.isAssignableFrom(fieldType))
+ {
+ clsName = classFromQName(element);
+ }
+ else
+ {
+ return fieldType;
+ }
+ }
+ }
+ }
+
+ return loadClassForTerm(clsName, element.getSchema().isIgnoreUnresolvedFieldOrClass(), element.getQName());
+ }
+
+ private String classFromQName(ElementBinding element)
+ {
+ String clsName;
+ QName typeBase = element.getType().getQName();
+ if(typeBase == null)
+ {
+ typeBase = element.getQName();
+ }
+
+ SchemaBinding schema = element.getSchema();
+ PackageMetaData pkgMetaData = schema.getPackageMetaData();
+ if(pkgMetaData == null)
+ {
+ clsName =
+ Util.xmlNameToClassName(typeBase.getNamespaceURI(),
+ typeBase.getLocalPart(),
+ schema.isIgnoreLowLine()
+ );
+ }
+ else
+ {
+ String pkg = pkgMetaData.getName();
+ clsName =
+ pkg == null || pkg.length() == 0 ?
+ Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine()) :
+ pkg + "." + Util.xmlNameToClassName(typeBase.getLocalPart(), schema.isIgnoreLowLine());
+ }
+ return clsName;
+ }
+
+ private static Class classForSimpleType(TypeBinding type, boolean nillable)
+ {
+ ValueMetaData valueMetaData = type.getValueMetaData();
+ if(valueMetaData != null && valueMetaData.getUnmarshalMethod() != null)
+ {
+ return RtUtil.getUnmarshalMethod(type.getQName(), valueMetaData).getReturnType();
+ }
+ else if(type.getClassMetaData() != null && type.getClassMetaData().getImpl() != null)
+ {
+ return RtUtil.loadClass(type.getClassMetaData().getImpl(), true);
+ }
+
+ TypeBinding itemType = type.getItemType();
+ if(itemType != null)
+ {
+ if(type.getSchemaBinding().isUnmarshalListsToArrays())
+ {
+ // todo: nillable not always should be propagated to the item
+ Class itemClass = classForSimpleType(itemType, nillable);
+ return Array.newInstance(itemClass, 0).getClass();
+ }
+ else
+ {
+ return java.util.List.class;
+ }
+ }
+ else
+ {
+ QName qName = type.getQName();
+ if(qName != null && Constants.NS_XML_SCHEMA.equals(qName.getNamespaceURI()))
+ {
+ return SimpleTypeBindings.classForType(qName.getLocalPart(), nillable);
+ }
+ else
+ {
+ TypeBinding baseType = type.getBaseType();
+ if(baseType == null)
+ {
+ throw new JBossXBRuntimeException("Expected a base type here.");
+ }
+
+ return classForSimpleType(baseType, nillable);
+ }
+ }
+ }
+}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java (from rev 2434, jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/IgnorableWhitespaceUnitTestCase.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,220 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, 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.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import junit.framework.TestSuite;
+
+import org.jboss.xb.binding.ObjectModelFactory;
+import org.jboss.xb.binding.Unmarshaller;
+import org.jboss.xb.binding.UnmarshallerFactory;
+import org.jboss.xb.binding.UnmarshallingContext;
+import org.jboss.xb.binding.metadata.ClassMetaData;
+import org.jboss.xb.binding.sunday.marshalling.MarshallerImpl;
+import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
+import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
+import org.xml.sax.Attributes;
+
+
+/**
+ * IgnorableWhitespaceUnitTestCase.
+ *
+ * @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
+ * @version $Revision$
+ */
+public class IgnorableWhitespaceUnitTestCase extends AbstractJBossXBTest
+{
+ private static final String NS = "http://www.jboss.org/test/xml/simpleContent";
+
+ private static final String XSD =
+ "<?xml version='1.0' encoding='UTF-8'?>" +
+ "<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'" +
+ " targetNamespace='http://www.jboss.org/test/xml/simpleContent'" +
+ " xmlns='http://www.jboss.org/test/xml/simpleContent'" +
+ " elementFormDefault='qualified'" +
+ " attributeFormDefault='unqualified'" +
+ " version='1.0'>" +
+ " <xsd:element name='top'>" +
+ " <xsd:complexType>" +
+ " <xsd:sequence>" +
+ " <xsd:element name='string' type='myString' minOccurs='0' maxOccurs='unbounded'/>" +
+ " </xsd:sequence>" +
+ " </xsd:complexType>" +
+ " </xsd:element>" +
+ " <xsd:complexType name='myString'>" +
+ " <xsd:simpleContent>" +
+ " <xsd:extension base='xsd:string'>" +
+ " <xsd:attribute name='id' type='xsd:ID'/>" +
+ " </xsd:extension>" +
+ " </xsd:simpleContent>" +
+ " </xsd:complexType>" +
+ "</xsd:schema>";
+
+ public static final TestSuite suite()
+ {
+ return new TestSuite(IgnorableWhitespaceUnitTestCase.class);
+ }
+
+ public IgnorableWhitespaceUnitTestCase(String name)
+ {
+ super(name);
+ }
+
+ public void testWhitespaceUnmarshalling() throws Exception
+ {
+ SchemaBinding schema = XsdBinder.bind(new StringReader(XSD), null);
+
+ schema.setIgnoreUnresolvedFieldOrClass(false);
+ schema.setIgnoreWhitespacesInMixedContent(false);
+
+ ClassMetaData classMetaData = new ClassMetaData();
+ classMetaData.setImpl(Top.class.getName());
+ ElementBinding element = schema.getElement(new QName(NS, "top"));
+ assertNotNull(element);
+ element.setClassMetaData(classMetaData);
+
+ Top top = (Top) unmarshal("IgnorableWhitespaceContent.xml", schema, Top.class);
+ assertNotNull(top.string);
+ assertEquals(2, top.string.size());
+ assertEquals(" ", top.string.get(0));
+ assertEquals("\n newline, 6 spaces, newline, 3 spaces\n ", top.string.get(1));
+ }
+
+ public void testWhitespaceMarshalling() throws Exception
+ {
+ SchemaBinding schema = XsdBinder.bind(new StringReader(XSD), null);
+
+ schema.setIgnoreUnresolvedFieldOrClass(false);
+ schema.setIgnoreWhitespacesInMixedContent(false);
+
+ ClassMetaData classMetaData = new ClassMetaData();
+ classMetaData.setImpl(Top.class.getName());
+ ElementBinding element = schema.getElement(new QName(NS, "top"));
+ assertNotNull(element);
+ element.setClassMetaData(classMetaData);
+
+ Top top = new Top();
+ top.string = new ArrayList();
+ top.string.add(" ");
+ top.string.add("\n newline, 6 spaces, newline, 3 spaces\n ");
+ MarshallerImpl marshaller = new MarshallerImpl();
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(schema, null, top, writer);
+
+ // TODO: the xml diff trims whitespaces...
+ //assertXmlFileContent("IgnorableWhitespaceContent.xml", writer.getBuffer().toString());
+ //System.out.println(writer.getBuffer().toString());
+
+ Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
+ Object o = unmarshaller.unmarshal(new StringReader(writer.getBuffer().toString()), schema);
+
+ assertEquals(top, o);
+ }
+
+ public void testObjectModelFactory() throws Exception
+ {
+ String url = findXML("IgnorableWhitespaceContent.xml");
+
+ ObjectModelFactory omf = new OMF();
+
+ Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
+ Object o = unmarshaller.unmarshal(url, omf, null);
+
+ assertNotNull(o);
+ assertTrue(o instanceof Top);
+ Top top = (Top) o;
+ assertEquals(2, top.string.size());
+ assertEquals(" ", top.string.get(0));
+ assertEquals("\n newline, 6 spaces, newline, 3 spaces\n ", top.string.get(1));
+
+ }
+
+ public static final class OMF implements ObjectModelFactory
+ {
+ public Object completeRoot(Object root, UnmarshallingContext ctx, String namespaceURI, String localName)
+ {
+ return root;
+ }
+
+ public Object newRoot(Object root, UnmarshallingContext ctx, String namespaceURI, String localName, Attributes attrs)
+ {
+ ctx.setTrimTextContent(false);
+ return new Top();
+ }
+
+ public void setValue(Top top, UnmarshallingContext ctx, String ns, String name, String value)
+ {
+ if(name.equals("string"))
+ {
+ if(top.string == null)
+ {
+ top.string = new ArrayList();
+ }
+ top.string.add(value);
+ }
+ }
+ }
+
+ public static class Top
+ {
+ public List string;
+
+ public int hashCode()
+ {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((string == null) ? 0 : string.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Top other = (Top) obj;
+ if (string == null)
+ {
+ if (other.string != null)
+ return false;
+ }
+ else if (!string.equals(other.string))
+ return false;
+ return true;
+ }
+
+ public String toString()
+ {
+ return "[top: string=" + string + "]";
+ }
+ }
+}
Deleted: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java
===================================================================
--- jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java 2007-06-19 12:42:59 UTC (rev 2419)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -1,119 +0,0 @@
-/*
- * 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.pojoserver.metadata;
-
-import java.util.Map;
-import java.util.Iterator;
-
-import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
-/**
- * @author Scott.Stark at jboss.org
- * @version $Revision: 37406 $
- */
-public class AbstractFeatureMetaData
- implements FeatureMetaData
-{
- /** The description */
- protected String description;
-
- /** The generic metadata */
- protected Map values;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- /**
- * Create a new meta data
- */
- public AbstractFeatureMetaData()
- {
- }
-
- // Public --------------------------------------------------------
-
- /**
- * Set the description.
- *
- * @param description the description.
- */
- public void setDescription(String description)
- {
- this.description = description;
- }
-
- /**
- * Set the value.
- *
- * @param key the key to the value
- * @param value The value to set.
- */
- public void setValue(String key, Object value)
- {
- if (values == null)
- values = new ConcurrentReaderHashMap();
- values.put(key, value);
- }
-
- // MetaData implementation ---------------------------------------
-
- public String getDescription()
- {
- return description;
- }
-
- public Object getValue(String key)
- {
- if (values == null)
- return null;
- return values.get(key);
- }
-
- // MetaDataVisitorNote overrides ----------------------------------
-
- public void visit(MetaDataVisitor visitor)
- {
- visitor.visit(this);
- }
-
- public Iterator getChildren()
- {
- return null;
- }
-
- // JBossObject overrides ------------------------------------------
-
- public void toString(StringBuffer buffer)
- {
- if (description != null)
- buffer.append("description=").append(description);
- if (values != null)
- buffer.append(" values=").append(values);
- }
-
- public void toShortString(StringBuffer buffer)
- {
- buffer.append(description);
- }
-
-}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java (from rev 2482, jbossxb/branches/1_0/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/java/org/jboss/test/xml/pojoserver/metadata/AbstractFeatureMetaData.java 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,119 @@
+/*
+ * 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.pojoserver.metadata;
+
+import java.util.Map;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 37406 $
+ */
+public class AbstractFeatureMetaData
+ implements FeatureMetaData
+{
+ /** The description */
+ protected String description;
+
+ /** The generic metadata */
+ protected Map values;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /**
+ * Create a new meta data
+ */
+ public AbstractFeatureMetaData()
+ {
+ }
+
+ // Public --------------------------------------------------------
+
+ /**
+ * Set the description.
+ *
+ * @param description the description.
+ */
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ /**
+ * Set the value.
+ *
+ * @param key the key to the value
+ * @param value The value to set.
+ */
+ public void setValue(String key, Object value)
+ {
+ if (values == null)
+ values = new ConcurrentHashMap();
+ values.put(key, value);
+ }
+
+ // MetaData implementation ---------------------------------------
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public Object getValue(String key)
+ {
+ if (values == null)
+ return null;
+ return values.get(key);
+ }
+
+ // MetaDataVisitorNote overrides ----------------------------------
+
+ public void visit(MetaDataVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ public Iterator getChildren()
+ {
+ return null;
+ }
+
+ // JBossObject overrides ------------------------------------------
+
+ public void toString(StringBuffer buffer)
+ {
+ if (description != null)
+ buffer.append("description=").append(description);
+ if (values != null)
+ buffer.append(" values=").append(values);
+ }
+
+ public void toShortString(StringBuffer buffer)
+ {
+ buffer.append(description);
+ }
+
+}
Copied: jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml (from rev 2420, jbossxb/branches/1_0/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml)
===================================================================
--- jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml (rev 0)
+++ jbossxb/tags/jbossxb-1.0.0.CR11/src/test/resources/org/jboss/test/xml/IgnorableWhitespaceContent.xml 2007-08-15 11:51:08 UTC (rev 2490)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<top xmlns='http://www.jboss.org/test/xml/simpleContent'>
+ <string> </string>
+ <string>
+ newline, 6 spaces, newline, 3 spaces
+ </string>
+</top>
More information about the jboss-svn-commits
mailing list