1 Apache Velocity Overview Dinagar Raghunathan by .

26
1 Apache Velocity Overview Dinagar Raghunathan by http://www.rdinagar.com

Transcript of 1 Apache Velocity Overview Dinagar Raghunathan by .

1

Apache Velocity Overview

Dinagar Raghunathan

by

http://www.rdinagar.com

2http://www.rdinagar.com

Agenda

• Introduction

• Architecture

• Velocity Template Language (VTL)

• References

• Directives

• Macros

• Accessing VM in JavaScript & JavaScript in VM

• how to use Velocity inside Java programs

• Sample Code

• Customized Directives

• Event Handler - Escape entities

• References

3http://www.rdinagar.com

Introduction - Velocity

• Velocity is an open source templating tool developed by an international volunteer community and hosted by the Apache Software Foundation's Jakarta Project .

• Velocity is a fast and easy-to-use Java-based templating engine.

• Used in a broad range of applications, including code generation, email templating, and web applications.

• The designers can focus exclusively on the data presentation (the view), and the application programmer can focus on the application control.

• Web Macro is an open source templating system enables programmers and designers to work together while promoting the ModelViewController pattern and served as the inspiration for Apache's Velocity.

4http://www.rdinagar.com

Uses of Velocity

• Web applications

Web designers can create HTML pages

• Source code generation

Velocity can be used to generate Java source code, SQL, C++.

• Automatic emails

Many applications generate automatic emails for account signup, password reminders. These mails can be created using velocity

5http://www.rdinagar.com

Architecture

MVC Architecture

Model

View

Controller

6http://www.rdinagar.com

Templates and Transformations

• Data Model

Contains data that has to be transformed.

• Template

Formats the data model into the output code

• Template Engine

The application that performs the transformation. It has the input data model and the template, and produces output by replacing the template internal references with real data coming from the model.

• Target The result of the transformation process.

7http://www.rdinagar.com

Velocity Template Language (VTL)

• VTL is a template language using which templates are created.

• VTL has two parts

References.

Directives.

• References

Objects in the Velocity context are accessed using references from within a template. References begin with a dollar sign.

8http://www.rdinagar.com

References

• There are three types of references in the VTL.• Variable.

• Property

• Methods.

• Variable

The shorthand notation of a variable consists of a leading "$" character followed by a VTL Identifier.

• Property

The shorthand notation consists of a leading $ character followed a VTL Identifier, followed by a dot character (".") and another VTL Identifier. E.g.

$customer.Address

9http://www.rdinagar.com

Contd..

• Method. A method is defined in the Java code and is capable of doing something useful, like

running a calculation or arriving at a decision.e.g.

$customer.getAddress().

• Directives They are a set statements used for control and actions. The Directives in VTL are

#set()    #if()    #else    #elseif()    #end    #foreach()    #include()    #parse()    #macro()

10http://www.rdinagar.com

Directives

Directive Syntax Purpose

#foreach

#foreach ($item in $collection) item is $item

#end

Iterates over a collection, array, or map.

#if/#else/ #elseif

#if ($order.total == 0) No charge#end

Conditional. Null can be checked for using #if ($obj) obj not null #end syntax.

#parse #parse("header.vm")Loads, parses, and incorporates the specified template into the generated

output.

#macro

#macro(currency $amount)${

formatter.currency($amount)

}#end

Defines a new directive and any required parameters. The result is interpreted when used later in the template. The example macro would be used as #currency($item.cost).

#include #include("disclaimer.txt") Includes the specified file, as is, into the generated output.

#set#set ($customer =

$order.customer)Assigns a value to a context object. If the context object does not exist, it is

added; otherwise, it is replaced.

#stop#if ($debug) #stop#end

Stops template processing. This is usually used for debugging purposes.

11http://www.rdinagar.com

Macros

Velocity macro example

#macro( square $no )

#set($sqr =$no *$no) The square of the number is $sqr

#end

To Invoke.

#square(10)

Output:The square of the number is 100

