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 }