001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.aegis.type.java5;
019:
020: import java.beans.PropertyDescriptor;
021: import java.lang.annotation.Annotation;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.ParameterizedType;
024: import java.lang.reflect.WildcardType;
025: import java.util.Collection;
026:
027: import javax.xml.namespace.QName;
028:
029: import org.apache.cxf.aegis.type.AbstractTypeCreator;
030: import org.apache.cxf.aegis.type.Type;
031: import org.apache.cxf.aegis.type.basic.BeanType;
032: import org.apache.cxf.aegis.util.NamespaceHelper;
033: import org.apache.cxf.aegis.util.ServiceUtils;
034:
035: public class Java5TypeCreator extends AbstractTypeCreator {
036:
037: @Override
038: public TypeClassInfo createClassInfo(Method m, int index) {
039: if (index >= 0) {
040: TypeClassInfo info;
041: java.lang.reflect.Type genericType = m
042: .getGenericParameterTypes()[index];
043: if (genericType instanceof Class) {
044: info = nextCreator.createClassInfo(m, index);
045: } else {
046: info = new TypeClassInfo();
047: info.setGenericType(genericType);
048: }
049: info.setTypeClass(m.getParameterTypes()[index]);
050:
051: XmlParamType xmlParam = getXmlParamAnnotation(m, index);
052: if (xmlParam != null) {
053: if (xmlParam.type() != Type.class) {
054: info.setType(xmlParam.type());
055: }
056:
057: info.setTypeName(createQName(
058: m.getParameterTypes()[index], xmlParam.name(),
059: xmlParam.namespace()));
060: }
061:
062: return info;
063: } else {
064: java.lang.reflect.Type genericReturnType = m
065: .getGenericReturnType();
066: TypeClassInfo info;
067: if (genericReturnType instanceof Class) {
068: info = nextCreator.createClassInfo(m, index);
069: } else {
070: info = new TypeClassInfo();
071: info.setGenericType(genericReturnType);
072: }
073: info.setTypeClass(m.getReturnType());
074: if (m.getParameterAnnotations() != null
075: && m.getAnnotations().length > 0) {
076: info.setAnnotations(m.getAnnotations());
077: }
078:
079: XmlReturnType xmlParam = m
080: .getAnnotation(XmlReturnType.class);
081: if (xmlParam != null) {
082: if (xmlParam.type() != Type.class) {
083: info.setType(xmlParam.type());
084: }
085:
086: info.setTypeName(createQName(m.getReturnType(),
087: xmlParam.name(), xmlParam.namespace()));
088: }
089:
090: return info;
091: }
092: }
093:
094: public XmlParamType getXmlParamAnnotation(Method m, int index) {
095: if (m.getParameterAnnotations() == null
096: || m.getParameterAnnotations().length <= index
097: || m.getParameterAnnotations()[index] == null) {
098: return null;
099: }
100:
101: Annotation[] annotations = m.getParameterAnnotations()[index];
102:
103: for (int i = 0; i < annotations.length; i++) {
104: Annotation annotation = annotations[i];
105: if (annotation.annotationType().equals(XmlParamType.class)) {
106: return (XmlParamType) annotations[i];
107: }
108: }
109:
110: return null;
111: }
112:
113: @Override
114: public TypeClassInfo createClassInfo(PropertyDescriptor pd) {
115: TypeClassInfo info = createBasicClassInfo(pd.getPropertyType());
116: info.setGenericType(pd.getReadMethod().getGenericReturnType());
117: info.setAnnotations(pd.getReadMethod().getAnnotations());
118:
119: XmlElement el = pd.getReadMethod().getAnnotation(
120: XmlElement.class);
121: if (el != null && !el.type().equals(Type.class)) {
122: info.setType(el.type());
123: }
124:
125: XmlAttribute att = pd.getReadMethod().getAnnotation(
126: XmlAttribute.class);
127: if (att != null && !att.type().equals(Type.class)) {
128: info.setType(att.type());
129: }
130:
131: return info;
132: }
133:
134: @Override
135: public Type createCollectionType(TypeClassInfo info) {
136: Object genericType = info.getGenericType();
137: Class paramClass = getComponentType(genericType, 0);
138:
139: if (paramClass != null) {
140: return createCollectionTypeFromGeneric(info);
141: } else {
142: return nextCreator.createCollectionType(info);
143: }
144: }
145:
146: protected Type getOrCreateGenericType(TypeClassInfo info) {
147: return getOrCreateParameterizedType(info.getGenericType(), 0);
148: }
149:
150: protected Type getOrCreateMapKeyType(TypeClassInfo info) {
151: return getOrCreateParameterizedType(info.getGenericType(), 0);
152: }
153:
154: protected Type getOrCreateMapValueType(TypeClassInfo info) {
155: return getOrCreateParameterizedType(info.getGenericType(), 1);
156: }
157:
158: protected Type getOrCreateParameterizedType(Object generic,
159: int index) {
160: Class clazz = getComponentType(generic, index);
161:
162: if (clazz == null) {
163: return createObjectType();
164: }
165:
166: if (!Collection.class.isAssignableFrom(clazz)) {
167: return getTopCreator().createType(clazz);
168: }
169:
170: Object component = getGenericComponent(generic, index);
171:
172: TypeClassInfo info = createBasicClassInfo(clazz);
173: info.setDescription(clazz.toString());
174: info.setGenericType(component);
175:
176: Type type = createTypeForClass(info);
177:
178: return type;
179: }
180:
181: private Object getGenericComponent(Object genericType, int index) {
182: if (genericType instanceof ParameterizedType) {
183: ParameterizedType type = (ParameterizedType) genericType;
184:
185: if (type.getActualTypeArguments()[index] instanceof WildcardType) {
186: WildcardType wildcardType = (WildcardType) type
187: .getActualTypeArguments()[index];
188:
189: return wildcardType;
190: } else if (type.getActualTypeArguments()[index] instanceof ParameterizedType) {
191: ParameterizedType ptype = (ParameterizedType) type
192: .getActualTypeArguments()[index];
193:
194: return ptype;
195: }
196: }
197:
198: return null;
199: }
200:
201: protected Class getComponentType(Object genericType, int index) {
202: Class paramClass = null;
203:
204: if (genericType instanceof ParameterizedType) {
205: ParameterizedType type = (ParameterizedType) genericType;
206:
207: if (type.getActualTypeArguments()[index] instanceof Class) {
208: paramClass = (Class) type.getActualTypeArguments()[index];
209: } else if (type.getActualTypeArguments()[index] instanceof WildcardType) {
210: WildcardType wildcardType = (WildcardType) type
211: .getActualTypeArguments()[index];
212:
213: if (wildcardType.getUpperBounds()[index] instanceof Class) {
214: paramClass = (Class) wildcardType.getUpperBounds()[index];
215: }
216: } else if (type.getActualTypeArguments()[index] instanceof ParameterizedType) {
217: ParameterizedType ptype = (ParameterizedType) type
218: .getActualTypeArguments()[index];
219: paramClass = (Class) ptype.getRawType();
220: }
221: }
222: return paramClass;
223: }
224:
225: @SuppressWarnings("unchecked")
226: @Override
227: public Type createDefaultType(TypeClassInfo info) {
228: QName typeName = info.getTypeName();
229: if (typeName == null) {
230: typeName = createQName(info.getTypeClass());
231: }
232:
233: AnnotatedTypeInfo typeInfo = new AnnotatedTypeInfo(
234: getTypeMapping(), info.getTypeClass(), typeName
235: .getNamespaceURI());
236: XmlType xtype = (XmlType) info.getTypeClass().getAnnotation(
237: XmlType.class);
238: if (xtype != null) {
239: typeInfo.setExtensibleElements(xtype.extensibleElements());
240: typeInfo.setExtensibleAttributes(xtype
241: .extensibleAttributes());
242: } else {
243: typeInfo.setExtensibleElements(getConfiguration()
244: .isDefaultExtensibleElements());
245: typeInfo.setExtensibleAttributes(getConfiguration()
246: .isDefaultExtensibleAttributes());
247: }
248:
249: typeInfo.setDefaultMinOccurs(getConfiguration()
250: .getDefaultMinOccurs());
251: typeInfo.setDefaultNillable(getConfiguration()
252: .isDefaultNillable());
253:
254: BeanType type = new BeanType(typeInfo);
255: type.setTypeMapping(getTypeMapping());
256: type.setSchemaType(typeName);
257:
258: return type;
259: }
260:
261: @Override
262: public Type createEnumType(TypeClassInfo info) {
263: EnumType type = new EnumType();
264:
265: type.setSchemaType(createQName(info.getTypeClass()));
266: type.setTypeClass(info.getTypeClass());
267: type.setTypeMapping(getTypeMapping());
268:
269: return type;
270: }
271:
272: @SuppressWarnings("unchecked")
273: @Override
274: public QName createQName(Class typeClass) {
275: String name = null;
276: String ns = null;
277:
278: XmlType xtype = (XmlType) typeClass
279: .getAnnotation(XmlType.class);
280: if (xtype != null) {
281: name = xtype.name();
282: ns = xtype.namespace();
283: }
284:
285: return createQName(typeClass, name, ns);
286: }
287:
288: private QName createQName(Class typeClass, String name, String ns) {
289: String clsName = typeClass.getName();
290: if (name == null || name.length() == 0) {
291: name = ServiceUtils.makeServiceNameFromClassName(typeClass);
292: }
293:
294: if (ns == null || ns.length() == 0) {
295: ns = NamespaceHelper.makeNamespaceFromClassName(clsName,
296: "http");
297: }
298:
299: return new QName(ns, name);
300: }
301:
302: @Override
303: protected boolean isEnum(Class javaType) {
304: return javaType.isEnum();
305: }
306: }
|