View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.geronimo.ews.jaxrpcmapping;
17  
18  import org.apache.axis.utils.Messages;
19  import org.apache.axis.wsdl.symbolTable.DefinedType;
20  import org.apache.axis.wsdl.symbolTable.ElementDecl;
21  import org.apache.axis.wsdl.symbolTable.SchemaUtils;
22  import org.apache.axis.wsdl.symbolTable.TypeEntry;
23  import org.apache.axis.wsdl.toJava.Utils;
24  
25  import javax.xml.namespace.QName;
26  import java.io.IOException;
27  import java.io.PrintWriter;
28  import java.util.Vector;
29  
30  /***
31   * This is Wsdl2java's Helper Type Writer.  It writes the <typeName>.java file.
32   *
33   * @author Ias (iasandcb@tmax.co.kr)
34   * @deprecated no more used by J2eeGeneratorFactory
35   */
36  public class J2eeBeanHelperWriter extends J2eeClassWriter {
37      protected TypeEntry type;
38      protected Vector elements;
39      protected Vector attributes;
40      protected TypeEntry extendType;
41      protected PrintWriter wrapperPW = null;
42      protected Vector elementMetaData = null;
43      protected boolean canSearchParents;
44  
45      /***
46       * Constructor.
47       *
48       * @param emitter
49       * @param type       The type representing this class
50       * @param elements   Vector containing the Type and name of each property
51       * @param extendType The type representing the extended class (or null)
52       * @param attributes Vector containing the attribute types and names
53       */
54      protected J2eeBeanHelperWriter(J2eeEmitter emitter,
55                                     TypeEntry type,
56                                     Vector elements,
57                                     TypeEntry extendType,
58                                     Vector attributes) {
59          super(emitter, type.getName() + "_Helper", "helper");
60          this.type = type;
61          this.elements = elements;
62          this.attributes = attributes;
63          this.extendType = extendType;
64          // is this a complex type that is derived from other types
65          // by restriction?  if so, set the policy of the generated
66          // TypeDescription to ignore metadata associated with
67          // superclasses, as restricted types are required to
68          // define their entire content model.  Hence the type
69          // description associated with the current type provides
70          // all of the types (and only those types) allowed in
71          // the restricted derivation.
72          if (null != extendType
73                  && null != SchemaUtils.getComplexElementRestrictionBase(type.getNode(),
74                          emitter.getSymbolTable())) {
75              this.canSearchParents = false;
76          } else {
77              this.canSearchParents = true;
78          }
79      } // ctor
80  
81      /***
82       * The bean helper class may be its own class, or it may be
83       * embedded within the bean class.  If it's embedded within the
84       * bean class, the JavaBeanWriter will set JavaBeanHelperWriter's
85       * PrintWriter to its own.
86       */
87      protected void setPrintWriter(PrintWriter pw) {
88          this.wrapperPW = pw;
89      } // setPrintWriter
90  
91      /***
92       * The default behaviour (of super.getPrintWriter) is, given the
93       * file name, create a PrintWriter for it.  If the bean helper
94       * that this class is generating is embedded within a bean, then
95       * the PrintWriter returned by this method is the JavaBeanWriter's
96       * PrintWriter.  Otherwise super.getPrintWriter is called.
97       */
98      protected PrintWriter getPrintWriter(String filename) throws IOException {
99          return wrapperPW == null ? super.getPrintWriter(filename) : wrapperPW;
100     } // getPrintWriter
101 
102     /***
103      * Only register the filename if the bean helper is not wrapped
104      * within a bean.
105      */
106     protected void registerFile(String file) {
107         if (wrapperPW == null)
108             super.registerFile(file);
109     } // registerFile
110 
111     /***
112      * Return the string:  "Generating <file>".
113      * only if we are going to generate a new file.
114      */
115     protected String verboseMessage(String file) {
116         if (wrapperPW == null) {
117             return super.verboseMessage(file);
118         } else {
119             return null;
120         }
121     } // verboseMessage
122 
123     /***
124      * Only write the file header if the bean helper is not wrapped
125      * within a bean.
126      */
127     protected void writeFileHeader(PrintWriter pw) throws IOException {
128         if (wrapperPW == null) {
129             super.writeFileHeader(pw);
130         }
131     } // writeFileHeader
132 
133     /***
134      * Generate the file body for the bean helper.
135      */
136     protected void writeFileBody(PrintWriter pw) throws IOException {
137         writeMetaData(pw);
138         writeSerializer(pw);
139         writeDeserializer(pw);
140     } // writeFileBody
141 
142     /***
143      * Only write the file footer if the bean helper is not
144      * wrapped within a bean.
145      */
146     protected void writeFileFooter(PrintWriter pw) throws IOException {
147         if (wrapperPW == null) {
148             super.writeFileFooter(pw);
149         }
150     } // writeFileFooter
151 
152     /***
153      * Only close the PrintWriter if the PrintWriter belongs to
154      * this class.  If the bean helper is embedded within a bean
155      * then the PrintWriter belongs to JavaBeanWriter and THAT
156      * class is responsible for closing the PrintWriter.
157      */
158     protected void closePrintWriter(PrintWriter pw) {
159         // If the output of this writer is wrapped within
160         // another writer (JavaBeanWriter), then THAT
161         // writer will close the PrintWriter, not this one.
162         if (wrapperPW == null) {
163             pw.close();
164         }
165     } // closePrintWriter
166 
167     /***
168      * write MetaData code
169      */
170     protected void writeMetaData(PrintWriter pw) throws IOException {
171         // Collect elementMetaData
172         if (elements != null) {
173             for (int i = 0; i < elements.size(); i++) {
174                 ElementDecl elem = (ElementDecl) elements.get(i);
175                 // String elemName = elem.getName().getLocalPart();
176                 // String javaName = Utils.xmlNameToJava(elemName);
177 
178                 // Changed the code to write meta data
179                 // for all of the elements in order to
180                 // support sequences. Defect 9060
181 
182 
183                 // Meta data is needed if the default serializer
184                 // action cannot map the javaName back to the
185                 // element's qname.  This occurs if:
186                 //  - the javaName and element name local part are different.
187                 //  - the javaName starts with uppercase char (this is a wierd
188                 //    case and we have several problems with the mapping rules.
189                 //    Seems best to gen meta data in this case.)
190                 //  - the element name is qualified (has a namespace uri)
191                 // its also needed if:
192                 //  - the element has the minoccurs flag set
193                 //if (!javaName.equals(elemName) ||
194                 //    Character.isUpperCase(javaName.charAt(0)) ||
195                 //!elem.getName().getNamespaceURI().equals("") ||
196                 //elem.getMinOccursIs0()) {
197                 // If we did some mangling, make sure we'll write out the XML
198                 // the correct way.
199                 if (elementMetaData == null)
200                     elementMetaData = new Vector();
201                 elementMetaData.add(elem);
202                 //}
203             }
204         }
205         pw.println("    // " + Messages.getMessage("typeMeta"));
206         pw.println("    private static org.apache.axis.description.TypeDesc typeDesc =");
207         pw.println("        new org.apache.axis.description.TypeDesc("
208                 + Utils.getJavaLocalName(jaxRpcMapper.getJavaType(type.getQName()))
209                 + ".class, "
210                 + (this.canSearchParents ? "true" : "false")
211                 + ");");
212         pw.println();
213         pw.println("    static {");
214         pw.println("        typeDesc.setXmlType(" + Utils.getNewQName(type.getQName()) + ");");
215 
216         // Add attribute and element field descriptors
217         if (attributes != null || elementMetaData != null) {
218             if (attributes != null) {
219                 boolean wroteAttrDecl = false;
220                 for (int i = 0; i < attributes.size(); i += 2) {
221                     TypeEntry te = (TypeEntry) attributes.get(i);
222                     QName attrName = (QName) attributes.get(i + 1);
223                     String attrLocalName = attrName.getLocalPart();
224                     String fieldName = Utils.xmlNameToJava(attrLocalName);
225                     fieldName = getAsFieldName(fieldName);
226                     QName attrXmlType = te.getQName();
227                     pw.print("        ");
228                     if (!wroteAttrDecl) {
229                         pw.print("org.apache.axis.description.AttributeDesc ");
230                         wroteAttrDecl = true;
231                     }
232                     pw.println("attrField = new org.apache.axis.description.AttributeDesc();");
233                     pw.println("        attrField.setFieldName(\"" + fieldName + "\");");
234                     pw.println("        attrField.setXmlName(" + Utils.getNewQName(attrName) + ");");
235                     if (attrXmlType != null) {
236                         pw.println("        attrField.setXmlType(" + Utils.getNewQName(attrXmlType) + ");");
237                     }
238                     pw.println("        typeDesc.addFieldDesc(attrField);");
239                 }
240             }
241             if (elementMetaData != null) {
242                 boolean wroteElemDecl = false;
243                 for (int i = 0; i < elementMetaData.size(); i++) {
244                     ElementDecl elem = (ElementDecl) elementMetaData.elementAt(i);
245                     if (elem.getAnyElement()) {
246                         continue;
247                     }
248                     String fieldName = getAsFieldName(elem.getName());
249                     QName xmlName = elem.getQName();
250                     
251                     // Some special handling for arrays.
252                     TypeEntry elemType = elem.getType();
253                     QName xmlType = null;
254                     if (elemType.getDimensions().length() > 1 &&
255                             (elemType.getClass() == DefinedType.class)) {
256                         // If we have a DefinedType with dimensions, it must
257                         // be a SOAP array derived type.  In this case, use
258                         // the refType's QName for the metadata.
259                         xmlType = elemType.getRefType().getQName();
260                     } else {
261                         // Otherwise, use the type at the end of the ref
262                         // chain.
263                         while (elemType.getRefType() != null) {
264                             elemType = elemType.getRefType();
265                         }
266                         xmlType = elemType.getQName();
267                     }
268                     pw.print("        ");
269                     if (!wroteElemDecl) {
270                         pw.print("org.apache.axis.description.ElementDesc ");
271                         wroteElemDecl = true;
272                     }
273                     pw.println("elemField = new org.apache.axis.description.ElementDesc();");
274                     pw.println("        elemField.setFieldName(\"" + fieldName + "\");");
275                     pw.println("        elemField.setXmlName(" + Utils.getNewQName(xmlName) + ");");
276                     if (xmlType != null) {
277                         pw.println("        elemField.setXmlType(" + Utils.getNewQName(xmlType) + ");");
278                     }
279                     if (elem.getMinOccursIs0()) {
280                         pw.println("        elemField.setMinOccurs(0);");
281                     }
282                     pw.println("        typeDesc.addFieldDesc(elemField);");
283                 }
284             }
285         }
286         pw.println("    }");
287         pw.println();
288         pw.println("    /**");
289         pw.println("     * " + Messages.getMessage("returnTypeMeta"));
290         pw.println("     */");
291         pw.println("    public static org.apache.axis.description.TypeDesc getTypeDesc() {");
292         pw.println("        return typeDesc;");
293         pw.println("    }");
294         pw.println();
295     }
296 
297     /***
298      * Utility function to get the bean property name (as will be returned
299      * by the Introspector) for a given field name.  This just means
300      * we capitalize the first character if the second character is
301      * capitalized.  Example: a field named "fOO" will turn into
302      * getter/setter methods "getFOO()/setFOO()".  So when the Introspector
303      * looks at that bean, the property name will be "FOO", not "fOO" due
304      * to the rules in the JavaBeans spec.  So this makes sure the
305      * metadata will match.
306      */
307     private String getAsFieldName(String fieldName) {
308         // If there's a second character, and it is uppercase, then the
309         // bean property name will have a capitalized first character
310         // (because setURL() maps to a property named "URL", not "uRL")
311         if (fieldName.length() > 1 &&
312                 Character.isUpperCase(fieldName.charAt(1))) {
313             return Utils.capitalizeFirstChar(fieldName);
314         }
315         return fieldName;
316     }
317 
318     /***
319      * write Serializer getter code and pass in meta data to avoid
320      * undo introspection.
321      */
322     protected void writeSerializer(PrintWriter pw) throws IOException {
323         String typeDesc = "typeDesc";
324         String ser = " org.apache.axis.encoding.ser.BeanSerializer";
325         if (type.isSimpleType()) {
326             ser = " org.apache.axis.encoding.ser.SimpleSerializer";
327         }
328         pw.println("    /**");
329         pw.println("     * Get Custom Serializer");
330         pw.println("     */");
331         pw.println("    public static org.apache.axis.encoding.Serializer getSerializer(");
332         pw.println("           java.lang.String mechType, ");
333         pw.println("           java.lang.Class _javaType,  ");
334         pw.println("           javax.xml.namespace.QName _xmlType) {");
335         pw.println("        return ");
336         pw.println("          new " + ser + "(");
337         pw.println("            _javaType, _xmlType, " + typeDesc + ");");
338         pw.println("    }");
339         pw.println();
340     }
341 
342     /***
343      * write Deserializer getter code and pass in meta data to avoid
344      * undo introspection.
345      */
346     protected void writeDeserializer(PrintWriter pw) throws IOException {
347         String typeDesc = "typeDesc";
348         String dser = " org.apache.axis.encoding.ser.BeanDeserializer";
349         if (type.isSimpleType()) {
350             dser = " org.apache.axis.encoding.ser.SimpleDeserializer";
351         }
352         pw.println("    /**");
353         pw.println("     * Get Custom Deserializer");
354         pw.println("     */");
355         pw.println("    public static org.apache.axis.encoding.Deserializer getDeserializer(");
356         pw.println("           java.lang.String mechType, ");
357         pw.println("           java.lang.Class _javaType,  ");
358         pw.println("           javax.xml.namespace.QName _xmlType) {");
359         pw.println("        return ");
360         pw.println("          new " + dser + "(");
361         pw.println("            _javaType, _xmlType, " + typeDesc + ");");
362         pw.println("    }");
363         pw.println();
364     }
365 } // class JavaBeanHelperWriter