1 package org.codehaus.xfire.xmlbeans;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Method;
5
6 import javax.xml.namespace.QName;
7
8 import org.apache.xmlbeans.SchemaType;
9 import org.apache.xmlbeans.XmlObject;
10 import org.codehaus.xfire.XFire;
11 import org.codehaus.xfire.XFireRuntimeException;
12 import org.codehaus.xfire.service.object.DefaultObjectService;
13 import org.codehaus.xfire.service.object.ObjectServiceBuilder;
14 import org.codehaus.xfire.service.object.Operation;
15 import org.codehaus.xfire.service.object.Parameter;
16 import org.codehaus.xfire.soap.SoapConstants;
17 import org.codehaus.xfire.type.TypeMappingRegistry;
18
19 /***
20 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
21 */
22 public class XMLBeansServiceBuilder
23 extends ObjectServiceBuilder
24 {
25 public XMLBeansServiceBuilder()
26 {
27 super();
28 }
29
30 public XMLBeansServiceBuilder(XFire xfire)
31 {
32 super(xfire);
33 }
34
35 public XMLBeansServiceBuilder(XFire xfire, TypeMappingRegistry typeMappingRegistry)
36 {
37 super(xfire, typeMappingRegistry);
38 }
39
40 protected void addOperation(DefaultObjectService service, Method method)
41 {
42 final Operation op = new Operation( method );
43
44 service.addOperation(op);
45
46 Class[] paramClasses = method.getParameterTypes();
47
48 boolean isDoc = service.getStyle().equals(SoapConstants.STYLE_DOCUMENT);
49
50 Parameter p = null;
51
52 for ( int j = 0; j < paramClasses.length; j++ )
53 {
54 if ( XmlObject.class.isAssignableFrom(paramClasses[j]) )
55 {
56 SchemaType st = getSchemaType(paramClasses[j]);
57
58 p = new Parameter(st.getDocumentElementName(), paramClasses[j]);
59 service.getTypeMapping().register(paramClasses[j], st.getDocumentElementName(), new XMLBeansType());
60 }
61 else
62 {
63 String paramName = "";
64 if (isDoc)
65 paramName = method.getName();
66
67 paramName = paramName + "in" + j;
68
69 final QName q = new QName(service.getDefaultNamespace(), paramName);
70 p = new Parameter(q, paramClasses[j]);
71 }
72
73 op.addInParameter( p );
74 }
75
76 Parameter outP = null;
77
78 Class outClass = op.getMethod().getReturnType();
79 if (!outClass.isAssignableFrom(void.class))
80 {
81 if ( XmlObject.class.isAssignableFrom(op.getMethod().getReturnType()) )
82 {
83 SchemaType st = getSchemaType(outClass);
84
85 outP = new Parameter(st.getDocumentElementName(), outClass);
86 service.getTypeMapping().register(outClass, st.getDocumentElementName(), new XMLBeansType());
87 }
88 else
89 {
90 String outName = "";
91 if ( isDoc )
92 outName = method.getName();
93
94 final QName q = new QName(service.getDefaultNamespace(), outName + "out");
95 outP = new Parameter(q, method.getReturnType());
96 }
97
98 op.addOutParameter(outP);
99 }
100 }
101
102 /***
103 * Introspect to find the SchemaType for a particular XMLBeans class.
104 */
105 protected SchemaType getSchemaType(Class clazz)
106 {
107 try
108 {
109 Field f = clazz.getDeclaredField("type");
110
111 return (SchemaType) f.get(null);
112 }
113 catch (NoSuchFieldException e)
114 {
115 throw new XFireRuntimeException("Couldn't find type field!", e);
116 }
117 catch (IllegalArgumentException e)
118 {
119 throw new XFireRuntimeException("Couldn't get type field!", e);
120 }
121 catch (IllegalAccessException e)
122 {
123 throw new XFireRuntimeException("Couldn't get type field!", e);
124 }
125 }
126 }