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 }