KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > encoding > ser > xbeans > XmlBeanSerializer


1 /*
2  * XmlBeanSerializer.java
3  *
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Original author: Jonathan Colwell
20  */

21
22 package org.apache.axis.encoding.ser.xbeans;
23
24 import org.apache.axis.Constants;
25 import org.apache.axis.encoding.SerializationContext;
26 import org.apache.axis.encoding.Serializer;
27 import org.apache.axis.wsdl.fromJava.Types;
28 import org.apache.xmlbeans.SchemaType;
29 import org.apache.xmlbeans.XmlBeans;
30 import org.apache.xmlbeans.XmlCursor;
31 import org.apache.xmlbeans.XmlObject;
32 import org.apache.xmlbeans.XmlOptions;
33 import org.w3.x2001.xmlSchema.SchemaDocument;
34 import org.w3.x2001.xmlSchema.TopLevelComplexType;
35 import org.w3.x2001.xmlSchema.TopLevelElement;
36 import org.w3c.dom.Document JavaDoc;
37 import org.w3c.dom.Element JavaDoc;
38 import org.w3c.dom.Node JavaDoc;
39 import org.xml.sax.Attributes JavaDoc;
40 import org.xmlsoap.schemas.wsdl.DefinitionsDocument;
41 import org.xmlsoap.schemas.wsdl.TDefinitions;
42 import org.xmlsoap.schemas.wsdl.TTypes;
43
44 import javax.xml.namespace.QName JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.InputStream JavaDoc;
47 import java.util.HashSet JavaDoc;
48 import java.util.Set JavaDoc;
49
50 /**
51  * Class XmlBeanSerializer
52  * @author Jonathan Colwell
53  */

