You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2005/02/11 04:39:13 UTC
cvs commit: ws-axis/java/src/org/apache/axis/encoding/ser/xbeans XmlBeanSerializer.java
dims 2005/02/10 19:39:13
Modified: java/src/org/apache/axis/encoding/ser/xbeans
XmlBeanSerializer.java
Log:
fix for AXIS-1812 - XMLBeanSerialization doesn't generate correct WSDL \n from daryoush mehrtash
Revision Changes Path
1.3 +131 -123 ws-axis/java/src/org/apache/axis/encoding/ser/xbeans/XmlBeanSerializer.java
Index: XmlBeanSerializer.java
===================================================================
RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/encoding/ser/xbeans/XmlBeanSerializer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- XmlBeanSerializer.java 21 Jan 2005 20:09:48 -0000 1.2
+++ XmlBeanSerializer.java 11 Feb 2005 03:39:13 -0000 1.3
@@ -21,15 +21,21 @@
package org.apache.axis.encoding.ser.xbeans;
+import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.encoding.Serializer;
import org.apache.axis.wsdl.fromJava.Types;
+import org.apache.beehive.wsm.wsdl.Schema;
+import org.apache.beehive.wsm.wsdl.Utilities;
+import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaType;
+import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
+import org.w3.x2001.xmlSchema.LocalElement;
import org.w3.x2001.xmlSchema.SchemaDocument;
import org.w3.x2001.xmlSchema.TopLevelComplexType;
import org.w3.x2001.xmlSchema.TopLevelElement;
@@ -44,6 +50,7 @@
import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Array;
import java.util.HashSet;
import java.util.Set;
@@ -92,145 +99,146 @@
}
/**
- * Return XML schema for the specified type, suitable for insertion into
- * the <types> element of a WSDL document, or underneath an
+ * Return XML schema for the specified type, suitable for insertion into the
+ * <types> element of a WSDL document, or underneath an
* <element> or <attribute> declaration.
- *
- * @param javaType the Java Class we're writing out schema for
- * @param types the Java2WSDL Types object which holds the context
- * for the WSDL being generated.
+ *
+ * @param javaType
+ * the Java Class we're writing out schema for
+ * @param types
+ * the Java2WSDL Types object which holds the context for the
+ * WSDL being generated.
* @return a type element containing a schema simpleType/complexType
* @see org.apache.axis.wsdl.fromJava.Types
*/
public Element writeSchema(Class javaType, Types types) throws Exception {
- if (XmlObject.class.isAssignableFrom(javaType)) {
+ try {
+ if (!XmlObject.class.isAssignableFrom(javaType)) {
+ throw new RuntimeException(
+ "Invalid Object type is assigned to the XMLBeanSerialization Type: "
+ + javaType.getCanonicalName());
+ }
+
SchemaType docType = XmlBeans.typeForClass(javaType);
+ writeSchemaForDocType(docType, types);
+ // assume that the writeSchemaForDocType wrote the schema
+ // for the type and all the dependent types.
+ return null;
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ }
- /*
- * NOTE jcolwell@bea.com 2004-Oct-18 --
- * This is a hack to handle node adoption.
- * I don't like it but I need to avoid a
- * org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR
- * NOTE jcolwell@bea.com 2004-Oct-21 --
- * since I already use the Document I'll use it to check
- * if a schema for the namspace is already in place.
- */
-
- Document doc = types.createElement("deleteme")
- .getOwnerDocument();
- XmlOptions opts = new XmlOptions()
- .setLoadReplaceDocumentElement(null);
- Element root = doc.getDocumentElement();
- String schemaSrc = docType.getSourceName();
- InputStream stream = docType.getTypeSystem()
- .getSourceAsStream(schemaSrc);
- SchemaDocument.Schema schema = null;
- if (schemaSrc.endsWith(".wsdl") || schemaSrc.endsWith(".WSDL")) {
- DefinitionsDocument defDoc =
- DefinitionsDocument.Factory.parse(stream);
- TTypes tt = defDoc.getDefinitions().getTypesArray(0);
- XmlObject[] kids = selectChildren
- (tt, SchemaDocument.Schema.class);
- SchemaDocument.Schema[] schemas =
- new SchemaDocument.Schema[kids.length];
-
- // NOTE jcolwell@bea.com 2005-Jan-10 -- this is the part that the
- // fancy generics saves me from having to do after each call to
- // selectChildren(XmlObject, Class)
-
- for (int j = 0; j < kids.length; j++) {
- schemas[j] = (SchemaDocument.Schema) kids[j];
- }
- if (schemas.length == 1) {
- schema = schemas[0];
- } else {
- String stNS = docType.getName().getNamespaceURI();
- for (int j = 0; j < schemas.length; j++) {
- if (stNS.equals(schemas[j].getTargetNamespace())) {
- schema = schemas[j];
- break;
- }
- }
- }
- } else {
- SchemaDocument schemaDoc = SchemaDocument.Factory.parse(stream);
- schema = schemaDoc.getSchema();
+ /**
+ * @param types
+ * @param docType
+ * @return
+ * @throws Exception
+ */
+ private void writeSchemaForDocType(SchemaType docType, Types types)
+ throws Exception {
+ Schema mySchema = Utilities.findtSchemaDocument(docType);
+
+ QName q = docType.getName();
+
+ XmlObject typeNodeInWSDL = mySchema.getTypeNode(q);
+
+ if (null == typeNodeInWSDL)
+ throw new RuntimeException(
+ "Type for object not found in the assigned WSDL file. "
+ + docType.getName() + " schema in: "
+ + docType.getSourceName());
+ // insertDependentTypes(typeNodeInWSDL, types);
+ Node n = typeNodeInWSDL.getDomNode();
+ Document doc = types.createElement(
+ "element_to_get_document_useless_otherwise").getOwnerDocument();
+ Element e = (Element) doc.importNode(n, true);
+ try {
+ types.writeSchemaElementDecl(q, e);
+ } catch (AxisFault e1) {
+ // this means the types was already in... fine!
+ // TBD: make sure there are other types of exceptions are at least
+ // reported
+ }
+ Set<QName> dependentTypes = new HashSet<QName>();
+ getAllDependentTypes(typeNodeInWSDL, dependentTypes);
+ for (QName nxtType : dependentTypes) {
+ Class nxtJavaType = null;
+ // add the class if it is an xml bean
+ if (null != (nxtJavaType = q2UserClass(nxtType))
+ && XmlObject.class.isAssignableFrom(nxtJavaType)) {
+ writeSchema(nxtJavaType, types);
}
+ }
+ return;
+ }
- /*
- FIXME jcolwell@bea.com 2004-Oct-21 -- it would be great if
- the Types.loadInputSchema took an input source instead of a
- String so I could directly pass in the input stream instead of
- providing the schema elements individually.
- */
- DefinitionsDocument defDoc = DefinitionsDocument.Factory
- .newInstance();
- TDefinitions definitions = defDoc.addNewDefinitions();
- definitions.addNewService();
- Node defEl = definitions.newDomNode(new XmlOptions()
- .setSaveOuter());
- Document dDoc = defEl.getOwnerDocument();
- if (null == dDoc.getDocumentElement()) {
- dDoc.appendChild(defEl);
- }
- Set existingNameSpaces = new HashSet();
- if (dDoc != null) {
- types.insertTypesFragment(dDoc);
- Element e = (Element) dDoc.getFirstChild().getFirstChild()
- .getFirstChild();
- if (e != null) {
- String tn = e.getAttribute("targetNamespace");
- existingNameSpaces.add(tn);
- while (null != (e = (Element) e.getNextSibling())) {
- tn = e.getAttribute("targetNamespace");
- existingNameSpaces.add(tn);
- }
- }
- } else {
- throw new Exception("null document");
- }
- if (schema != null) {
- String targetNamespace = schema.getTargetNamespace();
- if (targetNamespace != null) {
- if (!existingNameSpaces.contains(targetNamespace)) {
- TopLevelComplexType[] schemaTypes = schema
- .getComplexTypeArray();
- for (int j = 0; j < schemaTypes.length; j++) {
- types.writeSchemaElement(targetNamespace,
- (Element) doc
- .importNode(schemaTypes[j].newDomNode()
- .getFirstChild(),
- true));
- }
- TopLevelElement[] elements = schema
- .getElementArray();
- for (int j = 0; j < elements.length; j++) {
- types.writeSchemaElement(targetNamespace,
- (Element) doc
- .importNode(elements[j].newDomNode()
- .getFirstChild(),
- true));
- }
- }
- return null;
- }
+ /**
+ * @param nxtType
+ * @return null for classes that are not found, or if they are primitive types
+ * *
+ */
+ private Class q2UserClass(QName qname) {
+ SchemaTypeLoader stl = XmlBeans.getContextTypeLoader();
+ SchemaType st = stl.findType(qname);
+ if (st == null) {
+ SchemaField sf = stl.findElement(qname);
+ if (sf != null)
+ st = sf.getType();
+ }
+
+ if (st != null && !st.isBuiltinType())
+ return st.getJavaClass();
+ else
+ return null; // for classes that are not found, or are build in
+
+ }
+
+ /**
+ * @param nodeInWSDL
+ * @param dependentTypes
+ * @return
+ *
+ * Walk all the nodes under the nodeInWSDL if there is an 'element' type the
+ * add its types or references to the dependent type.
+ */
+ private void getAllDependentTypes(XmlObject nodeInWSDL,
+ Set<QName> dependentTypes) {
+ // scan for any node under the type that has "type" or "ref" attribute
+ XmlCursor cursor = nodeInWSDL.newCursor();
+ if (cursor.toFirstChild()) { // has child
+ while (true) {
+ getAllDependentTypes(cursor.getObject(), dependentTypes);
+ if (!cursor.toNextSibling())
+ break;
}
- throw new Exception(javaType.getName()
- + "did not specify a target namespace");
- } else {
- throw new Exception(javaType.getName()
- + " must be a subclass of XmlObject");
}
+ if (nodeInWSDL.schemaType().getName().getLocalPart().equals(
+ "localElement")) {
+ LocalElement e = (LocalElement) nodeInWSDL;
+
+ if (e.isSetType())
+ dependentTypes.add(e.getType());
+ else if (e.isSetRef())
+ dependentTypes.add(e.getRef());
+ }
+ return;
}
- // NOTE jcolwell@bea.com 2004-Nov-15 --
+ // NOTE jcolwell@bea.com 2004-Nov-15 --
// once the WSDLProcessor is changed to an interface, remove this function
// and use the one in the upcoming XmlBeanWSDLProcessor.
- private static XmlObject[] selectChildren(XmlObject parent,
- Class childClass)
- throws IllegalAccessException, NoSuchFieldException {
+ private static <T extends XmlObject> T[] selectChildren(XmlObject parent,
+ Class<T> childClass) throws IllegalAccessException,
+ NoSuchFieldException {
// retrieve the SchemaType from the static type field
SchemaType st = (SchemaType) childClass.getField("type").get(null);
- return parent.selectChildren(st.getDocumentElementName());
+ XmlObject[] kids = parent.selectChildren(st.getDocumentElementName());
+ T[] castKids = (T[]) Array.newInstance(childClass, kids.length);
+ for (int j = 0; j < castKids.length; j++) {
+ castKids[j] = childClass.cast(kids[j]);
+ }
+ return castKids;
}
}