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 **/ 019package lucee.runtime.concurrency; 020 021import java.io.ByteArrayInputStream; 022import java.io.ByteArrayOutputStream; 023import java.nio.charset.Charset; 024import java.util.concurrent.Callable; 025 026import lucee.commons.io.IOUtil; 027import lucee.commons.lang.ExceptionUtil; 028import lucee.runtime.PageContext; 029import lucee.runtime.PageContextImpl; 030import lucee.runtime.config.ConfigImpl; 031import lucee.runtime.engine.ThreadLocalPageContext; 032import lucee.runtime.exp.PageException; 033import lucee.runtime.net.http.HttpServletResponseDummy; 034import lucee.runtime.net.http.ReqRspUtil; 035import lucee.runtime.thread.ThreadUtil; 036import lucee.runtime.type.Struct; 037import lucee.runtime.type.UDF; 038 039public class UDFCaller2<P> implements Callable<Data<P>> { 040 041 private PageContext parent; 042 private PageContextImpl pc; 043 private ByteArrayOutputStream baos; 044 045 private UDF udf; 046 private boolean doIncludePath; 047 private Object[] arguments; 048 private Struct namedArguments; 049 private P passed; 050 051 052 private UDFCaller2(PageContext parent) { 053 this.parent = parent; 054 this.baos = new ByteArrayOutputStream(); 055 this.pc=ThreadUtil.clonePageContext(parent, baos, false, false, true); 056 } 057 058 public UDFCaller2(PageContext parent, UDF udf, Object[] arguments,P passed, boolean doIncludePath) { 059 this(parent); 060 this.udf=udf; 061 this.arguments=arguments; 062 this.doIncludePath=doIncludePath; 063 this.passed=passed; 064 } 065 public UDFCaller2(PageContext parent, UDF udf,Struct namedArguments, P passed,boolean doIncludePath) { 066 this(parent); 067 this.udf=udf; 068 this.namedArguments=namedArguments; 069 this.doIncludePath=doIncludePath; 070 this.passed=passed; 071 } 072 073 074 075 public final Data<P> call() throws PageException { 076 ThreadLocalPageContext.register(pc); 077 pc.getRootOut().setAllowCompression(false); // make sure content is not compressed 078 String str=null; 079 Object result=null; 080 try{ 081 if(namedArguments!=null) result=udf.callWithNamedValues(pc, namedArguments, doIncludePath); 082 else result=udf.call(pc, arguments, doIncludePath); 083 084 } 085 finally{ 086 try { 087 HttpServletResponseDummy rsp=(HttpServletResponseDummy) pc.getHttpServletResponse(); 088 089 Charset cs = ReqRspUtil.getCharacterEncoding(pc,rsp); 090 //if(enc==null) enc="ISO-8859-1"; 091 092 pc.getOut().flush(); //make sure content is flushed 093 094 ((ConfigImpl)pc.getConfig()).getFactory().releasePageContext(pc); 095 str=IOUtil.toString((new ByteArrayInputStream(baos.toByteArray())), cs); // TODO add support for none string content 096 } 097 catch (Throwable e) { 098 ExceptionUtil.rethrowIfNecessary(e); 099 // TODO Auto-generated catch block 100 e.printStackTrace(); 101 } 102 } 103 return new Data<P>(str,result,passed); 104 } 105}