Commits

Stephen McKamey committed 95a905c

simplifying maven coordinates before first deployment to maven central repository

Comments (0)

Files changed (66)

 mvcapp/src/main/webapp/js/views
 mvcapp/src/main/webapp/cdn
 mvcapp/src/main/resources/cdn.properties
-archetype/target
+duel-mvcapp-archetype/target

archetype/pom.xml

-<?xml version="1.0" encoding="UTF-8"?>
-<project
-	xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-	<groupId>org.duelengine.duel</groupId>
-	<artifactId>duel-mvcapp</artifactId>
-	<version>0.1.0</version>
-	<packaging>maven-archetype</packaging>
-
-	<name>DUEL MVC App v${project.version}</name>
-	<description>Maven Archetype for DUEL MVC app</description>
-	<url>http://duelengine.org</url>
-	<licenses>
-		<license>
-			<name>MIT License</name>
-			<url>http://duelengine.org/LICENSE.txt</url>
-		</license>
-	</licenses>
-	<scm>
-		<url>https://bitbucket.org/mckamey/duel-mvc</url>
-		<connection>scm:hg:https://bitbucket.org/mckamey/duel-mvc</connection>
-		<developerConnection>scm:hg:https://bitbucket.org/mckamey/duel-mvc</developerConnection>
-	</scm>
-	<developers>
-		<developer>
-			<id>mckamey</id>
-			<name>Stephen M. McKamey</name>
-			<url>http://mck.me</url>
-		</developer>
-	</developers>
-
-	<properties>
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-	</properties>
-
-	<build>
-		<extensions>
-			<extension>
-				<groupId>org.apache.maven.archetype</groupId>
-				<artifactId>archetype-packaging</artifactId>
-				<version>2.0</version>
-			</extension>
-		</extensions>
-
-		<pluginManagement>
-			<plugins>
-				<plugin>
-					<artifactId>maven-archetype-plugin</artifactId>
-					<version>2.0</version>
-				</plugin>
-			</plugins>
-		</pluginManagement>
-	</build>
-</project>

archetype/src/main/resources/META-INF/maven/archetype-metadata.xml

-<?xml version="1.0" encoding="UTF-8"?>
-<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="mvcapp"
-	xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-
-	<fileSets>
-		<fileSet filtered="true" packaged="true" encoding="UTF-8">
-			<directory>src/main/java</directory>
-			<includes>
-				<include>**/*.java</include>
-			</includes>
-		</fileSet>
-		<fileSet filtered="true" encoding="UTF-8">
-			<directory>src/main/webapp</directory>
-			<includes>
-				<include>**/*.xml</include>
-			</includes>
-		</fileSet>
-		<fileSet encoding="UTF-8">
-			<directory>src/main/webapp</directory>
-			<includes>
-				<include>**/*.css</include>
-				<include>**/*.ico</include>
-				<include>**/*.js</include>
-				<include>**/*.merge</include>
-				<include>**/*.txt</include>
-			</includes>
-		</fileSet>
-		<fileSet filtered="true" encoding="UTF-8">
-			<directory>src/main/resources</directory>
-			<includes>
-				<include>**/*.duel</include>
-			</includes>
-		</fileSet>
-	</fileSets>
-</archetype-descriptor>

archetype/src/main/resources/archetype-resources/pom.xml

