001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.net.rpc.server;
020
021import java.util.Map;
022import java.util.WeakHashMap;
023
024import lucee.commons.lang.types.RefBoolean;
025import lucee.commons.lang.types.RefBooleanImpl;
026import lucee.runtime.Component;
027
028import org.apache.axis.AxisFault;
029import org.apache.axis.MessageContext;
030import org.apache.axis.constants.Scope;
031import org.apache.axis.handlers.BasicHandler;
032import org.apache.axis.handlers.soap.SOAPService;
033import org.apache.axis.providers.java.JavaProvider;
034import org.apache.axis.providers.java.RPCProvider;
035
036
037/**
038 * Handle Component as Webservice
039 */
040public final class ComponentHandler extends BasicHandler {
041    
042    private static Map soapServices = new WeakHashMap();
043
044    @Override
045    public void invoke(MessageContext msgContext) throws AxisFault {
046        try {
047            setupService(msgContext);
048        } 
049        catch (Exception e) {
050            throw AxisFault.makeFault(e);
051        }
052    }
053    
054    @Override
055    public void generateWSDL(MessageContext msgContext) throws AxisFault {
056        try {
057            setupService(msgContext);
058        } 
059        catch (Exception e) {
060            throw AxisFault.makeFault(e);
061        }
062    }
063    
064    /**
065     * handle all the work necessary set
066     * up the "proxy" RPC service surrounding it as the MessageContext's
067     * active service.
068     *
069     */ 
070    protected void setupService(MessageContext msgContext) throws Exception {
071        RefBoolean isnew=new RefBooleanImpl(false);
072        Component cfc=(Component) msgContext.getProperty(Constants.COMPONENT);
073        Class clazz=cfc.getJavaAccessClass(isnew);
074        String clazzName=clazz.getName();
075        
076        ClassLoader classLoader=clazz.getClassLoader();
077        Pair pair;
078        SOAPService rpc=null;
079        if(!isnew.toBooleanValue() && (pair = (Pair)soapServices.get(clazzName))!=null) {
080                if(classLoader==pair.classloader)
081                        rpc=pair.rpc;
082        }
083        //else classLoader = clazz.getClassLoader();
084        
085        //print.out("cl:"+classLoader);
086        msgContext.setClassLoader(classLoader);
087        
088        if (rpc == null) {
089            rpc = new SOAPService(new RPCProvider());
090            rpc.setName(clazzName);
091            rpc.setOption(JavaProvider.OPTION_CLASSNAME, clazzName );
092            rpc.setEngine(msgContext.getAxisEngine());
093            
094            rpc.setOption(JavaProvider.OPTION_ALLOWEDMETHODS, "*");
095            rpc.setOption(JavaProvider.OPTION_SCOPE, Scope.REQUEST.getName());
096            rpc.getInitializedServiceDesc(msgContext);
097            soapServices.put(clazzName, new Pair(classLoader,rpc));                
098        }
099        
100        rpc.setEngine(msgContext.getAxisEngine());
101        rpc.init();   // ??
102        msgContext.setService( rpc );
103        
104    }
105    
106    class Pair {
107        private ClassLoader classloader;
108        private SOAPService rpc;
109                public Pair(ClassLoader classloader, SOAPService rpc) {
110                        this.classloader = classloader;
111                        this.rpc = rpc;
112                }
113    }
114}