001    package railo.commons.io.res.type.cfml;
002    import java.io.IOException;
003    import java.util.Iterator;
004    import java.util.Map;
005    
006    import railo.print;
007    import railo.commons.io.res.Resource;
008    import railo.commons.io.res.ResourceProvider;
009    import railo.commons.io.res.Resources;
010    import railo.commons.io.res.util.ResourceLockImpl;
011    import railo.commons.io.res.util.ResourceUtil;
012    import railo.commons.lang.StringUtil;
013    import railo.runtime.Component;
014    import railo.runtime.PageContext;
015    import railo.runtime.component.ComponentLoader;
016    import railo.runtime.engine.ThreadLocalPageContext;
017    import railo.runtime.exp.ApplicationException;
018    import railo.runtime.exp.PageException;
019    import railo.runtime.exp.PageRuntimeException;
020    import railo.runtime.functions.other.CreateDynamicProxy;
021    import railo.runtime.functions.other.CreateObject;
022    import railo.runtime.op.Caster;
023    import railo.runtime.type.Array;
024    
025    public class CFMLResourceProvider implements ResourceProvider {
026    
027            private static final Object[] ZERO_ARGS = new Object[0];
028            
029            private int lockTimeout=20000;
030            private final ResourceLockImpl lock=new ResourceLockImpl(lockTimeout,false);
031            private String scheme;
032            private Map args;
033            //private ResourceProvider provider;
034            private Resources resources;
035    
036            private String cfcPath;
037    
038            private Component component;
039    
040            private boolean useStreams=false;
041     
042            
043    
044            @Override
045            public ResourceProvider init(String scheme, Map args) {
046                    this.scheme=scheme;
047                    this.args=args;
048                    
049                    // CFC Path
050                    cfcPath=Caster.toString(args.get("cfc"),null);
051                    if(StringUtil.isEmpty(cfcPath,true))
052                            cfcPath=Caster.toString(args.get("component"),null);
053                    
054                    // use Streams for data
055                    Boolean _useStreams = Caster.toBoolean(args.get("use-streams"),null);
056                    if(_useStreams==null)_useStreams = Caster.toBoolean(args.get("usestreams"),null);
057                    
058                    if(_useStreams!=null)useStreams=_useStreams.booleanValue();
059                    
060                    return this;
061            }
062    
063            @Override
064            public Resource getResource(String path) {
065                    path=ResourceUtil.removeScheme(scheme,path);
066                    path=ResourceUtil.prettifyPath(path);
067                    if(!StringUtil.startsWith(path,'/'))path="/"+path;
068                    return callResourceRTE(null, null, "getResource", new Object[]{path},false);
069            }
070    
071            @Override
072            public String getScheme() {
073                    return scheme;
074            }
075    
076            @Override
077            public Map getArguments() {
078                    return args;
079            }
080    
081            @Override
082            public void setResources(Resources resources) {
083                    this.resources=resources;
084            }
085    
086    
087            @Override
088            public boolean isCaseSensitive() {
089                    return callbooleanRTE(null,null, "isCaseSensitive", ZERO_ARGS);
090            }
091    
092            @Override
093            public boolean isModeSupported() {
094                    return callbooleanRTE(null,null, "isModeSupported", ZERO_ARGS);
095            }
096    
097            @Override
098            public boolean isAttributesSupported() {
099                    return callbooleanRTE(null,null, "isAttributesSupported", ZERO_ARGS);
100            }
101            
102            public int getLockTimeout() {
103                    return lockTimeout;
104            }
105            
106            
107            
108            @Override
109            public void lock(Resource res) throws IOException {
110                    lock.lock(res);
111            }
112    
113            @Override
114            public void unlock(Resource res) {
115                    lock.unlock(res);
116            }
117    
118            @Override
119            public void read(Resource res) throws IOException {
120                    lock.read(res);
121            }
122    
123            public boolean isUseStreams() {
124                    return useStreams;
125            }
126            
127            
128            Resource callResourceRTE(PageContext pc,Component cfc,String methodName, Object[] args, boolean allowNull) {
129                    pc = ThreadLocalPageContext.get(pc);
130                    try {
131                            Object res = call(pc,getCFC(pc,cfc), methodName, args);
132                            if(allowNull && res==null) return null;
133                            return new CFMLResource(this,Caster.toComponent(res));
134                    } 
135                    catch (PageException pe) {pe.printStackTrace();
136                            throw new PageRuntimeException(pe);
137                    } 
138            }
139    
140            Resource[] callResourceArrayRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
141                    pc = ThreadLocalPageContext.get(pc);
142                    try {
143                            Array arr = Caster.toArray(call(pc,getCFC(pc,cfc), methodName, args));
144                            Iterator<Object> it = arr.valueIterator();
145                            CFMLResource[] resources=new CFMLResource[arr.size()];
146                            int index=0;
147                            while(it.hasNext()){
148                                    resources[index++]=new CFMLResource(this,Caster.toComponent(it.next()));
149                            }
150                            return resources;
151                    } 
152                    catch (PageException pe) {
153                            throw new PageRuntimeException(pe);
154                    }
155            }
156            
157    
158            int callintRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
159                    try {
160                            return callint(pc,cfc, methodName, args);
161                    } 
162                    catch (PageException pe) {
163                            throw new PageRuntimeException(pe);
164                    }
165            }
166            int callint(PageContext pc,Component cfc,String methodName, Object[] args) throws PageException {
167                    return Caster.toIntValue(call(pc,cfc,methodName, args));
168            }
169    
170            long calllongRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
171                    try {
172                            return calllong(pc,cfc, methodName, args);
173                    } 
174                    catch (PageException pe) {
175                            throw new PageRuntimeException(pe);
176                    }
177            }
178            long calllong(PageContext pc,Component cfc,String methodName, Object[] args) throws PageException {
179                    return Caster.toLongValue(call(pc,cfc,methodName, args));
180            }
181            
182            boolean callbooleanRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
183                    try {
184                            return callboolean(pc,cfc, methodName, args);
185                    } 
186                    catch (PageException pe) {
187                            throw new PageRuntimeException(pe);
188                    }
189            }
190            boolean callboolean(PageContext pc,Component cfc,String methodName, Object[] args) throws PageException {
191                    return Caster.toBooleanValue(call(pc,cfc,methodName, args));
192            }
193    
194            String callStringRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
195                    try {
196                            return Caster.toString(call(pc,cfc,methodName, args));
197                    } 
198                    catch (PageException pe) {
199                            throw new PageRuntimeException(pe);
200                    }
201            }
202    
203            String callString(PageContext pc,Component cfc,String methodName, Object[] args) throws PageException {
204                    return Caster.toString(call(pc,cfc,methodName, args));
205            }
206    
207            Object callRTE(PageContext pc,Component cfc,String methodName, Object[] args) {
208                    try {
209                            return call(pc,cfc,methodName, args);
210                    } 
211                    catch (PageException pe) {
212                            throw new PageRuntimeException(pe);
213                    }
214            }
215    
216            Object call(PageContext pc,Component cfc,String methodName, Object[] args) throws PageException {
217                    pc = ThreadLocalPageContext.get(pc);
218                    return getCFC(pc, cfc).call(pc, methodName, args);
219            }
220    
221            private Component getCFC(PageContext pc,Component cfc) throws PageException {
222                    if(cfc!=null) return cfc;
223                    
224                    if(component!=null) return component;
225                    
226                    if(StringUtil.isEmpty(cfcPath,true))throw new ApplicationException("you need to define the argument [component] for the [CFMLResourceProvider]");
227                    cfcPath=cfcPath.trim();
228                    component=pc.loadComponent(cfcPath);
229                    call(pc, component, "init", new Object[]{scheme,Caster.toStruct(args)});
230                    
231                    return component;
232            }
233    
234    }