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