54 public class XmlBeanSerializer implements Serializer {
55
56     /**
57      * Serialize an element named name, with the indicated attributes
58      * and value.
59      *
60      * @param name is the element name
61      * @param attributes are the attributes...serialize is free to add more.
62      * @param value is the value
63      * @param context is the SerializationContext
64      */

65     public void serialize(QName JavaDoc name, Attributes JavaDoc attributes,
66                           Object JavaDoc value, SerializationContext context)
67             throws IOException JavaDoc {
68         if (!(value instanceof XmlObject)) {
69             throw new IOException JavaDoc(((value != null) ?
70                     value.getClass().getName()
71                     : "null")
72                     + " is not an "
73                     + XmlObject.class.getName());
74         } else {
75             context.setWriteXMLType(null);
76             context.startElement(name, attributes);
77             XmlCursor xCur = ((XmlObject) value).newCursor();
78             if (xCur.toFirstContentToken() == XmlCursor.TokenType.START) {
79                 do {
80                     Node JavaDoc n = xCur.getDomNode();
81                     if (n.getNodeType() == Node.ELEMENT_NODE) {
82                         context.writeDOMElement((Element) n);
83                     }
84                 } while (xCur.toNextSibling());
85             }
86             context.endElement();
87         }
88     }
89
90     public String JavaDoc getMechanismType() {
91         return Constants.AXIS_SAX;
92     }
93
94     /**
95      * Return XML schema for the specified type, suitable for insertion into
96      * the <types> element of a WSDL document, or underneath an
97      * <element> or <attribute> declaration.
98      *
99      * @param javaType the Java Class we're writing out schema for
100      * @param types the Java2WSDL Types object which holds the context
101      * for the WSDL being generated.
102      * @return a type element containing a schema simpleType/complexType
103      * @see org.apache.axis.wsdl.fromJava.Types
104      */

105     public Element writeSchema(Class JavaDoc javaType, Types types) throws Exception JavaDoc {
106         if (XmlObject.class.isAssignableFrom(javaType)) {
107             SchemaType docType = XmlBeans.typeForClass(javaType);
108
109             /*
110              * NOTE jcolwell@bea.com 2004-Oct-18 --
111              * This is a hack to handle node adoption.
112              * I don't like it but I need to avoid a
113              * org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR
114              * NOTE jcolwell@bea.com 2004-Oct-21 --
115              * since I already use the Document I'll use it to check
116              * if a schema for the namspace is already in place.
117              */

118             
119             Document doc = types.createElement("deleteme")
120                     .getOwnerDocument();
121             XmlOptions opts = new XmlOptions()
122                     .setLoadReplaceDocumentElement(null);
123             Element root = doc.getDocumentElement();
124             String JavaDoc schemaSrc = docType.getSourceName();
125             InputStream JavaDoc stream = docType.getTypeSystem()
126                     .getSourceAsStream(schemaSrc);
127             SchemaDocument.Schema schema = null;
128             if (schemaSrc.endsWith(".wsdl") || schemaSrc.endsWith(".WSDL")) {
129                 DefinitionsDocument defDoc =
130                         DefinitionsDocument.Factory.parse(stream);
131                 TTypes tt = defDoc.getDefinitions().getTypesArray(0);
132                 XmlObject[] kids = selectChildren
133                         (tt, SchemaDocument.Schema.class);
134                 SchemaDocument.Schema[] schemas =
135                         new SchemaDocument.Schema[kids.length];
136
137                 // NOTE jcolwell@bea.com 2005-Jan-10 -- this is the part that the
138
// fancy generics saves me from having to do after each call to
139
// selectChildren(XmlObject, Class)
140

141                 for (int j = 0; j < kids.length; j++) {
142                     schemas[j] = (SchemaDocument.Schema) kids[j];
143                 }
144                 if (schemas.length == 1) {
145                     schema = schemas[0];
146                 } else {
147                     String JavaDoc stNS = docType.getName().getNamespaceURI();
148                     for (int j = 0; j < schemas.length; j++) {
149                         if (stNS.equals(schemas[j].getTargetNamespace())) {
150                             schema = schemas[j];
151                             break;
152                         }
153                     }
154                 }
155             } else {
156                 SchemaDocument schemaDoc = SchemaDocument.Factory.parse(stream);
157                 schema = schemaDoc.getSchema();
158             }
159
160             /*
161              FIXME jcolwell@bea.com 2004-Oct-21 -- it would be great if
162              the Types.loadInputSchema took an input source instead of a
163              String so I could directly pass in the input stream instead of
164              providing the schema elements individually.
165             */

166             DefinitionsDocument defDoc = DefinitionsDocument.Factory
167                     .newInstance();
168             TDefinitions definitions = defDoc.addNewDefinitions();
169             definitions.addNewService();
170             Node JavaDoc defEl = definitions.newDomNode(new XmlOptions()
171                     .setSaveOuter());
172             Document dDoc = defEl.getOwnerDocument();
173             if (null == dDoc.getDocumentElement()) {
174                 dDoc.appendChild(defEl);
175             }
176             Set JavaDoc existingNameSpaces = new HashSet JavaDoc();
177             if (dDoc != null) {
178                 types.insertTypesFragment(dDoc);
179                 Element e = (Element) dDoc.getFirstChild().getFirstChild()
180                         .getFirstChild();
181                 if (e != null) {
182                     String JavaDoc tn = e.getAttribute("targetNamespace");
183                     existingNameSpaces.add(tn);
184                     while (null != (e = (Element) e.getNextSibling())) {
185                         tn = e.getAttribute("targetNamespace");
186                         existingNameSpaces.add(tn);
187                     }
188                 }
189             } else {
190                 throw new Exception JavaDoc("null document");
191             }
192             if (schema != null) {
193                 String JavaDoc targetNamespace = schema.getTargetNamespace();
194                 if (targetNamespace != null) {
195                     if (!existingNameSpaces.contains(targetNamespace)) {
196                         TopLevelComplexType[] schemaTypes = schema
197                                 .getComplexTypeArray();
198                         for (int j = 0; j < schemaTypes.length; j++) {
199                             types.writeSchemaElement(targetNamespace,
200                                     (Element) doc
201                                     .importNode(schemaTypes[j].newDomNode()
202                                     .getFirstChild(),
203                                             true));
204                         }
205                         TopLevelElement[] elements = schema
206                                 .getElementArray();
207                         for (int j = 0; j < elements.length; j++) {
208                             types.writeSchemaElement(targetNamespace,
209                                     (Element) doc
210                                     .importNode(elements[j].newDomNode()
211                                     .getFirstChild(),
212                                             true));
213                         }
214                     }
215                     return null;
216                 }
217             }
218             throw new Exception JavaDoc(javaType.getName()
219                     + "did not specify a target namespace");
220         } else {
221             throw new Exception JavaDoc(javaType.getName()
222                     + " must be a subclass of XmlObject");
223         }
224     }
225
226     // NOTE jcolwell@bea.com 2004-Nov-15 --
227
// once the WSDLProcessor is changed to an interface, remove this function
228
// and use the one in the upcoming XmlBeanWSDLProcessor.
229
private static XmlObject[] selectChildren(XmlObject parent,
230                                               Class JavaDoc childClass)
231             throws IllegalAccessException JavaDoc, NoSuchFieldException JavaDoc {
232         // retrieve the SchemaType from the static type field
233
SchemaType st = (SchemaType) childClass.getField("type").get(null);
234         return parent.selectChildren(st.getDocumentElementName());
235     }
236 }
237
Popular Tags