aboutsummaryrefslogtreecommitdiff
path: root/velocity-custom-parser-example
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-custom-parser-example')
-rw-r--r--velocity-custom-parser-example/pom.xml284
-rw-r--r--velocity-custom-parser-example/src/test/java/org/apache/velocity/runtime/parser/CustomParserTestCase.java56
-rw-r--r--velocity-custom-parser-example/src/test/resources/reference/test.md13
-rw-r--r--velocity-custom-parser-example/src/test/resources/templates/test.md23
4 files changed, 376 insertions, 0 deletions
diff --git a/velocity-custom-parser-example/pom.xml b/velocity-custom-parser-example/pom.xml
new file mode 100644
index 00000000..72c6ab73
--- /dev/null
+++ b/velocity-custom-parser-example/pom.xml
@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+
+-->
+<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>
+ <parent>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-parent</artifactId>
+ <version>2.4-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>velocity-custom-parser-example</artifactId>
+ <name>Apache Velocity Custom Parser Example</name>
+ <description>Custom Parser Example for Apache Velocity</description>
+
+ <packaging>pom</packaging>
+
+ <!--
+ This module demonstrates how to build a custom Velocity parser.
+ The proposed custom parser replaces '#' with '@' and '@' with '%'
+ so that it's suitable to use with Markdown template files, for instance.
+
+ The generated parser class is ${parser.package}.${parser.basename}Parser,
+ and must be specified at runtime using the Velocity property parser.class:
+ parser.class = foo.bar.MyCustomParser
+
+ Please note that all configurable chars (*, @, $, #) must be specified, even when similar to default ones.
+ -->
+
+ <properties>
+ <!-- whether to display debug logs while parsing -->
+ <parser.debug>false</parser.debug>
+ <!-- parser basename -->
+ <parser.basename>Custom</parser.basename>
+ <!-- parser package -->
+ <parser.package>org.apache.velocity.runtime.parser.custom</parser.package>
+ <!-- character to substitute to '*' -->
+ <parser.char.asterisk>*</parser.char.asterisk>
+ <!-- character to substitute to '@' -->
+ <parser.char.at>%</parser.char.at>
+ <!-- character to substitute to '$' -->
+ <parser.char.dollar>$</parser.char.dollar>
+ <!-- character to substitute to '#' -->
+ <parser.char.hash>@</parser.char.hash>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity-engine-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.8.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <!-- generate manifest file -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ </plugin>
+
+ <!-- extract raw parser grammar from velocity jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>fetch-grammar-file</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifact>org.apache.velocity:velocity-engine-core:${project.version}</artifact>
+ <includes>org/apache/velocity/runtime/parser/Parser.jjt</includes>
+ <outputDirectory>${project.build.directory}/grammar</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- generate custom grammar file -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-parser-grammar</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <useDefaultDelimiters>false</useDefaultDelimiters>
+ <delimiters>
+ <delimiter>${*}</delimiter>
+ </delimiters>
+ <resources>
+ <resource>
+ <directory>${project.build.directory}/grammar</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <outputDirectory>${project.build.directory}/parser</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- run javacc -->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>javacc-maven-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <isStatic>false</isStatic>
+ <buildParser>true</buildParser>
+ <buildNodeFiles>false</buildNodeFiles>
+ <multi>true</multi>
+ <debugParser>${parser.debug}</debugParser>
+ <debugLookAhead>${parser.debug}</debugLookAhead>
+ <debugTokenManager>${parser.debug}</debugTokenManager>
+ <jdkVersion>${maven.compiler.target}</jdkVersion>
+ <nodeUsesParser>true</nodeUsesParser>
+ <nodePackage>${parser.package}.node</nodePackage>
+ <sourceDirectory>${project.build.directory}/parser/org/apache/velocity/runtime/parser</sourceDirectory>
+ <tokenManagerUsesParser>true</tokenManagerUsesParser>
+ </configuration>
+ <executions>
+ <execution>
+ <id>jjtree-javacc</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>jjtree-javacc</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>Parser.jjt</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Remove extra generated files we don't want -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>clean-extra-javacc</id>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ <configuration>
+ <excludeDefaultDirectories>true</excludeDefaultDirectories>
+ <filesets>
+ <fileset>
+ <directory>${project.build.directory}/generated-sources/javacc/</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/*${parser.basename}*.java</exclude>
+ </excludes>
+ </fileset>
+ <fileset>
+ <directory>${project.build.directory}/generated-sources/jjtree/</directory>
+ <includes>
+ <include>**/node/*.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/node/*${parser.basename}*.java</exclude>
+ </excludes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- add missing imports to some parser generated files -->
+ <plugin>
+ <groupId>com.google.code.maven-replacer-plugin</groupId>
+ <artifactId>replacer</artifactId>
+ <executions>
+ <execution>
+ <id>patch-parser-files</id>
+ <phase>process-sources</phase>
+ <goals>
+ <goal>replace</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>${project.build.directory}/generated-sources/jjtree/**/JJT${parser.basename}ParserState.java</include>
+ <include>${project.build.directory}/generated-sources/jjtree/**/${parser.basename}ParserVisitor.java</include>
+ </includes>
+ <replacements>
+ <replacement>
+ <token>import ${parser.package}.*;</token>
+ <value>import ${parser.package}.*;
+import org.apache.velocity.runtime.parser.node.*;</value>
+ </replacement>
+ </replacements>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- tests -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.plugin.version}</version>
+ <configuration>
+ <skip>${maven.test.skip}</skip>
+ <systemProperties>
+ <property>
+ <name>test</name>
+ <value>${test}</value>
+ </property>
+ <property>
+ <name>test.templates.dir</name>
+ <value>${project.build.testOutputDirectory}/templates</value>
+ </property>
+ <property>
+ <name>test.results.dir</name>
+ <value>${project.build.directory}/results</value>
+ </property>
+ <property>
+ <name>test.reference.dir</name>
+ <value>${project.build.testOutputDirectory}/reference</value>
+ </property>
+ <property>
+ <name>org.slf4j.simpleLogger.defaultLogLevel</name>
+ <value>warn</value>
+ </property>
+ <property>
+ <name>org.slf4j.simpleLogger.logFile</name>
+ <value>${project.build.directory}/velocity.log</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/velocity-custom-parser-example/src/test/java/org/apache/velocity/runtime/parser/CustomParserTestCase.java b/velocity-custom-parser-example/src/test/java/org/apache/velocity/runtime/parser/CustomParserTestCase.java
new file mode 100644
index 00000000..9a27ff89
--- /dev/null
+++ b/velocity-custom-parser-example/src/test/java/org/apache/velocity/runtime/parser/CustomParserTestCase.java
@@ -0,0 +1,56 @@
+package org.apache.velocity.runtime.parser;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.nio.charset.StandardCharsets;
+
+import static org.junit.Assert.*;
+
+public class CustomParserTestCase
+{
+ VelocityEngine engine;
+
+ static String TEMPLATES_DIR = System.getProperty("test.templates.dir");
+ static String RESULTS_DIR = System.getProperty("test.results.dir");
+ static String REFERENCE_DIR = System.getProperty("test.reference.dir");
+
+ @Before
+ public void setUp()
+ {
+ engine = new VelocityEngine();
+ engine.setProperty("resource.loaders", "file");
+ engine.setProperty("resource.loader.file.path", TEMPLATES_DIR);
+ engine.setProperty("parser.class", "org.apache.velocity.runtime.parser.custom.CustomParser");
+ engine.init();
+ }
+
+ @Test
+ public void testMarkdownTemplate() throws Exception
+ {
+ VelocityContext ctx = new VelocityContext();
+ ctx.put("some", "value");
+ Template tmpl = engine.getTemplate("test.md", "UTF-8");
+
+ String resultFile = RESULTS_DIR + File.separator + "test.md";
+ String referenceFile = REFERENCE_DIR + File.separator + "test.md";
+
+ new File(resultFile).getParentFile().mkdirs();
+
+ FileWriter writer = new FileWriter(resultFile);
+ tmpl.merge(ctx, writer);
+ writer.flush();
+ writer.close();
+
+ String result = IOUtils.toString(new FileInputStream(resultFile), StandardCharsets.UTF_8);
+ String reference = IOUtils.toString(new FileInputStream(referenceFile), StandardCharsets.UTF_8);
+ assertEquals(reference, result);
+ }
+}
diff --git a/velocity-custom-parser-example/src/test/resources/reference/test.md b/velocity-custom-parser-example/src/test/resources/reference/test.md
new file mode 100644
index 00000000..941d4f68
--- /dev/null
+++ b/velocity-custom-parser-example/src/test/resources/reference/test.md
@@ -0,0 +1,13 @@
+# Test markdown template for the custom parser
+
+
+
+
+## Custom parser is needed
+
+some value
+ all seems fine
+
+
+ block macro called with foo=value and bodyContent=here
+
diff --git a/velocity-custom-parser-example/src/test/resources/templates/test.md b/velocity-custom-parser-example/src/test/resources/templates/test.md
new file mode 100644
index 00000000..f8badd9d
--- /dev/null
+++ b/velocity-custom-parser-example/src/test/resources/templates/test.md
@@ -0,0 +1,23 @@
+# Test markdown template for the custom parser
+
+@* this is a comment *@
+
+@set ($subtitle = 'Custom parser is needed')
+
+## $subtitle
+
+some $some @@ should print 'some value'
+
+@if ($some == 'value')
+ all seems fine
+@else
+ there is a problem
+@end
+
+@macro(block $foo)
+ block macro called with foo=$foo and bodyContent=$bodyContent
+@end
+
+@%block($some)
+here
+@end