|
Hi Ajith, I've attached a patch against Axis2 0.94 that appears to address the problem. All the unit tests pass and the code for recursive types appears to be correct, but there could be other adverse consequences I haven't hit yet. Hope this is useful in addressing the issue, Chuck Hi Chuck, Hmm.. Valid scenario and humbly the recursive code that processes the schema would have failed in this scenario. Your suggesion is right but I'll have to go through the tests to figure out the consequences.Ajith On 3/3/06, Chuck Williams <[EMAIL PROTECTED]> wrote: |
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java codegen.src.new/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java
--- codegen.src.orig/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java 2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/BeanWriterMetaInfoHolder.java 2006-02-08 22:24:45.000000000 -1000
@@ -32,6 +32,7 @@
private boolean ordered = false;
+ private boolean choice = false;
private boolean anonymous = false;
private boolean extension = false;
private String extensionClassName = "";
@@ -115,6 +116,24 @@
public void setOrdered(boolean ordered) {
this.ordered = ordered;
}
+
+ /**
+ * Gets the choice status.
+ *
+ * @return Returns boolean.
+ */
+ public boolean isChoice() {
+ return choice;
+ }
+
+ /**
+ * Sets the choice flag.
+ *
+ * @param choice
+ */
+ public void setChoice(boolean choice) {
+ this.choice = choice;
+ }
/**
* Registers a mapping.
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/SchemaCompiler.java codegen.src.new/org/apache/axis2/schema/SchemaCompiler.java
--- codegen.src.orig/org/apache/axis2/schema/SchemaCompiler.java 2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/SchemaCompiler.java 2006-03-02 23:53:47.000000000 -1000
@@ -404,6 +404,10 @@
|| baseSchemaTypeMap.containsKey(complexType.getQName())) {
return;
}
+
+ // Must do this up front to support recursive types
+ String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(complexType.getQName());
+ processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
XmlSchemaParticle particle = complexType.getParticle();
BeanWriterMetaInfoHolder metaInfHolder = new BeanWriterMetaInfoHolder();
@@ -440,10 +444,7 @@
//write the class. This type mapping would have been populated right now
//Note - We always write classes for complex types
- String fullyQualifiedClassName = writer.write(complexType, processedTypemap, metaInfHolder);
- //populate the type mapping with the elements
- processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
-
+ writer.write(complexType, processedTypemap, metaInfHolder, fullyQualifiedClassName);
}
@@ -497,7 +498,9 @@
XmlSchemaObjectCollection items = ((XmlSchemaAll) particle).getItems();
process(items, metainfHolder, false);
} else if (particle instanceof XmlSchemaChoice) {
- //put the code here to handle the choice!
+ XmlSchemaObjectCollection items = ((XmlSchemaChoice) particle).getItems();
+ metainfHolder.setChoice(true);
+ process(items, metainfHolder, false);
}
}
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/template/ADBBeanTemplate.xsl codegen.src.new/org/apache/axis2/schema/template/ADBBeanTemplate.xsl
--- codegen.src.orig/org/apache/axis2/schema/template/ADBBeanTemplate.xsl 2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/template/ADBBeanTemplate.xsl 2006-02-08 22:24:45.000000000 -1000
@@ -32,6 +32,8 @@
<xsl:template match="bean">
<xsl:variable name="name"><xsl:value-of select="@name"/></xsl:variable>
+ <xsl:variable name="choice" select="@choice"/>
+
<!-- write the class header. this should be done only when unwrapped -->
<xsl:if test="not(not(@unwrapped) or (@skip-write))">
@@ -64,8 +66,18 @@
</xsl:otherwise>
</xsl:choose>
-
-
+
+ <xsl:if test="$choice">
+ /** Whenever a new property is set ensure all others are unset
+ * There can be only one choice and the last one wins
+ */
+ private void clearAllSettingTrackers() {
+ <xsl:for-each select="property">
+ local<xsl:value-of select="@javaname"/>Tracker = false;
+ </xsl:for-each>
+ }
+ </xsl:if>
+
<xsl:for-each select="property">
<xsl:variable name="propertyType"><xsl:value-of select="@type"></xsl:value-of></xsl:variable>
<xsl:variable name="propertyName"><xsl:value-of select="@name"></xsl:value-of></xsl:variable>
@@ -81,7 +93,7 @@
private <xsl:value-of select="$propertyType"/><xsl:text> </xsl:text><xsl:value-of select="$varName" /> ;
<!-- Generate a tracker only if the min occurs is zero, which means if the user does
not bother to set that value, we do not send it -->
- <xsl:if test="$min=0">
+ <xsl:if test="($min=0) or $choice">
/* This tracker boolean wil be used to detect whether the user called the set method
for this attribute. It will be used to determine whether to include this field
in the serialized XML
@@ -115,10 +127,13 @@
}
</xsl:if>
</xsl:if>
- <xsl:if test="$min=0">
- //update the setting tracker
- <xsl:value-of select="$settingTracker"/> = true;
- </xsl:if>
+ <xsl:if test="$choice">
+ clearAllSettingTrackers();
+ </xsl:if>
+ <xsl:if test="($min=0) or $choice">
+ //update the setting tracker
+ <xsl:value-of select="$settingTracker"/> = true;
+ </xsl:if>
this.<xsl:value-of select="$varName"/>=param;
}
</xsl:for-each>
@@ -143,7 +158,7 @@
<xsl:variable name="settingTracker">local<xsl:value-of select="@javaname"/>Tracker</xsl:variable>
- <xsl:if test="$min=0"> if (<xsl:value-of select="$settingTracker"/>){</xsl:if>
+ <xsl:if test="($min=0) or $choice"> if (<xsl:value-of select="$settingTracker"/>){</xsl:if>
<xsl:choose>
<xsl:when test="@ours or @any">
elementList.add(new javax.xml.namespace.QName("<xsl:value-of select="$namespace"/>",
@@ -160,7 +175,7 @@
elementList.add(org.apache.axis2.databinding.utils.ConverterUtil.convertToString(<xsl:value-of select="$varName"/>));
</xsl:otherwise>
</xsl:choose>
- <xsl:if test="$min=0">}</xsl:if>
+ <xsl:if test="($min=0) or $choice">}</xsl:if>
</xsl:for-each>
<xsl:for-each select="[EMAIL PROTECTED]">
@@ -218,7 +233,10 @@
try {
int event = reader.getEventType();
int count = 0;
- int argumentCount = <xsl:value-of select="count(property)"/> ;
+ int argumentCount = <xsl:choose>
+ <xsl:when test="$choice">1</xsl:when>
+ <xsl:otherwise><xsl:value-of select="count(property)"/></xsl:otherwise>
+ </xsl:choose>;
boolean done =false;
//event better be a START_ELEMENT. if not we should go up to the start element here
while (!reader.isStartElement()){
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/writer/BeanWriter.java codegen.src.new/org/apache/axis2/schema/writer/BeanWriter.java
--- codegen.src.orig/org/apache/axis2/schema/writer/BeanWriter.java 2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/BeanWriter.java 2006-03-02 23:54:38.000000000 -1000
@@ -1,5 +1,6 @@
package org.apache.axis2.schema.writer;
+import javax.xml.namespace.QName;
import org.apache.axis2.schema.BeanWriterMetaInfoHolder;
import org.apache.axis2.schema.CompilerOptions;
import org.apache.axis2.schema.SchemaCompilationException;
@@ -51,6 +52,12 @@
* of the schema compiler may be exposed.
*/
public Map getModelMap();
+
+ /** Make the fully qualified class name for an element or named type
+ * @param qName the qualified Name for this element or type in the schema
+ * @return the appropriate fully qualified class name to use in generated code
+ */
+ public String makeFullyQualifiedClassName(QName qName);
/**
* Write a complex type
@@ -58,10 +65,11 @@
* @param complexType
* @param typeMap
* @param metainf
+ * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
* @return Returns String.
* @throws SchemaCompilationException
*/
- public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException;
+ public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf, String fullyQualifiedClassName) throws SchemaCompilationException;
/**
* Write a element
diff -urX exclude.files codegen.src.orig/org/apache/axis2/schema/writer/JavaBeanWriter.java codegen.src.new/org/apache/axis2/schema/writer/JavaBeanWriter.java
--- codegen.src.orig/org/apache/axis2/schema/writer/JavaBeanWriter.java 2006-01-24 18:14:07.000000000 -1000
+++ codegen.src.new/org/apache/axis2/schema/writer/JavaBeanWriter.java 2006-03-02 23:54:38.000000000 -1000
@@ -138,7 +138,7 @@
try {
QName qName = element.getQName();
- return process(qName, metainf, typeMap, true);
+ return process(qName, metainf, typeMap, true, null);
} catch (Exception e) {
throw new SchemaCompilationException(e);
}
@@ -150,16 +150,17 @@
* @param complexType
* @param typeMap
* @param metainf
+ * @param fullyQualifiedClassName the name returned by makeFullyQualifiedClassName() or null if it wasn't called
* @throws org.apache.axis2.schema.SchemaCompilationException
*
* @see BeanWriter#write(org.apache.ws.commons.schema.XmlSchemaComplexType, java.util.Map, org.apache.axis2.schema.BeanWriterMetaInfoHolder)
*/
- public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException {
+ public String write(XmlSchemaComplexType complexType, Map typeMap, BeanWriterMetaInfoHolder metainf, String fullyQualifiedClassName) throws SchemaCompilationException {
try {
//determine the package for this type.
QName qName = complexType.getQName();
- return process(qName, metainf, typeMap, false);
+ return process(qName, metainf, typeMap, false, fullyQualifiedClassName);
} catch (SchemaCompilationException e) {
throw e;
@@ -223,6 +224,31 @@
}
+ /** Make the fully qualified class name for an element or named type
+ * @param qName the qualified Name for this element or type in the schema
+ * @return the appropriate fully qualified class name to use in generated code
+ */
+ public String makeFullyQualifiedClassName(QName qName) {
+ String nameSpaceFromURL = URLProcessor.makePackageName(qName.getNamespaceURI());
+ String packageName = this.packageName == null ?
+ nameSpaceFromURL :
+ this.packageName + nameSpaceFromURL;
+ String originalName = qName.getLocalPart();
+ String className = makeUniqueJavaClassName(this.namesList, originalName);
+ String packagePrefix = null;
+ String fullyqualifiedClassName;
+ if (wrapClasses)
+ packagePrefix = (this.packageName == null ? DEFAULT_PACKAGE+"." : this.packageName) + WRAPPED_DATABINDING_CLASS_NAME;
+ else if (writeClasses)
+ packagePrefix = packageName;
+ if (packagePrefix!=null)
+ fullyqualifiedClassName = packagePrefix + (packagePrefix.endsWith(".")?"":".") + className;
+ else
+ fullyqualifiedClassName = className;
+ //return the fully qualified class name
+ return fullyqualifiedClassName;
+ }
+
/**
* A util method that holds common code
* for the complete schema that the generated XML complies to
@@ -235,7 +261,11 @@
* @return Returns String.
* @throws Exception
*/
- private String process(QName qName, BeanWriterMetaInfoHolder metainf, Map typeMap, boolean isElement) throws Exception {
+ private String process(QName qName, BeanWriterMetaInfoHolder metainf, Map typeMap, boolean isElement, String fullyqualifiedClassName) throws Exception {
+
+ if (fullyqualifiedClassName == null)
+ fullyqualifiedClassName = makeFullyQualifiedClassName(qName);
+ String className = fullyqualifiedClassName.substring(1+fullyqualifiedClassName.lastIndexOf('.'));
String nameSpaceFromURL = URLProcessor.makePackageName(qName.getNamespaceURI());
@@ -244,11 +274,7 @@
this.packageName + nameSpaceFromURL;
String originalName = qName.getLocalPart();
- String className = makeUniqueJavaClassName(this.namesList, originalName);
-
- String packagePrefix = null;
- String fullyqualifiedClassName;
ArrayList propertyNames = new ArrayList();
if (!templateLoaded) {
@@ -261,7 +287,6 @@
globalWrappedDocument.getDocumentElement().appendChild(
getBeanElement(globalWrappedDocument, className, originalName, packageName, qName, isElement, metainf, propertyNames, typeMap)
);
- packagePrefix = (this.packageName == null ? DEFAULT_PACKAGE+"." : this.packageName) + WRAPPED_DATABINDING_CLASS_NAME;
} else {
//create the model
@@ -275,7 +300,6 @@
//parse with the template and create the files
parse(model, out);
- packagePrefix = packageName ;
}
//add the model to the model map
@@ -286,11 +310,6 @@
}
- if (packagePrefix!=null){
- fullyqualifiedClassName = packagePrefix + (packagePrefix.endsWith(".")?"":".") + className;
- }else{
- fullyqualifiedClassName = className;
- }
//return the fully qualified class name
return fullyqualifiedClassName;
@@ -342,6 +361,11 @@
if (metainf.isExtension()) {
XSLTUtils.addAttribute(model, "extension", metainf.getExtensionClassName(), rootElt);
}
+
+ if (metainf.isChoice()) {
+ XSLTUtils.addAttribute(model, "choice", "yes", rootElt);
+ }
+
// go in the loop and add the part elements
QName[] qNames;
if (metainf.isOrdered()) {
