View Javadoc

1   package org.codehaus.xfire.service.object;
2   
3   import java.lang.reflect.Method;
4   import java.lang.reflect.Modifier;
5   import java.net.URL;
6   
7   import javax.wsdl.Definition;
8   import javax.wsdl.factory.WSDLFactory;
9   import javax.wsdl.xml.WSDLReader;
10  import javax.xml.namespace.QName;
11  
12  import org.codehaus.xfire.XFire;
13  import org.codehaus.xfire.fault.Soap11FaultHandler;
14  import org.codehaus.xfire.fault.Soap12FaultHandler;
15  import org.codehaus.xfire.handler.SoapHandler;
16  import org.codehaus.xfire.message.ObjectServiceHandler;
17  import org.codehaus.xfire.service.Service;
18  import org.codehaus.xfire.soap.Soap11;
19  import org.codehaus.xfire.soap.SoapConstants;
20  import org.codehaus.xfire.soap.SoapVersion;
21  import org.codehaus.xfire.type.DefaultTypeMappingRegistry;
22  import org.codehaus.xfire.type.TypeMapping;
23  import org.codehaus.xfire.type.TypeMappingRegistry;
24  import org.codehaus.xfire.util.NamespaceHelper;
25  import org.codehaus.xfire.wsdl.ResourceWSDL;
26  import org.codehaus.xfire.wsdl11.ObjectServiceVisitor;
27  import org.codehaus.xfire.wsdl11.builder.JavaWSDLBuilder;
28  
29  /***
30   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
31   */
32  public class ObjectServiceBuilder
33      implements ServiceBuilder
34  {
35      private TypeMappingRegistry registry;
36      private XFire xfire;
37      
38      private Class invokerClass;
39      private Class messageBridgeClass;
40      
41      public ObjectServiceBuilder()
42      {
43          registry = new DefaultTypeMappingRegistry(true);
44      }
45      
46      public ObjectServiceBuilder(XFire xfire)
47      {
48          registry = new DefaultTypeMappingRegistry(true);
49          
50          this.xfire = xfire;
51      }
52  
53      public ObjectServiceBuilder(XFire xfire, TypeMappingRegistry registry)
54      {
55          this.registry = registry;
56  
57          this.xfire = xfire;
58      }
59  
60      /***
61       * @param wsdlUrl
62       * @return
63       */
64      public Service create(Class clazz, TypeMapping tm, URL wsdlUrl) throws Exception
65      {
66          WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
67          Definition def = reader.readWSDL(wsdlUrl.toString());
68          
69          DefaultObjectService service = new DefaultObjectService();
70          service.setServiceClass(clazz);
71          service.setTypeMapping(tm);
72  
73          ObjectServiceVisitor builder = new ObjectServiceVisitor(def, service);
74          builder.configure();
75  
76          service.setFaultHandler(new Soap11FaultHandler());
77          service.setWSDL(new ResourceWSDL(wsdlUrl));
78          
79          SoapHandler handler = new SoapHandler(new ObjectServiceHandler());
80          service.setServiceHandler(handler);
81          
82          xfire.getServiceRegistry().register(service);
83  
84          return service;
85      }
86      
87      /***
88       * @param clazz
89       * @return
90       */
91      public Service create(Class clazz)
92      {
93          return create(clazz,
94                        Soap11.getInstance(),
95                        SoapConstants.STYLE_WRAPPED,
96                        SoapConstants.USE_LITERAL);
97      }
98  
99      /***
100      * @param clazz
101      * @param version
102      * @param style
103      * @param use
104      * @return
105      */
106     public Service create(Class clazz, SoapVersion version, String style, String use)
107     {
108         String name = clazz.getName();
109         int last = name.lastIndexOf(".");
110         if ( last != -1 )
111         {
112             name = name.substring(last+1);
113         }
114         
115         String ns = NamespaceHelper.makeNamespaceFromClassName(clazz.getName(), "http");
116         return create(clazz, name, ns, version, style, use);
117     }
118     
119     public Service create(Class clazz,
120                           String name,
121                           String namespace,
122                           SoapVersion version,
123                           String style,
124                           String use)
125     {
126         DefaultObjectService service = new DefaultObjectService();
127 
128         service.setName(name);
129         service.setDefaultNamespace(namespace);
130         service.setServiceClass(clazz);
131         
132         service.setSoapVersion(version);
133         service.setStyle(style);
134         service.setUse(use);
135         service.setAutoTyped(true);
136         
137         if (version instanceof Soap11)
138         {
139             service.setFaultHandler(new Soap11FaultHandler());
140         }
141         else
142         {
143             service.setFaultHandler(new Soap12FaultHandler());
144         }
145         
146         if (xfire != null)
147         {
148             service.setWSDLBuilder(new JavaWSDLBuilder(xfire.getTransportManager()));
149         }
150         
151         SoapHandler handler = new SoapHandler(new ObjectServiceHandler());
152         service.setServiceHandler(handler);
153 
154         initializeTypeMapping(service);
155         initializeOperations(service);
156         
157         if (xfire != null)
158         {
159             xfire.getServiceRegistry().register(service);
160         }
161         
162         return service;
163     }
164 
165     
166     protected void initializeOperations(DefaultObjectService service)
167     {
168         final Method[] methods = service.getServiceClass().getDeclaredMethods();
169 
170         // TODO: go through superclasses, stopping at Object.class
171 
172         for (int i = 0; i < methods.length; i++)
173         {
174             final Method method = methods[i];
175             final String methodName = method.getName();
176             final int modifiers = method.getModifiers();
177 
178             if ( /*isAllowed(methodName) &&*/ Modifier.isPublic(modifiers)
179                     && !Modifier.isStatic(modifiers))
180             {
181                 addOperation(service, method);
182             }
183         }
184     }
185 
186     protected void addOperation(DefaultObjectService service, final Method method)
187     {
188         final Operation op = new Operation(method);
189 
190         final Class[] paramClasses = method.getParameterTypes();
191 
192         final boolean isDoc = service.getStyle().equals(SoapConstants.STYLE_DOCUMENT);
193 
194         final TypeMapping mapping = service.getTypeMapping();
195         
196         for (int j = 0; j < paramClasses.length; j++)
197         {
198             String paramName = "";
199             if (isDoc)
200                 paramName = method.getName();
201 
202             paramName = paramName + "in" + j;
203 
204             final QName q = new QName(service.getDefaultNamespace(), paramName);
205             final Parameter p = new Parameter(q, paramClasses[j]);
206 
207             op.addInParameter(p);
208         }
209 
210         final Class returnType = method.getReturnType();
211         if (!returnType.isAssignableFrom(void.class))
212         {
213             String outName = "";
214             if (isDoc)
215                 outName = method.getName();
216 
217             final QName q = new QName(service.getDefaultNamespace(), outName + "out");
218             final Parameter outP = new Parameter(q, method.getReturnType());
219             op.addOutParameter(outP);
220         }
221 
222         service.addOperation(op);
223     }
224 
225     /***
226      * Creates a type mapping for this class and registers it with the
227      * TypeMappingRegistry. This needs to be called before
228      * initializeOperations().
229      */
230     protected void initializeTypeMapping(DefaultObjectService service)
231     {
232         String encodingStyle = service.getEncodingStyleURI();
233             
234         if (encodingStyle == null)
235         {
236             if (service.getUse().equals(SoapConstants.USE_ENCODED))
237             {
238                 encodingStyle = service.getSoapVersion().getSoapEncodingStyle();
239             }
240             else
241             {
242                 encodingStyle = SoapConstants.XSD;
243             }
244         }
245 
246         service.setEncodingStyleURI(encodingStyle);
247         final TypeMapping tm = registry.createTypeMapping(encodingStyle, service.isAutoTyped());
248 
249         service.setTypeMapping(tm);
250         registry.register(service.getDefaultNamespace(), tm);
251     }
252 
253 }