12http://www.rdinagar.com

JS in VM and VM variables to JS

• VM variables can be assigned to JavaScript Variable.• Var age = $employee.age;

• VM object reference can’t be assigned to JavaScript Variable.

• JavaScript variables cant be assigned to VM files.

13http://www.rdinagar.com

How to use Velocity inside Java programs

• VelocityEngine • This class provides a separate new-able instance of the Velocity template engine.

The alternative model for use is using the Velocity class which employs the singleton model.

• Please ensure that you call one of the init() variants. This is critical for proper behavior.

• VelocityContext• General purpose implementation of the application Context interface for general

application use. This class should be used in place of the original Context class. This implementation uses a HashMap (@see java.util.HashMap ) for data storage.

• Template• This class is used for controlling all template operations. Merge operation merges

the information in the Context to the Writer object

Velocity Writer Java VM file

Output file

14http://www.rdinagar.com

Sample Code - Advertisement

public static void main(String args[]) throws Exception {VelocityEngine ve=new

VelocityEngine();ve.init();

ArrayList list=new ArrayList();

Map mp=new HashMap();mp.put("name",“Perfume");mp.put("price","Rs 100");list.add(mp);

mp=new HashMap();mp.put("name",“Biscuit");mp.put("price","Rs 10");list.add(mp);

// Setting up Velocity Context VelocityContext vc=new

VelocityContext();vc.put(“prodList",list);

Template t=ve.getTemplate("Products.vm");

StringWriter sw=new StringWriter();

t.merge(vc,sw);System.out.println(sw.toString());

}MyVelocityWriter.java

15http://www.rdinagar.com

Template - Advertisement

There are $prodList.size() Products for Sale!

We are proud to offer these products

at these amazing prices. This month only,

choose from:

#foreach($prod in $prodList)

$prod.name for only $prod.price

#end

Call Immediately!

sampleVelocityFile.vm

16http://www.rdinagar.com

Output

There are 2 Products for Sale!

We are proud to offer these products

at these amazing prices. This month only,

choose from:

Perfume for only Rs 100

Biscuit for only Rs 10

Call Immediately!

sampleVelocity.html

17http://www.rdinagar.com

Example - Mail Template

$Date

Dear $Contact.FirstName $Contact.LastName,

Thank you for your recent purchase of $Order.ProductName. The cost of the item was $Order.TotalCost #if($Order.Tax > 0) including a tax of $Order.TaxRate%#end.

Sincerely,Biggest and Best Book Merchants, Inc.

November 17, 2004

Dear Jennifer Glass,

Thank you for your recent purchase of Alice in Wonderland, Annotated Edition. The cost of the item was $29.95.

Sincerely,Biggest and Best Book Merchants, Inc.

Order

Contact

Date

18http://www.rdinagar.com

Controlling Velocity Template Generation with a Custom Directive

• Consider – can the problem you are trying to solve be done more simply with a Tool or VelocityMacro?

• If not, Velocity allows you to code your own custom directives by doing the following:• Create a class that extends

org.apache.velocity.runtime.directive.Directive

• Add the following to velocity.propertiesuserdirective = yourdirectiveclass

• Review the directives in the velocity source code for good examples. For example, review org.apache.velocity.runtime.directive.ForEach

19http://www.rdinagar.com

Custom Directive Example: Generate Endnotes

#endNotesAll in the golden afternoon (*1:In these prefatory verses Carroll recalls that "golden afternoon" in 1862 when he and his friend the Reverend Robinson Duckworth (then a fellow of Trinity College, Oxford, later canon of Westminster) took the three charming Liddell sisters on a rowing expedition up the Thames. *) Full leisurely we glide;For both our oars, with little skill,     By little arms are plied,While little hands make vain pretence     Our wanderings to guide.(* 2:Note how this stanza puns three times with the word "little." "Liddle" was pronounced to rhyme with "fiddle." *)#end

Usage:

All in the golden afternoon Full leisurely we glide;For both our oars, with little skill,     By little arms are plied,While little hands make vain pretence     Our wanderings to guide.

NOTES1: In these prefatory verses Carroll recalls that "golden afternoon" in 1862 when he and his friend the Reverend Robinson Duckworth (then a fellow of Trinity College, Oxford, later canon of Westminster) took the three charming Liddell sisters on a rowing expedition up the Thames.

2:Note how this stanza puns three times with the word "little." "Liddle" was pronounced to rhyme with "fiddle."

Results:

20http://www.rdinagar.com

Custom Directive Example: Code Excerpt – Main Class

public class MyVelocityWriterDirective {

public static void main(String argv[]) throws Exception {

VelocityEngine velocityEngine = new VelocityEngine();

// load properties from classpath

Properties properties = new Properties();

InputStream inputStream = MyVelocityWriterDirective.class.getResourceAsStream("velocity.properties");

properties.load(inputStream);

inputStream.close();

velocityEngine.init(properties);

// configure the context

Context context = new VelocityContext();

// process the template

Template template = velocityEngine.getTemplate("input1.vm");

FileWriter writer = new FileWriter("output.txt");

template.merge(context, writer);

writer.close();

}

}MyVelocityWriterDirective.java

21http://www.rdinagar.com

Custom Directive Example: Code Excerpt – Directive Class

public class EndNoteDirective extends Directive {

public String getName() { return "endNotes"; }

public int getType() { return BLOCK; }

public boolean render(InternalContextAdapter context, java.io.Writer writer,Node node)

throws ResourceNotFoundException,ParseErrorException,MethodInvocationException

{

// first, parse the entire block and retrieve the content

StringWriter internalwriter = new StringWriter();

// the node's children are the arguments and the body.

// here there should be only one child, since there are no arguments

node.jjtGetChild(0).render(context, internalwriter);

String sourcecontent = internalwriter.toString();

internalwriter.close();

// missing code creates new "finalcontent" based on "sourcecontent"

writer.write(finalcontent.toString());

return true;

}

}

EndNoteDirective.java

22http://www.rdinagar.com

Custom Directive Example: Configuration

velocity.properties Input1.vm

## Load templates from classpath

resource.loader = class

class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

## Specify the user directive

userdirective=com.jlamp.directive.EndNoteDirective

• Demo

Output.txt

23http://www.rdinagar.com

Adding an Event Handler

• Velocity provides a mechanism to intercept and modify parsing operation.

• Currently, three event handlers available:• ReferenceInsertionEventHandler: Modify the text that gets inserted

from a reference (e.g. $date)• NullSetEventHandler: Prevents logging of null #set operations• MethodExceptionEventHandler: Intercept a method thrown by a tool

in the context.

• Event handlers are instantiated for each page that is parsed, and are "attached" to the context before the template is merged:EventCartridge ec = new EventCartridge(); ec.addEventHandler(new CustomReferenceInsertionHandler());ec.attachToContext( context );

// now merge the template

24http://www.rdinagar.com

Event Handler Example: Escape XML Entities (excerpt)

MyVelocityWriterEvent.java CustomReferenceInsertionHandler.java

/**

* Escape all XML Entities in the reference insertion. Specifically, the following

* conversions are performed:

* <DL>

* <DT>&amp;</DT><DD>&amp;amp;</DD>

* <DT>&lt;</DT><DD>&amp;lt;</DD>

* <DT>&gt;</DT><DD>&amp;gt;</DD>

* <DT>&quot;</DT><DD>&amp;quot;</DD>

* </DL>

*/

public class EscapeXMLEntities implements ReferenceInsertionEventHandler {

/**

* Escape the XML entities for all inserted references.

*/

public Object referenceInsert(String reference, Object value) {

String val = value.toString();

return escapeText(val);

}

}

• DemosampleVelocity.html

25http://www.rdinagar.com

References

• http://jakarta.apache.org/velocity/

• http://wiki.apache.org/jakarta-velocity/HackingVelocity

26http://www.rdinagar.com

Thank You