View Javadoc

1   package org.codehaus.xfire.service.object;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   
6   import org.apache.commons.logging.Log;
7   import org.apache.commons.logging.LogFactory;
8   
9   import org.codehaus.xfire.MessageContext;
10  import org.codehaus.xfire.XFireRuntimeException;
11  import org.codehaus.xfire.fault.XFireFault;
12  import org.codehaus.xfire.transport.Session;
13  
14  /***
15   * An invoker which instantiates classes automatically based on the Service's
16   * scope.
17   * 
18   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
19   * @since Nov 16, 2004
20   */
21  public class ObjectInvoker implements Invoker
22  {
23      private static final Log logger = LogFactory.getLog( ObjectInvoker.class.getName() );
24  
25      /***
26       * The object if the scope is SCOPE_APPLICATION.
27       */
28      private Object appObj;
29  
30      public Object invoke( final Method method, final Object[] params, final MessageContext context )
31          throws XFireFault
32      {
33          try
34          {
35              final Object serviceObject = getServiceObject( context );
36  
37              return method.invoke( serviceObject, params );
38          }
39          catch( IllegalArgumentException e )
40          {
41              throw new XFireFault( "Illegal argument.", e, XFireFault.SENDER );
42          }
43          catch( InvocationTargetException e )
44          {
45              final Throwable t = e.getTargetException();
46  
47              if( t instanceof XFireFault )
48              {
49                  throw (XFireFault)t;
50              }
51              else if( t instanceof Exception )
52              {
53                  logger.warn( "Error invoking service.", t );
54                  throw new XFireFault( t, XFireFault.SENDER );
55              }
56              else
57              {
58                  logger.warn( "Error invoking service.", e );
59                  throw new XFireRuntimeException( "Error invoking service.", e );
60              }
61          }
62          catch( IllegalAccessException e )
63          {
64              throw new XFireFault( "Couldn't access service object.", e, XFireFault.RECEIVER );
65          }
66      }
67  
68      /***
69       * Creates and returns a service object depending on the scope.
70       */
71      public Object getServiceObject( final MessageContext context )
72          throws XFireFault
73      {
74          final ObjectService service = (ObjectService)context.getService();
75          final int scope = service.getScope();
76          if( scope == ObjectService.SCOPE_APPLICATION )
77          {
78              if( appObj == null )
79              {
80                  synchronized( DefaultObjectService.class )
81                  {
82                      appObj = createServiceObject( service );
83                  }
84              }
85              return appObj;
86          }
87          else if( scope == ObjectService.SCOPE_SESSION )
88          {
89              final Session session = context.getSession();
90              final String key = "service." + service.getName();
91  
92              Object sessObj = session.get( key );
93              if( sessObj == null )
94              {
95                  synchronized( DefaultObjectService.class )
96                  {
97                      sessObj = createServiceObject( service );
98                      session.put( key, sessObj );
99                  }
100             }
101             return sessObj;
102         }
103         else if( scope == ObjectService.SCOPE_REQUEST )
104         {
105             return createServiceObject( service );
106         }
107         else
108         {
109             throw new UnsupportedOperationException( "Scope " + scope + " is invalid." );
110         }
111     }
112 
113     /***
114      * Override this method to control how XFire creates the service object.
115      * @param service
116      * @return
117      * @throws XFireFault
118      */
119     public Object createServiceObject( final ObjectService service ) throws XFireFault
120     {
121         try
122         {
123             Class svcClass = (Class) service.getProperty(ObjectService.SERVICE_IMPL_CLASS);
124             
125             if (svcClass == null)
126             {
127                 svcClass = service.getServiceClass();
128             }
129 
130             return svcClass.newInstance();
131         }
132         catch( InstantiationException e )
133         {
134             throw new XFireFault( "Couldn't instantiate service object.", e, XFireFault.RECEIVER );
135         }
136         catch( IllegalAccessException e )
137         {
138             throw new XFireFault( "Couldn't access service object.", e, XFireFault.RECEIVER );
139         }
140     }
141 }