You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by di...@apache.org on 2005/07/07 05:10:46 UTC
cvs commit: ws-axis/java/src/org/apache/axis/encoding/ser/xbeans XmlBeanDeserializer.java XmlBeanSerializer.java
dims 2005/07/06 20:10:46
Modified: java/src/org/apache/axis/encoding/ser/xbeans
XmlBeanDeserializer.java XmlBeanSerializer.java
Log:
Fix for AXIS-1812 - XMLBeanSerialization doesn't generate correct WSDL
Revision Changes Path
1.2 +0 -4 ws-axis/java/src/org/apache/axis/encoding/ser/xbeans/XmlBeanDeserializer.java
Index: XmlBeanDeserializer.java
===================================================================
RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/encoding/ser/xbeans/XmlBeanDeserializer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XmlBeanDeserializer.java 21 Jan 2005 17:41:11 -0000 1.1
+++ XmlBeanDeserializer.java 7 Jul 2005 03:10:46 -0000 1.2
@@ -40,11 +40,9 @@
public class XmlBeanDeserializer extends DeserializerImpl {
private Class mJavaType;
- private QName mXmlType;
public XmlBeanDeserializer(Class javaType, QName xmlType) {
mJavaType = javaType;
- mXmlType = xmlType;
}
public void onStartElement(String namespace, String localName,
@@ -56,7 +54,6 @@
XmlOptions opts = new XmlOptions()
.setLoadReplaceDocumentElement(null);
XmlObject xObj = XmlObject.Factory.parse(me, opts);
- SchemaType st = xObj.schemaType();
SchemaType jt = (SchemaType) mJavaType.getField("type").get(null);
XmlObject converted = xObj.changeType(jt);
if (converted != null) {
@@ -64,7 +61,6 @@
} else {
XmlObject[] children = xObj.selectChildren(QNameSet.ALL);
for (int j = 0; j < children.length; j++) {
- st = children[j].schemaType();
converted = xObj.changeType(jt);
if (converted != null) {
setValue(converted);
1.5 +203 -128 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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- XmlBeanSerializer.java 14 Feb 2005 02:53:15 -0000 1.4
+++ XmlBeanSerializer.java 7 Jul 2005 03:10:46 -0000 1.5
@@ -18,41 +18,48 @@
*
* Original author: Jonathan Colwell
*/
-
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.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.XmlException;
import org.apache.xmlbeans.XmlObject;
-import org.apache.xmlbeans.XmlOptions;
-import org.w3.x2001.xmlSchema.SchemaDocument;
-import org.w3.x2001.xmlSchema.TopLevelComplexType;
-import org.w3.x2001.xmlSchema.TopLevelElement;
+import org.apache.xmlbeans.impl.xb.xsdschema.LocalElement;
+import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
+import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelComplexType;
+import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelElement;
+import org.apache.xmlbeans.impl.xb.xsdschema.TopLevelSimpleType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xmlsoap.schemas.wsdl.DefinitionsDocument;
-import org.xmlsoap.schemas.wsdl.TDefinitions;
import org.xmlsoap.schemas.wsdl.TTypes;
import javax.xml.namespace.QName;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashSet;
import java.util.Set;
/**
* Class XmlBeanSerializer
+ *
* @author Jonathan Colwell
*/
public class XmlBeanSerializer implements Serializer {
-
/**
* Serialize an element named name, with the indicated attributes
* and value.
@@ -92,145 +99,213 @@
}
/**
- * 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 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);
+ }
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();
+ private void writeSchemaForDocType(SchemaType docType, Types types)
+ throws Exception {
+ SchemaDocument.Schema[] mySchemas = findtSchemaDocument(docType);
+ QName q = docType.getName();
+ XmlObject typeNodeInWSDL = getTypeNode(mySchemas, 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 dependentTypes = new HashSet();
+ getAllDependentTypes(typeNodeInWSDL, dependentTypes);
+ for (java.util.Iterator it = dependentTypes.iterator(); it.hasNext();) {
+ QName nxtType = (QName) it.next();
+ Class nxtJavaType;
+ // add the class if it is an xml bean
+ if (null != (nxtJavaType = q2UserClass(nxtType))
+ && XmlObject.class.isAssignableFrom(nxtJavaType)) {
+ writeSchema(nxtJavaType, types);
}
+ }
+ }
- /*
- 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;
- }
+ 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();
+ // for classes that are not found, or are built in
+ return null;
+ }
+
+ /**
+ * @param nodeInWSDL
+ * @param dependentTypes 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 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");
+ }
+ 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());
+ }
+ }
+
+ public static DefinitionsDocument parseWSDL(String wsdlLocation)
+ throws IOException, MalformedURLException, XmlException {
+ if (wsdlLocation.indexOf("://") > 2) {
+ return parseWSDL(new URL(wsdlLocation));
} else {
- throw new Exception(javaType.getName()
- + " must be a subclass of XmlObject");
+ return parseWSDL(new File(wsdlLocation));
}
}
- // 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)
+ public static DefinitionsDocument parseWSDL(File wsdlFile)
+ throws IOException, XmlException {
+ return DefinitionsDocument.Factory.parse(wsdlFile);
+ }
+
+ public static DefinitionsDocument parseWSDL(URL wsdlURL)
+ throws IOException, XmlException {
+ return DefinitionsDocument.Factory.parse(wsdlURL);
+ }
+
+ public static DefinitionsDocument parseWSDL(InputStream wsdlStream)
+ throws IOException, XmlException {
+ return DefinitionsDocument.Factory.parse(wsdlStream);
+ }
+
+ public static SchemaDocument parseSchema(InputStream stream)
+ throws XmlException, IOException {
+ return SchemaDocument.Factory.parse(stream);
+ }
+
+ public static SchemaDocument.Schema[] selectChildren(XmlObject parent, Class 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());
+ SchemaDocument.Schema[] castKids = (SchemaDocument.Schema[]) Array.newInstance(childClass, kids.length);
+ for (int j = 0; j < castKids.length; j++) {
+ castKids[j] = (SchemaDocument.Schema) kids[j];
+ }
+ return castKids;
+ }
+
+ public static SchemaDocument.Schema[] findtSchemaDocument(SchemaType docType)
+ throws XmlException, IOException, IllegalAccessException, NoSuchFieldException {
+ SchemaDocument.Schema[] schemas = null;
+ String schemaSrc = docType.getSourceName();
+ InputStream stream = null;
+ try {
+ stream = docType.getTypeSystem().getSourceAsStream(schemaSrc);
+ if (null == stream) {
+ throw new RuntimeException("WSDL file not found: " + schemaSrc);
+ }
+ if (schemaSrc.toLowerCase().endsWith(".wsdl")) {
+ TTypes tt = parseWSDL(stream).getDefinitions().getTypesArray(0);
+ schemas = selectChildren(tt, SchemaDocument.Schema.class);
+ } else {
+ SchemaDocument schemaDoc = parseSchema(stream);
+ schemas = new SchemaDocument.Schema[1];
+ schemas[0] = schemaDoc.getSchema();
+ }
+ } finally {
+ if (null != stream)
+ stream.close();
+ }
+ return schemas;
+ }
+
+ public static XmlObject getTypeNode(SchemaDocument.Schema[] schemas, QName q) {
+ // first find the schema with matching namespace
+ SchemaDocument.Schema schema = null;
+ for (int i = 0; i < schemas.length; i++) {
+ SchemaDocument.Schema nxtSchema = schemas[i];
+ if (nxtSchema.getTargetNamespace() != null
+ && nxtSchema.getTargetNamespace().equals(
+ q.getNamespaceURI())) {
+ schema = nxtSchema;
+ break;
+ }
+ }
+ if (null == schema)
+ return null; // namespace is not found in this schema.
+ // look in complex types
+ TopLevelComplexType[] tlComplexTypes = schema.getComplexTypeArray();
+ for (int i = 0; i < tlComplexTypes.length; i++) {
+ TopLevelComplexType nxtComplexType = tlComplexTypes[i];
+ if (nxtComplexType.getName().equals(q.getLocalPart())) {
+ return nxtComplexType;
+ }
+ }
+ // look in simple types
+ TopLevelSimpleType[] tlSimpleTypes = schema.getSimpleTypeArray();
+ for (int i = 0; i < tlSimpleTypes.length; i++) {
+ TopLevelSimpleType nxtSimpleType = tlSimpleTypes[i];
+ if (nxtSimpleType.getName().equals(q.getLocalPart())) {
+ return nxtSimpleType;
+ }
+ }
+ // look in element types
+ TopLevelElement[] tlElementTypes = schema.getElementArray();
+ for (int i = 0; i < tlElementTypes.length; i++) {
+ TopLevelElement nxtElement = tlElementTypes[i];
+ if (nxtElement.getName().equals(q.getLocalPart())) {
+ return nxtElement;
+ }
+ }
+ return null; // it is not in comlex or simple types!
}
}