-<?xml version="1.0" encoding="UTF-8"?>
-<project
-	xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-	<modelVersion>4.0.0</modelVersion>
-
-	<groupId>${groupId}</groupId>
-	<artifactId>${artifactId}</artifactId>
-	<version>${version}</version>
-
-	<name>${artifactId} MVC App</name>
-	<description>MVC App built using Jersey/Guice/DUEL</description>
-	<packaging>war</packaging>
-
-	<properties>
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
-		<duel.version>0.4.1</duel.version>
-		<merge.version>0.1.1</merge.version>
-		<jackson.version>1.8.2</jackson.version>
-		<guice.version>3.0</guice.version>
-		<jersey.version>1.8</jersey.version>
-		<servlet.version>2.5</servlet.version>
-		<junit.version>4.8.2</junit.version>
-		<m2e.version>1.0.0</m2e.version>
-		<javac.version>1.6</javac.version>
-		<jrebel.version>1.0.5</jrebel.version>
-
-		<duel.clientPrefix>App</duel.clientPrefix>
-		<duel.serverPrefix>${package}.views</duel.serverPrefix>
-		<duel.sourceDir>src/main/resources/views/</duel.sourceDir>
-		<duel.clientDir>src/main/webapp/js/views/</duel.clientDir>
-
-		<merge.webapp>src/main/webapp/</merge.webapp>
-		<merge.cdnRoot>src/main/webapp/cdn/</merge.cdnRoot>
-		<merge.cdnMap>src/main/resources/cdn.properties</merge.cdnMap>
-		<merge.cdnFiles>.ico .png .jpg .gif</merge.cdnFiles>
-	</properties>
-
-	<repositories>
-		<!-- Jersey repository -->
-		<repository>
-			<id>java.net2</id>
-			<name>Java.net Maven2 Repository</name>
-			<url>http://download.java.net/maven/2</url>
-		</repository>
-	</repositories>
-
-	<dependencies>
-		<!-- DUEL runtime -->
-		<dependency>
-			<groupId>org.duelengine.duel</groupId>
-			<artifactId>duel-runtime</artifactId>
-			<version>${duel.version}</version>
-		</dependency>
-
-		<!-- Jackson JSON runtime -->
-		<dependency>
-			<groupId>org.codehaus.jackson</groupId>
-			<artifactId>jackson-core-asl</artifactId>
-			<version>${jackson.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.codehaus.jackson</groupId>
-			<artifactId>jackson-mapper-asl</artifactId>
-			<version>${jackson.version}</version>
-		</dependency>
-
-		<!-- Jackson JAX-RS provider -->
-		<dependency>
-			<groupId>org.codehaus.jackson</groupId>
-			<artifactId>jackson-jaxrs</artifactId>
-			<version>${jackson.version}</version>
-		</dependency>
-		<dependency>
-			<groupId>org.codehaus.jackson</groupId>
-			<artifactId>jackson-xc</artifactId>
-			<version>${jackson.version}</version>
-		</dependency>
-
-		<!-- Guice runtime -->
-		<dependency>
-			<groupId>com.google.inject</groupId>
-			<artifactId>guice</artifactId>
-			<version>${guice.version}</version>
-		</dependency>
-
-		<!-- Jersey runtime -->
-		<dependency>
-			<groupId>com.sun.jersey</groupId>
-			<artifactId>jersey-server</artifactId>
-			<version>${jersey.version}</version>
-		</dependency>
-
-		<!-- Jersey-Guice runtime -->
-		<dependency>
-			<groupId>com.sun.jersey.contribs</groupId>
-			<artifactId>jersey-guice</artifactId>
-			<version>${jersey.version}</version>
-		</dependency>
-
-		<!-- Servlet interfaces -->
-		<dependency>
-			<groupId>javax.servlet</groupId>
-			<artifactId>servlet-api</artifactId>
-			<version>${servlet.version}</version>
-			<scope>provided</scope>
-		</dependency>
-
-		<!-- JUnit runtime -->
-		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<version>${junit.version}</version>
-			<scope>test</scope>
-		</dependency>
-	</dependencies>
-
-	<build>
-		<finalName>${project.artifactId}</finalName>
-		<plugins>
-
-			<!-- DUEL Compiler -->
-			<plugin>
-				<groupId>org.duelengine.duel</groupId>
-				<artifactId>duel-maven-plugin</artifactId>
-				<version>${duel.version}</version>
-				<executions>
-					<execution>
-						<goals>
-							<goal>generate</goal>
-						</goals>
-						<configuration>
-							<clientPrefix>${duel.clientPrefix}</clientPrefix>
-							<serverPrefix>${duel.serverPrefix}</serverPrefix>
-							<inputFolder>${project.basedir}/${duel.sourceDir}</inputFolder>
-							<outputClientFolder>${project.basedir}/${duel.clientDir}</outputClientFolder>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-
-			<!-- Merge Builder -->
-			<plugin>
-				<groupId>org.duelengine.duel</groupId>
-				<artifactId>merge-maven-plugin</artifactId>
-				<version>${merge.version}</version>
-				<executions>
-					<execution>
-						<goals>
-							<goal>merge</goal>
-						</goals>
-						<configuration>
-							<webappDir>${project.basedir}/${merge.webapp}</webappDir>
-							<cdnRoot>${merge.cdnDir}</cdnRoot>
-							<cdnMapFile>${project.basedir}/${merge.cdnMap}</cdnMapFile>
-							<cdnFiles>${merge.cdnFiles}</cdnFiles>
-						</configuration>
-					</execution>
-				</executions>
-			</plugin>
-
-			<!-- JRebel Config -->
-			<plugin>
-				<groupId>org.zeroturnaround</groupId>
-				<artifactId>javarebel-maven-plugin</artifactId>
-				<version>${jrebel.version}</version>
-				<executions>
-					<execution>
-						<id>generate-rebel-xml</id>
-						<phase>process-resources</phase>
-						<goals>
-							<goal>generate</goal>
-						</goals>
-					</execution>
-				</executions>
-			</plugin>
-		</plugins>
-		<pluginManagement>
-			<plugins>
-				<!-- Java compiler -->
-				<plugin>
-					<artifactId>maven-compiler-plugin</artifactId>
-					<configuration>
-						<source>${javac.version}</source>
-						<target>${javac.version}</target>
-					</configuration>
-				</plugin>
-
-				<!-- http://wiki.eclipse.org/M2E_plugin_execution_not_covered -->
-				<plugin>
-					<groupId>org.eclipse.m2e</groupId>
-					<artifactId>lifecycle-mapping</artifactId>
-					<version>${m2e.version}</version>
-					<configuration>
-						<lifecycleMappingMetadata>
-							<pluginExecutions>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.duelengine.duel</groupId>
-										<artifactId>duel-maven-plugin</artifactId>
-										<versionRange>[${duel.version},)</versionRange>
-										<goals>
-											<goal>generate</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<execute />
-									</action>
-								</pluginExecution>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.duelengine.duel</groupId>
-										<artifactId>merge-maven-plugin</artifactId>
-										<versionRange>[${merge.version},)</versionRange>
-										<goals>
-											<goal>merge</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<execute />
-									</action>
-								</pluginExecution>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.zeroturnaround</groupId>
-										<artifactId>javarebel-maven-plugin</artifactId>
-										<versionRange>[${jrebel.version},)</versionRange>
-										<goals>
-											<goal>generate</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<execute />
-									</action>
-								</pluginExecution>
-							</pluginExecutions>
-						</lifecycleMappingMetadata>
-					</configuration>
-				</plugin>
-			</plugins> 
-		</pluginManagement>
-	</build>
-</project>

archetype/src/main/resources/archetype-resources/src/main/java/AppRoot.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package};
-
-import java.lang.reflect.Modifier;
-import java.util.*;
-import javax.ws.rs.*;
-import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
-import org.duelengine.duel.DuelContext;
-import org.duelengine.duel.util.*;
-import com.google.inject.*;
-import com.google.inject.matcher.Matchers;
-import com.google.inject.name.Names;
-import com.google.inject.servlet.GuiceServletContextListener;
-import com.sun.jersey.guice.JerseyServletModule;
-import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
-
-import ${package}.aspects.*;
-import ${package}.controllers.*;
-
-public class AppRoot extends GuiceServletContextListener {
-
-	@Override
-	public Injector getInjector() {
-		return Guice.createInjector(new JerseyServletModule() {
-
-			/**
-			 * Configuration constant bindings
-			 */
-			private void bindConfigConstants() {
-				// TODO: read environment var for DEV/STAGE/PROD
-				// set debug in DEV
-				// set CDN host in PROD
-
-				// general debug mode (also controls compaction)
-				bindConstant().annotatedWith(Names.named("DEBUG")).to(false);
-
-				// CDN server hostname, e.g. "cdn.example.com"
-				bindConstant().annotatedWith(Names.named("CDN_HOST")).to("");
-
-				// name of .properties file containing CDN mappings
-				bindConstant().annotatedWith(Names.named("CDN_MAP")).to("cdn");
-
-				// action timing duration threshold in ms
-				bindConstant().annotatedWith(Names.named("ACTION_THRESHOLD")).to(500.0);//ms
-
-				// render timing duration threshold in ms
-				bindConstant().annotatedWith(Names.named("RENDER_THRESHOLD")).to(100.0);//ms
-			}
-
-			/**
-			 * JAX-RS serialization bindings
-			 */
-			private void bindSerializers() {
-				// bind JAXB/JSON serialization
-				bind(JacksonJaxbJsonProvider.class).in(Singleton.class);
-			}
-
-			/**
-			 * AOP aspect bindings
-			 */
-			private void bindAspects() {
-				// exception handling
-				bind(ExceptionRouter.class);
-
-				// view settings
-				bind(DuelContext.class).toProvider(ViewContextProvider.class);
-
-				// controller action timing
-				ActionTimer actionTimer = new ActionTimer();
-				this.requestInjection(actionTimer);
-
-				bindInterceptor(
-					Matchers.annotatedWith(Path.class),
-					Matchers.annotatedWith(GET.class).or(Matchers.annotatedWith(POST.class)).or(Matchers.annotatedWith(PUT.class)).or(Matchers.annotatedWith(DELETE.class)).or(Matchers.annotatedWith(HEAD.class)),
-
-					// aspects which intercept all controller actions
-					actionTimer
-				);
-			}
-
-			/**
-			 * Static URL route bindings
-			 */
-			private void bindStaticRoutes() {
-				// http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/servlet/ServletModule.html
-
-				// this uses the standard static file servlet
-				DefaultWrapperServlet defaultServlet = new DefaultWrapperServlet();
-
-				serve(
-					"/robots.txt",
-					"/favicon.ico"
-				).with(defaultServlet);
-
-				serveRegex(
-					"/cdn/.*",
-					"/css/.*",
-					"/js/.*",
-					"/images/.*"
-				).with(defaultServlet);
-			}
-
-			/**
-			 * JAX-RS controller bindings
-			 */
-			private void bindControllers(String... packages) {
-				// we have to explicitly bind each controller class
-				// to ensure Guice controls instantiation for AOP
-				// this will auto-register controllers in each package
-
-				for (String packageName : packages) {
-					try {
-						Set<Class<?>> controllers = ClassEnumerator.getClasses(packageName);
-
-						for (Class<?> controller : controllers) {
-							if (controller.isInterface() || Modifier.isAbstract(controller.getModifiers())) {
-								// filter abstract or interfaces
-								continue;
-							}
-
-							// scope is determined by Guice annotations
-							bind(controller);
-						}
-					} catch (Exception ex) {
-						ex.printStackTrace();
-
-						throw new IllegalArgumentException(packageName, ex);
-					}
-				}
-			}
-
-			@Override
-			protected void configureServlets() {
-
-				// setup Guice-style configuration values
-				bindConfigConstants();
-
-				// register JAX-RS serialization providers
-				bindSerializers();
-
-				// register JAX-RS controllers in package
-				bindControllers(
-					BaseController.class.getPackage().getName()
-				);
-
-				// register AOP aspects
-				bindAspects();
-
-				// the rest effectively replaces /WEB-INF/web.xml
-
-				// map static routes
-				bindStaticRoutes();
-
-                // map all other routes to Guice
-				// http://jersey.java.net/nonav/apidocs/latest/contribs/jersey-guice/com/sun/jersey/guice/spi/container/servlet/package-summary.html
-				serve("/*").with(GuiceContainer.class);
-			}
-		});
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/aspects/ActionTimer.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.aspects;
-
-import java.util.logging.Logger;
-import javax.ws.rs.core.*;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import org.aopalliance.intercept.*;
-import com.google.inject.*;
-import com.google.inject.name.Named;
-
-/**
- * AOP proof of concept: this intercepts every controller action and logs the timings
- */
-@Singleton
-public class ActionTimer implements MethodInterceptor {
-
-	private final Logger log = Logger.getLogger(ActionTimer.class.getSimpleName());
-	private Provider<UriInfo> uriInfoProvider;
-	private double timingThreshold;
-
-	@Inject
-	public void init(
-		@Named("ACTION_THRESHOLD") double timingThreshold,
-		Provider<UriInfo> uriInfoProvider) {
-
-		this.timingThreshold = timingThreshold;
-		this.uriInfoProvider = uriInfoProvider;
-	}
-
-	@Override
-	public Object invoke(MethodInvocation invocation) throws Throwable {
-
-		// Note: this only includes the action method body timings, not serialization or render timings
-		
-		long start = System.nanoTime();
-		double elapsed;
-		Object result = null;
-
-		try {
-			result = invocation.proceed();
-
-		} finally {
-			elapsed = (System.nanoTime()-start) / 1000000.0;//ms
-
-			UriInfo uriInfo = this.uriInfoProvider.get();
-			String label = '/'+uriInfo.getPath()+" action: ";
-
-			if (elapsed > this.timingThreshold) {
-				log.warning(label+elapsed+" ms");
-			} else {
-				log.info(label+elapsed+" ms");
-			}
-		}
-
-		// emit a header with the timing
-		ResponseBuilder response = (result instanceof Response) ? Response.fromResponse((Response)result) : Response.ok(result);
-		return response.header("X-Action-MS", elapsed).build();
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/aspects/ExceptionRouter.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.aspects;
-
-import java.util.*;
-import java.util.logging.Logger;
-import javax.ws.rs.core.*;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.ext.ExceptionMapper;
-import com.google.inject.*;
-import com.sun.jersey.api.NotFoundException;
-import com.sun.jersey.api.core.ExtendedUriInfo;
-import com.sun.jersey.api.model.AbstractResourceMethod;
-
-import ${package}.controllers.ErrorController;
-
-/**
- * JAX-RS Glue for mapping exceptions to error views 
- */
-@Singleton
-@javax.ws.rs.ext.Provider
-public class ExceptionRouter implements ExceptionMapper<Throwable> {
-
-	private final Logger log = Logger.getLogger(ExceptionRouter.class.getSimpleName());
-
-	private static final MediaType DefaultMediaType = MediaType.TEXT_HTML_TYPE;
-	private final List<MediaType> supportedMediaTypes = Arrays.asList(
-			MediaType.TEXT_HTML_TYPE,
-			MediaType.APPLICATION_XHTML_XML_TYPE,
-			MediaType.APPLICATION_JSON_TYPE,
-			MediaType.APPLICATION_XML_TYPE);
-
-	private final ErrorController errorController;
-	private final Provider<ExtendedUriInfo> extendedUriInfoProvider;
-
-	@Inject
-	public ExceptionRouter(
-			ErrorController errorController,
-			Provider<ExtendedUriInfo> extendedUriInfoProvider) {
-
-		this.errorController = errorController;
-		this.extendedUriInfoProvider = extendedUriInfoProvider;
-	}
-
-	@Override
-	public Response toResponse(final Throwable ex) {
-
-		// get request metadata
-		ExtendedUriInfo uriInfo = this.extendedUriInfoProvider.get();
-
-		// find the intended result type
-		MediaType resultType = getResultType(uriInfo.getMatchedMethod());
-
-		return Response
-				.status(getHTTPStatus(ex, uriInfo))
-				.type(resultType)
-				.entity(getResult(ex, resultType))
-				.build();
-	}
-
-	public Status getHTTPStatus(Throwable ex, ExtendedUriInfo uriInfo) {
-
-		if (ex instanceof NotFoundException) {
-			return Status.NOT_FOUND;
-		}
-
-		// TODO: filter exception severity for logging
-		log.severe(uriInfo.getPath()+": "+ex.getMessage());
-
-		// TODO: map more response codes
-		return Status.INTERNAL_SERVER_ERROR;
-	}
-
-	private Object getResult(Throwable ex, MediaType resultType) {
-		// can these mappings be performed by JAX-RS?
-		// TODO: map more response views
-
-		if (MediaType.APPLICATION_JSON_TYPE.equals(resultType) ||
-			MediaType.APPLICATION_XML_TYPE.equals(resultType)) {
-			return errorController.errorData(ex);
-		}
-
-		return errorController.errorView(ex);
-	}
-
-	private MediaType getResultType(AbstractResourceMethod method) {
-		// can this matching be performed by JAX-RS?
-		if (method == null) {
-			return DefaultMediaType;
-		}
-
-		for (MediaType mediaType : method.getSupportedOutputTypes()) {
-			if (supportedMediaTypes.contains(mediaType)) {
-				return mediaType;
-			}
-		}
-
-		for (MediaType mediaType : method.getSupportedInputTypes()) {
-			if (supportedMediaTypes.contains(mediaType)) {
-				return mediaType;
-			}
-		}
-
-		return DefaultMediaType;
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/aspects/TimedViewResult.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.aspects;
-
-import java.util.logging.Logger;
-import java.io.*;
-import javax.ws.rs.WebApplicationException;
-import org.duelengine.duel.*;
-import org.duelengine.duel.rs.*;
-
-/**
- * Adds timing logging to standard ViewResult
- */
-public class TimedViewResult extends ViewResult {
-
-	private final Logger log;
-	private double timingThreshold;
-	private final Class<? extends DuelView> view;
-
-	public TimedViewResult(Class<? extends DuelView> view, DuelContext context, Logger log, double timingThreshold) {
-		super(view, context);
-
-		this.log = log;
-		this.timingThreshold = timingThreshold;
-		this.view = view;
-	}
-
-	@Override
-	public void write(OutputStream stream)
-		throws IOException, WebApplicationException {
-
-		long start = System.nanoTime();
-		double elapsed;
-
-		try {
-			super.write(stream);
-
-		} finally {
-			elapsed = (System.nanoTime()-start) / 1000000.0;//ms
-			String label = view.getName()+" render: ";
-
-			if (elapsed > this.timingThreshold) {
-				log.warning(label+elapsed+" ms");
-			} else {
-				log.info(label+elapsed+" ms");
-			}
-		}
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/aspects/ViewContextProvider.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.aspects;
-
-import java.net.URISyntaxException;
-import java.util.*;
-import com.google.inject.*;
-import com.google.inject.name.Named;
-import org.duelengine.duel.*;
-
-/**
- * Builds the view context for a request
- */
-@Singleton
-public class ViewContextProvider implements Provider<DuelContext> {
-
-	private final boolean isDebug;
-	private final LinkInterceptor interceptor;
-
-	@Inject
-	public ViewContextProvider(
-		@Named("DEBUG") boolean isDebug,
-		@Named("CDN_HOST") String cdnHost,
-		@Named("CDN_MAP") String cdnMapName) throws URISyntaxException {
-
-		this.isDebug = isDebug;
-
-		ResourceBundle cdnBundle = ResourceBundle.getBundle(cdnMapName);
-		this.interceptor = new CDNLinkInterceptor(cdnHost, cdnBundle, isDebug);
-	}
-
-	public DuelContext get() {
-		DuelContext context = new DuelContext();
-
-		context
-			.setLinkInterceptor(this.interceptor)
-			.setClientID(new IncClientIDStrategy("_"));
-
-		if (this.isDebug) {
-			// setup pretty-print formatting
-			// add ambient client-side data
-			context
-				.setFormat(new FormatPrefs().setIndent("${symbol_escape}t").setNewline("${symbol_escape}n"))
-				.putExtra("App.isDebug", true);
-		}
-
-		return context;
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/controllers/BaseController.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.controllers;
-
-import java.util.logging.Logger;
-import com.google.inject.*;
-import com.google.inject.name.Named;
-import org.duelengine.duel.*;
-import org.duelengine.duel.rs.*;
-
-import ${package}.aspects.TimedViewResult;
-
-/**
- * Base class for all controllers and provides access to helper methods and ambient request data.
- * Uses method injection so other controllers don't need to maintain constructors.
- */
-public abstract class BaseController {
-
-	private final Logger log = Logger.getLogger(BaseController.class.getSimpleName());
-	private double timingThreshold;
-	private Provider<DuelContext> viewContextProvider;
-
-	@Inject
-	public void init(
-		@Named("RENDER_THRESHOLD") double timingThreshold,
-		Provider<DuelContext> viewContextProvider) {
-
-		this.timingThreshold = timingThreshold;
-		this.viewContextProvider = viewContextProvider;
-	}
-
-	/**
-	 * Builds a view result
-	 */
-	protected ViewResult view(Class<? extends DuelView> view) {
-		return new TimedViewResult(view, viewContextProvider.get(), log, timingThreshold);
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/controllers/ErrorController.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.controllers;
-
-import javax.ws.rs.*;
-import com.google.inject.*;
-import com.google.inject.name.Named;
-
-import ${package}.model.*;
-import ${package}.views.*;
-
-/**
- * Error message controller
- */
-@Singleton
-public class ErrorController extends BaseController {
-
-	private final boolean printStackTrace;
-
-	@Inject
-	public ErrorController(@Named("DEBUG") boolean isDebug) {
-		this.printStackTrace = isDebug;
-	}
-
-	@GET
-	@Path("{path:.*}")
-	@Produces({"text/html", "application/xhtml+xml"})
-	public Object errorView(Throwable ex) {
-		ErrorResult error = this.errorData(ex);
-
-		// TODO: customize error responses
-		return view(ErrorPage.class).data(error);
-	}
-
-	@GET
-	@Path("{path:.*}")
-	@Produces({"application/json", "application/xml"})
-	public ErrorResult errorData(Throwable ex) {
-		return new ErrorResult(ex, this.printStackTrace);
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/controllers/HomeController.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.controllers;
-
-import java.util.*;
-import javax.ws.rs.*;
-import com.google.inject.*;
-
-import ${package}.model.*;
-import ${package}.views.*;
-
-/**
- * Example controller which verifies HTML/JSON/XML and error display are all working.
- */
-@Singleton
-@Path("/")
-@Produces("text/html")
-public class HomeController extends BaseController {
-
-	@GET
-	public Object getHTML() {
-		return getHTML("/");
-	}
-
-	@GET
-	@Path("{path:.*}")
-	public Object getHTML(@PathParam("path") String path) {
-		Foo foo = new Foo(path, new Date());
-
-		return view(FooPage.class).data(foo);
-	}
-
-	@GET
-	@Path("{path:.*}.json")
-	@Produces("application/json")
-	public Object getJSON(@PathParam("path") String path) {
-		return new Foo(path, new Date());
-	}
-
-	@GET
-	@Path("{path:.*}.xml")
-	@Produces("application/xml")
-	public Object getXML(@PathParam("path") String path) {
-		return new Foo(path, new Date());
-	}
-
-	/*------------------------------------------------*/
-
-	@GET
-	@Path("throw")
-	public Object throwErrorHTML() {
-		throw new IllegalStateException("This action always throws an exception in HTML.");
-	}
-
-	@GET
-	@Path("throw.json")
-	@Produces("application/json")
-	public Object throwErrorJSON() {
-		throw new IllegalStateException("This action always throws an exception in JSON.");
-	}
-
-	@GET
-	@Path("throw.xml")
-	@Produces("application/xml")
-	public Object throwErrorXML() {
-		throw new IllegalStateException("This action always throws an exception in XML.");
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/controllers/PingController.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.controllers;
-
-import javax.ws.rs.*;
-import com.google.inject.*;
-
-/**
- * Health monitoring controller
- */
-@Singleton
-@Path("/ping")
-public class PingController extends BaseController {
-
-	@GET
-	@Produces("text/plain")
-	public Object ping() {
-
-		// TODO: perform service health test
-		return "OK";
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/java/model/ErrorResult.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.model;
-
-import java.io.*;
-
-@javax.xml.bind.annotation.XmlRootElement
-public class ErrorResult {
-
-	private String type;
-	private String error;
-	private String stackTrace;
-
-	public ErrorResult() {}
-
-	public ErrorResult(Throwable ex, boolean showStackTrace) {
-		type = ex.getClass().getSimpleName();
-		error = ex.getMessage();
-
-		if (showStackTrace) {
-			StringWriter writer = new StringWriter();
-			ex.printStackTrace(new PrintWriter(writer, true));
-			stackTrace = writer.toString();
-		}
-	}
-
-	public String getType() { return type; }
-	public void setType(String value) { type = value; }
-
-	public String getError() { return error; }
-	public void setError(String value) { error = value; }
-
-	public String getStackTrace() { return stackTrace; }
-	public void setStackTrace(String value) { stackTrace = value; }
-}

archetype/src/main/resources/archetype-resources/src/main/java/model/Foo.java

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-package ${package}.model;
-
-import java.util.Date;
-
-@javax.xml.bind.annotation.XmlRootElement
-public class Foo {
-
-	private String path;
-	private Date date;
-
-	public Foo() {}
-
-	public Foo(String path, Date date) {
-		this.path = path;
-		this.date = date;
-	}
-
-	public String getPath() { return path; }
-	public void setPath(String value) { path = value; }
-
-	public Date getDate() { return date; }
-	public void setDate(Date value) { date = value; }
-}

archetype/src/main/resources/archetype-resources/src/main/resources/views/ErrorPage.duel

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-<view name="ErrorPage"><call view="Page">
-
-<part name="head">
-	<title>${artifactId} ERROR: <%= data.error %></title>
-</part>
-
-<h1>${artifactId} ERROR</h1>
-<p><strong><%= data.type %>:</strong> <%= data.error %></p>
-<pre class="box" if="data.stackTrace"><%= data.stackTrace %></pre>

archetype/src/main/resources/archetype-resources/src/main/resources/views/FooPage.duel

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-<view name="FooPage"><call view="Page">
-
-<part name="head">
-	<title>${artifactId}: <%= data.path %></title>
-</part>
-
-<h1>${artifactId}: <%= data.path %></h1>
-<p><%= data.date %></p>

archetype/src/main/resources/archetype-resources/src/main/resources/views/Menu.duel

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-<view name="Menu">
-<nav class="box">
-	<h2>Configuration Tests</h2>
-	<ul>
-		<li><strong>HTML:</strong> <a href="/Foo%20object">Foo object</a></li>
-		<li><strong>JSON:</strong> <a href="/Foo%20object.json">Foo object</a></li>
-		<li><strong>XML:</strong> <a href="/Foo%20object.xml">Foo object</a></li>
-	</ul><ul>
-		<li><strong>HTML:</strong> <a href="/throw">Throw an exception</a></li>
-		<li><strong>JSON:</strong> <a href="/throw.json">Throw an exception</a></li>
-		<li><strong>XML:</strong> <a href="/throw.xml">Throw an exception</a></li>
-	<ul>
-</nav>

archetype/src/main/resources/archetype-resources/src/main/resources/views/Page.duel

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-<view name="Page">
-<!DOCTYPE html>
-<html lang="en">
-<head>
-	<meta charset="UTF-8">
-<part name="head">
-	<title></title>
-</part>
-	<link rel="stylesheet" type="text/css" href="/css/main.merge" />
-	<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-</head>
-<body>
-	<!--[if lt IE 9]><script type="text/javascript" src="/js/html5shiv/html5.js"></script><![endif]-->
-	<script type="text/javascript" src="/js/main.merge"></script>
-<div id="content">
-	<part />
-
-	<call view="Menu" defer />
-</div>
-</body>
-</html>

archetype/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml

-#set( $symbol_pound = '#' )
-#set( $symbol_dollar = '$' )
-#set( $symbol_escape = '\' )
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app version="2.5"
-	xmlns="http://java.sun.com/xml/ns/javaee"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
-
-	<listener>
-		<listener-class>${package}.AppRoot</listener-class>
-	</listener>
-	<filter>
-		<filter-name>jersey-guice</filter-name>
-		<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
-	</filter>
-	<filter-mapping>
-		<filter-name>jersey-guice</filter-name>
-		<url-pattern>/*</url-pattern>
-	</filter-mapping>
-</web-app>

archetype/src/main/resources/archetype-resources/src/main/webapp/css/main.css

-html {
-	height: 100%;
-	margin: 0;
-	padding: 0;
-	width: 100%;
-	-webkit-font-smoothing: antialiased;
-}
-body, input, button, select, option {
-	font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
-	font-size: 100%;
-}
-body {
-	background-color: #BFBAB2; /*shine: #F8F8F8*/
-	background-image: -webkit-radial-gradient(50% 50%, farthest-side, #F8F8F8, #BFBAB2);
-	background-image: -moz-radial-gradient(50% 50%, farthest-side, #F8F8F8, #BFBAB2);
-	background-attachment: fixed;
-
-	color: #333;
-	height: 100%;
-	margin: 0;
-	overflow: hidden;
-	padding: 0;
-	text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	width: 100%;
-}
-header, footer, menu, nav, section, article, aside {
-	/* non-HTML5 browser patch */
-	display: block;
-}
-img, embed, object, video {
-	/* fluid image patch */
-	border: none;
-	margin: 0;
-	max-width: 100%;
-	padding: 0;
-	-ms-interpolation-mode: bicubic;
-}
-h1, h2, h3, h4, h5, h6 {
-	clear: both;
-	font-weight: bold;
-}
-a {
-	color: #990000;
-	text-decoration: none;
-}
-a:hover, a:active {
-	text-decoration: underline;
-}
-h1, h1 a, h1 a:hover, h1 a:active, h2 {
-	color: #F1F1F1;
-	text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.75);
-}
-h1 {
-	border: 0 solid rgba(0, 0, 0, 0.25);
-	border-bottom-width: 1px;
-	box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-	-moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-	-webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
-	font-size: 2em;
-	letter-spacing: -1px;
-	margin-bottom: 0.25em;
-	padding-bottom: 0.25em;
-}
-h2 {
-	border: 0 solid rgba(0, 0, 0, 0.25);
-	border-bottom-width: 1px;
-	font-size: 1.5em;
-	margin: 0;
-	margin-bottom: 0.5em;
-	padding-bottom: 0.5em;
-}
-hr {
-	border: 0 solid rgba(0, 0, 0, 0.25);
-	border-top-width: 1px;
-	box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	-moz-box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	-webkit-box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	clear: both;
-}
-
-ul {
-	list-style: square;
-	margin-left: 2em;
-}
-li {
-	padding-bottom: 0.25em;
-}
-
-.box {
-	background-color: #A1AAB3; /*shine: #C3CED9*/
-	background-image: -webkit-radial-gradient(50% 50%, farthest-side, #C3CED9, #A1AAB3);
-	background-image: -moz-radial-gradient(50% 50%, farthest-side, #C3CED9, #A1AAB3);
-	background-attachment: fixed;
-	border-radius: 8px;
-	-moz-border-radius: 4px;
-	-webkit-border-radius: 4px;
-	
-	border: 1px solid rgba(0, 0, 0, 0.25);
-	box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	-moz-box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-	-webkit-box-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
-
-	color: black;
-
-	margin: 1em 0;
-	overflow: hidden;
-	padding: 1em;
-}
-
-#content {
-	padding: 1em;
-}
-
-@media screen and (max-width: 640px) {
-	body {
-		font-size: 75%;
-	}
-}
-@media screen and (max-width: 480px) {
-	body {
-		font-size: 50%;
-	}
-}
-
-@media print {
-	body {
-		font-size: 15pt;
-	}
-}

archetype/src/main/resources/archetype-resources/src/main/webapp/css/main.merge

-/css/reset.css
-/css/main.css

archetype/src/main/resources/archetype-resources/src/main/webapp/css/reset.css

-/* http://meyerweb.com/eric/tools/css/reset/ 
-   v2.0 | 20110126
-   License: none (public domain)
-*/
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed, 
-figure, figcaption, footer, header, hgroup, 
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	font-size: 100%;
-	font: inherit;
-	vertical-align: baseline;
-}
-/* HTML5 display-role reset for older browsers */
-article, aside, details, figcaption, figure, 
-footer, header, hgroup, menu, nav, section {
-	display: block;
-}
-body {
-	line-height: 1;
-}
-ol, ul {
-	list-style: none;
-}
-blockquote, q {
-	quotes: none;
-}
-blockquote:before, blockquote:after,
-q:before, q:after {
-	content: '';
-	content: none;
-}
-table {
-	border-collapse: collapse;
-	border-spacing: 0;
-}

archetype/src/main/resources/archetype-resources/src/main/webapp/favicon.ico

Binary file removed.

archetype/src/main/resources/archetype-resources/src/main/webapp/js/app/app.js

-var App = App || {};
-
-/* TODO: put client side example logic here */

archetype/src/main/resources/archetype-resources/src/main/webapp/js/duel/duel.js

-/*global window */
-
-/**
- * @fileoverview duel.js: client-side template engine
- * 
- * http://duelengine.org
- * 
- * Copyright (c) 2006-2010 Stephen M. McKamey
- * Licensed under the MIT License (http://duelengine.org/license.txt)
- */
-
-/**
- * @public
- * @param {Array|Object|string|number|function(*,number,number):Array|Object|string} view The view template
- * @return {function(*)}
- */
-var duel = (
-	/**
-	 * @param {Window} window Window reference
-	 */
-	function(window) {
-
-	"use strict";
-
-	/**
-	 * @type {Document} document Document reference
-	 */
-	var document = window.document;
-
-	/* types.js --------------------*/
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var NUL = 0;
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var FUN = 1;
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var ARY = 2;
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var OBJ = 3;
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var VAL = 4;
-
-	/**
-	 * @private
-	 * @const
-	 * @type {number}
-	 */
-	var RAW = 5;
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {string}
-	 */
-	var MSIE = "ScriptEngineMajorVersion";
-
-	/**
-	 * Wraps a data value to maintain as raw markup in output
-	 * 
-	 * @private
-	 * @this {Markup}
-	 * @param {string} value The value
-	 * @constructor
-	 */
-	function Markup(value) {
-		/**
-		 * @type {string}
-		 * @const
-		 * @protected
-		 */
-		this.value = value;
-	}
-
-	/**
-	 * Renders the value
-	 * 
-	 * @public
-	 * @override
-	 * @this {Markup}
-	 * @return {string} value
-	 */
-	Markup.prototype.toString = function() {
-		return this.value;
-	};
-
-	/**
-	 * Determines if the value is an Array
-	 * 
-	 * @private
-	 * @param {*} val the object being tested
-	 * @return {boolean}
-	 */
-	var isArray = Array.isArray || function(val) {
-		return (val instanceof Array);
-	};
-	
-	/**
-	 * Determines the type of the value
-	 * 
-	 * @private
-	 * @param {*} val the object being tested
-	 * @return {number}
-	 */
-	function getType(val) {
-		switch (typeof val) {
-			case "object":
-				return !val ? NUL : (isArray(val) ? ARY : ((val instanceof Markup) ? RAW : ((val instanceof Date) ? VAL : OBJ)));
-			case "function":
-				return FUN;
-			case "undefined":
-				return NUL;
-			default:
-				return VAL;
-		}
-	}
-
-	/**
-	 * Determines if the value is a string
-	 * 
-	 * @private
-	 * @param {*} val the object being tested
-	 * @return {boolean}
-	 */
-	function isString(val) {
-		return (typeof val === "string");
-	}
-
-	/**
-	 * Determines if the value is a function
-	 * 
-	 * @private
-	 * @param {*} val the object being tested
-	 * @return {boolean}
-	 */
-	function isFunction(val) {
-		return (typeof val === "function");
-	}
-
-	/**
-	 * String buffer
-	 * 
-	 * @private
-	 * @this {Buffer}
-	 * @constructor
-	 */
-	function Buffer() {
-		/**
-		 * @type {Array|string}
-		 * @private
-		 */
-		this.value = Buffer.FAST ? "" : [];
-	}
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {boolean}
-	 */
-	Buffer.FAST = !window[MSIE];
-
-	/**
-	 * Appends to the internal value
-	 * 
-	 * @public
-	 * @this {Buffer}
-	 * @param {string} v1
-	 * @param {string} v2
-	 * @param {string} v3
-	 */
-	Buffer.prototype.append = function(v1, v2, v3) {
-		if (Buffer.FAST) {
-			this.value += v1;
-
-			if (v2 !== null && v2 !== undefined) {
-				this.value += v2;
-
-				if (v3 !== null && v3 !== undefined) {
-					this.value += v3;
-				}
-			}
-		} else {
-			this.value.push.apply(
-				// Closure Compiler type cast
-				/** @type{Array} */(this.value),
-				arguments);
-		}
-	};
-
-	/**
-	 * Clears the internal value
-	 * 
-	 * @public
-	 * @this {Buffer}
-	 */
-	Buffer.prototype.clear = function() {
-		this.value = Buffer.FAST ? "" : [];
-	};
-
-	/**
-	 * Renders the value
-	 * 
-	 * @public
-	 * @override
-	 * @this {Buffer}
-	 * @return {string} value
-	 */
-	Buffer.prototype.toString = function() {
-		return Buffer.FAST ?
-			// Closure Compiler type cast
-			/** @type{string} */(this.value) :
-			this.value.join("");
-	};
-
-	function digits(n) {
-        return (n < 10) ? '0'+n : n;
-    }
-
-	/**
-	 * Formats the value as a string
-	 * 
-	 * @private
-	 * @param {*} val the object being tested
-	 * @return {string|null}
-	 */
-	function asString(val) {
-		var buffer, needsDelim;
-		switch (getType(val)) {
-			case VAL:
-				if (val instanceof Date) {
-					// YYYY-MM-DD HH:mm:ss Z
-					return val.getUTCFullYear()+'-'+
-						digits(val.getUTCMonth()+1)+'-'+
-						digits(val.getUTCDate())+' '+
-						digits(val.getUTCHours())+':'+
-						digits(val.getUTCMinutes())+':'+
-						digits(val.getUTCSeconds())+" Z";
-				}
-				return ""+val;
-			case NUL:
-				return "";
-			case ARY:
-				// flatten into simple list
-				buffer = new Buffer();
-				for (var i=0, length=val.length; i<length; i++) {
-					if (needsDelim) {
-						buffer.append(", ");
-					} else {
-						needsDelim = true;
-					}
-					buffer.append(asString(val[i]));
-				}
-				return buffer.toString();
-			case OBJ:
-				// format JSON-like
-				buffer = new Buffer();
-				buffer.append('{');
-				for (var key in val) {
-					if (val.hasOwnProperty(key)) {
-						if (needsDelim) {
-							buffer.append(", ");
-						} else {
-							needsDelim = true;
-						}
-						buffer.append(key, '=', asString(val[key]));
-					}
-				}
-				buffer.append('}');
-				return buffer.toString();
-		}
-
-		// Closure Compiler type cast
-		return /** @type{string} */(val);
-	}
-	
-	/**
-	 * Wraps a binding result with rendering methods
-	 * 
-	 * @private
-	 * @this {Result}
-	 * @param {Array|Object|string|number} view The result tree
-	 * @constructor
-	 */
-	function Result(view) {
-		if (!isArray(view)) {
-			// ensure is rooted element
-			view = ["", view];
-		}
-	
-		/**
-		 * @type {Array}
-		 * @const
-		 * @protected
-		 */
-		// Closure Compiler type cast
-		this.value = /** @type {Array} */(view);
-	}
-
-	/* bind.js --------------------*/
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {string}
-	 */
-	var FOR = "$for";
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {string}
-	 */
-	var XOR = "$xor";
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {string}
-	 */
-	var IF = "$if";
-
-	/**
-	 * @private
-	 * @constant
-	 * @type {string}
-	 */
-	var CALL = "$call";
-