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 **/
019/**
020 * Implements the CFML Function createobject
021 * FUTURE neue attr unterstuetzen
022 */
023package lucee.runtime.functions.other;
024
025import java.util.ArrayList;
026import java.util.Iterator;
027
028import lucee.commons.io.res.Resource;
029import lucee.commons.io.res.util.ResourceUtil;
030import lucee.commons.lang.ClassException;
031import lucee.commons.lang.ClassUtil;
032import lucee.commons.lang.StringUtil;
033import lucee.runtime.Component;
034import lucee.runtime.PageContext;
035import lucee.runtime.PageContextImpl;
036import lucee.runtime.com.COMObject;
037import lucee.runtime.exp.ExpressionException;
038import lucee.runtime.exp.FunctionNotSupported;
039import lucee.runtime.exp.PageException;
040import lucee.runtime.exp.SecurityException;
041import lucee.runtime.ext.function.Function;
042import lucee.runtime.java.JavaObject;
043import lucee.runtime.net.http.HTTPClient;
044import lucee.runtime.net.proxy.ProxyData;
045import lucee.runtime.net.proxy.ProxyDataImpl;
046import lucee.runtime.net.rpc.client.WSClient;
047import lucee.runtime.op.Caster;
048import lucee.runtime.op.Decision;
049import lucee.runtime.security.SecurityManager;
050import lucee.runtime.type.Array;
051import lucee.runtime.type.Struct;
052import lucee.runtime.type.util.ListUtil;
053
054public final class CreateObject implements Function {
055        public static Object call(PageContext pc , String cfcName) throws PageException {
056                return call(pc,"component",cfcName,null,null);
057        }
058        public static Object call(PageContext pc , String type, String className) throws PageException {
059                return call(pc,type,className,null,null);
060        }
061        public static Object call(PageContext pc , String type, String className, Object context) throws PageException {
062                return call(pc,type,className,context,null);
063        }
064        public static Object call(PageContext pc , String type, String className, Object context, Object serverName) throws PageException {
065                type=StringUtil.toLowerCase(type);
066                
067                
068                // JAVA
069                        if(type.equals("java")) {
070                            checkAccess(pc,type);
071                                return doJava(pc, className, context, Caster.toString(serverName));
072                        }
073                // COM
074                        if(type.equals("com")) {
075                                return doCOM(pc,className);
076                        }
077        // Component
078            if(type.equals("component") || type.equals("cfc")) {
079                return doComponent(pc,className);
080            }
081        // Webservice
082            if(type.equals("webservice") || type.equals("wsdl")) {
083                String user=null;
084                String pass=null;
085                ProxyDataImpl proxy=null;
086                if(context!=null){
087                        Struct args=(serverName!=null)?Caster.toStruct(serverName):Caster.toStruct(context);
088                        // basic security
089                        user=Caster.toString(args.get("username",null));
090                        pass=Caster.toString(args.get("password",null));
091                        
092                        // proxy
093                        String proxyServer=Caster.toString(args.get("proxyServer",null));
094                        String proxyPort=Caster.toString(args.get("proxyPort",null));
095                        String proxyUser=Caster.toString(args.get("proxyUser",null));
096                        if(StringUtil.isEmpty(proxyUser)) proxyUser=Caster.toString(args.get("proxyUsername",null));
097                        String proxyPassword=Caster.toString(args.get("proxyPassword",null));
098                        
099                        if(!StringUtil.isEmpty(proxyServer)){
100                                proxy=new ProxyDataImpl(proxyServer,Caster.toIntValue(proxyPort,-1),proxyUser,proxyPassword);
101                        }                       
102                        
103                }
104                return doWebService(pc,className,user,pass,proxy);
105            }
106            if(type.equals("http")) {
107                String user=null;
108                String pass=null;
109                ProxyDataImpl proxy=null;
110                if(context!=null){
111                        Struct args=(serverName!=null)?Caster.toStruct(serverName):Caster.toStruct(context);
112                        // basic security
113                        user=Caster.toString(args.get("username",null));
114                        pass=Caster.toString(args.get("password",null));
115                        
116                        // proxy
117                        String proxyServer=Caster.toString(args.get("proxyServer",null));
118                        String proxyPort=Caster.toString(args.get("proxyPort",null));
119                        String proxyUser=Caster.toString(args.get("proxyUser",null));
120                        if(StringUtil.isEmpty(proxyUser)) proxyUser=Caster.toString(args.get("proxyUsername",null));
121                        String proxyPassword=Caster.toString(args.get("proxyPassword",null));
122                        
123                        if(!StringUtil.isEmpty(proxyServer)){
124                                proxy=new ProxyDataImpl(proxyServer,Caster.toIntValue(proxyPort,-1),proxyUser,proxyPassword);
125                        }                       
126                        
127                }
128                return doHTTP(pc,className,user,pass,proxy);
129            }
130        // .net
131            if(type.equals(".net") || type.equals("dotnet")) {
132                return doDotNet(pc,className);
133            }
134                        throw new ExpressionException("invalid argument for function createObject, first argument (type), " +
135                                        "must be (com, java, webservice or component) other types are not supported");
136                
137        } 
138
139    private static Object doDotNet(PageContext pc, String className) throws FunctionNotSupported {
140        throw new FunctionNotSupported("CreateObject","type .net");
141        }
142        private static void checkAccess(PageContext pc, String type) throws SecurityException {
143        if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_TAG_OBJECT)==SecurityManager.VALUE_NO) 
144                        throw new SecurityException("can't access function [createObject] with type ["+type+"]","access is prohibited by security manager");
145                
146    }
147        
148         
149    public static Object doJava(PageContext pc, String className, Object paths, String delimiter) throws PageException {
150        if(pc.getConfig().getSecurityManager().getAccess(SecurityManager.TYPE_DIRECT_JAVA_ACCESS)==SecurityManager.VALUE_YES) {
151                PageContextImpl pci = (PageContextImpl)pc;
152                java.util.List<Resource> resources=new ArrayList<Resource>();
153                
154                // get java settings from application.cfc
155                //java.util.List<Resource> resources=getJavaSettings(pc);
156                
157                // load resources
158                if (paths instanceof String) {
159
160                        String strp = ((String)paths).trim();
161                        if(!strp.isEmpty()) {
162
163                                if(StringUtil.isEmpty(delimiter))delimiter=",";
164                                String[] arrPaths = ListUtil.trimItems(ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty( strp, delimiter ) ));
165
166                                for(int i=0;i<arrPaths.length;i++) {
167                                        resources.add(ResourceUtil.toResourceExisting(pc,arrPaths[i]));
168                                }
169                        }
170                }
171                else if (Decision.isArray( paths )) {
172
173                                Array arrp = Caster.toArray(paths);
174                        Iterator it = arrp.valueIterator();
175                        while (it.hasNext()) {
176                                resources.add(ResourceUtil.toResourceExisting(pc, Caster.toString( it.next() )));
177                        }
178                }
179                
180                // load class
181                try     {
182                        ClassLoader cl = resources.size()==0?pci.getClassLoader():pci.getClassLoader(resources.toArray(new Resource[resources.size()]));
183                        Class clazz=null;
184                        try{
185                                clazz = ClassUtil.loadClass(cl,className);
186                        }
187                        catch(ClassException ce) {
188                                // try java.lang if no package definition
189                                if(className.indexOf('.')==-1) {
190                                        try{
191                                        clazz = ClassUtil.loadClass(cl,"java.lang."+className);
192                                }
193                                catch(ClassException e) {
194                                        throw ce;
195                                }
196                                }
197                                    else throw ce;
198                        }
199                        
200                        return new JavaObject((pc).getVariableUtil(),clazz);
201                } 
202                        catch (Exception e) {
203                                throw Caster.toPageException(e);
204                        }
205        }
206        throw new SecurityException("can't create Java Object ["+className+"], direct java access is deinied by security manager");
207        } 
208    
209    /*public static java.util.List<Resource> getJavaSettings(PageContext pc) {
210        java.util.List<Resource> resources=new ArrayList<Resource>();
211        
212        // get Resources from application context
213        JavaSettings settings=pc.getApplicationContext().getJavaSettings();
214        Resource[] _resources = settings==null?null:settings.getResources();
215        if(_resources!=null)for(int i=0;i<_resources.length;i++){
216                resources.add(ResourceUtil.getCanonicalResourceEL(_resources[i]));
217        }
218        
219                return resources;
220        }*/
221    
222        public static Object doCOM(PageContext pc,String className) {
223                return new COMObject(className);
224        } 
225    
226    public static Component doComponent(PageContext pc,String className) throws PageException {
227        
228        return pc.loadComponent(className);
229    } 
230    
231    public static Object doWebService(PageContext pc,String wsdlUrl) throws PageException {
232        // TODO CF8 impl. all new attributes for wsdl
233        return WSClient.getInstance(pc, wsdlUrl, null, null, null);
234    } 
235
236    public static Object doWebService(PageContext pc,String wsdlUrl,String username,String password, ProxyData proxy) throws PageException {
237        // TODO CF8 impl. all new attributes for wsdl
238        return WSClient.getInstance(pc,wsdlUrl,username,password,proxy);
239    } 
240    public static Object doHTTP(PageContext pc,String httpUrl) throws PageException {
241        return new HTTPClient(httpUrl,null,null,null);
242    } 
243    public static Object doHTTP(PageContext pc,String httpUrl,String username,String password, ProxyData proxy) throws PageException {
244        return new HTTPClient(httpUrl,username,password,proxy);
245    } 
246}