Skip to content

Commit

Permalink
first version (quick and dirty implementation) of pippo-velocity (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
decebals committed Jun 11, 2015
1 parent 96cd99b commit 853d4ae
Show file tree
Hide file tree
Showing 11 changed files with 350 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pippo-demo/pippo-demo-template/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>ro.pippo</groupId>
<artifactId>pippo-velocity</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Webjars -->
<dependency>
<groupId>org.webjars</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import ro.pippo.core.route.RouteHandler;
import ro.pippo.metrics.Metered;
import ro.pippo.metrics.Timed;
import ro.pippo.velocity.VelocityTemplateEngine;

import java.util.Calendar;
import java.util.Date;
Expand All @@ -32,16 +33,21 @@
public class TemplateApplication extends Application {

private final String template;
private final boolean velocity;

public TemplateApplication(TemplateEngine engine, String template) {
this.template = template;

// set the template engine
setTemplateEngine(engine);

velocity = (engine instanceof VelocityTemplateEngine);
}

@Override
protected void onInit() {
getRouter().ignorePaths("/favicon.ico");

// add routes for static content
addPublicResourceRoute();
addWebjarsResourceRoute();
Expand All @@ -61,6 +67,12 @@ public void handle(RouteContext routeContext) {
routeContext.setLocal("testDate", testDate);
routeContext.setLocal("mode", getRuntimeMode());

// ugly hack
// TODO remove
if (velocity) {
routeContext.setLocal("welcome", "Welcome");
}

routeContext.render(template);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2015 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.
*/
package ro.pippo.demo.template;

import ro.pippo.core.Pippo;
import ro.pippo.velocity.VelocityTemplateEngine;

/**
* @author Decebal Suiu
*/
public class VelocityDemo {

public static void main(String[] args) {
// .vm is the default file extension
Pippo pippo = new Pippo(new TemplateApplication(new VelocityTemplateEngine(), "velocity/hello"));
pippo.start();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>Velocity Demo</title>
</head>

<body>
<span>$welcome</span>
</body>
</html>
43 changes: 43 additions & 0 deletions pippo-velocity/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?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">

<parent>
<groupId>ro.pippo</groupId>
<artifactId>pippo-parent</artifactId>
<version>0.6.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>pippo-velocity</artifactId>
<version>0.6.0-SNAPSHOT</version>
<name>Pippo Velocity</name>
<description>Velocity template engine</description>

<properties>
<velocity.version>1.7</velocity.version>
</properties>

<dependencies>
<dependency>
<groupId>ro.pippo</groupId>
<artifactId>pippo-core</artifactId>
<version>${project.version}</version>
</dependency>

<!-- Velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
</dependency>

<!-- PrettyTime -->
<dependency>
<groupId>org.ocpsoft.prettytime</groupId>
<artifactId>prettytime</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2015 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.
*/
package ro.pippo.velocity;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;

import java.io.InputStream;

/**
* @see http://stackoverflow.com/a/9693749/390044
*
* @author Decebal Suiu
*/
public class PrefixedClasspathResourceLoader extends ClasspathResourceLoader {

/** Prefix to be added to any names */
private String prefix = "";

@Override
public void init(ExtendedProperties configuration) {
prefix = configuration.getString("prefix", "");
}

@Override
public InputStream getResourceStream(String name) {
return super.getResourceStream(prefix + name);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2015 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.
*/
package ro.pippo.velocity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.pippo.core.Application;
import ro.pippo.core.Initializer;

/**
* @author Decebal Suiu
*/
public class VelocityInitializer implements Initializer {

private static final Logger log = LoggerFactory.getLogger(VelocityInitializer.class);

@Override
public void init(Application application) {
application.registerTemplateEngine(VelocityTemplateEngine.class);
}

@Override
public void destroy(Application application) {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
* Copyright (C) 2015 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.
*/
package ro.pippo.velocity;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import ro.pippo.core.Application;
import ro.pippo.core.Languages;
import ro.pippo.core.Messages;
import ro.pippo.core.PippoConstants;
import ro.pippo.core.PippoRuntimeException;
import ro.pippo.core.PippoSettings;
import ro.pippo.core.TemplateEngine;
import ro.pippo.core.util.StringUtils;

import java.io.StringReader;
import java.io.Writer;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

/**
* @author Decebal Suiu
*/
public class VelocityTemplateEngine implements TemplateEngine {

public static final String VM = "vm";
public static final String FILE_SUFFIX = "." + VM;

private Languages languages;
private Messages messages;
private VelocityEngine velocityEngine;

@Override
public void init(Application application) {
this.languages = application.getLanguages();
this.messages = application.getMessages();

PippoSettings pippoSettings = application.getPippoSettings();

String pathPrefix = pippoSettings.getString(PippoConstants.SETTING_TEMPLATE_PATH_PREFIX, null);
if (StringUtils.isNullOrEmpty(pathPrefix)) {
pathPrefix = TemplateEngine.DEFAULT_PATH_PREFIX;
}

// create properties (see http://velocity.apache.org/engine/releases/velocity-1.7/developer-guide.html#Configuring_Resource_Loaders)
// maybe we can found in classpath a file velocity.properties and load all properties from this file
Properties properties = new Properties();
// properties.setProperty("pathPrefix", pathPrefix);
// properties.setProperty("resource.loader", "classpath");
// properties.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
// properties.setProperty("classpath.resource.loader.prefixPath", pathPrefix);
// properties.setProperty("classpath.resource.loader.cache", String.valueOf(!pippoSettings.isDev()));

properties.setProperty("resource.loader", "myloader");
properties.setProperty("myloader.resource.loader.class", PrefixedClasspathResourceLoader.class.getName());
properties.setProperty("myloader.resource.loader.prefix", StringUtils.addEnd(pathPrefix, "/"));
properties.setProperty("myloader.resource.loader.cache", String.valueOf(!pippoSettings.isDev()));

// properties.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, pathPrefix);
// velocity.properties
// resource.loader = file
// file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
// file.resource.loader.path = c:/tomcat/webapps/velocity/WEB-INF/templates
// file.resource.loader.cache = true
// file.resource.loader.modificationCheckInterval = 2
// properties.setProperty("input.encoding","UTF-8");
// properties.setProperty("output.encoding","UTF-8");

velocityEngine = new VelocityEngine(properties);
}

public VelocityEngine getVelocityEngine() {
return velocityEngine;
}

@Override
public void renderString(String templateContent, Map<String, Object> model, Writer writer) {
// prepare the locale-aware i18n method
String language = (String) model.get(PippoConstants.REQUEST_PARAMETER_LANG);
if (StringUtils.isNullOrEmpty(language)) {
language = languages.getLanguageOrDefault(language);
}
// model.put("i18n", new I18nMethod(messages, language));

// prepare the locale-aware prettyTime method
Locale locale = (Locale) model.get(PippoConstants.REQUEST_PARAMETER_LOCALE);
if (locale == null) {
locale = languages.getLocaleOrDefault(language);
}
// model.put("prettyTime", new PrettyTimeMethod(locale));
// model.put("formatTime", new FormatTimeMethod(locale));
// model.put("webjarsAt", webjarResourcesMethod);
// model.put("publicAt", publicResourcesMethod);

try {
RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
StringReader reader = new StringReader(templateContent);
SimpleNode node = runtimeServices.parse(reader, "StringTemplate");
Template template = new Template();
template.setRuntimeServices(runtimeServices);
template.setData(node);
template.initDocument();
VelocityContext context = new VelocityContext(model);
template.merge(context, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
}
}

@Override
public void renderResource(String templateName, Map<String, Object> model, Writer writer) {
// prepare the locale-aware i18n method
String language = (String) model.get(PippoConstants.REQUEST_PARAMETER_LANG);
if (StringUtils.isNullOrEmpty(language)) {
language = languages.getLanguageOrDefault(language);
}
// model.put("i18n", new I18nMethod(messages, language));

// prepare the locale-aware prettyTime method
Locale locale = (Locale) model.get(PippoConstants.REQUEST_PARAMETER_LOCALE);
if (locale == null) {
locale = languages.getLocaleOrDefault(language);
}
// model.put("prettyTime", new PrettyTimeMethod(locale));
// model.put("formatTime", new FormatTimeMethod(locale));
// model.put("webjarsAt", webjarResourcesMethod);
// model.put("publicAt", publicResourcesMethod);

try {
if (templateName.indexOf('.') == -1) {
templateName += FILE_SUFFIX;
}
// TODO locale ?!
Template template = velocityEngine.getTemplate(templateName);
VelocityContext context = new VelocityContext(model);
template.merge(context, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ro.pippo.velocity.VelocityTemplateEngine
1 change: 1 addition & 0 deletions pippo-velocity/src/main/resources/pippo.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
initializer=ro.pippo.velocity.VelocityInitializer
Loading

0 comments on commit 853d4ae

Please sign in to comment.