pax_global_header00006660000000000000000000000064124152556100014513gustar00rootroot0000000000000052 comment=a56b037e3c8c59da703d845ea4d6a531ce0c3c2b mustache.java-mustache.java-0.8.17/000077500000000000000000000000001241525561000170705ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/.gitignore000066400000000000000000000001201241525561000210510ustar00rootroot00000000000000*.iml *.ipr *.iws .DS_Store target *~ .idea *.swp .classpath .project .settings mustache.java-mustache.java-0.8.17/.gitmodules000066400000000000000000000002041241525561000212410ustar00rootroot00000000000000[submodule "compiler/src/test/resources/spec"] path = compiler/src/test/resources/spec url = https://github.com/mustache/spec.git mustache.java-mustache.java-0.8.17/.travis.yml000066400000000000000000000000171241525561000211770ustar00rootroot00000000000000language: java mustache.java-mustache.java-0.8.17/LICENSE000066400000000000000000000011101241525561000200660ustar00rootroot00000000000000Copyright 2010 RightTime, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mustache.java-mustache.java-0.8.17/README.md000066400000000000000000000163601241525561000203550ustar00rootroot00000000000000Mustache.java ============= **Mustache.java** is a derivative of [mustache.js](http://mustache.github.com/mustache.5.html). There is a Google Group for support and questions: Travis CI: https://travis-ci.org/spullara/mustache.java Largest production deployment of Mustache.java: - Twitter (the web site, email, syndicated widgets, etc) Thanks to YourKit for many performance improvements: YourKit is kindly supporting the mustache.java open source project with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: - [YourKit Java Profiler](http://www.yourkit.com/java/profiler/index.jsp) - [YourKit .NET Profiler](http://www.yourkit.com/.net/profiler/index.jsp) Request for contributions: - Real world benchmarks that matter - currently benchmarking based on Twitter templates - Documentation - Bug reports / fixes - API feedback - Optimizations Documentation: - [Javadocs](http://mustachejava.s3-website-us-west-1.amazonaws.com) - [Mustache.js manual](http://mustache.github.com/mustache.5.html) - Passes all of the `mustache` [specification tests](https://github.com/mustache/spec) modulo whitespace differences - Biggest difference between mustache.js and mustache.java is optional concurrent evaluation - Data is provided by objects in an array of scopes and are accessed via non-private fields, methods or maps - Any `Iterable` can be used for list-like behaviors - Returning a `Callable` allows for concurrent evaluation if an `ExecutorService` is configured - Template inheritance is supported by this implementation, see (eg. `{{ com.github.spullara.mustache.java compiler 0.8.16 ``` Example template file: {{#items}} Name: {{name}} Price: {{price}} {{#features}} Feature: {{description}} {{/features}} {{/items}} Might be powered by some backing code: ```java public class Context { List items() { return Arrays.asList( new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))), new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly."))) ); } static class Item { Item(String name, String price, List features) { this.name = name; this.price = price; this.features = features; } String name, price; List features; } static class Feature { Feature(String description) { this.description = description; } String description; } } ``` And would result in: Name: Item 1 Price: $19.99 Feature: New! Feature: Awesome! Name: Item 2 Price: $29.99 Feature: Old. Feature: Ugly. Evaluation of the template proceeds serially. For instance, if you have blocking code within one of your callbacks you the system will pause while executing them: ```java static class Feature { Feature(String description) { this.description = description; } String description() throws InterruptedException { Thread.sleep(1000); return description; } } ``` If you change description to return a `Callable` instead it will automatically be executed in a separate thread if you have provided an `ExecutorService` when you created your `MustacheFactory`. ```java Callable description() throws InterruptedException { return new Callable() { @Override public String call() throws Exception { Thread.sleep(1000); return description; } }; } ``` This enables scheduled tasks, streaming behavior and asynchronous i/o. Check out the `example` module in order to see a complete end-to-end example: ```java package mustachejava; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; import java.util.Arrays; import java.util.List; public class Example { List items() { return Arrays.asList( new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))), new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly."))) ); } static class Item { Item(String name, String price, List features) { this.name = name; this.price = price; this.features = features; } String name, price; List features; } static class Feature { Feature(String description) { this.description = description; } String description; } public static void main(String[] args) throws IOException { MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile("template.mustache"); mustache.execute(new PrintWriter(System.out), new Example()).flush(); } } ``` An alternative approach for providing variables would be to use a Map object, like: ```java public static void main(String[] args) throws IOException { HashMap scopes = new HashMap(); scopes.put("name", "Mustache"); scopes.put("feature", new Feature("Perfect!")); Writer writer = new OutputStreamWriter(System.out); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new StringReader("{{name}}, {{feature.description}}!"), "example"); mustache.execute(writer, scopes); writer.flush(); } ``` mustache.java-mustache.java-0.8.17/codegen/000077500000000000000000000000001241525561000204745ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/pom.xml000066400000000000000000000034011241525561000220070ustar00rootroot00000000000000 mustache.java com.github.spullara.mustache.java 0.8.17 4.0.0 codegen codegen com.github.spullara.mustache.java compiler 0.8.17 org.ow2.asm asm-commons 4.0 org.ow2.asm asm-util 4.0 com.github.spullara.mustache.java compiler 0.8.17 tests test org.codehaus.jackson jackson-mapper-asl 1.9.3 test junit junit 4.8.2 test org.jruby jruby 1.6.7 test mustache.java-mustache.java-0.8.17/codegen/src/000077500000000000000000000000001241525561000212635ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/000077500000000000000000000000001241525561000222075ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/000077500000000000000000000000001241525561000231305ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/000077500000000000000000000000001241525561000237065ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/000077500000000000000000000000001241525561000251705ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/000077500000000000000000000000001241525561000276435ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/000077500000000000000000000000001241525561000312475ustar00rootroot00000000000000CodeCompiler.java000066400000000000000000000074201241525561000344030ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.Code; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; import java.io.Writer; import java.lang.reflect.Modifier; import java.util.concurrent.atomic.AtomicInteger; import static org.objectweb.asm.commons.Method.getMethod; /** * Compile a list of codes to execute down to a single method. */ public class CodeCompiler { private static AtomicInteger id = new AtomicInteger(0); private static final Method EXECUTE_METHOD = Method.getMethod("java.io.Writer execute(java.io.Writer, Object[])"); public static CompiledCodes compile(Code[] newcodes) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); int classId = id.incrementAndGet(); String className = "com.github.mustachejava.codegen.RunCodes" + classId; String internalClassName = className.replace(".", "/"); cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{CompiledCodes.class.getName().replace(".", "/")}); cw.visitSource("runCodes", null); GeneratorAdapter cm = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod("void (com.github.mustachejava.Code[])"), null, null, cw); cm.loadThis(); cm.invokeConstructor(Type.getType(Object.class), getMethod("void ()")); { GeneratorAdapter gm = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod("java.io.Writer runCodes(java.io.Writer, Object[])"), null, null, cw); int writerLocal = gm.newLocal(Type.getType(Writer.class)); // Put the writer in our local gm.loadArg(0); gm.storeLocal(writerLocal); int fieldNum = 0; for (Code newcode : newcodes) { Class codeClass = newcode.getClass(); Class fieldClass = codeClass; while(fieldClass.isAnonymousClass() || fieldClass.isLocalClass() || (fieldClass.getModifiers() & Modifier.PUBLIC) == 0) { if (codeClass.getSuperclass() != Object.class && codeClass.getSuperclass().isAssignableFrom(Code.class)) { fieldClass = codeClass.getSuperclass(); } else { fieldClass = Code.class; } } Type fieldType = Type.getType(fieldClass); // add a field for each one to the class String fieldName = "code" + fieldNum; cw.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, fieldType.getDescriptor(), null, null); // set the fields to the passed in values in the constructor cm.loadThis(); cm.loadArg(0); cm.push(fieldNum); cm.arrayLoad(Type.getType(Code.class)); cm.checkCast(fieldType); cm.putField(Type.getType(internalClassName), fieldName, fieldType); // writer, scopes) gm.loadThis(); gm.getField(Type.getType(internalClassName), fieldName, fieldType); gm.loadLocal(writerLocal); gm.loadArg(1); // code.execute( if (fieldClass.isInterface()) { gm.invokeInterface(fieldType, EXECUTE_METHOD); } else { gm.invokeVirtual(fieldType, EXECUTE_METHOD); } // writer = gm.storeLocal(writerLocal); fieldNum++; } cm.returnValue(); cm.endMethod(); // Load writer and return it gm.loadLocal(writerLocal); gm.returnValue(); gm.endMethod(); } cw.visitEnd(); Class aClass = GuardCompiler.defineClass(className, cw.toByteArray()); try { return (CompiledCodes) aClass.getConstructor(Code[].class).newInstance(new Object[] {newcodes}); } catch (Exception e) { e.printStackTrace(); return null; } } } CodegenMissingWrapper.java000066400000000000000000000012161241525561000362720ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.MissingWrapper; import com.github.mustachejava.util.GuardException; import java.util.List; public class CodegenMissingWrapper extends MissingWrapper { final Guard compiledGuards; public CodegenMissingWrapper(String name, List guards) { super(name, guards.toArray(new Guard[guards.size()])); compiledGuards = GuardCompiler.compile(guards); } @Override protected void guardCall(Object[] scopes) throws GuardException { if (!compiledGuards.apply(scopes)) { throw guardException; } } } CodegenMustacheFactory.java000066400000000000000000000012631241525561000364230ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.*; import java.io.File; /** * Codegen mustache code execution. */ public class CodegenMustacheFactory extends DefaultMustacheFactory { @Override public MustacheVisitor createMustacheVisitor() { return new CodegenMustacheVisitor(this); } public CodegenMustacheFactory() { super(); setObjectHandler(new CodegenObjectHandler()); } public CodegenMustacheFactory(File fileRoot) { super(fileRoot); setObjectHandler(new CodegenObjectHandler()); } public CodegenMustacheFactory(String resourceRoot) { super(resourceRoot); setObjectHandler(new CodegenObjectHandler()); } } CodegenMustacheVisitor.java000066400000000000000000000017311241525561000364530ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.*; import com.github.mustachejava.codes.DefaultMustache; import java.io.Writer; public class CodegenMustacheVisitor extends DefaultMustacheVisitor { public CodegenMustacheVisitor(DefaultMustacheFactory mf) { super(mf); } @Override public Mustache mustache(TemplateContext templateContext) { return new DefaultMustache(templateContext, df, list.toArray(new Code[list.size()]), templateContext.file()) { private CompiledCodes compiledCodes; @Override public Writer run(Writer writer, Object[] scopes) { if (compiledCodes != null) { return compiledCodes.runCodes(writer, scopes); } return super.run(writer, scopes); } @Override public void setCodes(Code[] newcodes) { super.setCodes(newcodes); if (newcodes != null) { compiledCodes = CodeCompiler.compile(newcodes); } } }; } } CodegenObjectHandler.java000066400000000000000000000037301241525561000360270ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.codegen.guards.*; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.MissingWrapper; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.reflect.guards.*; import com.github.mustachejava.util.Wrapper; import java.lang.reflect.AccessibleObject; import java.util.List; /** * Generates code when it can for higher performance. Make sure you have enough * PermGen to run your application. Each variable will generate at least one guard * class and each mustache section or partial will as well. */ public class CodegenObjectHandler extends ReflectionObjectHandler { @Override protected ClassGuard createClassGuard(int i, Object scope) { return new CompilableClassGuard(i, scope); } @Override protected DepthGuard createDepthGuard(int length) { return new CompilableDepthGuard(length); } @Override protected DotGuard createDotGuard(int i, Object scope, String lookup) { return new CompilableDotGuard(lookup, i, scope); } @Override protected MapGuard createMapGuard(int scopeIndex, Wrapper[] wrappers, String name, boolean contains) { return new CompilableMapGuard(this, scopeIndex, name, contains, wrappers); } @Override protected NullGuard createNullGuard() { return new CompilableNullGuard(); } @Override protected WrappedGuard createWrappedGuard(int i, List wrappers, List wrapperGuard) { return new CompilableWrappedGuard(this, i, wrappers, wrapperGuard); } @Override protected MissingWrapper createMissingWrapper(String name, List guards) { return new CodegenMissingWrapper(name, guards); } @Override protected Wrapper createWrapper(int scopeIndex, Wrapper[] wrappers, List guards, AccessibleObject member, Object[] arguments) { return new CodegenReflectionWrapper(this, scopeIndex, wrappers, guards, member, arguments); } } CodegenReflectionWrapper.java000066400000000000000000000021261241525561000367540ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.ReflectionWrapper; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.lang.reflect.AccessibleObject; import java.util.Arrays; import java.util.List; public class CodegenReflectionWrapper extends ReflectionWrapper { final Guard compiledGuards; public CodegenReflectionWrapper(CodegenObjectHandler codegenObjectHandler, int scopeIndex, Wrapper[] wrappers, List guards, AccessibleObject member, Object[] arguments) { super(scopeIndex, wrappers, guards.toArray(new Guard[guards.size()]), member, arguments, codegenObjectHandler); compiledGuards = GuardCompiler.compile(guards); } public CodegenReflectionWrapper(ReflectionWrapper rw) { super(rw); compiledGuards = GuardCompiler.compile(Arrays.asList(rw.getGuards())); } @Override protected void guardCall(Object[] scopes) throws GuardException { if (!compiledGuards.apply(scopes)) { throw guardException; } } } CompilableGuard.java000066400000000000000000000034371241525561000350740ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.util.Wrapper; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** * Optimizable guards */ public interface CompilableGuard extends Guard, Opcodes { Type OBJECT_TYPE = Type.getType(Object.class); Type CLASS_TYPE = Type.getType(Class.class); Type MAP_TYPE = Type.getType(Map.class); Type OH_TYPE = Type.getType(ObjectHandler.class); Type WRAPPERS_TYPE = Type.getType(Wrapper[].class); Type ROH_TYPE = Type.getType(ReflectionObjectHandler.class); Type GUARD_TYPE = Type.getType(Guard.class); Method CLASS_FORNAME = Method.getMethod("Class forName(String)"); Method OBJECT_GETCLASS = Method.getMethod("Class getClass()"); Method ROH_UNWRAP = Method.getMethod("Object unwrap(com.github.mustachejava.ObjectHandler, int, com.github.mustachejava.util.Wrapper[], Object[])"); Method MAP_CONTAINSKEY = Method.getMethod("boolean containsKey(Object)"); Method GUARD_APPLY = Method.getMethod("boolean apply(Object[])"); public abstract void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType); } CompiledCodes.java000066400000000000000000000002621241525561000345450ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import java.io.Writer; /** * Compiled code. */ public interface CompiledCodes { Writer runCodes(Writer writer, Object[] scopes); } GuardCompiler.java000066400000000000000000000073271241525561000346010ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.MustacheException; import com.github.mustachejava.reflect.Guard; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.objectweb.asm.commons.Method.getMethod; /** * Compiles Compilable Guards. */ public class GuardCompiler { private static AtomicInteger id = new AtomicInteger(0); public static Guard compile(List guards) { List compilableGuards = new ArrayList(); for (Guard guard : guards) { if (guard instanceof CompilableGuard) { compilableGuards.add((CompilableGuard) guard); } else { throw new MustacheException("Invalid guard for compilation: " + guard); } } try { return compile("compiledguards:" + guards.size(), compilableGuards); } catch (Exception e) { throw new MustacheException("Compilation failure", e); } } private static Guard compile(String source, Iterable guards) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); int classId = id.incrementAndGet(); String className = "com.github.mustachejava.codegen.CompiledGuards" + classId; String internalClassName = className.replace(".", "/"); cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalClassName, null, "java/lang/Object", new String[]{Guard.class.getName().replace(".", "/")}); cw.visitSource(source, null); // Constructor GeneratorAdapter cm = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod("void (Object[])"), null, null, cw); cm.loadThis(); cm.invokeConstructor(Type.getType(Object.class), getMethod("void ()")); // Static initializer GeneratorAdapter sm = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, getMethod("void ()"), null, null, cw); // Method implementation GeneratorAdapter gm = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod("boolean apply(Object[])"), null, null, cw); Label returnFalse = new Label(); // Add each guard in the list List cargs = new ArrayList(); for (CompilableGuard guard : guards) { guard.addGuard(returnFalse, gm, cm, sm, cw, id, cargs, Type.getType(internalClassName)); } // Makes it through the guard, success gm.push(true); gm.returnValue(); // Jumps to returnFalse, failure gm.visitLabel(returnFalse); gm.push(false); gm.returnValue(); gm.endMethod(); // Close the constructor cm.returnValue(); cm.endMethod(); // Close the static initializer sm.returnValue(); sm.endMethod(); cw.visitEnd(); Class aClass = defineClass(className, cw.toByteArray()); return (Guard) aClass.getConstructor(Object[].class).newInstance((Object) cargs.toArray(new Object[cargs.size()])); } private static final DefiningClassLoader cl = new DefiningClassLoader(Thread.currentThread().getContextClassLoader()); private static class DefiningClassLoader extends ClassLoader { public DefiningClassLoader(ClassLoader parent) { super(parent); } public Class defineClass(final String name, final byte[] b) { return defineClass(name, b, 0, b.length); } } public static Class defineClass(String name, byte[] b) { return cl.defineClass(name, b); } } mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guards/000077500000000000000000000000001241525561000325345ustar00rootroot00000000000000CompilableClassGuard.java000066400000000000000000000054221241525561000373430ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.reflect.guards.ClassGuard; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.objectweb.asm.commons.GeneratorAdapter.LE; import static org.objectweb.asm.commons.GeneratorAdapter.NE; /** * Compiled form of the class guard. */ public class CompilableClassGuard extends ClassGuard implements CompilableGuard { public CompilableClassGuard(int scopeIndex, Object scope) { super(scopeIndex, scope); } @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { int id = atomicId.incrementAndGet(); // Add the field for the class guard String fieldName = "classGuard" + id; cw.visitField(ACC_PUBLIC | ACC_STATIC, fieldName, "Ljava/lang/Class;", null, null); // Initialize the field sm.push(classGuard.getName()); sm.invokeStatic(CLASS_TYPE, CLASS_FORNAME); sm.putStatic(thisType, fieldName, CLASS_TYPE); // Check that the scopes are not null gm.loadArg(0); // scopes gm.ifNull(returnFalse); // if scopes == null return false // Check that we have enough scopes to satisfy gm.loadArg(0); // scopes gm.arrayLength(); // scopes.length gm.push(scopeIndex); gm.ifICmp(LE, returnFalse); // scopes.length <= scopeIndex return false // Initialize local variables gm.loadArg(0); // scopes gm.push(scopeIndex); gm.arrayLoad(OBJECT_TYPE); // Object[] int scopeLocal = gm.newLocal(OBJECT_TYPE); gm.storeLocal(scopeLocal); int classGuardLocal = gm.newLocal(CLASS_TYPE); gm.getStatic(thisType, fieldName, CLASS_TYPE); gm.storeLocal(classGuardLocal); // Check to see if the scope is null gm.loadLocal(scopeLocal); Label scopeIsNull = new Label(); gm.ifNull(scopeIsNull); // after here scope is not null // Check to see if the scopes class matches the guard gm.loadLocal(scopeLocal); gm.invokeVirtual(OBJECT_TYPE, OBJECT_GETCLASS); // scope.getClass() gm.loadLocal(classGuardLocal); gm.ifCmp(CLASS_TYPE, NE, returnFalse); // if they are not equal return false Label next = new Label(); gm.goTo(next); // next guard // Check to see if the class guard itself is null gm.visitLabel(scopeIsNull); // after here scope is null gm.loadLocal(classGuardLocal); gm.ifNonNull(returnFalse); // if there is a class guard, return false // Successfully passed the guard gm.visitLabel(next); // end of method } } CompilableDepthGuard.java000066400000000000000000000020061241525561000373350ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.reflect.guards.DepthGuard; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * Compiled version of the depth guard. */ public class CompilableDepthGuard extends DepthGuard implements CompilableGuard { public CompilableDepthGuard(int length) { super(length); } @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { // If objects is null return false gm.loadArg(0); gm.ifNull(returnFalse); // If they are not equal return false gm.loadArg(0); gm.arrayLength(); gm.push(length); gm.ifICmp(GeneratorAdapter.NE, returnFalse); } } CompilableDotGuard.java000066400000000000000000000015431241525561000370240ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.reflect.guards.DotGuard; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * Compiled dot guard. */ public class CompilableDotGuard extends DotGuard implements CompilableGuard { public CompilableDotGuard(String lookup, int scopeIndex, Object classGuard) { super(lookup, scopeIndex, classGuard); } @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { // do nothing and it is assumed true } } CompilableMapGuard.java000066400000000000000000000051401241525561000370100ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.reflect.guards.MapGuard; import com.github.mustachejava.util.Wrapper; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.objectweb.asm.commons.GeneratorAdapter.EQ; import static org.objectweb.asm.commons.GeneratorAdapter.NE; /** * Compiled version of map guard. */ public class CompilableMapGuard extends MapGuard implements CompilableGuard { public CompilableMapGuard(ObjectHandler oh, int scopeIndex, String name, boolean contains, Wrapper[] wrappers) { super(oh, scopeIndex, name, contains, wrappers); } @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { int id = atomicId.incrementAndGet(); String wrappersFieldName = "wrappers" + id; String ohFieldName = "oh" + id; // Add the two fields we need cw.visitField(ACC_PRIVATE, ohFieldName, "Lcom/github/mustachejava/ObjectHandler;", null, null); cw.visitField(ACC_PRIVATE, wrappersFieldName, "[Lcom/github/mustachejava/util/Wrapper;", null, null); // Initialize them in the constructor int ohArg = cargs.size(); cargs.add(oh); cm.loadThis(); cm.loadArg(0); cm.push(ohArg); cm.arrayLoad(OBJECT_TYPE); cm.checkCast(OH_TYPE); cm.putField(thisType, ohFieldName, OH_TYPE); int wrappersArg = cargs.size(); cargs.add(wrappers); cm.loadThis(); cm.loadArg(0); cm.push(wrappersArg); cm.arrayLoad(OBJECT_TYPE); cm.checkCast(WRAPPERS_TYPE); cm.putField(thisType, wrappersFieldName, WRAPPERS_TYPE); // Unwrap the scope gm.loadThis(); gm.getField(thisType, ohFieldName, OH_TYPE); gm.push(scopeIndex); gm.loadThis(); gm.getField(thisType, wrappersFieldName, WRAPPERS_TYPE); gm.loadArg(0); gm.invokeStatic(ROH_TYPE, ROH_UNWRAP); int scopeLocal = gm.newLocal(OBJECT_TYPE); gm.storeLocal(scopeLocal); // Check to see if it is a map gm.loadLocal(scopeLocal); gm.instanceOf(MAP_TYPE); gm.ifZCmp(EQ, returnFalse); // It is a map gm.loadLocal(scopeLocal); gm.checkCast(MAP_TYPE); gm.push(name); gm.invokeInterface(MAP_TYPE, MAP_CONTAINSKEY); gm.ifZCmp(contains ? EQ : NE, returnFalse); } } CompilableNullGuard.java000066400000000000000000000014371241525561000372120ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.reflect.guards.NullGuard; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; /** * Compiled null guard. */ public class CompilableNullGuard extends NullGuard implements CompilableGuard { @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { gm.loadArg(0); gm.push(0); gm.arrayLoad(OBJECT_TYPE); gm.ifNonNull(returnFalse); } } CompilableWrappedGuard.java000066400000000000000000000065151241525561000377040ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/main/java/com/github/mustachejava/codegen/guardspackage com.github.mustachejava.codegen.guards; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.codegen.CompilableGuard; import com.github.mustachejava.codegen.GuardCompiler; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.guards.WrappedGuard; import com.github.mustachejava.util.Wrapper; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.objectweb.asm.commons.GeneratorAdapter.EQ; /** * Compiled wrapper guard. */ public class CompilableWrappedGuard extends WrappedGuard implements CompilableGuard { private Guard guard; @SuppressWarnings("unchecked") public CompilableWrappedGuard(ObjectHandler oh, int index, List wrappers, List wrapperGuard) { super(oh, index, wrappers, wrapperGuard); guard = GuardCompiler.compile(wrapperGuard); } @Override public void addGuard(Label returnFalse, GeneratorAdapter gm, GeneratorAdapter cm, GeneratorAdapter sm, ClassWriter cw, AtomicInteger atomicId, List cargs, Type thisType) { int id = atomicId.incrementAndGet(); String wrappersFieldName = "wrappers" + id; String ohFieldName = "oh" + id; String guardFieldName = "guard" + id; // Add the two fields we need cw.visitField(ACC_PRIVATE, ohFieldName, "Lcom/github/mustachejava/ObjectHandler;", null, null); cw.visitField(ACC_PRIVATE, wrappersFieldName, "[Lcom/github/mustachejava/util/Wrapper;", null, null); cw.visitField(ACC_PRIVATE, guardFieldName, "Lcom/github/mustachejava/reflect/Guard;", null, null); // Initialize them in the constructor int ohArg = cargs.size(); cargs.add(oh); cm.loadThis(); cm.loadArg(0); cm.push(ohArg); cm.arrayLoad(OBJECT_TYPE); cm.checkCast(OH_TYPE); cm.putField(thisType, ohFieldName, OH_TYPE); int wrappersArg = cargs.size(); cargs.add(wrappers); cm.loadThis(); cm.loadArg(0); cm.push(wrappersArg); cm.arrayLoad(OBJECT_TYPE); cm.checkCast(WRAPPERS_TYPE); cm.putField(thisType, wrappersFieldName, WRAPPERS_TYPE); int guardArg = cargs.size(); cargs.add(guard); cm.loadThis(); cm.loadArg(0); cm.push(guardArg); cm.arrayLoad(OBJECT_TYPE); cm.checkCast(GUARD_TYPE); cm.putField(thisType, guardFieldName, GUARD_TYPE); // Unwrap the scope gm.loadThis(); gm.getField(thisType, ohFieldName, OH_TYPE); gm.push(index); gm.loadThis(); gm.getField(thisType, wrappersFieldName, WRAPPERS_TYPE); gm.loadArg(0); gm.invokeStatic(ROH_TYPE, ROH_UNWRAP); int scopeLocal = gm.newLocal(OBJECT_TYPE); gm.storeLocal(scopeLocal); // Create the object array gm.push(1); gm.newArray(OBJECT_TYPE); int arrayLocal = gm.newLocal(Type.getType(Object[].class)); gm.storeLocal(arrayLocal); // Put the scope in the array gm.loadLocal(arrayLocal); gm.push(0); gm.loadLocal(scopeLocal); gm.arrayStore(OBJECT_TYPE); // Call the apply method on the guard gm.loadThis(); gm.getField(thisType, guardFieldName, GUARD_TYPE); gm.loadLocal(arrayLocal); gm.invokeInterface(GUARD_TYPE, GUARD_APPLY); // If this is false, return false gm.ifZCmp(EQ, returnFalse); } } mustache.java-mustache.java-0.8.17/codegen/src/test/000077500000000000000000000000001241525561000222425ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/000077500000000000000000000000001241525561000231635ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/000077500000000000000000000000001241525561000237415ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/000077500000000000000000000000001241525561000252235ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejava/000077500000000000000000000000001241525561000276765ustar00rootroot00000000000000CodegenInterpreterTest.java000066400000000000000000000004341241525561000351130ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; public class CodegenInterpreterTest extends InterpreterTest { @Override protected DefaultMustacheFactory createMustacheFactory() { return new CodegenMustacheFactory(root); } } CodegenSpecTest.java000066400000000000000000000012141241525561000334770ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; import org.codehaus.jackson.JsonNode; import java.io.Reader; import java.io.StringReader; /** * Specification tests */ public class CodegenSpecTest extends SpecTest { @Override protected DefaultMustacheFactory createMustacheFactory(final JsonNode test) { return new CodegenMustacheFactory("/spec/specs") { @Override public Reader getReader(String resourceName) { JsonNode partial = test.get("partials").get(resourceName); return new StringReader(partial == null ? "" : partial.getTextValue()); } }; } } mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejava/codegen/000077500000000000000000000000001241525561000313025ustar00rootroot00000000000000CompiledGuardTest.java000066400000000000000000000026551241525561000354550ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejava/codegenpackage com.github.mustachejava.codegen; import com.github.mustachejava.codegen.guards.CompilableClassGuard; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.guards.ClassGuard; import org.junit.Test; import org.objectweb.asm.Opcodes; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import static com.github.mustachejava.codegen.GuardCompiler.compile; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; /** * Test our guard compilations */ public class CompiledGuardTest implements Opcodes { @Test public void testGuard() { ClassGuard stringClassGuard = new ClassGuard(0, ""); assertTrue("string is ok", stringClassGuard.apply(new Object[]{"test"})); assertFalse("integer is not ok", stringClassGuard.apply(new Object[]{1})); } @Test public void testCompiledGuard() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { String source = "Test.java"; CompilableClassGuard stringClassGuard = new CompilableClassGuard(0, ""); List guards = new ArrayList(); guards.add(stringClassGuard); Guard testGuard = compile(guards); assertTrue("string is ok", testGuard.apply(new Object[]{"test", 1})); assertFalse("integer is not ok", testGuard.apply(new Object[]{1, "test"})); } }mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejavabench/000077500000000000000000000000001241525561000306765ustar00rootroot00000000000000CodegenBenchmarkTest.java000066400000000000000000000010441241525561000355000ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejavabenchpackage com.github.mustachejavabench; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejavabenchmarks.BenchmarkTest; /** * Compare compilation with interpreter. *

* User: sam * Date: 5/14/11 * Time: 9:28 PM */ public class CodegenBenchmarkTest extends BenchmarkTest { @Override public void testCompiler() { } @Override protected DefaultMustacheFactory createMustacheFactory() { return new CodegenMustacheFactory(root); } } CodegenJsonInterpreterTest.java000066400000000000000000000010001241525561000367330ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/codegen/src/test/java/com/github/mustachejavabenchpackage com.github.mustachejavabench; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejavabenchmarks.JsonInterpreterTest; /** * Tests for the compiler. *

* User: sam * Date: May 3, 2010 * Time: 10:23:54 AM */ public class CodegenJsonInterpreterTest extends JsonInterpreterTest { @Override protected DefaultMustacheFactory createMustacheFactory() { return new CodegenMustacheFactory(root); } } mustache.java-mustache.java-0.8.17/compiler/000077500000000000000000000000001241525561000207025ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/pom.xml000066400000000000000000000101141241525561000222140ustar00rootroot00000000000000 mustache.java com.github.spullara.mustache.java 0.8.17 ../pom.xml 4.0.0 compiler bundle compiler Implementation of mustache.js for Java http://github.com/spullara/mustache.java Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 repo scm:git:git://github.com/spullara/mustache.java.git http://github.com/spullara/mustache.java mustache.java-0.8.17 Sam Pullara sam@sampullara.com http://www.javarants.com Twitter http://maven.twttr.com/ UTF-8 com.google.guava guava 16.0.1 org.jruby jruby 1.6.7 provided junit junit 4.8.2 test org.codehaus.jackson jackson-mapper-asl 1.9.3 test org.apache.maven.plugins maven-compiler-plugin 2.0.2 1.6 1.6 org.apache.maven.plugins maven-compiler-plugin compile compile org.apache.maven.plugins maven-jar-plugin 2.2 jar test-jar org.apache.felix maven-bundle-plugin maven-assembly-plugin jar-with-dependencies make-assembly package attached mustache.java-mustache.java-0.8.17/compiler/src/000077500000000000000000000000001241525561000214715ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/000077500000000000000000000000001241525561000224155ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/000077500000000000000000000000001241525561000233365ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/000077500000000000000000000000001241525561000241145ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/000077500000000000000000000000001241525561000253765ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/000077500000000000000000000000001241525561000300515ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/Binding.java000066400000000000000000000003211241525561000322620ustar00rootroot00000000000000package com.github.mustachejava; /** * Bindings connect templates to their views. *

* User: sam * Date: 7/7/12 * Time: 6:07 PM */ public interface Binding { public Object get(Object[] scopes); } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/Code.java000066400000000000000000000014621241525561000315710ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.util.Node; import java.io.IOException; import java.io.Writer; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** * Code objects that are executed in order to evaluate the template */ public interface Code { Writer execute(Writer writer, Object scope); Writer execute(Writer writer, Object[] scopes); void identity(Writer writer); void append(String text); Code[] getCodes(); void setCodes(Code[] codes); void init(); Object clone(); Object clone(Set seen); String getName(); /** * If it returns a node, that means that it successfully parsed it * and advanced the reader. * * @param reader * @return */ Node invert(Node node, String text, AtomicInteger position); } DefaultMustacheFactory.java000066400000000000000000000167641241525561000352610ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.resolver.DefaultResolver; import com.google.common.base.Charsets; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.io.Files; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.UncheckedExecutionException; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import static com.github.mustachejava.util.HtmlEscaper.escape; /** * Simplest possible code factory */ public class DefaultMustacheFactory implements MustacheFactory { /** * Create the default cache for mustache compilations. This is basically * required by the specification to handle recursive templates. */ protected final LoadingCache mustacheCache = createMustacheCache(); /** * This is the default object handler. */ protected ObjectHandler oh = new ReflectionObjectHandler(); /** * This parser should work with any MustacheFactory */ protected final MustacheParser mc = new MustacheParser(this); /** * New templates that are generated at runtime are cached here. The template key * includes the text of the template and the context so we get proper error * messages and debugging information. */ protected final LoadingCache templateCache = createLambdaCache(); protected int recursionLimit = 100; private final MustacheResolver mustacheResolver; protected ListeningExecutorService les; public DefaultMustacheFactory() { this.mustacheResolver = new DefaultResolver(); } public DefaultMustacheFactory(MustacheResolver mustacheResolver) { this.mustacheResolver = mustacheResolver; } /** * Use the classpath to resolve mustache templates. * * @param resourceRoot */ public DefaultMustacheFactory(String resourceRoot) { this.mustacheResolver = new DefaultResolver(resourceRoot); } /** * Use the file system to resolve mustache templates. * * @param fileRoot */ public DefaultMustacheFactory(File fileRoot) { this.mustacheResolver = new DefaultResolver(fileRoot); } public String resolvePartialPath(String dir, String name, String extension) { String filePath = name; // Do not prepend directory if it is already defined if (!name.startsWith("/")) { filePath = dir + filePath; } // Do not append extension if it is already defined if (!name.endsWith(extension)) { filePath = filePath + extension; } String path = Files.simplifyPath(new File(filePath).getPath()); return ensureForwardSlash(path); } private static String ensureForwardSlash(String path) { return path.replace('\\', '/'); } @Override public MustacheVisitor createMustacheVisitor() { return new DefaultMustacheVisitor(this); } @Override public Reader getReader(String resourceName) { Reader reader = mustacheResolver.getReader(resourceName); if(reader == null) { throw new MustacheNotFoundException(resourceName); } return reader; } @Override public void encode(String value, Writer writer) { escape(value, writer, true); } @Override public ObjectHandler getObjectHandler() { return oh; } /** * You can override the default object handler post construction. * * @param oh */ public void setObjectHandler(ObjectHandler oh) { this.oh = oh; } /** * There is an ExecutorService that is used when executing parallel * operations when a Callable is returned from a mustache value or iterable. * * @return */ public ExecutorService getExecutorService() { return les; } /** * If you need to specify your own executor service you can. * * @param es */ public void setExecutorService(ExecutorService es) { if (es instanceof ListeningExecutorService) { les = (ListeningExecutorService) es; } else { les = MoreExecutors.listeningDecorator(es); } } public Mustache getFragment(FragmentKey templateKey) { try { Mustache mustache = templateCache.get(templateKey); mustache.init(); return mustache; } catch (ExecutionException e) { throw handle(e); } } private MustacheException handle(Exception e) { Throwable cause = e.getCause(); if (cause instanceof MustacheException) { return (MustacheException) cause; } return new MustacheException(cause); } @Override public Mustache compile(String name) { try { Mustache mustache = mustacheCache.get(name); mustache.init(); return mustache; } catch (UncheckedExecutionException e) { throw handle(e); } catch (ExecutionException e) { throw handle(e); } } @Override public Mustache compile(Reader reader, String name) { return compile(reader, name, "{{", "}}"); } // Template functions need this to comply with the specification public Mustache compile(Reader reader, String file, String sm, String em) { Mustache compile = mc.compile(reader, file, sm, em); compile.init(); return compile; } @Override public String translate(String from) { return from; } /** * Override this method to apply any filtering to text that will appear * verbatim in the output template. * * * @param appended * @param b * @return */ public String filterText(String appended, boolean b) { return appended; } /** * Maximum recursion limit for partials. */ public void setRecursionLimit(int recursionLimit) { this.recursionLimit = recursionLimit; } public int getRecursionLimit() { return recursionLimit; } private final ThreadLocal> partialCache = new ThreadLocal>() { @Override protected Map initialValue() { return new HashMap(); } }; /** * In order to handle recursion, we need a temporary thread local cache during compilation * that is ultimately thrown away after the top level partial is complete. * * @param s * @return */ public Mustache compilePartial(String s) { Map cache = partialCache.get(); try { Mustache mustache = cache.get(s); if (mustache == null) { mustache = mc.compile(s); cache.put(s, mustache); mustache.init(); } return mustache; } finally { cache.remove(s); } } protected class MustacheCacheLoader extends CacheLoader { @Override public Mustache load(String key) throws Exception { return mc.compile(key); } } protected class FragmentCacheLoader extends CacheLoader { @Override public Mustache load(FragmentKey fragmentKey) throws Exception { StringReader reader = new StringReader(fragmentKey.templateText); TemplateContext tc = fragmentKey.tc; return mc.compile(reader, tc.file(), tc.startChars(), tc.endChars(), tc.startOfLine()); } } protected LoadingCache createMustacheCache() { return CacheBuilder.newBuilder().build(new MustacheCacheLoader()); } protected LoadingCache createLambdaCache() { return CacheBuilder.newBuilder().build(new FragmentCacheLoader()); } } DefaultMustacheVisitor.java000066400000000000000000000100131241525561000352660ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codes.DefaultCode; import com.github.mustachejava.codes.DefaultMustache; import com.github.mustachejava.codes.ExtendCode; import com.github.mustachejava.codes.ExtendNameCode; import com.github.mustachejava.codes.IterableCode; import com.github.mustachejava.codes.NotIterableCode; import com.github.mustachejava.codes.PartialCode; import com.github.mustachejava.codes.ValueCode; import com.github.mustachejava.codes.WriteCode; import com.github.mustachejava.util.Node; import java.io.Writer; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; /** * The default implementation that builds up Code lists */ public class DefaultMustacheVisitor implements MustacheVisitor { protected static Logger logger = Logger.getLogger(DefaultMustacheVisitor.class.getSimpleName()); private static final Code EOF = new DefaultCode() { @Override public Node invert(Node node, String text, AtomicInteger position) { return text.length() == position.get() ? node : null; } }; protected final List list = new LinkedList(); private final Map handlers = new HashMap() {{ put("implicit-iterator", new PragmaHandler() { @Override public Code handle(TemplateContext tc, String pragma, String args) { return new DefaultCode() { @Override public Writer execute(Writer writer, Object[] scopes) { return super.execute(writer, scopes); } }; } }); }}; protected DefaultMustacheFactory df; public DefaultMustacheVisitor(DefaultMustacheFactory df) { this.df = df; } public void addPragmaHandler(String pragma, PragmaHandler handler) { handlers.put(pragma.toLowerCase(), handler); } @Override public Mustache mustache(TemplateContext templateContext) { return new DefaultMustache(templateContext, df, list.toArray(new Code[list.size()]), templateContext.file()); } @Override public void iterable(TemplateContext templateContext, String variable, Mustache mustache) { list.add(new IterableCode(templateContext, df, mustache, variable)); } @Override public void notIterable(TemplateContext templateContext, String variable, Mustache mustache) { list.add(new NotIterableCode(templateContext, df, mustache, variable)); } @Override public void name(TemplateContext templateContext, String variable, Mustache mustache) { list.add(new ExtendNameCode(templateContext, df, mustache, variable)); } @Override public void partial(TemplateContext tc, final String variable) { TemplateContext partialTC = new TemplateContext("{{", "}}", tc.file(), tc.line(), tc.startOfLine()); list.add(new PartialCode(partialTC, df, variable)); } @Override public void value(TemplateContext tc, final String variable, boolean encoded) { list.add(new ValueCode(tc, df, variable, encoded)); } @Override public void write(TemplateContext tc, final String text) { if (text.length() > 0) { int size = list.size(); if (size > 0) { Code code = list.get(size - 1); code.append(text); } else { list.add(new WriteCode(tc, df, text)); } } } @Override public void pragma(TemplateContext tc, String pragma, String args) { PragmaHandler pragmaHandler = handlers.get(pragma.toLowerCase()); if (pragmaHandler == null) { // By default, warn that no pragmas are understood logger.warning("Unimplemented pragma: " + pragma); } else { Code code = pragmaHandler.handle(tc, pragma, args); if (code != null) { list.add(code); } } } @Override public void eof(TemplateContext templateContext) { list.add(EOF); } @Override public void extend(TemplateContext templateContext, String variable, Mustache mustache) { list.add(new ExtendCode(templateContext, df, mustache, variable)); } } DeferringMustacheFactory.java000066400000000000000000000106501241525561000355660ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codes.PartialCode; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; /** * This allows you to automatically defer evaluation of partials. By default * it generates HTML but you can override that behavior. */ public class DeferringMustacheFactory extends DefaultMustacheFactory { public static final Object DEFERRED = new Object(); public DeferringMustacheFactory() { } public DeferringMustacheFactory(String resourceRoot) { super(resourceRoot); } public DeferringMustacheFactory(File fileRoot) { super(fileRoot); } private static class Deferral { final long id; final Future future; Deferral(long id, Future future) { this.id = id; this.future = future; } } public static class DeferredCallable implements Callable { private List deferrals = new ArrayList(); public void add(Deferral deferral) { deferrals.add(deferral); } @Override public String call() throws Exception { StringBuilder sb = new StringBuilder(); for (Deferral deferral : deferrals) { Object o = deferral.future.get(); if (o != null) { writeDeferral(sb, deferral, o); } } return sb.toString(); } } @Override public MustacheVisitor createMustacheVisitor() { final AtomicLong id = new AtomicLong(0); return new DefaultMustacheVisitor(this) { @Override public void partial(TemplateContext tc, final String variable) { TemplateContext partialTC = new TemplateContext("{{", "}}", tc.file(), tc.line(), tc.startOfLine()); final Long divid = id.incrementAndGet(); list.add(new PartialCode(partialTC, df, variable) { Wrapper deferredWrapper; @Override public Writer execute(Writer writer, final Object[] scopes) { final Object object = get(scopes); final DeferredCallable deferredCallable = getDeferred(scopes); if (object == DEFERRED && deferredCallable != null) { try { writeTarget(writer, divid); writer.append(appended); } catch (IOException e) { throw new MustacheException("Failed to write", e); } deferredCallable.add( new Deferral(divid, getExecutorService().submit(new Callable() { @Override public Object call() { try { StringWriter writer = new StringWriter(); Object[] newscopes = addScope(scopes, object); partial.execute(writer, newscopes).close(); return writer.toString(); } catch (IOException e) { throw new MustacheException("Failed to writer", e); } } }))); return writer; } else { return appendText(partial.execute(writer, scopes)); } } private DeferredCallable getDeferred(Object[] scopes) { try { if (deferredWrapper == null) { deferredWrapper = getObjectHandler().find("deferred", scopes); } return (DeferredCallable) deferredWrapper.call(scopes); } catch (GuardException e) { deferredWrapper = null; return getDeferred(scopes); } } }); } }; } protected void writeTarget(Writer writer, Long divid) throws IOException { writer.append("
"); } protected static void writeDeferral(StringBuilder sb, Deferral deferral, Object o) { sb.append(""); } } FallbackMustacheFactory.java000066400000000000000000000076121241525561000353640ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; /** * Mustache.java factory with a fallback mechanism for locating resources. *

* (Some parts are based on DefaultMustacheFactory code that is Copyright 2010 RightTime, Inc.) * * @author gw0 [http://gw.tnode.com/] */ public class FallbackMustacheFactory extends DefaultMustacheFactory { /** * List of fallback resource roots to search through. */ private Object[] resourceRoots; /** * Simple constructor for a fallback Mustache.java factory. * * @param resourceRoot normal resource root * @param fallbackRoot fallback alternative root */ public FallbackMustacheFactory(String resourceRoot, String fallbackRoot) { this(new String[]{resourceRoot, fallbackRoot}); } /** * Simple constructor for a fallback Mustache.java factory. * * @param resourceRoot normal resource root * @param fallbackRoot fallback alternative root */ public FallbackMustacheFactory(File fileRoot, File fallbackRoot) { this(new File[]{fileRoot, fallbackRoot}); } /** * Generic constructor for a fallback Mustache.java factory. * * @param resourceRoots array of fallback resource roots as String or File */ public FallbackMustacheFactory(Object... resourceRoots) { super(); for (Object resourceObj : resourceRoots) { if (resourceObj instanceof String) { // for String String resourceRoot = (String) resourceObj; if (!resourceRoot.endsWith("/")) resourceRoot += "/"; } else if (resourceObj instanceof File) { // for File File fileRoot = (File) resourceObj; if (!fileRoot.exists()) { throw new MustacheException(fileRoot + " does not exist"); } if (!fileRoot.isDirectory()) { throw new MustacheException(fileRoot + " is not a directory"); } } else if (resourceObj == null) { // for null } else { throw new MustacheException("Invalid constructor parameter: " + resourceObj.toString()); } } this.resourceRoots = resourceRoots; } /** * Return a reader for accessing resource files. * * @param resourceName resource name relative to one of the fallback resource roots * @return resource file reader */ @Override public Reader getReader(String resourceName) { Exception lastException = null; for (Object resourceObj : this.resourceRoots) { try { InputStream is = null; if (resourceObj instanceof String) { // class resource loader only for String String resourceRoot = (String) resourceObj; ClassLoader ccl = Thread.currentThread().getContextClassLoader(); is = ccl.getResourceAsStream(resourceRoot + resourceName); } if (is == null) { File file; if (resourceObj instanceof String) { // for String file = new File((String) resourceObj, resourceName); } else if (resourceObj instanceof File) { // for File file = new File((File) resourceObj, resourceName); } else { // for null file = new File(resourceName); } if (file.exists() && file.isFile()) { try { is = new FileInputStream(file); } catch (FileNotFoundException e) { throw new MustacheException("Found file, could not open: " + file, e); } } } if (is == null) { throw new MustacheNotFoundException(resourceName); } else { return new BufferedReader(new InputStreamReader(is, "UTF-8")); } } catch (Exception e) { lastException = e; } } throw new MustacheNotFoundException(resourceName, lastException); } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/FragmentKey.java000066400000000000000000000014311241525561000331270ustar00rootroot00000000000000package com.github.mustachejava; /** * Used for indexing runtime compiled template text from lambdas. */ public class FragmentKey { public final TemplateContext tc; public final String templateText; public FragmentKey(TemplateContext tc, String templateText) { this.tc = tc; this.templateText = templateText; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FragmentKey that = (FragmentKey) o; if (!tc.equals(that.tc)) return false; if (!templateText.equals(that.templateText)) return false; return true; } @Override public int hashCode() { int result = tc.hashCode(); result = 31 * result + templateText.hashCode(); return result; } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/Iteration.java000066400000000000000000000005211241525561000326500ustar00rootroot00000000000000package com.github.mustachejava; import java.io.Writer; /** * This is the callback interface for iterating on a value. You can override the iterate * method in an ObjectHandler to change the types recognized by mustache.java as iterable. */ public interface Iteration { Writer next(Writer writer, Object next, Object[] scopes); } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/Mustache.java000066400000000000000000000031111241525561000324610ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.util.Node; import java.io.Writer; /** * The interface to Mustache objects */ public interface Mustache extends Code { /** * Append text to the mustache output. * @param text */ void append(String text); /** * Deep clone of the mustache object. * @return */ Object clone(); /** * Execute the mustache object with a given writer and a single scope context. * @param writer * @param scope * @return */ Writer execute(Writer writer, Object scope); /** * Execute the mustache with a given writer and an array of scope objects. The * scopes are searched right-to-left for references. * @param writer * @param scopes * @return */ Writer execute(Writer writer, Object[] scopes); /** * Get the underlying code objects. * @return */ Code[] getCodes(); /** * Execute the mustache to output itself. * @param writer */ void identity(Writer writer); /** * Initialize the mustache before executing. This is must be called at least once * and is normally called already by the time you have a mustache instance. */ void init(); /** * Change the underlying codes of the mustache implementation. * @param codes */ void setCodes(Code[] codes); /** * Only executes the codes. Does not append the text. * @param writer * @param scopes * @return */ Writer run(Writer writer, Object[] scopes); /** * Invert this mustache given output text. * * @param text * @return */ Node invert(String text); } MustacheException.java000066400000000000000000000015751241525561000342750ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; /** * Generally there is nothing you can do if it fails. */ public class MustacheException extends RuntimeException { private TemplateContext context; public MustacheException() { super(); } public MustacheException(String message) { super(message); } public MustacheException(String message, Throwable throwable) { super(message, throwable); } public MustacheException(String s, Throwable throwable, TemplateContext context) { super(s, throwable); this.context = context; } public MustacheException(Throwable throwable) { super(throwable); } @Override public String getMessage() { return context == null ? super.getMessage() : super.getMessage() + " @" + context; } public void setContext(TemplateContext context) { if (this.context == null) this.context = context; } } MustacheFactory.java000066400000000000000000000026331241525561000337420ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import java.io.Reader; import java.io.Writer; /** * Factory for creating codes */ public interface MustacheFactory { /** * Creates the visitor for compilation. * * @return visitor */ MustacheVisitor createMustacheVisitor(); /** * Given a resource name, construct a reader. * * @param resourceName used to find the resource * @return a reader */ Reader getReader(String resourceName); /** * This defines how "encoded" values are encoded. It defaults to * something appropriate for HTML output. * * @param value the unencoded value * @param writer where to encode the value */ void encode(String value, Writer writer); /** * The object handler knows how to transform names into fields and methods. * * @return the handler */ ObjectHandler getObjectHandler(); /** * Create a mustache given a resource name. * * @param name the name of the resource * @return the compiled mustache */ Mustache compile(String name); /** * Create a mustache given a reader and a name. * * @param reader the reader * @param name the name of the resource * @return the compiled mustache */ Mustache compile(Reader reader, String name); /** * Converts your arbitrary name to another name. * * @param from the tag to replace * @return the new tag */ String translate(String from); } MustacheNotFoundException.java000066400000000000000000000010331241525561000357370ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; /** * Mustache exception that provides the name of the missing mustache. */ public class MustacheNotFoundException extends MustacheException { private final String name; public MustacheNotFoundException(String name) { super("Template " + name + " not found"); this.name = name; } public MustacheNotFoundException(String name, Throwable throwable) { super("Template " + name + " not found", throwable); this.name = name; } public String getName() { return name; } } MustacheParser.java000066400000000000000000000246731241525561000335770ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.concurrent.atomic.AtomicInteger; /** * The parser generates callbacks into the MustacheFactory to build them. Do not use these * directly as you must manage the Mustache object lifecycle as well. *

*

* User: sam * Date: 5/14/11 * Time: 3:52 PM */ public class MustacheParser { public static final String DEFAULT_SM = "{{"; public static final String DEFAULT_EM = "}}"; private MustacheFactory mf; protected MustacheParser(MustacheFactory mf) { this.mf = mf; } public Mustache compile(String file) { Reader reader = mf.getReader(file); if (reader == null) { throw new MustacheNotFoundException(file); } return compile(reader, file); } public Mustache compile(Reader reader, String file) { return compile(reader, file, DEFAULT_SM, DEFAULT_EM); } public Mustache compile(Reader reader, String file, String sm, String em) { return compile(reader, null, new AtomicInteger(0), file, sm, em, true); } public Mustache compile(Reader reader, String file, String sm, String em, boolean startOfLine) { return compile(reader, null, new AtomicInteger(0), file, sm, em, startOfLine); } protected Mustache compile(final Reader reader, String tag, final AtomicInteger currentLine, String file, String sm, String em, boolean startOfLine) throws MustacheException { if (reader == null) { throw new MustacheException("Reader is null"); } Reader br; if (reader.markSupported()) { br = reader; } else { br = new BufferedReader(reader); } try { boolean sawCR = false; int startLine = currentLine.get(); MustacheVisitor mv = mf.createMustacheVisitor(); // Now we grab the mustache template boolean onlywhitespace = true; // Starting a new line boolean iterable = currentLine.get() != 0; currentLine.compareAndSet(0, 1); StringBuilder out = new StringBuilder(); try { int c; while ((c = br.read()) != -1) { if (c == '\r') { sawCR = true; continue; } // Increment the line if (c == '\n') { currentLine.incrementAndGet(); if (!iterable || (iterable && !onlywhitespace)) { if (sawCR) out.append("\r"); out.append("\n"); } out = write(mv, out, file, currentLine.intValue(), startOfLine); iterable = false; onlywhitespace = true; startOfLine = true; continue; } sawCR = false; // Check for a mustache start if (c == sm.charAt(0)) { br.mark(1); if (sm.length() == 1 || br.read() == sm.charAt(1)) { // Two mustaches, now capture command StringBuilder sb = new StringBuilder(); while ((c = br.read()) != -1) { br.mark(1); if (c == em.charAt(0)) { if (em.length() > 1) { if (br.read() == em.charAt(1)) { // Matched end break; } else { // Only one br.reset(); } } else break; } sb.append((char) c); } final String command = mf.translate(sb.toString()); if (command.length() == 0) { throw new MustacheException("Empty mustache in " + file + ":" + currentLine); } final char ch = command.charAt(0); final String variable = command.substring(1).trim(); switch (ch) { case '#': case '^': case '<': case '$': { boolean oldStartOfLine = startOfLine; startOfLine = startOfLine & onlywhitespace; int line = currentLine.get(); final Mustache mustache = compile(br, variable, currentLine, file, sm, em, startOfLine); int lines = currentLine.get() - line; if (!onlywhitespace || lines == 0) { write(mv, out, file, currentLine.intValue(), oldStartOfLine); } out = new StringBuilder(); switch (ch) { case '#': mv.iterable(new TemplateContext(sm, em, file, line, startOfLine), variable, mustache); break; case '^': mv.notIterable(new TemplateContext(sm, em, file, line, startOfLine), variable, mustache); break; case '<': mv.extend(new TemplateContext(sm, em, file, line, startOfLine), variable, mustache); break; case '$': mv.name(new TemplateContext(sm, em, file, line, startOfLine), variable, mustache); break; } iterable = lines != 0; break; } case '/': { // Tag end if (!startOfLine || !onlywhitespace) { write(mv, out, file, currentLine.intValue(), startOfLine); } if (!variable.equals(tag)) { throw new MustacheException( "Mismatched start/end tags: " + tag + " != " + variable + " in " + file + ":" + currentLine); } return mv.mustache(new TemplateContext(sm, em, file, 0, startOfLine)); } case '>': { out = write(mv, out, file, currentLine.intValue(), startOfLine); startOfLine = startOfLine & onlywhitespace; mv.partial(new TemplateContext(sm, em, file, currentLine.get(), startOfLine), variable); break; } case '{': { out = write(mv, out, file, currentLine.intValue(), startOfLine); // Not escaped String name = variable; if (em.charAt(1) != '}') { name = variable.substring(0, variable.length() - 1); } else { if (br.read() != '}') { throw new MustacheException( "Improperly closed variable in " + file + ":" + currentLine); } } final String finalName = name; mv.value(new TemplateContext(sm, em, file, currentLine.get(), false), finalName, false); break; } case '&': { // Not escaped out = write(mv, out, file, currentLine.intValue(), startOfLine); mv.value(new TemplateContext(sm, em, file, currentLine.get(), false), variable, false); break; } case '%': // Pragmas if (!onlywhitespace) { out = write(mv, out, file, currentLine.intValue(), startOfLine); } int index = variable.indexOf(" "); String pragma; String args; if (index == -1) { pragma = variable; args = null; } else { pragma = variable.substring(0, index); args = variable.substring(index + 1); } mv.pragma(new TemplateContext(sm, em, file, currentLine.get(), startOfLine), pragma, args); break; case '!': // Comment out = write(mv, out, file, currentLine.intValue(), startOfLine); break; case '=': // Change delimiters out = write(mv, out, file, currentLine.intValue(), startOfLine); String delimiters = command.replaceAll("\\s+", ""); int length = delimiters.length(); if (length > 6 || length / 2 * 2 != length) { throw new MustacheException("Invalid delimiter string"); } sm = delimiters.substring(1, length / 2); em = delimiters.substring(length / 2, length - 1); break; default: { if (c == -1) { throw new MustacheException( "Improperly closed variable in " + file + ":" + currentLine); } // Reference out = write(mv, out, file, currentLine.intValue(), startOfLine); mv.value(new TemplateContext(sm, em, file, currentLine.get(), false), command.trim(), true); break; } } // Additional text is no longer at the start of the line startOfLine = false; continue; } else { // Only one br.reset(); } } onlywhitespace = onlywhitespace && (c == ' ' || c == '\t' || c == '\r'); out.append((char) c); } write(mv, out, file, currentLine.intValue(), startOfLine); if (tag == null) { br.close(); } else { throw new MustacheException("Failed to close '" + tag + "' tag at line " + startLine); } } catch (IOException e) { throw new MustacheException("Failed to read", e); } mv.eof(new TemplateContext(sm, em, file, currentLine.get(), startOfLine)); return mv.mustache(new TemplateContext(sm, em, file, 0, startOfLine)); } catch (MustacheException me) { try { // We're going to blow the whole stack of compilation and // close the readers on the way up. br.close(); } catch (IOException e) { // Ignore IOExceptions on close } throw me; } } /** * Ignore empty strings and append to the previous code if it was also a write. */ private StringBuilder write(MustacheVisitor mv, StringBuilder out, String file, int line, boolean startOfLine) { String text = out.toString(); mv.write(new TemplateContext(null, null, file, line, startOfLine), text); return new StringBuilder(); } } MustacheResolver.java000066400000000000000000000003201241525561000341230ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import java.io.Reader; /** * Resolves mustache resources. * * @author Simon Buettner */ public interface MustacheResolver { Reader getReader(String resourceName); } MustacheVisitor.java000066400000000000000000000016451241525561000337740ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; /** * Callbacks from the parser as a mustache template is parsed. */ public interface MustacheVisitor { // Mustache Mustache mustache(TemplateContext templateContext); // Specified void iterable(TemplateContext templateContext, String variable, Mustache mustache); void notIterable(TemplateContext templateContext, String variable, Mustache mustache); void partial(TemplateContext templateContext, String variable); void value(TemplateContext templateContext, String variable, boolean encoded); void write(TemplateContext templateContext, String text); void pragma(TemplateContext templateContext, String pragma, String args); // Internal void eof(TemplateContext templateContext); // Extension void extend(TemplateContext templateContext, String variable, Mustache mustache); void name(TemplateContext templateContext, String variable, Mustache mustache); } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/ObjectHandler.java000066400000000000000000000032021241525561000334150ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.util.Wrapper; import java.io.Writer; /** * The ObjectHandler is responsible for creating wrappers to find values * in scopes at runtime and to coerce those results to the appropriate Java types */ public interface ObjectHandler { /** * Find a value named "name" in the array of scopes in reverse order. * @param name * @param scopes * @return */ Wrapper find(String name, Object[] scopes); /** * Coerce results to Java native iterables, functions, callables. * @param object * @return */ Object coerce(Object object); /** * Iterate over an object by calling Iteration.next for each value. * @param iteration * @param writer * @param object * @param scopes * @return */ Writer iterate(Iteration iteration, Writer writer, Object object, Object[] scopes); /** * Call Iteration.next() either 0 (true) or 1 (fale) times. * @param iteration * @param writer * @param object * @param scopes * @return */ Writer falsey(Iteration iteration, Writer writer, Object object, Object[] scopes); /** * Each call site has its own binding to allow for fine grained caching without * a separate parallel hierarchy of objects. * @param name * @param tc * @param code * @return */ Binding createBinding(String name, TemplateContext tc, Code code); /** * Turns an object into the string representation that should be displayed * in templates. * * * @param object the object to be displayed * @return a string representation of the object. */ String stringify(Object object); } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/PragmaHandler.java000066400000000000000000000002041241525561000334150ustar00rootroot00000000000000package com.github.mustachejava; public interface PragmaHandler { Code handle(TemplateContext tc, String pragma, String args); } TemplateContext.java000066400000000000000000000027571241525561000337700ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; public final class TemplateContext { private final String sm; private final String em; private final String file; private final int line; private final boolean startOfLine; public TemplateContext(String sm, String em, String file, int line, boolean startOfLine) { this.sm = sm; this.em = em; this.file = file; this.line = line; this.startOfLine = startOfLine; } public boolean startOfLine() { return startOfLine; } public String startChars() { return sm; } public String endChars() { return em; } public String file() { return file; } public int line() { return line; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; TemplateContext that = (TemplateContext) o; if (line != that.line) return false; if (em != null ? !em.equals(that.em) : that.em != null) return false; if (file != null ? !file.equals(that.file) : that.file != null) return false; if (sm != null ? !sm.equals(that.sm) : that.sm != null) return false; return true; } @Override public int hashCode() { int result = sm != null ? sm.hashCode() : 0; result = 31 * result + (em != null ? em.hashCode() : 0); result = 31 * result + (file != null ? file.hashCode() : 0); result = 31 * result + line; return result; } public String toString() { return "[" + file + ":" + line + "]"; } } TemplateFunction.java000066400000000000000000000004551241525561000341220ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import com.google.common.base.Function; /** * Use this function if you to implement additional functions/lambdas * (eg. `{{#func1}}`) and want mustache.java to reparse their results again. */ public interface TemplateFunction extends Function { } TypeCheckingHandler.java000066400000000000000000000056221241525561000345150ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.BaseObjectHandler; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.io.Writer; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; /** * Rather than pulling values this looks only at types. To check if a template matches the shape * of your view classes, pass in the set of classes you expect to have at runtime in the scope. *

* User: sam * Date: 2/3/13 * Time: 9:43 AM */ public class TypeCheckingHandler extends BaseObjectHandler { /** * Find a value named "name" in the array of scopes in reverse order. * * @param name * @param scopes * @return */ @Override public Wrapper find(String name, Object[] scopes) { for (Object scope : scopes) { if (!(scope instanceof Class)) { throw new MustacheException("Only classes allowed with this object handler: " + scope); } } int length = scopes.length; if (length == 0) { throw new MustacheException("Empty scopes"); } for (int i = length - 1; i >= 0; i--) { Object scope = scopes[i]; if (scope == null || !(scope instanceof Class)) { throw new MustacheException("Invalid scope: " + scope); } Class scopeClass = (Class) scope; final AccessibleObject member = findMember(scopeClass, name); if (member != null) { return new Wrapper() { @Override public Object call(Object[] scopes) throws GuardException { if (member instanceof Field) { return ((Field) member).getType(); } else if (member instanceof Method) { return ((Method) member).getReturnType(); } else { throw new MustacheException("Member not a field or method: " + member); } } }; } } throw new MustacheException("Failed to find matching field or method: " + name + " in " + Arrays.asList(scopes)); } @Override public Binding createBinding(final String name, TemplateContext tc, Code code) { return new Binding() { @Override public Object get(Object[] scopes) { return find(name, scopes).call(scopes); } }; } @Override public Writer falsey(Iteration iteration, Writer writer, Object object, Object[] scopes) { // Iterate once in either case return iterate(iteration, writer, object, scopes); } @Override public Writer iterate(Iteration iteration, Writer writer, Object object, Object[] scopes) { return iteration.next(writer, object, scopes); } @Override public String stringify(Object object) { if (object instanceof Class) { Class c = (Class) object; return "[" + c.getSimpleName() + "]"; } throw new MustacheException("Object was not a class: " + object); } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codes/000077500000000000000000000000001241525561000311465ustar00rootroot00000000000000DefaultCode.java000066400000000000000000000137401241525561000341160ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.Binding; import com.github.mustachejava.Code; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.util.Node; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.TemplateContext; import java.io.IOException; import java.io.Writer; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; /** * Simplest possible code implementaion with some default shared behavior */ public class DefaultCode implements Code, Cloneable { // Final once init() is complete protected String appended; protected Mustache mustache; protected final ObjectHandler oh; protected final String name; protected final TemplateContext tc; protected final String type; protected final boolean returnThis; protected final Binding binding; protected final DefaultMustacheFactory df; public Object clone() { Set seen = new HashSet(); seen.add(this); return clone(seen); } public Object clone(Set seen) { try { DefaultCode code = (DefaultCode) super.clone(); Code[] codes = code.getCodes(); if (codes != null) { // Create a new set of codes codes = codes.clone(); for (int i = 0; i < codes.length; i++) { // If the code hasn't been seen before // use this one, else clone it. if (!seen.add(codes[i])) { codes[i] = (Code) codes[i].clone(seen); seen.remove(codes[i]); } } code.setCodes(codes); } if (mustache != null) { if (!seen.add(mustache)) { code.mustache = (Mustache) mustache.clone(seen); seen.remove(mustache); } } return code; } catch (CloneNotSupportedException e) { throw new MustacheException("Clone not supported"); } } public DefaultCode() { this(null, null, null, null, null); } public DefaultCode(TemplateContext tc, DefaultMustacheFactory df, Mustache mustache, String name, String type) { this.df = df; this.oh = df == null ? null : df.getObjectHandler(); this.mustache = mustache; this.type = type; this.name = name; this.tc = tc; this.binding = oh == null ? null : oh.createBinding(name, tc, this); this.returnThis = ".".equals(name); } @Override public Node invert(Node node, String text, AtomicInteger position) { int start = position.get(); Code[] codes = getCodes(); if (codes != null) { for (Code code : codes) { Node invert = code.invert(node, text, position); if (invert == null) { position.set(start); return null; } } } if (appended == null) { return node; } else if (text.substring(position.get()).startsWith(appended)) { position.addAndGet(appended.length()); return node; } else { position.set(start); return null; } } public Code[] getCodes() { return mustache == null ? null : mustache.getCodes(); } @Override public synchronized void init() { filterText(); Code[] codes = getCodes(); if (codes != null) { for (Code code : codes) { code.init(); } } } protected void filterText() { if (df != null && appended != null) { appended = df.filterText(appended, tc.startOfLine()); } } public void setCodes(Code[] newcodes) { mustache.setCodes(newcodes); } public Object get(Object[] scopes) { if (returnThis) { int length = scopes == null ? 0 : scopes.length; return length == 0 ? null : scopes[length - 1]; } try { return binding.get(scopes); } catch (MustacheException e) { e.setContext(tc); throw e; } catch (Throwable e) { throw new MustacheException(e.getMessage(), e, tc); } } @Override public Writer execute(Writer writer, Object scope) { return execute(writer, new Object[]{scope}); } /** * The default behavior is to run the codes and append the captured text. * * @param writer The writer to write the output to * @param scopes The scopes to evaluate the embedded names against. */ @Override public Writer execute(Writer writer, Object[] scopes) { return appendText(run(writer, scopes)); } @Override public void identity(Writer writer) { try { if (name != null) { tag(writer, type); if (getCodes() != null) { runIdentity(writer); tag(writer, "/"); } } appendText(writer); } catch (IOException e) { throw new MustacheException(e); } } protected void runIdentity(Writer writer) { int length = getCodes().length; for (int i = 0; i < length; i++) { getCodes()[i].identity(writer); } } protected void tag(Writer writer, String tag) throws IOException { writer.write(tc.startChars()); writer.write(tag); writer.write(name); writer.write(tc.endChars()); } protected Writer appendText(Writer writer) { if (appended != null) { try { writer.write(appended); } catch (IOException e) { throw new MustacheException(e); } } return writer; } protected Writer run(Writer writer, Object[] scopes) { return mustache == null ? writer : mustache.run(writer, scopes); } @Override public void append(String text) { if (appended == null) { appended = text; } else { appended = appended + text; } } // Expand the current set of scopes protected Object[] addScope(Object[] scopes, Object scope) { if (scope == null) { return scopes; } else { int length = scopes.length; Object[] newScopes = new Object[length + 1]; System.arraycopy(scopes, 0, newScopes, 0, length); newScopes[length] = scope; return newScopes; } } @Override public String getName() { return name; } } DefaultMustache.java000066400000000000000000000026461241525561000350200ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.Code; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.util.Node; import java.io.Writer; import java.util.concurrent.atomic.AtomicInteger; /** * Default Mustache */ public class DefaultMustache extends DefaultCode implements Mustache { private Code[] codes; private boolean inited = false; public DefaultMustache(TemplateContext tc, DefaultMustacheFactory df, Code[] codes, String name) { super(tc, df, null, name, null); setCodes(codes); } @Override public Code[] getCodes() { return codes; } public Writer run(Writer writer, Object[] scopes) { if (codes != null) { for (Code code : codes) { writer = code.execute(writer, scopes); } } return writer; } /** * Invert this mustache given output text. * * @param text * @return */ @Override public Node invert(String text) { return invert(new Node(), text, new AtomicInteger(0)); } @Override public void setCodes(Code[] newcodes) { codes = newcodes; } @Override public void identity(Writer writer) { // No self output at the top level runIdentity(writer); } @Override public synchronized void init() { if (!inited) { inited = true; super.init(); } } } DepthLimitedWriter.java000066400000000000000000000006711241525561000355070ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import java.io.FilterWriter; import java.io.Writer; import java.util.concurrent.atomic.AtomicInteger; class DepthLimitedWriter extends FilterWriter { private AtomicInteger depth = new AtomicInteger(0); public DepthLimitedWriter(Writer writer) { super(writer); } public int incr() { return depth.incrementAndGet(); } public int decr() { return depth.decrementAndGet(); } } ExtendCode.java000066400000000000000000000051271241525561000337610ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.*; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * Extending a template through in-place replacement of the overridden codes. *

* User: sam * Date: 11/27/11 * Time: 10:39 AM */ public class ExtendCode extends PartialCode { private final DefaultMustacheFactory mf; public ExtendCode(TemplateContext tc, DefaultMustacheFactory mf, Mustache codes, String name) throws MustacheException { super(tc, mf, codes, "<", name); this.mf = mf; } private Code[] replaceCodes(Code[] supercodes, Map replaceMap, Set seen) { Code[] newcodes = supercodes.clone(); for (int i = 0; i < supercodes.length; i++) { Code code = supercodes[i]; if (seen.add(code)) { if (code instanceof ExtendNameCode) { ExtendNameCode enc = (ExtendNameCode) code; ExtendNameCode extendReplaceCode = replaceMap.get(enc.getName()); if (extendReplaceCode != null) { ExtendNameCode newcode = (ExtendNameCode) (newcodes[i] = (Code) extendReplaceCode.clone()); // We need to set the appended text of the new code to that of the old code newcode.appended = enc.appended; } else { enc.setCodes(replaceCodes(enc.getCodes(), replaceMap, seen)); } } else { Code[] codes = code.getCodes(); if (codes != null) { code.setCodes(replaceCodes(codes, replaceMap, seen)); } } seen.remove(code); } } return newcodes; } @Override public synchronized void init() { filterText(); Map replaceMap = new HashMap(); for (Code code : mustache.getCodes()) { if (code instanceof ExtendNameCode) { // put name codes in the map ExtendNameCode erc = (ExtendNameCode) code; replaceMap.put(erc.getName(), erc); erc.init(); } else if (code instanceof WriteCode) { // ignore text } else { // fail on everything else throw new IllegalArgumentException( "Illegal code in extend section: " + code.getClass().getName()); } } Mustache original = mf.compilePartial(partialName()); partial = (Mustache) original.clone(); Code[] supercodes = partial.getCodes(); // recursively replace named sections with replacements Set seen = new HashSet(); seen.add(partial); partial.setCodes(replaceCodes(supercodes, replaceMap, seen)); } } ExtendNameCode.java000066400000000000000000000010071241525561000345530ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.TemplateContext; /** * Name a section: {{$name}}...{{/name}} */ public class ExtendNameCode extends DefaultCode { public ExtendNameCode(TemplateContext templateContext, DefaultMustacheFactory df, Mustache mustache, String variable) { super(templateContext, df, mustache, variable, "$"); } public String getName() { return name; } } IterableCode.java000066400000000000000000000121701241525561000342550ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.FragmentKey; import com.github.mustachejava.Iteration; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.TemplateFunction; import com.github.mustachejava.util.LatchedWriter; import com.github.mustachejava.util.Node; import com.google.common.base.Function; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import static com.github.mustachejava.util.NodeValue.list; public class IterableCode extends DefaultCode implements Iteration { private final ExecutorService les; public IterableCode(TemplateContext tc, DefaultMustacheFactory df, Mustache mustache, String variable, String type) { super(tc, df, mustache, variable, type); les = df.getExecutorService(); } public IterableCode(TemplateContext tc, DefaultMustacheFactory df, Mustache mustache, String variable) { this(tc, df, mustache, variable, "#"); } @Override public Writer execute(Writer writer, final Object[] scopes) { Object resolved = get(scopes); writer = handle(writer, resolved, scopes); appendText(writer); return writer; } protected Writer handle(Writer writer, Object resolved, Object[] scopes) { if (resolved != null) { if (resolved instanceof Function) { writer = handleFunction(writer, (Function) resolved, scopes); } else if (resolved instanceof Callable) { writer = handleCallable(writer, (Callable) resolved, scopes); } else { writer = execute(writer, resolved, scopes); } } return writer; } protected Writer handleCallable(Writer writer, final Callable callable, final Object[] scopes) { if (les == null) { try { writer = execute(writer, callable.call(), scopes); } catch (Exception e) { throw new MustacheException(e); } } else { // Flush the current writer try { writer.flush(); } catch (IOException e) { throw new MustacheException("Failed to flush writer", e); } final Writer originalWriter = writer; final LatchedWriter latchedWriter = new LatchedWriter(writer); writer = latchedWriter; // Scopes must not cross thread boundaries as they // are thread locally reused final Object[] newScopes = scopes.clone(); les.execute(new Runnable() { @Override public void run() { try { Object call = callable.call(); Writer subWriter = handle(originalWriter, call, newScopes); // Wait for the subwriter to complete if (subWriter instanceof LatchedWriter) { ((LatchedWriter) subWriter).await(); } // Tell the replacement writer that we are done latchedWriter.done(); } catch (Throwable e) { latchedWriter.failed(e); } } }); } return writer; } @SuppressWarnings("unchecked") protected Writer handleFunction(Writer writer, Function function, Object[] scopes) { StringWriter sw = new StringWriter(); runIdentity(sw); if (function instanceof TemplateFunction) { Object newtemplate = function.apply(sw.toString()); if (newtemplate != null) { String templateText = newtemplate.toString(); writer = writeTemplate(writer, templateText, scopes); } } else { try { StringWriter capture = new StringWriter(); writeTemplate(capture, sw.toString(), scopes).close(); Object apply = function.apply(capture.toString()); if (apply != null) { writer.write(apply.toString()); } } catch (IOException e) { throw new MustacheException("Failed to write function result", e); } } return writer; } protected Writer writeTemplate(Writer writer, String templateText, Object[] scopes) { return df.getFragment(new FragmentKey(tc, templateText)).execute(writer, scopes); } protected Writer execute(Writer writer, Object resolve, Object[] scopes) { return oh.iterate(this, writer, resolve, scopes); } public Writer next(Writer writer, Object next, Object... scopes) { Object[] iteratorScopes = addScope(scopes, next); writer = run(writer, iteratorScopes); return writer; } @Override public Node invert(Node node, String text, AtomicInteger position) { int start = position.get(); List nodes = new ArrayList(); Node invert; while ((invert = mustache.invert(new Node(), text, position)) != null) { nodes.add(invert); } node.put(name, list(nodes)); if (appended == null) { return node; } else if (text.substring(position.get()).startsWith(appended)) { position.addAndGet(appended.length()); return node; } else { position.set(start); return null; } } } NotIterableCode.java000066400000000000000000000024271241525561000347420ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.TemplateContext; import java.io.Writer; import java.util.concurrent.Callable; /** * Runs the enclosed template once if the value is falsey. */ public class NotIterableCode extends IterableCode { public NotIterableCode(TemplateContext templateContext, DefaultMustacheFactory df, Mustache mustache, String variable) { super(templateContext, df, mustache, variable, "^"); } @Override public Writer execute(Writer writer, final Object[] scopes) { Object resolved = get(scopes); writer = handle(writer, resolved, scopes); appendText(writer); return writer; } protected Writer handle(Writer writer, Object resolved, Object[] scopes) { if (resolved instanceof Callable) { writer = handleCallable(writer, (Callable) resolved, scopes); } else { writer = execute(writer, resolved, scopes); } return writer; } @Override protected Writer execute(Writer writer, Object resolve, Object[] scopes) { return oh.falsey(this, writer, resolve, scopes); } @Override public Writer next(Writer writer, Object object, Object[] scopes) { return run(writer, scopes); } } PartialCode.java000066400000000000000000000047161241525561000341310ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.*; import java.io.IOException; import java.io.Writer; public class PartialCode extends DefaultCode { protected final String extension; protected final String dir; protected Mustache partial; protected int recrusionLimit; protected PartialCode(TemplateContext tc, DefaultMustacheFactory df, Mustache mustache, String type, String variable) { super(tc, df, mustache, variable, type); // Use the name of the parent to get the name of the partial String file = tc.file(); int dotindex = file.lastIndexOf("."); extension = dotindex == -1 ? "" : file.substring(dotindex); int slashindex = file.lastIndexOf("/"); dir = file.substring(0, slashindex + 1); recrusionLimit = df.getRecursionLimit(); } public PartialCode(TemplateContext tc, DefaultMustacheFactory cf, String variable) { this(tc, cf, null, ">", variable); } @Override public void identity(Writer writer) { try { if (name != null) { super.tag(writer, type); } appendText(writer); } catch (IOException e) { throw new MustacheException(e); } } @Override public Code[] getCodes() { return partial == null ? null : partial.getCodes(); } @Override public void setCodes(Code[] newcodes) { partial.setCodes(newcodes); } @Override public Writer execute(Writer writer, final Object[] scopes) { DepthLimitedWriter depthLimitedWriter; if (writer instanceof DepthLimitedWriter) { depthLimitedWriter = (DepthLimitedWriter) writer; } else { depthLimitedWriter = new DepthLimitedWriter(writer); } if (depthLimitedWriter.incr() > recrusionLimit) { throw new MustacheException("Maximum partial recursion limit reached: " + recrusionLimit); } Writer execute = partial.execute(depthLimitedWriter, scopes); depthLimitedWriter.decr(); return appendText(execute); } @Override public synchronized void init() { filterText(); partial = df.compilePartial(partialName()); if (partial == null) { throw new MustacheException("Failed to compile partial: " + name); } } /** * Builds the file name to be included by this partial tag. Default implementation ppends the tag contents with * the current file's extension. * * @return The filename to be included by this partial tag */ protected String partialName() { return df.resolvePartialPath(dir, name, extension); } } ValueCode.java000066400000000000000000000113371241525561000336060ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.FragmentKey; import com.github.mustachejava.MustacheException; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.util.LatchedWriter; import com.github.mustachejava.util.Node; import com.google.common.base.Function; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.github.mustachejava.MustacheParser.DEFAULT_EM; import static com.github.mustachejava.MustacheParser.DEFAULT_SM; import static com.github.mustachejava.util.NodeValue.value; /** * Output a value */ public class ValueCode extends DefaultCode { private final boolean encoded; private final ExecutorService les; @Override public void identity(Writer writer) { try { if (name != null) { writer.write(tc.startChars()); if (!encoded) { writer.write("{"); } writer.write(type); writer.write(name); if (!encoded) { writer.write("}"); } writer.write(tc.endChars()); } appendText(writer); } catch (IOException e) { throw new MustacheException(e); } } public ValueCode(TemplateContext tc, DefaultMustacheFactory df, String variable, boolean encoded) { super(tc, df, null, variable, ""); this.encoded = encoded; les = df.getExecutorService(); } @Override public Writer execute(Writer writer, final Object[] scopes) { try { final Object object = get(scopes); if (object != null) { if (object instanceof Function) { handleFunction(writer, (Function) object, scopes); } else if (object instanceof Callable) { return handleCallable(writer, (Callable) object, scopes); } else { execute(writer, oh.stringify(object)); } } return super.execute(writer, scopes); } catch (Exception e) { throw new MustacheException("Failed to get value for " + name, e, tc); } } protected Writer handleCallable(Writer writer, final Callable callable, final Object[] scopes) throws Exception { if (les == null) { Object call = callable.call(); execute(writer, call == null ? null : oh.stringify(call)); return super.execute(writer, scopes); } else { // Flush the current writer try { writer.flush(); } catch (IOException e) { throw new MustacheException("Failed to flush writer", e); } final LatchedWriter latchedWriter = new LatchedWriter(writer); final Writer finalWriter = writer; les.execute(new Runnable() { @Override public void run() { try { Object call = callable.call(); execute(finalWriter, call == null ? null : oh.stringify(call)); latchedWriter.done(); } catch (Throwable e) { latchedWriter.failed(e); } } }); return super.execute(latchedWriter, scopes); } } @SuppressWarnings("unchecked") protected void handleFunction(Writer writer, Function function, Object[] scopes) throws IOException { String value; Object newtemplate = function.apply(null); if (newtemplate == null) { value = ""; } else { String templateText = newtemplate.toString(); StringWriter sw = new StringWriter(); TemplateContext newTC = new TemplateContext(DEFAULT_SM, DEFAULT_EM, tc.file(), tc.line(), tc.startOfLine()); df.getFragment(new FragmentKey(newTC, templateText)).execute(sw, scopes).close(); value = sw.toString(); } execute(writer, value); } protected void execute(Writer writer, String value) throws IOException { // Treat null values as the empty string if (value != null) { if (encoded) { df.encode(value, writer); } else { writer.write(value); } } } private Pattern compiledAppended; @Override public Node invert(Node node, String text, AtomicInteger position) { if (compiledAppended == null) { if (appended == null) { compiledAppended = Pattern.compile("$"); } else { compiledAppended = Pattern.compile(appended); } } int start = position.get(); Matcher matcher = compiledAppended.matcher(text); if (matcher.find(position.get())) { String value = text.substring(start, matcher.start()); position.set(matcher.start() + matcher.group(0).length()); node.put(name, value(value)); return node; } else { return null; } } } WriteCode.java000066400000000000000000000020541241525561000336200ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/codespackage com.github.mustachejava.codes; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.util.Node; import java.io.Writer; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Write template text. */ public class WriteCode extends DefaultCode { public WriteCode(TemplateContext tc, DefaultMustacheFactory df, String text) { super(tc, df, null, null, null); super.append(text); } @Override public void identity(Writer writer) { execute(writer, null); } private Pattern compiledAppended; @Override public Node invert(Node node, String text, AtomicInteger position) { if (compiledAppended == null) { compiledAppended = Pattern.compile(appended); } Matcher matcher = compiledAppended.matcher(text); if (matcher.find(position.get())) { position.set(matcher.start() + matcher.group(0).length()); return node; } else { return null; } } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/functions/000077500000000000000000000000001241525561000320615ustar00rootroot00000000000000BundleFunctions.java000066400000000000000000000130101241525561000357420ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import java.util.Locale; import java.util.ResourceBundle; import com.github.mustachejava.TemplateFunction; import com.google.common.base.Function; /** * Factory for Mustache.java translation functions based on localized Resource bundles. * * Example with a class: *

 * public class ... {
 *     Function trans = BundleFunctions.newPreTranslate("com.project.locale", Locale.US);
 *     ...
 * }
 * 
* * Example with a map: *
 * Map scopes =  new HashMap();
 * scopes.put("trans", BundleFunctions.newPostTranslateNullableLabel("com.project.locale", Locale.US);
 * ...
 * 
* * Usage in template: * {@code {{#trans}}TranslatedLabel1{{/trans}}} * * @author R.A. Porter */ public class BundleFunctions { private static abstract class BundleFunc { protected final ResourceBundle res; protected final boolean returnLabels; protected BundleFunc(String bundle, Locale locale, boolean returnLabels) { this.res = ResourceBundle.getBundle(bundle, locale); this.returnLabels = returnLabels; } final protected String lookup(String key) { if (res.containsKey(key)) { return res.getString(key); // return translation } else { return returnLabels ? key : null; } } } static class PreTranslateFunc extends BundleFunc implements TemplateFunction { private PreTranslateFunc(String bundle, Locale locale, boolean returnLabels) { super(bundle, locale, returnLabels); } @Override public String apply(String input) { return super.lookup(input); } } static class PostTranslateFunc extends BundleFunc implements Function { private PostTranslateFunc(String bundle, Locale locale, boolean returnLabels) { super(bundle, locale, returnLabels); } @Override public Object apply(Object input) { return super.lookup((String) input); } } /** * Returns a Function that operates prior to template evaluation and returns unknown keys intact. *

* Given the following HTML: *

   * {{#trans}}Label1{{/trans}}
   * {{#trans}}Label.unknown{{/trans}}
   * {{#trans}}Label.{{replaceMe}}{{/trans}}
   * 
* and the following properties in the provided bundle: *
   * Label1=hello
   * Label.replaced=world
   * 
* and a mapping from {@code replaceMe} to the value {@code replaced}, the following output * will be generated: *
   * hello
   * Label.unknown
   * Label.replaced
   * 
* * @param bundle name of the resource bundle * @param locale translation locale * @return Function that operates prior to template evaluation and returns unknown keys intact */ public static Function newPreTranslate(String bundle, Locale locale) { return new PreTranslateFunc(bundle, locale, true); } /** * Returns a Function that operates prior to template evaluation and returns nulls for unknown keys. *

* Given the following HTML: *

   * {{#trans}}Label1{{/trans}}
   * {{#trans}}Label.unknown{{/trans}}
   * {{#trans}}Label.{{replaceMe}}{{/trans}}
   * 
* and the following properties in the provided bundle: *
   * Label1=hello
   * Label.replaced=world
   * 
* and a mapping from {@code replaceMe} to the value {@code replaced}, the following output * will be generated: *
   * hello
   * 
* * @param bundle name of the resource bundle * @param locale translation locale * @return Function that operates prior to template evaluation and returns nulls for unknown keys */ public static Function newPreTranslateNullableLabel(String bundle, Locale locale) { return new PreTranslateFunc(bundle, locale, false); } /** * Returns a Function that operates after template evaluation and returns unknown keys intact. *

* Given the following HTML: *

   * {{#trans}}Label1{{/trans}}
   * {{#trans}}Label.unknown{{/trans}}
   * {{#trans}}Label.{{replaceMe}}{{/trans}}
   * 
* and the following properties in the provided bundle: *
   * Label1=hello
   * Label.replaced=world
   * 
* and a mapping from {@code replaceMe} to the value {@code replaced}, the following output * will be generated: *
   * hello
   * Label.unknown
   * world
   * 
* * @param bundle name of the resource bundle * @param locale translation locale * @return Function that operates after template evaluation and returns unknown keys intact */ public static Function newPostTranslate(String bundle, Locale locale) { return new PostTranslateFunc(bundle, locale, true); } /** * Returns a Function that operates after template evaluation and returns nulls for unknown keys. *

* Given the following HTML: *

   * {{#trans}}Label1{{/trans}}
   * {{#trans}}Label.unknown{{/trans}}
   * {{#trans}}Label.{{replaceMe}}{{/trans}}
   * 
* and the following properties in the provided bundle: *
   * Label1=hello
   * Label.replaced=world
   * 
* and a mapping from {@code replaceMe} to the value {@code replaced}, the following output * will be generated: *
   * hello
   * world
   * 
* * @param bundle name of the resource bundle * @param locale translation locale * @return Function that operates after template evaluation and returns nulls for unknown keys */ public static Function newPostTranslateNullableLabel(String bundle, Locale locale) { return new PostTranslateFunc(bundle, locale, false); } } CommentFunction.java000066400000000000000000000013551241525561000357610ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import com.google.common.base.Function; /** * Mustache.java block comment function. * * Usage code with a class: * public class ... { * CommentFunction comment = new CommentFunction(); * ... * } * * Usage code with a Map: * HashMap scopes = new HashMap(); * scopes.put("comment", new CommentFunction()); * ... * * Usage in template: * ... {{#comment}} Your multiline comment text {{/comment}} ... * * @author gw0 [http://gw.tnode.com/] */ public class CommentFunction implements Function { /** Ignore contents of comment block. */ @Override public String apply(String input) { return ""; } } TranslateBundleFunction.java000066400000000000000000000025271241525561000374500ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import com.github.mustachejava.TemplateFunction; import java.util.Locale; import java.util.ResourceBundle; /** * Mustache.java translation function based on localized ResourceBundles. * * Usage code with a class: * public class ... { * TemplateFunction trans = new TranslateBundleFunction("com.project.locale", Locale.US); * ... * } * * Usage code with a Map: * HashMap scopes = new HashMap(); * scopes.put("trans", new TranslateBundleFunction("com.project.locale", Locale.US)); * ... * * Usage in template: * ... {{#trans}}TranslatedLabel1{{/trans}} ... * * @author gw0 [http://gw.tnode.com/] */ public class TranslateBundleFunction implements TemplateFunction { private ResourceBundle res; /** * Constructor for a Mustache.java translation function. * * @param bundle resource bundle name * @param locale translation locale */ public TranslateBundleFunction(String bundle, Locale locale) { this.res = ResourceBundle.getBundle(bundle, locale); } /** Return translation from the localized ResourceBundle. */ @Override public String apply(String input) { if(res.containsKey(input)) { return res.getString(input); // return translation } else { return input; // return untranslated label } } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/jruby/000077500000000000000000000000001241525561000312045ustar00rootroot00000000000000JRubyObjectHandler.java000066400000000000000000000057001241525561000354520ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/jrubypackage com.github.mustachejava.jruby; import com.github.mustachejava.TemplateFunction; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.util.Wrapper; import org.jruby.RubyBoolean; import org.jruby.RubyHash; import org.jruby.RubyObject; import org.jruby.RubyProc; import org.jruby.RubySymbol; import org.jruby.embed.ScriptingContainer; import java.lang.reflect.Method; import java.util.List; public class JRubyObjectHandler extends ReflectionObjectHandler { private static final Method CALL_METHOD; private static ScriptingContainer sc = new ScriptingContainer(); static { try { CALL_METHOD = RubyHash.class.getMethod("callMethod", String.class); } catch (NoSuchMethodException e) { throw new AssertionError(e); } } @Override public Object coerce(Object object) { if (object instanceof RubyBoolean) { RubyBoolean rb = (RubyBoolean) object; return rb.toJava(Boolean.class); } if (object instanceof RubyProc) { final RubyProc proc = (RubyProc) object; return new TemplateFunction() { @Override public String apply(String s) { TemplateFunction fun = sc.getInstance(proc, TemplateFunction.class); return fun.apply(s); } }; } return object; } @Override protected Wrapper findWrapper(final int scopeIndex, final Wrapper[] wrappers, final List guards, final Object scope, final String name) { if (scope instanceof RubyHash) { RubyHash hash = (RubyHash) scope; final RubySymbol rs = RubySymbol.newSymbol(hash.getRuntime(), name); if (hash.containsKey(rs)) { guards.add(new Guard() { @Override public boolean apply(Object[] input) { return ((RubyHash) input[scopeIndex]).containsKey(rs); } }); return createWrapper(scopeIndex, wrappers, guards, MAP_METHOD, new Object[]{rs}); } else { guards.add(new Guard() { @Override public boolean apply(Object[] input) { return !((RubyHash) input[scopeIndex]).containsKey(rs); } }); } } if (scope instanceof RubyObject) { RubyObject ro = (RubyObject) scope; if (ro.respondsTo(name)) { guards.add(new Guard() { @Override public boolean apply(Object[] objects) { RubyObject scope = (RubyObject) objects[scopeIndex]; return scope.respondsTo(name); } }); return createWrapper(scopeIndex, wrappers, guards, CALL_METHOD, new Object[]{name}); } else { guards.add(new Guard() { @Override public boolean apply(Object[] objects) { RubyObject scope = (RubyObject) objects[scopeIndex]; return !scope.respondsTo(name); } }); } } return super.findWrapper(scopeIndex, wrappers, guards, scope, name); } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/000077500000000000000000000000001241525561000314755ustar00rootroot00000000000000BaseObjectHandler.java000066400000000000000000000121551241525561000355640ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.Binding; import com.github.mustachejava.Code; import com.github.mustachejava.Iteration; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.TemplateContext; import java.io.Writer; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; public abstract class BaseObjectHandler implements ObjectHandler { @Override public Object coerce(Object object) { return object; } @Override public Writer falsey(Iteration iteration, Writer writer, Object object, Object[] scopes) { if (object != null) { if (object instanceof Boolean) { if ((Boolean) object) { return writer; } } else if (object instanceof String) { if (!object.toString().equals("")) { return writer; } } else if (object instanceof List) { List list = (List) object; int length = list.size(); if (length > 0) return writer; } else if (object instanceof Iterable) { Iterable iterable = (Iterable) object; if (iterable.iterator().hasNext()) return writer; } else if (object instanceof Iterator) { Iterator iterator = (Iterator) object; if (iterator.hasNext()) return writer; } else if (object.getClass().isArray()) { int length = Array.getLength(object); if (length > 0) return writer; } else { // All other objects are truthy return writer; } } return iteration.next(writer, object, scopes); } @Override public abstract Binding createBinding(String name, TemplateContext tc, Code code); public Writer iterate(Iteration iteration, Writer writer, Object object, Object[] scopes) { if (object == null) return writer; if (object instanceof Boolean) { if (!(Boolean) object) { return writer; } } if (object instanceof String) { if (object.toString().equals("")) { return writer; } } if (object instanceof Iterable) { for (Object next : ((Iterable) object)) { writer = iteration.next(writer, coerce(next), scopes); } } else if (object instanceof Iterator) { Iterator iterator = (Iterator) object; while (iterator.hasNext()) { writer = iteration.next(writer, coerce(iterator.next()), scopes); } } else if (object.getClass().isArray()) { int length = Array.getLength(object); for (int i = 0; i < length; i++) { writer = iteration.next(writer, coerce(Array.get(object, i)), scopes); } } else { writer = iteration.next(writer, object, scopes); } return writer; } protected Field getField(Class aClass, String name) throws NoSuchFieldException { Field member; try { member = aClass.getDeclaredField(name); } catch (NoSuchFieldException nsfe) { Class superclass = aClass.getSuperclass(); if (superclass != null && superclass != Object.class) { return getField(superclass, name); } throw nsfe; } checkField(member); member.setAccessible(true); return member; } protected Method getMethod(Class aClass, String name, Class... params) throws NoSuchMethodException { Method member; try { member = aClass.getDeclaredMethod(name, params); } catch (NoSuchMethodException nsme) { Class superclass = aClass.getSuperclass(); if (superclass != null && superclass != Object.class) { return getMethod(superclass, name); } throw nsme; } checkMethod(member); member.setAccessible(true); return member; } protected AccessibleObject findMember(Class sClass, String name) { AccessibleObject ao; try { ao = getMethod(sClass, name); } catch (NoSuchMethodException e) { String propertyname = name.substring(0, 1).toUpperCase() + (name.length() > 1 ? name.substring(1) : ""); try { ao = getMethod(sClass, "get" + propertyname); } catch (NoSuchMethodException e2) { try { ao = getMethod(sClass, "is" + propertyname); } catch (NoSuchMethodException e3) { try { ao = getField(sClass, name); } catch (NoSuchFieldException e4) { ao = null; } } } } return ao; } // We default to not allowing private methods protected void checkMethod(Method member) throws NoSuchMethodException { if ((member.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE) { throw new NoSuchMethodException("Only public, protected and package members allowed"); } } // We default to not allowing private fields protected void checkField(Field member) throws NoSuchFieldException { if ((member.getModifiers() & Modifier.PRIVATE) == Modifier.PRIVATE) { throw new NoSuchFieldException("Only public, protected and package members allowed"); } } @Override public String stringify(Object object) { return object.toString(); } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/Guard.java000066400000000000000000000002241241525561000334000ustar00rootroot00000000000000package com.github.mustachejava.reflect; /** * Simple specialization of Predicate */ public interface Guard { boolean apply(Object[] input); } GuardedBinding.java000066400000000000000000000103111241525561000351230ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.*; import com.github.mustachejava.codes.PartialCode; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.util.Arrays; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.logging.Logger; /** * Codes are bound to their variables through bindings. *

* User: sam * Date: 7/7/12 * Time: 6:05 PM */ public class GuardedBinding implements Binding { // Debug callsites private static Logger logger = Logger.getLogger("mustache"); private static boolean debug = Boolean.getBoolean("mustache.debug"); private final ObjectHandler oh; private final TemplateContext tc; private final String name; private final Code code; public GuardedBinding(ObjectHandler oh, String name, TemplateContext tc, Code code) { this.name = name; this.code = code; this.oh = oh; this.tc = tc; } /** * The chances of a new guard every time is very low. Instead we will * store previously used guards and try them all before creating a new one. */ private Set previousSet = new CopyOnWriteArraySet(); private volatile Wrapper[] prevWrappers; /** * Retrieve the first value in the stacks of scopes that matches * the give name. The method wrappers are cached and guarded against * the type or number of scopes changing. *

* Methods will be found using the object handler, called here with * another lookup on a guard failure and finally coerced to a final * value based on the ObjectHandler you provide. * * @param scopes An array of scopes to interrogate from right to left. * @return The value of the field or method */ @Override public Object get(Object[] scopes) { // Loop over the wrappers and find the one that matches // this set of scopes or get a new one Wrapper current = null; Wrapper[] wrappers = prevWrappers; if (wrappers != null) { for (Wrapper prevWrapper : wrappers) { try { current = prevWrapper; return oh.coerce(prevWrapper.call(scopes)); } catch (GuardException ge) { // Check the next one or create a new one } catch (MustacheException me) { throw new MustacheException("Failed: " + current, me); } } } return createAndGet(scopes); } private Object createAndGet(Object[] scopes) { // Make a new wrapper for this set of scopes and add it to the set Wrapper wrapper = getWrapper(name, scopes); previousSet.add(wrapper); if (prevWrappers == null || prevWrappers.length != previousSet.size()) { prevWrappers = previousSet.toArray(new Wrapper[previousSet.size()]); } // If this fails the guard, there is a bug try { return oh.coerce(wrapper.call(scopes)); } catch (GuardException e) { throw new GuardException( "BUG: Unexpected guard failure: " + name + " " + previousSet + " " + Arrays.asList(scopes)); } } protected synchronized Wrapper getWrapper(String name, Object[] scopes) { Wrapper wrapper = oh.find(name, scopes); if (wrapper instanceof MissingWrapper) { if (debug) { // Ugly but generally not interesting if (!(code instanceof PartialCode)) { StringBuilder sb = new StringBuilder("Failed to find: ") .append(name) .append(" (") .append(tc.file()) .append(":") .append(tc.line()) .append(") ") .append("in"); for (Object scope : scopes) { if (scope != null) { Class aClass = scope.getClass(); try { sb.append(" ").append(aClass.getSimpleName()); } catch (Exception e) { // Some generated classes don't have simple names try { sb.append(" ").append(aClass.getName()); } catch (Exception e1) { // Some generated classes have proper names at all } } } } logger.warning(sb.toString()); } } } return wrapper; } } GuardedWrapper.java000066400000000000000000000032361241525561000352010ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.util.Arrays; import static java.util.Arrays.asList; /** * Wrapper that guards. */ public class GuardedWrapper implements Wrapper { // We only need a single guard exception -- don't fill stack trace // and don't reallocate it. protected static final GuardException guardException = new GuardException(); static { guardException.setStackTrace(new StackTraceElement[0]); } // Array of guards that must be satisfied protected final Guard[] guards; // Hashcode cache private int hashCode; public GuardedWrapper(Guard[] guards) { this.guards = guards; } @Override public Object call(Object[] scopes) throws GuardException { guardCall(scopes); return null; } protected void guardCall(Object[] scopes) throws GuardException { for (Guard predicate : guards) { if (!predicate.apply(scopes)) { throw guardException; } } } @Override public int hashCode() { if (hashCode == 0) { for (Guard predicate : guards) { hashCode += hashCode * 43 + predicate.hashCode(); } if (hashCode == 0) hashCode = 1; } return hashCode; } @Override public boolean equals(Object o) { if (o instanceof GuardedWrapper) { GuardedWrapper other = (GuardedWrapper) o; return (guards == null && other.guards == null) || Arrays.equals(other.guards, guards); } return false; } public Guard[] getGuards() { return guards; } public String toString() { return "[GuardedWrapper: " + asList(guards) + "]"; } } MissingWrapper.java000066400000000000000000000006731241525561000352410ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import static java.util.Arrays.asList; /** * Used to mark a wrapper this is only guarding a complete miss. */ public class MissingWrapper extends GuardedWrapper { private final String name; public MissingWrapper(String name, Guard[] guards) { super(guards); this.name = name; } public String toString() { return "[Missing: " + name + " Guards: " + asList(guards) + "]"; } } ReflectionObjectHandler.java000066400000000000000000000152671241525561000370130ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.Binding; import com.github.mustachejava.Code; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.reflect.guards.*; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; /** * Lookup objects using reflection and execute them the same way. *

* User: sam * Date: 7/24/11 * Time: 3:02 PM */ public class ReflectionObjectHandler extends BaseObjectHandler { protected static final Method MAP_METHOD; public static Object unwrap(ObjectHandler oh, int scopeIndex, Wrapper[] wrappers, Object[] scopes) throws GuardException { Object scope = oh.coerce(scopes[scopeIndex]); // The value may be buried by . notation if (wrappers != null) { for (Wrapper wrapper : wrappers) { scope = oh.coerce(wrapper.call(new Object[]{scope})); } } return scope; } static { try { MAP_METHOD = Map.class.getMethod("get", Object.class); } catch (NoSuchMethodException e) { throw new AssertionError(e); } } @SuppressWarnings("unchecked") @Override public Wrapper find(String name, final Object[] scopes) { Wrapper wrapper = null; final int length = scopes.length; List guards = new ArrayList(scopes.length); // Simple guard to break if the number of scopes at this call site have changed guards.add(createDepthGuard(length)); NEXT: for (int i = length - 1; i >= 0; i--) { Object scope = scopes[i]; if (scope == null) continue; // Make sure that the current scope is the same class guards.add(createClassGuard(i, scope)); List wrappers = null; int dotIndex; String subname = name; // Try and find a wrapper using the simple name wrapper = findWrapper(i, null, guards, scope, subname); if (wrapper != null) { break; } // If there is dot notation, start evaluating it while ((dotIndex = subname.indexOf('.')) != -1) { final String lookup = subname.substring(0, dotIndex); subname = subname.substring(dotIndex + 1); // This is used for lookups but otherwise always succeeds guards.add(createDotGuard(i, scope, lookup)); List wrapperGuard = new ArrayList(1); wrapperGuard.add(createClassGuard(0, scope)); wrapper = findWrapper(0, null, wrapperGuard, scope, lookup); if (wrappers == null) wrappers = new ArrayList(); if (wrapper != null) { // We need to dig into a scope when dot notation shows up wrappers.add(wrapper); try { // Pull out the next level scope = coerce(wrapper.call(new Object[]{scope})); } catch (GuardException e) { throw new AssertionError(e); } } else { // Failed to find a wrapper for the next dot guards.add(createWrappedGuard(i, wrappers, wrapperGuard)); continue NEXT; } if (scope == null) { // Found a wrapper, but the result of was null guards.add(createWrappedGuard(i, wrappers, Arrays.asList(createNullGuard()))); // Break here to allow the wrapper to be returned with the partial evaluation of the dot notation break; } } if (wrappers != null) { guards.add(createWrappedGuard(i, wrappers, Arrays.asList((Guard)createClassGuard(0, scope)))); } Wrapper[] foundWrappers = wrappers == null ? null : wrappers.toArray(new Wrapper[wrappers.size()]); wrapper = findWrapper(i, foundWrappers, guards, scope, subname); if (wrapper != null) { break; } } return wrapper == null ? createMissingWrapper(name, guards) : wrapper; } /** * Find a wrapper given the current context. If not found, return null. * * @param scopeIndex the index into the scope array * @param wrappers the current set of wrappers to get here * @param guards the list of guards used to find this * @param scope the current scope * @param name the name in the scope * @return null if not found, otherwise a wrapper for this scope and name */ protected Wrapper findWrapper(final int scopeIndex, Wrapper[] wrappers, List guards, Object scope, final String name) { scope = coerce(scope); if (scope == null) return null; // If the scope is a map, then we use the get() method // to see if it contains a value named name. if (scope instanceof Map) { Map map = (Map) scope; if (map.containsKey(name)) { guards.add(createMapGuard(scopeIndex, wrappers, name, true)); return createWrapper(scopeIndex, wrappers, guards, MAP_METHOD, new Object[]{name}); } else { guards.add(createMapGuard(scopeIndex, wrappers, name, false)); if (!areMethodsAccessible(map)) { return null; } } } AccessibleObject member = findMember(scope.getClass(), name); return member == null ? null : createWrapper(scopeIndex, wrappers, guards, member, null); } // Factories protected MissingWrapper createMissingWrapper(String name, List guards) { return new MissingWrapper(name, guards.toArray(new Guard[guards.size()])); } protected DotGuard createDotGuard(int i, Object scope, String lookup) { return new DotGuard(lookup, i, scope); } protected WrappedGuard createWrappedGuard(int i, List wrappers, List wrapperGuard) { return new WrappedGuard(this, i, wrappers, wrapperGuard); } protected NullGuard createNullGuard() { return new NullGuard(); } protected DepthGuard createDepthGuard(int length) { return new DepthGuard(length); } protected ClassGuard createClassGuard(int i, Object scope) { return new ClassGuard(i, scope); } protected MapGuard createMapGuard(int scopeIndex, Wrapper[] wrappers, String name, boolean contains) { return new MapGuard(this, scopeIndex, name, contains, wrappers); } @SuppressWarnings("unchecked") protected Wrapper createWrapper(int scopeIndex, Wrapper[] wrappers, List guard, AccessibleObject member, Object[] arguments) { return new ReflectionWrapper(scopeIndex, wrappers, guard.toArray(new Guard[guard.size()]), member, arguments, this); } @Override public Binding createBinding(String name, TemplateContext tc, Code code) { return new GuardedBinding(this, name, tc, code); } protected boolean areMethodsAccessible(Map map) { return false; } } ReflectionWrapper.java000066400000000000000000000102661241525561000357210ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.MustacheException; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; /** * Used for evaluating values at a callsite */ public class ReflectionWrapper extends GuardedWrapper { // Context protected final int scopeIndex; protected final Wrapper[] wrappers; protected final ObjectHandler oh; // Dispatch protected final Method method; protected final Field field; protected final Object[] arguments; public ReflectionWrapper(int scopeIndex, Wrapper[] wrappers, Guard[] guard, AccessibleObject method, Object[] arguments, ObjectHandler oh) { super(guard); this.wrappers = wrappers; this.oh = oh; if (method instanceof Field) { this.method = null; this.field = (Field) method; } else { this.method = (Method) method; this.field = null; } this.arguments = arguments; this.scopeIndex = scopeIndex; } public ReflectionWrapper(ReflectionWrapper rw) { this(rw.scopeIndex, rw.wrappers, rw.guards, rw.method == null ? rw.field : rw.method, rw.arguments, rw.oh); } protected Object unwrap(Object[] scopes) { if (wrappers == null || wrappers.length == 0) { return scopes[scopeIndex]; } else { return ReflectionObjectHandler.unwrap(oh, scopeIndex, wrappers, scopes); } } @Override public Object call(Object[] scopes) throws GuardException { guardCall(scopes); Object scope = oh.coerce(unwrap(scopes)); try { if (scope == null) return null; if (method == null) { return field.get(scope); } else { return method.invoke(scope, arguments); } } catch (IllegalArgumentException e) { throw new MustacheException("Error accessing " + getTargetDescription() + " on " + elementToString(scope) + ", scope: [" + elementsToString(scopes, scopeIndex) + "]" + ", guards: " + Arrays.toString(guards), e); } catch (IllegalAccessException e) { throw new MustacheException("Error accessing " + getTargetDescription() + " on " + elementToString(scope) + ", scope: [" + elementsToString(scopes, scopeIndex) + "]" + ", guards: " + Arrays.toString(guards), e); } catch (InvocationTargetException e) { throw new MustacheException("Error invoking " + getTargetDescription() + " on " + elementToString(scope), e.getTargetException()); } catch (Exception e) { throw new MustacheException("Error invoking " + getTargetDescription() + " on " + elementToString(scope), e); } } public Method getMethod() { return method; } public Field getField() { return field; } public Object[] getArguments() { return arguments; } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (field == null) { sb.append(method.toString()); if (arguments != null) { for (Object arg : arguments) { sb.append(",").append(arg); } } } else { sb.append(field); } return sb.toString(); } public Wrapper[] getWrappers() { return wrappers; } private String getTargetDescription() { return method == null ? "field " + field.getDeclaringClass() + "." + field.getName() : "method " + method.getDeclaringClass().getCanonicalName() + "." + method.getName() + "(" + elementsToString(arguments, method.getParameterTypes().length - 1) + ")"; } private String elementsToString(Object[] objects, int showUpTo) { if (objects == null || objects.length == 0 || showUpTo < 0) { return ""; } StringBuilder sb = new StringBuilder(); for (int i = 0; i <= showUpTo && i < objects.length; i++) { if (sb.length() > 0) sb.append(","); sb.append(elementToString(objects[i])); } return sb.toString(); } private String elementToString(Object object) { return object == null ? null : object.getClass().getCanonicalName() + '@' + object.hashCode(); } } SimpleObjectHandler.java000066400000000000000000000110231241525561000361340ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflectpackage com.github.mustachejava.reflect; import com.github.mustachejava.Binding; import com.github.mustachejava.Code; import com.github.mustachejava.MustacheException; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SimpleObjectHandler extends BaseObjectHandler { @Override public Binding createBinding(final String name, TemplateContext tc, Code code) { return new Binding() { // We find the wrapper just once since only the name is needed private Wrapper wrapper = find(name, null); @Override public Object get(Object[] scopes) { return wrapper.call(scopes); } }; } @Override public Wrapper find(final String name, final Object[] scopes) { return new Wrapper() { @Override public Object call(Object[] scopes) throws GuardException { for (int i = scopes.length - 1; i >= 0; i--) { Object scope = scopes[i]; if (scope != null) { int index = name.indexOf("."); if (index == -1) { // Special case Maps if (scope instanceof Map) { Map map = (Map) scope; if (map.containsKey(name)) { return map.get(name); } else if (!areMethodsAccessible(map)) { continue; //don't check methods, move to next scope } } // Check to see if there is a method or field that matches try { AccessibleObject ao = lookup(scope.getClass(), name); if (ao instanceof Method) { return ((Method) ao).invoke(scope); } else if (ao instanceof Field) { return ((Field) ao).get(scope); } } catch (InvocationTargetException ie) { throw new MustacheException("Failed to get " + name + " from " + scope.getClass(), ie); } catch (IllegalAccessException iae) { throw new MustacheException("Set accessible failed to get " + name + " from " + scope.getClass(), iae); } } else { // Dig into the dot-notation through recursion Object[] subscope = {scope}; Wrapper wrapper = find(name.substring(0, index), subscope); if (wrapper != null) { scope = wrapper.call(subscope); if (scope == null) { continue; } subscope = new Object[]{scope}; return find(name.substring(index + 1), new Object[]{subscope}).call(subscope); } } } } return null; } }; } // Used for the member cache private static class WrapperKey { private final Class aClass; private final String name; private int hashcode; WrapperKey(Class aClass, String name) { this.aClass = aClass; this.name = name; hashcode = aClass.hashCode() + 43 * name.hashCode(); } @Override public int hashCode() { return hashcode; } @Override public boolean equals(Object obj) { if (obj instanceof WrapperKey) { WrapperKey oKey = (WrapperKey) obj; return aClass.equals(oKey.aClass) && name.equals(oKey.name); } else { return false; } } } // Cache of classes + name => field mappings // By keeping this non-static you can release the cache by releasing the handler private Map cache = new ConcurrentHashMap(); // Used to cache misses private static AccessibleObject NONE; static { try { NONE = SimpleObjectHandler.class.getDeclaredField("NONE"); } catch (NoSuchFieldException e) { throw new AssertionError("Failed to init: " + e); } } // Use the cache to find lookup members faster private AccessibleObject lookup(Class sClass, String name) { WrapperKey key = new WrapperKey(sClass, name); AccessibleObject ao = cache.get(key); if (ao == null) { ao = findMember(sClass, name); cache.put(key, ao == null ? NONE : ao); } return ao == NONE ? null : ao; } protected boolean areMethodsAccessible(Map map) { return false; } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guards/000077500000000000000000000000001241525561000327625ustar00rootroot00000000000000ClassGuard.java000066400000000000000000000024141241525561000355770ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.reflect.Guard; /** * Ensure that the class of the current scope is that same as when this wrapper was generated. * User: spullara * Date: 4/13/12 * Time: 9:23 AM * To change this template use File | Settings | File Templates. */ public class ClassGuard implements Guard { protected final Class classGuard; protected final int scopeIndex; public ClassGuard(int scopeIndex, Object scope) { this.scopeIndex = scopeIndex; this.classGuard = scope == null ? null : scope.getClass(); } @Override public int hashCode() { return classGuard == null ? 0 : classGuard.hashCode(); } @Override public boolean equals(Object o) { ClassGuard other = (ClassGuard) o; return o instanceof ClassGuard && (classGuard == null ? classGuard == other.classGuard : classGuard.equals(other.classGuard)); } @Override public boolean apply(Object[] scopes) { if (scopes == null || scopes.length <= scopeIndex) return false; Object scope = scopes[scopeIndex]; return !(scope != null && classGuard != scope.getClass()) && !(scope == null && classGuard != null); } public String toString() { return "[ClassGuard: " + scopeIndex + " " + classGuard.getName() + "]"; } } DepthGuard.java000066400000000000000000000013641241525561000356010ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.reflect.Guard; /** * Check that there are the same number of scope levels. */ public class DepthGuard implements Guard { protected final int length; public DepthGuard(int length) { this.length = length; } @Override public int hashCode() { return length; } @Override public boolean equals(Object o) { if (o instanceof DepthGuard) { DepthGuard depthGuard = (DepthGuard) o; return length == depthGuard.length; } return false; } @Override public boolean apply(Object[] objects) { return objects != null && length == objects.length; } public String toString() { return "[DepthGuard: " + length + "]"; } } DotGuard.java000066400000000000000000000020241241525561000352550ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.reflect.Guard; /** * Guard dot notation references. */ public class DotGuard implements Guard { private final String lookup; private final int scopeIndex; private final Class classGuard; public DotGuard(String lookup, int scopeIndex, Object classGuard) { this.lookup = lookup; this.scopeIndex = scopeIndex; this.classGuard = classGuard.getClass(); } @Override public int hashCode() { return (lookup.hashCode() * 43 + scopeIndex) * 43 + classGuard.hashCode(); } @Override public boolean equals(Object o) { if (o instanceof DotGuard) { DotGuard other = (DotGuard) o; return scopeIndex == other.scopeIndex && lookup.equals(other.lookup) && classGuard.equals(other.classGuard); } return false; } @Override public boolean apply(Object[] objects) { return true; } public String toString() { return "[DotGuard: " + lookup + " " + scopeIndex + " " + classGuard.getName() + "]"; } } MapGuard.java000066400000000000000000000023461241525561000352530ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.util.Wrapper; import java.util.Map; import static com.github.mustachejava.reflect.ReflectionObjectHandler.unwrap; /** * Guards whether or not a name was present in the map. */ public class MapGuard implements Guard { protected final ObjectHandler oh; protected final int scopeIndex; protected final String name; protected final boolean contains; protected final Wrapper[] wrappers; public MapGuard(ObjectHandler oh, int scopeIndex, String name, boolean contains, Wrapper[] wrappers) { this.oh = oh; this.scopeIndex = scopeIndex; this.name = name; this.contains = contains; this.wrappers = wrappers; } @Override public boolean apply(Object[] objects) { Object scope = unwrap(oh, scopeIndex, wrappers, objects); if (scope instanceof Map) { Map map = (Map) scope; if (contains) { return map.containsKey(name); } else { return !map.containsKey(name); } } return false; } public String toString() { return "[MapGuard: " + scopeIndex + " " + name + " " + contains + "]"; } } NullGuard.java000066400000000000000000000004431241525561000354440ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.reflect.Guard; public class NullGuard implements Guard { @Override public boolean apply(Object[] objects) { return objects[0] == null; } public String toString() { return "[NullGuard]"; } } WrappedGuard.java000066400000000000000000000023051241525561000361330ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/reflect/guardspackage com.github.mustachejava.reflect.guards; import com.github.mustachejava.ObjectHandler; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.util.Wrapper; import java.util.List; import static com.github.mustachejava.reflect.ReflectionObjectHandler.unwrap; /** * Dig into the dot notation to guard it from changing. *

* User: sam * Date: 6/26/12 * Time: 9:09 PM */ public class WrappedGuard implements Guard { protected final ObjectHandler oh; protected final int index; protected final Wrapper[] wrappers; private final List wrapperGuard; public WrappedGuard(ObjectHandler oh, int index, List wrappers, List wrapperGuard) { this.oh = oh; this.index = index; this.wrappers = wrappers.toArray(new Wrapper[wrappers.size()]); this.wrapperGuard = wrapperGuard; } @Override public boolean apply(Object[] objects) { Object scope = unwrap(oh, index, wrappers, objects); for (Guard predicate : wrapperGuard) { if (!predicate.apply(new Object[]{scope})) { return false; } } return true; } public String toString() { return "[WrappedGuard: " + index + " " + wrapperGuard + "]"; } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/resolver/000077500000000000000000000000001241525561000317125ustar00rootroot00000000000000ClasspathResolver.java000066400000000000000000000023411241525561000361420ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/resolverpackage com.github.mustachejava.resolver; import com.github.mustachejava.MustacheResolver; import com.google.common.base.Charsets; import java.io.*; /** * MustacheResolver implementation that resolves * mustache files from the classpath. */ public class ClasspathResolver implements MustacheResolver { private final String resourceRoot; public ClasspathResolver() { this.resourceRoot = null; } /** * Use the classpath to resolve mustache templates. * * @param resourceRoot */ public ClasspathResolver(String resourceRoot) { if (!resourceRoot.endsWith("/")) { resourceRoot += "/"; } this.resourceRoot = resourceRoot; } @Override public Reader getReader(String resourceName) { ClassLoader ccl = Thread.currentThread().getContextClassLoader(); String name = (resourceRoot == null ? "" : resourceRoot) + resourceName; InputStream is = ccl.getResourceAsStream(name); if (is == null) { is = ClasspathResolver.class.getClassLoader().getResourceAsStream(name); } if (is != null) { return new BufferedReader(new InputStreamReader(is, Charsets.UTF_8)); } else { return null; } } public String getResourceRoot() { return resourceRoot; } } DefaultResolver.java000066400000000000000000000025751241525561000356150ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/resolverpackage com.github.mustachejava.resolver; import com.github.mustachejava.MustacheResolver; import java.io.File; import java.io.Reader; /** * Mustache resolver that provides the default functionality * that the default mustache factory relies on by combining * the classpath and the filesystem resolver. */ public class DefaultResolver implements MustacheResolver { private final ClasspathResolver classpathResolver; private final FileSystemResolver fileSystemResolver; public DefaultResolver() { this.fileSystemResolver = new FileSystemResolver(); this.classpathResolver = new ClasspathResolver(); } /** * Use the classpath to resolve mustache templates. * * @param resourceRoot */ public DefaultResolver(String resourceRoot) { this.classpathResolver = new ClasspathResolver(resourceRoot); this.fileSystemResolver = new FileSystemResolver(); } /** * Use the file system to resolve mustache templates. * * @param fileRoot */ public DefaultResolver(File fileRoot) { this.fileSystemResolver = new FileSystemResolver(fileRoot); this.classpathResolver = new ClasspathResolver(); } @Override public Reader getReader(String resourceName) { Reader reader = classpathResolver.getReader(resourceName); if(reader == null) { reader = fileSystemResolver.getReader(resourceName); } return reader; } } FileSystemResolver.java000066400000000000000000000040231241525561000363030ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/resolverpackage com.github.mustachejava.resolver; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheResolver; import com.google.common.base.Charsets; import java.io.*; /** * MustacheResolver implementation that resolves * mustache files from the filesystem. */ public class FileSystemResolver implements MustacheResolver { private final File fileRoot; public FileSystemResolver() { this.fileRoot = null; } /** * Use the file system to resolve mustache templates. * * @param fileRoot */ public FileSystemResolver(File fileRoot) { if (!fileRoot.exists()) { throw new MustacheException(fileRoot + " does not exist"); } if (!fileRoot.isDirectory()) { throw new MustacheException(fileRoot + " is not a directory"); } this.fileRoot = fileRoot; } @Override public Reader getReader(String resourceName) { InputStream is = null; File file = fileRoot == null ? new File(resourceName) : new File(fileRoot, resourceName); if (file.exists() && file.isFile()) { try { // Check to make sure that the file is under the file root or current directory. // Without this check you might accidentally open a security whole when exposing // mustache templates to end users. File checkRoot = fileRoot == null ? new File("").getCanonicalFile() : fileRoot.getCanonicalFile(); File parent = file.getCanonicalFile(); while ((parent = parent.getParentFile()) != null) { if (parent.equals(checkRoot)) break; } if (parent == null) { throw new MustacheException("File not under root: " + checkRoot.getAbsolutePath()); } is = new FileInputStream(file); } catch (IOException e) { throw new MustacheException("Found file, could not open: " + file, e); } } if (is != null) { return new BufferedReader(new InputStreamReader(is, Charsets.UTF_8)); } else { return null; } } public File getFileRoot() { return fileRoot; } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/util/000077500000000000000000000000001241525561000310265ustar00rootroot00000000000000CapturingMustacheVisitor.java000066400000000000000000000053071241525561000366250ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.DefaultMustacheVisitor; import com.github.mustachejava.Mustache; import com.github.mustachejava.TemplateContext; import com.github.mustachejava.codes.IterableCode; import com.github.mustachejava.codes.NotIterableCode; import com.github.mustachejava.codes.ValueCode; import java.io.Writer; /** * Grab a map of values returned from calls */ public class CapturingMustacheVisitor extends DefaultMustacheVisitor { private final Captured captured; public interface Captured { void value(String name, String value); void arrayStart(String name); void arrayEnd(); void objectStart(); void objectEnd(); } public CapturingMustacheVisitor(DefaultMustacheFactory cf, Captured captured) { super(cf); this.captured = captured; } @Override public void value(TemplateContext tc, String variable, boolean encoded) { list.add(new ValueCode(tc, df, variable, encoded) { @Override public Object get(Object[] scopes) { Object o = super.get(scopes); if (o != null) { captured.value(name, o.toString()); } return o; } }); } @Override public void iterable(TemplateContext tc, String variable, Mustache mustache) { list.add(new IterableCode(tc, df, mustache, variable) { @Override public Writer execute(Writer writer, Object[] scopes) { Writer execute = super.execute(writer, scopes); captured.arrayEnd(); return execute; } @Override public Writer next(Writer writer, Object next, Object... scopes) { captured.objectStart(); Writer nextObject = super.next(writer, next, scopes); captured.objectEnd(); return nextObject; } @Override public Object get(Object[] scopes) { Object o = super.get(scopes); captured.arrayStart(name); return o; } }); } @Override public void notIterable(TemplateContext tc, String variable, Mustache mustache) { list.add(new NotIterableCode(tc, df, mustache, variable) { boolean called; @Override public Object get(Object[] scopes) { return super.get(scopes); } @Override public Writer next(Writer writer, Object object, Object[] scopes) { called = true; return super.next(writer, object, scopes); } @Override public Writer execute(Writer writer, Object[] scopes) { Writer execute = super.execute(writer, scopes); if (called) { captured.arrayStart(name); captured.arrayEnd(); } return execute; } }); } } DecoratedCollection.java000066400000000000000000000024441241525561000355240ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; /** * Exposes first / last / index / value on each element. */ public class DecoratedCollection extends AbstractCollection> { private final Collection c; public DecoratedCollection(Collection c) { this.c = c; } @Override public Iterator> iterator() { final Iterator iterator = c.iterator(); return new Iterator>() { int index = 0; @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Element next() { T next = iterator.next(); int current = index++; return new Element(current, current == 0, !iterator.hasNext(), next); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int size() { return c.size(); } } class Element { public final int index; public final boolean first; public final boolean last; public final T value; public Element(int index, boolean first, boolean last, T value) { this.index = index; this.first = first; this.last = last; this.value = value; } } GuardException.java000066400000000000000000000004411241525561000345320ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; /** * If the wrapper has a different calling signature, tell the * caller to refind it. */ public class GuardException extends RuntimeException { public GuardException() { } public GuardException(String message) { super(message); } } HtmlEscaper.java000066400000000000000000000065161241525561000340310ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import com.github.mustachejava.MustacheException; import java.io.IOException; import java.io.Writer; /** * Escapes user data that you wish to include in HTML pages. */ public class HtmlEscaper { public static void escape(String value, Writer writer, boolean escapeEscaped) { try { int position = 0; int length = value.length(); for (int i = 0; i < length; i++) { char c = value.charAt(i); if (c <= 13) { writer.append(value, position, i); writer.append("&#"); writer.append(String.valueOf((int)c)); writer.append(";"); position = i + 1; } else { switch (c) { case '&': // If we match an entity or char ref then keep it // as is in the text. Otherwise, replace it. if (!escapeEscaped && matchesEntityRef(i + 1, length, value)) { // If we are at the beginning we can just keep going if (position != 0) { position = append(value, writer, position, i, "&"); } } else { position = append(value, writer, position, i, "&"); } break; case '<': position = append(value, writer, position, i, "<"); break; case '>': position = append(value, writer, position, i, ">"); break; case '"': position = append(value, writer, position, i, """); break; case '\'': position = append(value, writer, position, i, "'"); break; } } } writer.append(value, position, length); } catch (IOException e) { throw new MustacheException("Failed to encode value: " + value); } } private static int append(String value, Writer writer, int position, int i, String replace) throws IOException { // Append the clean text writer.append(value, position, i); // Append the encoded value writer.append(replace); // and advance the position past it return i + 1; } // Matches all HTML named and character entity references private static boolean matchesEntityRef(int position, int length, String value) { for (int i = position; i < length; i++) { char c = value.charAt(i); switch (c) { case ';': // End of the entity return i != position; case '#': // Switch to char reference return i == position && matchesCharRef(i + 1, length, value); default: // Letters can be at the start if (c >= 'a' && c <= 'z') continue; if (c >= 'A' && c <= 'Z') continue; if (i != position) { // Can only appear in the middle if (c >= '0' && c <= '9') continue; } return false; } } // Didn't find ending ; return false; } private static boolean matchesCharRef(int position, int length, String value) { for (int i = position; i < length; i++) { char c = value.charAt(i); if (c == ';') { return i != position; } else if ((c >= '0' && c <= '9') || c == 'x' || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { } else return false; } return false; } } HtmlState.java000066400000000000000000000157051241525561000335270ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import java.util.logging.Logger; import static com.github.mustachejava.util.HtmlState.HTML.*; /** * Stores the HTML state while parsing. */ public class HtmlState implements State { private static Logger l = Logger.getLogger("HTMLAwareWriter"); // Current state of the document private HTML state; private HTML quoteState; private HTML bodyState; // Ringbuffer for comments and script tags private final RingBuffer ringBuffer = new RingBuffer(6); // Ask the writer for the current state public HTML getState() { return state; } public HtmlState() { this(BODY); } public HtmlState(HTML state) { this.state = state; } public enum HTML { ATTRIBUTES, BODY, TAG, ATTR_NAME, ATTR_EQUAL, DQ_VALUE, SCRIPT_DQ_VALUE, TAG_NAME, END_TAG, END_TAG_NAME, ESCAPE, SCRIPT, SCRIPT_SQ_VALUE, SCRIPT_CHECK, AFTER_END_TAG_NAME, SQ_VALUE, NQ_VALUE, PRAGMA, COMMENT, CSS, CSS_CHECK, } public void nextState(char[] cbuf, int off, int len) { int end = off + len; for (int i = off; i < end; i++) { char c = cbuf[i]; switch (state) { case ATTRIBUTES: attr(c); break; case BODY: body(c); break; case TAG: tag(c); break; case ATTR_NAME: attrName(c); break; case ATTR_EQUAL: attrEqual(c); break; case DQ_VALUE: dqValue(c); break; case SCRIPT_DQ_VALUE: scriptDqValue(c); break; case TAG_NAME: tagName(c); break; case END_TAG: endTag(c); break; case END_TAG_NAME: endTagName(c); break; case ESCAPE: escape(); break; case SCRIPT: script(c); break; case SCRIPT_SQ_VALUE: scriptSqValue(c); break; case SCRIPT_CHECK: scriptCheck(c); break; case AFTER_END_TAG_NAME: afterEndTagName(c); break; case SQ_VALUE: sqValue(c); break; case NQ_VALUE: nqValue(c); break; case PRAGMA: pragma(c); break; case COMMENT: comment(c); break; case CSS: css(c); break; case CSS_CHECK: cssCheck(c); break; } if (state == TAG_NAME || state == PRAGMA || state == COMMENT) { ringBuffer.append(c); } } } private void scriptCheck(char c) { if (c == '/') { bodyState = BODY; state = END_TAG; } else if (ws(c)) { } else { state = SCRIPT; } } private void cssCheck(char c) { if (c == '/') { bodyState = BODY; state = END_TAG; } else if (ws(c)) { } else { state = CSS; } } private void pragma(char c) { if (c == '-') { if (ringBuffer.compare("!-", false)) { state = COMMENT; ringBuffer.clear(); } } else if (c == '>') { state = bodyState; } } private void scriptSqValue(char c) { if (c == '\\') { quoteState = state; state = ESCAPE; } else if (c == '\'') { state = SCRIPT; } } private void scriptDqValue(char c) { if (c == '\\') { quoteState = state; state = ESCAPE; } else if (c == '"') { state = SCRIPT; } } private void script(char c) { if (c == '"') { state = SCRIPT_DQ_VALUE; } else if (c == '\'') { state = SCRIPT_SQ_VALUE; } else if (c == '<') { state = SCRIPT_CHECK; } } private void css(char c) { if (c == '<') { state = CSS_CHECK; } } private void afterEndTagName(char c) { if (ws(c)) { } else if (c == '>') { state = bodyState; } else error(c); } private void endTagName(char c) { if (namePart(c)) { } else if (c == '>') { state = bodyState; } else if (ws(c)) { state = AFTER_END_TAG_NAME; } else error(c); } private void endTag(char c) { if (nameStart(c)) { state = END_TAG_NAME; } else if (Character.isWhitespace(c)) { } else if (c == '>') { state = bodyState; } else error(c); } private boolean nameStart(char c) { return Character.isJavaIdentifierStart(c); } private void comment(char c) { if (c == '>') { if (ringBuffer.compare("--", false)) { state = bodyState; } } } private void nqValue(char c) { if (ws(c)) { state = ATTRIBUTES; } else if (c == '<') { error(c); } else if (c == '>') { state = bodyState; } } private void escape() { state = quoteState; } private void sqValue(char c) { if (c == '\\') { state = ESCAPE; quoteState = SQ_VALUE; } else if (c == '\'') { state = ATTRIBUTES; } else if (c == '<' || c == '>') { error(c); } } private void dqValue(char c) { if (c == '\\') { state = ESCAPE; quoteState = DQ_VALUE; } else if (c == '\"') { state = ATTRIBUTES; } else if (c == '<' || c == '>') { error(c); } } private void attrEqual(char c) { if (c == '"') { state = DQ_VALUE; } else if (c == '\'') { state = SQ_VALUE; } else if (ws(c)) { } else { state = NQ_VALUE; } } private boolean ws(char c) { return Character.isWhitespace(c); } private void attrName(char c) { if (namePart(c)) { } else if (c == '=') { state = ATTR_EQUAL; } else if (ws(c)) { } else if (c == '>') { state = bodyState; } else error(c); } private void attr(char c) { if (nameStart(c)) { state = ATTR_NAME; } else if (c == '>') { state = bodyState; } else if (c == '/') { state = AFTER_END_TAG_NAME; } else if (ws(c)) { } else error(c); } private void tagName(char c) { if (namePart(c)) { } else if (ws(c)) { setBodyTag(); state = ATTRIBUTES; } else if (c == '>') { setBodyTag(); state = bodyState; } } private boolean namePart(char c) { return Character.isJavaIdentifierPart(c) || c == '-'; } private void setBodyTag() { if (ringBuffer.compare("script", true)) { bodyState = SCRIPT; } else if (ringBuffer.compare("style", true)) { bodyState = CSS; } else bodyState = BODY; } private void tag(char c) { if (nameStart(c)) { state = TAG_NAME; ringBuffer.clear(); } else if (c == '/') { state = END_TAG; } else if (c == '!') { state = PRAGMA; ringBuffer.clear(); } else if (ws(c)) { } else error(c); } private void error(char c) { l.warning("Invalid: " + new StringBuilder().append(c) + " (" + state + ")"); state = bodyState; } private void body(char c) { if (c == '<') { bodyState = state; state = TAG; } } } LatchedWriter.java000066400000000000000000000040171241525561000343550ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import com.github.mustachejava.MustacheException; import java.io.IOException; import java.io.Writer; import java.util.concurrent.CountDownLatch; /** * Buffer content while a future is being evaluated in another thread. */ public class LatchedWriter extends Writer { // Write to the buffer while latched, when unlatched, write the // buffer to the underlying writer and any future writes private final CountDownLatch latch = new CountDownLatch(1); // A buffer that holds writes until the latch is unlatched private final StringBuilder buffer = new StringBuilder(); // The underlying writer private final Writer writer; // This is set when the latch holder fails private volatile Throwable e; public LatchedWriter(Writer writer) { this.writer = writer; } // Call this when your processing is complete public synchronized void done() throws IOException { writer.append(buffer); latch.countDown(); } // If you fail to complete, put an exception here public void failed(Throwable e) { this.e = e; latch.countDown(); } @Override public synchronized void write(char[] cbuf, int off, int len) throws IOException { checkException(); if (latch.getCount() == 0) { writer.write(cbuf, off, len); } else { buffer.append(cbuf, off, len); } } private void checkException() throws IOException { if (e != null) { if (e instanceof IOException) { throw ((IOException) e); } throw new IOException(e); } } @Override public void flush() throws IOException { checkException(); if (latch.getCount() == 0) { synchronized (this) { writer.flush(); } } } @Override public void close() throws IOException { checkException(); await(); flush(); writer.close(); } public void await() { try { latch.await(); } catch (InterruptedException e1) { throw new MustacheException("Interrupted while waiting for completion", e1); } } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/util/Node.java000066400000000000000000000002361241525561000325570ustar00rootroot00000000000000package com.github.mustachejava.util; import java.util.LinkedHashMap; import java.util.List; public class Node extends LinkedHashMap { } NodeValue.java000066400000000000000000000024531241525561000335000ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import java.util.List; public class NodeValue { private final List list; private final String value; private final boolean isList; private NodeValue(List list, String value) { this.list = list; isList = list != null; this.value = value; } public static NodeValue list(List list) { return new NodeValue(list, null); } public static NodeValue value(String value) { return new NodeValue(null, value); } public boolean isList() { return isList; } public List list() { return list; } public String value() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NodeValue nodeValue = (NodeValue) o; if (list != null ? !list.equals(nodeValue.list) : nodeValue.list != null) return false; if (value != null ? !value.equals(nodeValue.value) : nodeValue.value != null) return false; return true; } @Override public int hashCode() { int result = list != null ? list.hashCode() : 0; result = 31 * result + (value != null ? value.hashCode() : 0); return result; } @Override public String toString() { return isList ? list.toString() : value; } } RingBuffer.java000066400000000000000000000022361241525561000336460ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; /** * A very simple ring buffer you can use for parsing and keeping a look behind. */ public class RingBuffer { private final int ringSize; private final int ringHash; private final char[] ring; private int length = 0; public RingBuffer(int ringSize) { int i = 1; while (i < ringSize) { i *= 2; } this.ringSize = i; this.ringHash = i - 1; ring = new char[i]; } public void append(char c) { ring[length++ & ringHash] = c; } public void clear() { length = 0; } public boolean compare(String s, boolean exact) { int len = s.length(); if (exact && len != length) return false; if (len > ringSize) { throw new IllegalArgumentException("Ring buffer too small: " + ringSize + " < " + s.length()); } if (length >= len) { int j = 0; int position = length & ringHash; for (int i = position - len; i < position; i++) { char c; if (i < 0) { c = ring[ringSize + i]; } else { c = ring[i]; } if (s.charAt(j++) != c) { return false; } } } return true; } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/util/State.java000066400000000000000000000002751241525561000327550ustar00rootroot00000000000000package com.github.mustachejava.util; /** * Tracks the state of a stream */ public interface State { public void nextState(char[] chars, int off, int len); public T getState(); } StateAwareWriter.java000066400000000000000000000013561241525561000350540ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import java.io.IOException; import java.io.Writer; /** * Manages a state machine that knows the context in an HTML document it is writing. */ public class StateAwareWriter extends Writer { // Delegate private Writer writer; private T state; public StateAwareWriter(Writer writer, T state) { this.writer = writer; this.state = state; } @Override public void write(char[] cbuf, int off, int len) throws IOException { state.nextState(cbuf, off, len); writer.write(cbuf, off, len); } @Override public void flush() throws IOException { writer.flush(); } @Override public void close() throws IOException { flush(); writer.close(); } } mustache.java-mustache.java-0.8.17/compiler/src/main/java/com/github/mustachejava/util/Wrapper.java000066400000000000000000000002551241525561000333130ustar00rootroot00000000000000package com.github.mustachejava.util; /** * Call a wrapped name on a set of scopes. */ public interface Wrapper { Object call(Object[] scopes) throws GuardException; } mustache.java-mustache.java-0.8.17/compiler/src/test/000077500000000000000000000000001241525561000224505ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/000077500000000000000000000000001241525561000233715ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/000077500000000000000000000000001241525561000241475ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/000077500000000000000000000000001241525561000254315ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/000077500000000000000000000000001241525561000301045ustar00rootroot00000000000000AbstractClassTest.java000066400000000000000000000040411241525561000342600ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import org.junit.Test; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class AbstractClassTest { static abstract class AbstractFoo { public abstract String getValue(); } static class Foo extends AbstractFoo { @Override public String getValue() { return "I am Foo"; } } static class Bar extends AbstractFoo { @Override public String getValue() { return "I am Bar"; } } static class Container { public final AbstractFoo foo; public Container(final AbstractFoo foo) { this.foo = foo; } } @Test public void testAbstractClass() throws IOException { final List containers = new ArrayList(); containers.add(new Container(new Foo())); containers.add(new Container(new Bar())); HashMap scopes = new HashMap(); Writer writer = new OutputStreamWriter(System.out); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new StringReader("{{#containers}} {{foo.value}} {{/containers}}"), "example"); scopes.put("containers", containers); mustache.execute(writer, scopes); writer.flush(); } @Test public void testAbstractClassNoDots() throws IOException { final List containers = new ArrayList(); containers.add(new Container(new Foo())); containers.add(new Container(new Bar())); HashMap scopes = new HashMap(); Writer writer = new OutputStreamWriter(System.out); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new StringReader("{{#containers}} {{#foo}}{{value}}{{/foo}} {{/containers}}"), "example"); scopes.put("containers", containers); mustache.execute(writer, scopes); writer.flush(); } } ArraysIndexesTest.java000066400000000000000000000061331241525561000343140ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.ReflectionObjectHandler; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.Array; import java.util.AbstractMap; import java.util.Iterator; import java.util.Set; import static org.junit.Assert.assertEquals; /** * Shows a simple way to add indexes for arrays. *

* User: sam * Date: 4/7/13 * Time: 11:12 AM */ public class ArraysIndexesTest { @Test public void testArrayIndexExtension() throws IOException { String template = "

    \n" + "
  1. {{test.1}}
  2. \n" + "
  3. {{test.0}}
  4. \n" + "
  5. {{test.3}}
  6. \n" + "
\n" + "
    \n" + "{{#test}}\n" + "
  1. {{.}}
  2. \n" + "{{/test}}\n" + "
"; String result = "
    \n" + "
  1. 1
  2. \n" + "
  3. 0
  4. \n" + "
  5. 3
  6. \n" + "
\n" + "
    \n" + "
  1. 0
  2. \n" + "
  3. 1
  4. \n" + "
  5. 2
  6. \n" + "
  7. 3
  8. \n" + "
"; Object scope = new Object() { int[] test = { 0, 1, 2, 3 }; }; ReflectionObjectHandler oh = new ReflectionObjectHandler() { @Override public Object coerce(final Object object) { if (object != null && object.getClass().isArray()) { return new ArrayMap(object); } return super.coerce(object); } }; DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(oh); Mustache m = mf.compile(new StringReader(template), "template"); StringWriter writer = new StringWriter(); m.execute(writer, scope).flush(); assertEquals(result, writer.toString()); } private static class ArrayMap extends AbstractMap implements Iterable { private final Object object; public ArrayMap(Object object) { this.object = object; } @Override public Object get(Object key) { try { int index = Integer.parseInt(key.toString()); return Array.get(object, index); } catch (NumberFormatException nfe) { return null; } } @Override public boolean containsKey(Object key) { return get(key) != null; } @Override public Set> entrySet() { throw new UnsupportedOperationException(); } /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ @Override public Iterator iterator() { return new Iterator() { int index = 0; int length = Array.getLength(object); @Override public boolean hasNext() { return index < length; } @Override public Object next() { return Array.get(object, index++); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/ComplexObject.java000066400000000000000000000015211241525561000335040ustar00rootroot00000000000000package com.github.mustachejava; import java.util.Arrays; import java.util.List; /** * Created by IntelliJ IDEA. * User: spullara * Date: 1/17/12 * Time: 8:17 PM * To change this template use File | Settings | File Templates. */ public class ComplexObject { String header = "Colors"; List item = Arrays.asList( new Color("red", true, "#Red"), new Color("green", false, "#Green"), new Color("blue", false, "#Blue") ); boolean list() { return item.size() != 0; } boolean empty() { return item.size() == 0; } private static class Color { boolean link() { return !current; } Color(String name, boolean current, String url) { this.name = name; this.current = current; this.url = url; } String name; boolean current; String url; } } ConcurrencyTest.java000066400000000000000000000107751241525561000340340ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejavabenchmarks.BenchmarkTest; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.security.SecureRandom; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import static com.github.mustachejavabenchmarks.BenchmarkTest.skip; import static junit.framework.Assert.assertEquals; /** * Inspired by an unconfirmed bug report. */ public class ConcurrencyTest { static Random r = new SecureRandom(); private static class TestObject { final int a; final int b; final int c; int aa() throws InterruptedException { Thread.sleep(r.nextInt(10)); return a; } int bb() throws InterruptedException { Thread.sleep(r.nextInt(10)); return b; } int cc() throws InterruptedException { Thread.sleep(r.nextInt(10)); return c; } Callable calla() throws InterruptedException { return new Callable() { @Override public Integer call() throws Exception { Thread.sleep(r.nextInt(10)); return a; } }; } Callable callb() throws InterruptedException { return new Callable() { @Override public Integer call() throws Exception { Thread.sleep(r.nextInt(10)); return b; } }; } Callable callc() throws InterruptedException { return new Callable() { @Override public Integer call() throws Exception { Thread.sleep(r.nextInt(10)); return c; } }; } private TestObject(int a, int b, int c) { this.a = a; this.b = b; this.c = c; } } // Alternate render static String render(TestObject to) { return to.a + ":" + to.b + ":" + to.c; } @Test public void testConcurrentExecution() throws InterruptedException { if (skip()) return; String template = "{{aa}}:{{bb}}:{{cc}}"; final Mustache test = new DefaultMustacheFactory().compile(new StringReader(template), "test"); ExecutorService es = Executors.newCachedThreadPool(); final AtomicInteger total = new AtomicInteger(); final Semaphore semaphore = new Semaphore(100); for (int i = 0; i < 100000; i++) { semaphore.acquire(); es.submit(new Runnable() { @Override public void run() { try { TestObject testObject = new TestObject(r.nextInt(), r.nextInt(), r.nextInt()); StringWriter sw = new StringWriter(); test.execute(sw, testObject).close(); if (!render(testObject).equals(sw.toString())) { total.incrementAndGet(); } } catch (IOException e) { // Can't fail e.printStackTrace(); System.exit(1); } finally { semaphore.release(); } } }); } // Wait for them all to complete semaphore.acquire(100); assertEquals(0, total.intValue()); } @Test public void testConcurrentExecutionWithConcurrentTemplate() throws InterruptedException { if (skip()) return; String template = "{{calla}}:{{callb}}:{{callc}}"; ExecutorService es = Executors.newCachedThreadPool(); DefaultMustacheFactory dmf = new DefaultMustacheFactory(); dmf.setExecutorService(es); final Mustache test = dmf.compile(new StringReader(template), "test"); final AtomicInteger total = new AtomicInteger(); final Semaphore semaphore = new Semaphore(100); for (int i = 0; i < 100000; i++) { semaphore.acquire(); es.submit(new Runnable() { @Override public void run() { try { TestObject testObject = new TestObject(r.nextInt(), r.nextInt(), r.nextInt()); StringWriter sw = new StringWriter(); test.execute(sw, testObject).close(); if (!render(testObject).equals(sw.toString())) { total.incrementAndGet(); } } catch (IOException e) { // Can't fail e.printStackTrace(); System.exit(1); } finally { semaphore.release(); } } }); } // Wait for them all to complete semaphore.acquire(100); assertEquals(0, total.intValue()); } } ConvertMethodsToFunctionsTest.java000066400000000000000000000111031241525561000366640ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.Guard; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.reflect.ReflectionWrapper; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import com.google.common.base.Function; import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import static junit.framework.Assert.assertEquals; public class ConvertMethodsToFunctionsTest { private static ReflectionObjectHandler roh; @Retention(RetentionPolicy.RUNTIME) @interface TemplateMethod { } @BeforeClass public static void setup() { roh = new ReflectionObjectHandler() { /** * Find a wrapper given the current context. If not found, return null. * * @param scopeIndex the index into the scope array * @param wrappers the current set of wrappers to get here * @param guards the list of guards used to find this * @param scope the current scope * @param name the name in the scope * @return null if not found, otherwise a wrapper for this scope and name */ @Override protected Wrapper findWrapper(int scopeIndex, Wrapper[] wrappers, List guards, Object scope, String name) { Wrapper wrapper = super.findWrapper(scopeIndex, wrappers, guards, scope, name); if (wrapper == null) { // Now check to see if there is a method that takes a string return getWrapper(scopeIndex, wrappers, guards, scope, name, scope.getClass()); } return wrapper; } private Wrapper getWrapper(final int scopeIndex, final Wrapper[] wrappers, final List guards, Object scope, String name, Class aClass) { try { Method method = aClass.getDeclaredMethod(name, String.class); method.setAccessible(true); return new ReflectionWrapper(scopeIndex, wrappers, guards.toArray(new Guard[guards.size()]), method, null, this) { @Override public Object call(Object[] scopes) throws GuardException { guardCall(scopes); final Object scope1 = unwrap(scopes); if (scope1 == null) return null; if (method.getAnnotation(TemplateMethod.class) == null) { return new Function() { @Override public String apply(String input) { return getString(input, scope1); } }; } else { return new TemplateFunction() { @Override public String apply(String input) { return getString(input, scope1); } }; } } private String getString(String input, Object scope1) { try { Object invoke = method.invoke(scope1, input); return invoke == null ? null : String.valueOf(invoke); } catch (InvocationTargetException e) { throw new MustacheException("Failed to execute method: " + method, e.getTargetException()); } catch (IllegalAccessException e) { throw new MustacheException("Failed to execute method: " + method, e); } } }; } catch (NoSuchMethodException e) { Class superclass = aClass.getSuperclass(); return superclass == Object.class ? null : getWrapper(scopeIndex, wrappers, guards, scope, name, superclass); } } }; } @Test public void testConvert() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); dmf.setObjectHandler(roh); Mustache uppertest = dmf.compile(new StringReader("{{#upper}}{{test}}{{/upper}}"), "uppertest"); StringWriter sw = new StringWriter(); uppertest.execute(sw, new Object() { String test = "test"; String upper(String s) { return s.toUpperCase(); } }).close(); assertEquals("TEST", sw.toString()); sw = new StringWriter(); uppertest.execute(sw, new Object() { String test2 = "test"; @TemplateMethod String upper(String s) { return "{{test2}}"; } }).close(); assertEquals("test", sw.toString()); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/DelimiterTest.java000066400000000000000000000025001241525561000335220ustar00rootroot00000000000000package com.github.mustachejava; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import static org.junit.Assert.assertEquals; public class DelimiterTest { @Test public void testMavenDelimiter() throws IOException { DefaultMustacheFactory mf = new NoEncodingMustacheFactory(); Mustache maven = mf.compile(new StringReader("Hello, ${foo}."), "maven", "${", "}"); StringWriter sw = new StringWriter(); maven.execute(sw, new Object() { String foo = "Jason"; }).close(); assertEquals("Hello, Jason.", sw.toString()); } @Test public void testAntDelimiter() throws IOException { DefaultMustacheFactory mf = new NoEncodingMustacheFactory(); Mustache maven = mf.compile(new StringReader("Hello, @foo@."), "maven", "@", "@"); StringWriter sw = new StringWriter(); maven.execute(sw, new Object() { String foo = "Jason"; }).close(); assertEquals("Hello, Jason.", sw.toString()); } private static class NoEncodingMustacheFactory extends DefaultMustacheFactory { @Override public void encode(String value, Writer writer) { // TODO: encoding rules try { writer.write(value); } catch (IOException e) { throw new MustacheException(e); } } } } DotNotationTest.java000066400000000000000000000036501241525561000337760ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import org.junit.Before; import org.junit.Test; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; public class DotNotationTest { private static final String EARLY_MISS_TEMPLATE = "{{container1.container2.target}}"; private static final String LAST_ELEMENT_MISS_TEMPLATE = "{{container1.nothing}}"; private static final class ModelObject { @SuppressWarnings("unused") public Object getContainer2() { return null; } } private MustacheFactory factory; private Map mapModel; private Map objectModel; @Before public void setUp() { factory = new DefaultMustacheFactory(); mapModel = new HashMap(); Map container1 = new HashMap(); mapModel.put("container1", container1); objectModel = new HashMap(); objectModel.put("container1", new ModelObject()); } @Test public void testIncompleteMapPath() { testMiss(mapModel, EARLY_MISS_TEMPLATE); } @Test public void testAlmostCompleteMapPath() { testMiss(mapModel, LAST_ELEMENT_MISS_TEMPLATE); } @Test public void testIncompleteObjectPath() { testMiss(objectModel, EARLY_MISS_TEMPLATE); } @Test public void testAlmostCompleteObjectPath() { testMiss(objectModel, LAST_ELEMENT_MISS_TEMPLATE); } private void testMiss(Object model, String template) { Mustache mustache = compile(template); StringWriter writer = new StringWriter(); mustache.execute(writer, model); assertEquals("", writer.toString()); } private Mustache compile(String template) { Reader reader = new StringReader(template); return factory.compile(reader, "template"); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/ExamplesTest.java000066400000000000000000000032421241525561000333660ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.util.GuardException; import com.github.mustachejava.util.Wrapper; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import static org.junit.Assert.assertEquals; public class ExamplesTest { @Test public void testExpressionsInNames() throws IOException { DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(new ReflectionObjectHandler() { @Override public Wrapper find(String name, Object[] scopes) { // Worst expression parser ever written follows String[] split = name.split("[*]"); if (split.length > 1) { final double multiplier = Double.parseDouble(split[1].trim()); final Wrapper wrapper = super.find(split[0].trim(), scopes); return new Wrapper() { @Override public Object call(Object[] scopes) throws GuardException { Object value = wrapper.call(scopes); if (value instanceof Number) { value = ((Number) value).doubleValue(); } else { value = value == null ? 0d : Double.parseDouble(value.toString()); } return ((Double) value) * multiplier; } }; } return super.find(name, scopes); } }); Mustache test = mf.compile(new StringReader("{{number * 2.2}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, new Object() { double number = 10; }).flush(); assertEquals("22.0", sw.toString()); } } ExplicitMapNullTest.java000066400000000000000000000016711241525561000346070ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import org.junit.Before; import org.junit.Test; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; public class ExplicitMapNullTest { private static final String TEMPLATE = "{{nullData}}"; private Mustache mustache; @Before public void setUp() { MustacheFactory factory = new DefaultMustacheFactory(); Reader reader = new StringReader(TEMPLATE); mustache = factory.compile(reader, "template"); } @Test public void textExplicitNullMapValue() { Map model = new HashMap(); model.put("nullData", null); StringWriter writer = new StringWriter(); mustache.execute(writer, model); assertEquals("", writer.toString()); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/ExtensionTest.java000066400000000000000000000150311241525561000335630ustar00rootroot00000000000000package com.github.mustachejava; import org.junit.BeforeClass; import org.junit.Test; import java.io.*; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; public class ExtensionTest { private static File root; @Test public void testSub() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("sub.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("name", "Sam"); scope.put("randomid", "asdlkfj"); m.execute(sw, scope); assertEquals(getContents(root, "sub.txt"), sw.toString()); } @Test public void testSubInPartial() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("partialsub.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("name", "Sam"); scope.put("randomid", "asdlkfj"); m.execute(sw, scope); assertEquals(getContents(root, "sub.txt"), sw.toString()); } @Test public void testPartialInSub() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("partialsubpartial.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("randomid", "asdlkfj"); m.execute(sw, scope); assertEquals(getContents(root, "partialsubpartial.txt"), sw.toString()); } @Test public void testFollow() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("follownomenu.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object()); assertEquals(getContents(root, "follownomenu.txt"), sw.toString()); } @Test public void testMultipleExtensions() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("multipleextensions.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object()); assertEquals(getContents(root, "multipleextensions.txt"), sw.toString()); } @Test public void testParentReplace() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("replace.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String replace = "false"; }); assertEquals(getContents(root, "replace.txt"), sw.toString()); } @Test public void testSubBlockCaching() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("subblockchild1.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subblockchild1.txt"), sw.toString()); m = c.compile("subblockchild2.html"); sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subblockchild2.txt"), sw.toString()); m = c.compile("subblockchild1.html"); sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subblockchild1.txt"), sw.toString()); } @Test public void testSubSub() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("subsub.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("name", "Sam"); scope.put("randomid", "asdlkfj"); m.execute(sw, scope); assertEquals(getContents(root, "subsub.txt"), sw.toString()); } @Test public void testClientMethod() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("client.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("reply", "TestReply"); scope.put("commands", Arrays.asList("a", "b")); m.execute(sw, scope); assertEquals(getContents(root, "client.txt"), sw.toString()); } @Test public void testSubSubCaching() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("subsubchild1.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subsubchild1.txt"), sw.toString()); m = c.compile("subsubchild2.html"); sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subsubchild2.txt"), sw.toString()); } @Test public void testSubSubCaching2() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("subsubchild1.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subsubchild1.txt"), sw.toString()); m = c.compile("subsubchild3.html"); sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "subsubchild3.txt"), sw.toString()); } @Test public void testNested() throws IOException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("nested_inheritance.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() {}); assertEquals(getContents(root, "nested_inheritance.txt"), sw.toString()); } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, file)),"UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } @BeforeClass public static void setUp() throws Exception { File file = new File("compiler/src/test/resources"); root = new File(file, "sub.html").exists() ? file : new File("src/test/resources"); } } FailOnMissingTest.java000066400000000000000000000033161241525561000342350ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.GuardedBinding; import com.github.mustachejava.reflect.MissingWrapper; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.util.Wrapper; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class FailOnMissingTest { @Test public void testFail() { ReflectionObjectHandler roh = new ReflectionObjectHandler() { @Override public Binding createBinding(String name, final TemplateContext tc, Code code) { return new GuardedBinding(this, name, tc, code) { @Override protected synchronized Wrapper getWrapper(String name, Object[] scopes) { Wrapper wrapper = super.getWrapper(name, scopes); if (wrapper instanceof MissingWrapper) { throw new MustacheException(name + " not found in " + tc); } return wrapper; } }; } }; DefaultMustacheFactory dmf = new DefaultMustacheFactory(); dmf.setObjectHandler(roh); try { Mustache test = dmf.compile(new StringReader("{{test}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, new Object() { String test = "ok"; }).close(); assertEquals("ok", sw.toString()); test.execute(new StringWriter(), new Object()); fail("Should have failed"); } catch (MustacheException me) { assertEquals("test not found in [test:1] @[test:1]", me.getCause().getMessage()); } catch (IOException e) { e.printStackTrace(); } } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/FallbackTest.java000066400000000000000000000057011241525561000333110ustar00rootroot00000000000000package com.github.mustachejava; import org.junit.BeforeClass; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import static junit.framework.Assert.fail; import static org.junit.Assert.assertEquals; public class FallbackTest { private static File rootDefault; private static File rootOverride; @Test public void testDefaultPage1() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new FallbackMustacheFactory(rootDefault, rootDefault); // no override Mustache m = c.compile("page1.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("title", "My title"); m.execute(sw, scope); assertEquals(getContents(rootDefault, "page1.txt"), sw.toString()); } @Test public void testOverridePage1() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new FallbackMustacheFactory(rootOverride, rootDefault); Mustache m = c.compile("page1.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("title", "My title"); m.execute(sw, scope); assertEquals(getContents(rootOverride, "page1.txt"), sw.toString()); } @Test public void testOverridePage2() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new FallbackMustacheFactory(rootOverride, rootDefault); Mustache m = c.compile("page2.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("title", "My title"); m.execute(sw, scope); assertEquals(getContents(rootOverride, "page2.txt"), sw.toString()); } @Test public void testMustacheNotFoundException() { String nonExistingMustache = "404"; try { MustacheFactory c = new FallbackMustacheFactory(rootOverride, rootDefault); c.compile(nonExistingMustache); fail("Didn't throw an exception"); } catch (MustacheNotFoundException e) { assertEquals(nonExistingMustache, e.getName()); } } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, file)),"UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } @BeforeClass public static void setUp() throws Exception { File file = new File("compiler/src/test/resources/fallback/default"); rootDefault = new File(file, "base.html").exists() ? file : new File("src/test/resources/fallback/default"); file = new File("compiler/src/test/resources/fallback/override"); rootOverride = new File(file, "base.html").exists() ? file : new File("src/test/resources/fallback/override"); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/HelloWorld.java000066400000000000000000000011301241525561000330150ustar00rootroot00000000000000package com.github.mustachejava; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.Writer; public class HelloWorld { // String hello = "Hello"; String world() {return "world";} public static void main(String[] args) throws MustacheException, IOException { Writer writer = new OutputStreamWriter(System.out); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new StringReader("{{hello}}, {{world}}!"), "helloworld"); mustache.execute(writer, new HelloWorld()); writer.flush(); } }InterpreterTest.java000066400000000000000000001235721241525561000340450ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codes.IterableCode; import com.github.mustachejava.codes.PartialCode; import com.github.mustachejava.functions.CommentFunction; import com.github.mustachejava.reflect.SimpleObjectHandler; import com.github.mustachejava.resolver.DefaultResolver; import com.github.mustachejava.util.CapturingMustacheVisitor; import com.github.mustachejavabenchmarks.JsonCapturer; import com.github.mustachejavabenchmarks.JsonInterpreterTest; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import junit.framework.TestCase; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.MappingJsonFactory; import org.junit.Assert; import org.junit.Test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; /** * Tests for the compiler. *

* User: sam * Date: May 3, 2010 * Time: 10:23:54 AM */ public class InterpreterTest extends TestCase { protected File root; public void testSimple() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); assertEquals(getContents(root, "simple.txt"), sw.toString()); } private static class LocalizedMustacheResolver extends DefaultResolver { private final Locale locale; LocalizedMustacheResolver(File root, Locale locale) { super(root); this.locale = locale; } @Override public Reader getReader(String resourceName) { // Build resource name with locale suffix int index = resourceName.lastIndexOf('.'); String newResourceName; if (index == -1) { newResourceName = resourceName; } else { newResourceName = resourceName.substring(0, index) + "_" + locale.toLanguageTag() + resourceName.substring(index); } // First look with locale Reader reader = super.getReader(newResourceName); if(reader == null) { // Fallback to non-localized resourceName reader = super.getReader(resourceName); } return reader; } } public void testSimpleI18N() throws MustacheException, IOException, ExecutionException, InterruptedException { { MustacheFactory c = new DefaultMustacheFactory(new LocalizedMustacheResolver(root, Locale.KOREAN)); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); assertEquals(getContents(root, "simple_ko.txt"), sw.toString()); } { MustacheFactory c = new DefaultMustacheFactory(new LocalizedMustacheResolver(root, Locale.JAPANESE)); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); assertEquals(getContents(root, "simple.txt"), sw.toString()); } } public void testRootCheck() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = createMustacheFactory(); try { Mustache m = c.compile("../../../pom.xml"); fail("Should have failed to compile"); } catch (MustacheException e) { // Success } } public void testSimpleFiltered() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root) { /** * Override this method to apply any filtering to text that will appear * verbatim in the output template. * * * * @param appended * @param startOfLine * @return */ @Override public String filterText(String appended, boolean startOfLine) { // Remove duplicate spaces, leading spaces and trailing spaces if (startOfLine) { appended = appended.replaceAll("^[\t ]+", ""); } return appended .replaceAll("[ \t]+", " ") .replaceAll("[ \n\t]*\n[ \n\t]*", "\n"); } }; Mustache m = c.compile("simplefiltered.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); assertEquals(getContents(root, "simplefiltered.txt"), sw.toString()); } public void testTypedSimple() throws MustacheException, IOException, ExecutionException, InterruptedException { final Object scope = new Object() { String name = "Chris"; int value = 10000; class MyObject { int taxed_value() { return (int) (value - (value * 0.4)); } String fred = ""; } MyObject in_ca = new MyObject(); boolean test = false; }; DefaultMustacheFactory c = new DefaultMustacheFactory(root); c.setObjectHandler(new TypeCheckingHandler()); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, scope.getClass()).flush(); assertEquals(getContents(root, "simpletyped.txt"), sw.toString()); } protected DefaultMustacheFactory createMustacheFactory() { return new DefaultMustacheFactory(root); } public void testRecurision() throws IOException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("recursion.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Object value = new Object() { boolean value = false; }; }); assertEquals(getContents(root, "recursion.txt"), sw.toString()); } public void testRecursionWithInheritance() throws IOException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("recursion_with_inheritance.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Object value = new Object() { boolean value = false; }; }); assertEquals(getContents(root, "recursion.txt"), sw.toString()); } public void testPartialRecursionWithInheritance() throws IOException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("recursive_partial_inheritance.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Object test = new Object() { boolean test = false; }; }); assertEquals(getContents(root, "recursive_partial_inheritance.txt"), sw.toString()); } public void testSimplePragma() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("simplepragma.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); assertEquals(getContents(root, "simple.txt"), sw.toString()); } private class OkGenerator { public boolean isItOk() { return true; } } public void testNestedAccessWithSimpleObjectHandler() throws IOException { assertEquals(getOutput(false), getOutput(true)); } private String getOutput(final boolean setObjectHandler) { final DefaultMustacheFactory mustacheFactory = new DefaultMustacheFactory(); if (setObjectHandler) { mustacheFactory.setObjectHandler(new SimpleObjectHandler()); } final Mustache defaultMustache = mustacheFactory.compile(new StringReader("{{#okGenerator.isItOk}}{{okGenerator.isItOk}}{{/okGenerator.isItOk}}"), "Test template"); final Map params = new HashMap(); params.put("okGenerator", new OkGenerator()); final Writer writer = new StringWriter(); defaultMustache.execute(writer, params); return writer.toString(); } public void testClosingReader() { final AtomicBoolean closed = new AtomicBoolean(); StringReader reader = new StringReader("{{test") { @Override public void close() { closed.set(true); } }; MustacheFactory mf = new DefaultMustacheFactory(); try { mf.compile(reader, "test"); fail("Should have thrown an exception"); } catch (MustacheException me) { // The reader should be closed now assertEquals(true, closed.get()); } } public void testMultipleWrappers() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; Object o = new Object() { int taxed_value() { return (int) (value - (value * 0.4)); } String fred = "test"; }; Object in_ca = Arrays.asList( o, new Object() { int taxed_value = (int) (value - (value * 0.2)); }, o ); }); assertEquals(getContents(root, "simplerewrap.txt"), sw.toString()); } public void testNestedLatchesIterable() throws IOException { DefaultMustacheFactory c = createMustacheFactory(); c.setExecutorService(Executors.newCachedThreadPool()); Mustache m = c.compile("latchedtestiterable.html"); StringWriter sw = new StringWriter(); final StringBuffer sb = new StringBuffer(); final CountDownLatch cdl1 = new CountDownLatch(1); final CountDownLatch cdl2 = new CountDownLatch(1); m.execute(sw, new Object() { Iterable list = Arrays.asList( new Callable() { @Override public Object call() throws Exception { cdl1.await(); sb.append("How"); return "How"; } }, new Callable() { @Override public Object call() throws Exception { cdl2.await(); sb.append("are"); cdl1.countDown(); return "are"; } }, new Callable() { @Override public Object call() throws Exception { sb.append("you?"); cdl2.countDown(); return "you?"; } } ); }).close(); assertEquals(getContents(root, "latchedtest.txt"), sw.toString()); assertEquals("you?areHow", sb.toString()); } public void testNestedLatches() throws IOException { DefaultMustacheFactory c = createMustacheFactory(); c.setExecutorService(Executors.newCachedThreadPool()); Mustache m = c.compile("latchedtest.html"); StringWriter sw = new StringWriter(); Writer execute = m.execute(sw, new Object() { Callable nest = new Callable() { @Override public Object call() throws Exception { Thread.sleep(300); return "How"; } }; Callable nested = new Callable() { @Override public Object call() throws Exception { Thread.sleep(200); return "are"; } }; Callable nestest = new Callable() { @Override public Object call() throws Exception { Thread.sleep(100); return "you?"; } }; }); execute.close(); assertEquals("\nHow\nare\nyou?\n\n", sw.toString()); } public void testBrokenSimple() throws MustacheException, IOException, ExecutionException, InterruptedException { try { MustacheFactory c = init(); Mustache m = c.compile("brokensimple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; }); fail("Should have failed: " + sw.toString()); } catch (Exception e) { // success } } public void testIsNotEmpty() throws IOException { MustacheFactory c = createMustacheFactory(); Mustache m = c.compile("isempty.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { List people = Arrays.asList("Test"); }); assertEquals(getContents(root, "isempty.txt"), sw.toString()); } public void testSecurity() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = init(); Mustache m = c.compile("security.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String name = "Chris"; int value = 10000; int taxed_value() { return (int) (this.value - (this.value * 0.4)); } boolean in_ca = true; // Should not be accessible private String test = "Test"; }); assertEquals(getContents(root, "security.txt"), sw.toString()); } public void testIdentitySimple() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = init(); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.identity(sw); assertEquals(getContents(root, "simple.html").replaceAll("\\s+", ""), sw.toString().replaceAll( "\\s+", "")); } public void testProperties() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = init(); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String getName() { return "Chris"; } int getValue() { return 10000; } int taxed_value() { return (int) (this.getValue() - (this.getValue() * 0.4)); } boolean isIn_ca() { return true; } }); assertEquals(getContents(root, "simple.txt"), sw.toString()); } public void testSimpleWithMap() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = init(); Mustache m = c.compile("simple.html"); StringWriter sw = new StringWriter(); m.execute(sw, new HashMap() {{ put("name", "Chris"); put("value", 10000); put("taxed_value", 6000); put("in_ca", true); }}); assertEquals(getContents(root, "simple.txt"), sw.toString()); } public void testPartialWithTF() throws MustacheException, IOException { MustacheFactory c = init(); Mustache m = c.compile("partialintemplatefunction.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { public TemplateFunction i() { return new TemplateFunction() { @Override public String apply(String s) { return s; } }; } }); assertEquals("This is not interesting.", sw.toString()); } public void testFunctions() throws IOException { MustacheFactory c = init(); Mustache m = c.compile(new StringReader("{{#f}}{{foo}}{{/f}}"), "test"); { StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Function f = new Function() { @Override public String apply(String s) { return s.toUpperCase(); } }; String foo = "bar"; }).flush(); assertEquals("BAR", sw.toString()); } { StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Function f = new TemplateFunction() { @Override public String apply(String s) { return s.toUpperCase(); } }; String foo = "bar"; String FOO = "baz"; }).flush(); assertEquals("baz", sw.toString()); } } public void testComplex() throws MustacheException, IOException { StringWriter json = new StringWriter(); MappingJsonFactory jf = new MappingJsonFactory(); final JsonGenerator jg = jf.createJsonGenerator(json); jg.writeStartObject(); final JsonCapturer captured = new JsonCapturer(jg); MustacheFactory c = new DefaultMustacheFactory(root) { @Override public MustacheVisitor createMustacheVisitor() { return new CapturingMustacheVisitor(this, captured); } }; Mustache m = c.compile("complex.html"); StringWriter sw = new StringWriter(); m.execute(sw, new ComplexObject()); jg.writeEndObject(); jg.flush(); assertEquals(getContents(root, "complex.txt"), sw.toString()); JsonNode jsonNode = jf.createJsonParser(json.toString()).readValueAsTree(); Object o = JsonInterpreterTest.toObject(jsonNode); sw = new StringWriter(); m = init().compile("complex.html"); m.execute(sw, o); assertEquals(getContents(root, "complex.txt"), sw.toString()); } public void testComplexParallel() throws MustacheException, IOException { MustacheFactory c = initParallel(); Mustache m = c.compile("complex.html"); StringWriter sw = new StringWriter(); m.execute(sw, new ParallelComplexObject()).close(); assertEquals(getContents(root, "complex.txt"), sw.toString()); } public void testSerialCallable() throws MustacheException, IOException { MustacheFactory c = init(); Mustache m = c.compile("complex.html"); StringWriter sw = new StringWriter(); m.execute(sw, new ParallelComplexObject()); assertEquals(getContents(root, "complex.txt"), sw.toString()); } /* @SuppressWarnings("serial") public void testCurrentElementInArray() throws IOException, MustacheException { MustacheBuilder c = init(); Mustache m = c.parseFile("simple_array.html"); StringWriter sw = new StringWriter(); FutureWriter writer = new FutureWriter(sw); m.execute(writer, new Scope(new HashMap() { { put("list", Arrays.asList(1,2,3)); } })); writer.flush(); assertEquals(getContents(root, "simple_array.txt"), sw.toString()); sw = new StringWriter(); writer = new FutureWriter(sw); m.execute(writer, new Scope(new HashMap() { { put("list", Arrays.asList(null,null)); } })); writer.flush(); assertEquals("\n\n", sw.toString()); } */ public void testReadme() throws MustacheException, IOException { MustacheFactory c = init(); Mustache m = c.compile("items.html"); StringWriter sw = new StringWriter(); long start = System.currentTimeMillis(); m.execute(sw, new Context()); long diff = System.currentTimeMillis() - start; assertEquals(getContents(root, "items.txt"), sw.toString()); } public void testReadmeSerial() throws MustacheException, IOException { MustacheFactory c = init(); Mustache m = c.compile("items2.html"); StringWriter sw = new StringWriter(); long start = System.currentTimeMillis(); m.execute(sw, new Context()); long diff = System.currentTimeMillis() - start; assertEquals(getContents(root, "items.txt"), sw.toString()); assertTrue("Should be a little bit more than 4 seconds: " + diff, diff > 3999 && diff < 6000); } public void testReadmeParallel() throws MustacheException, IOException { MustacheFactory c = initParallel(); Mustache m = c.compile("items2.html"); StringWriter sw = new StringWriter(); long start = System.currentTimeMillis(); m.execute(sw, new Context()).close(); long diff = System.currentTimeMillis() - start; assertEquals(getContents(root, "items.txt"), sw.toString()); assertTrue("Should be a little bit more than 1 second: " + diff, diff > 999 && diff < 2000); } static class Context { List items() { return Arrays.asList( new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))), new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly."))) ); } static class Item { Item(String name, String price, List features) { this.name = name; this.price = price; this.features = features; } String name, price; List features; } static class Feature { Feature(String description) { this.description = description; } String description; Callable desc() throws InterruptedException { return new Callable() { @Override public String call() throws Exception { Thread.sleep(1000); return description; } }; } } } public void testDeferred() throws IOException { DefaultMustacheFactory mf = new DeferringMustacheFactory(root); mf.setExecutorService(Executors.newCachedThreadPool()); Object context = new Object() { String title = "Deferred"; Object deferred = new DeferringMustacheFactory.DeferredCallable(); Object deferredpartial = DeferringMustacheFactory.DEFERRED; }; Mustache m = mf.compile("deferred.html"); StringWriter sw = new StringWriter(); m.execute(sw, context).close(); assertEquals(getContents(root, "deferred.txt"), sw.toString()); } public void testMultipleCallsWithDifferentScopes() throws IOException { String template = "Value: {{value}}"; Mustache mustache = new DefaultMustacheFactory().compile(new StringReader( template), "test"); // scope object doesn't have a 'value' property, lookup will fail mustache.execute(new StringWriter(), new Object()); // scope object has a 'value' property, lookup shouldn't fail StringWriter sw = new StringWriter(); mustache.execute(sw, new Object() { String value = "something"; }); assertEquals("Value: something", sw.toString()); } public void testMultipleCallsWithDifferentMapScopes() throws IOException { String template = "Value: {{value}}"; Mustache mustache = new DefaultMustacheFactory().compile(new StringReader( template), "test"); Map emptyMap = new HashMap(); Map map = new HashMap(); map.put("value", "something"); // map doesn't have an entry for 'value', lookup will fail mustache.execute(new StringWriter(), emptyMap); // map has an entry for 'value', lookup shouldn't fail StringWriter sw = new StringWriter(); mustache.execute(sw, map); assertEquals("Value: something", sw.toString()); } public void testRelativePathsSameDir() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache compile = mf.compile("relative/paths.html"); StringWriter sw = new StringWriter(); compile.execute(sw, null).close(); assertEquals(getContents(root, "relative/paths.txt"), sw.toString()); } public void testRelativePathsRootDir() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache compile = mf.compile("relative/rootpath.html"); StringWriter sw = new StringWriter(); compile.execute(sw, null).close(); assertEquals(getContents(root, "relative/paths.txt"), sw.toString()); } public void testPathsWithExtension() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache compile = mf.compile("relative/extension.html"); StringWriter sw = new StringWriter(); compile.execute(sw, null).close(); assertEquals(getContents(root, "relative/paths.txt"), sw.toString()); } public void testRelativePathsTemplateFunction() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache compile = mf.compile("relative/functionpaths.html"); StringWriter sw = new StringWriter(); compile.execute(sw, new Object() { Function i = new TemplateFunction() { @Override public String apply(String s) { return s; } }; }).close(); assertEquals(getContents(root, "relative/paths.txt"), sw.toString()); } public void testRelativePathFail() throws IOException { MustacheFactory mf = createMustacheFactory(); try { Mustache compile = mf.compile("relative/pathfail.html"); fail("Should have failed to compile"); } catch (MustacheException e) { // Success } } public void testIterator() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}{{.}}{{/values}}{{^values}}Test2{{/values}}"), "testIterator"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Iterator values() { return Arrays.asList(1, 2, 3).iterator(); } }).close(); assertEquals("123", sw.toString()); } public void testObjectArray() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}{{.}}{{/values}}{{^values}}Test2{{/values}}"), "testObjectArray"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Integer[] values = new Integer[]{1, 2, 3}; }).close(); assertEquals("123", sw.toString()); } public void testBaseArray() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}{{.}}{{/values}}{{^values}}Test2{{/values}}"), "testBaseArray"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { int[] values = new int[]{1, 2, 3}; }).close(); assertEquals("123", sw.toString()); } public void testEmptyString() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}Test1{{/values}}{{^values}}Test2{{/values}}"), "testEmptyString"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String values = ""; }).close(); assertEquals("Test2", sw.toString()); } public void testPrivate() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}Test1{{/values}}{{^values}}Test2{{/values}}"), "testPrivate"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { private String values = "value"; private String values() { return "value"; } }).close(); // Values ignored as if it didn't exist at all assertEquals("Test2", sw.toString()); } public void testSingleCurly() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{value } }}"), "testSingleCurly"); StringWriter sw = new StringWriter(); m.execute(sw, new HashMap() {{ put("value }", "test"); }}).close(); // Values ignored as if it didn't exist at all assertEquals("test", sw.toString()); } public void testPragma() throws IOException { final AtomicBoolean found = new AtomicBoolean(); DefaultMustacheFactory mf = new DefaultMustacheFactory() { @Override public MustacheVisitor createMustacheVisitor() { DefaultMustacheVisitor visitor = new DefaultMustacheVisitor(this); visitor.addPragmaHandler("pragma", new PragmaHandler() { @Override public Code handle(TemplateContext tc, String pragma, String args) { if (pragma.equals("pragma") && args.equals("1 2 3")) { found.set(true); } return null; } }); return visitor; } }; Mustache m = mf.compile(new StringReader("Pragma: {{% pragma 1 2 3 }}"), "testPragma"); StringWriter sw = new StringWriter(); m.execute(sw, null).close(); // Values ignored as if it didn't exist at all assertEquals("Pragma: ", sw.toString()); assertTrue(found.get()); } public void testNotIterableCallable() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{^value}}test{{/value}}"), "testNotIterableCallable"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Callable value = new Callable() { @Override public Object call() throws Exception { return null; } }; }).close(); // Values ignored as if it didn't exist at all assertEquals("test", sw.toString()); } public static class AccessTrackingMap extends HashMap { Set accessed = new HashSet(); @Override public String get(Object key) { accessed.add(key); return super.get(key); } public void check() { Set keyset = new HashSet(keySet()); keyset.removeAll(accessed); if (!keyset.isEmpty()) { throw new MustacheException("All keys in the map were not accessed"); } } } public void testAccessTracker() throws IOException { { Map accessTrackingMap = createBaseMap(); DefaultMustacheFactory mf = createMustacheFactory(); Mustache test = mf.compile(new StringReader("{{first}} {{last}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, accessTrackingMap).close(); assertEquals("Sam Pullara", sw.toString()); } { AccessTrackingMap accessTrackingMap = createBaseMap(); accessTrackingMap.put("notused", "shouldcauseanerror"); DefaultMustacheFactory mf = createMustacheFactory(); Mustache test = mf.compile(new StringReader("{{first}} {{last}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, accessTrackingMap).close(); assertEquals("Sam Pullara", sw.toString()); try { accessTrackingMap.check(); fail("Should have thrown an exception"); } catch (MustacheException me) { // Succcess } } } private AccessTrackingMap createBaseMap() { AccessTrackingMap accessTrackingMap = new AccessTrackingMap(); accessTrackingMap.put("first", "Sam"); accessTrackingMap.put("last", "Pullara"); return accessTrackingMap; } public void testMismatch() { try { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#value}}"), "testMismatch"); fail("Not mismatched"); } catch (MustacheException e) { // Success try { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#value}}{{/values}}"), "testMismatch"); fail("Not mismatched"); } catch (MustacheException e2) { // Success } } } public void testInvalidDelimiters() { try { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{=toolong}}"), "testInvalidDelimiters"); fail("Not invalid"); } catch (MustacheException e) { // Success } } public void testTemplateFunction() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#i}}{{{test}}}{{f}}{{/i}}" + "{{#comment}}comment{{/comment}}"), "testTemplateFunction"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Function i = new TemplateFunction() { @Override public String apply(String s) { return s.replace("test", "test2"); } }; String test2 = "test"; Function f = new Function() { @Override public Object apply(Object o) { return null; } }; CommentFunction comment = new CommentFunction(); }).close(); // Values ignored as if it didn't exist at all assertEquals("test", sw.toString()); } static class SuperClass { String values = "value"; } public void testSuperField() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache m = mf.compile(new StringReader("{{#values}}Test1{{/values}}{{^values}}Test2{{/values}}"), "testIterator"); StringWriter sw = new StringWriter(); m.execute(sw, new SuperClass() { }).close(); // Values ignored as if it didn't exist at all assertEquals("Test1", sw.toString()); } public void testRelativePathsDotDotDir() throws IOException { MustacheFactory mf = createMustacheFactory(); Mustache compile = mf.compile("relative/dotdot.html"); StringWriter sw = new StringWriter(); compile.execute(sw, null).close(); assertEquals(getContents(root, "uninterestingpartial.html"), sw.toString()); } public void testRelativePathsDotDotDirOverride() throws IOException { MustacheFactory mf = new DefaultMustacheFactory(root) { @Override public String resolvePartialPath(String dir, String name, String extension) { return name + extension; } }; Mustache compile = mf.compile("relative/nonrelative.html"); StringWriter sw = new StringWriter(); compile.execute(sw, null).close(); assertEquals(getContents(root, "nonrelative.html"), sw.toString()); } public void testOverrideExtension() throws IOException { MustacheFactory mf = new DefaultMustacheFactory(root) { @Override public MustacheVisitor createMustacheVisitor() { return new DefaultMustacheVisitor(this) { @Override public void partial(TemplateContext tc, String variable) { TemplateContext partialTC = new TemplateContext("{{", "}}", tc.file(), tc.line(), tc.startOfLine()); list.add(new PartialCode(partialTC, df, variable) { @Override protected String partialName() { return name; } }); } }; } }; StringWriter sw = new StringWriter(); mf.compile("overrideextension.html").execute(sw, null).close(); assertEquals("not interesting.", sw.toString()); } public void testEmptyMustache() { try { new DefaultMustacheFactory().compile(new StringReader("{{}}"), "test"); fail("Didn't throw an exception"); } catch (MustacheException e) { assertTrue(e.getMessage().startsWith("Empty mustache")); } } public void testMustacheNotFoundException() { String nonExistingMustache = "404"; try { new DefaultMustacheFactory().compile(nonExistingMustache); fail("Didn't throw an exception"); } catch (MustacheNotFoundException e) { assertEquals(nonExistingMustache, e.getName()); } } public void testImplicitIteratorNoScope() throws IOException { Mustache test = new DefaultMustacheFactory().compile(new StringReader("{{.}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, null).close(); assertEquals("", sw.toString()); StringWriter sw2 = new StringWriter(); test.execute(sw2, new Object[0]).close(); assertEquals("", sw2.toString()); } public void testImplicitIteratorWithScope() throws IOException { Mustache test = new DefaultMustacheFactory().compile(new StringReader("{{#test}}{{.}}{{/test}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, new Object() { List test = Arrays.asList("a", "b", "c"); }).close(); assertEquals("abc", sw.toString()); } public void testCR() { Mustache m = new DefaultMustacheFactory().compile(new StringReader("{{test}}\r\n{{test}}\r\n"), "test"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { String test = "fred"; }); assertEquals("fred\r\nfred\r\n", sw.toString()); } public void testOutputDelimiters() { String template = "{{=## ##=}}{{##={{ }}=####"; Mustache mustache = new DefaultMustacheFactory().compile(new StringReader(template), "test"); StringWriter sw = new StringWriter(); mustache.execute(sw, new Object[0]); assertEquals("{{##", sw.toString()); } public void testLimitedDepthRecursion() { try { MustacheFactory c = init(); Mustache m = c.compile("infiniteparent.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Context()); fail("Should have failed"); } catch (StackOverflowError soe) { fail("Should not have overflowed the stack"); } catch (MustacheException e) { assertEquals("Maximum partial recursion limit reached: 100", e.getMessage()); } } public void testMalformedTag() { try { String template = "\n{{$value}}\n{/value}}"; Mustache mustache = new DefaultMustacheFactory().compile(new StringReader(template), "test"); StringWriter sw = new StringWriter(); mustache.execute(sw, new Object[0]); fail("Should have failed to compile"); } catch (MustacheException e) { assertEquals("Failed to close 'value' tag at line 2", e.getMessage()); } } public void testTemplateFunctionWithData() { String template = "{{#parse}}\n" + "{{replaceMe}}\n" + "{{/parse}}"; Mustache mustache = new DefaultMustacheFactory().compile(new StringReader(template), "test"); StringWriter sw = new StringWriter(); mustache.execute(sw, new Object() { public TemplateFunction parse() { return new TemplateFunction() { @Override public String apply(String s){ return "blablabla {{anotherVar}}, blablabla {{yetAnotherVar}}"; } }; } String anotherVar = "banana"; String yetAnotherVar = "apple"; }); assertEquals("blablabla banana, blablabla apple", sw.toString()); } public void testTemplateFunctionWithImplicitParams() { String template = "{{#parse}}\n" + "{{replaceMe}}\n" + "{{/parse}}"; DefaultMustacheFactory mf = new DefaultMustacheFactory() { public MustacheVisitor createMustacheVisitor() { return new DefaultMustacheVisitor(this) { public void iterable(final TemplateContext templateContext, String variable, Mustache mustache) { list.add(new IterableCode(templateContext, df, mustache, variable) { Binding binding = oh.createBinding("params", templateContext, this); protected Writer handleFunction(Writer writer, Function function, Object[] scopes) { return super.handleFunction(writer, function, addScope(scopes, binding.get(scopes))); } }); } }; } }; Mustache mustache = mf.compile(new StringReader(template), "test"); StringWriter sw = new StringWriter(); mustache.execute(sw, new Object() { public TemplateFunction parse() { return new TemplateFunction() { @Override public String apply(String s){ return "blablabla {{anotherVar}}, blablabla {{yetAnotherVar}}"; } }; } Map params = ImmutableMap.builder() .put("anotherVar", "banana") .put("yetAnotherVar", "apple") .build(); }); assertEquals("blablabla banana, blablabla apple", sw.toString()); } public void testPropertyWithDot() throws IOException { DefaultMustacheFactory mustacheFactory = new DefaultMustacheFactory(); Reader reader = new StringReader("value=${some.value}"); Mustache mustache = mustacheFactory.compile(reader, "maven", "${", "}"); Map properties = new HashMap(); properties.put("some.value", "some.value"); StringWriter writer = new StringWriter(); mustache.execute(writer, new Object[]{properties}).close(); Assert.assertEquals("value=some.value", writer.toString()); } private MustacheFactory init() { return createMustacheFactory(); } private DefaultMustacheFactory initParallel() { DefaultMustacheFactory cf = createMustacheFactory(); cf.setExecutorService(Executors.newCachedThreadPool()); return cf; } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(new File(root, file)), "UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } protected void setUp() throws Exception { super.setUp(); File file = new File("src/test/resources"); root = new File(file, "simple.html").exists() ? file : new File("../src/test/resources"); } @Test public void testMap() throws IOException { ArrayList> fn = new ArrayList>(); Map map1 = new HashMap(); map1.put("name", "firstName"); map1.put("last", "lastName"); fn.add(map1); Map map2 = new HashMap(); map2.put("name", "firstName 1"); map2.put("last", "lastName 1"); fn.add(map2); Map map = new HashMap(); map.put("names", fn); Writer writer = new OutputStreamWriter(System.out); MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(new StringReader("{{#names}}

First Name : {{name}}

Last Name : {{last}}

{{/names}}"), "example"); mustache.execute(writer, map); writer.flush(); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/Issue75Test.java000066400000000000000000000011331241525561000330510ustar00rootroot00000000000000package com.github.mustachejava; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; /** * Reproduction test case */ public class Issue75Test { @Test public void testDotNotationWithNull() throws IOException { DefaultMustacheFactory mf = new DefaultMustacheFactory(); Mustache m = mf.compile(new StringReader("[{{category.name}}]"), "test"); StringWriter sw = new StringWriter(); Map map = new HashMap(); map.put("category", null); m.execute(sw, map).close(); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/JRubyTest.java000066400000000000000000000036351241525561000326510ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.jruby.JRubyObjectHandler; import org.jruby.embed.ScriptingContainer; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import static junit.framework.Assert.assertEquals; public class JRubyTest { @Test public void testHash() throws IOException { ScriptingContainer sc = new ScriptingContainer(); Object context = sc.runScriptlet("{:test=>'fred'}"); DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(new JRubyObjectHandler()); Mustache m = mf.compile(new StringReader("{{test}}"), "test"); Writer writer = new StringWriter(); writer = m.execute(writer, context); writer.close(); assertEquals("fred", writer.toString()); } @Test public void testObject() throws IOException { ScriptingContainer sc = new ScriptingContainer(); Object context = sc.runScriptlet("class Test\ndef test()\n \"fred\"\nend\nend\nTest.new\n"); DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(new JRubyObjectHandler()); Mustache m = mf.compile(new StringReader("{{test}}"), "test"); Writer writer = new StringWriter(); writer = m.execute(writer, context); writer.close(); assertEquals("fred", writer.toString()); } @Test public void testArray() throws IOException { ScriptingContainer sc = new ScriptingContainer(); Object context = sc.runScriptlet("class Test\ndef test()\n [\"fred\",\"fred\"]\nend\nend\nTest.new\n"); DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(new JRubyObjectHandler()); Mustache m = mf.compile(new StringReader("{{#test}}{{.}}{{/test}}"), "test"); Writer writer = new StringWriter(); writer = m.execute(writer, context); writer.close(); assertEquals("fredfred", writer.toString()); } } MapNonGetMethodsTest.java000066400000000000000000000067711241525561000347170ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.reflect.SimpleObjectHandler; import org.junit.Before; import org.junit.Test; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import static org.junit.Assert.assertEquals; public class MapNonGetMethodsTest { /** * Extended reflection handler that can access map methods. */ private class MapMethodReflectionHandler extends ReflectionObjectHandler { @Override protected boolean areMethodsAccessible(Map map) { return true; } } private class SimpleMapMethodHandler extends SimpleObjectHandler { @Override protected boolean areMethodsAccessible(Map map) { return true; } } private static final String TEMPLATE = "{{empty}}"; private static final String TEMPLATE2 = "{{#entrySet}}" + "{{key}}={{value}}\n" + "{{/entrySet}}"; private DefaultMustacheFactory factory; @Before public void setUp() { factory = new DefaultMustacheFactory(); } @Test public void testKeyValues() { Map model = new TreeMap() {{ put("test", "testvalue"); put("key", "keyvalue"); }}; Reader reader = new StringReader(TEMPLATE2); factory.setObjectHandler(new MapMethodReflectionHandler()); Mustache mustache = factory.compile(reader, "template"); verifyOutput("key=keyvalue\ntest=testvalue\n", model, mustache); } @Test public void testMethodAccessDisallowed() { Map model = new HashMap(); Reader reader = new StringReader(TEMPLATE); Mustache mustache = factory.compile(reader, "template"); verifyOutput("", model, mustache); } @Test public void testMethodAccessAllowed() { Map model = new HashMap(); factory.setObjectHandler(new MapMethodReflectionHandler()); Reader reader = new StringReader(TEMPLATE); Mustache mustache = factory.compile(reader, "template"); verifyOutput("true", model, mustache); } @Test public void testWrapperCaching() { factory.setObjectHandler(new MapMethodReflectionHandler()); Reader reader = new StringReader(TEMPLATE); Mustache mustache = factory.compile(reader, "template"); Map model = new HashMap(); verifyOutput("true", model, mustache); model.put("empty", "data"); verifyOutput("data", model, mustache); } @Test public void testSimpleHandlerMethodAccessDisallowed() { Map model = new HashMap(); factory.setObjectHandler(new SimpleObjectHandler()); Reader reader = new StringReader(TEMPLATE); Mustache mustache = factory.compile(reader, "template"); verifyOutput("", model, mustache); } @Test public void testSimpleHandlerMethodAccessAllowed() { Map model = new HashMap(); factory.setObjectHandler(new SimpleMapMethodHandler()); Reader reader = new StringReader(TEMPLATE); Mustache mustache = factory.compile(reader, "template"); verifyOutput("true", model, mustache); } private void verifyOutput(String expected, Object model, Mustache mustache) { StringWriter writer = new StringWriter(); mustache.execute(writer, model); assertEquals(expected, writer.toString()); } } NestedPartialTest.java000066400000000000000000000020311241525561000342630ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import java.io.File; import java.io.StringWriter; import java.util.Arrays; import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; public final class NestedPartialTest { private static final String TEMPLATE_FILE = "nested_partials_template.html"; private static File root; @BeforeClass public static void setUp() throws Exception { File file = new File("compiler/src/test/resources"); root = new File(file, TEMPLATE_FILE).exists() ? file : new File("src/test/resources"); } @Test public void should_handle_more_than_one_level_of_partial_nesting() throws Exception { MustacheFactory factory = new DefaultMustacheFactory(root); Mustache maven = factory.compile(TEMPLATE_FILE); StringWriter sw = new StringWriter(); maven.execute(sw, new Object() { List messages = Arrays.asList("w00pw00p", "mustache rocks"); }).close(); assertEquals("w00pw00p mustache rocks ", sw.toString()); } } ParallelComplexObject.java000066400000000000000000000017601241525561000351070ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; /** * Created by IntelliJ IDEA. * User: spullara * Date: 1/17/12 * Time: 8:19 PM * To change this template use File | Settings | File Templates. */ public class ParallelComplexObject { String header = "Colors"; Callable> item = new Callable>() { @Override public List call() throws Exception { return Arrays.asList( new Color("red", true, "#Red"), new Color("green", false, "#Green"), new Color("blue", false, "#Blue")); } }; boolean list() { return true; } boolean empty() { return false; } private static class Color { boolean link() { return !current; } Color(String name, boolean current, String url) { this.name = name; this.current = current; this.url = url; } String name; boolean current; String url; } } PolymorphicClassTest.java000066400000000000000000000026221241525561000350250ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import static org.junit.Assert.*; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.HashMap; import org.junit.Test; public class PolymorphicClassTest { static class Value { public String getText() { return "ok"; } } static class A { public Value getValue() { return new Value(); } } static class B extends A { @Override public Value getValue() { return new Value(); } } String compile(String template, Object model) { final StringWriter buffer = new StringWriter(); factory.compile(template).execute(buffer, model); return buffer.toString(); } DefaultMustacheFactory factory = new DefaultMustacheFactory() { public Reader getReader(String resourceName) { return new StringReader(resourceName); } }; /** * Test for issue 97, java.lang.IllegalArgumentException: object is not an instance of declaring class */ @Test public void testPolyClass() throws IOException { HashMap model = new HashMap(); model.put("x", new B()); assertEquals("ok", compile("{{x.value.text}}", model)); model.put("x", new A()); assertEquals("ok", compile("{{x.value.text}}", model)); model.put("x", new B()); assertEquals("ok", compile("{{x.value.text}}", model)); } } PreTranslateTest.java000066400000000000000000000040541241525561000341370ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.google.common.base.Function; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import org.junit.Test; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import static junit.framework.Assert.assertEquals; /** * If you want to precompile translations, you will need to do two passes against * templates. This is an example of how to implement this. */ public class PreTranslateTest { @Test public void testPretranslate() throws IOException { MustacheFactory mf = new DefaultMustacheFactory() { MustacheParser mp = new MustacheParser(this) { @Override public Mustache compile(Reader reader, String file) { return super.compile(reader, file, "{[", "]}"); } }; @Override public Mustache compile(Reader reader, String file, String sm, String em) { return super.compile(reader, file, "{[", "]}"); } @Override protected LoadingCache createMustacheCache() { return CacheBuilder.newBuilder().build(new CacheLoader() { @Override public Mustache load(String key) throws Exception { return mp.compile(key); } }); } }; Mustache m = mf.compile("pretranslate.html"); StringWriter sw = new StringWriter(); m.execute(sw, new Object() { Function i = new TemplateFunction() { @Override public String apply(java.lang.String input) { return "{{test}} Translate"; } }; }).close(); assertEquals("{{#show}}\n{{test}} Translate\n{{/show}}", sw.toString()); mf = new DefaultMustacheFactory(); m = mf.compile(new StringReader(sw.toString()), "pretranslate.html"); sw = new StringWriter(); m.execute(sw, new Object() { boolean show = true; String test = "Now"; }).close(); assertEquals("Now Translate\n", sw.toString()); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/SpecTest.java000066400000000000000000000171411241525561000325050ustar00rootroot00000000000000package com.github.mustachejava; import com.google.common.base.Function; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.MappingJsonFactory; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import static junit.framework.Assert.assertFalse; /** * Specification tests */ public class SpecTest { private JsonFactory jf = new MappingJsonFactory(); @Test public void interpolations() throws IOException { run(getSpec("interpolation.json")); } @Test public void sections() throws IOException { run(getSpec("sections.json")); } @Test public void delimiters() throws IOException { run(getSpec("delimiters.json")); } @Test public void inverted() throws IOException { run(getSpec("inverted.json")); } @Test public void partials() throws IOException { run(getSpec("partials.json")); } @Test public void lambdas() throws IOException { run(getSpec("~lambdas.json")); } // @Test — need this to appear in the spec repository to enable public void inheritance() throws IOException { run(getSpec("inheritance.json")); } private void run(JsonNode spec) { int fail = 0; int success = 0; int whitespace = 0; Map functionMap = new HashMap() {{ put("Interpolation", new Object() { Function lambda() { return new Function() { @Override public String apply(String input) { return "world"; } }; } }); put("Interpolation - Expansion", new Object() { Function lambda() { return new TemplateFunction() { @Override public String apply(String input) { return "{{planet}}"; } }; } }); put("Interpolation - Alternate Delimiters", new Object() { Function lambda() { return new TemplateFunction() { @Override public String apply(String input) { return "|planet| => {{planet}}"; } }; } }); put("Interpolation - Multiple Calls", new Object() { int calls = 0; Function lambda() { return new Function() { @Override public String apply(String input) { return String.valueOf(++calls); } }; } }); put("Escaping", new Object() { Function lambda() { return new Function() { @Override public String apply(String input) { return ">"; } }; } }); put("Section", new Object() { Function lambda() { return new TemplateFunction() { @Override public String apply(String input) { return input.equals("{{x}}") ? "yes" : "no"; } }; } }); put("Section - Expansion", new Object() { Function lambda() { return new TemplateFunction() { @Override public String apply(String input) { return input + "{{planet}}" + input; } }; } }); put("Section - Alternate Delimiters", new Object() { Function lambda() { return new TemplateFunction() { @Override public String apply(String input) { return input + "{{planet}} => |planet|" + input; } }; } }); put("Section - Multiple Calls", new Object() { Function lambda() { return new Function() { @Override public String apply(String input) { return "__" + input + "__"; } }; } }); put("Inverted Section", new Object() { Function lambda() { return new Function() { @Override public Object apply(String input) { return false; } }; } }); }}; for (final JsonNode test : spec.get("tests")) { boolean failed = false; final DefaultMustacheFactory CF = createMustacheFactory(test); String file = test.get("name").getTextValue(); System.out.print("Running " + file + " - " + test.get("desc").getTextValue()); StringReader template = new StringReader(test.get("template").getTextValue()); JsonNode data = test.get("data"); try { Mustache compile = CF.compile(template, file); StringWriter writer = new StringWriter(); compile.execute(writer, new Object[] { new JsonMap(data), functionMap.get(file) }); String expected = test.get("expected").getTextValue(); if (writer.toString().replaceAll("\\s+", "").equals(expected.replaceAll("\\s+", ""))) { System.out.print(": success"); if (writer.toString().equals(expected)) { System.out.println("!"); } else { whitespace++; System.out.println(", whitespace differences."); } } else { System.out.println(": failed!"); System.out.println(expected + " != " + writer.toString()); System.out.println(test); failed = true; } } catch (Throwable e) { System.out.println(": exception"); e.printStackTrace(); System.out.println(test); failed = true; } if (failed) fail++; else success++; } System.out.println("Success: " + success + " Whitespace: " + whitespace + " Fail: " + fail); assertFalse(fail > 0); } protected DefaultMustacheFactory createMustacheFactory(final JsonNode test) { return new DefaultMustacheFactory("/spec/specs") { @Override public Reader getReader(String resourceName) { JsonNode partial = test.get("partials").get(resourceName); return new StringReader(partial == null ? "" : partial.getTextValue()); } }; } private JsonNode getSpec(String spec) throws IOException { return jf.createJsonParser(new InputStreamReader( SpecTest.class.getResourceAsStream( "/spec/specs/" + spec))).readValueAsTree(); } private static class JsonMap extends HashMap { private final JsonNode test; public JsonMap(JsonNode test) { this.test = test; } @Override public Object get(Object key) { JsonNode value = test.get(key.toString()); return convert(value); } @Override public boolean containsKey(Object key) { return test.has(key.toString()); } private Object convert(final JsonNode value) { if (value == null || value.isNull()) return null; if (value.isBoolean()) { return value.getBooleanValue(); } else if (value.isValueNode()) { return value.asText(); } else if (value.isArray()) { return new Iterable() { @Override public Iterator iterator() { return new Iterator() { private Iterator iterator = value.iterator(); @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Object next() { return convert(iterator.next()); } @Override public void remove() { } }; } }; } else { return new JsonMap(value); } } } } TestWrapperCaching.java000066400000000000000000000076021241525561000344320ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import org.junit.Before; import org.junit.Test; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; /** * Test that wrappers are not cached too aggressively, * causing false misses or hits. */ public class TestWrapperCaching { private static final String TEMPLATE = "{{object.data}}"; private static final String SCOPES_TEMPLATE = "{{#scope2}}{{#scope1}}{{data.data}}{{/scope1}}{{/scope2}}"; private class TestObject { public TestObject() {} public TestObject(Object data) { this.data = data; } private Object data; public Object getData() { return data; } public void setData(Object data) { this.data = data; } public String toString() { return "{data=" + data + "}"; } } private Mustache template; private Mustache scopesTemplate; @Before public void setUp() { MustacheFactory factory = new DefaultMustacheFactory(); template = factory.compile(new StringReader(TEMPLATE), "template"); scopesTemplate = factory.compile(new StringReader(SCOPES_TEMPLATE), "template"); } /** * Test that initial misses on dot-notation are not incorrectly cached. */ @Test public void testInitialMiss() { Map model = new HashMap(); assertEquals("", render(template, model)); TestObject object = new TestObject(); object.setData("hit"); model.put("object", object); assertEquals("hit", render(template, model)); } /** * Test that initial misses on map dot notation are not incorrectly cached. */ @Test public void testMapInitialMiss() { Map model = new HashMap(); assertEquals("", render(template, model)); Map object = new HashMap(); object.put("data", "hit"); model.put("object", object); assertEquals("hit", render(template, model)); } @Test public void testMultiScopeInitialHit() { Map model = new HashMap(); model.put("scope1", "foo"); //scope 1 full miss model.put("scope2", new TestObject(new TestObject("hit"))); //scope 2 dot hit assertEquals("hit", render(scopesTemplate, model)); model.put("scope2", new TestObject()); //scope2 dot miss assertEquals("", render(scopesTemplate, model)); } @Test public void testMultiScopeInitialHit2() { Map model = new HashMap(); model.put("scope1", new TestObject(new TestObject("hit"))); //scope 1 hit model.put("scope2", "foo"); //scope 2 full miss (shouldn't matter) assertEquals("hit", render(scopesTemplate, model)); model.put("scope1", new TestObject()); //scope1 dot miss assertEquals("", render(scopesTemplate, model)); } @Test public void testMultiScopeInitialMiss() { Map model = new HashMap(); model.put("scope1", new TestObject()); //scope 1 dot miss model.put("scope2", "foo"); //scope 2 full miss (shouldn't matter) assertEquals("", render(scopesTemplate, model)); model.put("scope1", new TestObject(new TestObject("hit"))); //scope 1 dot hit assertEquals("hit", render(scopesTemplate, model)); } @Test public void testMultiScopeInitialMiss2() { Map model = new HashMap(); model.put("scope1", "foo"); //scope 1 full miss model.put("scope2", new TestObject()); //scope 2 dot miss assertEquals("", render(scopesTemplate, model)); model.put("scope2", new TestObject(new TestObject("hit"))); //scope 2 hit assertEquals("hit", render(scopesTemplate, model)); } private String render(Mustache template, Object data) { Writer writer = new StringWriter(); template.execute(writer, data); return writer.toString(); } }mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/functions/000077500000000000000000000000001241525561000321145ustar00rootroot00000000000000BundleFunctionsTest.java000066400000000000000000000073361241525561000366530ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheFactory; import org.junit.BeforeClass; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; /** * @author R.A. Porter * @version 1.0 * @since 1/17/13 */ public class BundleFunctionsTest { private static File root; private static final String BUNDLE = "com.github.mustachejava.functions.translatebundle"; @Test public void testPreLabels() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("bundles.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("trans", BundleFunctions.newPreTranslate(BUNDLE, Locale.US)); scope.put("replaceMe", "replaced"); m.execute(sw, scope); assertEquals(getContents(root, "bundles_pre_labels.txt"), sw.toString()); } @Test public void testPostLabels() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("bundles.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("trans", BundleFunctions.newPostTranslate(BUNDLE, Locale.US)); scope.put("replaceMe", "replaced"); m.execute(sw, scope); assertEquals(getContents(root, "bundles_post_labels.txt"), sw.toString()); } @Test public void testPreNullLabels() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("bundles.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("trans", BundleFunctions.newPreTranslateNullableLabel(BUNDLE, Locale.US)); scope.put("replaceMe", "replaced"); m.execute(sw, scope); assertEquals(getContents(root, "bundles_nulllabels.txt"), sw.toString()); } @Test public void testPostNullLabels() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("bundles.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("trans", BundleFunctions.newPostTranslateNullableLabel(BUNDLE, Locale.US)); // Intentionally leave off the replacement value m.execute(sw, scope); assertEquals(getContents(root, "bundles_nulllabels.txt"), sw.toString()); } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, file)),"UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } @BeforeClass public static void setUp() throws Exception { File compiler = new File("compiler").exists() ? new File("compiler") : new File("."); root = new File(compiler, "src/test/resources/functions"); } } CommentTest.java000066400000000000000000000030751241525561000351470ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheFactory; import org.junit.BeforeClass; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; public class CommentTest { private static File root; @Test public void testCommentBlock() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("comment.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("ignored", "ignored"); m.execute(sw, scope); assertEquals(getContents(root, "comment.txt"), sw.toString()); } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, file)),"UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } @BeforeClass public static void setUp() throws Exception { File file = new File("compiler/src/test/resources/functions"); root = new File(file, "comment.html").exists() ? file : new File("src/test/resources/functions"); } } TranslateBundleTest.java000066400000000000000000000033731241525561000366350ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/functionspackage com.github.mustachejava.functions; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheFactory; import org.junit.BeforeClass; import org.junit.Test; import java.io.*; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.concurrent.ExecutionException; import static org.junit.Assert.assertEquals; public class TranslateBundleTest { private static File root; private static final String BUNDLE = "com.github.mustachejava.functions.translatebundle"; @Test public void testTranslation() throws MustacheException, IOException, ExecutionException, InterruptedException { MustacheFactory c = new DefaultMustacheFactory(root); Mustache m = c.compile("translatebundle.html"); StringWriter sw = new StringWriter(); Map scope = new HashMap(); scope.put("trans", new TranslateBundleFunction(BUNDLE, Locale.US)); m.execute(sw, scope); assertEquals(getContents(root, "translatebundle.txt"), sw.toString()); } protected String getContents(File root, String file) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, file)),"UTF-8")); StringWriter capture = new StringWriter(); char[] buffer = new char[8192]; int read; while ((read = br.read(buffer)) != -1) { capture.write(buffer, 0, read); } return capture.toString(); } @BeforeClass public static void setUp() throws Exception { File compiler = new File("compiler").exists() ? new File("compiler") : new File("."); root = new File(compiler, "src/test/resources/functions"); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/inverter/000077500000000000000000000000001241525561000317425ustar00rootroot00000000000000InvertToJsonTest.java000066400000000000000000000106011241525561000357700ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/inverterpackage com.github.mustachejava.inverter; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.util.Node; import com.github.mustachejava.util.NodeValue; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.map.MappingJsonFactory; import org.junit.Test; import java.io.IOException; import java.io.StringWriter; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Map; public class InvertToJsonTest extends InvertUtils { @Test public void testToJson() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("fdbcli.mustache"); Path file = getPath("src/test/resources/fdbcli.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); Node invert = compile.invert(txt); MappingJsonFactory jf = new MappingJsonFactory(); StringWriter out = new StringWriter(); JsonGenerator jg = jf.createJsonGenerator(out); writeNode(jg, invert); jg.flush(); System.out.println(out.toString()); } @Test public void testToJson2() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("fdbcli2.mustache"); Path file = getPath("src/test/resources/fdbcli2.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); Node invert = compile.invert(txt); MappingJsonFactory jf = new MappingJsonFactory(); StringWriter out = new StringWriter(); JsonGenerator jg = jf.createJsonGenerator(out); writeNode(jg, invert); jg.flush(); System.out.println(out.toString()); } @Test public void testToJson3() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("psauxwww.mustache"); Path file = getPath("src/test/resources/psauxwww.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); Node invert = compile.invert(txt); MappingJsonFactory jf = new MappingJsonFactory(); StringWriter out = new StringWriter(); JsonGenerator jg = jf.createJsonGenerator(out); writeNode(jg, invert); jg.flush(); System.out.println(out.toString()); } @Test public void testToJson4() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("fdbcli2.mustache"); Path file = getPath("src/test/resources/fdbcli3.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); System.out.println("Input text:["); System.out.print(txt); System.out.println("]"); Node invert = compile.invert(txt); MappingJsonFactory jf = new MappingJsonFactory(); StringWriter out = new StringWriter(); JsonGenerator jg = jf.createJsonGenerator(out); writeNode(jg, invert); jg.flush(); System.out.println(out.toString()); } @Test public void testToJson5() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("fdbcli3.mustache"); Path file = getPath("src/test/resources/fdbcli.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); Node invert = compile.invert(txt); MappingJsonFactory jf = new MappingJsonFactory(); StringWriter out = new StringWriter(); JsonGenerator jg = jf.createJsonGenerator(out); writeNode(jg, invert); jg.flush(); System.out.println(out.toString()); } private void writeNode(final JsonGenerator jg, Node invert) throws IOException { jg.writeStartObject(); for (final Map.Entry entry : invert.entrySet()) { NodeValue nodeValue = entry.getValue(); if (nodeValue.isList() && nodeValue.list().size() > 0) { jg.writeFieldName(entry.getKey()); List list = nodeValue.list(); boolean array = list.size() > 1; if (array) jg.writeStartArray(); for (Node node : list) { writeNode(jg, node); } if (array) jg.writeEndArray(); } else { String value = nodeValue.value(); if (value != null) { jg.writeFieldName(entry.getKey()); try { double v = Double.parseDouble(value); jg.writeNumber(v); } catch (NumberFormatException e) { jg.writeString(value); } } } } jg.writeEndObject(); } } InvertUtils.java000066400000000000000000000007471241525561000350260ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/inverterpackage com.github.mustachejava.inverter; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Path; /** * TODO: Edit this *

* User: sam * Date: 9/7/13 * Time: 10:14 PM */ public class InvertUtils { public Path getPath(String name) { FileSystem fs = FileSystems.getDefault(); Path path = fs.getPath(name); if (path.toFile().exists()) { return path; } else { return fs.getPath("compiler/" + name); } } } InverterTest.java000066400000000000000000000053471241525561000351750ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/inverterpackage com.github.mustachejava.inverter; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import com.github.mustachejava.util.Node; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.nio.file.Files; import java.nio.file.Path; import java.util.UUID; import static com.github.mustachejava.util.NodeValue.list; import static com.github.mustachejava.util.NodeValue.value; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class InverterTest extends InvertUtils { @Test public void testParser() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile("fdbcli.mustache"); Path file = getPath("src/test/resources/fdbcli.txt"); String txt = new String(Files.readAllBytes(file), "UTF-8"); Node invert = compile.invert(txt); System.out.println(invert); } @Test public void testSimple() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache test = dmf.compile(new StringReader("test {{value}} test"), "test"); Node invert = test.invert("test value test"); Node node = new Node(); node.put("value", value("value")); assertEquals(node, invert); } @Test public void testIterable() throws IOException { DefaultMustacheFactory dmf = new DefaultMustacheFactory(); Mustache test = dmf.compile(new StringReader("{{#values}}\ntest: {{value}}\n{{/values}}"), "test"); Node invert = test.invert("test: sam\ntest: fred\n"); Node node = new Node(); Node sam = new Node(); sam.put("value", value("sam")); Node fred = new Node(); fred.put("value", value("fred")); node.put("values", list(asList(sam, fred))); assertEquals(node, invert); StringWriter sw = new StringWriter(); test.execute(sw, invert).close(); System.out.println(sw); } @Test public void testCollectPoints() throws Exception { MustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile(new StringReader("{{#page}}This is a {{test}}{{/page}}"), UUID.randomUUID().toString()); Node node = compile.invert("This is a good day"); assertNotNull(node); } @Test public void testNoNode() throws Exception { MustacheFactory dmf = new DefaultMustacheFactory(); Mustache compile = dmf.compile(new StringReader("Using cluster file [^\\n]+\nHello World"), UUID.randomUUID().toString()); Node node = compile.invert("Using cluster file `/etc/foundationdb/fdb.cluster'.\nHello World"); assertNotNull(node); } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/simple/000077500000000000000000000000001241525561000313755ustar00rootroot00000000000000SimpleSpecTest.java000066400000000000000000000007751241525561000350760ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/simplepackage com.github.mustachejava.simple; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.SpecTest; import com.github.mustachejava.reflect.SimpleObjectHandler; import org.codehaus.jackson.JsonNode; public class SimpleSpecTest extends SpecTest { @Override protected DefaultMustacheFactory createMustacheFactory(JsonNode test) { DefaultMustacheFactory mf = super.createMustacheFactory(test); mf.setObjectHandler(new SimpleObjectHandler()); return mf; } } mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/util/000077500000000000000000000000001241525561000310615ustar00rootroot00000000000000DecoratedCollectionTest.java000066400000000000000000000035711241525561000364210ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import com.github.mustachejava.reflect.ReflectionObjectHandler; import org.junit.Test; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.Arrays; import java.util.Collection; import static org.junit.Assert.assertEquals; public class DecoratedCollectionTest { @Test public void testIndexLastFirst() throws IOException { MustacheFactory mf = new DefaultMustacheFactory(); Mustache test = mf.compile(new StringReader( "{{#test}}{{index}}: {{#first}}first: {{/first}}{{#last}}last: {{/last}}{{value}}\n{{/test}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, new Object() { Collection test = new DecoratedCollection(Arrays.asList("First", "Second", "Third", "Last")); }).flush(); assertEquals("0: first: First\n1: Second\n2: Third\n3: last: Last\n", sw.toString()); } @Test public void testObjectHandler() throws IOException { DefaultMustacheFactory mf = new DefaultMustacheFactory(); mf.setObjectHandler(new ReflectionObjectHandler() { @Override public Object coerce(Object object) { if (object instanceof Collection) { return new DecoratedCollection((Collection) object); } return super.coerce(object); } }); Mustache test = mf.compile(new StringReader( "{{#test}}{{index}}: {{#first}}first: {{/first}}{{#last}}last: {{/last}}{{value}}\n{{/test}}"), "test"); StringWriter sw = new StringWriter(); test.execute(sw, new Object() { Collection test = Arrays.asList("First", "Second", "Third", "Last"); }).flush(); assertEquals("0: first: First\n1: Second\n2: Third\n3: last: Last\n", sw.toString()); } } HtmlEscaperTest.java000066400000000000000000000054611241525561000347220ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import junit.framework.TestCase; import java.io.StringWriter; import static com.github.mustachejava.util.HtmlEscaper.escape; public class HtmlEscaperTest extends TestCase { public void testEscape() throws Exception { { StringWriter sw = new StringWriter(); escape("Hello, world!", sw, true); assertEquals("Hello, world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("Hello & world!", sw, true); assertEquals("Hello & world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("Hello & world!", sw, false); assertEquals("Hello & world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("Hello & world!", sw, true); assertEquals("Hello &amp; world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("Hello & world!", sw, true); assertEquals("Hello &amp world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & world!", sw, true); assertEquals(""Hello" &amp world!", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & world! ", sw, false); assertEquals(""Hello" &amp world! ", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & world! ", sw, true); assertEquals(""Hello" &amp world!&#10;", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & !\n", sw, true); assertEquals(""Hello" &amp <world>! ", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & world!\n&sam", sw, true); assertEquals(""Hello" &amp world! &sam", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & 'world'!\n&sam", sw, true); assertEquals(""Hello" &amp 'world'! &sam", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" & 'world'!\n&sam", sw, true); assertEquals(""Hello" &amp 'world'! &sam", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" &&#zz 'world'!\n&sam", sw, true); assertEquals(""Hello" &amp&#zz 'world'! &sam", sw.toString()); } { StringWriter sw = new StringWriter(); escape("\"Hello\" &&#zz 'world'!\n&sam&#", sw, true); assertEquals(""Hello" &amp&#zz 'world'! &sam&#", sw.toString()); } } } HtmlWriterTest.java000066400000000000000000000111001241525561000345770ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/compiler/src/test/java/com/github/mustachejava/utilpackage com.github.mustachejava.util; import com.github.mustachejavabenchmarks.NullWriter; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.*; import static com.github.mustachejava.util.HtmlState.HTML.*; import static junit.framework.Assert.assertEquals; public class HtmlWriterTest { private HtmlState state; private StateAwareWriter w; private void c(HtmlState.HTML expected) { assertEquals(expected, state.getState()); } @Before public void setup() { w = new StateAwareWriter(new StringWriter(), state = new HtmlState()); } @After public void tearDown() throws IOException { w.close(); } @Test public void bodyToTag() throws IOException { c(BODY); w.write("<"); c(TAG); } @Test public void bodyToTagName() throws IOException { w.write(""); c(BODY); } @Test public void bodyToTagToBody() throws IOException { w.write(""); c(BODY); w.write(""); c(BODY); } @Test public void bodyToAttributes() throws IOException { w.write(" body stuff <"); c(TAG); w.write(" /"); c(END_TAG); w.write(" test"); c(END_TAG_NAME); w.write(" "); c(AFTER_END_TAG_NAME); w.write(">"); c(BODY); } @Test public void script() throws IOException { w.write("

Hello, Sam!
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/subblockchild1.html000066400000000000000000000001071241525561000302370ustar00rootroot00000000000000{{ Subtitle
Hello, world!
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/subsubchild1.html000066400000000000000000000001201241525561000277310ustar00rootroot00000000000000{{ {{$title}}Default Title{{/title}} {{$head}} {{/head}}
{{$body}}Default Body{{/body}}
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/template.html000066400000000000000000000001721241525561000271630ustar00rootroot00000000000000 Items
  1. Item 1
  2. Item 2
  3. Item 3
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/template.mustache000066400000000000000000000001661241525561000300330ustar00rootroot00000000000000 {{title}}
    {{#items}}
  1. {{item}}
  2. {{/items}}
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/toomany.html000066400000000000000000000001641241525561000270370ustar00rootroot00000000000000{{ mustache.java-mustache.java-0.8.17/compiler/src/test/resources/twitter.html000066400000000000000000005506241241525561000270660ustar00rootroot00000000000000 Twitter
Image will appear as a link
Link will appear shortened Links will appear shortened 140

Tweets

Very much, if it means I get to keep both the loot and my rights. RT : how'd you like to be David Guetta or Pink Floyd?

NBC will still make money airing tape-delayed events in a realtime era. The big problem is they can't adapt to new audience behaviors.

indeed. We're working to figure out what happened. Trust me, the community won't let shenanigans like this stand.

lorenzo, the parrot was arrested by the Columbian police after he warned the drug cartels that the police was nearby.

"At the end of your life you'll either be an example, or a warning." - Baron Baptiste this morning

Brazil signed up for $20,000,000 U.S. "loan". Foreign Minister Aranha: "We should erect a statue to Hitler- he made USA finally notice us"

Truer words have never been tweeted! “: the week is for meetings; the weekend is for working.”

It's quite evident that NBC thinks it's still 1996. Their live stream was embargo'ed on iPad until half way through too.

Aiming for the finish line: 2 thruster firings tonight will adjust my path for final approach to Mars. 8 days till landing!

if you put a sheet over a birdcage it falls asleep but if you put one over me I'm a ghost yaaay

the USA badly need a BBC. The bbc have 23 live sports channels during the Olympics and all HD - all free and no ads CC

Ok one more: not airing key events live on TV gives whole country that awful "I didn't see it yet! No spoilers please!" anxiety

Loading seems to be taking a while.

Twitter may be over capacity or experiencing a momentary hiccup. Try again or visit Twitter Status for more information.

Image will appear as a link
Link will appear shortened Links will appear shortened 140
mustache.java-mustache.java-0.8.17/compiler/src/test/resources/uninterestingpartial.html000066400000000000000000000000201241525561000316130ustar00rootroot00000000000000not interesting.mustache.java-mustache.java-0.8.17/example/000077500000000000000000000000001241525561000205235ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/pom.xml000066400000000000000000000034241241525561000220430ustar00rootroot00000000000000 4.0.0 com.github.spullara.mustache.java example 0.8.16-SNAPSHOT bundle com.github.spullara.mustache.java compiler 0.8.15 org.apache.maven.plugins maven-compiler-plugin 1.6 1.6 UTF-8 com.github.spullara.mustache.java mustache-maven-plugin 0.8.16-SNAPSHOT validate org.apache.felix maven-bundle-plugin 2.3.7 true mustache.java-mustache.java-0.8.17/example/src/000077500000000000000000000000001241525561000213125ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/src/main/000077500000000000000000000000001241525561000222365ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/src/main/java/000077500000000000000000000000001241525561000231575ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/src/main/java/mustachejava/000077500000000000000000000000001241525561000256325ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/src/main/java/mustachejava/DeferredExample.java000066400000000000000000000016601241525561000315340ustar00rootroot00000000000000package mustachejava; import com.github.mustachejava.DeferringMustacheFactory; import com.github.mustachejava.Mustache; import java.io.IOException; import java.io.PrintWriter; import java.util.concurrent.Executors; /** * This show how to use the deferred mustache factory. *

* User: sam * Date: 7/7/12 * Time: 12:32 PM */ public class DeferredExample { Object deferredpartial = DeferringMustacheFactory.DEFERRED; Object deferred = new DeferringMustacheFactory.DeferredCallable(); boolean wait1second() throws InterruptedException { Thread.sleep(1000); return true; } public static void main(String[] args) throws IOException { DeferringMustacheFactory mf = new DeferringMustacheFactory(); mf.setExecutorService(Executors.newCachedThreadPool()); Mustache m = mf.compile("deferring.mustache"); PrintWriter pw = new PrintWriter(System.out); m.execute(pw, new DeferredExample()).close(); } } mustache.java-mustache.java-0.8.17/example/src/main/java/mustachejava/Example.java000066400000000000000000000022311241525561000300660ustar00rootroot00000000000000package mustachejava; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.List; public class Example { List items() { return Arrays.asList( new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))), new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly."))) ); } static class Item { Item(String name, String price, List features) { this.name = name; this.price = price; this.features = features; } String name, price; List features; } static class Feature { Feature(String description) { this.description = description; } String description; } public static void main(String[] args) throws IOException { MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile("template.mustache"); mustache.execute(new PrintWriter(System.out), new Example()).flush(); } } mustache.java-mustache.java-0.8.17/example/src/main/resources/000077500000000000000000000000001241525561000242505ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/example/src/main/resources/deferredpartial.mustache000066400000000000000000000000701241525561000311350ustar00rootroot00000000000000{{#wait1second}}This was saved for later{{/wait1second}}mustache.java-mustache.java-0.8.17/example/src/main/resources/deferring.mustache000066400000000000000000000001231241525561000277440ustar00rootroot00000000000000This comes first {{>deferredpartial}} Then we show this immediately {{{deferred}}} mustache.java-mustache.java-0.8.17/example/src/main/resources/template.mustache000066400000000000000000000001701241525561000276140ustar00rootroot00000000000000 {{#items}} Name: {{name}} Price: {{price}} {{#features}} Feature: {{description}} {{/features}} {{/items}} mustache.java-mustache.java-0.8.17/handlebar/000077500000000000000000000000001241525561000210105ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/pom.xml000066400000000000000000000052011241525561000223230ustar00rootroot00000000000000 com.github.spullara.mustache.java mustache.java 0.8.17 ../pom.xml 4.0.0 com.github.spullara.mustache.java handlebar bundle handlebar http://maven.apache.org UTF-8 com.github.spullara.cli-parser cli-parser 1.0 com.github.spullara.mustache.java compiler 0.8.17 org.codehaus.jackson jackson-mapper-asl 1.9.4 org.eclipse.jetty jetty-server 7.0.2.v20100331 junit junit 4.8.1 test org.apache.felix maven-bundle-plugin maven-assembly-plugin jar-with-dependencies com.sampullara.mustache.Handlebar make-assembly package attached mustache.java-mustache.java-0.8.17/handlebar/src/000077500000000000000000000000001241525561000215775ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/000077500000000000000000000000001241525561000225235ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/java/000077500000000000000000000000001241525561000234445ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/java/com/000077500000000000000000000000001241525561000242225ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/java/com/sampullara/000077500000000000000000000000001241525561000263635ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/java/com/sampullara/mustache/000077500000000000000000000000001241525561000301745ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/java/com/sampullara/mustache/Handlebar.java000066400000000000000000000172721241525561000327300ustar00rootroot00000000000000package com.sampullara.mustache; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.activation.FileTypeMap; import javax.activation.MimetypesFileTypeMap; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.github.mustachejava.TemplateFunction; import com.google.common.base.Function; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.MappingJsonFactory; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.Mustache; import com.github.mustachejava.MustacheFactory; import com.google.common.base.Throwables; import com.google.common.io.Files; import com.sampullara.cli.Args; import com.sampullara.cli.Argument; /** * Run a local server and merge .js and .html files using mustache. *

* User: sam Date: Jun 15, 2010 Time: 4:25:31 PM */ public class Handlebar { @Argument(alias = "p") private static Integer port = 8000; @Argument(alias = "d", required = true) private static String dir; @Argument(alias = "m") private static String mocks; private static File rootDir; private static final FileTypeMap FILE_TYPE_MAP; private static final JsonFactory JSON_FACTORY = new MappingJsonFactory(); static { FILE_TYPE_MAP = loadFileTypeMapFromContextSupportModule(); } private static FileTypeMap loadFileTypeMapFromContextSupportModule() { // see if we can find the extended mime.types from the context-support module InputStream is = ClassLoader.getSystemResourceAsStream("com/sampullara/mustache/mimes.txt"); if (null != is) { return new MimetypesFileTypeMap(is); } return FileTypeMap.getDefaultFileTypeMap(); } public static Object toObject(final JsonNode node) { if (node.isArray()) { return new ArrayList() { { for (JsonNode jsonNodes : node) { add(toObject(jsonNodes)); } } }; } else if (node.isObject()) { return new HashMap() { { for (Iterator> i = node.getFields(); i.hasNext();) { Map.Entry next = i.next(); Object o = toObject(next.getValue()); put(next.getKey(), o); } } }; } else if (node.isBoolean()) { return node.getBooleanValue(); } else if (node.isNull()) { return null; } else { return node.asText(); } } public static void main(String[] args) throws Exception { try { Args.parse(Handlebar.class, args); } catch (IllegalArgumentException e) { Args.usage(Handlebar.class); System.exit(1); } rootDir = new File(dir); if (null == mocks) mocks = dir; Handler handler = new AbstractHandler() { public void handle(String s, Request r, HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { try { String pathInfo = req.getPathInfo(); if (pathInfo.endsWith("/")) pathInfo += "index.html"; // obtain mime type String mimeType = FILE_TYPE_MAP.getContentType(pathInfo); System.out.println(String.format("%s: %s", mimeType, pathInfo)); // create a handle to the resource File staticres = new File(rootDir, pathInfo.substring(1)); res.setContentType(mimeType == null ? "text/html" : mimeType); res.setCharacterEncoding("utf-8"); if (mimeType == null || mimeType.equals("text/html")) { // Handle like a template String filename = pathInfo.substring(1); // check if file exists if (!staticres.exists()) { res.setStatus(HttpServletResponse.SC_NOT_FOUND); processTemplate(req, res, "404.html"); } else { res.setStatus(HttpServletResponse.SC_OK); processTemplate(req, res, filename); } r.setHandled(true); } else { if (!staticres.exists()) { res.setStatus(HttpServletResponse.SC_NOT_FOUND); return; } // Handle like a file res.setStatus(HttpServletResponse.SC_OK); ServletOutputStream out = res.getOutputStream(); Files.copy(staticres, out); out.close(); r.setHandled(true); } } catch (Exception e) { // params Map params = new HashMap(); params.put("stacktrace", Throwables.getStackTraceAsString(e)); // render template res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); processTemplate(req, res, "500.html", params); r.setHandled(true); } } private void processTemplate(HttpServletRequest req, HttpServletResponse res, String filename, Object... scopes) throws UnsupportedEncodingException, FileNotFoundException, IOException, JsonParseException, JsonProcessingException { if (!new File(rootDir, filename).exists()) { System.out.println("template not found, skipping: " + filename); return; } MustacheFactory mc = new DefaultMustacheFactory(rootDir); Mustache mustache = mc.compile(filename); String base = filename.substring(0, filename.lastIndexOf(".")); File file = new File(mocks, base + ".json"); Map parameters = new HashMap(req.getParameterMap()) { @Override public Object get(Object o) { Object result = super.get(o); // To change body of overridden methods use File | // Settings | File Templates. if (result instanceof String[]) { String[] strings = (String[]) result; if (strings.length == 1) { return strings[0]; } } return result; } }; List scs = new ArrayList(); if (null != scopes) scs.addAll(Arrays.asList(scopes)); scs.add(parameters); scs.add(new Object() { Function slots = new TemplateFunction() { @Override public String apply(String input) { return "{{>" + input.trim() + "}}"; } }; }); if (file.exists()) { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")); JsonParser parser = JSON_FACTORY.createJsonParser(br); JsonNode json = parser.readValueAsTree(); br.close(); scs.add(0, toObject(json)); } mustache.execute(res.getWriter(), scs.toArray()); } private String simpleEscape(String string) { return string.replace("&", "&").replace("<", "<").replace(">", ">"); } }; Server server = new Server(port); server.setHandler(handler); server.start(); } } mustache.java-mustache.java-0.8.17/handlebar/src/main/resources/000077500000000000000000000000001241525561000245355ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/resources/com/000077500000000000000000000000001241525561000253135ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/resources/com/sampullara/000077500000000000000000000000001241525561000274545ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/resources/com/sampullara/mustache/000077500000000000000000000000001241525561000312655ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/main/resources/com/sampullara/mustache/mimes.txt000066400000000000000000000206351241525561000331460ustar00rootroot00000000000000################################################################################ # Copyright 2002-2010 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ################################################################################ ################################################################################ # # Defaults for the Java Activation Framework # Additional extensions registered in this file: # text/plain java c c++ pl cc h # ################################################################################ text/html html htm HTML HTM text/plain txt text TXT TEXT java c c++ pl cc h image/gif gif GIF image/ief ief image/jpeg jpeg jpg jpe JPG image/tiff tiff tif image/x-xwindowdump xwd application/postscript ai eps ps application/rtf rtf application/x-tex tex application/x-texinfo texinfo texi application/x-troff t tr roff audio/basic au audio/midi midi mid audio/x-aifc aifc audio/x-aiff aif aiff audio/x-mpeg mpeg mpg audio/x-wav wav video/mpeg mpeg mpg mpe video/quicktime qt mov video/x-msvideo avi ################################################################################ # # Additional file types adapted from # http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html # kindly re-licensed to Apache Software License 2.0 by Ian Graham. # ################################################################################ # TEXT TYPES text/x-speech talk text/css css text/csv csv # IMAGE TYPES # icon image/x-icon ico # X-Windows bitmap (b/w) image/x-xbitmap xbm # X-Windows pixelmap (8-bit color) image/x-xpixmap xpm # Portable Network Graphics image/x-png png # Image Exchange Format (RFC 1314) image/ief ief # JPEG image/jpeg jpeg jpg jpe # RGB image/rgb rgb # Group III Fax (RFC 1494) image/g3fax g3f # X Windowdump format image/x-xwindowdump xwd # Macintosh PICT format image/x-pict pict # PPM (UNIX PPM package) image/x-portable-pixmap ppm # PGM (UNIX PPM package) image/x-portable-graymap pgm # PBM (UNIX PPM package) image/x-portable-bitmap pbm # PNM (UNIX PPM package) image/x-portable-anymap pnm # Microsoft Windows bitmap image/x-ms-bmp bmp # CMU raster image/x-cmu-raster ras # Kodak Photo-CD image/x-photo-cd pcd # Computer Graphics Metafile image/cgm cgm # CALS Type 1 or 2 image/x-cals mil cal # Fractal Image Format (Iterated Systems) image/fif fif # QuickSilver active image (Micrografx) image/x-mgx-dsf dsf # CMX vector image (Corel) image/x-cmx cmx # Wavelet-compressed (Summus) image/wavelet wi # AutoCad Drawing (SoftSource) image/vnd.dwg dwg # AutoCad DXF file (SoftSource) image/vnd.dxf dxf # Simple Vector Format (SoftSource) image/vnd.svf svf # AUDIO/VOICE/MUSIC RELATED TYPES # """basic""audio - 8-bit u-law PCM" audio/basic au snd # Macintosh audio format (AIpple) audio/x-aiff aif aiff aifc # Microsoft audio audio/x-wav wav # MPEG audio audio/x-mpeg mpa abs mpega # MPEG-2 audio audio/x-mpeg-2 mp2a mpa2 # compressed speech (Echo Speech Corp.) audio/echospeech es # Toolvox speech audio (Voxware) audio/voxware vox # RapidTransit compressed audio (Fast Man) application/fastman lcc # Realaudio (Progressive Networks) application/x-pn-realaudio ra ram # MIDI music data x-music/x-midi mmid # Koan music data (SSeyo) application/vnd.koan skp # Speech synthesis data (MVP Solutions) text/x-speech talk # VIDEO TYPES # MPEG video video/mpeg mpeg mpg mpe # MPEG-2 video video/mpeg-2 mpv2 mp2v # Macintosh Quicktime video/quicktime qt mov # Microsoft video video/x-msvideo avi # SGI Movie format video/x-sgi-movie movie # VDOlive streaming video (VDOnet) video/vdo vdo # Vivo streaming video (Vivo software) video/vnd.vivo viv # SPECIAL HTTP/WEB APPLICATION TYPES # Proxy autoconfiguration (Netscape browsers) application/x-ns-proxy-autoconfig pac # Netscape Cooltalk chat data (Netscape) x-conference/x-cooltalk ice # TEXT-RELATED # PostScript application/postscript ai eps ps # Microsoft Rich Text Format application/rtf rtf # Adobe Acrobat PDF application/pdf pdf # Maker Interchange Format (FrameMaker) application/vnd.mif mif # Troff document application/x-troff t tr roff # Troff document with MAN macros application/x-troff-man man # Troff document with ME macros application/x-troff-me me # Troff document with MS macros application/x-troff-ms ms # LaTeX document application/x-latex latex # Tex/LateX document application/x-tex tex # GNU TexInfo document application/x-texinfo texinfo texi # TeX dvi format application/x-dvi dvi # MS word document application/msword doc DOC # Office Document Architecture application/oda oda # Envoy Document application/envoy evy # ARCHIVE/COMPRESSED ARCHIVES # Gnu tar format application/x-gtar gtar # 4.3BSD tar format application/x-tar tar # POSIX tar format application/x-ustar ustar # Old CPIO format application/x-bcpio bcpio # POSIX CPIO format application/x-cpio cpio # UNIX sh shell archive application/x-shar shar # DOS/PC - Pkzipped archive application/zip zip # Macintosh Binhexed archive application/mac-binhex40 hqx # Macintosh Stuffit Archive application/x-stuffit sit sea # Fractal Image Format application/fractals fif # "Binary UUencoded" application/octet-stream bin uu # PC executable application/octet-stream exe # "WAIS ""sources""" application/x-wais-source src wsrc # NCSA HDF data format application/hdf hdf # DOWNLOADABLE PROGRAM/SCRIPTS # Javascript program text/javascript js ls mocha # UNIX bourne shell program application/x-sh sh # UNIX c-shell program application/x-csh csh # Perl program application/x-perl pl # Tcl (Tool Control Language) program application/x-tcl tcl # ANIMATION/MULTIMEDIA # FutureSplash vector animation (FutureWave) application/futuresplash spl # mBED multimedia data (mBED) application/mbedlet mbd # PowerMedia multimedia (RadMedia) application/x-rad-powermedia rad # PRESENTATION # PowerPoint presentation (Microsoft) application/mspowerpoint ppz # ASAP WordPower (Software Publishing Corp.) application/x-asap asp # Astound Web Player multimedia data (GoldDisk) application/astound asn # SPECIAL EMBEDDED OBJECT # OLE script e.g. Visual Basic (Ncompass) application/x-olescript axs # OLE Object (Microsoft/NCompass) application/x-oleobject ods # OpenScape OLE/OCX objects (Business@Web) x-form/x-openscape opp # Visual Basic objects (Amara) application/x-webbasic wba # Specialized data entry forms (Alpha Software) application/x-alpha-form frm # client-server objects (Wayfarer Communications) x-script/x-wfxclient wfx # GENERAL APPLICATIONS # Undefined binary data (often executable progs) application/octet-stream exe com # Pointcast news data (Pointcast) application/x-pcn pcn # Excel spreadsheet (Microsoft) application/vnd.ms-excel xls # PowerPoint (Microsoft) application/vnd.ms-powerpoint ppt # Microsoft Project (Microsoft) application/vnd.ms-project mpp # SourceView document (Dataware Electronics) application/vnd.svd svd # Net Install - software install (20/20 Software) application/x-net-install ins # Carbon Copy - remote control/access (Microcom) application/ccv ccv # Spreadsheets (Visual Components) workbook/formulaone vts # 2D/3D DATA/VIRTUAL REALITY TYPES # VRML data file x-world/x-vrml wrl vrml # WIRL - VRML data (VREAM) x-world/x-vream vrw # Play3D 3d scene data (Play3D) application/x-p3d p3d # Viscape Interactive 3d world data (Superscape) x-world/x-svr svr # WebActive 3d data (Plastic Thought) x-world/x-wvr wvr # QuickDraw3D scene data (Apple) x-world/x-3dmf 3dmf # SCIENTIFIC/MATH/CAD TYPES # Mathematica notebook application/mathematica ma # Computational meshes for numerical simulations x-model/x-mesh msh # Vis5D 5-dimensional data application/vis5d v5d # IGES models -- CAD/CAM (CGM) data application/iges igs # Autocad WHIP vector drawings drawing/x-dwf dwf # Common mustache extension text/html mustache mustache.java-mustache.java-0.8.17/handlebar/src/test/000077500000000000000000000000001241525561000225565ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/test/resources/000077500000000000000000000000001241525561000245705ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/test/resources/mocks/000077500000000000000000000000001241525561000257045ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/handlebar/src/test/resources/mocks/test.json000066400000000000000000000003121241525561000275520ustar00rootroot00000000000000{ "title": "This is the title", "header": "The table header", "rows": [ { "name": "Name 1", "data": "Data 1" }, { "name": "Name 2", "data": "Data 2" } ] }mustache.java-mustache.java-0.8.17/handlebar/src/test/resources/test.html000066400000000000000000000003511241525561000264340ustar00rootroot00000000000000 {{title}}

{{header}}

{{#rows}} {{/rows}}
NameData
{{name}}{{data}}
mustache.java-mustache.java-0.8.17/indy/000077500000000000000000000000001241525561000200335ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/pom.xml000066400000000000000000000046121241525561000213530ustar00rootroot00000000000000 mustache.java com.github.spullara.mustache.java 0.8.17 ../pom.xml 4.0.0 com.github.spullara.mustache.java indy 0.8.17 bundle indy Invokedynamic implementation of ObjectHandler http://github.com/spullara/mustache.java com.github.spullara.mustache.java codegen 0.8.17 org.jruby jruby 1.6.7 provided junit junit 4.8.2 test org.codehaus.jackson jackson-mapper-asl 1.9.3 test com.github.spullara.mustache.java compiler 0.8.17 tests test org.apache.maven.plugins maven-compiler-plugin 1.7 1.7 UTF-8 org.apache.felix maven-bundle-plugin mustache.java-mustache.java-0.8.17/indy/src/000077500000000000000000000000001241525561000206225ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/000077500000000000000000000000001241525561000215465ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/000077500000000000000000000000001241525561000224675ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/com/000077500000000000000000000000001241525561000232455ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/com/github/000077500000000000000000000000001241525561000245275ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/com/github/mustachejava/000077500000000000000000000000001241525561000272025ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/com/github/mustachejava/indy/000077500000000000000000000000001241525561000301455ustar00rootroot00000000000000IndyObjectHandler.java000066400000000000000000000014321241525561000342610ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/main/java/com/github/mustachejava/indypackage com.github.mustachejava.indy; import com.github.mustachejava.codegen.CodegenObjectHandler; import com.github.mustachejava.codegen.CodegenReflectionWrapper; import com.github.mustachejava.util.Wrapper; /** * Creates custom classes instead of using reflection for handling objects. Leverages * the ReflectionObjectHandler to create the original wrappers and converts them to * new versions. */ public class IndyObjectHandler extends CodegenObjectHandler { @Override public Wrapper find(String name, Object[] scopes) { Wrapper wrapper = super.find(name, scopes); if (wrapper instanceof CodegenReflectionWrapper) { CodegenReflectionWrapper rw = (CodegenReflectionWrapper) wrapper; return IndyWrapper.create(rw); } else { return wrapper; } } } mustache.java-mustache.java-0.8.17/indy/src/main/java/com/github/mustachejava/indy/IndyWrapper.java000066400000000000000000000157451241525561000332700ustar00rootroot00000000000000package com.github.mustachejava.indy; import com.github.mustachejava.MustacheException; import com.github.mustachejava.codegen.CodegenReflectionWrapper; import com.github.mustachejava.reflect.ReflectionWrapper; import com.github.mustachejava.util.GuardException; import org.objectweb.asm.*; import org.objectweb.asm.commons.GeneratorAdapter; import java.lang.invoke.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.UUID; /** * Creates wrappers using ASM and Invokedynamic. */ public abstract class IndyWrapper extends CodegenReflectionWrapper implements Opcodes { public static final Handle BOOTSTRAP_METHOD = new Handle(Opcodes.H_INVOKESTATIC, "com/github/mustachejava/indy/IndyWrapper", "bootstrap", MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class).toMethodDescriptorString()); private static final String METHOD_SIGNATURE = "(Lcom/github/mustachejava/indy/IndyWrapper;Ljava/lang/Object;)Ljava/lang/Object;"; /** * This bootstrap method simply points to the lookup method so we can see what is on the stack at runtime * since we need the parameters in order to make a decision. * * @param caller * @param name * @param type * @return * @throws NoSuchMethodException * @throws IllegalAccessException */ public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MutableCallSite callSite = new MutableCallSite(MethodType.methodType(Object.class, IndyWrapper.class, Object.class)); MethodHandle lookup = caller.findStatic(IndyWrapper.class, "lookup", MethodType.methodType(Object.class, MutableCallSite.class, IndyWrapper.class, Object.class)); lookup = MethodHandles.insertArguments(lookup, 0, callSite); callSite.setTarget(lookup); return callSite; } protected IndyWrapper(ReflectionWrapper rw) { super(rw); } public abstract Object call(Object[] scopes) throws GuardException; // { public static IndyWrapper create(CodegenReflectionWrapper rw) { return create(rw, true); } public static IndyWrapper create(CodegenReflectionWrapper rw, boolean guard) { String name; Method method = rw.getMethod(); if (method == null) { Field field = rw.getField(); name = "W_" + field.getDeclaringClass().getSimpleName() + "_" + field.getName(); } else { name = "W_" + method.getDeclaringClass().getSimpleName() + "_" + method.getName(); } String className = encodeClassName("com.github.mustachejava.indy", name); try { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, className.replace(".", "/"), null, "com/github/mustachejava/indy/IndyWrapper", null); cw.visitSource(className + ".java", null); { org.objectweb.asm.commons.Method constructor = org.objectweb.asm.commons.Method.getMethod( "void (com.github.mustachejava.reflect.ReflectionWrapper)"); GeneratorAdapter ga = new GeneratorAdapter(ACC_PUBLIC, constructor, null, null, cw); ga.loadThis(); ga.loadArg(0); ga.invokeConstructor(Type.getType(IndyWrapper.class), constructor); ga.returnValue(); ga.endMethod(); } { GeneratorAdapter ga = new GeneratorAdapter(ACC_PUBLIC, org.objectweb.asm.commons.Method.getMethod("Object call(Object[])"), null, new Type[] { Type.getType(GuardException.class)}, cw); if (guard) { ga.visitVarInsn(ALOAD, 0); ga.visitVarInsn(ALOAD, 1); ga.invokeVirtual(Type.getType(IndyWrapper.class), org.objectweb.asm.commons.Method.getMethod("void guardCall(Object[])")); } ga.visitVarInsn(ALOAD, 0); ga.visitVarInsn(ALOAD, 1); ga.invokeVirtual(Type.getType(IndyWrapper.class), org.objectweb.asm.commons.Method.getMethod("Object unwrap(Object[])")); ga.visitVarInsn(ASTORE, 2); ga.visitVarInsn(ALOAD, 2); Label l0 = new Label(); ga.ifNonNull(l0); ga.visitInsn(ACONST_NULL); ga.returnValue(); ga.visitLabel(l0); ga.visitVarInsn(ALOAD, 0); ga.visitVarInsn(ALOAD, 2); ga.invokeDynamic("bootstrap", METHOD_SIGNATURE, BOOTSTRAP_METHOD); ga.returnValue(); ga.endMethod(); } cw.visitEnd(); Class aClass = defineClass(className, cw.toByteArray()); return (IndyWrapper) aClass.getConstructor(ReflectionWrapper.class).newInstance(rw); } catch (Exception e) { throw new MustacheException(e); } } public static String encodeClassName(String pkgName, String name) { String uuid = UUID.randomUUID().toString().replace("-", "_"); return pkgName + "." + name + "_" + uuid; } private static final IndyClassLoader indyCL = new IndyClassLoader(Thread.currentThread().getContextClassLoader()); private static class IndyClassLoader extends ClassLoader { public IndyClassLoader(ClassLoader parent) { super(parent); } public Class defineClass(final String name, final byte[] b) { return defineClass(name, b, 0, b.length); } } public static Class defineClass(String name, byte[] b) { return indyCL.defineClass(name, b); } /** * This bootstrap method does the actual work of tracking down the CallSite at runtime. * * @param callSite * @param iw * @param scope * @return * @throws IllegalAccessException * @throws InvocationTargetException */ public static Object lookup(MutableCallSite callSite, IndyWrapper iw, Object scope) throws IllegalAccessException, InvocationTargetException { Method method = iw.getMethod(); if (method == null) { Field field = iw.getField(); MethodHandle unreflect = MethodHandles.lookup().unreflectGetter(field); unreflect = MethodHandles.dropArguments(unreflect, 0, IndyWrapper.class); setCallsite(callSite, unreflect); return field.get(scope); } else { MethodHandle unreflect = MethodHandles.lookup().unreflect(method); unreflect = MethodHandles.dropArguments(unreflect, 0, IndyWrapper.class); if (method.getParameterTypes().length != 0) { for (int i = 0; i < iw.getArguments().length; i++) { unreflect = MethodHandles.insertArguments(unreflect, i + 2, iw.getArguments()[i]); } } setCallsite(callSite, unreflect); return method.invoke(scope, iw.getArguments()); } } private static void setCallsite(MutableCallSite callSite, MethodHandle unreflect) { unreflect = MethodHandles.explicitCastArguments(unreflect, MethodType.methodType(Object.class, IndyWrapper.class, Object.class)); callSite.setTarget(unreflect); } } mustache.java-mustache.java-0.8.17/indy/src/test/000077500000000000000000000000001241525561000216015ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/000077500000000000000000000000001241525561000225225ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/IndyDemo.java000066400000000000000000000153551241525561000251060ustar00rootroot00000000000000import com.github.mustachejava.codegen.CodegenObjectHandler; import com.github.mustachejava.codegen.CodegenReflectionWrapper; import com.github.mustachejava.indy.IndyObjectHandler; import com.github.mustachejava.indy.IndyWrapper; import com.github.mustachejava.reflect.ReflectionObjectHandler; import com.github.mustachejava.util.Wrapper; import org.junit.Test; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Method; public class IndyDemo { public static final int TIMES = 100000000; public static void main(String[] args) throws Throwable { IndyDemo indyDemo = new IndyDemo(); for (int i = 0; i < 10; i++) { timeReflectionOH(indyDemo); timeCodegenReflectionOH(indyDemo); timeIndy(indyDemo); timeIndyNoGuard(indyDemo); timeIndyOH(indyDemo); timeReflection(indyDemo); timeReflectionCached(indyDemo); timeUnReflection(indyDemo); timeUnReflectionCached(indyDemo); timeMH(indyDemo); timeMHCached(indyDemo); timeDirect(indyDemo); System.out.println("-----------------"); } } public static void timeReflectionOH(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Object[] scopes = {indyDemo}; for (int i = 0; i < TIMES; i++) { REFLECTED.call(scopes); } System.out.println("reflection OH: " + (System.currentTimeMillis() - start)); } public static void timeCodegenReflectionOH(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Object[] scopes = {indyDemo}; for (int i = 0; i < TIMES; i++) { CODEGEN_REFLECTED.call(scopes); } System.out.println("codegen reflection OH: " + (System.currentTimeMillis() - start)); } @Test public void timeIndyOH() throws Throwable { for (int i = 0; i < 10; i++) { timeIndy(new IndyDemo()); } } @Test public void timeReflectionOH() throws Throwable { for (int i = 0; i < 10; i++) { timeReflectionOH(new IndyDemo()); } } public static void timeIndy(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Object[] scopes = {indyDemo}; for (int i = 0; i < TIMES; i++) { INDY.call(scopes); } System.out.println("indy wrapper: " + (System.currentTimeMillis() - start)); } public static void timeIndyNoGuard(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Object[] scopes = {indyDemo}; for (int i = 0; i < TIMES; i++) { INDY_NOGUARD.call(scopes); } System.out.println("indy wrapper no guard: " + (System.currentTimeMillis() - start)); } public static void timeIndyOH(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Object[] scopes = {indyDemo}; for (int i = 0; i < TIMES; i++) { INDY_OH.call(scopes); } System.out.println("indy OH: " + (System.currentTimeMillis() - start)); } public static void timeReflection(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); int REFLECTION_TIMES = 10000000; for (int i = 0; i < REFLECTION_TIMES; i++) { IndyDemo.class.getDeclaredMethod("someMethod").invoke(indyDemo); } System.out.println("reflection: " + (TIMES/ REFLECTION_TIMES)*(System.currentTimeMillis() - start)); } public static void timeReflectionCached(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); Method someMethod = IndyDemo.class.getDeclaredMethod("someMethod"); for (int i = 0; i < TIMES; i++) { someMethod.invoke(indyDemo); } System.out.println("reflection cached: " + (System.currentTimeMillis() - start)); } public static void timeUnReflection(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); int REFLECTION_TIMES = 10000; MethodHandles.Lookup lookup = MethodHandles.lookup(); for (int i = 0; i < REFLECTION_TIMES; i++) { int result = (int) lookup.unreflect(IndyDemo.class.getDeclaredMethod("someMethod")).invokeExact(indyDemo); } System.out.println("unreflection: " + (TIMES/ REFLECTION_TIMES)*(System.currentTimeMillis() - start)); } public static void timeUnReflectionCached(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle someMethod = lookup.unreflect(IndyDemo.class.getDeclaredMethod("someMethod")); for (int i = 0; i < TIMES; i++) { int result = (int) someMethod.invokeExact(indyDemo); } System.out.println("unreflection cached: " + (System.currentTimeMillis() - start)); } public static void timeMH(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); int REFLECTION_TIMES = 10000; MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType type = MethodType.methodType(Integer.TYPE); for (int i = 0; i < REFLECTION_TIMES; i++) { MethodHandle someMethod = lookup.findVirtual(IndyDemo.class, "someMethod", type); int result = (int) someMethod.invokeExact(indyDemo); } System.out.println("methodhandle: " + (TIMES/ REFLECTION_TIMES)*(System.currentTimeMillis() - start)); } public static void timeMHCached(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType type = MethodType.methodType(Integer.TYPE); MethodHandle someMethod = lookup.findVirtual(IndyDemo.class, "someMethod", type); for (int i = 0; i < TIMES; i++) { int result = (int) someMethod.invokeExact(indyDemo); } System.out.println("methodhandle cached: " + (System.currentTimeMillis() - start)); } public static void timeDirect(IndyDemo indyDemo) throws Throwable { long start = System.currentTimeMillis(); for (int i = 0; i < TIMES; i++) { indyDemo.someMethod(); } System.out.println("direct: " + (System.currentTimeMillis() - start)); } private static Wrapper REFLECTED; private static Wrapper INDY; private static IndyWrapper INDY_NOGUARD; private static Wrapper CODEGEN_REFLECTED; private static final Wrapper INDY_OH; static { IndyDemo indyDemo = new IndyDemo(); REFLECTED = new ReflectionObjectHandler().find("someMethod", new Object[] { indyDemo }); CODEGEN_REFLECTED = new CodegenObjectHandler().find("someMethod", new Object[] { indyDemo }); INDY = IndyWrapper.create((CodegenReflectionWrapper) CODEGEN_REFLECTED); INDY_NOGUARD = IndyWrapper.create((CodegenReflectionWrapper) CODEGEN_REFLECTED, false); INDY_OH = new IndyObjectHandler().find("someMethod", new Object[] { indyDemo }); } private int length = 0; public int someMethod() { return length++; } }mustache.java-mustache.java-0.8.17/indy/src/test/java/com/000077500000000000000000000000001241525561000233005ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/000077500000000000000000000000001241525561000245625ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/mustachejava/000077500000000000000000000000001241525561000272355ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/mustachejava/IndyBenchmarkTest.java000066400000000000000000000012311241525561000334530ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejava.indy.IndyObjectHandler; import com.github.mustachejavabenchmarks.BenchmarkTest; /** * Compare compilation with interpreter. *

* User: sam * Date: 5/14/11 * Time: 9:28 PM */ public class IndyBenchmarkTest extends BenchmarkTest { @Override public void testCompiler() { } @Override protected DefaultMustacheFactory createMustacheFactory() { DefaultMustacheFactory mustacheFactory = new CodegenMustacheFactory(root); mustacheFactory.setObjectHandler(new IndyObjectHandler()); return mustacheFactory; } } IndyInterpreterTest.java000066400000000000000000000007151241525561000340130ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejava.indy.IndyObjectHandler; public class IndyInterpreterTest extends InterpreterTest { @Override protected DefaultMustacheFactory createMustacheFactory() { DefaultMustacheFactory mustacheFactory = new CodegenMustacheFactory(root); mustacheFactory.setObjectHandler(new IndyObjectHandler()); return mustacheFactory; } } IndyJsonInterpreterTest.java000066400000000000000000000011651241525561000346450ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/mustachejavapackage com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejava.indy.IndyObjectHandler; import com.github.mustachejavabenchmarks.JsonInterpreterTest; /** * Tests for the compiler. *

* User: sam * Date: May 3, 2010 * Time: 10:23:54 AM */ public class IndyJsonInterpreterTest extends JsonInterpreterTest { @Override protected DefaultMustacheFactory createMustacheFactory() { DefaultMustacheFactory mustacheFactory = new CodegenMustacheFactory(root); mustacheFactory.setObjectHandler(new IndyObjectHandler()); return mustacheFactory; } } mustache.java-mustache.java-0.8.17/indy/src/test/java/com/github/mustachejava/IndySpecTest.java000066400000000000000000000014751241525561000324650ustar00rootroot00000000000000package com.github.mustachejava; import com.github.mustachejava.codegen.CodegenMustacheFactory; import com.github.mustachejava.indy.IndyObjectHandler; import org.codehaus.jackson.JsonNode; import java.io.Reader; import java.io.StringReader; /** * Specification tests */ public class IndySpecTest extends SpecTest { @Override protected DefaultMustacheFactory createMustacheFactory(final JsonNode test) { DefaultMustacheFactory mustacheFactory = new CodegenMustacheFactory("/spec/specs") { @Override public Reader getReader(String resourceName) { JsonNode partial = test.get("partials").get(resourceName); return new StringReader(partial == null ? "" : partial.getTextValue()); } }; mustacheFactory.setObjectHandler(new IndyObjectHandler()); return mustacheFactory; } } mustache.java-mustache.java-0.8.17/indy/src/test/resources000077700000000000000000000000001241525561000317072../../../compiler/src/test/resourcesustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/javascript/000077500000000000000000000000001241525561000212365ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/javascript/pom.xml000066400000000000000000000013211241525561000225500ustar00rootroot00000000000000 com.github.spullara.mustache.java mustache.java 0.8.15-SNAPSHOT 4.0.0 javascript com.github.spullara.mustache.java compiler 0.8.15-SNAPSHOT mustache.java-mustache.java-0.8.17/mustache-maven-plugin/000077500000000000000000000000001241525561000233015ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/pom.xml000066400000000000000000000040651241525561000246230ustar00rootroot00000000000000 4.0.0 com.github.spullara.mustache.java mustache.java 0.8.17 mustache-maven-plugin 0.8.17 maven-plugin mustache-maven-plugin Maven Mojo http://maven.apache.org org.apache.maven.plugins maven-plugin-plugin 3.2 true mojo-descriptor descriptor help-goal helpmojo org.apache.maven.plugin-tools maven-plugin-annotations 3.2 compile org.apache.maven maven-plugin-api 3.2.1 org.codehaus.plexus plexus-compiler-api 2.3 com.github.spullara.mustache.java compiler 0.8.17 mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/000077500000000000000000000000001241525561000240705ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/000077500000000000000000000000001241525561000250145ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/000077500000000000000000000000001241525561000257355ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/000077500000000000000000000000001241525561000265135ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/github/000077500000000000000000000000001241525561000277755ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/github/spullara/000077500000000000000000000000001241525561000316205ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/github/spullara/mustache/000077500000000000000000000000001241525561000334315ustar00rootroot00000000000000000077500000000000000000000000001241525561000343165ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/github/spullara/mustache/mojoMustacheValidationMojo.java000066400000000000000000000047231241525561000416000ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/mustache-maven-plugin/src/main/java/com/github/spullara/mustache/mojopackage com.github.spullara.mustache.mojo; import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.MustacheException; import com.github.mustachejava.MustacheFactory; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.codehaus.plexus.compiler.util.scan.InclusionScanException; import org.codehaus.plexus.compiler.util.scan.SimpleSourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.SourceInclusionScanner; import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner; import org.codehaus.plexus.compiler.util.scan.mapping.SuffixMapping; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.Collections; import java.util.Set; @Mojo(name = "validate", defaultPhase = LifecyclePhase.PROCESS_RESOURCES) public class MustacheValidationMojo extends AbstractMojo { @Parameter(defaultValue = "src/main/resources") private File sourceDirectory; @Parameter(defaultValue = "target/classes") private File outputDirectory; @Parameter(defaultValue = "mustache") private String extension; @Parameter(defaultValue = "false") private boolean includeStale; public void execute() throws MojoExecutionException, MojoFailureException { SourceInclusionScanner scanner = includeStale ? new StaleSourceScanner(1024, Collections.singleton("**/*." + extension), Collections.emptySet()) : new SimpleSourceInclusionScanner(Collections.singleton("**/*." + extension), Collections.emptySet()); scanner.addSourceMapping(new SuffixMapping("." + extension, "." + extension)); MustacheFactory mustacheFactory = new DefaultMustacheFactory(); try { Set files = scanner.getIncludedSources(sourceDirectory, outputDirectory); for (File file : files) { try { mustacheFactory.compile(new FileReader(file), file.getAbsolutePath()); } catch (MustacheException e) { throw new MojoFailureException(e.getMessage(), e); } } } catch (InclusionScanException e) { throw new MojoExecutionException(e.getMessage()); } catch (FileNotFoundException e) { throw new MojoExecutionException(e.getMessage()); } } } mustache.java-mustache.java-0.8.17/nodetest.js000066400000000000000000000015101241525561000212500ustar00rootroot00000000000000var sys = require('sys'); var m = require("mustache"); var fs = require("fs"); var items = [{name:"red", current:true, url:"#Red", link:false}, {name:"green", current:false, url:"#Green", link:true}, {name:"blue", current:false, url:"#Blue", link:true}]; var view = { header : "Colors", item : items, list:function() { return items.length != 0; }, empty:function() { return items.length == 0; } }; fs.readFile("src/test/resources/complex.html", function(err, data) { if (err) throw err; var template = data.toString(); var html = m.to_html(template, view); var start = new Date().getTime(); var total = 0; sys.puts(m.to_html(template, view)); while(true) { m.to_html(template, view); total++; if (new Date().getTime() - start > 5000) { break; } } sys.puts(total / 5); }); mustache.java-mustache.java-0.8.17/pom.xml000066400000000000000000000071171241525561000204130ustar00rootroot00000000000000 4.0.0 com.github.spullara.mustache.java mustache.java 0.8.17 Implementation of the Mustache language in Java. compiler handlebar codegen indy mustache-maven-plugin scala-extensions pom mustache.java http://github.com/spullara/mustache.java spullara Sam Pullara spullara@yahoo.com http://javarants.com architect developer -8 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:git:git@github.com:spullara/mustache.java.git scm:git:git@github.com:spullara/mustache.java.git scm:git:git@github.com:spullara/mustache.java.git mustache.java-0.8.17 sonatype-nexus-staging https://oss.sonatype.org/service/local/staging/deploy/maven2 sonatype-nexus-snapshots https://oss.sonatype.org/content/repositories/snapshots org.apache.felix maven-bundle-plugin 2.3.7 true org.apache.maven.plugins maven-compiler-plugin 2.5.1 1.6 1.6 UTF-8 org.apache.maven.plugins maven-release-plugin 2.5 release-sign-artifacts performRelease true org.apache.maven.plugins maven-gpg-plugin 1.4 sign-artifacts verify sign mustache.java-mustache.java-0.8.17/scala-extensions/000077500000000000000000000000001241525561000223505ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/pom.xml000066400000000000000000000014531241525561000236700ustar00rootroot00000000000000 4.0.0 com.github.spullara.mustache.java mustache.java 0.8.17 ../pom.xml scala-extensions Scala extensions parent module scala-extensions-2.8 scala-extensions-2.9 scala-extensions-2.10 pom mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/000077500000000000000000000000001241525561000262065ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/build.sbt000066400000000000000000000005341241525561000300210ustar00rootroot00000000000000lazy val `scala-extensions-2-10` = project .in(file(".")) .settings( resolvers += Resolver.mavenLocal, scalaVersion := "2.10.4", libraryDependencies ++= Seq( "com.github.spullara.mustache.java" % "compiler" % "0.8.17-SNAPSHOT", "junit" % "junit" % "4.8.2" % "test", "com.twitter" % "util-core" % "6.12.1" ) )mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/pom.xml000066400000000000000000000064521241525561000275320ustar00rootroot00000000000000 scala-extensions com.github.spullara.mustache.java 0.8.17 ../pom.xml 4.0.0 scala-extensions-2.10 jar scala-extensions-2.10 Scala extensions for mustache.java http://github.com/spullara/mustache.java Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 repo Sam Pullara sam@sampullara.com http://www.javarants.com Twitter http://maven.twttr.com/ UTF-8 com.github.spullara.mustache.java compiler 0.8.17 junit junit 4.8.2 test org.scala-lang scala-library 2.10.4 provided com.twitter util-core 6.12.1 provided src/main/scala src/test/scala org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin scala-compile-first process-resources add-source compile scala-test-compile process-test-resources testCompile mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/000077500000000000000000000000001241525561000267755ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/000077500000000000000000000000001241525561000277215ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/scala/000077500000000000000000000000001241525561000310045ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/scala/com/000077500000000000000000000000001241525561000315625ustar00rootroot00000000000000000077500000000000000000000000001241525561000332055ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/scala/com/twitter000077500000000000000000000000001241525561000350165ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/scala/com/twitter/mustacheScalaObjectHandler.scala000066400000000000000000000037111241525561000414750ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/main/scala/com/twitter/mustachepackage com.twitter.mustache import collection.JavaConversions._ import com.github.mustachejava.Iteration import com.github.mustachejava.reflect.ReflectionObjectHandler import java.io.Writer import java.lang.reflect.{Field, Method} import runtime.BoxedUnit import scala.reflect.ClassTag /** * Plain old scala handler that doesn't depend on Twitter libraries. */ class ScalaObjectHandler extends ReflectionObjectHandler { // Allow any method or field override def checkMethod(member: Method) {} override def checkField(member: Field) {} override def coerce(value: AnyRef) = { value match { case m: collection.Map[_, _] => mapAsJavaMap(m) case u: BoxedUnit => null case Some(some: AnyRef) => coerce(some) case None => null case _ => value } } override def iterate(iteration: Iteration, writer: Writer, value: AnyRef, scopes: Array[AnyRef]) = { value match { case TraversableAnyRef(t) => { var newWriter = writer t foreach { next => newWriter = iteration.next(newWriter, coerce(next), scopes) } newWriter } case n: Number => if (n.intValue() == 0) writer else iteration.next(writer, coerce(value), scopes) case _ => super.iterate(iteration, writer, value, scopes) } } override def falsey(iteration: Iteration, writer: Writer, value: AnyRef, scopes: Array[AnyRef]) = { value match { case TraversableAnyRef(t) => { if (t.isEmpty) { iteration.next(writer, value, scopes) } else { writer } } case n: Number => if (n.intValue() == 0) iteration.next(writer, coerce(value), scopes) else writer case _ => super.falsey(iteration, writer, value, scopes) } } val TraversableAnyRef = new Def[Traversable[AnyRef]] class Def[C: ClassTag] { def unapply[X: ClassTag](x: X): Option[C] = { x match { case c: C => Some(c) case _ => None } } } } mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/000077500000000000000000000000001241525561000277545ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/scala/000077500000000000000000000000001241525561000310375ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/scala/com/000077500000000000000000000000001241525561000316155ustar00rootroot00000000000000000077500000000000000000000000001241525561000332405ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/scala/com/twitter000077500000000000000000000000001241525561000350515ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/scala/com/twitter/mustacheObjectHandlerTest.scala000066400000000000000000000060601241525561000414240ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.10/src/test/scala/com/twitter/mustachepackage com.twitter.mustache import com.github.mustachejava.DefaultMustacheFactory import com.twitter.util.{Future, FuturePool} import java.io.{StringWriter, StringReader} import java.util.concurrent.{Callable, Executors} import org.junit.{Assert, Test} class ObjectHandlerTest { @Test def testMap() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) val m = mf.compile( new StringReader("{{#map}}{{test}}{{test2}}{{/map}}"), "helloworld" ) val sw = new StringWriter val w = m.execute(sw, Map( "map" -> Map( "test" -> "fred" ) ) ).close() Assert.assertEquals("fred", sw.toString()) } @Test def testScalaHandler() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) mf.setExecutorService(pool) val m = mf.compile( new StringReader("{{#list}}{{optionalHello}}, {{futureWorld}}!" + "{{#test}}?{{/test}}{{^test}}!{{/test}}{{#num}}?{{/num}}{{^num}}!{{/num}}" + "{{#map}}{{value}}{{/map}}\n{{/list}}"), "helloworld" ) val sw = new StringWriter val writer = m.execute(sw, new { val list = Seq(new { lazy val optionalHello = Some("Hello") val futureWorld = new Callable[String] { def call(): String = "world" } val test = true val num = 0 }, new { val optionalHello = Some("Goodbye") val futureWorld = new Callable[String] { def call(): String = "thanks for all the fish" } lazy val test = false val map = Map(("value", "test")) val num = 1 }) }) // You must use close if you use concurrent latched writers writer.close() Assert.assertEquals("Hello, world!?!\nGoodbye, thanks for all the fish!!?test\n", sw.toString) } @Test def testScalaStream() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) mf.setExecutorService(pool) val m = mf.compile(new StringReader("{{#stream}}{{value}}{{/stream}}"), "helloworld") val sw = new StringWriter val writer = m.execute(sw, new { val stream = Stream( new { val value = "hello" }, new { val value = "world" }) }) writer.close() Assert.assertEquals("helloworld", sw.toString) } @Test def testUnit() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) val m = mf.compile(new StringReader("{{test}}"), "unit") val sw = new StringWriter m.execute(sw, new { val test = if (false) "test" }).close() Assert.assertEquals("", sw.toString) } @Test def testOptions() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) val m = mf.compile(new StringReader("{{foo}}{{bar}}"), "unit") val sw = new StringWriter m.execute(sw, new { val foo = Some("Hello") val bar = None }).close() Assert.assertEquals("Hello", sw.toString) } } mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/000077500000000000000000000000001241525561000261355ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/pom.xml000066400000000000000000000064461241525561000274640ustar00rootroot00000000000000 scala-extensions com.github.spullara.mustache.java 0.8.17 ../pom.xml 4.0.0 scala-extensions-2.8 jar scala-extensions-2.8 Scala extensions for mustache.java http://github.com/spullara/mustache.java Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 repo Sam Pullara sam@sampullara.com http://www.javarants.com Twitter http://maven.twttr.com/ UTF-8 com.github.spullara.mustache.java compiler 0.8.17 junit junit 4.8.2 test org.scala-lang scala-library 2.8.2 provided com.twitter util-core 4.0.0 provided src/main/scala src/test/scala org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin scala-compile-first process-resources add-source compile scala-test-compile process-test-resources testCompile mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/000077500000000000000000000000001241525561000267245ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/000077500000000000000000000000001241525561000276505ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/000077500000000000000000000000001241525561000307335ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/com/000077500000000000000000000000001241525561000315115ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/com/twitter/000077500000000000000000000000001241525561000332135ustar00rootroot00000000000000000077500000000000000000000000001241525561000347455ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/com/twitter/mustacheScalaObjectHandler.scala000066400000000000000000000034021241525561000414210ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/com/twitter/mustachepackage com.twitter.mustache import collection.JavaConversions._ import com.github.mustachejava.Iteration import com.github.mustachejava.reflect.ReflectionObjectHandler import java.io.Writer import java.lang.reflect.{Field, Method} import runtime.BoxedUnit /** * Plain old scala handler that doesn't depend on Twitter libraries. */ class ScalaObjectHandler extends ReflectionObjectHandler { // Allow any method or field override def checkMethod(member: Method) {} override def checkField(member: Field) {} override def coerce(value: Object) = { value match { case m: collection.Map[_, _] => asJavaMap(m) case u: BoxedUnit => null case o: Option[_] => o match { case Some(some: Object) => coerce(some) case None => null } case _ => value } } override def iterate(iteration: Iteration, writer: Writer, value: Object, scopes: Array[Object]) = { value match { case t: Traversable[AnyRef] => { var newWriter = writer t foreach { next => newWriter = iteration.next(newWriter, coerce(next), scopes) } newWriter } case n: Number => if (n.intValue() == 0) writer else iteration.next(writer, coerce(value), scopes) case _ => super.iterate(iteration, writer, value, scopes) } } override def falsey(iteration: Iteration, writer: Writer, value: Object, scopes: Array[Object]) = { value match { case t: Traversable[AnyRef] => { if (t.isEmpty) { iteration.next(writer, value, scopes) } else { writer } } case n: Number => if (n.intValue() == 0) iteration.next(writer, coerce(value), scopes) else writer case _ => super.falsey(iteration, writer, value, scopes) } } } TwitterObjectHandler.scala000066400000000000000000000007101241525561000420370ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/main/scala/com/twitter/mustachepackage com.twitter.mustache import com.twitter.util.Future import java.util.concurrent.Callable class TwitterObjectHandler extends ScalaObjectHandler { override def coerce(value: Object) = { value match { case f: Future[_] => { new Callable[Any]() { def call() = { val value = f.get().asInstanceOf[Object] coerce(value) } } } case _ => super.coerce(value) } } } mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/000077500000000000000000000000001241525561000277035ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/scala/000077500000000000000000000000001241525561000307665ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/scala/com/000077500000000000000000000000001241525561000315445ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/scala/com/twitter/000077500000000000000000000000001241525561000332465ustar00rootroot00000000000000000077500000000000000000000000001241525561000350005ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/scala/com/twitter/mustacheObjectHandlerTest.scala000066400000000000000000000076141241525561000413610ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.8/src/test/scala/com/twitter/mustachepackage com.twitter.mustache import com.github.mustachejava.DefaultMustacheFactory import com.twitter.util.{Future, FuturePool} import java.io.{StringWriter, StringReader} import java.util.concurrent.{Callable, Executors} import org.junit.{Assert, Test} class ObjectHandlerTest { @Test def testMap() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) val m = mf.compile( new StringReader("{{#map}}{{test}}{{test2}}{{/map}}"), "helloworld" ) val sw = new StringWriter val w = m.execute(sw, Map( "map" -> Map( "test" -> "fred" ) ) ).close() Assert.assertEquals("fred", sw.toString()) } @Test def testTwitterHandler() { val pool = Executors.newCachedThreadPool() val futurePool = FuturePool(pool) val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) mf.setExecutorService(pool) val m = mf.compile( new StringReader("{{#list}}{{optionalHello}}, {{futureWorld}}!" + "{{#test}}?{{/test}}{{^test}}!{{/test}}{{#num}}?{{/num}}{{^num}}!{{/num}}" + "{{#map}}{{value}}{{/map}}\n{{/list}}"), "helloworld" ) val sw = new StringWriter val writer = m.execute(sw, new { val list = Seq(new { lazy val optionalHello = Some("Hello") val futureWorld = futurePool { "world" } val test = true val num = 0 }, new { val optionalHello = Some("Goodbye") val futureWorld = futurePool { "thanks for all the fish" } lazy val test = Future { false } val map = Map(("value", "test")) val num = 1 }) }) // You must use close if you use concurrent latched writers writer.close() Assert.assertEquals("Hello, world!?!\nGoodbye, thanks for all the fish!!?test\n", sw.toString) } @Test def testScalaHandler() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) mf.setExecutorService(pool) val m = mf.compile( new StringReader("{{#list}}{{optionalHello}}, {{futureWorld}}!" + "{{#test}}?{{/test}}{{^test}}!{{/test}}{{#num}}?{{/num}}{{^num}}!{{/num}}" + "{{#map}}{{value}}{{/map}}\n{{/list}}"), "helloworld" ) val sw = new StringWriter val writer = m.execute(sw, new { val list = Seq(new { lazy val optionalHello = Some("Hello") val futureWorld = new Callable[String] { def call(): String = "world" } val test = true val num = 0 }, new { val optionalHello = Some("Goodbye") val futureWorld = new Callable[String] { def call(): String = "thanks for all the fish" } lazy val test = false val map = Map(("value", "test")) val num = 1 }) }) // You must use close if you use concurrent latched writers writer.close() Assert.assertEquals("Hello, world!?!\nGoodbye, thanks for all the fish!!?test\n", sw.toString) } @Test def testScalaStream() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) mf.setExecutorService(pool) val m = mf.compile(new StringReader("{{#stream}}{{value}}{{/stream}}"), "helloworld") val sw = new StringWriter val writer = m.execute(sw, new { val stream = Stream( new { val value = "hello" }, new { val value = "world" }) }) writer.close() Assert.assertEquals("helloworld", sw.toString) } @Test def testUnit() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) val m = mf.compile(new StringReader("{{test}}"), "unit") val sw = new StringWriter m.execute(sw, new { val test = if (false) "test" }).close() Assert.assertEquals("", sw.toString) } } mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/000077500000000000000000000000001241525561000261365ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/pom.xml000066400000000000000000000064471241525561000274660ustar00rootroot00000000000000 scala-extensions com.github.spullara.mustache.java 0.8.17 ../pom.xml 4.0.0 scala-extensions-2.9 jar scala-extensions-2.9 Scala extensions for mustache.java http://github.com/spullara/mustache.java Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0 repo Sam Pullara sam@sampullara.com http://www.javarants.com Twitter http://maven.twttr.com/ UTF-8 com.github.spullara.mustache.java compiler 0.8.17 junit junit 4.8.2 test org.scala-lang scala-library 2.9.3 provided com.twitter util-core 6.12.1 provided src/main/scala src/test/scala org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin 2.14.1 org.scala-tools maven-scala-plugin scala-compile-first process-resources add-source compile scala-test-compile process-test-resources testCompile mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/000077500000000000000000000000001241525561000267255ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/000077500000000000000000000000001241525561000276515ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/000077500000000000000000000000001241525561000307345ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/com/000077500000000000000000000000001241525561000315125ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/com/twitter/000077500000000000000000000000001241525561000332145ustar00rootroot00000000000000000077500000000000000000000000001241525561000347465ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/com/twitter/mustacheScalaObjectHandler.scala000066400000000000000000000034021241525561000414220ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/com/twitter/mustachepackage com.twitter.mustache import collection.JavaConversions._ import com.github.mustachejava.Iteration import com.github.mustachejava.reflect.ReflectionObjectHandler import java.io.Writer import java.lang.reflect.{Field, Method} import runtime.BoxedUnit /** * Plain old scala handler that doesn't depend on Twitter libraries. */ class ScalaObjectHandler extends ReflectionObjectHandler { // Allow any method or field override def checkMethod(member: Method) {} override def checkField(member: Field) {} override def coerce(value: Object) = { value match { case m: collection.Map[_, _] => asJavaMap(m) case u: BoxedUnit => null case o: Option[_] => o match { case Some(some: Object) => coerce(some) case None => null } case _ => value } } override def iterate(iteration: Iteration, writer: Writer, value: Object, scopes: Array[Object]) = { value match { case t: Traversable[AnyRef] => { var newWriter = writer t foreach { next => newWriter = iteration.next(newWriter, coerce(next), scopes) } newWriter } case n: Number => if (n.intValue() == 0) writer else iteration.next(writer, coerce(value), scopes) case _ => super.iterate(iteration, writer, value, scopes) } } override def falsey(iteration: Iteration, writer: Writer, value: Object, scopes: Array[Object]) = { value match { case t: Traversable[AnyRef] => { if (t.isEmpty) { iteration.next(writer, value, scopes) } else { writer } } case n: Number => if (n.intValue() == 0) iteration.next(writer, coerce(value), scopes) else writer case _ => super.falsey(iteration, writer, value, scopes) } } } TwitterObjectHandler.scala000066400000000000000000000007101241525561000420400ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/main/scala/com/twitter/mustachepackage com.twitter.mustache import com.twitter.util.Future import java.util.concurrent.Callable class TwitterObjectHandler extends ScalaObjectHandler { override def coerce(value: Object) = { value match { case f: Future[_] => { new Callable[Any]() { def call() = { val value = f.get().asInstanceOf[Object] coerce(value) } } } case _ => super.coerce(value) } } } mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/000077500000000000000000000000001241525561000277045ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/scala/000077500000000000000000000000001241525561000307675ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/scala/com/000077500000000000000000000000001241525561000315455ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/scala/com/twitter/000077500000000000000000000000001241525561000332475ustar00rootroot00000000000000000077500000000000000000000000001241525561000350015ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/scala/com/twitter/mustacheObjectHandlerTest.scala000066400000000000000000000076141241525561000413620ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/scala-extensions/scala-extensions-2.9/src/test/scala/com/twitter/mustachepackage com.twitter.mustache import com.github.mustachejava.DefaultMustacheFactory import com.twitter.util.{Future, FuturePool} import java.io.{StringWriter, StringReader} import java.util.concurrent.{Callable, Executors} import org.junit.{Assert, Test} class ObjectHandlerTest { @Test def testMap() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) val m = mf.compile( new StringReader("{{#map}}{{test}}{{test2}}{{/map}}"), "helloworld" ) val sw = new StringWriter val w = m.execute(sw, Map( "map" -> Map( "test" -> "fred" ) ) ).close() Assert.assertEquals("fred", sw.toString()) } @Test def testTwitterHandler() { val pool = Executors.newCachedThreadPool() val futurePool = FuturePool(pool) val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) mf.setExecutorService(pool) val m = mf.compile( new StringReader("{{#list}}{{optionalHello}}, {{futureWorld}}!" + "{{#test}}?{{/test}}{{^test}}!{{/test}}{{#num}}?{{/num}}{{^num}}!{{/num}}" + "{{#map}}{{value}}{{/map}}\n{{/list}}"), "helloworld" ) val sw = new StringWriter val writer = m.execute(sw, new { val list = Seq(new { lazy val optionalHello = Some("Hello") val futureWorld = futurePool { "world" } val test = true val num = 0 }, new { val optionalHello = Some("Goodbye") val futureWorld = futurePool { "thanks for all the fish" } lazy val test = Future { false } val map = Map(("value", "test")) val num = 1 }) }) // You must use close if you use concurrent latched writers writer.close() Assert.assertEquals("Hello, world!?!\nGoodbye, thanks for all the fish!!?test\n", sw.toString) } @Test def testScalaHandler() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) mf.setExecutorService(pool) val m = mf.compile( new StringReader("{{#list}}{{optionalHello}}, {{futureWorld}}!" + "{{#test}}?{{/test}}{{^test}}!{{/test}}{{#num}}?{{/num}}{{^num}}!{{/num}}" + "{{#map}}{{value}}{{/map}}\n{{/list}}"), "helloworld" ) val sw = new StringWriter val writer = m.execute(sw, new { val list = Seq(new { lazy val optionalHello = Some("Hello") val futureWorld = new Callable[String] { def call(): String = "world" } val test = true val num = 0 }, new { val optionalHello = Some("Goodbye") val futureWorld = new Callable[String] { def call(): String = "thanks for all the fish" } lazy val test = false val map = Map(("value", "test")) val num = 1 }) }) // You must use close if you use concurrent latched writers writer.close() Assert.assertEquals("Hello, world!?!\nGoodbye, thanks for all the fish!!?test\n", sw.toString) } @Test def testScalaStream() { val pool = Executors.newCachedThreadPool() val mf = new DefaultMustacheFactory() mf.setObjectHandler(new ScalaObjectHandler) mf.setExecutorService(pool) val m = mf.compile(new StringReader("{{#stream}}{{value}}{{/stream}}"), "helloworld") val sw = new StringWriter val writer = m.execute(sw, new { val stream = Stream( new { val value = "hello" }, new { val value = "world" }) }) writer.close() Assert.assertEquals("helloworld", sw.toString) } @Test def testUnit() { val mf = new DefaultMustacheFactory() mf.setObjectHandler(new TwitterObjectHandler) val m = mf.compile(new StringReader("{{test}}"), "unit") val sw = new StringWriter m.execute(sw, new { val test = if (false) "test" }).close() Assert.assertEquals("", sw.toString) } } mustache.java-mustache.java-0.8.17/site/000077500000000000000000000000001241525561000200345ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/site/resources/000077500000000000000000000000001241525561000220465ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/site/resources/images/000077500000000000000000000000001241525561000233135ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/site/resources/images/mustache.java-small.jpg000066400000000000000000000133041241525561000276550ustar00rootroot00000000000000JFIFKK@ICC_PROFILE0appl mntrRGB XYZ   acspAPPLappl-appl dscmdescogXYZlwtptrXYZbXYZrTRCcprt8chad,gTRCbTRCmluc enUS&~esES&daDK.deDE,fiFI(frFU(*itIT(VnlNL(nbNO&ptBR&svSE&jaJPRkoKR@zhTWlzhCNruRU"plPL,Yleinen RGB-profiiliGenerisk RGB-profilProfil Gnrique RVBN, RGB 000000u( RGB r_icϏPerfil RGB GenricoAllgemeines RGB-Profilfn RGB cϏeNGenerel RGB-beskrivelseAlgemeen RGB-profiel| RGB \ |Profilo RGB GenericoGeneric RGB Profile1I89 ?@>D8;L RGBUniwersalny profil RGBdescGeneric RGB ProfileGeneric RGB ProfileXYZ Zus4XYZ RXYZ tM=XYZ (6curvtextCopyright 2007 Apple Inc., all rights reserved.sf32 B&lExifMM*nv(1~2iKKAdobe Photoshop CS5 Macintosh2010:05:08 11:12:030221dPC     C  Pd" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?(((/)>_ޣ$OIɠX8+ng`[QmWKdaHdA5ԨQ~~?to 37],F+ɎJ_IJol GE~hߎ |CFPmKâWũt ݭۻPuEEQA u4O<EQEQE|P~^?c|M~ˠRO嶫Hl`H,탵۵>"x:$/.p> ݍB" ". .5;q7?)fP3 QRai;# QDk-{?xaQL6\BHK(Vf/u.TɃOw >ٯ6IէmgMQa2AprNݙ5qySRٴ~fs>+h?d|VU|IEyo ֲb :zz~>[/%|G#̱B8a g㮓<[I??jT:N\6-"l~eWi*A8#C >)|Gmox^Νqy.3c1,!I1n"Ll:wǷV:'B$ { 7}@ Ws>FkQmKԮ-$5Q& ?=mO;~ӄx_ş|}xEд$A!YBnZmŶW_w9G? Fąnn@?>xH煼4gij1G)7Ѱq5;aGӬ*`@X qܞMx/7 07z_xmRk,K vn|dd<>&xvOd A;Wqv66׹o?>\1pA)+Ѯ~@'+j? i]`$ԭ[{h!sUbE} pf^;/Ui?mQQ 7i82u<;c\ul|vC:GO;*eyVM69^mM=_S>A3]~|MyѵtmQ#u6-wp+hҭmghXCt`XB5^#' A$"3y #m0i.W5OExxSnh^'SaQ<;2'_C?e?ϧK_xM?@f[XQ1}|rE_n.,3 Oaȱ1n O,y_|)?>گnԼAߐ;oG$*UT cd| <,F^ F幼Ԡ(_J5 _͍_[K,3ૣH$F_Ke%~ͺgooiɦޘ"X6ɱ2 b|z~~/|fVi$AeRڹ'Н<>҂I~GNmf9UWi-'nדnyƟ{>x?m͢I=.T]:ss41gBN+}ثńM Vp]-4Jǒ"yORu/ ҷ<((G>0oA3Hס vITE); wy01_tPWQ_' mK/:fX$'C!Ҽ'ip ;HQU(|)3Acvq V~'mtpȑFQ h! jߴSÏ'gŝ3R~)Y9yH5}@B~(Y)ԵWl Յ=}u > ? io/ I5| a@G i! ֓an銕KJ<$P}2#c} l 9GZFu'HY͗~D &R`+(^CW^ş3?hVI>M")l(4LF"?? <{; oFBgܫzroɓ,Umd0cxUtds6ܗ7{U s)IAI%?EF8~g=۲gu`ow o=Itzm^᷷3뻟m+RI$^gcbMĢZo5ӹc߾~ĔbKҿx 3 [SdeԹs,]BJTI%)$IJI$Rƶ8O6΢4-]~{KƦ5H*,_8feݗa#!Ά[$nrٿ]Uox$ jdtޡ8P޶0}kUSJ lʬe8Ǵs\_I}U˙hs= .U bzgnWA̱Pc nsk,TI$xbVܞ]MMf*or?R_s:Q!Yԩq/MS?9ӰzQͣz,_k+߽9}s jcL9Խ|ks h8SO,ٚ>}-H/hjb˿N+'ӤTI%)$IJI%}a?Wz=y72z-nو6{MwIOi'Mt?Htv}z?G}vpNȹees9[+2z772X_ M{/9y}EǮέXp1&}SU.6Á >DIܝV3ԻP#@nziϬWqk`$I,hmF]"2V>[Q](rhOA UΏ=Sf%6H >GZѽOVxt?+uqwzYWv k40roVXl}8\I's`}iu_V~ou(h*jtjƵߤzVzP51ֱvu} ?SS nsuޫ]-ex},,ή=Oװ_*]f>@ɮ~l6T;tFTѾYuN۱Z\;*lc9)TI%5PC-qku&'k7mcm=;_߮6i:nSpo}nmǫ z=OyX}%E}_Nw{Q[9S0͖ɴ2&zh$ɳFc%yׯV}^n!,ɜ.u,{dnWc_C_a5^+/rJo'αOc7{v1oi`~|M;l ۫k~^/y\/w^ůtuL&m3g5/s!!`d8C ׂBU.9Sv\Wh?R"-0K}c?boVx*18hA['-DKHĞu/ɑɽV_s1.}{,t΍{cqowТwSh dYs')N2q@NG?O{\~݋]fV, ݵvYߨ:ɉ:z`ִ6ޕ٥_R>[^E@sU^j o_MtkD˒YrO$l3/}Kgԟ9hkbƺ[m6zVj7??t>՞ 1zs}w^v{kߴ~p㟤oMuau6=3x]rhfu[-"J}U=#Rc,6mk$Pn7QJ]0zرK2:lS*=:˜XKdzwFk^Se$ M7w] )*7]N=6_{U54akF?Ej;:UͭZ~l,VgJzν/l91*kehzQ}Tźߔ1=7uE寧Zo-!5d|1TѺ7>75U -u}u;}}}JuGmf۝Mml,cn,w='􎍍^^-F7smm+ג}ig2J\[Ck6?5ʝv=OK6o]?;8bJ}%VOyu`\SͮRiIk[CIO 8zp32+՞Ziwm[Yeojmg_TzO Km43KnLxM>6IO$I)I$JՏíc~v 52pkckG}ν[~Gpn0ykjζ\V ɝ0c)D\[ 6{׎,{?w!lײo~cW^SFM2}*cKgYNZ:tt/=mt{վg󟤭{IO?Y~ce}@k2MOеʫmU0ymoT hյTyS?%>8L>mkDe[]Yc; k_Nf`ߗ{cd{/Uj?-"^:oK)>cvnqbJU]/Rq(Ç24Z/=㟠bc]\?˝ёqnO~e]nS/oEs016˫ϺͿ:G.L[{Qר~E)3>^p+e{_Uzkffz? h*r6QX86?c轿+))cX'd#'Gv_r/i0w??Ė0oB23 )dI%)$IOTI%,$SWwvzy[/cꨩ\UM/ǐֵ1^]?cWնYkZsCj.n<;צ9?Ed]4==Ba @Ns>lc߁aIsdi(?=w~dtm6O?y/mț2H[Y-n5~,u^]Ѿ\Zͱٳwٷ}?Ѯ% ckk%RI%1{=p4yusKn \$%`- MI%>!:7mFO݁al֟F?o?ZWTt4fb~Cr\eX4R/Ug`u Kp*m״ڝ}^9>}iU^N>wTn~Jz] p:iaW=Թ8}L2^qc6Uf{2jp([Xsqn3.ϧgO轻q 饍۠kZ61BJHI$$I)XPhotoshop 3.08BIMZ%G8BIM%}Ǿ pvN8BIM: printOutputClrSenumClrSRGBCInteenumInteClrmMpBlboolprintSixteenBitbool printerNameTEXT8BIM;printOutputOptionsCptnboolClbrboolRgsMboolCrnCboolCntCboolLblsboolNgtvboolEmlDboolIntrboolBckgObjcRGBCRd doub@oGrn doub@oBl doub@oBrdTUntF#RltBld UntF#RltRsltUntF#Pxl@R vectorDataboolPgPsenumPgPsPgPCLeftUntF#RltTop UntF#RltScl UntF#Prc@Y8BIMKK8BIM&?8BIM 8BIM8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIMO,v mustache.javav,nullboundsObjcRct1Top longLeftlongBtomlong,RghtlongvslicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong,RghtlongvurlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?8BIM8BIM8BIM  Adobe_CMAdobed            " ?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?TI%)$IJI$RI$\_70 DV;)o?I ұ)_EBϫY#oGO]}VvexXxo]{?k9qssd$+XHK]Wn=_CB7I$I%)$IJI$STI%)$IJI$RIB몢sUU4CZִn{{Z5%9_Z[,Ǡ6ZnTw}O33^lq}?Zݮ~~ekg>d0cxUtds6ܗ7{U s)IAI%?EF8~g=۲gu`ow o=Itzm^᷷3뻟m+RI$^gcbMĢZo5ӹc߾~ĔbKҿx 3 [SdeԹs,]BJTI%)$IJI$Rƶ8O6΢4-]~{KƦ5H*,_8feݗa#!Ά[$nrٿ]Uox$ jdtޡ8P޶0}kUSJ lʬe8Ǵs\_I}U˙hs= .U bzgnWA̱Pc nsk,TI$xbVܞ]MMf*or?R_s:Q!Yԩq/MS?9ӰzQͣz,_k+߽9}s jcL9Խ|ks h8SO,ٚ>}-H/hjb˿N+'ӤTI%)$IJI%}a?Wz=y72z-nو6{MwIOi'Mt?Htv}z?G}vpNȹees9[+2z772X_ M{/9y}EǮέXp1&}SU.6Á >DIܝV3ԻP#@nziϬWqk`$I,hmF]"2V>[Q](rhOA UΏ=Sf%6H >GZѽOVxt?+uqwzYWv k40roVXl}8\I's`}iu_V~ou(h*jtjƵߤzVzP51ֱvu} ?SS nsuޫ]-ex},,ή=Oװ_*]f>@ɮ~l6T;tFTѾYuN۱Z\;*lc9)TI%5PC-qku&'k7mcm=;_߮6i:nSpo}nmǫ z=OyX}%E}_Nw{Q[9S0͖ɴ2&zh$ɳFc%yׯV}^n!,ɜ.u,{dnWc_C_a5^+/rJo'αOc7{v1oi`~|M;l ۫k~^/y\/w^ůtuL&m3g5/s!!`d8C ׂBU.9Sv\Wh?R"-0K}c?boVx*18hA['-DKHĞu/ɑɽV_s1.}{,t΍{cqowТwSh dYs')N2q@NG?O{\~݋]fV, ݵvYߨ:ɉ:z`ִ6ޕ٥_R>[^E@sU^j o_MtkD˒YrO$l3/}Kgԟ9hkbƺ[m6zVj7??t>՞ 1zs}w^v{kߴ~p㟤oMuau6=3x]rhfu[-"J}U=#Rc,6mk$Pn7QJ]0zرK2:lS*=:˜XKdzwFk^Se$ M7w] )*7]N=6_{U54akF?Ej;:UͭZ~l,VgJzν/l91*kehzQ}Tźߔ1=7uE寧Zo-!5d|1TѺ7>75U -u}u;}}}JuGmf۝Mml,cn,w='􎍍^^-F7smm+ג}ig2J\[Ck6?5ʝv=OK6o]?;8bJ}%VOyu`\SͮRiIk[CIO 8zp32+՞Ziwm[Yeojmg_TzO Km43KnLxM>6IO$I)I$JՏíc~v 52pkckG}ν[~Gpn0ykjζ\V ɝ0c)D\[ 6{׎,{?w!lײo~cW^SFM2}*cKgYNZ:tt/=mt{վg󟤭{IO?Y~ce}@k2MOеʫmU0ymoT hյTyS?%>8L>mkDe[]Yc; k_Nf`ߗ{cd{/Uj?-"^:oK)>cvnqbJU]/Rq(Ç24Z/=㟠bc]\?˝ёqnO~e]nS/oEs016˫ϺͿ:G.L[{Qר~E)3>^p+e{_Uzkffz? h*r6QX86?c轿+))cX'd#'Gv_r/i0w??Ė0oB23 )dI%)$IOTI%,$SWwvzy[/cꨩ\UM/ǐֵ1^]?cWնYkZsCj.n<;צ9?Ed]4==Ba @Ns>lc߁aIsdi(?=w~dtm6O?y/mț2H[Y-n5~,u^]Ѿ\Zͱٳwٷ}?Ѯ% ckk%RI%1{=p4yusKn \$%`- MI%>!:7mFO݁al֟F?o?ZWTt4fb~Cr\eX4R/Ug`u Kp*m״ڝ}^9>}iU^N>wTn~Jz] p:iaW=Թ8}L2^qc6Uf{2jp([Xsqn3.ϧgO轻q 饍۠kZ61BJHI$$I)8BIM!UAdobe PhotoshopAdobe Photoshop CS58BIM maniIRFR8BIMAnDsnullAFStlongFrInVlLsObjcnullFrIDlong?šaFrGAdoub@>FStsVlLsObjcnullFsIDlongAFrmlongFsFrVlLslong?šaLCntlong8BIMRoll8BIMmfri8BIMbhttp://ns.adobe.com/xap/1.0/ Adobed         ,v/  s!1AQa"q2B#R3b$r%C4Scs5D'6Tdt& EFVU(eufv7GWgw8HXhx)9IYiy*:JZjzm!1AQa"q2#BRbr3$4CS%cs5DT &6E'dtU7()󄔤euFVfvGWgw8HXhx9IYiy*:JZjz ?N*UثWb]v*UثWb]v*UثWb]Jizs+gF\\H~<]*(u 7<~S?R}$37eT=ٟ|΂Ie)r!.*v*UثWb]v*UثWb]v*UN*UثWb]v*UثWb]v*UثWb]y4.*(1튾ڳh_rr4W]v*UثWb]v*UثWb]N*UثWb]v*UثWb]v*UثWbcGEڽYdz^ˌZ"ϯ1yUyFFR{(+KVJN/R?f*]v*UثWb]v*UثWb]N*UثWb]v*UثWb]v*Uث(?9[Z2[Fux4'>C/đU>*UثWb]v*qi>׮nK:tly~ im*N*UثWb]v*UثWb]!<+R)Qum"#ı~@c^*y晚Yd,HǓolUCv*Uت"a q+}Ff?We_ߘW-tZV{4yWNJzOtȭ^,(܃ ,}Ie1WN*UثWb]v*UثWb] O:`Iޮa^O(c^A\1 vDZ]^\%O=č8ReUzg<8Ҭwk.YW!ifw:~̭{6] EҴlҟYzfLU*UثWb^9OmMӅoSM1WXUXbyeHw!Wz|X ]s~:̼U+GLUWZ[huƫr461ˬ|y:qZbd忙5}GK0CfIz5I"GN*UثWb]v*UثWb_Mc8~bMgi!},~LELU㸫Wbis\K{BZ򃜟BQ=IFb@ܛ[:q2E dq72WD#R땗?J[*.n0~R\ \iMT\S1mg/AK:=ɶմ>.x_b~*/3̺斁;.,-8z|'1W*N*UثWb]v*UثWbϣ:Oi[F8{ƜO;$rK;UثWLI֛kxH9ٳS,0GeVTWQ4i2~9'qUL O\-]Q?e*mq'U7huٟ<LPE%ǾYmF Zlj-ǾDQi$_,ch5[}'G{F뗡kޚjWfQ'zzyU5c}uedP]C?+Hܾ'߲Ij]v*UثWbN*UثWb^]9 75Ճz֤S<>_ӆ*[kY<ٙff;b&tXt=wqޣp*h`W_nyqwUnXiqYiֱYa54Q*D\U|9_"ivfk[*%>?*~fd2K+*Gf_}~\~A_[Ik /G+։d"N~qzbP4#PtPbִ KFRSL7K~dj6:vscr.-% n \:9j #q&&Q 6⹩LS8E@l|6i=%D$ |Ir# o+3  [q(o/j?~':M5/i NOgyŨy/M% u?{1&fuy>gX FªUe%lu29CMen7zg+?p"x oV:ZkV[+G줫G#|Ut_֏[5f9ܣpo*ȼ , ags'<>!UN_N/\UIy [L3['z>Ŀwg-- OVEŸ5qO'"^3qw2MRϞc6nKm2]+z_yU*UثWb]v*N*UثWb_lk_6y{Gt!i/ Ǯ*O(}!5}z/5WVI$ޔ_W^*UثW?~oՔ2zIa>ϩNsFK(ҒDgURiڲ_OxǾ6TAEr!$Ė4\4w7a>l(1Pz.|ڟhāb_?$^TƵ~A 3_ʨF~܏|1Ɵ~^y/K_<|QY%$+Ŧ9eDe-d$;v*s#gN݇娎fڞ Oh>ȵ_>ɈWָWb?uO/ysSnk-̊O^rUj7Zw^HeKy&bm/qԬih[k$NԴԽ$\}am">S]xoߚG]*)u]Gl VXi"Ɗ**Wz#X.U>ɹepwwY>*UثV1"ykκ$7mիoɿaxu̲^m$&, ʼ /QchNxgwe1*_#I'ejc/Qe3tsvxңc󿙔j?dc?B{)Q*!TZw}&sQ-oDeB=~Z%l#1KFT.R_fy;>VH?ct_O'ߗOZB&P7q9?&?Lj:—b]@kMjMͨ[Mk7##ıW>]zޛyi-c?,,Q qW1Thz-"ɧh&VHzdRߜ3b8$;3C]#.S+O?_}n*LUث2%ז2B/bS437*1b,UثWgmKBFƅh^~V a_o/i[ۡ_Jd(U#v*UثWboIRS%qY}eVU#1W?WOk%ޚA?o+,qWm~K~^_kz}K& ̦.ħF~W7{F4_7 VsY?. ' z8ck1Su AuLv_ow$_gz(-RM AAT}k}ԑ~bv*UثWb]蟜Zơ`Ԍz[w_{85zՔpo_pb]v*UثWb]=ƥu>YI.̂;|>9+E4NZ~Yބ{GSMWJhQi^1~nZr=(>n^v*̿)C50De,^6KR' 8Fn⹶fHVWYXl˾*\MqW?y5;d\b_pk.1UOs/Q~LU*UثWb]v* rgPcPk9=k--SNa&H 'U wYӃ^Ec@. .*Gv*UثWb]v*/soByk^E ڝ=Yb紿?*~ckR܈5_TV1 ثv*UثWb]v*Uѝ~`*yZޱisuwf"A$wI5wvR/yn8ṀI₾ֿ֢ˇx7\Xe%m~ R7?NJXuMRkY,u btB@e_lU+]v*o8_2!YKӧ&__}[moERZJy\X \ƛcLU柘?~PBl--GQ,2$9+~V*}8屢~NNVypHE*UثWb;)g`:4@ԭW4c6T_͞VOX!bfqG_MP E?Cox/嶝6q$ b[u1j Vq_^'nKMhfΠk7$A|5?&T =ޛxm28dF0_CXdXY ͢Y۔Y_.|k^rWV/Q<oE8O9-0)qUMKI';7N*ɴ͟_0:ǤygsȆ)'-H ْ~+~_3kzpƵy{+u2LRcfU~pH7DO샻%Qz~_lU1]y佌~eHZHq^ N~J)Á].1,\犳|UثWb]v*Uث?-_˽C[u)8iqo颼?_W7w\N$933lU3tc\Ԣt)o4gc~X"wGtu/1hrYNxxP'z_ӆ*±VkG;@BRF?_?m,t_ZyV^\I] S6LHݎ|K3{}I&Y<SNuⶕ\?ݞɱWbI|Ўr㷹75ѮX?&* ]yDK+ LZζ"YG1W:fj[܋JY*7dqyWkIPߣ'2Jᖿ/,UF[kuwIQq'I]&w\i6J,yn)dSP\L?^B?t=Gcoaob"RGr US&$xPG~}%ܚbznBTO_ǖZC4]~Z~^' .i%mEX'*|m'Ԭ|Gl4&0?)qWǟbh‰"L`n"9-~˯I#I# |,ד.d-Դ;+02}Ev*j&.*_?'|0KlUWb]v*UثW?z'-Tms+?xR5_~M~lXܛy;k{9#dLU5毙u1d֕5 q"DG)~\_WҢ7}wVW%_?䤿U;m?6Ǩ0.q"r¼Ŋ91W_  O#[ӝ䴱 I)͌df4ڥ⬃v*UثWb]v*UتxYaqGeaAK}Ceӭa RH;v*UC!{8됿U.*$+<JѻfWb]v*UثWN*UثWʱ ?MC⯋1W_)x$f1qHSn]/͝It5^zJXd$_Q~lb?,WDY/$7dEOb\]v*UثT=^ihJ?ٽ*2VPb%_49*&*]_srs'"S&m4?dٸUX`Ҭ?Co+WGK.*/ELU3ЁbK&TVhq_Osnݸ&My=j]tUWFuc\?s o;YG(!u6Uv*UثWb}_(xsok)r\?⯈QPt 9l-6zzְ%?#UlU1]v*UثWb]N*UثV'{y2hqHC<\D̟fD߃:7|UWX51Miy56ڇW՗~p9?Wі66z}+ogimcqE_EQxWJ_O2ʜy ֹ|UF$l2,e̾>*qWb]yϒDJ+5o咇?HW^wֱ[j//?%[vVO{^!]/ 汨\j7Gu+LRU?ySW񰯭 4C}O_fwU񍎀-ar.OL_qVͷ"1TqZo,HZRId|Uk~Kvkz-մYrR'n>4^S1bt[Lլ!4˨ln(n`u6_YqTn*UثWz&m4Wr(mǢrOW|U/4lѴA /m}2x֕S/Xt]v*UثWb]N*UثWb]v*YOG*Z_SfqW韐?bip *1WbX/?/MnZIda?˓ӏ|9;8s$o/hgI?^}LU3GW7/2A^?mKq ez'Uo?y>* ɿ1*O m^#Wי}G_*,~N~Yyb5?>ы7&**UثV1V4mK@}VoO1Wϟ?. Vw<]H⯞}Uѯ[9l/a46Eb{i7&M5ە#Vk1<~}aoMj]^\gIK⯩.|J_jx#WmqG'jQ|7W*[{̿[jnl!-os~H|mk~f״y87a%9NHE״XwlyIo2ޟq6LUEK *{b45y\-܍lǗ A^_J*/-0yE--㰁NSO*KSu;Ԯ彻Kigz*?ƟHO,h+H-9$)OmIEگ1Wb]v*UثWb]N*UثWb]v*Uث<Bc7~/Zw?SmW{nWq*v*UثWb]v*UثWb]:×_~׸Te|X/R'yO?ޚ}OQb1V*N~OX?W_T?K|=kb|eOH~]?O*b]v*UثWb]mustache.java-mustache.java-0.8.17/site/site.xml000066400000000000000000000014121241525561000215200ustar00rootroot00000000000000 mustache.java images/mustache.java-small.jpg http://github.com/spullara/mustache.java

mustache.java-mustache.java-0.8.17/src/000077500000000000000000000000001241525561000176575ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/000077500000000000000000000000001241525561000206365ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/000077500000000000000000000000001241525561000226505ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings.html000066400000000000000000000001101241525561000271010ustar00rootroot00000000000000{{%IMPLICIT-ITERATOR}} {{#array_of_strings}} {{.}} {{/array_of_strings}}mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings.js000066400000000000000000000000771241525561000265650ustar00rootroot00000000000000var array_of_strings = {array_of_strings: ['hello', 'world']}; mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings.txt000066400000000000000000000000151241525561000267600ustar00rootroot00000000000000hello world mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings_options.html000066400000000000000000000001471241525561000306660ustar00rootroot00000000000000{{%IMPLICIT-ITERATOR iterator=rob}} {{#array_of_strings_options}} {{rob}} {{/array_of_strings_options}}mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings_options.js000066400000000000000000000001171241525561000303330ustar00rootroot00000000000000var array_of_strings_options = {array_of_strings_options: ['hello', 'world']}; mustache.java-mustache.java-0.8.17/src/test/resources/array_of_strings_options.txt000066400000000000000000000000151241525561000305330ustar00rootroot00000000000000hello world mustache.java-mustache.java-0.8.17/src/test/resources/array_partial.2.html000066400000000000000000000001271241525561000265300ustar00rootroot00000000000000Here's a non-sense array of values {{%IMPLICIT-ITERATOR}} {{#array}} {{.}} {{/array}}mustache.java-mustache.java-0.8.17/src/test/resources/array_partial.html000066400000000000000000000000141241525561000263630ustar00rootroot00000000000000{{>partial}}mustache.java-mustache.java-0.8.17/src/test/resources/array_partial.js000066400000000000000000000001141241525561000260340ustar00rootroot00000000000000var partial_context = { partial: { array: ['1', '2', '3', '4'] } };mustache.java-mustache.java-0.8.17/src/test/resources/array_partial.txt000066400000000000000000000000561241525561000262440ustar00rootroot00000000000000Here's a non-sense array of values 1 2 3 4 mustache.java-mustache.java-0.8.17/src/test/resources/brokensimple.html000066400000000000000000000000511241525561000262240ustar00rootroot00000000000000Hello {{name}} You have just won ${{valuemustache.java-mustache.java-0.8.17/src/test/resources/comments.html000066400000000000000000000001011241525561000253530ustar00rootroot00000000000000

{{title}}{{! just something interesting... or not... }}

mustache.java-mustache.java-0.8.17/src/test/resources/comments.js000066400000000000000000000001171241525561000250320ustar00rootroot00000000000000var comments = { title: function() { return "A Comedy of Errors"; } }; mustache.java-mustache.java-0.8.17/src/test/resources/comments.txt000066400000000000000000000000341241525561000252330ustar00rootroot00000000000000

A Comedy of Errors

mustache.java-mustache.java-0.8.17/src/test/resources/complex.html000066400000000000000000000005131241525561000252040ustar00rootroot00000000000000

{{header}}

{{#list}}
    {{#item}} {{#current}}
  • {{name}}
  • {{/current}} {{#link}}
  • {{name}}
  • {{/link}} {{/item}}
{{/list}} {{#empty}}

The list is empty.

{{/empty}} {{^empty}}

The list is not empty.

{{/empty}}mustache.java-mustache.java-0.8.17/src/test/resources/complex.js000066400000000000000000000006461241525561000246630ustar00rootroot00000000000000var complex = { header: function() { return "Colors"; }, item: [ {name: "red", current: true, url: "#Red"}, {name: "green", current: false, url: "#Green"}, {name: "blue", current: false, url: "#Blue"} ], link: function() { return this["current"] !== true; }, list: function() { return this.item.length !== 0; }, empty: function() { return this.item.length === 0; } }; mustache.java-mustache.java-0.8.17/src/test/resources/complex.txt000066400000000000000000000002651241525561000250630ustar00rootroot00000000000000

Colors

The list is not empty.

mustache.java-mustache.java-0.8.17/src/test/resources/deferred.html000066400000000000000000000001471241525561000253200ustar00rootroot00000000000000 {{title}} {{>deferredpartial}} {{{deferred}}} mustache.java-mustache.java-0.8.17/src/test/resources/deferred.txt000066400000000000000000000003171241525561000251720ustar00rootroot00000000000000 Deferred
mustache.java-mustache.java-0.8.17/src/test/resources/deferredpartial.html000066400000000000000000000000661241525561000266750ustar00rootroot00000000000000I am calculated "later" and divs are written out < nowmustache.java-mustache.java-0.8.17/src/test/resources/delimiters.html000066400000000000000000000001261241525561000256760ustar00rootroot00000000000000{{=<% %>=}}* <% first %> * <% second %> <%=| |=%> * | third | |={{ }}=| * {{ fourth }}mustache.java-mustache.java-0.8.17/src/test/resources/delimiters.js000066400000000000000000000003051241525561000253450ustar00rootroot00000000000000var delimiters = { first: "It worked the first time.", second: "And it worked the second time.", third: "Then, surprisingly, it worked the third time.", fourth: "Fourth time also fine!." } mustache.java-mustache.java-0.8.17/src/test/resources/delimiters.txt000066400000000000000000000002071241525561000255510ustar00rootroot00000000000000* It worked the first time. * And it worked the second time. * Then, surprisingly, it worked the third time. * Fourth time also fine!. mustache.java-mustache.java-0.8.17/src/test/resources/empty_partial.2.html000066400000000000000000000000021241525561000265400ustar00rootroot00000000000000yomustache.java-mustache.java-0.8.17/src/test/resources/empty_partial.html000066400000000000000000000000311241525561000264020ustar00rootroot00000000000000hey {{foo}} {{>partial}} mustache.java-mustache.java-0.8.17/src/test/resources/empty_partial.js000066400000000000000000000000441241525561000260560ustar00rootroot00000000000000var partial_context = { foo: 1 }; mustache.java-mustache.java-0.8.17/src/test/resources/empty_partial.txt000066400000000000000000000000111241525561000262530ustar00rootroot00000000000000hey 1 yo mustache.java-mustache.java-0.8.17/src/test/resources/empty_template.html000066400000000000000000000000641241525561000265670ustar00rootroot00000000000000

Test

mustache.java-mustache.java-0.8.17/src/test/resources/empty_template.js000066400000000000000000000000311241525561000262310ustar00rootroot00000000000000var empty_template = {}; mustache.java-mustache.java-0.8.17/src/test/resources/empty_template.txt000066400000000000000000000000651241525561000264430ustar00rootroot00000000000000

Test

mustache.java-mustache.java-0.8.17/src/test/resources/error_not_found.html000066400000000000000000000000071241525561000267370ustar00rootroot00000000000000{{foo}}mustache.java-mustache.java-0.8.17/src/test/resources/error_not_found.js000066400000000000000000000000371241525561000264120ustar00rootroot00000000000000var error_not_found = {bar: 2};mustache.java-mustache.java-0.8.17/src/test/resources/error_not_found.txt000066400000000000000000000000011241525561000266040ustar00rootroot00000000000000 mustache.java-mustache.java-0.8.17/src/test/resources/escaped.html000066400000000000000000000000511241525561000251360ustar00rootroot00000000000000

{{title}}

But not {{entities}}. mustache.java-mustache.java-0.8.17/src/test/resources/escaped.js000066400000000000000000000001361241525561000246120ustar00rootroot00000000000000var escaped = { title: function() { return "Bear > Shark"; }, entities: """ }; mustache.java-mustache.java-0.8.17/src/test/resources/escaped.txt000066400000000000000000000000511241525561000250110ustar00rootroot00000000000000

Bear > Shark

But not ". mustache.java-mustache.java-0.8.17/src/test/resources/explicitlambda.html000066400000000000000000000001241241525561000265150ustar00rootroot00000000000000

{{_translate}}Hello{{/translate}}

{{_translate}}Hola{{/translate}}

mustache.java-mustache.java-0.8.17/src/test/resources/explicitlambda.txt000066400000000000000000000000341241525561000263700ustar00rootroot00000000000000

Hola

Hello

mustache.java-mustache.java-0.8.17/src/test/resources/higher_order_sections.html000066400000000000000000000000431241525561000301030ustar00rootroot00000000000000{{#bolder}}Hi {{name}}.{{/bolder}} mustache.java-mustache.java-0.8.17/src/test/resources/higher_order_sections.js000066400000000000000000000003161241525561000275560ustar00rootroot00000000000000var higher_order_sections = { "name": "Tater", "helper": "To tinker?", "bolder": function() { return function(text, render) { return "" + render(text) + ' ' + this.helper; } } }mustache.java-mustache.java-0.8.17/src/test/resources/higher_order_sections.txt000066400000000000000000000000341241525561000277560ustar00rootroot00000000000000Hi Tater. To tinker? mustache.java-mustache.java-0.8.17/src/test/resources/i18n.html000066400000000000000000000002171241525561000243150ustar00rootroot00000000000000你好 {{name}} 你赚了 ${{value}}! {{#test}} {{/test}} {{#in_ca}} Well, ${{ taxed_value }}, after taxes.{{fred}} {{/in_ca}}mustache.java-mustache.java-0.8.17/src/test/resources/i18n.txt000066400000000000000000000000721241525561000241670ustar00rootroot00000000000000你好 Chris 你赚了 $10000! Well, $6000, after taxes. mustache.java-mustache.java-0.8.17/src/test/resources/ibis-1107586786643355109.html000066400000000000000000000204771241525561000265200ustar00rootroot00000000000000
Twitter

Hey XXXXXXXX @XXXXXX, Twitter has suggestions for you!

Did you know that Twitter generates personalized Who To Follow suggestions for you? Following the ones you like will help you stay informed on what matters the most to you today and discover what might matter to you tomorrow.
XXXXXXXX
@XXXXXX
view profile →
XXXXXXX
@XXXXXX
view profile →
XXXXXX
@XXXXXXX
view profile →
View all suggestions for you
Forgot your Twitter password?
Get instructions on how to reset it »
If you'd rather not receive Twitter product or service updates, you can unsubscribe immediately. Please do not reply to this message; it was sent from an unmonitored email address. This message is a service email related to your use of Twitter. For general inquiries or to request support with your Twitter account, please visit us at Twitter Support. If you received this message in error and did not sign up for a Twitter account, click not my account.
mustache.java-mustache.java-0.8.17/src/test/resources/ibis.html000066400000000000000000000176251241525561000244770ustar00rootroot00000000000000
Twitter

Hey {{USER_NAME}} @{{USER_SCREENNAME}}, Twitter has suggestions for you!

Did you know that Twitter generates personalized Who To Follow suggestions for you? Following the ones you like will help you stay informed on what matters the most to you today and discover what might matter to you tomorrow.
{{^NO_SUGGESTED_USERS}}
{{SUGGESTED_USER_1_NAME}}
@{{SUGGESTED_USER_1_SCREENNAME}}
view profile →
{{SUGGESTED_USER_2_NAME}}
@{{SUGGESTED_USER_2_SCREENNAME}}
view profile →
{{SUGGESTED_USER_3_NAME}}
@{{SUGGESTED_USER_3_SCREENNAME}}
view profile →
{{/NO_SUGGESTED_USERS}}
View all suggestions for you
Forgot your Twitter password?
Get instructions on how to reset it »
If you'd rather not receive Twitter product or service updates, you can unsubscribe immediately. Please do not reply to this message; it was sent from an unmonitored email address. This message is a service email related to your use of Twitter. For general inquiries or to request support with your Twitter account, please visit us at Twitter Support. If you received this message in error and did not sign up for a Twitter account, click not my account.
mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/000077500000000000000000000000001241525561000236605ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/content.html.mustache000066400000000000000000000047461241525561000300430ustar00rootroot00000000000000
{{>dir:content.html}} {{>dir:footer}}
Twitter
If you'd rather not receive Twitter product or service updates, you can unsubscribe immediately. Please do not reply to this message; it was sent from an unmonitored email address. This message is a service email related to your use of Twitter. For general inquiries or to request support with your Twitter account, please visit us at Twitter Support. If you received this message in error and did not sign up for a Twitter account, click not my account.
mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/modules/000077500000000000000000000000001241525561000253305ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/modules/wtf.mustache000066400000000000000000000016431241525561000276670ustar00rootroot00000000000000 {{#wtf}} {{#wtf_users}} {{/wtf_users}} {{/wtf}}
{{name}}
@{{screen_name}}
view profile →
mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/network_digest_v1/000077500000000000000000000000001241525561000273165ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/network_digest_v1/content.html.mustache000066400000000000000000000022161241525561000334670ustar00rootroot00000000000000 {{#top_tweets}} {{#tweets}}
{{user.name}} @{{user.screen_name}}
{{{linkified_text}}}
{{retweet_count}}{{fav_count}}{{reply_count}} {{explicit_timestamp}} {{{source.get}}}
{{/tweets}} {{/top_tweets}} {{#include_wtf}} {{>modules:wtf}} {{/include_wtf}} mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/network_digest_v1/content.txt.mustache000066400000000000000000000011321241525561000333360ustar00rootroot00000000000000Hey {{USER_NAME}} (@{{USER_SCREENNAME}}), Twitter has suggestions for you! Did you know that Twitter generates personalized Who To Follow suggestions for you? Following the ones you like will help you stay informed on what matters most to you today and discover what might matter to you most tomorrow. Curious to know who you're missing on Twitter right now? View all suggestions for you: {{SUGGESTED_USERS_HEADER_PLAIN}} Forgot your Twitter password?: {{RESET_PLAIN}} If you received this message in error and did not sign up for a Twitter account, click on the url below: {{NOTMYACCOUNT_PLAIN}}mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/network_digest_v1/footer.mustache000066400000000000000000000032641241525561000323540ustar00rootroot00000000000000
View all suggestions for you
Forgot your Twitter password?
Get instructions on how to reset it »
mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/network_digest_v1/subject.txt.mustache000066400000000000000000000000311241525561000333200ustar00rootroot00000000000000Discover more on Twitter mustache.java-mustache.java-0.8.17/src/test/resources/ibis2/test.html000066400000000000000000000321721241525561000255320ustar00rootroot00000000000000
Twitter
dick costolo @dickc
Great end to a fantastic day in London. Cc @thisisdavina @stephenfry pic.twitter.com/HTM0JrmZ
345234123 03:27 PM Nov 07 Twitter for BlackBerry?
CalAcademyofSciences @calacademy
Science Today Story: Science Girl Power - The recent successes of girls in science. ow.ly/1fwWD5
345234123 03:35 PM Nov 07 HootSuite
Alton Brown @altonbrown
Breaking radio silence to say: if you see a poster at your college regarding a lecture by me: It's a recording!
345234123 03:40 PM Nov 07 Twitter for iPhone
The Economist @TheEconomist
Wherever Segways are allowed, someone is probably making an effort to rein in their use on safety grounds econ.st/uPiu6w
345234123 03:42 PM Nov 07 SocialFlow
USA Cycling @usacycling
Thx to all our #webinarcontest participants! @twoupsports won this afternoon's free entry. Upcoming webinar info here: bit.ly/abkRVJ
345234123 03:31 PM Nov 07 web
Gaku Ueda
@gakuueda
view profile →
Doug Williams
@dougw
view profile →
Fabien Penso
@fabienpenso
view profile →
View all suggestions for you
Forgot your Twitter password?
Get instructions on how to reset it »
If you'd rather not receive Twitter product or service updates, you can unsubscribe immediately. Please do not reply to this message; it was sent from an unmonitored email address. This message is a service email related to your use of Twitter. For general inquiries or to request support with your Twitter account, please visit us at Twitter Support. If you received this message in error and did not sign up for a Twitter account, click not my account.
mustache.java-mustache.java-0.8.17/src/test/resources/infinitechild.html000066400000000000000000000000231241525561000263420ustar00rootroot00000000000000{{>infiniteparent}}mustache.java-mustache.java-0.8.17/src/test/resources/infiniteparent.html000066400000000000000000000000221241525561000265470ustar00rootroot00000000000000{{>infinitechild}}mustache.java-mustache.java-0.8.17/src/test/resources/inverted_section.html000066400000000000000000000000771241525561000271060ustar00rootroot00000000000000{{#repo}}{{name}}{{/repo}}{{^repo}}No repos :({{/repo}} mustache.java-mustache.java-0.8.17/src/test/resources/inverted_section.js000066400000000000000000000000511241525561000265460ustar00rootroot00000000000000var inverted_section = { "repo": [] } mustache.java-mustache.java-0.8.17/src/test/resources/inverted_section.txt000066400000000000000000000000141241525561000267500ustar00rootroot00000000000000No repos :( mustache.java-mustache.java-0.8.17/src/test/resources/isempty.html000066400000000000000000000001461241525561000252310ustar00rootroot00000000000000{{^people.isEmpty}} Is not empty {{/people.isEmpty}} {{#people.isEmpty}} Is empty {{/people.isEmpty}} mustache.java-mustache.java-0.8.17/src/test/resources/isempty.txt000066400000000000000000000000151241525561000250770ustar00rootroot00000000000000Is not empty mustache.java-mustache.java-0.8.17/src/test/resources/items.html000066400000000000000000000001551241525561000246600ustar00rootroot00000000000000{{#items}} Name: {{name}} Price: {{price}} {{#features}} Feature: {{description}} {{/features}} {{/items}} mustache.java-mustache.java-0.8.17/src/test/resources/items.txt000066400000000000000000000001731241525561000245330ustar00rootroot00000000000000Name: Item 1 Price: $19.99 Feature: New! Feature: Awesome! Name: Item 2 Price: $29.99 Feature: Old. Feature: Ugly. mustache.java-mustache.java-0.8.17/src/test/resources/items2.html000066400000000000000000000001461241525561000247420ustar00rootroot00000000000000{{#items}} Name: {{name}} Price: {{price}} {{#features}} Feature: {{desc}} {{/features}} {{/items}} mustache.java-mustache.java-0.8.17/src/test/resources/items3.html000066400000000000000000000002221241525561000247360ustar00rootroot00000000000000{{#items}} Name: {{name}} Price: {{price}} {{#hasfeatures}} Features: {{#features}} Feature: {{desc}} {{/features}} {{/hasfeatures}} {{/items}} mustache.java-mustache.java-0.8.17/src/test/resources/items3.txt000066400000000000000000000002171241525561000246150ustar00rootroot00000000000000Name: Item 1 Price: $19.99 Features: Feature: New! Feature: Awesome! Name: Item 2 Price: $29.99 Features: Feature: Old. Feature: Ugly. mustache.java-mustache.java-0.8.17/src/test/resources/lambda.html000066400000000000000000000002011241525561000247470ustar00rootroot00000000000000{{#translate}}Hello{{/translate}} {{_translate}}Hello{{/translate}} {{#translate}}{{#translate}}Hello{{/translate}}{{/translate}}mustache.java-mustache.java-0.8.17/src/test/resources/lambda.txt000066400000000000000000000000171241525561000246270ustar00rootroot00000000000000Hola Hola Hellomustache.java-mustache.java-0.8.17/src/test/resources/latchedtest.html000066400000000000000000000003401241525561000260370ustar00rootroot00000000000000 {{#nest}} {{.}} {{#nested}} {{.}} {{#nestest}} {{/nestest}} {{/nested}} {{#nested}} {{#nestest}} {{.}} {{/nestest}} {{/nested}} {{/nest}} mustache.java-mustache.java-0.8.17/src/test/resources/latchedtest.txt000066400000000000000000000001131241525561000257100ustar00rootroot00000000000000 How are you? mustache.java-mustache.java-0.8.17/src/test/resources/latchedtestiterable.html000066400000000000000000000000721241525561000275510ustar00rootroot00000000000000 {{#list}} {{.}} {{/list}} mustache.java-mustache.java-0.8.17/src/test/resources/nonrelative.html000066400000000000000000000000141241525561000260570ustar00rootroot00000000000000Nonrelative mustache.java-mustache.java-0.8.17/src/test/resources/null_string.html000066400000000000000000000001261241525561000260750ustar00rootroot00000000000000Hello {{name}} glytch {{glytch}} binary {{binary}} value {{value}} numeric {{numeric}}mustache.java-mustache.java-0.8.17/src/test/resources/null_string.js000066400000000000000000000002041241525561000255420ustar00rootroot00000000000000var null_string = { name: "Elise", glytch: true, binary: false, value: null, numeric: function() { return NaN; } }; mustache.java-mustache.java-0.8.17/src/test/resources/null_string.txt000066400000000000000000000000701241525561000257460ustar00rootroot00000000000000Hello Elise glytch true binary false value numeric NaN mustache.java-mustache.java-0.8.17/src/test/resources/partialwithpadding.html000066400000000000000000000000511241525561000274110ustar00rootroot00000000000000 With padding! mustache.java-mustache.java-0.8.17/src/test/resources/reallysimple.html000066400000000000000000000000541241525561000262370ustar00rootroot00000000000000Hello {{name}} You have just won ${{value}}!mustache.java-mustache.java-0.8.17/src/test/resources/reallysimple.txt000066400000000000000000000000451241525561000261120ustar00rootroot00000000000000Hello Chris You have just won $10000!mustache.java-mustache.java-0.8.17/src/test/resources/recurse_base.html000066400000000000000000000000361241525561000261770ustar00rootroot00000000000000{{$content}} Test {{/content}}mustache.java-mustache.java-0.8.17/src/test/resources/recursion.html000066400000000000000000000000531241525561000255450ustar00rootroot00000000000000Test {{#value}} {{>recursion}} {{/value}}mustache.java-mustache.java-0.8.17/src/test/resources/recursion.txt000066400000000000000000000000151241525561000254160ustar00rootroot00000000000000Test Test mustache.java-mustache.java-0.8.17/src/test/resources/recursion_with_inheritance.html000066400000000000000000000000361241525561000311520ustar00rootroot00000000000000{{recursive_partial2}} {{/test}} mustache.java-mustache.java-0.8.17/src/test/resources/recursive_partial2.html000066400000000000000000000000651241525561000273440ustar00rootroot00000000000000{{#test}} TEST {{>recursive_partial3}} {{/test}} mustache.java-mustache.java-0.8.17/src/test/resources/recursive_partial3.html000066400000000000000000000000661241525561000273460ustar00rootroot00000000000000{{#test}} TEST {{>recursive_partial}} {{/test}} mustache.java-mustache.java-0.8.17/src/test/resources/recursive_partial_inheritance.html000066400000000000000000000001311241525561000316250ustar00rootroot00000000000000{{recursive_partial}} {{/content}} {{/recurse_base}}mustache.java-mustache.java-0.8.17/src/test/resources/recursive_partial_inheritance.txt000066400000000000000000000000161241525561000315020ustar00rootroot00000000000000TEST TEST mustache.java-mustache.java-0.8.17/src/test/resources/relative/000077500000000000000000000000001241525561000244635ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/relative/dotdot.html000066400000000000000000000000341241525561000266430ustar00rootroot00000000000000{{>../uninterestingpartial}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/extension.html000066400000000000000000000000331241525561000273610ustar00rootroot00000000000000{{>/relative/include.html}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/functionpaths.html000066400000000000000000000000301241525561000302270ustar00rootroot00000000000000{{#i}}{{>include}}{{/i}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/include.html000066400000000000000000000000041241525561000267660ustar00rootroot00000000000000testmustache.java-mustache.java-0.8.17/src/test/resources/relative/nonrelative.html000066400000000000000000000000201241525561000276670ustar00rootroot00000000000000{{>nonrelative}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/pathfail.html000066400000000000000000000000251241525561000271360ustar00rootroot00000000000000{{>relative/include}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/paths.html000066400000000000000000000000141241525561000264630ustar00rootroot00000000000000{{>include}}mustache.java-mustache.java-0.8.17/src/test/resources/relative/paths.txt000066400000000000000000000000041241525561000263350ustar00rootroot00000000000000testmustache.java-mustache.java-0.8.17/src/test/resources/relative/rootpath.html000066400000000000000000000000261241525561000272070ustar00rootroot00000000000000{{>/relative/include}}mustache.java-mustache.java-0.8.17/src/test/resources/reuse_of_enumerables.html000066400000000000000000000001321241525561000277230ustar00rootroot00000000000000{{#terms}} {{name}} {{index}} {{/terms}} {{#terms}} {{name}} {{index}} {{/terms}} mustache.java-mustache.java-0.8.17/src/test/resources/reuse_of_enumerables.js000066400000000000000000000001461241525561000274000ustar00rootroot00000000000000var reuse_of_enumerables = { terms: [ {name: 't1', index: 0}, {name: 't2', index: 1}, ] };mustache.java-mustache.java-0.8.17/src/test/resources/reuse_of_enumerables.txt000066400000000000000000000000341241525561000275770ustar00rootroot00000000000000t1 0 t2 1 t1 0 t2 1 mustache.java-mustache.java-0.8.17/src/test/resources/section_as_context.html000066400000000000000000000002221241525561000274250ustar00rootroot00000000000000{{#a_object}}

{{title}}

{{description}}

    {{#a_list}}
  • {{label}}
  • {{/a_list}}
{{/a_object}} mustache.java-mustache.java-0.8.17/src/test/resources/section_as_context.js000066400000000000000000000002751241525561000271050ustar00rootroot00000000000000var section_as_context = { a_object: { title: 'this is an object', description: 'one of its attributes is a list', a_list: [{label: 'listitem1'}, {label: 'listitem2'}] } }; mustache.java-mustache.java-0.8.17/src/test/resources/section_as_context.txt000066400000000000000000000002031241525561000272770ustar00rootroot00000000000000

this is an object

one of its attributes is a list

  • listitem1
  • listitem2
mustache.java-mustache.java-0.8.17/src/test/resources/security.html000066400000000000000000000000521241525561000254020ustar00rootroot00000000000000{{class.name}}{{getClass.getName}}{{test}}mustache.java-mustache.java-0.8.17/src/test/resources/security.txt000066400000000000000000000000001241525561000252460ustar00rootroot00000000000000mustache.java-mustache.java-0.8.17/src/test/resources/simple.html000066400000000000000000000002311241525561000250230ustar00rootroot00000000000000Hello {{name}} You have just won ${{value}}! {{#test}} {{/test}} {{#in_ca}} Well, ${{ taxed_value }}, after taxes.{{fred}} {{/in_ca}}mustache.java-mustache.java-0.8.17/src/test/resources/simple.js000066400000000000000000000002161241525561000244760ustar00rootroot00000000000000var simple = { name: "Chris", value: 10000, taxed_value: function() { return this.value - (this.value * 0.4); }, in_ca: true }; mustache.java-mustache.java-0.8.17/src/test/resources/simple.json000066400000000000000000000001201241525561000250250ustar00rootroot00000000000000{ "name": "Chris", "value": 10000, "taxed_value": 6000, "in_ca": true } mustache.java-mustache.java-0.8.17/src/test/resources/simple.txt000066400000000000000000000001041241525561000246750ustar00rootroot00000000000000Hello Chris You have just won $10000! Well, $6000, after taxes. mustache.java-mustache.java-0.8.17/src/test/resources/simple2.html000066400000000000000000000001761241525561000251150ustar00rootroot00000000000000{{#data}} Hello {{name}} You have just won ${{value}}! {{#in_ca}} Well, ${{ taxed_value }}, after taxes. {{/in_ca}} {{/data}}mustache.java-mustache.java-0.8.17/src/test/resources/simple2.txt000066400000000000000000000000511241525561000247600ustar00rootroot00000000000000Hello Chris You have just won $10000! mustache.java-mustache.java-0.8.17/src/test/resources/simple_array.html000066400000000000000000000000321241525561000262200ustar00rootroot00000000000000{{#list}} {{.}} {{/list}} mustache.java-mustache.java-0.8.17/src/test/resources/simple_array.txt000066400000000000000000000000061241525561000260740ustar00rootroot000000000000001 2 3 mustache.java-mustache.java-0.8.17/src/test/resources/simple_ko.html000066400000000000000000000002621241525561000255200ustar00rootroot00000000000000안녕하세요 {{name}}    당신은 {{value}}달러를 원했다! {{#test}} {{/test}} {{#in_ca}} 음, {{ taxed_value }}달러, 세금 후.{{fred}} {{/in_ca}}mustache.java-mustache.java-0.8.17/src/test/resources/simple_ko.txt000066400000000000000000000001351241525561000253720ustar00rootroot00000000000000안녕하세요 Chris    당신은 10000달러를 원했다! 음, 6000달러, 세금 후. mustache.java-mustache.java-0.8.17/src/test/resources/simplefiltered.html000066400000000000000000000004351241525561000265500ustar00rootroot00000000000000 Hello {{name}} You have just won ${{value}}! {{#test}} {{/test}} {{#in_ca}} Well, ${{ taxed_value }}, after taxes.{{fred}} {{/in_ca}} {{>partialwithpadding}} {{#name}} This is a test {{/name}} Test{{#name}} space{{/name}} Test {{>partialwithpadding}} Testmustache.java-mustache.java-0.8.17/src/test/resources/simplefiltered.txt000066400000000000000000000002511241525561000264170ustar00rootroot00000000000000Hello Chris You have just won $10000! Well, $6000, after taxes. With padding! This is a test Test space Test With padding! Testmustache.java-mustache.java-0.8.17/src/test/resources/simplemissing.txt000066400000000000000000000000351241525561000262720ustar00rootroot00000000000000Hello You have just won $! mustache.java-mustache.java-0.8.17/src/test/resources/simplepragma.html000066400000000000000000000003031241525561000262130ustar00rootroot00000000000000{{%IMPLICIT-ITERATOR}}Hello {{name}} You have just won ${{value}}! {{#test}} {{/test}} {{#in_ca}} Well, ${{ taxed_value }}, after taxes.{{fred}} {{/in_ca}} {{%UNKNOWN-PRAGMA}}mustache.java-mustache.java-0.8.17/src/test/resources/simplerewrap.txt000066400000000000000000000002021241525561000261150ustar00rootroot00000000000000Hello Chris You have just won $10000! Well, $6000, after taxes.test Well, $8000, after taxes. Well, $6000, after taxes.test mustache.java-mustache.java-0.8.17/src/test/resources/simpletyped.txt000066400000000000000000000001201241525561000257410ustar00rootroot00000000000000Hello [String] You have just won $[int]! Well, $[int], after taxes.[String] mustache.java-mustache.java-0.8.17/src/test/resources/template_partial.html000066400000000000000000000001161241525561000270630ustar00rootroot00000000000000

{{title}}

{{>template_partial_2}} Test: {{template_partial_2.again}} mustache.java-mustache.java-0.8.17/src/test/resources/template_partial.js000066400000000000000000000001451241525561000265350ustar00rootroot00000000000000var partial_context = { "title": "Welcome", "template_partial_2": { "again": "Goodbye" } } mustache.java-mustache.java-0.8.17/src/test/resources/template_partial.txt000066400000000000000000000000571241525561000267420ustar00rootroot00000000000000

Welcome

Again, Goodbye! Test: Goodbye mustache.java-mustache.java-0.8.17/src/test/resources/template_partial2.html000066400000000000000000000001421241525561000271440ustar00rootroot00000000000000

{{title}}

{{#test}} {{>template_partial_2}} {{/test}} Test: {{template_partial_2.again}} mustache.java-mustache.java-0.8.17/src/test/resources/template_partial2.txt000066400000000000000000000000571241525561000270240ustar00rootroot00000000000000

Welcome

Again, Goodbye! Test: Goodbye mustache.java-mustache.java-0.8.17/src/test/resources/template_partial_2.html000066400000000000000000000000211241525561000272770ustar00rootroot00000000000000Again, {{again}}!mustache.java-mustache.java-0.8.17/src/test/resources/templatelambda.html000066400000000000000000000002021241525561000265040ustar00rootroot00000000000000{{#translate}}Hello {{name}}{{/translate}} {{_translate}}Hello {{name}}{{/translate}} {{#translate}}Hello {{>user}}!{{/translate}}mustache.java-mustache.java-0.8.17/src/test/resources/templatelambda.txt000066400000000000000000000000571241525561000263670ustar00rootroot00000000000000Sam, Hola! Sam, Hola! Hola, Sam!mustache.java-mustache.java-0.8.17/src/test/resources/timeline.mustache000066400000000000000000000003011241525561000262030ustar00rootroot00000000000000
{{#tweets}} {{>tweet}} {{/tweets}}
mustache.java-mustache.java-0.8.17/src/test/resources/tweet.mustache000066400000000000000000000070751241525561000255440ustar00rootroot00000000000000{{{before_tweet_element}}} <{{ _tweet_element}} {{ _root_attr}} data-twt-id="{{id}}" {{#_web_intents}} data-twt-intents="{{ _enabled}}" {{#_partner}} data-twt-partner="{{ _partner}}" {{/_partner}} {{#_related}} data-twt-related="{{ _related}}" {{/_related}} {{/_web_intents}} class="twt-o twt-tweet {{#_as_reply}} twt-inline twt-reply {{/_as_reply}} {{#_always_show_actions}} twt-always-show-actions {{/_always_show_actions}} {{#_was_retweeted}} tweet-retweeted twt-rt {{/_was_retweeted}} {{#media}} has-photo {{/media}} {{#_pin_media}} twt-pinned {{/_pin_media}} {{#_tweet_not_found}} twt-error {{/_tweet_not_found}} {{#_favorited}} twt-fav {{/_favorited}} {{#_format}} {{ _format}} {{/_format}} {{#_touch_device}} twt-touch {{/_touch_device}} hentry">
{{{before_username}}} {{#user}} {{#screen_name}} {{/screen_name}} {{#profile_image_url_https}}{{/profile_image_url_https}} {{#name}}{{name}}{{/name}} {{#_has_badges}}
    {{{before_badges}}} {{#protected}}
  • 🔒
  • {{/protected}} {{#verified}}
  • {{/verified}} {{{after_badges}}}
{{/_has_badges}} {{#screen_name}} @{{screen_name}}
{{/screen_name}} {{#in_reply_to}}· {{{ _in_reply_to}}}{{/in_reply_to}} {{#_show_follow_button}} {{/_show_follow_button}} {{/user}} {{{after_username}}} {{#_as_timeline}} {{#rendered_time}} {{/rendered_time}} {{/_as_timeline}}
{{#rendered_text}}
{{{before_tweet}}}

{{{rendered_text}}}

{{{after_tweet}}}
{{/rendered_text}} {{{tweet_media}}} {{^_as_reply}} {{/_as_reply}} {{{timeline_media}}} {{#_as_reply}}
{{/_as_reply}} {{{after_tweet_element}}}mustache.java-mustache.java-0.8.17/src/test/resources/two_in_a_row.html000066400000000000000000000000271241525561000262230ustar00rootroot00000000000000{{greeting}}, {{name}}!mustache.java-mustache.java-0.8.17/src/test/resources/two_in_a_row.js000066400000000000000000000000751241525561000256760ustar00rootroot00000000000000var two_in_a_row = { name: "Joe", greeting: "Welcome" }; mustache.java-mustache.java-0.8.17/src/test/resources/two_in_a_row.txt000066400000000000000000000000161241525561000260740ustar00rootroot00000000000000Welcome, Joe! mustache.java-mustache.java-0.8.17/src/test/resources/unambiguoussimple.html000066400000000000000000000001521241525561000273040ustar00rootroot00000000000000Hello {{name}} You have just won ${{value}}! {{#in_ca}} Well, ${{ taxed_value }}, after taxes. {{/in_ca}}mustache.java-mustache.java-0.8.17/src/test/resources/unambiguoussimple.txt000066400000000000000000000001011241525561000271510ustar00rootroot00000000000000Hello Chris You have just won $10000! Well, $6000, after taxes. mustache.java-mustache.java-0.8.17/src/test/resources/unambiguoussimpleencoded.txt000066400000000000000000000001111241525561000304740ustar00rootroot00000000000000Hello <Chris> You have just won $10000! Well, $6000, after taxes. mustache.java-mustache.java-0.8.17/src/test/resources/unescaped.html000066400000000000000000000000251241525561000255020ustar00rootroot00000000000000

{{{title}}}

mustache.java-mustache.java-0.8.17/src/test/resources/unescaped.js000066400000000000000000000001121241525561000251470ustar00rootroot00000000000000var unescaped = { title: function() { return "Bear > Shark"; } }; mustache.java-mustache.java-0.8.17/src/test/resources/unescaped.txt000066400000000000000000000000261241525561000253560ustar00rootroot00000000000000

Bear > Shark

mustache.java-mustache.java-0.8.17/src/test/resources/unexecutecomplex.html000066400000000000000000000005431241525561000271350ustar00rootroot00000000000000

{{header}}

{{#list}}
    {{#item}} {{#current}}
  • {{#include}}{{name}}{{/include}}
  • {{/current}} {{#link}}
  • {{name}}
  • {{/link}} {{/item}}
{{/list}} {{#empty}}

The list is empty.

{{/empty}} {{^empty}}

The list is not empty.

{{/empty}}mustache.java-mustache.java-0.8.17/src/test/resources/unexecutecomplex.txt000066400000000000000000000002651241525561000270110ustar00rootroot00000000000000

Colors

The list is not empty.

mustache.java-mustache.java-0.8.17/src/test/resources/unexecutetemplatelambda.html000066400000000000000000000000531241525561000304360ustar00rootroot00000000000000{{_translate}}Hello {{name}}{{/translate}} mustache.java-mustache.java-0.8.17/src/test/resources/unexecutetemplatelambda.txt000066400000000000000000000000131241525561000303050ustar00rootroot00000000000000Sam, Hola! mustache.java-mustache.java-0.8.17/src/test/resources/uninterestingpartial.html000066400000000000000000000000201241525561000300010ustar00rootroot00000000000000not interesting.mustache.java-mustache.java-0.8.17/src/test/resources/unknown_pragma.html000066400000000000000000000000421241525561000265600ustar00rootroot00000000000000{{%I-HAVE-THE-GREATEST-MUSTACHE}} mustache.java-mustache.java-0.8.17/src/test/resources/unknown_pragma.js000066400000000000000000000000311241525561000262260ustar00rootroot00000000000000var unknown_pragma = {}; mustache.java-mustache.java-0.8.17/src/test/resources/unknown_pragma.txt000066400000000000000000000001441241525561000264360ustar00rootroot00000000000000ERROR: This implementation of mustache doesn't understand the 'I-HAVE-THE-GREATEST-MUSTACHE' pragma mustache.java-mustache.java-0.8.17/src/test/resources/user.html000066400000000000000000000000271241525561000245130ustar00rootroot00000000000000{{name}}mustache.java-mustache.java-0.8.17/src/test/resources/view_partial.2.html000066400000000000000000000001521241525561000263620ustar00rootroot00000000000000Hello {{name}} You have just won ${{value}}! {{#in_ca}} Well, ${{ taxed_value }}, after taxes. {{/in_ca}} mustache.java-mustache.java-0.8.17/src/test/resources/view_partial.html000066400000000000000000000000701241525561000262210ustar00rootroot00000000000000

{{greeting}}

{{>partial}}

{{farewell}}

mustache.java-mustache.java-0.8.17/src/test/resources/view_partial.js000066400000000000000000000004531241525561000256760ustar00rootroot00000000000000var partial_context = { greeting: function() { return "Welcome"; }, farewell: function() { return "Fair enough, right?"; }, partial: { name: "Chris", value: 10000, taxed_value: function() { return this.value - (this.value * 0.4); }, in_ca: true } }; mustache.java-mustache.java-0.8.17/src/test/resources/view_partial.txt000066400000000000000000000001571241525561000261020ustar00rootroot00000000000000

Welcome

Hello Chris You have just won $10000! Well, $6000, after taxes.

Fair enough, right?

mustache.java-mustache.java-0.8.17/src/test/resources/xss.html000066400000000000000000000000761241525561000243560ustar00rootroot00000000000000{{message}} mustache.java-mustache.java-0.8.17/src/test/resources/xss.txt000066400000000000000000000001741241525561000242300ustar00rootroot00000000000000I <3 Ponies!