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 javax.xml.rpc.encoding.TypeMapping; 022 023import lucee.commons.lang.CFTypes; 024import lucee.commons.lang.ExceptionUtil; 025import lucee.runtime.Component; 026import lucee.runtime.PageContext; 027import lucee.runtime.exp.ApplicationException; 028import lucee.runtime.exp.PageException; 029import lucee.runtime.net.rpc.AxisCaster; 030import lucee.runtime.net.rpc.TypeMappingUtil; 031import lucee.runtime.op.Caster; 032import lucee.runtime.type.Collection.Key; 033import lucee.runtime.type.FunctionArgument; 034import lucee.runtime.type.UDF; 035 036import org.apache.axis.AxisFault; 037import org.apache.axis.MessageContext; 038 039/** 040 * 041 */ 042public final class ComponentController { 043 044 private static ThreadLocal<Component> component=new ThreadLocal<Component>(); 045 private static ThreadLocal<PageContext> pagecontext=new ThreadLocal<PageContext>(); 046 private static ThreadLocal<MessageContext> messageContext=new ThreadLocal<MessageContext>(); 047 048 /** 049 * invokes thread local component 050 * @param name 051 * @param args 052 * @return 053 * @throws AxisFault 054 * @throws PageException 055 */ 056 public static Object invoke(String name, Object[] args) throws AxisFault { 057 try { 058 return _invoke(name, args); 059 } 060 catch (Throwable t) { 061 ExceptionUtil.rethrowIfNecessary(t); 062 throw AxisFault.makeFault((Caster.toPageException(t))); 063 } 064 } 065 private static Object _invoke(String name, Object[] args) throws PageException { 066 Key key = Caster.toKey(name); 067 Component c=component.get(); 068 PageContext p=pagecontext.get(); 069 MessageContext mc = messageContext.get(); 070 if(c==null) throw new ApplicationException("missing component"); 071 if(p==null) throw new ApplicationException("missing pagecontext"); 072 073 UDF udf = Caster.toFunction(c.get(p,key,null),null); 074 FunctionArgument[] fa=null; 075 if(udf!=null) fa = udf.getFunctionArguments(); 076 077 for(int i=0;i<args.length;i++) { 078 if(fa!=null && i<fa.length && fa[i].getType()==CFTypes.TYPE_UNKNOW) { 079 args[i]=AxisCaster.toLuceeType(p,fa[i].getTypeAsString(),args[i]); 080 } 081 else 082 args[i]=AxisCaster.toLuceeType(p,args[i]); 083 } 084 085 086 // return type 087 String rtnType=udf!=null?udf.getReturnTypeAsString():"any"; 088 089 090 Object rtn = c.call(p, key, args); 091 092 // cast return value to Axis type 093 try { 094 RPCServer server = RPCServer.getInstance(p.getId(),p.getServletContext()); 095 TypeMapping tm = mc!=null?mc.getTypeMapping():TypeMappingUtil.getServerTypeMapping(server.getEngine().getTypeMappingRegistry()); 096 rtn=Caster.castTo(p, rtnType, rtn, false); 097 Class<?> clazz = Caster.cfTypeToClass(rtnType); 098 return AxisCaster.toAxisType(tm,rtn,clazz.getComponentType()!=null?clazz:null); 099 } 100 catch (Throwable t) { 101 ExceptionUtil.rethrowIfNecessary(t); 102 throw Caster.toPageException(t); 103 } 104 } 105 106 /** 107 * removes PageContext and Component 108 * sets component and pageContext to invoke 109 * @param p 110 * @param c 111 */ 112 public static void set(PageContext p,Component c) { 113 pagecontext.set(p); 114 component.set(c); 115 } 116 public static void set(MessageContext mc) { 117 messageContext.set(mc); 118 } 119 120 /** 121 * 122 */ 123 public static void release() { 124 pagecontext.set(null); 125 component.set(null); 126 messageContext.set(null); 127 } 128}