1 package org.codehaus.xfire.wsdl11;
2
3 import java.lang.reflect.Method;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.wsdl.Definition;
11 import javax.wsdl.Input;
12 import javax.wsdl.Operation;
13 import javax.wsdl.Part;
14 import javax.wsdl.Service;
15
16 import org.codehaus.xfire.XFireRuntimeException;
17 import org.codehaus.xfire.service.object.DefaultObjectService;
18 import org.codehaus.xfire.service.object.Parameter;
19 import org.codehaus.xfire.soap.SoapConstants;
20 import org.codehaus.xfire.type.Type;
21 import org.codehaus.xfire.type.TypeMapping;
22
23 /***
24 * TODO: I would be great to be able to configure XFire during deployment and
25 * write it to the configuration
26 */
27 public class ObjectServiceVisitor
28 extends WSDLVisitor
29 {
30 private DefaultObjectService service;
31
32 private TypeMapping typeMappings;
33
34 private Map parameterMap;
35
36 private Map typeMap;
37
38 public ObjectServiceVisitor(Definition definition,
39 DefaultObjectService service)
40 {
41 super(definition);
42
43 this.service = service;
44
45
46 service.setAutoTyped(true);
47 service.setStyle(SoapConstants.STYLE_DOCUMENT);
48 service.setUse(SoapConstants.USE_LITERAL);
49
50 typeMappings = service.getTypeMapping();
51
52 parameterMap = new HashMap();
53 typeMap = new HashMap();
54 }
55
56 public void configure()
57 {
58 this.walkTree();
59 }
60
61 protected void visit(Part part)
62 {
63 Type type = typeMappings.getType(part.getElementName());
64 if (type == null)
65 throw new XFireRuntimeException("Couldn't find type for " + part.getElementName());
66
67 Parameter parameter = new Parameter(part.getElementName(), type.getTypeClass());
68 parameterMap.put(part, parameter);
69 typeMap.put(part, type.getTypeClass());
70 }
71
72 protected void visit(Operation wsdlOperation)
73 {
74 Method method = getMethod(wsdlOperation);
75
76 org.codehaus.xfire.service.object.Operation xfireOperation = new org.codehaus.xfire.service.object.Operation(
77 method);
78
79
80 Collection inParts = wsdlOperation.getInput().getMessage().getParts().values();
81 for (Iterator iterator = inParts.iterator(); iterator.hasNext();)
82 {
83 Part part = (Part) iterator.next();
84 Parameter inParameter = (Parameter) parameterMap.get(part);
85 xfireOperation.addInParameter(inParameter);
86 }
87
88
89 Iterator outParts = wsdlOperation.getOutput().getMessage().getParts().values().iterator();
90 if (outParts.hasNext())
91 {
92 Part part = (Part) outParts.next();
93 Parameter outParameter = (Parameter) parameterMap.get(part);
94 xfireOperation.addOutParameter(outParameter);
95 }
96
97 service.addOperation(xfireOperation);
98 }
99
100 private Method getMethod(Operation wsdlOperation)
101 {
102 Input input = wsdlOperation.getInput();
103 List parts = input.getMessage().getOrderedParts(wsdlOperation.getParameterOrdering());
104 Class[] types = new Class[parts.size()];
105 for (int i = 0; i < parts.size(); i++)
106 {
107 types[i] = (Class) typeMap.get((Part) parts.get(i));
108 }
109
110 try
111 {
112 return service.getServiceClass().getMethod(wsdlOperation.getName(), types);
113 }
114 catch (NoSuchMethodException e)
115 {
116 throw new IllegalArgumentException("There is no method matching the operation named "
117 + wsdlOperation.getName());
118 }
119 }
120
121 protected void visit(Service wsdlService)
122 {
123 service.setDefaultNamespace(wsdlService.getQName().getNamespaceURI());
124 service.setName(wsdlService.getQName().getLocalPart());
125 }
126 }