001    package railo.runtime.tag;
002    
003    import railo.commons.lang.StringUtil;
004    import railo.runtime.PageContext;
005    import railo.runtime.exp.ApplicationException;
006    import railo.runtime.exp.PageException;
007    import railo.runtime.ext.tag.BodyTagImpl;
008    import railo.runtime.ext.tag.DynamicAttributes;
009    import railo.runtime.net.proxy.ProxyData;
010    import railo.runtime.net.proxy.ProxyDataImpl;
011    import railo.runtime.net.rpc.client.RPCClient;
012    import railo.runtime.op.Caster;
013    import railo.runtime.type.KeyImpl;
014    import railo.runtime.type.Struct;
015    import railo.runtime.type.StructImpl;
016    import railo.runtime.type.UDF;
017    
018    /*
019     * FUTURE tag invoke
020     * Attributes: servicePort,timeout
021     * */
022    
023    
024    /**
025    * Invokes component methods from within a page or component. 
026    *                       You use this tag to reference a WSDL file and consume a web service from within a block of CFML code.
027    *
028    *
029    *
030    **/
031    public final class Invoke  extends BodyTagImpl implements DynamicAttributes {
032    
033            private Struct data=new StructImpl(StructImpl.TYPE_LINKED);
034            //private Map attributes = new HashTable();
035            //private HashSet keys = new HashSet();
036            
037            private boolean hasBody;
038            
039            private Object component;
040            private String method;
041            private String returnvariable;
042            private String username;
043            private String password;
044            private String webservice;
045            private int timeout=-1;
046            private String serviceport;
047            private ProxyData proxy=new ProxyDataImpl();
048    
049    
050            @Override
051            public void release()   {
052                    super.release();
053                    data.clear();
054                    component=null;
055                    method=null;
056                    returnvariable=null;
057                    username=null;
058                    password=null;
059                    webservice=null;
060                    timeout=-1;
061                    serviceport=null;
062                    proxy.release();
063            }
064    
065    
066            /**
067             * @param component the component to set
068             */
069            public void setComponent(Object component) {
070                    this.component = component;
071            }
072    
073    
074            /**
075             * @param method the method to set
076             */
077            public void setMethod(String method) {
078                    this.method = method;
079            }
080    
081    
082            /**
083             * @param password the password to set
084             */
085            public void setPassword(String password) {
086                    this.password = password;
087            }
088    
089            /**
090             * @param proxyserver the proxyserver to set
091             */
092            public void setProxyserver(String proxyserver) {
093                    proxy.setServer(proxyserver);
094            }
095    
096            /**
097             * @param proxyport the proxyport to set
098             */
099            public void setProxyport(double proxyport) {
100                    proxy.setPort((int)proxyport);
101            }
102    
103            /**
104             * @param proxyuser the proxyuser to set
105             */
106            public void setProxyuser(String proxyuser) {
107                    proxy.setUsername(proxyuser);
108            }
109    
110            /**
111             * @param proxypassword the proxypassword to set
112             */
113            public void setProxypassword(String proxypassword) {
114                    proxy.setPassword(proxypassword);
115            }
116    
117            /**
118             * @param returnvariable the returnvariable to set
119             */
120            public void setReturnvariable(String returnvariable) {
121                    this.returnvariable = returnvariable.trim();
122            }
123    
124    
125            /**
126             * @param serviceport the serviceport to set
127             */
128            public void setServiceport(String serviceport) {
129                    this.serviceport = serviceport;
130            }
131    
132    
133            /**
134             * @param timeout the timeout to set
135             */
136            public void setTimeout(double timeout) {
137                    this.timeout = (int) timeout;
138            }
139    
140    
141            /**
142             * @param username the username to set
143             */
144            public void setUsername(String username) {
145                    this.username = username;
146            }
147    
148    
149            /**
150             * @param webservice the webservice to set
151             */
152            public void setWebservice(String webservice) {
153                    this.webservice = webservice.trim();
154            }
155            
156            @Override
157            public void setDynamicAttribute(String uri, String localName, Object value) {
158                    setDynamicAttribute(uri, KeyImpl.init(localName), value);
159            }
160            
161            @Override
162            public void setDynamicAttribute(String uri, railo.runtime.type.Collection.Key localName, Object value) {
163                    data.setEL(localName, value);
164            }
165    
166    
167            @Override
168            public int doStartTag() throws PageException    {
169                return EVAL_BODY_INCLUDE;
170            }
171    
172            @Override
173            public int doEndTag() throws PageException      {
174                    // CFC
175                    if(component!=null){
176                            doComponent(component);
177                    }
178                    // Webservice
179                    else if(!StringUtil.isEmpty(webservice)){
180                            doWebService(webservice);
181                    }
182                    // call active cfc or component
183                    else {
184                doFunction(pageContext);
185            }
186                    return EVAL_PAGE;
187            }
188    
189    
190    
191            /**
192             * @param oComponent
193             * @throws PageException
194             */
195            private void doComponent(Object oComponent) throws PageException {
196                    railo.runtime.Component component=null;
197                    if(oComponent instanceof railo.runtime.Component)
198                            component=(railo.runtime.Component)oComponent;
199                    else
200                            component=pageContext.loadComponent(Caster.toString(oComponent));
201                            
202                    // execute
203                    Object rtn=component.callWithNamedValues(pageContext,method,data);
204                    
205                    // return 
206                    if(!StringUtil.isEmpty(returnvariable)) pageContext.setVariable(returnvariable,rtn);
207            }
208            
209            private void doFunction(PageContext pc) throws PageException {
210                            
211                    // execute
212                    if(StringUtil.isEmpty(method,true))
213                            throw new ApplicationException("Attribute [method] for tag [invoke] is required in this context.");
214                    
215                    Object oUDF=pc.getVariable(method);
216                    if(!(oUDF instanceof UDF))throw new ApplicationException("there is no function with name "+method); 
217                    Object rtn = ((UDF)oUDF).callWithNamedValues(pageContext, data, false);
218                    
219                    
220                    // return 
221                    if(!StringUtil.isEmpty(returnvariable)) pageContext.setVariable(returnvariable,rtn);
222            }
223    
224            /**
225             * @param webservice
226             * @throws PageException
227             */
228            private void doWebService(String webservice) throws PageException {
229            if(username!=null)   {
230                if(password==null)password = "";
231            }
232            ProxyData pd=StringUtil.isEmpty(proxy.getServer())?null:proxy;
233            RPCClient ws = username!=null?new RPCClient(webservice,username,password,pd):new RPCClient(webservice,pd);
234            Object rtn = ws.callWithNamedValues(pageContext,method,data);
235            
236            // return
237            if(!StringUtil.isEmpty(returnvariable)) pageContext.setVariable(returnvariable,rtn);
238            
239            //throw new ApplicationException("type webservice is not yet implemented for tag invoke");
240            }
241    
242            /**
243             * @param name
244             * @param value
245             * @throws PageException
246             */
247            public void setArgument(String name,Object value) throws PageException {
248                    data.set(name,value);           
249            }
250            
251            /**
252             * sets if taf has a body or not
253             * @param hasBody
254             */
255            public void hasBody(boolean hasBody) {
256                    this.hasBody=hasBody;
257            }
258    
259    }