Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
play.templates.GroovyTemplate Maven / Gradle / Ivy
package play.templates;
import com.jamonapi.Monitor;
import com.jamonapi.MonitorFactory;
import groovy.lang.*;
import org.apache.commons.io.FileUtils;
import org.codehaus.groovy.control.*;
import org.codehaus.groovy.control.CompilationUnit.GroovyClassOperation;
import org.codehaus.groovy.control.messages.ExceptionMessage;
import org.codehaus.groovy.control.messages.Message;
import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.tools.GroovyClass;
import play.Logger;
import play.Play;
import play.Play.Mode;
import play.classloading.BytecodeCache;
import play.classloading.enhancers.LocalvariablesNamesEnhancer.LocalVariablesNamesTracer;
import play.data.binding.Unbinder;
import play.exceptions.*;
import play.exceptions.TemplateExecutionException.DoBodyException;
import play.i18n.Lang;
import play.i18n.Messages;
import play.libs.Codec;
import play.mvc.ActionInvoker;
import play.mvc.Http;
import play.mvc.Http.Request;
import play.mvc.Router;
import play.templates.types.SafeCSVFormatter;
import play.templates.types.SafeHTMLFormatter;
import play.templates.types.SafeXMLFormatter;
import play.utils.HTML;
import play.utils.Java;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
* A template
*/
public class GroovyTemplate extends BaseTemplate {
static final Map safeFormatters = new HashMap();
static {
safeFormatters.put("csv", new SafeCSVFormatter());
safeFormatters.put("html", new SafeHTMLFormatter());
safeFormatters.put("xml", new SafeXMLFormatter());
}
public static void registerFormatter(String format, SafeFormatter formatter) {
safeFormatters.put(format, formatter);
}
static {
new GroovyShell().evaluate("java.lang.String.metaClass.if = { condition -> if(condition) delegate; else '' }");
}
public GroovyTemplate(String name, String source) {
super(name, source);
}
public GroovyTemplate(String source) {
super(source);
}
public static class TClassLoader extends GroovyClassLoader {
public TClassLoader() {
super(Play.classloader);
}
public Class defineTemplate(String name, byte[] byteCode) {
return defineClass(name, byteCode, 0, byteCode.length, Play.classloader.protectionDomain);
}
}
@SuppressWarnings("unchecked")
void directLoad(byte[] code) throws Exception {
TClassLoader tClassLoader = new TClassLoader();
String[] lines = new String(code, "utf-8").split("\n");
this.linesMatrix = (HashMap) Java.deserialize(Codec.decodeBASE64(lines[1]));
this.doBodyLines = (HashSet) Java.deserialize(Codec.decodeBASE64(lines[3]));
for (int i = 4; i < lines.length; i = i + 2) {
String className = lines[i];
byte[] byteCode = Codec.decodeBASE64(lines[i + 1]);
Class c = tClassLoader.defineTemplate(className, byteCode);
if (compiledTemplate == null) {
compiledTemplate = c;
}
}
}
/**
* Define the Compiler configuration
* @return the compiler Configuration
*/
protected CompilerConfiguration setUpCompilerConfiguration(){
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.setSourceEncoding("utf-8"); // ouf
return compilerConfiguration;
}
protected void onCompileEnd(){
}
public void compile() {
if (compiledTemplate == null) {
try {
long start = System.currentTimeMillis();
TClassLoader tClassLoader = new TClassLoader();
// Let's compile the groovy source
final List groovyClassesForThisTemplate = new ArrayList();
// ~~~ Please !
CompilerConfiguration compilerConfiguration = this.setUpCompilerConfiguration();
CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration);
compilationUnit.addSource(new SourceUnit(name, compiledSource, compilerConfiguration, tClassLoader, compilationUnit.getErrorCollector()));
Field phasesF = compilationUnit.getClass().getDeclaredField("phaseOperations");
phasesF.setAccessible(true);
LinkedList[] phases = (LinkedList[]) phasesF.get(compilationUnit);
LinkedList output = new LinkedList();
phases[Phases.OUTPUT] = output;
output.add(new GroovyClassOperation() {
public void call(GroovyClass gclass) {
groovyClassesForThisTemplate.add(gclass);
}
});
compilationUnit.compile();
// ouf
// Define script classes
StringBuilder sb = new StringBuilder();
sb.append("LINESMATRIX" + "\n");
sb.append(Codec.encodeBASE64(Java.serialize(linesMatrix)).replaceAll("\\s", ""));
sb.append("\n");
sb.append("DOBODYLINES" + "\n");
sb.append(Codec.encodeBASE64(Java.serialize(doBodyLines)).replaceAll("\\s", ""));
sb.append("\n");
for (GroovyClass gclass : groovyClassesForThisTemplate) {
tClassLoader.defineTemplate(gclass.getName(), gclass.getBytes());
sb.append(gclass.getName());
sb.append("\n");
sb.append(Codec.encodeBASE64(gclass.getBytes()).replaceAll("\\s", ""));
sb.append("\n");
}
// Cache
BytecodeCache.cacheBytecode(sb.toString().getBytes("utf-8"), name, source);
compiledTemplate = tClassLoader.loadClass(groovyClassesForThisTemplate.get(0).getName());
if (System.getProperty("precompile") != null) {
try {
// emit bytecode to standard class layout as well
File f = Play.getFile("precompiled/templates/" + name.replaceAll("\\{(.*)\\}", "from_$1").replace(":", "_").replace("..", "parent"));
f.getParentFile().mkdirs();
FileUtils.write(f, sb.toString(), "utf-8");
} catch (Exception e) {
Logger.warn(e, "Unexpected");
}
}
if (Logger.isTraceEnabled()) {
Logger.trace("%sms to compile template %s to %d classes", System.currentTimeMillis() - start, name, groovyClassesForThisTemplate.size());
}
} catch (MultipleCompilationErrorsException e) {
if (e.getErrorCollector().getLastError() != null) {
Message errorMsg = e.getErrorCollector().getLastError();
if (errorMsg instanceof SyntaxErrorMessage) {
SyntaxErrorMessage errorMessage = (SyntaxErrorMessage) e.getErrorCollector().getLastError();
SyntaxException syntaxException = errorMessage.getCause();
Integer line = this.linesMatrix.get(syntaxException.getLine());
if (line == null) {
line = 0;
}
String message = syntaxException.getMessage();
if (message.indexOf("@") > 0) {
message = message.substring(0, message.lastIndexOf("@"));
}
throw new TemplateCompilationException(this, line, message);
} else{
ExceptionMessage errorMessage = (ExceptionMessage ) e.getErrorCollector().getLastError();
Exception exception = errorMessage.getCause();
Integer line = 0;
String message = exception.getMessage();
throw new TemplateCompilationException(this, line, message);
}
}
throw new UnexpectedException(e);
} catch (Exception e) {
throw new UnexpectedException(e);
} finally{
this.onCompileEnd();
}
}
compiledTemplateName = compiledTemplate.getName();
}
@Override
public String render(Map args) {
try {
return super.render(args);
} finally {
currentTemplate.remove();
}
}
protected Binding setUpBindingVariables(Map args){
Binding binding = new Binding(args);
binding.setVariable("play", new Play());
binding.setVariable("messages", new Messages());
binding.setVariable("lang", Lang.get());
return binding;
}
@Override
protected String internalRender(Map args) {
compile();
Binding binding = this.setUpBindingVariables(args);
// If current response-object is present, add _response_encoding'
Http.Response currentResponse = Http.Response.current();
if (currentResponse != null) {
binding.setVariable("_response_encoding", currentResponse.encoding);
}
StringWriter writer = null;
Boolean applyLayouts = false;
// must check if this is the first template being rendered..
// If this template is called from inside another template,
// then args("out") have already been initialized
if (!args.containsKey("out")) {
// This is the first template being rendered.
// We have to set up the PrintWriter that this (and all sub-templates) are going
// to write the output to..
applyLayouts = true;
layout.set(null);
writer = new StringWriter();
binding.setProperty("out", new PrintWriter(writer));
currentTemplate.set(this);
}
if (!args.containsKey("_body") && !args.containsKey("_isLayout") && !args.containsKey("_isInclude")) {
layoutData.set(new HashMap());
TagContext.init();
}
ExecutableTemplate t = (ExecutableTemplate) InvokerHelper.createScript(compiledTemplate, binding);
t.init(this);
Monitor monitor = null;
try {
monitor = MonitorFactory.start(name);
long start = System.currentTimeMillis();
t.run();
monitor.stop();
monitor = null;
if (Logger.isTraceEnabled()) {
Logger.trace("%sms to render template %s", System.currentTimeMillis() - start, name);
}
} catch (NoRouteFoundException e) {
if (e.isSourceAvailable()) {
throw e;
}
throwException(e);
} catch (PlayException e) {
throw (PlayException) cleanStackTrace(e);
} catch (DoBodyException e) {
if (Play.mode == Mode.DEV) {
compiledTemplate = null;
BytecodeCache.deleteBytecode(name);
}
Throwable ex = e.getCause();
throwException(ex);
} catch (Throwable e) {
if (Play.mode == Mode.DEV) {
compiledTemplate = null;
BytecodeCache.deleteBytecode(name);
}
throwException(e);
} finally {
if (monitor != null) {
monitor.stop();
}
}
if (applyLayouts && layout.get() != null) {
Map layoutArgs = new HashMap(args);
layoutArgs.remove("out");
layoutArgs.put("_isLayout", true);
String layoutR = layout.get().internalRender(layoutArgs);
// Must replace '____%LAYOUT%____' inside the string layoutR with the content from writer..
final String whatToFind = "____%LAYOUT%____";
final int pos = layoutR.indexOf(whatToFind);
if (pos >=0) {
// prepending and appending directly to writer/buffer to prevent us
// from having to duplicate the string.
// this makes us use half of the memory!
writer.getBuffer().insert(0,layoutR.substring(0,pos));
writer.append(layoutR.substring(pos+whatToFind.length()));
return writer.toString().trim();
}
return layoutR;
}
if (writer != null) {
return writer.toString();
}
return null;
}
protected Throwable cleanStackTrace(Throwable e) {
List cleanTrace = new ArrayList();
for (StackTraceElement se : e.getStackTrace()) {
//Here we are parsing the classname to find the file on disk the template was generated from.
//See GroovyTemplateCompiler.head() for more info.
if (se.getClassName().startsWith("Template_")) {
String tn = se.getClassName().substring(9);
if (tn.indexOf("$") > -1) {
tn = tn.substring(0, tn.indexOf("$"));
}
BaseTemplate template = TemplateLoader.templates.get(tn);
if( template != null ) {
Integer line = template.linesMatrix.get(se.getLineNumber());
if (line != null) {
String ext = "";
if (tn.indexOf(".") > -1) {
ext = tn.substring(tn.indexOf(".") + 1);
tn = tn.substring(0, tn.indexOf("."));
}
StackTraceElement nse = new StackTraceElement(TemplateLoader.templates.get(tn).name, ext, "line", line);
cleanTrace.add(nse);
}
}
}
if (!se.getClassName().startsWith("org.codehaus.groovy.") && !se.getClassName().startsWith("groovy.") && !se.getClassName().startsWith("sun.reflect.") && !se.getClassName().startsWith("java.lang.reflect.") && !se.getClassName().startsWith("Template_")) {
cleanTrace.add(se);
}
}
e.setStackTrace(cleanTrace.toArray(new StackTraceElement[cleanTrace.size()]));
return e;
}
/**
* Groovy template
*/
public static abstract class ExecutableTemplate extends Script {
// Leave this field public to allow custom creation of TemplateExecutionException from different pkg
public GroovyTemplate template;
private String extension;
public void init(GroovyTemplate t) {
template = t;
int index = template.name.lastIndexOf(".");
if (index > 0) {
extension = template.name.substring(index + 1);
}
}
@Override
public Object getProperty(String property) {
try {
if (property.equals("actionBridge")) {
return new ActionBridge(this);
}
return super.getProperty(property);
} catch (MissingPropertyException mpe) {
return null;
}
}
public void invokeTag(Integer fromLine, String tag, Map attrs, Closure body) {
String templateName = tag.replace(".", "/");
String callerExtension = (extension != null) ? extension : "tag";
BaseTemplate tagTemplate = null;
try {
tagTemplate = (BaseTemplate)TemplateLoader.load("tags/" + templateName + "." + callerExtension);
} catch (TemplateNotFoundException e) {
try {
tagTemplate = (BaseTemplate)TemplateLoader.load("tags/" + templateName + ".tag");
} catch (TemplateNotFoundException ex) {
if (callerExtension.equals("tag")) {
throw new TemplateNotFoundException("tags/" + templateName + ".tag", template, fromLine);
}
throw new TemplateNotFoundException("tags/" + templateName + "." + callerExtension + " or tags/" + templateName + ".tag", template, fromLine);
}
}
TagContext.enterTag(tag);
Map args = new HashMap();
args.put("session", getBinding().getVariables().get("session"));
args.put("flash", getBinding().getVariables().get("flash"));
args.put("request", getBinding().getVariables().get("request"));
args.put("params", getBinding().getVariables().get("params"));
args.put("play", getBinding().getVariables().get("play"));
args.put("lang", getBinding().getVariables().get("lang"));
args.put("messages", getBinding().getVariables().get("messages"));
args.put("out", getBinding().getVariable("out"));
args.put("_attrs", attrs);
// all other vars are template-specific
args.put("_caller", getBinding().getVariables());
if (attrs != null) {
for (Map.Entry entry : attrs.entrySet()) {
args.put("_" + entry.getKey(), entry.getValue());
}
}
args.put("_body", body);
try {
tagTemplate.internalRender(args);
} catch (TagInternalException e) {
throw new TemplateExecutionException(template, fromLine, e.getMessage(), template.cleanStackTrace(e));
} catch (TemplateNotFoundException e) {
throw new TemplateNotFoundException(e.getPath(), template, fromLine);
}
TagContext.exitTag();
}
/**
* @deprecated '_' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on
* use {@link #__loadClass} instead
*/
@Deprecated
public Class _(String className) throws Exception {
return __loadClass(className);
}
/**
* Load the class from Pay Class loader
* @param className : the class name
* @return the given class
* @throws Exception
*/
public Class __loadClass(String className) throws Exception {
try {
return Play.classloader.loadClass(className);
} catch (ClassNotFoundException e) {
return null;
}
}
/**
* This method is faster to call from groovy than __safe() since we only evaluate val.toString()
* if we need to
*/
public String __safeFaster(Object val) {
if (val instanceof RawData) {
return ((RawData)val).data;
} else if (extension != null) {
SafeFormatter formatter = safeFormatters.get(extension);
if (formatter != null) {
return formatter.format(template, val);
}
}
return (val != null) ? val.toString() : "";
}
public String __getMessage(Object[] val) {
if (val==null) {
throw new NullPointerException("You are trying to resolve a message with an expression " +
"that is resolved to null - " +
"have you forgotten quotes around the message-key?");
}
if (val.length == 1) {
return Messages.get(val[0]);
} else {
// extract args from val
Object[] args = new Object[val.length-1];
for( int i=1;i r = new HashMap();
Method actionMethod = (Method) ActionInvoker.getActionMethod(action)[1];
String[] names = (String[]) actionMethod.getDeclaringClass().getDeclaredField("$" + actionMethod.getName() + LocalVariablesNamesTracer.computeMethodHash(actionMethod.getParameterTypes())).get(null);
if (param instanceof Object[]) {
if(((Object[])param).length == 1 && ((Object[])param)[0] instanceof Map) {
r = (Map)((Object[])param)[0];
} else {
// too many parameters versus action, possibly a developer error. we must warn him.
if (names.length < ((Object[]) param).length) {
throw new NoRouteFoundException(action, null);
}
for (int i = 0; i < ((Object[]) param).length; i++) {
if (((Object[]) param)[i] instanceof Router.ActionDefinition && ((Object[]) param)[i] != null) {
Unbinder.unBind(r, ((Object[]) param)[i].toString(), i < names.length ? names[i] : "", actionMethod.getAnnotations());
} else if (isSimpleParam(actionMethod.getParameterTypes()[i])) {
if (((Object[]) param)[i] != null) {
Unbinder.unBind(r, ((Object[]) param)[i].toString(), i < names.length ? names[i] : "", actionMethod.getAnnotations());
}
} else {
Unbinder.unBind(r, ((Object[]) param)[i], i < names.length ? names[i] : "", actionMethod.getAnnotations());
}
}
}
}
Router.ActionDefinition def = Router.reverse(action, r);
if (absolute) {
def.absolute();
}
if (template.template.name.endsWith(".xml")) {
def.url = def.url.replace("&", "&");
}
return def;
} catch (ActionNotFoundException e) {
throw new NoRouteFoundException(action, null);
}
} catch (Exception e) {
if (e instanceof PlayException) {
throw (PlayException) e;
}
throw new UnexpectedException(e);
}
}
}
}
protected static boolean isSimpleParam(Class type) {
return Number.class.isAssignableFrom(type) || type.equals(String.class) || type.isPrimitive();
}
}