1 package org.codehaus.ivory;
2
3 import java.io.InputStream;
4
5 import javax.xml.namespace.QName;
6
7 import org.apache.avalon.framework.activity.Initializable;
8 import org.apache.avalon.framework.activity.Startable;
9 import org.apache.avalon.framework.configuration.Configurable;
10 import org.apache.avalon.framework.configuration.Configuration;
11 import org.apache.avalon.framework.configuration.ConfigurationException;
12 import org.apache.avalon.framework.logger.AbstractLogEnabled;
13 import org.apache.avalon.framework.service.ServiceException;
14 import org.apache.avalon.framework.service.ServiceManager;
15 import org.apache.avalon.framework.service.Serviceable;
16 import org.apache.axis.AxisFault;
17 import org.apache.axis.configuration.FileProvider;
18 import org.apache.axis.configuration.SimpleProvider;
19 import org.apache.axis.deployment.wsdd.WSDDConstants;
20 import org.apache.axis.deployment.wsdd.WSDDProvider;
21 import org.apache.axis.description.ServiceDesc;
22 import org.apache.axis.encoding.TypeMappingImpl;
23 import org.apache.axis.encoding.TypeMappingRegistry;
24 import org.apache.axis.enum.Scope;
25 import org.apache.axis.handlers.soap.SOAPService;
26 import org.apache.axis.providers.java.RPCProvider;
27 import org.apache.axis.server.AxisServer;
28 import org.apache.axis.wsdl.fromJava.Namespaces;
29 import org.codehaus.ivory.provider.AvalonProvider;
30 import org.codehaus.ivory.provider.IvoryAvalonProvider;
31 import org.codehaus.ivory.provider.IvoryProvider;
32 import org.codehaus.ivory.provider.WSDDJavaAvalonProvider;
33
34 /***
35 * The default AxisService implementation.
36 *
37 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
38 * @since Mar 9, 2003
39 */
40 public class DefaultAxisService
41 extends AbstractLogEnabled
42 implements AxisService, Startable, Configurable, Initializable, Serviceable
43 {
44
45 public static final QName QNAME_AVALONRPC_PROVIDER =
46 new QName(WSDDConstants.URI_WSDD_JAVA, "Avalon");
47
48 private ServiceManager manager;
49
50 protected static final String SERVER_CONFIG_KEY = "server-config";
51
52 protected static final String DEFAULT_SERVER_CONFIG =
53 "/org/codehaus/ivory/server-config.wsdd";
54
55 private SimpleProvider provider;
56
57 private AxisServer axisServer;
58
59 private String serverConfig;
60
61 private Configuration services;
62
63 /***
64 * @param configuration
65 * @throws ConfigurationException
66 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
67 */
68 public void configure( Configuration configuration )
69 throws ConfigurationException
70 {
71 serverConfig = configuration.getAttribute( SERVER_CONFIG_KEY, "" );
72
73 services = configuration.getChild( "services" );
74 }
75
76 /***
77 * @throws Exception
78 * @see org.apache.avalon.framework.activity.Initializable#initialize()
79 */
80 public void initialize() throws Exception
81 {
82 initializeAxisServer();
83 initializeWSDDProviders();
84
85 // Initialize the services in the configuration.
86 initializeServices( services );
87
88 // This is definitely not what setOption was meant for...
89 getAxisServer().setOption(SERVICE_MANAGER_KEY, manager);
90 }
91
92 /***
93 * Register custom providers with Axis.
94 */
95 private void initializeWSDDProviders()
96 {
97 /* This could be registered other ways - like through the jar's
98 * META-INF, but lets take the easy and straightforward way out.
99 */
100 WSDDProvider.registerProvider(
101 QNAME_AVALONRPC_PROVIDER,
102 new WSDDJavaAvalonProvider());
103 }
104
105 /***
106 * @param services
107 */
108 protected void initializeServices(Configuration services)
109 throws Exception
110 {
111 initializeClassServices( services.getChildren( "classService" ) );
112
113 initializeAvalonServices( services.getChildren( "avalonService" ) );
114 }
115
116 /***
117 * @param configurations
118 */
119 protected void initializeClassServices( Configuration[] services )
120 throws Exception
121 {
122 for ( int i = 0; i < services.length; i++ )
123 {
124 String name = services[i].getAttribute( "name" );
125 String role = services[i].getAttribute( "class" );
126 exposeClass( name, role );
127 }
128 }
129
130 /***
131 * @param configurations
132 */
133 protected void initializeAvalonServices(Configuration[] services )
134 throws Exception
135 {
136 for ( int i = 0; i < services.length; i++ )
137 {
138 String name = services[i].getAttribute( "name" );
139 String className = services[i].getAttribute( "role" );
140 exposeService( name, className );
141 }
142 }
143
144 /***
145 * Initializes the AxisServer.
146 * @throws Exception
147 */
148 public void initializeAxisServer() throws Exception
149 {
150 /* Technically, we are supposed to use Axis's EngineConfigurationFactory
151 * but it is a big PITA and seems uneccessary. This can be changed
152 * in the future if more flexible mechanisms of loading the
153 * configuration are needed.
154 */
155 FileProvider fileProvider = null;
156
157 if ( serverConfig.equals("") )
158 {
159 getLogger().debug( "Using default server-config.wsdd." );
160
161 InputStream is = this.getClass().getResourceAsStream( DEFAULT_SERVER_CONFIG );
162
163 if ( is == null )
164 throw new RuntimeException( "Configuration is null!" );
165
166 fileProvider = new FileProvider( DEFAULT_SERVER_CONFIG );
167 fileProvider.setInputStream( is );
168 }
169 else
170 {
171 getLogger().debug( "Using server-config " + serverConfig + "." );
172
173 fileProvider = new FileProvider( serverConfig );
174 }
175
176 /* Wrap the FileProvider with a SimpleProvider. This needs to be done
177 * because the only way to expose services with the FileProvider is to
178 * use WSDD deployment descriptors. SimpleProvider allows us to deploy
179 * services much easier.
180 */
181 provider = new SimpleProvider( fileProvider );
182
183 // Create the AxisServer from the configuraiton.
184 axisServer = new AxisServer( provider );
185 axisServer.getApplicationSession().set( AvalonProvider.SERVICE_MANAGER,
186 manager );
187 }
188
189 /***
190 * @throws Exception
191 * @see org.apache.avalon.framework.activity.Startable#start()
192 */
193 public void start() throws Exception
194 {
195 getLogger().debug( "Starting " + DefaultAxisService.ROLE );
196
197 // This doesn't need to be done, since the AxisServier constructor
198 // calls init(), which is what start() does.
199 // axisServer.start();
200 }
201
202 /***
203 * @throws Exception
204 * @see org.apache.avalon.framework.activity.Startable#stop()
205 */
206 public void stop() throws Exception
207 {
208 getLogger().debug( "Stopping " + DefaultAxisService.ROLE );
209
210 axisServer.stop();
211 }
212
213 /***
214 * @return AxisServer
215 * @see org.codehaus.ivory.axis.AxisService#getAxisServer()
216 */
217 public AxisServer getAxisServer()
218 {
219 return axisServer;
220 }
221
222 /***
223 * @see org.codehaus.ivory.axis.AxisService#exposeClass(java.lang.String, java.lang.Class)
224 */
225 public void exposeClass( String serviceName, String classService )
226 throws AxisFault, ClassNotFoundException
227 {
228 exposeClass( serviceName, null, classService );
229 }
230
231 /***
232 * @see org.codehaus.ivory.axis.AxisService#exposeClass(java.lang.String, java.lang.String[], java.lang.Class)
233 */
234 public void exposeClass( String serviceName,
235 String[] methodNames,
236 String className )
237 throws AxisFault, ClassNotFoundException
238 {
239 SOAPService service = new SOAPService( new IvoryProvider() );
240
241 initializeService( service, serviceName,
242 methodNames, className );
243
244 getLogger().debug( "Exposed class " + className +
245 " as " + serviceName + "." );
246 }
247
248 /***
249 * @see org.codehaus.ivory.axis.AxisService#exposeService(java.lang.String, java.lang.String)
250 */
251 public void exposeService(String serviceName, String role)
252 throws AxisFault, ClassNotFoundException
253 {
254 exposeService( serviceName, null, role );
255 }
256
257 /***
258 * @see org.codehaus.ivory.axis.AxisService#exposeService(java.lang.String, java.lang.String[], java.lang.String)
259 */
260 public void exposeService(String serviceName,
261 String[] methodNames,
262 String role)
263 throws AxisFault, ClassNotFoundException
264 {
265 SOAPService service = new SOAPService( new IvoryAvalonProvider() );
266
267 initializeService( service, serviceName, methodNames, role );
268
269 getLogger().debug( "Exposed service " + role +
270 " as " + serviceName + "." );
271 }
272
273 /***
274 * Initializes the SOAPService with the appropriate information.
275 */
276 protected void initializeService( SOAPService service,
277 String serviceName,
278 String[] methodNames,
279 String className )
280 throws AxisFault, ClassNotFoundException
281 {
282 service.setEngine( getAxisServer() );
283
284 // The namespace of the service.
285 String namespace = Namespaces.makeNamespace( className );
286
287 /* Now we set up the various options for the SOAPService. We set:
288 *
289 * RPCProvider.OPTION_WSDL_SERVICEPORT
290 * In essense, this is our service name
291 *
292 * RPCProvider.OPTION_CLASSNAME
293 * This tells the provider (whether it be an AvalonProvider or just
294 * JavaProvider) what class to load via "makeNewServiceObject".
295 *
296 * RPCProvider.OPTION_SCOPE
297 * How long the object loaded via "makeNewServiceObject" will persist -
298 * either request, session, or application. We use the default for now.
299 *
300 * RPCProvider.OPTION_WSDL_TARGETNAMESPACE
301 * A namespace created from the package name of the service.
302 *
303 * RPCProvider.OPTION_ALLOWEDMETHODS
304 * What methods the service can execute on our class.
305 *
306 * We don't set:
307 * RPCProvider.OPTION_WSDL_PORTTYPE
308 * RPCProvider.OPTION_WSDL_SERVICEELEMENT
309 */
310 service.setOption( RPCProvider.OPTION_WSDL_SERVICEPORT, serviceName );
311 service.setOption( RPCProvider.OPTION_CLASSNAME, className );
312 service.setOption( RPCProvider.OPTION_SCOPE, Scope.DEFAULT.getName());
313 service.setOption( RPCProvider.OPTION_WSDL_TARGETNAMESPACE,
314 namespace );
315
316 // Set the allowed methods, allow all if there are none specified.
317 if ( methodNames == null)
318 {
319 service.setOption( RPCProvider.OPTION_ALLOWEDMETHODS, "*" );
320 }
321 else
322 {
323 service.setOption( RPCProvider.OPTION_ALLOWEDMETHODS, methodNames );
324 }
325
326 /* Create a service description. This tells Axis that this
327 * service exists and also what it can execute on this service. It is
328 * created with all the options we set above.
329 */
330 ServiceDesc sd = service.getInitializedServiceDesc(null);
331
332 // Tell Axis to try and be intelligent about serialization.
333 TypeMappingRegistry registry = service.getTypeMappingRegistry();
334
335 TypeMappingImpl tm = (TypeMappingImpl) registry.getDefaultTypeMapping();
336 tm.setDoAutoTypes( true );
337
338 // Tell the axis configuration about our new service.
339 provider.deployService( serviceName, service );
340 }
341
342 /***
343 * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
344 */
345 public void service(ServiceManager manager) throws ServiceException
346 {
347 this.manager = manager;
348 }
349 }
This page was automatically generated by Maven