1 package org.codehaus.xfire.plexus.config;
2
3 import java.io.File;
4 import java.lang.reflect.Constructor;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7
8 import javax.wsdl.WSDLException;
9 import javax.xml.namespace.QName;
10
11 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
12 import org.codehaus.plexus.configuration.PlexusConfiguration;
13 import org.codehaus.plexus.configuration.PlexusConfigurationException;
14 import org.codehaus.xfire.XFire;
15 import org.codehaus.xfire.handler.SoapHandler;
16 import org.codehaus.xfire.message.ObjectServiceHandler;
17 import org.codehaus.xfire.plexus.PlexusXFireComponent;
18 import org.codehaus.xfire.plexus.ServiceInvoker;
19 import org.codehaus.xfire.service.Service;
20 import org.codehaus.xfire.service.ServiceRegistry;
21 import org.codehaus.xfire.service.object.DefaultObjectService;
22 import org.codehaus.xfire.service.object.ObjectService;
23 import org.codehaus.xfire.service.object.ObjectServiceBuilder;
24 import org.codehaus.xfire.service.object.ServiceBuilder;
25 import org.codehaus.xfire.soap.Soap11;
26 import org.codehaus.xfire.soap.Soap12;
27 import org.codehaus.xfire.soap.SoapVersion;
28 import org.codehaus.xfire.transport.TransportManager;
29 import org.codehaus.xfire.type.Type;
30 import org.codehaus.xfire.type.TypeMapping;
31 import org.codehaus.xfire.type.TypeMappingRegistry;
32
33 /***
34 * Creates and configures services.
35 *
36 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
37 * @since Sep 20, 2004
38 */
39 public class ObjectServiceConfigurator
40 extends PlexusXFireComponent
41 implements Configurator
42 {
43 public Service createService( PlexusConfiguration config )
44 throws Exception
45 {
46 String builderClass = config.getChild("serviceBuilder").getValue("");
47 ServiceBuilder builder = getServiceBuilder(builderClass);
48
49 String name = config.getChild("name").getValue();
50 String namespace = config.getChild("namespace" ).getValue("");
51 String use = config.getChild("use").getValue("literal");
52 String style = config.getChild("style").getValue("wrapped");
53 String serviceClass = config.getChild("serviceClass").getValue();
54 String implClass = config.getChild("implementationClass").getValue("");
55 String soapVersion = config.getChild("soapVersion").getValue("1.1");
56 String wsdlUrl = config.getChild("wsdl").getValue("");
57
58 DefaultObjectService service = null;
59 if (wsdlUrl.length() > 0)
60 {
61 try
62 {
63 TypeMapping tm = getTypeMappingRegistry().createTypeMapping(true);
64 PlexusConfiguration[] types = config.getChild("types").getChildren("type");
65 for ( int i = 0; i < types.length; i++ )
66 {
67 initializeType( types[i], tm );
68 }
69
70 URL url = null;
71 try
72 {
73 url = new URL(wsdlUrl);
74 }
75 catch (MalformedURLException e)
76 {
77 url = new File(wsdlUrl).toURL();
78 }
79
80 getLogger().info("Creating service with " + url.toString() );
81 service = (DefaultObjectService) builder.create(loadClass(serviceClass), tm, url);
82 }
83 catch (WSDLException e)
84 {
85 throw new PlexusConfigurationException("Could not load the WSDL file.", e);
86 }
87 }
88 else
89 {
90 getLogger().info("Creating service " + name );
91
92 Class clazz = getClass().getClassLoader().loadClass(serviceClass);
93
94 SoapVersion version = null;
95 if (soapVersion.equals("1.1"))
96 {
97 version = Soap11.getInstance();
98 }
99 else if (soapVersion.equals("1.2"))
100 {
101 version = Soap12.getInstance();
102 }
103
104 service = (DefaultObjectService) builder.create(clazz, name, namespace, version, style, use);
105
106 PlexusConfiguration[] types = config.getChild("types").getChildren("type");
107 for ( int i = 0; i < types.length; i++ )
108 {
109 initializeType( types[i], service.getTypeMapping() );
110 }
111 }
112
113 if (implClass.length() > 0)
114 {
115 service.setProperty(ObjectService.SERVICE_IMPL_CLASS, loadClass(implClass));
116 }
117
118 final String scope = config.getChild( "scope" ).getValue( "application" );
119 if( scope.equals( "application" ) )
120 service.setScope( ObjectService.SCOPE_APPLICATION );
121 else if( scope.equals( "session" ) )
122 service.setScope( ObjectService.SCOPE_SESSION );
123 else if( scope.equals( "request" ) )
124 service.setScope( ObjectService.SCOPE_REQUEST );
125
126 ServiceInvoker invoker = new ServiceInvoker(getServiceLocator());
127 ObjectServiceHandler handler = new ObjectServiceHandler(invoker);
128 SoapHandler sHandler = new SoapHandler(handler);
129 service.setServiceHandler(sHandler);
130
131 return service;
132 }
133
134 /***
135 * @return
136 * @throws PlexusConfigurationException
137 */
138 protected ServiceBuilder getServiceBuilder(String builderClass)
139 throws Exception
140 {
141 if (builderClass.length() == 0)
142 {
143 return new ObjectServiceBuilder(getXFire(), getTypeMappingRegistry());
144 }
145 else
146 {
147 Class clz = getClass().getClassLoader().loadClass(builderClass);
148 Constructor con =
149 clz.getConstructor( new Class[] {XFire.class, TypeMappingRegistry.class} );
150
151 return (ServiceBuilder)
152 con.newInstance(new Object[] {getXFire(), getTypeMappingRegistry()});
153 }
154 }
155
156 private void initializeType(PlexusConfiguration configuration,
157 TypeMapping tm)
158 throws PlexusConfigurationException
159 {
160 try
161 {
162 String ns = configuration.getAttribute("namespace", tm.getEncodingStyleURI());
163 String name = configuration.getAttribute("name");
164
165 Type type = (Type) loadClass( configuration.getAttribute("type") ).newInstance();
166
167 tm.register( loadClass( configuration.getAttribute("class") ),
168 new QName( ns, name ),
169 type );
170 }
171 catch (Exception e)
172 {
173 if ( e instanceof PlexusConfigurationException )
174 throw (PlexusConfigurationException) e;
175
176 throw new PlexusConfigurationException( "Could not configure type.", e );
177 }
178 }
179
180 public XFire getXFire()
181 {
182 XFire xfire = null;
183
184 try
185 {
186 xfire = (XFire) getServiceLocator().lookup( XFire.ROLE );
187 }
188 catch (ComponentLookupException e)
189 {
190 throw new RuntimeException( "Couldn't find the XFire engine!", e );
191 }
192
193 return xfire;
194 }
195
196 public TypeMappingRegistry getTypeMappingRegistry()
197 {
198 TypeMappingRegistry registry = null;
199
200 try
201 {
202 registry = (TypeMappingRegistry) getServiceLocator().lookup( TypeMappingRegistry.ROLE );
203 }
204 catch (ComponentLookupException e)
205 {
206 throw new RuntimeException( "Couldn't find the TypeMappingRegistry!", e );
207 }
208
209 return registry;
210 }
211
212 protected TransportManager getTransportManager()
213 {
214 TransportManager transMan = null;
215
216 try
217 {
218 transMan = (TransportManager) getServiceLocator().lookup( TransportManager.ROLE );
219 }
220 catch (ComponentLookupException e)
221 {
222 throw new RuntimeException( "Couldn't find the TransportManager!", e );
223 }
224
225 return transMan;
226 }
227
228 /***
229 * Load a class from the class loader.
230 *
231 * @param className The name of the class.
232 * @return The class.
233 * @throws Exception
234 */
235 protected Class loadClass( String className )
236 throws Exception
237 {
238
239 if ( className.endsWith("[]") )
240 {
241 className = "[L" + className.substring(0, className.length() - 2 ) + ";";
242 }
243
244 return getClass().getClassLoader().loadClass( className );
245 }
246
247 protected ServiceRegistry getServiceRegistry()
248 {
249 ServiceRegistry registry = null;
250
251 try
252 {
253 registry = (ServiceRegistry) getServiceLocator().lookup( ServiceRegistry.ROLE );
254 }
255 catch (ComponentLookupException e)
256 {
257 throw new RuntimeException( "Couldn't find the ServiceRegistry!", e );
258 }
259
260 return registry;
261 }
262 }