1 package org.codehaus.ivory.serialize;
2
3 import java.lang.reflect.Modifier;
4 import java.util.List;
5
6 import javax.xml.namespace.QName;
7
8 import org.apache.axis.description.FieldDesc;
9 import org.apache.axis.description.TypeDesc;
10 import org.apache.axis.encoding.ser.BeanSerializer;
11 import org.apache.axis.utils.BeanPropertyDescriptor;
12 import org.apache.axis.wsdl.fromJava.Types;
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
24 public MetadataSerializer(Class javaType, QName xmlType)
25 {
26 this(javaType, xmlType, TypeDesc.getTypeDescForClass(javaType));
27 }
28
29
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
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 /***
66 * Return XML schema for the specified type, suitable for insertion into
67 * the <types> element of a WSDL document, or underneath an
68 * <element> or <attribute> declaration.
69 *
70 * @param javaType the Java Class we're writing out schema for
71 * @param types the Java2WSDL Types object which holds the context
72 * for the WSDL being generated.
73 * @return a type element containing a schema simpleType/complexType
74 * @see org.apache.axis.wsdl.fromJava.Types
75 */
76 public Element writeSchema(Class javaType, Types types) throws Exception {
77
78
79 Element complexType = types.createElement("complexType");
80
81
82 Element e = null;
83 Class superClass = javaType.getSuperclass();
84 BeanPropertyDescriptor[] superPd = null;
85 List stopClasses = types.getStopClasses();
86 if (superClass != null &&
87 superClass != java.lang.Object.class &&
88 superClass != java.lang.Exception.class &&
89 superClass != java.lang.Throwable.class &&
90 superClass != java.rmi.RemoteException.class &&
91 superClass != org.apache.axis.AxisFault.class &&
92 (stopClasses == null ||
93 !(stopClasses.contains(superClass.getName()))) ) {
94
95 String base = types.writeType(superClass);
96 Element complexContent = types.createElement("complexContent");
97 complexType.appendChild(complexContent);
98 Element extension = types.createElement("extension");
99 complexContent.appendChild(extension);
100 extension.setAttribute("base", base);
101 e = extension;
102
103 TypeDesc superTypeDesc = TypeDesc.getTypeDescForClass(superClass);
104 if (superTypeDesc != null) {
105 superPd = superTypeDesc.getPropertyDescriptors();
106 } else {
107 superPd = MetaBeanUtils.getPd(superClass, null);
108 }
109 } else {
110 e = complexType;
111 }
112
113
114
115
116
117
118
119
120 Element all = types.createElement("sequence");
121 e.appendChild(all);
122
123 if (Modifier.isAbstract(javaType.getModifiers())) {
124 complexType.setAttribute("abstract", "true");
125 }
126
127
128 for (int i=0; i<propertyDescriptor.length; i++) {
129 String propName = propertyDescriptor[i].getName();
130
131
132 boolean writeProperty = true;
133 if (propName.equals("class")) {
134 writeProperty = false;
135 }
136
137
138
139 if (superPd != null && writeProperty) {
140 for (int j=0; j<superPd.length && writeProperty; j++) {
141 if (propName.equals(superPd[j].getName())) {
142 writeProperty = false;
143 }
144 }
145 }
146 if (!writeProperty) {
147 continue;
148 }
149
150 Class fieldType = propertyDescriptor[i].getType();
151
152
153
154
155
156
157 if (typeDesc != null) {
158 FieldDesc field = typeDesc.getFieldByName(propName);
159
160 if (field != null) {
161 QName qname = field.getXmlName();
162 QName fieldXmlType = field.getXmlType();
163 boolean isAnonymous = fieldXmlType != null && fieldXmlType.getLocalPart().startsWith(">");
164
165 if (qname != null) {
166
167
168
169
170
171
172 propName = qname.getLocalPart();
173 }
174 if (!field.isElement()) {
175 writeAttribute(types,
176 propName,
177 fieldType,
178 fieldXmlType,
179 complexType);
180 } else {
181 writeField(types,
182 propName,
183 fieldXmlType,
184 fieldType,
185 propertyDescriptor[i].isIndexed(),
186 field.isMinOccursZero(),
187 all, isAnonymous);
188 }
189 } else {
190 writeField(types,
191 propName,
192 null,
193 fieldType,
194 propertyDescriptor[i].isIndexed(), false, all, false);
195 }
196 } else {
197 writeField(types,
198 propName,
199 null,
200 fieldType,
201 propertyDescriptor[i].isIndexed(), false, all, false);
202 }
203 }
204
205
206 return complexType;
207 }
208 }