package railo.runtime.op;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import railo.commons.date.DateTimeUtil;
import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.Pair;
import railo.loader.engine.CFMLEngine;
import railo.runtime.CFMLFactoryImpl;
import railo.runtime.Component;
import railo.runtime.PageContext;
import railo.runtime.config.Config;
import railo.runtime.config.RemoteClient;
import railo.runtime.db.DatasourceConnection;
import railo.runtime.db.SQL;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.functions.system.ContractPath;
import railo.runtime.net.http.HttpServletRequestDummy;
import railo.runtime.net.http.HttpServletResponseDummy;
import railo.runtime.spooler.ExecutionPlan;
import railo.runtime.spooler.SpoolerTask;
import railo.runtime.spooler.remote.RemoteClientTask;
import railo.runtime.text.xml.XMLUtil;
import railo.runtime.type.Array;
import railo.runtime.type.ArrayImpl;
import railo.runtime.type.Collection;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Query;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.Date;
import railo.runtime.type.dt.DateImpl;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.dt.Time;
import railo.runtime.type.dt.TimeImpl;
import railo.runtime.type.dt.TimeSpan;
import railo.runtime.type.dt.TimeSpanImpl;
import railo.runtime.type.scope.ClusterEntry;
import railo.runtime.type.scope.ClusterEntryImpl;
import railo.runtime.type.util.ListUtil;
import railo.runtime.util.Creation;
/**
* implemention of the ctration object
*/
public final class CreationImpl implements Creation,Serializable {
private static CreationImpl singelton;
private CreationImpl(CFMLEngine engine) {
// !!! do not store engine Object, the engine is not serializable
}
/**
* @return singleton instance
*/
public static Creation getInstance(CFMLEngine engine) {
if(singelton==null)singelton=new CreationImpl(engine);
return singelton;
}
@Override
public Array createArray() {
return new ArrayImpl();
}
@Override
public Array createArray(String list, String delimiter,boolean removeEmptyItem, boolean trim) {
if(removeEmptyItem)return ListUtil.listToArrayRemoveEmpty(list, delimiter);
if(trim)return ListUtil.listToArrayTrim(list, delimiter);
return ListUtil.listToArray(list, delimiter);
}
@Override
public Array createArray(int dimension) throws PageException {
return new ArrayImpl(dimension);
}
@Override
public Struct createStruct() {
return new StructImpl();
}
@Override
public Struct createStruct(int type) {
return new StructImpl(type);
}
@Override
public Query createQuery(String[] columns, int rows, String name) {
return new QueryImpl(columns,rows,name);
}
@Override
public Query createQuery(Collection.Key[] columns, int rows, String name) throws DatabaseException {
return new QueryImpl(columns,rows,name);
}
@Override
public Query createQuery(DatasourceConnection dc, SQL sql, int maxrow, String name) throws PageException {
return new QueryImpl(ThreadLocalPageContext.get(),dc,sql,maxrow,-1,-1,name);
}
public Query createQuery(DatasourceConnection dc, SQL sql, int maxrow, int fetchsize, int timeout, String name) throws PageException {
return new QueryImpl(ThreadLocalPageContext.get(),dc,sql,maxrow,fetchsize,timeout,name);
}
@Override
public DateTime createDateTime(long time) {
return new DateTimeImpl(time,false);
}
@Override
public TimeSpan createTimeSpan(int day,int hour,int minute,int second) {
return new TimeSpanImpl(day,hour,minute,second);
}
@Override
public Date createDate(long time) {
return new DateImpl(time);
}
@Override
public Time createTime(long time) {
return new TimeImpl(time,false);
}
@Override
public DateTime createDateTime(int year, int month, int day, int hour, int minute, int second, int millis) throws ExpressionException {
return DateTimeUtil.getInstance().toDateTime(ThreadLocalPageContext.getTimeZone(),year,month,day,hour,minute,second,millis);
}
@Override
public Date createDate(int year, int month, int day) throws ExpressionException {
return new DateImpl(DateTimeUtil.getInstance().toDateTime(null,year,month,day, 0, 0, 0,0));
}
@Override
public Time createTime(int hour, int minute, int second, int millis) {
return new TimeImpl(
DateTimeUtil.getInstance().toTime(null,1899,12,30,hour,minute,second,millis,0),false);
}
@Override
public Document createDocument() throws PageException {
try {
return XMLUtil.newDocument();
} catch (Exception e) {
throw Caster.toPageException(e);
}
}
@Override
public Document createDocument(Resource res, boolean isHTML) throws PageException {
InputStream is=null;
try {
return XMLUtil.parse(new InputSource(is=res.getInputStream()),null,isHTML);
} catch (Exception e) {
throw Caster.toPageException(e);
}
finally {
IOUtil.closeEL(is);
}
}
@Override
public Document createDocument(String xml, boolean isHTML) throws PageException {
try {
return XMLUtil.parse(XMLUtil.toInputSource(null, xml),null,isHTML);
} catch (Exception e) {
throw Caster.toPageException(e);
}
}
@Override
public Document createDocument(InputStream is, boolean isHTML) throws PageException {
try {
return XMLUtil.parse(new InputSource(is),null,isHTML);
} catch (Exception e) {
throw Caster.toPageException(e);
}
}
@Override
public Key createKey(String key) {
return KeyImpl.init(key);
}
public SpoolerTask createRemoteClientTask(ExecutionPlan[] plans,RemoteClient remoteClient,Struct attrColl,String callerId, String type) {
return new RemoteClientTask(plans,remoteClient,attrColl,callerId, type);
}
public ClusterEntry createClusterEntry(Key key,Serializable value, int offset) {
return new ClusterEntryImpl(key,value,offset);
}
public Resource createResource(String path, boolean existing) throws PageException {
if(existing)return ResourceUtil.toResourceExisting(ThreadLocalPageContext.get(), path);
return ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), path);
}
public HttpServletRequest createHttpServletRequest(File contextRoot,String serverName, String scriptName,String queryString,
Cookie[] cookies, Map<String,Object> headers, Map<String, String> parameters, Map<String,Object> attributes, HttpSession session) {
// header
Pair<String,Object>[] _headers=new Pair[headers.size()];
{
int index=0;
Iterator<Entry<String, Object>> it = headers.entrySet().iterator();
Entry<String, Object> entry;
while(it.hasNext()){
entry = it.next();
_headers[index++]=new Pair<String,Object>(entry.getKey(), entry.getValue());
}
}
// parameters
Pair<String,Object>[] _parameters=new Pair[headers.size()];
{
int index=0;
Iterator<Entry<String, String>> it = parameters.entrySet().iterator();
Entry<String, String> entry;
while(it.hasNext()){
entry = it.next();
_parameters[index++]=new Pair<String,Object>(entry.getKey(), entry.getValue());
}
}
return new HttpServletRequestDummy(ResourceUtil.toResource(contextRoot), serverName, scriptName, queryString, cookies,
_headers, _parameters, Caster.toStruct(attributes,null), session);
}
public HttpServletResponse createHttpServletResponse(OutputStream io) {
return new HttpServletResponseDummy(io);
}
@Override
public PageContext createPageContext(HttpServletRequest req, HttpServletResponse rsp, OutputStream out) {
Config config = ThreadLocalPageContext.getConfig();
return (PageContext) ((CFMLFactoryImpl)config.getFactory()).getPageContext(config.getFactory().getServlet(), req, rsp, null, false, -1, false);
}
@Override
public Component createComponentFromName(PageContext pc, String fullName) throws PageException {
return pc.loadComponent(fullName);
}
@Override
public Component createComponentFromPath(PageContext pc, String path) throws PageException {
path=path.trim();
String pathContracted=ContractPath.call(pc, path);
if(pathContracted.toLowerCase().endsWith(".cfc"))
pathContracted=pathContracted.substring(0,pathContracted.length()-4);
pathContracted=pathContracted
.replace(File.pathSeparatorChar, '.')
.replace('/', '.')
.replace('\\', '.');
while(pathContracted.toLowerCase().startsWith("."))
pathContracted=pathContracted.substring(1);
return createComponentFromName(pc, pathContracted);
}
}