001    package railo.runtime.net.rpc.server;
002    
003    import java.util.Map;
004    import java.util.WeakHashMap;
005    
006    import org.apache.axis.AxisFault;
007    import org.apache.axis.MessageContext;
008    import org.apache.axis.constants.Scope;
009    import org.apache.axis.handlers.BasicHandler;
010    import org.apache.axis.handlers.soap.SOAPService;
011    import org.apache.axis.providers.java.JavaProvider;
012    import org.apache.axis.providers.java.RPCProvider;
013    
014    import railo.commons.lang.types.RefBoolean;
015    import railo.commons.lang.types.RefBooleanImpl;
016    import railo.runtime.Component;
017    
018    
019    /**
020     * Handle Component as Webservice
021     */
022    public final class ComponentHandler extends BasicHandler {
023        
024        private static Map soapServices = new WeakHashMap();
025    
026        /**
027         * Just set up the service, the inner service will do the rest...
028         * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
029         */
030        public void invoke(MessageContext msgContext) throws AxisFault {
031            try {
032                setupService(msgContext);
033            } 
034            catch (Exception e) {
035                throw AxisFault.makeFault(e);
036            }
037        }
038        
039        /**
040         * Just set up the service, the inner service will do the rest...
041         * @see org.apache.axis.Handler#generateWSDL(org.apache.axis.MessageContext)
042         */
043        public void generateWSDL(MessageContext msgContext) throws AxisFault {
044            try {
045                setupService(msgContext);
046            } 
047            catch (Exception e) {
048                throw AxisFault.makeFault(e);
049            }
050        }
051        
052        /**
053         * handle all the work necessary set
054         * up the "proxy" RPC service surrounding it as the MessageContext's
055         * active service.
056         *
057         */ 
058        protected void setupService(MessageContext msgContext) throws Exception {
059            RefBoolean isnew=new RefBooleanImpl(false);
060            Component cfc=(Component) msgContext.getProperty(Constants.COMPONENT);
061            Class clazz=cfc.getJavaAccessClass(isnew);
062            String clazzName=clazz.getName();
063            
064            ClassLoader classLoader=clazz.getClassLoader();
065            Pair pair;
066            SOAPService rpc=null;
067            if(!isnew.toBooleanValue() && (pair = (Pair)soapServices.get(clazzName))!=null) {
068                    if(classLoader==pair.classloader)
069                            rpc=pair.rpc;
070            }
071            //else classLoader = clazz.getClassLoader();
072            
073            //print.out("cl:"+classLoader);
074            msgContext.setClassLoader(classLoader);
075            
076            if (rpc == null) {
077                rpc = new SOAPService(new RPCProvider());
078                rpc.setName(clazzName);
079                rpc.setOption(JavaProvider.OPTION_CLASSNAME, clazzName );
080                rpc.setEngine(msgContext.getAxisEngine());
081                
082                rpc.setOption(JavaProvider.OPTION_ALLOWEDMETHODS, "*");
083                rpc.setOption(JavaProvider.OPTION_SCOPE, Scope.REQUEST.getName());
084                rpc.getInitializedServiceDesc(msgContext);
085                soapServices.put(clazzName, new Pair(classLoader,rpc));                
086            }
087            
088            rpc.setEngine(msgContext.getAxisEngine());
089            rpc.init();   // ??
090            msgContext.setService( rpc );
091            
092        }
093        
094        class Pair {
095            private ClassLoader classloader;
096            private SOAPService rpc;
097                    public Pair(ClassLoader classloader, SOAPService rpc) {
098                            this.classloader = classloader;
099                            this.rpc = rpc;
100                    }
101        }
102    }