1 package org.codehaus.ivory.serialize;
2
3 import java.lang.reflect.Modifier;
4 import java.util.List;
5
6 import org.apache.axis.wsdl.fromJava.Types;
7 import javax.xml.namespace.QName;
8
9 import org.apache.axis.description.FieldDesc;
10 import org.apache.axis.description.TypeDesc;
11 import org.apache.axis.encoding.ser.BeanSerializer;
12 import org.apache.axis.utils.BeanPropertyDescriptor;
13 import org.w3c.dom.Element;
14
15 /***
16 * A BeanSerializer with metadata support.
17 *
18 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
19 * @since May 21, 2003
20 */
21 public class MetadataSerializer extends BeanSerializer
22 {
23 // Construct BeanSerializer for the indicated class/qname
24 public MetadataSerializer(Class javaType, QName xmlType)
25 {
26 this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType));
27 }
28
29 // Construct BeanSerializer for the indicated class/qname
30 public MetadataSerializer(Class javaType, QName xmlType, TypeDesc typeDesc)
31 {
32 super(javaType, xmlType, typeDesc, null);
33
34 if (typeDesc != null)
35 {
36 propertyDescriptor = typeDesc.getPropertyDescriptors();
37 }
38 else
39 {
40 propertyDescriptor = MetaBeanUtils.getPd(javaType, null);
41 }
42 }
43
44 // Construct BeanSerializer for the indicated class/qname/propertyDesc
45 public MetadataSerializer(
46 Class javaType,
47 QName xmlType,
48 TypeDesc typeDesc,
49 BeanPropertyDescriptor[] propertyDescriptor)
50 {
51 super(javaType, xmlType, typeDesc, propertyDescriptor);
52 }
53
54 /***
55 * Return XML schema for the specified type, suitable for insertion into
56 * the <types> element of a WSDL document, or underneath an
57 * <element> or <attribute> declaration.
58 *
59 * @param javaType the Java Class we're writing out schema for
60 * @param types the Java2WSDL Types object which holds the context
61 * for the WSDL being generated.
62 * @return a type element containing a schema simpleType/complexType
63 * @see org.apache.axis.wsdl.fromJava.Types
64 */
65 public Element writeSchema(Class javaType, Types types) throws Exception {
66
67 // ComplexType representation of bean class
68 Element complexType = types.createElement("complexType");
69
70 // See if there is a super class, stop if we hit a stop class
71 Element e = null;
72 Class superClass = javaType.getSuperclass();
73 BeanPropertyDescriptor[] superPd = null;
74 List stopClasses = types.getStopClasses();
75 if (superClass != null &&
76 superClass != java.lang.Object.class &&
77 superClass != java.lang.Exception.class &&
78 superClass != java.lang.Throwable.class &&
79 superClass != java.rmi.RemoteException.class &&
80 superClass != org.apache.axis.AxisFault.class &&
81 (stopClasses == null ||
82 !(stopClasses.contains(superClass.getName()))) ) {
83 // Write out the super class
84 String base = types.writeType(superClass);
85 Element complexContent = types.createElement("complexContent");
86 complexType.appendChild(complexContent);
87 Element extension = types.createElement("extension");
88 complexContent.appendChild(extension);
89 extension.setAttribute("base", base);
90 e = extension;
91 // Get the property descriptors for the super class
92 TypeDesc superTypeDesc = TypeDesc.getTypeDescForClass(superClass);
93 if (superTypeDesc != null) {
94 superPd = superTypeDesc.getPropertyDescriptors();
95 } else {
96 superPd = MetaBeanUtils.getPd(superClass, null);
97 }
98 } else {
99 e = complexType;
100 }
101
102 // Add fields under sequence element.
103 // Note: In most situations it would be okay
104 // to put the fields under an all element.
105 // However it is illegal schema to put an
106 // element with minOccurs=0 or maxOccurs>1 underneath
107 // an all element. This is the reason why a sequence
108 // element is used.
109 Element all = types.createElement("sequence");
110 e.appendChild(all);
111
112 if (Modifier.isAbstract(javaType.getModifiers())) {
113 complexType.setAttribute("abstract", "true");
114 }
115
116 // Serialize each property
117 for (int i=0; i<propertyDescriptor.length; i++) {
118 String propName = propertyDescriptor[i].getName();
119
120 // Don't serializer properties named class
121 boolean writeProperty = true;
122 if (propName.equals("class")) {
123 writeProperty = false;
124 }
125
126 // Don't serialize the property if it is present
127 // in the super class property list
128 if (superPd != null && writeProperty) {
129 for (int j=0; j<superPd.length && writeProperty; j++) {
130 if (propName.equals(superPd[j].getName())) {
131 writeProperty = false;
132 }
133 }
134 }
135 if (!writeProperty) {
136 continue;
137 }
138
139 Class fieldType = propertyDescriptor[i].getType();
140
141 // If we have type metadata, check to see what we're doing
142 // with this field. If it's an attribute, skip it. If it's
143 // an element, use whatever qname is in there. If we can't
144 // find any of this info, use the default.
145
146 if (typeDesc != null) {
147 FieldDesc field = typeDesc.getFieldByName(propName);
148
149 if (field != null) {
150 QName qname = field.getXmlName();
151 QName fieldXmlType = field.getXmlType();
152 boolean isAnonymous = fieldXmlType.getLocalPart().startsWith(">");
153
154 if (qname != null) {
155 // FIXME!
156 // Check to see if this is in the right namespace -
157 // if it's not, we need to use an <element ref="">
158 // to represent it!!!
159
160 // Use the default...
161 propName = qname.getLocalPart();
162 }
163 if (!field.isElement()) {
164 writeAttribute(types,
165 propName,
166 fieldType,
167 field.getXmlType(),
168 complexType);
169 } else {
170 writeField(types,
171 propName,
172 fieldType,
173 propertyDescriptor[i].isIndexed(),
174 field.isMinOccursZero(),
175 all, isAnonymous);
176 }
177 } else {
178 writeField(types,
179 propName,
180 fieldType,
181 propertyDescriptor[i].isIndexed(), false, all, false);
182 }
183 } else {
184 writeField(types,
185 propName,
186 fieldType,
187 propertyDescriptor[i].isIndexed(), false, all, false);
188 }
189 }
190
191 // done
192 return complexType;
193 }
194 }
This page was automatically generated by Maven