velocity-1.7/0000755000175000017500000000000011675166253013113 5ustar moellermoellervelocity-1.7/build/0000755000175000017500000000000011675166243014211 5ustar moellermoellervelocity-1.7/build/download.xml0000644000175000017500000001775111101415132016527 0ustar moellermoeller velocity-1.7/build/xsl/0000755000175000017500000000000011675166242015016 5ustar moellermoellervelocity-1.7/build/xsl/xml2pdf.xsl0000644000175000017500000003040410513464370017114 0ustar moellermoeller Velocity User's Guide - pg Velocity Content · ) ... velocity-1.7/build/xsl/xml2xml.xsl0000644000175000017500000000316710513464370017151 0ustar moellermoeller velocity-1.7/build/findbugs-exclude.xml0000755000175000017500000001114011122245113020140 0ustar moellermoeller velocity-1.7/build/build.properties0000644000175000017500000004000711470267434017424 0ustar moellermoeller# 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. # # This file is used by build.xml and testcases.xml # # Global defaults name= Velocity project= velocity version= 1.7 final.name= ${project}-${version} # compile switches debug= on optimize= on deprecation= off # Needs to be configured with system location of javacc for parser task javacc.home= *unset* velocity.build.dir= build build.dir= ${velocity.dir}/bin # The source tree runs through a filter copy task to # allow substitution of version, date etc. and will # end up in build.src build.src= ${build.dir}/src build.lib= ${build.dir}/lib build.test.src= ${build.dir}/test-src build.test.lib= ${build.dir}/test-lib build.dest= ${build.dir}/classes build.deps= ${build.dir}/deps build.test.dest= ${build.dir}/test-classes build.javadoc= ${build.dir}/apidocs build.test= ${build.dir}/test build.test.reports= ${build.dir}/test-reports build.docs= ${build.dir}/docs # Various local pathes in the distribution src.java.dir= ${velocity.dir}/src/java src.parser.dir = ${velocity.dir}/src/parser test.java.dir= ${velocity.dir}/src/test test.dir= ${velocity.dir}/test example.dir= ${velocity.dir}/examples xdocs.dir= ${velocity.dir}/xdocs # @TODO Move parser build out of the tree. build.parser= ${src.java.dir}/org/apache/velocity/runtime/parser # Running the tests test.haltonerror= true test.haltonfailure= true # Needs to be configured with system location of Bundlor for bundlor task # If you wish to skip this, set no.osgi=true (DO NOT SKIP FOR RELEASES) bundlor.home=*unset* # Needs to be configured with system location of findbugs for findbugs task findbugs.home=*unset* # Needs to be configured with system location of PMD for pmd task pmd.home=*unset* # Building the distribution dist.root= ${build.dir}/dist dist.dir= ${dist.root}/${final.name} # distribution properties publish.server=people.apache.org publish.dir=~/public_html/velocity/engine/${version} # required Java version for building the distribution (with "ant release") # should be major distribution (e.g. 1.4) will match property ${ant.java.version} dist.required.java.version = 1.4 # Set to "project.xml" for distribution and "project-website.xml" # when building docs for web site docs.project= project.xml # Set to Sun Javadocs javadocs.ref.jsdk= http://java.sun.com/j2se/1.4.2/docs/api/ # ####################################################################### # # Downloading jars from ibiblio repository # # ####################################################################### # The default behaviour is to download dependency jars only when # they are not already present. # Set skip.jar.loading to true to never download any dependency jar, # or force.jar.loading to true to always download all dependency jars. skip.jar.loading= false force.jar.loading= false # # Settings for the proxy to use for download. Change this if you must # use a proxy from your host. If the proxy.host property is unset, no # proxy is used. proxy.host= proxy.port= 80 # # We download directly from the ibiblio maven repository repo.m1.url= http://www.ibiblio.org/maven repo.m2.url=http://www.ibiblio.org/maven2 # # Jars to be downloaded jar.antlr.version= 2.7.5 jar.avalon-logkit.version= 2.1 jar.commons-collections.version= 3.2.1 jar.commons-lang.version= 2.4 jar.commons-logging.version= 1.1 jar.jdom.version= 1.0 jar.log4j.version= 1.2.12 jar.oro.version= 2.0.8 jar.servletapi.version= 2.3 jar.werken-xpath.version= 0.9.4 jar.hsqldb.version= 1.7.1 jar.junit.version= 3.8.1 jar.maven.ant.version=2.0.9 ######################################################################## # Maven settings maven.pom=${velocity.dir}/pom.xml maven.build.dir= ${build.dir}/maven wagon-ssh.version=1.0-beta-2 # POM distributionManagement is used if this is not set #maven.remote.repository= ######################################################################## # Gump wants to override these names, so make # it configurable... # jar.oro.name= oro jar.commons-collections.name= commons-collections jar.commons-lang.name = commons-lang jar.oro.dir= ${build.lib} jar.commons-collections.dir= ${build.lib} jar.commons-lang.dir= ${build.lib} # ######################################################################## javac.target=1.4 javac.source=1.4 ######################################################################## # OSGi stuff import=com.werken.xpath;resolution:=optional,\ javax.naming,\ javax.servlet;resolution:=optional,\ javax.servlet.http;resolution:=optional,\ javax.sql,\ org.apache.commons.collections,\ org.apache.commons.collections.map,\ org.apache.commons.lang,\ org.apache.commons.lang.builder,\ org.apache.commons.lang.text,\ org.apache.commons.logging;resolution:=optional,\ org.apache.log;resolution:=optional,\ org.apache.log.format;resolution:=optional,\ org.apache.log.output.io;resolution:=optional,\ org.apache.log4j;resolution:=optional,\ org.apache.oro.text.perl;resolution:=optional,\ org.apache.tools.ant;resolution:=optional,\ org.apache.tools.ant.taskdefs;resolution:=optional,\ org.jdom;resolution:=optional,\ org.jdom.input;resolution:=optional,\ org.jdom.output;resolution:=optional,\ org.xml.sax dep.import=com.werken.xpath;resolution:=optional,\ javax.naming,\ javax.servlet;resolution:=optional,\ javax.servlet.http;resolution:=optional,\ javax.sql,\ org.apache.commons.logging;resolution:=optional,\ org.apache.log;resolution:=optional,\ org.apache.log.format;resolution:=optional,\ org.apache.log.output.io;resolution:=optional,\ org.apache.log4j;resolution:=optional,\ org.apache.tools.ant;resolution:=optional,\ org.apache.tools.ant.taskdefs;resolution:=optional,\ org.jdom;resolution:=optional,\ org.jdom.input;resolution:=optional,\ org.jdom.output;resolution:=optional,\ org.xml.sax export=org.apache.velocity;uses:="org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime.resource",\ org.apache.velocity.anakia;uses:="com.werken.xpath,\ org.apache.tools.ant,\ org.apache.tools.ant.taskdefs,\ org.jdom,\ org.jdom.output",\ org.apache.velocity.app;uses:="org.apache.commons.collections,\ org.apache.velocity,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.log",\ org.apache.velocity.app.event;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.util.introspection",\ org.apache.velocity.app.event.implement;uses:="org.apache.velocity.app.event,\ org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.util,\ org.apache.velocity.util.introspection",\ org.apache.velocity.app.tools;uses:="org.apache.velocity.context",\ org.apache.velocity.context;uses:="org.apache.velocity.app.event,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.util.introspection",\ org.apache.velocity.convert,\ org.apache.velocity.exception;uses:="org.apache.velocity.runtime.parser,\ org.apache.velocity.util.introspection",\ org.apache.velocity.io,\ org.apache.velocity.runtime;uses:="org.apache.commons.collections,\ org.apache.velocity,\ org.apache.velocity.app.event,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.defaults,\ org.apache.velocity.runtime.directive;uses:="org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.runtime.log;uses:="org.apache.log.format,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.parser;uses:="org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.runtime.parser.node;uses:="org.apache.commons.lang.text,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.resource;uses:="org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.resource.loader",\ org.apache.velocity.runtime.resource.loader;uses:="javax.sql,\ org.apache.commons.collections,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.runtime.resource.util",\ org.apache.velocity.runtime.resource.util,\ org.apache.velocity.runtime.visitor;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.servlet;uses:="javax.servlet,\ javax.servlet.http,\ org.apache.velocity,\ org.apache.velocity.context,\ org.apache.velocity.exception",\ org.apache.velocity.texen;uses:="org.apache.velocity,\ org.apache.velocity.app,\ org.apache.velocity.context",\ org.apache.velocity.texen.ant;uses:="org.apache.commons.collections,\ org.apache.tools.ant,\ org.apache.velocity.context",\ org.apache.velocity.texen.defaults,\ org.apache.velocity.texen.util,\ org.apache.velocity.util;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util.introspection",\ org.apache.velocity.util.introspection;uses:="org.apache.velocity.runtime,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util" dep.export=org.apache.commons.collections,\ org.apache.commons.collections.iterators;uses:="org.apache.commons.collections",\ org.apache.commons.collections.map;uses:="org.apache.commons.collections",\ org.apache.commons.lang;uses:="org.apache.commons.lang.exception",\ org.apache.commons.lang.builder,\ org.apache.commons.lang.enum,\ org.apache.commons.lang.enums,\ org.apache.commons.lang.exception,\ org.apache.commons.lang.math,\ org.apache.commons.lang.mutable,\ org.apache.commons.lang.text,\ org.apache.commons.lang.time,\ org.apache.oro.io;uses:="org.apache.oro.text,\ org.apache.oro.text.regex",\ org.apache.oro.text;uses:="org.apache.oro.text.regex,\ org.apache.oro.util",\ org.apache.oro.text.awk;uses:="org.apache.oro.text.regex",\ org.apache.oro.text.perl;uses:="org.apache.oro.text,\ org.apache.oro.text.regex",\ org.apache.oro.text.regex,\ org.apache.oro.util,\ org.apache.velocity;uses:="org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime.resource",\ org.apache.velocity.anakia;uses:="com.werken.xpath,\ org.apache.tools.ant,\ org.apache.tools.ant.taskdefs,\ org.jdom,\ org.jdom.output",\ org.apache.velocity.app;uses:="org.apache.commons.collections,\ org.apache.velocity,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.log",\ org.apache.velocity.app.event;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.util.introspection",\ org.apache.velocity.app.event.implement;uses:="org.apache.velocity.app.event,\ org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.util,\ org.apache.velocity.util.introspection",\ org.apache.velocity.app.tools;uses:="org.apache.velocity.context",\ org.apache.velocity.context;uses:="org.apache.velocity.app.event,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.util.introspection",\ org.apache.velocity.convert,\ org.apache.velocity.exception;uses:="org.apache.velocity.runtime.parser,\ org.apache.velocity.util.introspection",\ org.apache.velocity.io,\ org.apache.velocity.runtime;uses:="org.apache.commons.collections,\ org.apache.velocity,\ org.apache.velocity.app.event,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.defaults,\ org.apache.velocity.runtime.directive;uses:="org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.runtime.log;uses:="org.apache.log.format,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.parser;uses:="org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.directive,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.runtime.parser.node;uses:="org.apache.commons.lang.text,\ org.apache.velocity.context,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser,\ org.apache.velocity.util.introspection",\ org.apache.velocity.runtime.resource;uses:="org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.resource.loader",\ org.apache.velocity.runtime.resource.loader;uses:="javax.sql,\ org.apache.commons.collections,\ org.apache.velocity.exception,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.resource,\ org.apache.velocity.runtime.resource.util",\ org.apache.velocity.runtime.resource.util,\ org.apache.velocity.runtime.visitor;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime.parser.node",\ org.apache.velocity.servlet;uses:="javax.servlet,\ javax.servlet.http,\ org.apache.velocity,\ org.apache.velocity.context,\ org.apache.velocity.exception",\ org.apache.velocity.texen;uses:="org.apache.velocity,\ org.apache.velocity.app,\ org.apache.velocity.context",\ org.apache.velocity.texen.ant;uses:="org.apache.commons.collections,\ org.apache.tools.ant,\ org.apache.velocity.context",\ org.apache.velocity.texen.defaults,\ org.apache.velocity.texen.util,\ org.apache.velocity.util;uses:="org.apache.velocity.context,\ org.apache.velocity.runtime,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util.introspection",\ org.apache.velocity.util.introspection;uses:="org.apache.velocity.runtime,\ org.apache.velocity.runtime.log,\ org.apache.velocity.runtime.parser.node,\ org.apache.velocity.util" velocity-1.7/build/testcases.xml0000644000175000017500000001625410513464370016731 0ustar moellermoeller velocity-1.7/build/build.xml0000644000175000017500000016032011355456247016035 0ustar moellermoeller **************************************************************************** ** ** help is no longer supported. Please run 'ant -projecthelp' ** *************************************************************************** Global settings: java.home = ${java.home} user.home = ${user.home} java.class.path = ${java.class.path} Velocity settings: Version: ${version} Debug: ${debug} Optimize: ${optimize} Deprecation: ${deprecation} Target settings (relative to build tree root): Velocity Source: ${build.src} Velocity Classes: ${build.dest} Velocity API Docs: ${build.javadoc} Velocity Docs: ${build.docs} Velocity Test Reports: ${build.test.reports} ******************************************************** ** ** The javax.sql.Datasource class has not been found on ** your classpath. This means that your newly built ** Velocity jar will not contain the JDBC based resource ** loaders. If this is a problem, please use a JDK for ** building that contains the javax.sql.Datasource class. ** ******************************************************** ******************************************************** ** ** The java.util.logging.Logger class has not been found on your ** classpath. This means that your newly built Velocity jar will ** not contain JDK 1.4 compatible logging code. If this is a ** problem, please use a 1.4 or newer JDK for building. ** ******************************************************** Could not run javacc: *********************************************************** ** You have not configured your JavaCC installation ** location in the javacc.home property. *********************************************************** Could not run javacc: *********************************************************** ** ** JavaCC 3.2 or later must be installed at ${javacc.home}. ** Ant must be at least version 1.6.x. ** *********************************************************** *********************************************************** ** Creating Parser.jj and Parser.java in source tree. ** ** Note: ASTNode files generated by jjtree are ** not generated with this task. To create new ASTNode files, ** run jjtree manually then copy the relevant files into ** the runtime/parser/node directory (deleting all other ** generated files). ** *********************************************************** This build will be made ready for use with OSGi, so long as you configure the "bundlor.home" property. You can download Bundlor from: http://www.springsource.org/bundlor Or you can disable this part of the build by setting "no.osgi" to true in your properties. (Do not do this for releases!) This build is not be ready for use with OSGi, unless you add the "build.osgi" property and configure the "bundlor.home" property to point to the Bundlor resources. You can download Bundlor from: http://www.springsource.org/bundlor ************************************************************** ** Building the examples : ** examples/app_example1 : application example ** examples/app_example2 : application example ** examples/context_example : example context implementations ** examples/logger_example : how to make an external logger ** examples/xmlapp_example : how to access XML data in a template ** examples/event_example : how to use Velocity's event handlers ************************************************************** Deploying to ${maven.remote.repository} Deploying to Apache Maven repository ***** RELEASE INSTRUCTIONS ***** * Be sure you can answer "yes" to the following: * Was your local code up to date and free of modifications or extra files? * Was the version number correct in both build.properties and pom.xml? * For a final release, the distributionManagement.site.url value in the pom.xml should be: scpexe://people.apache.org/www/velocity.apache.org/engine/releases/velocity-${version} and for alpha or beta releases it should be: scpexe://people.apache.org/www/velocity.apache.org/engine/devel/ * Do all new files have the Apache License? (use "ant rat" to double-check) * Is ${build.src}/changes/changes.xml up to date? Feel free to set an estimated release date for this version in that file; it can be corrected later if the release is delayed. * Is ${build.src}/site/apt/upgrading.apt up to date for this release? * Is the ${velocity.dir}/README.txt up to date for this release? * If a final release, update the "Where do I get releases?" section of ${build.dir}/xdocs/docs/index.xml to show the latest stable version number. * Write down the current svn revision so you don't have to look it up later when you make the tag for this release (post-vote). * Go to ${build.dir} and sign all the jar, zip, tar.gz and pom files with your personal PGP key using a script like this: #! /bin/bash for i in *.tar.gz *.zip *jar; do gpg --armor --output $i.asc --detach-sig $i done * SSH into people.apache.org and make sure that this directory exists: ${publish.dir} * If you haven't done it before, ensure that your PGP key is appended to /www/www.apache.org/dist/velocity/KEYS Some instructions for that are at the top of that file. * Call "ant publish" * Review http://wiki.apache.org/velocity/ReleaseProcess for more details. Could not run create distribution package: *********************************************************** ** ** In order to create a distribution package, you must be ** using Java version ${dist.required.java.version} instead ** of Java version ${java.version} ** *********************************************************** *********************************************************** ** ** Creating a distribution package. Compiling with ** Java version ${java.version} ** *********************************************************** ####################################################### # # Now using Anakia to transform the XML documentation # to HTML. # # using project file: ${docs.project} # # Note: set property "docs.project" to "project.xml" # for distribution and "project-website.xml" for # website. ####################################################### !!NOT READY TO PUBLISH!! You must first execute "release" target, then sign the distribution files with your pgp key (creating the needed '.asc'signature files). To override this (only when uploading development snapshots not meant for public release), add the property "release.signed=true" to your build.properties. You may also need to add the Jsch jar to Ant's classpath to enable the optional 'scp' task. Uploading distribution files from ${build.dir} to ${username}:${password}@${publish.server}:${publish.dir} ***** RELEASE INSTRUCTIONS ***** * SSH to ${publish.server} and verify the checksums and signatures of the uploaded files with a script like: #!/bin/csh foreach fn ( *.tar.gz *.zip *.jar *.pom ) echo Verifying $fn... echo GPG signature should be "Good" gpg --verify $fn.asc echo MD5s should be identical cat $fn.md5 md5 -q $fn echo SHA1s should be identical cat $fn.sha1 sha1 -q $fn echo end * Announce the availability of an Engine ${version} test build on dev@velocity.apache.org. * Allow a few days for people to test the test build. * Call for a release vote on private@velocity.apache.org and dev@velocity.apache.org * Once the release vote has passed, these files should all be copied to /www/www.apache.org/dist/velocity/engine/${version} and the non-dep jar, source jar, javadoc jar, pom and respective md5, sha1 and asc files should be copied into /www/people.apache.org/repo/m2-ibiblio-rsync-repository/org/apache/velocity/velocity/${version}/ * Remove older releases of the same grade as this one (alpha, beta, final) from /www/www.apache.org/dist/velocity/engine * Tag the release in SVN with a command such as: svn copy -m "Release Engine ${version}" -r [revision #] \ https://svn.apache.org/repos/asf/velocity/engine/trunk \ https://svn.apache.org/repos/asf/velocity/engine/tags/${version} * Go to ${velocity.dir} and run "mvn site" then "mvn site:deploy" to publish the documentation for this release on the website * Wait a day or so for the mirrors and maven repos to sync up. * Update the main website (velocity-site project) with the release info: * Add this ${version} release to news.xml, download.xml, doap_engine.rdf and the "Release status" section of index.xml * Check those changes into SVN * Email Henning to have him update and build the site from velocity.zones.apache.org (or get velocity-site to work for other people besides Henning) * Wait a few hours for the site to sync up. * Send an announcement email from your apache.org address to all Velocity lists and also to announce@apache.org. * Review http://wiki.apache.org/velocity/ReleaseProcess for more details. Could not run junit tests: *********************************************************** ** ** Ant must be at least version 1.7 ** *********************************************************** NOTE: At this time, you must add Apache RAT, Apache RAT AntTasks Commons-Lang, Commons-Collections and Commons-CLI to Ant's lib directory to use this. Your RAT report is here: ${build.test.reports}/rat-report.txt Working with FindBugs at: ${findbugs.home} Analyzing ${build.dir}/${final.name}.jar built from ${build.src} Analyzing ${build.src}... unusedcode imports Generated report is at ${build.test.reports}\pmd_report.html velocity-1.7/test/0000755000175000017500000000000011675166244014072 5ustar moellermoellervelocity-1.7/test/parsemacros/0000755000175000017500000000000011675166243016410 5ustar moellermoellervelocity-1.7/test/parsemacros/parseMacro2.vm0000644000175000017500000000002210663062343021114 0ustar moellermoeller#foo(1) #bar(2) velocity-1.7/test/parsemacros/parseMacro3.vm0000644000175000017500000000010410673652637021132 0ustar moellermoeller#parse("vm_library1.vm") #parse("vm_library2.vm") #foo(1) #bar(2) velocity-1.7/test/parsemacros/compare/0000755000175000017500000000000011675166243020036 5ustar moellermoellervelocity-1.7/test/parsemacros/compare/parseMacro1_3b.cmp0000644000175000017500000000000610663062343023264 0ustar moellermoeller 8 6 velocity-1.7/test/parsemacros/compare/parseMacro1_4b.cmp0000644000175000017500000000000610663062343023265 0ustar moellermoeller 8 6 velocity-1.7/test/parsemacros/compare/parseMacro1_1.cmp0000644000175000017500000000000610663062343023120 0ustar moellermoeller 2 4 velocity-1.7/test/parsemacros/compare/parseMacro1_2.cmp0000644000175000017500000000000610663062343023121 0ustar moellermoeller 2 4 velocity-1.7/test/parsemacros/compare/parseMacro2.cmp0000644000175000017500000000002210663062343022677 0ustar moellermoeller#foo(1) #bar(2) velocity-1.7/test/parsemacros/compare/parseMacro1_1b.cmp0000644000175000017500000000000610663062343023262 0ustar moellermoeller 8 6 velocity-1.7/test/parsemacros/compare/parseMacro1_3.cmp0000644000175000017500000000000610663062343023122 0ustar moellermoeller 2 4 velocity-1.7/test/parsemacros/compare/parseMacro3.cmp0000644000175000017500000000000710673652637022717 0ustar moellermoeller 8 6 velocity-1.7/test/parsemacros/compare/parseMacro1_2b.cmp0000644000175000017500000000000610663062343023263 0ustar moellermoeller 8 6 velocity-1.7/test/parsemacros/compare/parseMacro1_4.cmp0000644000175000017500000000000610663062343023123 0ustar moellermoeller 2 4 velocity-1.7/test/parsemacros/vm_library1.vm0000644000175000017500000000015010663062343021167 0ustar moellermoeller#macro(bar $a) #if($a)#set($a = $a + $a)$a#end #end #macro(foo $a) #if($a)#set($a = $a + 1)$a#end #end velocity-1.7/test/parsemacros/vm_library2.vm0000644000175000017500000000015710663062343021177 0ustar moellermoeller#macro( bar $a) #if($a)#set($a = $a + $a + $a)$a#end #end #macro( foo $a) #if($a)#set($a = $a * 8)$a#end #end velocity-1.7/test/parsemacros/parseMacro1.vm0000644000175000017500000000004710663062343021122 0ustar moellermoeller#parse($includefile) #foo(1) #bar(2) velocity-1.7/test/multiloader/0000755000175000017500000000000011675166243016412 5ustar moellermoellervelocity-1.7/test/multiloader/compare/0000755000175000017500000000000011675166243020040 5ustar moellermoellervelocity-1.7/test/multiloader/compare/test2.cmp0000644000175000017500000000004707255707541021604 0ustar moellermoeller this is a template for test1.jar velocity-1.7/test/multiloader/compare/test3.cmp0000644000175000017500000000004707300225714021571 0ustar moellermoeller this is a template for test2.jar velocity-1.7/test/multiloader/compare/path1.cmp0000644000175000017500000000002007255707541021547 0ustar moellermoeller I am path1.vm velocity-1.7/test/multiloader/test1.jar0000644000175000017500000000112607255514616020150 0ustar moellermoellerPK‰e* META-INF/þÊPKPK‰e*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK ãˆe* template/PKɈe*template/test1.vmãâ*ÉÈ,V¢D…’ÔÜ‚œÄ’T…´ü" §¸ÄP/+±H¸PK¶‚$'PK‰e* META-INF/þÊPK‰e*3ù5¤DD=META-INF/MANIFEST.MFPK ãˆe* Ãtemplate/PKɈe*¶‚$'êtemplate/test1.vmPKóMvelocity-1.7/test/multiloader/test2.jar0000644000175000017500000000112607300225573020141 0ustar moellermoellerPK ?¯* META-INF/þÊPKPK ?¯*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK ?¯* template/PK?¯*template/test2.vmãâ*ÉÈ,V¢D…’ÔÜ‚œÄ’T…´ü" §¸ÄH/+±H¸PK µï$'PK ?¯* META-INF/þÊPK ?¯*3ù5¤DD=META-INF/MANIFEST.MFPK ?¯* Ãtemplate/PK?¯* µï$'êtemplate/test2.vmPKóMvelocity-1.7/test/multiloader/path1.vm0000644000175000017500000000034710315733667017777 0ustar moellermoeller#* @test path1.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# I am path1.vm velocity-1.7/test/texen/0000755000175000017500000000000011675166243015214 5ustar moellermoellervelocity-1.7/test/texen/license.txt0000644000175000017500000000145510513464370017374 0ustar moellermoeller/* * 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. */ velocity-1.7/test/texen/service.props0000644000175000017500000000206310513464370017732 0ustar moellermoellerbaseName=Weather package=org.apache.turbine.services.weather name=Jason van Zyl email=jvanzyl@apache.org # 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. license.file.contents = test/texen/license.txt # Test some properties that have be give some boolean # values. one = true two = yes three = on four = false five = no six = off velocity-1.7/test/texen/compare/0000755000175000017500000000000011675166243016642 5ustar moellermoellervelocity-1.7/test/texen/compare/WeatherService.java0000644000175000017500000000215510513464370022420 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.Service; /** * * @author Jason van Zyl * @occupation somnambulist */ public interface WeatherService extends Service { public static final String SERVICE_NAME = "TurbineWeatherService"; } velocity-1.7/test/texen/compare/TurbineWeather.java0000644000175000017500000000254310513464370022431 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.TurbineServices; /** * * * @author Jason van Zyl * @occupation somnambulist */ public class TurbineWeather { /** * Utility method for accessing the service * implementation * * @return a WeatherService implementation instance */ protected static WeatherService getService() { return (WeatherService)TurbineServices .getInstance().getService(WeatherService.SERVICE_NAME); } } velocity-1.7/test/texen/compare/book.txt0000644000175000017500000000046210315733667020337 0ustar moellermoellerThis is the book of the week: Props retrieved using new method: Title: Consilience: The Unity of Knowledge Author: Edward O. Wilson Publisher: Knopf ISBN: 0965058305 Props retrieved using old method: Title: Consilience: The Unity of Knowledge Author: Edward O. Wilson Publisher: Knopf ISBN: 0965058305 velocity-1.7/test/texen/compare/TurbineWeatherService.java0000644000175000017500000000232610513464370023751 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.TurbineBaseService; /** * * @author Jason van Zyl * @occupation somnambulist */ public class TurbineWeatherService extends TurbineBaseService implements WeatherService { /** * Initialize the TurbineWeather Service. */ public void init() { setInit(true); } } velocity-1.7/test/texen/compare/Test.txt0000644000175000017500000000015510315733667020323 0ustar moellermoeller# These should all evaluate to true true true true # These should all evaluate to false false false false velocity-1.7/test/texen/additional.props0000644000175000017500000000145510513464370020406 0ustar moellermoeller# 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. occupation=somnambulist velocity-1.7/test/texen/templates/0000755000175000017500000000000011675166243017212 5ustar moellermoellervelocity-1.7/test/texen/templates/Test.vm0000644000175000017500000000015610315733667020477 0ustar moellermoeller# These should all evaluate to true $one $two $three # These should all evaluate to false $four $five $six velocity-1.7/test/texen/templates/Control.vm0000644000175000017500000000164710315733667021206 0ustar moellermoeller#set ( $sourceFile = "Turbine${baseName}Service.java" ) $generator.parse("ServiceImplementation.vm",$sourceFile) #set ( $sourceFile = "${baseName}Service.java" ) $generator.parse("ServiceInterface.vm",$sourceFile) #set ( $sourceFile = "Turbine${baseName}.java" ) $generator.parse("ServiceStaticHelper.vm",$sourceFile) #set ( $sourceFile = "Test.txt" ) $generator.parse("Test.vm",$sourceFile) #set ( $props = $properties.load("test.props") ) ## This is to test a properties file that was once taken from ## the file system but is now taken from a JAR. We have to ## deprecate the use of $generator.TemplatePath if we want ## templates to work the same way from JARs and the file ## system. I have a hack in PropsUtil right now to deal ## with it. #set ( $props2 = $properties.load("$generator.TemplatePath/test.props") ) $generator.TemplatePath/test.props #set ( $sourceFile = "book.txt" ) $generator.parse("book.vm",$sourceFile) velocity-1.7/test/texen/templates/test.props0000644000175000017500000000157710513464370021260 0ustar moellermoeller# 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. author = Edward O. Wilson title = Consilience: The Unity of Knowledge publisher = Knopf isbn = 0965058305 velocity-1.7/test/texen/templates/ServiceInterface.vm0000644000175000017500000000044010315733667022775 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.Service; /** * * @author $name * @occupation $occupation */ public interface ${baseName}Service extends Service { public static final String SERVICE_NAME = "Turbine${baseName}Service"; } velocity-1.7/test/texen/templates/ServiceImplementation.vm0000644000175000017500000000061510315733667024066 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.TurbineBaseService; /** * * @author $name * @occupation $occupation */ public class Turbine${baseName}Service extends TurbineBaseService implements ${baseName}Service { /** * Initialize the Turbine${baseName} Service. */ public void init() { setInit(true); } } velocity-1.7/test/texen/templates/ServiceStaticHelper.vm0000644000175000017500000000104010315733667023461 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.TurbineServices; /** * * * @author $name * @occupation $occupation */ public class Turbine$baseName { /** * Utility method for accessing the service * implementation * * @return a ${baseName}Service implementation instance */ protected static ${baseName}Service getService() { return (${baseName}Service)TurbineServices .getInstance().getService(${baseName}Service.SERVICE_NAME); } } velocity-1.7/test/texen/templates/book.vm0000644000175000017500000000052210315733667020507 0ustar moellermoellerThis is the book of the week: Props retrieved using new method: Title: $props.get("title") Author: $props.get("author") Publisher: $props.get("publisher") ISBN: $props.get("isbn") Props retrieved using old method: Title: $props2.get("title") Author: $props2.get("author") Publisher: $props2.get("publisher") ISBN: $props2.get("isbn") velocity-1.7/test/anakia/0000755000175000017500000000000011675166243015315 5ustar moellermoellervelocity-1.7/test/anakia/xdocs/0000755000175000017500000000000011675166243016435 5ustar moellermoellervelocity-1.7/test/anakia/xdocs/index.xml0000644000175000017500000000316110513464370020257 0ustar moellermoeller Jon S. Stevens The Jakarta Project

This is an example template that gets processed.

It even has a table in it!

And an h3 tag

here is another section

A link to a sub page

velocity-1.7/test/anakia/xdocs/stylesheets/0000755000175000017500000000000011675166243021011 5ustar moellermoellervelocity-1.7/test/anakia/xdocs/stylesheets/project.xml0000644000175000017500000000226010513464370023171 0ustar moellermoeller Jakarta Site velocity-1.7/test/anakia/xdocs/stylesheets/site.vsl0000644000175000017500000000735410513464370022504 0ustar moellermoeller## 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. ## Defined variables #set ($bodybg = "#ffffff") #set ($bodyfg = "#000000") #set ($bodylink = "#525D76") #set ($bannerbg = "#525D76") #set ($bannerfg = "#ffffff") #set ($tablethbg = "#039acc") #set ($tabletdbg = "#a0ddf0") #document() ## This is where the macro's live #macro ( makeProject ) #set ($menus = $xpath.applyTo("body/menu", $project)) #foreach ( $menu in $menus ) $menu.getAttributeValue("name") #end #end #macro ( image $value ) #if ($value.getAttributeValue("width")) #set ($width=$value.getAttributeValue("width")) #end #if ($value.getAttributeValue("height")) #set ($height=$value.getAttributeValue("height")) #end #if ($value.getAttributeValue("align")) #set ($align=$value.getAttributeValue("align")) #end #end #macro ( projectanchor $name $value ) $name #end #macro ( metaauthor $author $email ) #end #macro (document) ## set ($au = $root.getChild("properties").getChild("author").getText()) ## set ($em = $root.getChild("properties").getChild("author").getAttributeValue("email")) #metaauthor ( $au.getText() $em.getValue() ) $root.getChild("properties").getChild("title").getText()
#makeProject() ## set ($allSections = $root.getChild("body").getChildren("section")) #set ($allSections = $xpath.applyTo("body/section", $root)) #foreach ( $section in $allSections ) #foreach ( $item in $section.getChildren() ) #if ($item.getName().equals("img")) #image ($item) #else $xmlout.outputString($item) #end #end #end
#end velocity-1.7/test/anakia/xdocs/stylesheets/customContext.xml0000644000175000017500000000217310513464370024405 0ustar moellermoeller velocity-1.7/test/anakia/xdocs/stylesheets/site_contexts.vsl0000644000175000017500000000756310513464370024435 0ustar moellermoeller## 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. ## Defined variables #set ($bodybg = "#ffffff") #set ($bodyfg = "#000000") #set ($bodylink = "#525D76") #set ($bannerbg = "#525D76") #set ($bannerfg = "#ffffff") #set ($tablethbg = "#039acc") #set ($tabletdbg = "#a0ddf0") #document() ## This is where the macro's live #macro ( makeProject ) #set ($menus = $xpath.applyTo("body/menu", $project)) #foreach ( $menu in $menus ) $menu.getAttributeValue("name") #end #set ($customMenus = $xpath.applyTo("body/menu",$customContext)) #foreach($customMenu in $customMenus) $customMenu.getAttributeValue("name") #end #end #macro ( image $value ) #if ($value.getAttributeValue("width")) #set ($width=$value.getAttributeValue("width")) #end #if ($value.getAttributeValue("height")) #set ($height=$value.getAttributeValue("height")) #end #if ($value.getAttributeValue("align")) #set ($align=$value.getAttributeValue("align")) #end #end #macro ( projectanchor $name $value ) $name #end #macro ( metaauthor $author $email ) #end #macro (document) #metaauthor ( $au.getText() $em.getValue() ) $root.getChild("properties").getChild("title").getText()
#makeProject() #set ($allSections = $xpath.applyTo("body/section", $root)) #foreach ( $section in $allSections ) #foreach ( $item in $section.getChildren() ) #if ($item.getName().equals("img")) #image ($item) #else $xmlout.outputString($item) #end #end #end
#end velocity-1.7/test/anakia/compare/0000755000175000017500000000000011675166243016743 5ustar moellermoellervelocity-1.7/test/anakia/compare/index.html0000644000175000017500000000611610513464370020734 0ustar moellermoeller The Jakarta Project
Home About

This is an example template that gets processed.

It even has a table in it!

And an h3 tag

here is another section

A link to a sub page

velocity-1.7/test/anakia/compare/index.context.html0000644000175000017500000000504510256120454022413 0ustar moellermoeller The Jakarta Project
Home About Other Context Other About

This is an example template that gets processed.

It even has a table in it!

And an h3 tag

here is another section

A link to a sub page

velocity-1.7/test/anakia/velocity.properties0000644000175000017500000000142510513464370021263 0ustar moellermoeller# 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. velocity-1.7/test/stop/0000755000175000017500000000000011675166243015056 5ustar moellermoellervelocity-1.7/test/stop/stop1.vm0000644000175000017500000000005611130150630016444 0ustar moellermoellerText 1#stop Text 2 ## We should not see this velocity-1.7/test/stop/stop2.vm0000644000175000017500000000002611130150630016442 0ustar moellermoellerText123#test1() stuff velocity-1.7/test/stop/stop3.vm0000644000175000017500000000003511130150630016443 0ustar moellermoellertext1#parse("parse.vm")text2 velocity-1.7/test/stop/parse.vm0000644000175000017500000000002211130150630016501 0ustar moellermoellerblaa1#{stop}blaa2 velocity-1.7/test/stop/vmlib1.vm0000644000175000017500000000004711130150630016570 0ustar moellermoeller#macro(test1) stuff1#{stop}stuff2 #end velocity-1.7/test/includeevent/0000755000175000017500000000000011675166243016556 5ustar moellermoellervelocity-1.7/test/includeevent/test1.vm0000644000175000017500000000007310315733667020162 0ustar moellermoellerTest File 1 #include("include-a.vm") #parse("parse-a.vm") velocity-1.7/test/includeevent/include-a.vm0000644000175000017500000000001610315733667020760 0ustar moellermoellerinclude file avelocity-1.7/test/includeevent/include-b.vm0000644000175000017500000000002210315733667020756 0ustar moellermoellerBAD include file bvelocity-1.7/test/includeevent/test3.vm0000644000175000017500000000007310315733667020164 0ustar moellermoellerTest File 3 #include("include-a.vm") #parse("parse-a.vm") velocity-1.7/test/includeevent/include-c.vm0000644000175000017500000000002310506300334020737 0ustar moellermoellerGood include file cvelocity-1.7/test/includeevent/test4.vm0000644000175000017500000000004410315733667020163 0ustar moellermoellerTest File 4 #include("include4.vm") velocity-1.7/test/includeevent/test5.vm0000644000175000017500000000004410315733667020164 0ustar moellermoellerTest File 5 #include("include5.vm") velocity-1.7/test/includeevent/test6.vm0000644000175000017500000000010110503223030020130 0ustar moellermoellerBad include follows #include("badfile.vm") After the bad include velocity-1.7/test/includeevent/compare/0000755000175000017500000000000011675166243020204 5ustar moellermoellervelocity-1.7/test/includeevent/compare/test2.cmp0000644000175000017500000000013510506300334021724 0ustar moellermoellerTest File 2 Good include file b Good parse file b Good include file c Good parse file c velocity-1.7/test/includeevent/compare/test3.cmp0000644000175000017500000000001710311127224021723 0ustar moellermoellerTest File 3 velocity-1.7/test/includeevent/compare/test4.cmp0000644000175000017500000000004410311127224021724 0ustar moellermoellerTest File 4 page not found (subdir)velocity-1.7/test/includeevent/compare/test5.cmp0000644000175000017500000000003310311127224021723 0ustar moellermoellerTest File 5 page not foundvelocity-1.7/test/includeevent/compare/test6.cmp0000644000175000017500000000007010631156765021746 0ustar moellermoellerBad include follows page not foundAfter the bad include velocity-1.7/test/includeevent/compare/test7.cmp0000644000175000017500000000003311273710244021735 0ustar moellermoellerTest File 7 #sample("boo")velocity-1.7/test/includeevent/compare/test1.cmp0000644000175000017500000000005110311127224021717 0ustar moellermoellerTest File 1 include file a parse file avelocity-1.7/test/includeevent/test7.vm0000644000175000017500000000005711273710244020160 0ustar moellermoellerTest File 7 #parse("macros.vm") #sample("boo")velocity-1.7/test/includeevent/include4.vm0000644000175000017500000000002610315733667020627 0ustar moellermoellershould not be includedvelocity-1.7/test/includeevent/subdir/0000755000175000017500000000000011675166243020046 5ustar moellermoellervelocity-1.7/test/includeevent/subdir/test2.vm0000644000175000017500000000015510506300334021433 0ustar moellermoellerTest File 2 #include("include-b.vm") #parse("parse-b.vm") #include("/include-c.vm") #parse("/parse-c.vm") velocity-1.7/test/includeevent/subdir/include-b.vm0000644000175000017500000000002310315733667022247 0ustar moellermoellerGood include file bvelocity-1.7/test/includeevent/subdir/include-c.vm0000644000175000017500000000002310506300334022227 0ustar moellermoellerBAD include file c velocity-1.7/test/includeevent/subdir/include4.vm0000644000175000017500000000003710315733667022121 0ustar moellermoellershould not be included (subdir)velocity-1.7/test/includeevent/subdir/include5.vm0000644000175000017500000000003710315733667022122 0ustar moellermoellershould not be included (subdir)velocity-1.7/test/includeevent/subdir/parse-b.vm0000644000175000017500000000002110315733667021734 0ustar moellermoellerGood parse file bvelocity-1.7/test/includeevent/subdir/parse-c.vm0000644000175000017500000000002110506300334021714 0ustar moellermoellerBAD parse file c velocity-1.7/test/includeevent/subdir/notfound.vm0000644000175000017500000000002710315733667022245 0ustar moellermoellerpage not found (subdir)velocity-1.7/test/includeevent/include5.vm0000644000175000017500000000002610315733667020630 0ustar moellermoellershould not be includedvelocity-1.7/test/includeevent/macros.vm0000644000175000017500000000005411273710244020373 0ustar moellermoeller#macro(sample $a) do something with $a #endvelocity-1.7/test/includeevent/parse-a.vm0000644000175000017500000000001410315733667020445 0ustar moellermoellerparse file avelocity-1.7/test/includeevent/parse-b.vm0000644000175000017500000000002010315733667020443 0ustar moellermoellerBAD parse file bvelocity-1.7/test/includeevent/parse-c.vm0000644000175000017500000000002210506300334020425 0ustar moellermoellerGood parse file c velocity-1.7/test/includeevent/notfound.vm0000644000175000017500000000001610315733667020753 0ustar moellermoellerpage not foundvelocity-1.7/test/resourceexists/0000755000175000017500000000000011675166243017160 5ustar moellermoellervelocity-1.7/test/resourceexists/testfile.vm0000755000175000017500000000004511053104277021332 0ustar moellermoellerwe're just testing that this exists. velocity-1.7/test/parseexception/0000755000175000017500000000000011675166243017122 5ustar moellermoellervelocity-1.7/test/parseexception/badtemplate.vm0000644000175000017500000000004110324117416021727 0ustar moellermoellerok ok ok ok #set($s) ok okvelocity-1.7/test/multi/0000755000175000017500000000000011675166243015223 5ustar moellermoellervelocity-1.7/test/multi/compare/0000755000175000017500000000000011675166243016651 5ustar moellermoellervelocity-1.7/test/multi/compare/path1.cmp0000644000175000017500000000002007250307473020353 0ustar moellermoeller I am path1.vm velocity-1.7/test/multi/compare/path2.cmp0000644000175000017500000000002007250307473020354 0ustar moellermoeller I am path2.vm velocity-1.7/test/multi/path1/0000755000175000017500000000000011675166243016240 5ustar moellermoellervelocity-1.7/test/multi/path1/path1.vm0000644000175000017500000000034710315733667017625 0ustar moellermoeller#* @test path1.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# I am path1.vm velocity-1.7/test/multi/path2/0000755000175000017500000000000011675166243016241 5ustar moellermoellervelocity-1.7/test/multi/path2/path2.vm0000644000175000017500000000034710315733667017627 0ustar moellermoeller#* @test path2.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# I am path2.vm velocity-1.7/test/set/0000755000175000017500000000000011675166243014664 5ustar moellermoellervelocity-1.7/test/set/compare/0000755000175000017500000000000011675166243016312 5ustar moellermoellervelocity-1.7/test/set/compare/set1.cmp0000644000175000017500000000003710723271545017662 0ustar moellermoellerset1 123 123 foo bar foo bar velocity-1.7/test/set/compare/set2.cmp0000644000175000017500000000006411036444013017651 0ustar moellermoellerset2 123 $abc foo bar foo $map.bar test $test velocity-1.7/test/set/set1.vm0000644000175000017500000000040710723271545016100 0ustar moellermoeller## This template is used for the case in which #set with a null ## is not accepted set1 #set($abc = "123") $abc #set($abc = $boohoo) $abc #set($map = {}) #set($map.foo = "foo") #set($map.bar = "bar") $map.foo $map.bar #set($map.bar = $boohoo) $map.foo $map.bar velocity-1.7/test/set/set2.vm0000644000175000017500000000056611036444013016075 0ustar moellermoeller## This template is used for the case in which #set with a null ## IS accepted set2 #set($abc = "123") $abc #set($abc = $boohoo) $abc #set($map = {}) #set($map.foo = "foo") #set($map.bar = "bar") $map.foo $map.bar #set($map.bar = $boohoo) $map.foo $map.bar ## ## check a macro ## #macro (test) #set ($test = "test") $test #set ($test = $null) $test #end #test() velocity-1.7/test/info/0000755000175000017500000000000011675166243015024 5ustar moellermoellervelocity-1.7/test/info/info1.vm0000644000175000017500000000002210315733667016376 0ustar moellermoeller$main.unknownFieldvelocity-1.7/test/info/info2.vm0000644000175000017500000000002510315733667016402 0ustar moellermoeller$main.unknownMethod()velocity-1.7/test/misc/0000755000175000017500000000000011675166243015024 5ustar moellermoellervelocity-1.7/test/misc/compile.sh0000755000175000017500000000172410513464370017007 0ustar moellermoeller# !/bin/sh # 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. CLASSPATH=.:../../bin/classes for jar in ../../build/lib/*.jar do CLASSPATH=${CLASSPATH}:${jar} done java -cp ${CLASSPATH} org.apache.velocity.runtime.compiler.Compiler $1 velocity-1.7/test/misc/test.sh0000755000175000017500000000173210513464370016335 0ustar moellermoeller# !/bin/sh # 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. CLASSPATH=.:../../bin/classes for jar in ../../build/lib/*.jar do CLASSPATH=${CLASSPATH}:${jar} done java -cp ${CLASSPATH} org.apache.velocity.test.misc.Test $1 $2 > output 2>&1 velocity-1.7/test/misc/README.txt0000644000175000017500000000123410362225112016501 0ustar moellermoeller$Id: README.txt 369043 2006-01-14 16:43:54Z henning $ This directory contains some misc tests for you to ponder over. compile.sh: This script will compile a .vm file into a .class file. Note: at the current time, this code is not working. Usage: ./compile.sh ../templates/test.vm dump.sh: This script will dump out a text representation of the AST. Usage: ./dump.sh ../templates/test.vm test.sh: This script is used for command line testing of .vm files. Note: this script is not a replacement for the engine testing suite. It is simply a convinence script/class for the developers. thanks! - The Velocity Team velocity-1.7/test/misc/dump.sh0000755000175000017500000000174310513464370016325 0ustar moellermoeller# !/bin/sh # 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. CLASSPATH=.:../../bin/classes for jar in ../../build/lib/*.jar do CLASSPATH=${CLASSPATH}:${jar} done java -cp ${CLASSPATH} org.apache.velocity.test.view.TemplateNodeView $1 > output.dump velocity-1.7/test/classloader/0000755000175000017500000000000011675166243016365 5ustar moellermoellervelocity-1.7/test/classloader/Foo.java0000644000175000017500000000247610513464370017754 0ustar moellermoeller/* * 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. */ /** * Simple class Foo to be used in classloader testing * This class should be kept here and not in velocity.jar * to keep out of the parent classloader of the test * classloader */ public class Foo { /* * the ClassloaderChangeTest * depends on this string as * is. If this changes (there is no reason * to ever do that, BTW), then * udpate ClassloaderChangeTest as well. */ private static String MSG = "Hello From Foo"; public String doIt() { return MSG; } } velocity-1.7/test/classloader/Foo.class0000644000175000017500000000056407351235475020144 0ustar moellermoellerÊþº¾-  MSGLjava/lang/String;()VCodeLineNumberTabledoIt()Ljava/lang/String; SourceFileFoo.java  Hello From FooFoojava/lang/Object!   *·± =  ²° K  ³± Fvelocity-1.7/test/stringloader/0000755000175000017500000000000011675166243016566 5ustar moellermoellervelocity-1.7/test/stringloader/compare/0000755000175000017500000000000011675166243020214 5ustar moellermoellervelocity-1.7/test/stringloader/compare/simpletemplate.cmp0000644000175000017500000000003710531706670023734 0ustar moellermoellerThis is a test for a foo objectvelocity-1.7/test/stringloader/compare/change1.cmp0000644000175000017500000000002410531706670022211 0ustar moellermoellerI am the 1 template.velocity-1.7/test/stringloader/compare/change2.cmp0000644000175000017500000000002610531706670022214 0ustar moellermoellerI am the two template.velocity-1.7/test/stringloader/compare/multi1.cmp0000644000175000017500000000002410531706670022116 0ustar moellermoellerI am the 1 template.velocity-1.7/test/stringloader/compare/multi2.cmp0000644000175000017500000000002610531706670022121 0ustar moellermoellerI am the two template.velocity-1.7/test/includeerror/0000755000175000017500000000000011675166243016566 5ustar moellermoellervelocity-1.7/test/includeerror/parsemain.vm0000644000175000017500000000014110367314621021075 0ustar moellermoeller## tests to see if ## ParseException in parsed file is caught text #parse("haserror.txt") textvelocity-1.7/test/includeerror/parsemain2.vm0000644000175000017500000000014210367314621021160 0ustar moellermoeller## tests to see if ## ParseException in parsed file is caught text #parse("haserror2.txt") textvelocity-1.7/test/includeerror/haserror.txt0000644000175000017500000000021310367314621021140 0ustar moellermoeller## This file has a Velocity error. ## It's intentionally not saved with a 'vm' suffix ## to avoid errors in IDE #foreach($i in (1..10) $ivelocity-1.7/test/includeerror/haserror2.txt0000644000175000017500000000040710367314621021227 0ustar moellermoeller## This file has a Velocity error. ## It's intentionally not saved with a 'vm' suffix ## to avoid errors in IDE ## Note: text directly from VELOCITY-96 #macro (myMacro $arg1 $list) This is text from velPTest2.vm #myMacro('name', ['apples', 'oranges'] More text velocity-1.7/test/includeerror/missingparse.vm0000644000175000017500000000013110367314621021621 0ustar moellermoeller## tests to see if ## missing parse throws an error text #parse("doesntexist.vm") textvelocity-1.7/test/includeerror/missinginclude.vm0000644000175000017500000000013510367314621022136 0ustar moellermoeller## tests to see if ## missing include throws an error text #include("doesntexist.vm") textvelocity-1.7/test/templates/0000755000175000017500000000000011675166244016070 5ustar moellermoellervelocity-1.7/test/templates/velocimacro.vm0000644000175000017500000000356310315733667020745 0ustar moellermoeller#** @test velocimacro.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# ## inline VM : shows how a tablerow might be generated #macro( tablerow $array $color ) #foreach( $element in $array ) $element #end #end Now, use the \#quietnull example from the global library VM_global_library.vm : Now, there should be nothing in the brackets : >#quietnull($nada)< #set($foo = "hello!") Where there should be something here : >#quietnull($foo)< #set($arr = ["$10.24","$15.32","$12.15"]) #set($col = "blue") #tablerow( $arr $col)
Further tests. The following VMs and non-VM should be properly escaped : \#tablerow \#quietnull \#notavm >\\#quietnull($nada)< Now try to define a new quietnull VM : #macro( quietnull $a ) QuietNull : $a #end It should have been rejected, as the default is to not let inlines override existing, and there should be a message in velocity.log. Therefore it should still function normally : >#quietnull($foo)< >#quietnull($nada)< We should be able to use argless VMs (and directives....) #macro( noargs ) Hello! I have no args! #end #noargs() And there was a bug where I wasn't getting the params right for the use-instance : #macro( showarg $i ) Arg :>$i< #end #showarg( $jdom.getRootElement().getChild("properties").getChild("author").getTextTrim() ) String literals should work as you expect : #showarg( "stringliteral") Test boolean args : #testbool(true) #testbool(false) Test map args : #macro(showmap $map $key) $map.get($key) #end #set($map = {"a":"aval", "b":"bval" } ) #showmap($map "a") #showmap($map "b") #showmap({"a":"avalinline", "b":"bvalinline"} "a") #showmap({"a":"avalinline", "b":"bvalinline"} "b") - Another fine Velocity Production - velocity-1.7/test/templates/vm_test2.vm0000644000175000017500000000101510315733667020173 0ustar moellermoeller#** @test vm_test2.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests VM recursion *and* the local template namespace feature. This version of recurse should override the global version when called by the global VM callrecurse() *# #macro( recurse $a ) local recurse $a #set( $a = $a - 1) #if ($a > 0) #recurse( $a ) #end #end #set($count = 5) #callrecurse() velocity-1.7/test/templates/compare/0000755000175000017500000000000011675166244017516 5ustar moellermoellervelocity-1.7/test/templates/compare/comment.cmp0000644000175000017500000000034207747721115021657 0ustar moellermoeller this is some text. The following is a 'Christoph Comment' ;) foo We can now comment after the inline set : $barfoo! $there is a dollar before me Test of multiline/singleline combo with some closing text velocity-1.7/test/templates/compare/encodingtest.cmp0000644000175000017500000000015310256120454022667 0ustar moellermoellerThanks to Kent Johnson for this example and the nudge.

Chinese: 网站登录

Spanish: niño

velocity-1.7/test/templates/compare/vm_test1.cmp0000644000175000017500000000022007214607131021740 0ustar moellermoeller global recurse 5 global recurse 4 global recurse 3 global recurse 2 global recurse 1 velocity-1.7/test/templates/compare/foreach-type.cmp0000644000175000017500000000044707365430123022601 0ustar moellermoeller Using a Object [] a b c d Using a Map this is from a hashtable! this is from a hashtable too! Using a Collection string1 string2 Using an Iterator string1 string2 Using an Enumeration string1 string2 Using an array of primitives 10 20 30 40 50 velocity-1.7/test/templates/compare/vm_test2.cmp0000644000175000017500000000021407214607131021744 0ustar moellermoeller local recurse 5 local recurse 4 local recurse 3 local recurse 2 local recurse 1 velocity-1.7/test/templates/compare/pedantic.cmp0000644000175000017500000000245307214051545022001 0ustar moellermoeller This is a test of the new pedantic mode. There are a few things you can do in pedantic mode. Like get the spacing between things first elementsecond element to be really, really tight. Further, it now binds any \n to the control structures, taking them out of the output. The hope that this is What You Expect. So... -- pedantic -- should come out looking like -- pedantic -- But pay attention to what follows the #end statement : 1) First, follow with 'stuff' (not sure why you want to do this... but anway...) -- pedantic woogie! -- should be -- pedantic woogie! -- 2) Whitespace will be eaten if there is a following newline -- pedantic -- should be -- pedantic -- -- INLINE STUFF --- 1) respect spaces in the block >first elementsecond element< > first element second element< >first element second element < > first element second element < 2) set statement has no output, incuding preceeding whitespace first element is first element second element is second element public void foo( String lala ) { System.out.println("first element"); System.out.println("second element"); } public void foo( String lala ) { System.out.println("first element"); System.out.println("second element"); } Inline set statement : Here are the prices : $10.24 $15.32 $12.15 velocity-1.7/test/templates/compare/stop1.cmp0000644000175000017500000000006610256120454021252 0ustar moellermoellerThis page checks the stop directive in the main body velocity-1.7/test/templates/compare/foreach-null-list.cmp0000644000175000017500000000020610256120454023530 0ustar moellermoeller Foreach with a list that contains null. This is a. 1 This is b. 2 This is $element. 3 This is d. 4 velocity-1.7/test/templates/compare/string.cmp0000644000175000017500000000124507774271372021533 0ustar moellermoeller This is a very long string that we are breaking up into multiple lines for testing. This is a string. The number 2 = 2 This is a string. The value = 3 New language feature allows newlines in the strings might make some happy V V EEEEE L OOOOO CCCCC I TTTTT Y Y V V E L O O C I T Y Y V V EEE L O O C I T Y VV E L O O C I T Y V EEEEE LLLL OOOOO CCCCC I T Y RRRRR OOOOO CCCCC K K SSSSS R R O O C K K S RRRR O O C KK SSSS R R O O C K K S R R O O C K K S R R OOOOO CCCCC K K SSSS velocity-1.7/test/templates/compare/arithmetic.cmp0000644000175000017500000000053210226620623022333 0ustar moellermoeller 6 5 10 5 Check the decimal literals 4500.0 4500.0 0.0045 4.5E55 4.5 5.5 11.0 Check that the system can handle integers greater than Integer.MAX_INT 100000000000 100000000001 2 This is a very long string that we are breaking up into multiple lines for testing. This is a string. The number 2 = 2 This is a string. The value = 3 velocity-1.7/test/templates/compare/stop2.cmp0000644000175000017500000000012210256120454021244 0ustar moellermoellerThis page checks the stop directive inside an if statement this should render velocity-1.7/test/templates/compare/block.cmp0000644000175000017500000000220307213514210021265 0ustar moellermoeller First test : spacing between stuff. Note that spacing preceeding the directives counts! One blank line follows this should be followed by two blank lines this is the if statement. (followed by two blank lines) this is great (followed by a blank line, 4 spaces on a line,and 2 more, yes there should be one after the 4 spaces) -- Second Test : no spacing between anything (1 blank line follows) this this is the if statement. this is great (line w/ 4 spaces follows (from in front of the #end) + another blank line) ------------ True ----------- -- Third Test : tight tight tight. Note that #end eats the \n, which is NOT what people expect, I think. -- one blank line follows blargh This follows blarghblarghThis immedately follows blargh with a following newline -- Fourth Test : another tight tight tight. If you want the \n, then put one *after* the content, not a space after #end. -- one blank line follows blargh This follows blargh blarghThis immedately follows blargh with a following newline -- Fifth Test : different kind of tight. blank line follows blargh blargh2 blargh3 velocity-1.7/test/templates/compare/encodingtest2.cmp0000644000175000017500000000013410256120454022750 0ustar moellermoellerThis is an example of chinese code encoding: The chinese string is 上网, its length is 2 velocity-1.7/test/templates/compare/stop3.cmp0000644000175000017500000000020510405661436021255 0ustar moellermoellerThis test checks the stop directive when included from a parse directive. Foo is: stop3-include.vm A line from stop3-include.vm velocity-1.7/test/templates/compare/encodingtest3.cmp0000644000175000017500000000311010256120454022746 0ustar moellermoeller
Chinese/GBK

50ÄêǰµÄ½ñÌ죬ÖйúÈËÃñÖ¾Ô¸¾üÐÛôñôñÆø°º°º£¬ÔÚÈýǧÀュɽÉÏ¿ªÊ¼¿¹ÃÀÔ®³¯£¬±£¼ÒÎÀ¹ú¡£ÔÚÄǶοɸè¿ÉÆüµÄËêÔÂÖУ¬¶àÉÙÖйúÈËΪǰ·½Ö¾Ô¸¾ü½«Ê¿µÄ¾«ÉñËù¹ÄÎ裬ÔÚ¼ÄÍÐÃÀºÃ×£Ô¸µÄͬʱ£¬Ò²½«¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÕâÁ½¸öÃû´ÊƵƵΪ×Ô¼º¸Õ³öÉúµÄ×ÓÅ®ÃüÃû¡£50ÄêÀ´£¬¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÃÇ´ø×ÅÕⳡսÕùµÄÀúÊ·ºÛ¼££¬Ò»¸ö¸öµ½Á˽«½ü°ë°ÙµÄÄêÁ䣬½ñÌ죬ËûÃǹ¤×÷¡¢Éú»îµÃÈçºÎ£¿ÄǶÎÀúÊ·ÔÚ½ñÌìµÄËûÃÇÑÛÀÓÖÊÇÔõÑùÒ»·¬¾°Ï󣿱¾±¨¼ÇÕß×òÌìÏÂÎçÆð·ÖÍ·×·×Ù£¬Ñ°·ÃÄϾ©´ó½ÖСÏïÖеġ°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡£

×·×ÙÒÁʼ£¬ÎÒÃÇÊ×ÏȺÍÄϾ©Êй«°²¾ÖµÄ»§Õþ¹ÜÀí²¿ÃÅÈ¡µÃÁËÁªÏµ£¬Ï£ÍûÄÜͨ¹ýËûÃDz鵽ÄϾ©Êе½µ×ÓжàÉÙ¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡£ÄϾ©ÊÐÇø250ÍòÈ˿ڣ¬¼ÓÉÏÎåÏØ³¬¹ý500ÍòÈ˿ڣ¬²éÒ»±éÈËÃûÆÄ·Ñʱ¼ä¡£ËûÃÇ´óÁ¦Ö§³Ö£¬ÔÚ¹¤×÷Öмû·ì²åÕëΪÎÒÃǰ²ÅÅÁËÉÏ»ú²éѯ£¬ÎÒÃÇÏÈ´Ó¡°Ô®³¯¡±²éÆð£¬¾­¹ý½üÁ½¸öСʱµÄµçÄÔ²éѯ£¬ÄϾ©ÊÐÇø¹²²éµ½ÓÐ233λÊÐÃñµÄÃû×ÖÖк¬ÓС°Ô®³¯¡±¡£²é¡°¿¹ÃÀ¡±ÎÒÃDz»¸ÒÔÙ¡°É§ÈÅ¡±ËûÃÇÈç´Ë·ÑÁ¦²éѯ£¬±ã½øÐÐÁ˳éÑù²éѯ£¬½á¹û²éµÃÄϾ©Ãû½Ð¡°ÕÅ¿¹ÃÀ¡±µÄÓÐ6¸ö£¬¡°Íõ¿¹ÃÀ¡±8¸ö£¬¡°ËÃÀ¡±3¸ö£¬¡°ÀÃÀ¡±2¸ö£¬±ÈÆð¡°Ô®³¯¡±£¬¡°¿¹ÃÀ¡±Ò²²»ÔÚÉÙÊý¡£

ÔÚ²éѯ¡°Ô®³¯¡±µÄ¹ý³ÌÖУ¬ÓÉÓÚÊÇûÓÐÉ趨±»²éѯÕßµÄÄêÁäµÄ£¬½á¹û233¸ö¡°Ô®³¯¡±ÖУ¬²¢²»ÊÇÎÒÃÇÏëÏñÖж¼ÊÇ1950ÄêÖÁ1954ÄêÕâ¶Îʱ¼äÄÚ³öÉúµÄ£¬ÓÐЩÈ˵ijöÉúÄê·ÝÊÇ1944Äê¡¢1945Ä꣬¸ÃÊй«°²¾Ö»§Õþ¿ÆµÄͬ־˵£¬ÕâЩÈ˺ܿÉÄÜÊÇÔÚÉÏСѧʱȡµÄÃû»ò¸ÄµÄÃû£¬ÄÇʱÕýÖµ³¯ÏÊÕ½ÕùÆÚ¼ä£¬¸¸Ä¸Ëæ×ŵ±Ê±³±Á÷Ò²¸øº¢×ÓÈ¡(¸Ä)ÁËÕâÑùµÄÃû¡£

²éѯ×ÊÁÏÏÔʾ£¬¾ø´ó¶àÊý¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¶¼ÊÇ50Äê´ú³õµÄ¼¸Äê¼ä³öÊÀ¡£»§Õþ¿ÆµÄһλŮͬ־»ØÒä˵£¬ÄÇ»á½Ð¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÕæÊÇÒ»ÖÖʱ´úµÄ³±Á÷£¬Ëý¼ÇµÃµ±Ê±ÁÚ¾Ó¼ÒÓÐ4¸öСº¢£¬ÒÀ´Î¾Í½Ð¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡¢¡°±£¼Ò¡±¡¢¡°ÎÀ¹ú¡±£¬½ÐÒ»±é×Ô¼Òº¢×ÓµÄÃû×Ö£¬Õæ¸öÊÇÓÐÖÖ¡°ÐÛôñôñÆø°º°º¡±µÄ¸Ð¾õÔÚÐļ䡣

velocity-1.7/test/templates/compare/logical.cmp0000644000175000017500000000353510315162557021630 0ustar moellermoeller $foo is greater then 1 $foo is less than 10 $foo is great than or equal to 5 $foo is less than or equal to 5 foo is false -- $foo is greater than $bar $foo is greater than or equal to $bar $bar is less than $foo $bar is less than or equal to $foo -- $foo is greater than $bar $foo is greater than or equal to $bar $bar is less than $foo $bar is less than or equal to $foo -- $foo is equal to $foo $foo is not equal to $bar -- $templatenumber1 is greater than $foo $templatenumber1 is greater than or equal to $foo $foo is less than $templatenumber1 $foo is less than or equal to $templatenumber1 -- $bar is greater than $templatenumber1 $bar is greater than or equal to $templatenumber1 $templatenumber1 is less than $bar $templatenumber1 is less than or equal to $bar -- $abc is equal to $templatenumber1 $templatenumber1 is equal to $abc $bar is not equal to $templatenumber1 $templatenumber1 is not equal to $bar -- Logical OR : right right right right right right Logical AND : right right right right right right right right ---------- equivalence ----------- right right right right right right right right right ----------- comparisons ----------- right right right right right right right right right right right right ---------------------- goofy but legal stuff ---------------------- Should equal true : true Should equal true : true Should equal true : true Should equal true : true ---------------------- Compare String and StringBuffer ---------------------- This should be true: true This should be false: false This should be true: true right right Test to see if we can do logical assignment from any expression right right right right right right velocity-1.7/test/templates/compare/array.cmp0000644000175000017500000000033407325203705021324 0ustar moellermoeller a b c 1 2 a b 1 2 a a a > a < > a < > b < > 1 < > 2 < > 1 < > 2 < $p.m( [ $A.g(1), $title ]) $pp.messageFormat( [ $Abc.get($sti), $title, $ti, $sti, 'bodytext' ], $subtopicTemplate) velocity-1.7/test/templates/compare/directive.cmp0000644000175000017500000000004107177567101022167 0ustar moellermoeller this is a dynamic directive! velocity-1.7/test/templates/compare/context_safety1.cmp0000644000175000017500000000006007212571244023323 0ustar moellermoeller vector hello 1 vector hello 2 vector hello 3 velocity-1.7/test/templates/compare/method.cmp0000644000175000017500000000003007177667061021475 0ustar moellermoeller I am a running man velocity-1.7/test/templates/compare/quotes.cmp0000644000175000017500000000017407220642461021530 0ustar moellermoeller "what is that" velocity-1.7/test/templates/compare/sample.cmp0000644000175000017500000000121107177567101021472 0ustar moellermoeller Sample velocity page

Hello from velocity!

Here's the list of people
Names
ArrayList element 1
ArrayList element 2
ArrayList element 3
ArrayList element 4
velocity-1.7/test/templates/compare/context_safety2.cmp0000644000175000017500000000005507212571277023336 0ustar moellermoeller array hello 1 array hello 2 array hello 3 velocity-1.7/test/templates/compare/escape2.cmp0000644000175000017500000000260007447102605021530 0ustar moellermoeller --- Schmoo --- These are not in the context, so they should render as they are here (schmoo). $foo \$foo \\$foo \#woogie \\#woogie \\\#woogie Now put $foo in the context : $foo = bar \$foo =\bar \\$foo =\\bar As we increase the number of \'s, we alternate renderings : bar $foo \bar \$foo \\bar --- Pluggable Directives ---- We are doing an #include("test.txt"), starting with 0 '\' preceeding : --text-- #include("test.txt") \--text-- \#include("test.txt") \\--text-- Now, foreach is a PD. Escape the first one, and then not the second so it renders. The third and fourth examples show the single 'unpleasantry' about this. The \ is only an escape when 'touching' VTL, otherwise, it's just schmoo. #foreach( \ first element \ second element \ \ first element \ \ second element \ \ \first element\ \second element\ \ --- Control Structures ---- First should be escaped... #if(true) hi #end This isn't. Note then that it has to render the \\ as a \ because it's stuck to the VTL \ hi \ \ hi And so forth... \#if(true) hi \#end \\ hi \\ And more... #if(true) hi #else there #end \ hi \ \#if(true) hi \#else there \#end \ there \ \#if(false) hi \#elseif(true) there \#end #$foo1 \#$foo1 #${foo1} \#$${foo1} #C0C0C0 \#C0C0C0 #C0C0C0 \#$C0C0C0 #\$C0C0C0 $(QUERY_STRING{forumid}) \$(QUERY_STRING{forumid}) \\$(QUERY_STRING{forumid}) \ \\ \\\ \\\\ \\\\\ \\\\\\ \\\\\\\ \\\\\\\\ velocity-1.7/test/templates/compare/diabolical.cmp0000644000175000017500000000120610315071472022265 0ustar moellermoeller $f. $f $f. $f foo. foo foo. foo $thingy.dingy "#FFFFFF" "$ow" "$row","var" #333333 #FFFFFF "#FFFFF #FFFFF" "#000000"> "#ffffff" $strings.getVillageType($col.Type) $strings.getVillageType( $col.Type) $strings.getVillageType($col.Type ) -#-# Inline loops #-#- blargh> This is first element and it is the 1 item This is second element and it is the 2 item --Foreach with a null array. 1 blank line follows
-- And when we declare the array in-template : Choose among : red blue green $foo : a $foo2 : bar velocity-1.7/test/templates/compare/ifstatement.cmp0000644000175000017500000000016007220277515022532 0ustar moellermoeller start : right right right right right right right right right right right done velocity-1.7/test/templates/compare/velocimacro2.cmp0000644000175000017500000000100607450366474022604 0ustar moellermoeller Hello from foo : hi Hello from foo2 : hi Hello from foo_two : hi Hello from foo : $notincontext Hello from foo : $notincontext.getThing() $notincontext : no $notincontext.woogie() : no bar : yes Hello from foo2 : bar # # \# hi victor >1< >true< >false< >hello< >hello< >1< >[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]< >[a, b, 1]< velocity-1.7/test/templates/compare/interpolation.cmp0000644000175000017500000000103710337441033023071 0ustar moellermoeller Start with simple string interpolation : it will cost you $10.00 dog.jpg foobar.jpg foobar.jpg 123 1 2 3 How about a directive? Sure : >a< >b< >c< For our next trick, lets interpolate a.... VelociMacro! Hi, I'm a VM! And now, for something completely different : False Now, non interpolated stringlits : False $code $!$\!code Now, check comments within strings. double quotes they should be removed. Single quotes, they should be kept literal. test test testtest test##test test#* hello *#test -- end -- velocity-1.7/test/templates/compare/math.cmp0000644000175000017500000000151510226620623021135 0ustar moellermoeller Addition and subtraction : 1 + 1 = 2 2 - 1 = 1 Multiplication, division, and modulus : 5 % 2 = 1 5 % 0 = $rem2 7 % 2 = 1 5 / 2 = 2 5 / 0 = $rem4 5 * 2 = 10 5 * -1 = -5 5 * -2 = -10 5 * -2 = -10 And now null nodes to make sure it doesn't throw an NPE : Some test for the new number-handling 1000 + 10000000000 = 10000001000 1000 - 10000000000 = -9999999000 1000 * 10000000000 = 10000000000000 1000 / 10000000000 = 0 1000 % 10000000000 = 1000 1000 + 1000.1234 = 2000.1234 1000 - 1000.1234 = -0.123413086 1000 * 1000.1234 = 1000123.44 1000 / 1000.1234 = 0.9998766 This checks that an object implementing TemplateNumber can be used in arithmetic 1000 + 999.125 = 1999.125 1000 - 999.125 = 0.875 1000 * 999.125 = 999125.0 1000 / 999.125 = 1.0008757662955086 Test integer division 5 / 2 = 2 Test decimal division 5 / 2.0 = 2.5 5.0 / 2 = 2.5velocity-1.7/test/templates/compare/shorthand.cmp0000644000175000017500000000005207175166701022204 0ustar moellermoeller velocity-1.7/test/templates/compare/foreach-variable.cmp0000644000175000017500000000377507772051711023420 0ustar moellermoeller Foreach with a variable. This is ArrayList element 1. 1 This is ArrayList element 2. 2 This is ArrayList element 3. 3 This is ArrayList element 4. 4 -- inner foreach -- This is ArrayList element 1. 1 This is ArrayList element 2. 2 This is ArrayList element 3. 3 This is ArrayList element 4. 4 -- inner foreach -- -- outer foreach -- This is ArrayList element 1. 1 -- outer foreach -- -- inner foreach -- This is ArrayList element 1. 1 This is ArrayList element 2. 2 This is ArrayList element 3. 3 This is ArrayList element 4. 4 -- inner foreach -- -- outer foreach -- This is ArrayList element 2. 2 -- outer foreach -- -- inner foreach -- This is ArrayList element 1. 1 This is ArrayList element 2. 2 This is ArrayList element 3. 3 This is ArrayList element 4. 4 -- inner foreach -- -- outer foreach -- This is ArrayList element 3. 3 -- outer foreach -- -- inner foreach -- This is ArrayList element 1. 1 This is ArrayList element 2. 2 This is ArrayList element 3. 3 This is ArrayList element 4. 4 -- inner foreach -- -- outer foreach -- This is ArrayList element 4. 4 -- outer foreach -- ArrayList element 1 ArrayList element 1 ArrayList element 2 ArrayList element 2 ArrayList element 3 ArrayList element 3 ArrayList element 4 ArrayList element 4 ArrayList element 1 ArrayList element 1 ArrayList element 2 ArrayList element 2 ArrayList element 3 ArrayList element 3 ArrayList element 4 ArrayList element 4 ArrayList element 1 ArrayList element 1 ArrayList element 2 ArrayList element 2 ArrayList element 3 ArrayList element 3 ArrayList element 4 ArrayList element 4 velocity-1.7/test/templates/compare/string-interpolation.cmp0000644000175000017500000000010407210621144024366 0ustar moellermoellerit will cost you $10.00 dog.jpg foobar.jpg foobar.jpg 123 1 2 3 velocity-1.7/test/templates/compare/settest.cmp0000644000175000017500000000045607462577464021730 0ustar moellermoeller* @test settest.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests #set parsing funkyness *# I am setthing : bar SessionBean#setSessionContext velocity-1.7/test/templates/compare/range.cmp0000644000175000017500000000144307222664372021313 0ustar moellermoeller [1..5] 1 2 3 4 5 ----- [0..0] 0 ----- [-4..-5] -4 -5 ----- [ 1 .. 5 ] 1 2 3 4 5 ----- [5..1] 5 4 3 2 1 ----- [-5..5] -5 -4 -3 -2 -1 0 1 2 3 4 5 ----- [5..-5] 5 4 3 2 1 0 -1 -2 -3 -4 -5 ----- refs $a=1 $b=5 [$a..$b] 1 2 3 4 5 ----- [$a.. 7] 1 2 3 4 5 6 7 ----- [-7 ..$a] -7 -6 -5 -4 -3 -2 -1 0 1 ----- [ -7 ..$a] -7 -6 -5 -4 -3 -2 -1 0 1 ------ setting in $foo -> [0..5] : 0 1 2 3 4 5 ---- Now some use-case examples. Suppose we want a table to have 10 rows
a
b
c
 
 
 
 
 
 
 
=done= velocity-1.7/test/templates/compare/logical2.cmp0000644000175000017500000000145707774263443021726 0ustar moellermoeller $foo is greater then 1 $foo is less than 10 $foo is great than or equal to 5 $foo is less than or equal to 5 foo is false -- Logical OR : right right right right right right Logical AND : right right right right right right right right ---------- equivalence ----------- right right right right right right right right right ----------- comparisons ----------- right right right right right right right right right right right right ---------------------- goofy but legal stuff ---------------------- Should equal true : true Should equal true : true Should equal true : true Should equal true : true right right Test to see if we can do logical assignment from any expression right right right right right right velocity-1.7/test/templates/compare/literal.cmp0000644000175000017500000000025707217615316021653 0ustar moellermoeller #foreach ($woogie in $boogie) nothing will happen to $woogie #end #if($skin) $!data.setLayoutTemplate($!skin.getLayout()) $!page.setCss($!skin.getCss()) #end velocity-1.7/test/templates/compare/foreach-introspect.cmp0000644000175000017500000000012507335300776024012 0ustar moellermoeller 21 1 22 2 23 3 24 4 25 5 26 6 27 7 28 8 29 9 30 10 velocity-1.7/test/templates/compare/newline.cmp0000644000175000017500000000010307772041222021641 0ustar moellermoeller This is a string Call woog hello there 1 2 3 4 5 6 7 8 9 10 velocity-1.7/test/templates/compare/velocimacro.cmp0000644000175000017500000000215507772041222022514 0ustar moellermoeller Now, use the #quietnull example from the global library VM_global_library.vm : Now, there should be nothing in the brackets : >< Where there should be something here : >hello!< $10.24$15.32$12.15
Further tests. The following VMs and non-VM should be properly escaped : #tablerow #quietnull \#notavm >\< Now try to define a new quietnull VM : It should have been rejected, as the default is to not let inlines override existing, and there should be a message in velocity.log. Therefore it should still function normally : >hello!< >< We should be able to use argless VMs (and directives....) Hello! I have no args! And there was a bug where I wasn't getting the params right for the use-instance : Arg :>$jdom.getRootElement().getChild("properties").getChild("author").getTextTrim()< String literals should work as you expect : Arg :>stringliteral< Test boolean args : arg true arg false Test map args : aval bval avalinline bvalinline - Another fine Velocity Production - velocity-1.7/test/templates/compare/comment-eof.cmp0000644000175000017500000000000610321123527022404 0ustar moellermoellertest velocity-1.7/test/templates/compare/loop.cmp0000644000175000017500000000021207201331452021144 0ustar moellermoeller hello< ArrayList element 1 > hello< ArrayList element 2 > hello< ArrayList element 3 > hello< ArrayList element 4 > velocity-1.7/test/templates/compare/curly-directive.cmp0000644000175000017500000000012510256120454023312 0ustar moellermoeller this is a test sometextand yet more hello xxx #if #else #elseif #set velocity-1.7/test/templates/compare/parse.cmp0000644000175000017500000000043407203436042021316 0ustar moellermoeller Test the #parse pluggable directive Now calling parse1.vm : --- This is content from parse1.vm Hello first element. Hello second element. Now using a reference to get the next one : -- This is parse2.vm. This is from a true #if. -- done with parse1.vm --- all done! velocity-1.7/test/templates/compare/map.cmp0000644000175000017500000000024310634417550020764 0ustar moellermoeller this is from a hashtable! foovalue foovalue foovalue foovalue booboo aval aval bval bval 2 value foovalue $mymap.map.foo {aa=aaa} 0 0 aa bb bb aa aa velocity-1.7/test/templates/compare/get.cmp0000644000175000017500000000002407225713414020763 0ustar moellermoeller Muck Duck Truck velocity-1.7/test/templates/compare/commas.cmp0000644000175000017500000000010110367336304021457 0ustar moellermoeller a: 1 b: 2 a: 1 b: 2 a: 1 b: 2 a2: 1 b2: 2 c2: 3 d2: 4 velocity-1.7/test/templates/compare/encodingtest_KOI8-R.cmp0000644000175000017500000000656007310766566023711 0ustar moellermoellerFrom - Sat Jun 2 11:47:36 2001 Return-Path: Received: from mta1.srv.hcvlny.cv.net (mta1.srv.hcvlny.cv.net [167.206.5.4]) by s1.optonline.net (8.10.2/8.10.2) with ESMTP id f4U9uVc26907 for <@mail.srv.nrwlct.cv.net:geirm@optonline.net>; Wed, 30 May 2001 05:56:31 -0400 (EDT) Received: from apache.org (h31.sny.collab.net [64.208.42.41]) by mta1.srv.hcvlny.cv.net (iPlanet Messaging Server 5.0 Patch 2 (built Dec 14 2000)) with SMTP id <0GE5008U97M83H@mta1.srv.hcvlny.cv.net> for geirm@optonline.net (ORCPT geirm@optonline.net); Wed, 30 May 2001 05:56:33 -0400 (EDT) Received: (qmail 19350 invoked by uid 500); Wed, 30 May 2001 09:56:20 +0000 Received: (qmail 19153 invoked from network); Wed, 30 May 2001 09:56:18 +0000 Date: Wed, 30 May 2001 13:57:17 +0400 From: Vitaly Repetenko Subject: Re: Russian Character Encoding To: velocity-user@jakarta.apache.org Reply-to: velocity-user@jakarta.apache.org Message-id: <3B14C3FD.3834AF02@mtu.ru> Organization: MTU-Intel MIME-version: 1.0 X-Mailer: Mozilla 4.77 [en] (Windows NT 5.0; U) Content-type: multipart/mixed; boundary="Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g)" X-Accept-Language: ru,en Precedence: bulk Delivered-to: mailing list velocity-user@jakarta.apache.org Mailing-List: contact velocity-user-help@jakarta.apache.org; run by ezmlm X-Recipient: velocity-user@jakarta.apache.org X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N References: <3B139D1A.E49723E2@mtu.ru> <3B139DB1.CD00E5E2@optonline.net> <3B13A6B9.B02D04BF@mtu.ru> <3B13B5FB.57130BA9@optonline.net> <3B149DF4.72383B1D@mtu.ru> <3B14BC65.A688FFFB@optonline.net> List-Post: List-Subscribe: List-Unsubscribe: List-Help: X-Mozilla-Status: 8011 X-Mozilla-Status2: 00000000 X-UIDL: a57ee51a80f6ed07173b135dbac0735e This is a multi-part message in MIME format. --Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g) Content-type: text/plain; charset=koi8-r Content-transfer-encoding: 7BIT template "Geir Magnusson Jr." wrote: > Vitaly Repetenko wrote: > > > > Hi! > > > > Test is attached. > > > > Not only russian capital "U" is converted into space but russian capital "F" (ASCII > > code E6) also. > > > > Can you attach a test template? Or better yet, see if the latest in CVS > fixes it? It might have gone in later than the nightly snapshot, so you > may need to just get a dump from CVS. > > geir > > -- > Geir Magnusson Jr. geirm@optonline.net > System and Software Consulting > Developing for the web? See http://jakarta.apache.org/velocity/ > "still climbing up to the shoulders..." --Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g) Content-type: text/html; charset=koi8-r; name=charset_test.vm Content-transfer-encoding: 8BIT Content-disposition: inline; filename=charset_test.vm Russian charset test
ABCDEFGHIJKLMNOPRSTUVWXYZ
abcdefghijklmnoprstuvwxyz

Russian alphabet:(32 chars) Displayed without codes 0xF5 0xE6 (code page KOI8-R)

Â×ÞÚÄųÃßÊËÌÍÎÏÐÒÔÕÆÈÖÉÇÀÙÜÑÝÛÁÓ
                    ^^
------------------>F5E6
â÷þúäå£ãÿêëìíîïðòôõæèöéçàùüñýûáó

alt="Èõíèúê"
     ^
---->F5
alt="Öêúâ"
     ^
---->E6
--Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g)-- velocity-1.7/test/templates/compare/subclass.cmp0000644000175000017500000000002307200061627022015 0ustar moellermoeller Person Child velocity-1.7/test/templates/compare/test.cmp0000644000175000017500000000352707220642461021174 0ustar moellermoeller jason this is testing for wild loose commas , , $100 This is the bar way. This is $bar. This is the if. #set $foo = "bar" $foo => bar $foo; => bar; $foo. => bar. $foo.. => bar.. $foo/ => bar/ $foo" => bar" $foo\ => bar\ $foo< => bar< \$foo- => $foo- \$fooo+ => $fooo+ \$foo-x => $foo-x $foo$ => bar$ jon nothing here function preload(imgObj,imgSrc) { if (document.images) { eval(imgObj+' = new Image()') eval(imgObj+'.src = "'+imgSrc+'"') } } function changeImage(layer,imgName,imgObj) { if (document.images) { if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src') else document.images[imgName].src = eval(imgObj+".src") } } $provider2.Title x x lunatic lunatic crocodile hunter! lunatic jason jason This is a property that returns a boolean value of true. This expression is always (true). Foreach with a variable. This is ArrayList element 1. This is ArrayList element 2. This is ArrayList element 3. This is ArrayList element 4. Foreach with an array.
This is first element
This is second element
This is the vector element 1. This is the vector element 2. Foreach with a method. This is ArrayList element 1. This is ArrayList element 2. This is ArrayList element 3. This is ArrayList element 4. $10.00 "this is great" (this is also great) This is the \#stuff and this is the way \#to \#go. this = that I am a jason. Yes the APL rules! velocity-1.7/test/templates/compare/formal.cmp0000644000175000017500000000044307366141122021466 0ustar moellermoeller 1. lunatic 2. lunatic 3. lunatic 4. lunatic lunaticlunatic lunaticMapBuilder lunatic.map.lunaticMapBuilder thisthat lunatic value0 value1 value2 $provider.getHashtable().get("floogie!") {lunatic lunatic} {lunatic} test provider}.Title test provider.Title test provider{.Title velocity-1.7/test/templates/compare/foreach-map.cmp0000644000175000017500000000004307201331452022357 0ustar moellermoeller value2 value1 value0 velocity-1.7/test/templates/compare/include.cmp0000644000175000017500000000117507235204524021635 0ustar moellermoeller #* @test include.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #include("include.vm" "include.vm") #set($foo = "subdir/test.txt") #include($foo) #* @test include.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #include("include.vm" "include.vm") #set($foo = "subdir/test.txt") #include($foo) This is included text! velocity-1.7/test/templates/compare/foreach-method.cmp0000644000175000017500000000023607177567101023104 0ustar moellermoeller Foreach with a method. This is ArrayList element 1. This is ArrayList element 2. This is ArrayList element 3. This is ArrayList element 4. velocity-1.7/test/templates/compare/equality.cmp0000644000175000017500000000016707177567101022057 0ustar moellermoeller the user jason is logged in! the count is 5! the user isn't logged in. $count is not equal to 3 velocity-1.7/test/templates/compare/if.cmp0000644000175000017500000000002507177567101020611 0ustar moellermoeller this is true velocity-1.7/test/templates/compare/reference.cmp0000644000175000017500000000126607376103651022156 0ustar moellermoeller bar $_foo equals "bar" : bar Late introspection : 7 More stupid reference escaping ... When it does exist in the context : foo $foo $!foo $!foo $\!foo \$!foo And when it doesn't : $bar \$bar \$!bar (because it's just text...) $!foo $\!foo $\\!foo $\\\!foo \\$!foo Misc tests : [$foo.bar] Test lower case property names lunatic lunatic vector element 1 vector element 2 vector element 1 vector element 2 Now test if we can use lowercase for propertes in set Was : lunatic Now : geir Back : lunatic Test what was a bug : boycat.java boycat.java More tests : lunatic $lunatic #lunatic $foo.bar ($bar) Test boolean introspection isFoo() Correct Correct velocity-1.7/test/templates/compare/escape.cmp0000644000175000017500000000111507235204524021444 0ustar moellermoeller \A #set($woo = "bar") $woo => bar The following should print 'as is' : $f\oo \a "\r" Now, test the built in directives. Note that $foo isn't in the context : #set($foo = $foo + 1) #set(\$foo = $foo + 1) #if($foo) #if ( $foo ) #else #end #elseif( Now, a reference not in the context: \$foo -> $foo #if($foo) #if(\$foo) Put it in : $foo -> 1 #if(1) #if($foo) This isn't in the context, so we get the full monty : \$woobie.blagh() The following two are references : $provider.Title = lunatic $provider.getTitle() = lunatic Now, pluggable directives: \#notadirective #foreach velocity-1.7/test/templates/stop3.vm0000644000175000017500000000033210405661436017473 0ustar moellermoellerThis test checks the stop directive when included from a parse directive. #set($foo = "stop3-include.vm") Foo is: $foo #parse("$foo") Since the template issued a stop, this line should not be visible. #parse("$foo") velocity-1.7/test/templates/stop2.vm0000644000175000017500000000043310315733667017502 0ustar moellermoellerThis page checks the stop directive inside an if statement #if(false) #stop #end this should render #if(true) #stop #end this should not render check reference #set($a = 10) $a check method call $a.toString() check escaped directive \#if check escaped reference \$a velocity-1.7/test/templates/comment-eof.vm0000644000175000017500000000006010321123527020621 0ustar moellermoeller## Test to see if ##EOF gives an error test ##velocity-1.7/test/templates/encodingtest3.vm0000644000175000017500000000311010315733667021177 0ustar moellermoeller
Chinese/GBK

50ÄêǰµÄ½ñÌ죬ÖйúÈËÃñÖ¾Ô¸¾üÐÛôñôñÆø°º°º£¬ÔÚÈýǧÀュɽÉÏ¿ªÊ¼¿¹ÃÀÔ®³¯£¬±£¼ÒÎÀ¹ú¡£ÔÚÄǶοɸè¿ÉÆüµÄËêÔÂÖУ¬¶àÉÙÖйúÈËΪǰ·½Ö¾Ô¸¾ü½«Ê¿µÄ¾«ÉñËù¹ÄÎ裬ÔÚ¼ÄÍÐÃÀºÃ×£Ô¸µÄͬʱ£¬Ò²½«¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÕâÁ½¸öÃû´ÊƵƵΪ×Ô¼º¸Õ³öÉúµÄ×ÓÅ®ÃüÃû¡£50ÄêÀ´£¬¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÃÇ´ø×ÅÕⳡսÕùµÄÀúÊ·ºÛ¼££¬Ò»¸ö¸öµ½Á˽«½ü°ë°ÙµÄÄêÁ䣬½ñÌ죬ËûÃǹ¤×÷¡¢Éú»îµÃÈçºÎ£¿ÄǶÎÀúÊ·ÔÚ½ñÌìµÄËûÃÇÑÛÀÓÖÊÇÔõÑùÒ»·¬¾°Ï󣿱¾±¨¼ÇÕß×òÌìÏÂÎçÆð·ÖÍ·×·×Ù£¬Ñ°·ÃÄϾ©´ó½ÖСÏïÖеġ°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡£

×·×ÙÒÁʼ£¬ÎÒÃÇÊ×ÏȺÍÄϾ©Êй«°²¾ÖµÄ»§Õþ¹ÜÀí²¿ÃÅÈ¡µÃÁËÁªÏµ£¬Ï£ÍûÄÜͨ¹ýËûÃDz鵽ÄϾ©Êе½µ×ÓжàÉÙ¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡£ÄϾ©ÊÐÇø250ÍòÈ˿ڣ¬¼ÓÉÏÎåÏØ³¬¹ý500ÍòÈ˿ڣ¬²éÒ»±éÈËÃûÆÄ·Ñʱ¼ä¡£ËûÃÇ´óÁ¦Ö§³Ö£¬ÔÚ¹¤×÷Öмû·ì²åÕëΪÎÒÃǰ²ÅÅÁËÉÏ»ú²éѯ£¬ÎÒÃÇÏÈ´Ó¡°Ô®³¯¡±²éÆð£¬¾­¹ý½üÁ½¸öСʱµÄµçÄÔ²éѯ£¬ÄϾ©ÊÐÇø¹²²éµ½ÓÐ233λÊÐÃñµÄÃû×ÖÖк¬ÓС°Ô®³¯¡±¡£²é¡°¿¹ÃÀ¡±ÎÒÃDz»¸ÒÔÙ¡°É§ÈÅ¡±ËûÃÇÈç´Ë·ÑÁ¦²éѯ£¬±ã½øÐÐÁ˳éÑù²éѯ£¬½á¹û²éµÃÄϾ©Ãû½Ð¡°ÕÅ¿¹ÃÀ¡±µÄÓÐ6¸ö£¬¡°Íõ¿¹ÃÀ¡±8¸ö£¬¡°ËÃÀ¡±3¸ö£¬¡°ÀÃÀ¡±2¸ö£¬±ÈÆð¡°Ô®³¯¡±£¬¡°¿¹ÃÀ¡±Ò²²»ÔÚÉÙÊý¡£

ÔÚ²éѯ¡°Ô®³¯¡±µÄ¹ý³ÌÖУ¬ÓÉÓÚÊÇûÓÐÉ趨±»²éѯÕßµÄÄêÁäµÄ£¬½á¹û233¸ö¡°Ô®³¯¡±ÖУ¬²¢²»ÊÇÎÒÃÇÏëÏñÖж¼ÊÇ1950ÄêÖÁ1954ÄêÕâ¶Îʱ¼äÄÚ³öÉúµÄ£¬ÓÐЩÈ˵ijöÉúÄê·ÝÊÇ1944Äê¡¢1945Ä꣬¸ÃÊй«°²¾Ö»§Õþ¿ÆµÄͬ־˵£¬ÕâЩÈ˺ܿÉÄÜÊÇÔÚÉÏСѧʱȡµÄÃû»ò¸ÄµÄÃû£¬ÄÇʱÕýÖµ³¯ÏÊÕ½ÕùÆÚ¼ä£¬¸¸Ä¸Ëæ×ŵ±Ê±³±Á÷Ò²¸øº¢×ÓÈ¡(¸Ä)ÁËÕâÑùµÄÃû¡£

²éѯ×ÊÁÏÏÔʾ£¬¾ø´ó¶àÊý¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¶¼ÊÇ50Äê´ú³õµÄ¼¸Äê¼ä³öÊÀ¡£»§Õþ¿ÆµÄһλŮͬ־»ØÒä˵£¬ÄÇ»á½Ð¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±ÕæÊÇÒ»ÖÖʱ´úµÄ³±Á÷£¬Ëý¼ÇµÃµ±Ê±ÁÚ¾Ó¼ÒÓÐ4¸öСº¢£¬ÒÀ´Î¾Í½Ð¡°¿¹ÃÀ¡±¡¢¡°Ô®³¯¡±¡¢¡°±£¼Ò¡±¡¢¡°ÎÀ¹ú¡±£¬½ÐÒ»±é×Ô¼Òº¢×ÓµÄÃû×Ö£¬Õæ¸öÊÇÓÐÖÖ¡°ÐÛôñôñÆø°º°º¡±µÄ¸Ð¾õÔÚÐļ䡣

velocity-1.7/test/templates/formal.vm0000644000175000017500000000144310315733667017715 0ustar moellermoeller#* @test formal.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# 1. $!{provider.Title} 2. $provider.Title 3. $!provider.Title 4. ${provider.Title} ${provider.Title}${provider.Title} ${provider.Title}MapBuilder ${provider.Title}.map.${provider.Title}MapBuilder #set($this = "this") #set($that = "that") ${this}${that} ${provider.getTitle()} $provider.getHashtable().get( "key0") $provider.getHashtable().get("key1" ) $provider.getHashtable().get( "key2" ) $provider.getHashtable().get("floogie!") ## curly wierdness {$provider.Title $provider.Title} {$provider.Title} $provider}.Title ${provider}.Title $provider{.Title velocity-1.7/test/templates/loop.vm0000644000175000017500000000052610315733667017407 0ustar moellermoeller#* @test loop.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #foreach ($element in $list) #set($foo = $provider.concat(["<", $element, ">"])) $provider.concat("hello", $foo) #end velocity-1.7/test/templates/ifstatement.vm0000644000175000017500000000127410315733667020762 0ustar moellermoeller#* @test ifstatement.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($foo = "woogie" ) start : #if($foo) right #end #if(!$foo) wrong #else right #end #if( !$foo ) wrong #else right #end #if( ! $foo ) wrong #else right #end #if( ! ! $foo ) right #end #if($bar) wrong #else right #end #if($bar) wrong #elseif( $foo ) right #end #if( $bar ) wrong #elseif( $floogie ) wrong #elseif( $woppie ) wrong #else right #end #if(!$bar) right #end #if( !$bar) right #end #if( !!$bar) wrong #else right #end done velocity-1.7/test/templates/array.vm0000644000175000017500000000157410315733667017560 0ustar moellermoeller#* @test array.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set( $foo = [$this, $that, $woog.Bar, [$this, "this"] ]) $provider.concat(["a", "b", "c"]) #set($foo = "a") $provider.objConcat( [1..2] ) $provider.objConcat( ["a","b"] ) $provider.objConcat( [1..2 ] ) $provider.objConcat( [$foo] ) $provider.objConcat( [ $foo] ) $provider.objConcat( [$foo ] ) #macro( showme $array ) #foreach( $i in $array ) > $i <#end #end #set($woog = "a") #set($floog = "b") #showme( [ $woog] ) #showme( [ $woog,$floog] ) #showme( [1..2]) #showme( [1 ..2 ]) ## and more.... $p.m( [ $A.g(1), $title ]) $pp.messageFormat( [ $Abc.get($sti), $title, $ti, $sti, 'bodytext' ], $subtopicTemplate) #set ($args = [ $pp.nQuestions, $pass, $units ] ) velocity-1.7/test/templates/interpolation.vm0000644000175000017500000000264110337441033021310 0ustar moellermoeller#* @test interpolation.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Start with simple string interpolation : #set($name = "jason") $provider.concat("it will cost you $10.00", "") #set($image = "dog") $provider.concat("${image}.jpg", "") #set($foo-bar = "foobar") $provider.concat("${foo-bar}.jpg", "") #set($foo_bar = "foobar") $provider.concat("${foo_bar}.jpg", "") #set($one = 1) #set($two = 2) #set($three = 3) $provider.concat("${one}${two}${three}", "") $provider.concat("$one $two $three", "") How about a directive? Sure : #set($arr = ["a","b","c"]) #set($foo = "#foreach($a in $arr) >$a< #end") $foo For our next trick, lets interpolate a.... VelociMacro! #macro( interpfoo ) Hi, I'm a VM! #end #set($ivm = "#interpfoo()") $ivm And now, for something completely different : #set($code = "#if(false) True #else False #end") $code Now, non interpolated stringlits : #set($a = "$code") #set($b = '$code') #set($c = '$!$\!code') $a $b $c Now, check comments within strings. double quotes they should be removed. Single quotes, they should be kept literal. #set($c1 = "test##test") #set($c2 = "test ##test") #set($c3 = "##test") #set($c4 = "test#* hello *#test") #set($c5 = 'test##test') #set($c6 = 'test#* hello *#test') $c1 $c2 $c3 $c4 $c5 $c6 -- end -- velocity-1.7/test/templates/logical.vm0000644000175000017500000001234410315733667020051 0ustar moellermoeller#* @test logical.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($foo = 5) #if ($foo > 1) \$foo is greater then 1 #end #if ($foo < 10) \$foo is less than 10 #end #if ($foo >= 5) \$foo is great than or equal to 5 #end #if ($foo <= 5) \$foo is less than or equal to 5 #end #set($foo = false) #if (!($foo == true)) foo is false #end -- #set ($foo = 49/2) #set ($bar = 10) #if ($foo > $bar) \$foo is greater than \$bar #end #if ($foo >= $bar) \$foo is greater than or equal to \$bar #end #if ($bar < $foo) \$bar is less than \$foo #end #if ($bar <= $foo) \$bar is less than or equal to \$foo #end -- #set ($foo = 49/2) #set ($bar = 10) #if ($foo > $bar) \$foo is greater than \$bar #end #if ($foo >= $bar) \$foo is greater than or equal to \$bar #end #if ($bar < $foo) \$bar is less than \$foo #end #if ($bar <= $foo) \$bar is less than or equal to \$foo #end -- #set ($foo = 3) #set ($bar = 4) #if ($foo == $foo) \$foo is equal to \$foo #end #if ($foo != $bar) \$foo is not equal to \$bar #end -- #set ($foo = 888) #set ($bar = 1111) #set ($abc = $templatenumber1.AsNumber) #if ($templatenumber1 > $foo) \$templatenumber1 is greater than \$foo #end #if ($templatenumber1 >= $foo) \$templatenumber1 is greater than or equal to \$foo #end #if ($foo < $templatenumber1) \$foo is less than \$templatenumber1 #end #if ($foo <= $templatenumber1) \$foo is less than or equal to \$templatenumber1 #end -- #if ($bar > $templatenumber1) \$bar is greater than \$templatenumber1 #end #if ($bar >= $templatenumber1) \$bar is greater than or equal to \$templatenumber1 #end #if ($templatenumber1 < $bar) \$templatenumber1 is less than \$bar #end #if ($templatenumber1 <= $bar) \$templatenumber1 is less than or equal to \$bar #end -- #if ($abc == $templatenumber1) \$abc is equal to \$templatenumber1 #end #if ($templatenumber1 == $abc) \$templatenumber1 is equal to \$abc #end #if ($bar != $templatenumber1) \$bar is not equal to \$templatenumber1 #end #if ($templatenumber1 != $bar) \$templatenumber1 is not equal to \$bar #end -- #set($t = true) #set($f = false) Logical OR : #if($t || $f) right #else wrong #end #if( !($f || $t) ) wrong #else right #end #if( $null || $t ) right #else wrong #end #if( $t || $null ) right #else wrong #end #if( $f || $null) wrong #else right #end #if( $null || $null ) wrong #else right #end Logical AND : #if( $t && $t) right #else wrong #end #if( $f && $f ) wrong #else right #end #if( !($f && $f) ) right #else wrong #end #if( $t && $f ) wrong #else right #end #if( $t && $null ) wrong #else right #end #if( $null && $t ) wrong #else right #end #if( $f && $null ) wrong #else right #end #if( !($null && $null) ) right #else wrong #end ---------- equivalence ----------- #set($int = 1) #set($str = "str") #set($bool = true) #if( $int == $str) wrong #else right #end #if( $int == 1 ) right #else wrong #end #if ( $int == 2 ) wrong #else right #end #if( $str == 2 ) wrong #else right #end #if( $str == "str") right #else wrong #end #if( $str == $nonexistantreference ) wrong #else right #end #if( $str == $bool ) wrong #else right #end #if ($bool == true ) right #else wrong #end #if( $bool == false ) wrong #else right #end ----------- comparisons ----------- #set($int = 1) #set($str = "str") #set($bool = true) #if( $int > 0 ) right #else wrong #end #if( $str > 0 ) wrong #else right #end #if( $nonexistant > 0 ) wrong #else right #end #if( $int >= 0 ) right #else wrong #end #if( $str >= 0 ) wrong #else right #end #if( $nonexistant >= 0 ) wrong #else right #end #if( $int < 10 ) right #else wrong #end #if( $str < 10 ) wrong #else right #end #if( $nonexistant < 10 ) wrong #else right #end #if( $int <= 10 ) right #else wrong #end #if( $str <= 10 ) wrong #else right #end #if( $nonexistant <= 10 ) wrong #else right #end ---------------------- goofy but legal stuff ---------------------- #set($lala = ( false || true ) ) Should equal true : $lala #set($fofo = ( true && true ) ) Should equal true : $fofo #set($fofo = ( true && ( false || true ) ) ) Should equal true : $fofo #set($fofo = ( ($t || $f) && $t)) Should equal true : $fofo ---------------------- Compare String and StringBuffer ---------------------- #set($compClass = ($name == $name2)) This should be true: $compClass #set($compClass2 = ($name == $name3)) This should be false: $compClass2 #set($compClass3 = ($name != $name3)) This should be true: $compClass3 #set($x = !true) #if($x == false) right #else wrong #end #set($y = !$x) #if($y == true) right #else wrong #end Test to see if we can do logical assignment from any expression #set($val = (3 == 3)) #if($val == true) right #else wrong #end #set($val = (1 < 2)) #if( $val == true) right #else wrong #end #set($val = (1 <= 2)) #if( $val == true) right #else wrong #end #set($val = (7 > 2)) #if( $val == true) right #else wrong #end #set($val = (7 >= 2)) #if( $val == true) right #else wrong #end #set($val = ( 1 != 2)) #if( $val == true) right #else wrong #end ## check empty if statement is ok #if( true )#end velocity-1.7/test/templates/block.vm0000644000175000017500000000405210315733667017526 0ustar moellermoeller#* @test block.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# First test : spacing between stuff. Note that spacing preceeding the directives counts! One blank line follows #set($foo = false) #if ($foo) this is true #elseif ($bar) this is false #elseif (true) this should be followed by two blank lines #end #if (true) this is the if statement. (followed by two blank lines) #if (true) this is great (followed by a blank line, 4 spaces on a line,and 2 more, yes there should be one after the 4 spaces) #elseif (false) this is also great. #end #elseif (true) this is the first elseif. #elseif (false) this is the second elseif. #else this is the else statement #end -- Second Test : no spacing between anything (1 blank line follows) #set($foo = false) #if ($foo) this is true #elseif ($bar) this is false #elseif (true) this #end #if (true) this is the if statement. #if (true) this is great (line w/ 4 spaces follows (from in front of the \#end) + another blank line) #elseif (false) this is also great. #end #elseif (true) this is the first elseif. #elseif (false) this is the second elseif. #else this is the else statement #end ------------ #if(false) False #else True #end ----------- -- Third Test : tight tight tight. Note that \#end eats the \n, which is NOT what people expect, I think. -- one blank line follows blargh #if(true)This follows blargh#end blargh#if(true)This immedately follows blargh with a following newline #end -- Fourth Test : another tight tight tight. If you want the \n, then put one *after* the content, not a space after \#end. -- one blank line follows blargh #if(true)This follows blargh #end blargh#if(true)This immedately follows blargh with a following newline #end -- Fifth Test : different kind of tight. blank line follows blargh #if(true) blargh2 #end blargh3 velocity-1.7/test/templates/get.vm0000644000175000017500000000057510315733667017221 0ustar moellermoeller#* @test get.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# ## Now the provider has been outfitted with ## a get(key) method so it will just return ## the key when asked for it. $provider.Muck $provider.Duck $provider.Truck velocity-1.7/test/templates/parse2.vm0000644000175000017500000000043010315733667017624 0ustar moellermoeller#* @test parse2.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# This is parse2.vm. #if (true) This is from a true \#if. #end velocity-1.7/test/templates/commas.vm0000644000175000017500000000025610367336304017707 0ustar moellermoeller#macro(test $a $b) a: $a b: $b #end #macro(test2 $a, $b,$c,$d) a2: $a b2: $b c2: $c d2: $d #end #test("1","2") #test("1" , "2") #test("1" "2") #test2("1","2","3","4") velocity-1.7/test/templates/context_safety.vm0000644000175000017500000000004110315733667021465 0ustar moellermoeller#foreach($a in $vector) $a #end velocity-1.7/test/templates/encodingtest_KOI8-R.vm0000644000175000017500000000656010315733667022121 0ustar moellermoellerFrom - Sat Jun 2 11:47:36 2001 Return-Path: Received: from mta1.srv.hcvlny.cv.net (mta1.srv.hcvlny.cv.net [167.206.5.4]) by s1.optonline.net (8.10.2/8.10.2) with ESMTP id f4U9uVc26907 for <@mail.srv.nrwlct.cv.net:geirm@optonline.net>; Wed, 30 May 2001 05:56:31 -0400 (EDT) Received: from apache.org (h31.sny.collab.net [64.208.42.41]) by mta1.srv.hcvlny.cv.net (iPlanet Messaging Server 5.0 Patch 2 (built Dec 14 2000)) with SMTP id <0GE5008U97M83H@mta1.srv.hcvlny.cv.net> for geirm@optonline.net (ORCPT geirm@optonline.net); Wed, 30 May 2001 05:56:33 -0400 (EDT) Received: (qmail 19350 invoked by uid 500); Wed, 30 May 2001 09:56:20 +0000 Received: (qmail 19153 invoked from network); Wed, 30 May 2001 09:56:18 +0000 Date: Wed, 30 May 2001 13:57:17 +0400 From: Vitaly Repetenko Subject: Re: Russian Character Encoding To: velocity-user@jakarta.apache.org Reply-to: velocity-user@jakarta.apache.org Message-id: <3B14C3FD.3834AF02@mtu.ru> Organization: MTU-Intel MIME-version: 1.0 X-Mailer: Mozilla 4.77 [en] (Windows NT 5.0; U) Content-type: multipart/mixed; boundary="Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g)" X-Accept-Language: ru,en Precedence: bulk Delivered-to: mailing list velocity-user@jakarta.apache.org Mailing-List: contact velocity-user-help@jakarta.apache.org; run by ezmlm X-Recipient: velocity-user@jakarta.apache.org X-Spam-Rating: h31.sny.collab.net 1.6.2 0/1000/N References: <3B139D1A.E49723E2@mtu.ru> <3B139DB1.CD00E5E2@optonline.net> <3B13A6B9.B02D04BF@mtu.ru> <3B13B5FB.57130BA9@optonline.net> <3B149DF4.72383B1D@mtu.ru> <3B14BC65.A688FFFB@optonline.net> List-Post: List-Subscribe: List-Unsubscribe: List-Help: X-Mozilla-Status: 8011 X-Mozilla-Status2: 00000000 X-UIDL: a57ee51a80f6ed07173b135dbac0735e This is a multi-part message in MIME format. --Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g) Content-type: text/plain; charset=koi8-r Content-transfer-encoding: 7BIT template "Geir Magnusson Jr." wrote: > Vitaly Repetenko wrote: > > > > Hi! > > > > Test is attached. > > > > Not only russian capital "U" is converted into space but russian capital "F" (ASCII > > code E6) also. > > > > Can you attach a test template? Or better yet, see if the latest in CVS > fixes it? It might have gone in later than the nightly snapshot, so you > may need to just get a dump from CVS. > > geir > > -- > Geir Magnusson Jr. geirm@optonline.net > System and Software Consulting > Developing for the web? See http://jakarta.apache.org/velocity/ > "still climbing up to the shoulders..." --Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g) Content-type: text/html; charset=koi8-r; name=charset_test.vm Content-transfer-encoding: 8BIT Content-disposition: inline; filename=charset_test.vm Russian charset test
ABCDEFGHIJKLMNOPRSTUVWXYZ
abcdefghijklmnoprstuvwxyz

Russian alphabet:(32 chars) Displayed without codes 0xF5 0xE6 (code page KOI8-R)

Â×ÞÚÄųÃßÊËÌÍÎÏÐÒÔÕÆÈÖÉÇÀÙÜÑÝÛÁÓ
                    ^^
------------------>F5E6
â÷þúäå£ãÿêëìíîïðòôõæèöéçàùüñýûáó

alt="Èõíèúê"
     ^
---->F5
alt="Öêúâ"
     ^
---->E6
--Boundary_(ID_tldpu1b8SMKs0pXiY1Dv8g)-- velocity-1.7/test/templates/escape.vm0000644000175000017500000000156510315733667017702 0ustar moellermoeller#* @test escape.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# \A \#set($woo = "bar") #set($woo = "bar") \$woo => $woo The following should print 'as is' : $f\oo \a "\r" Now, test the built in directives. Note that $foo isn't in the context : \#set($foo = $foo + 1) \#set(\$foo = $foo + 1) \#if($foo) \#if ( $foo ) \#else \#end \#elseif( Now, a reference not in the context: \$foo -> $foo \#if($foo) \#if(\$foo) Put it in : #set($foo = 1) \$foo -> $foo \#if($foo) \#if(\$foo) This isn't in the context, so we get the full monty : \$woobie.blagh() The following two are references : \$provider.Title = $provider.Title \$provider.getTitle() = $provider.getTitle() Now, pluggable directives: \#notadirective \#foreach velocity-1.7/test/templates/subclass.vm0000644000175000017500000000076410315733667020261 0ustar moellermoeller#** @test subclass.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# ## This is our base class. #set($person = $provider.Person) ## This is a subclass of Person #set($child = $provider.Child) #* showPerson takes a person object, so check to see that subclasses of Person work too! *# $provider.showPerson($person) $provider.showPerson($child) velocity-1.7/test/templates/newline.vm0000644000175000017500000000033110315733667020071 0ustar moellermoeller#macro(woogie $a) This is $a #end #woogie( "a string" ) #macro( name $thing ) Call $thing #end #name("woog") #set($foo = "hello there") $foo #set($list = [1..10]) #foreach($item in $list) $item #end velocity-1.7/test/templates/vm_test1.vm0000644000175000017500000000063610315733667020202 0ustar moellermoeller#** @test vm_test1.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests VM recursion. In our VM library, we have a VM callrecurse() which calls recurse(). The point is to have the global def of recurse() called since we don't define it here. *# #callrecurse() velocity-1.7/test/templates/stop1.vm0000644000175000017500000000032310315733667017477 0ustar moellermoellerThis page checks the stop directive in the main body #stop this should not render check reference #set($a = 10) $a check method call $a.toString() check escaped directive \#if check escaped reference \$a velocity-1.7/test/templates/string.vm0000644000175000017500000000163710315733667017750 0ustar moellermoeller## now lets try some string concatenation #set($stringy = "This is a very long string" + " that we are breaking up into multiple" + " lines for testing." ) $stringy #set($stringy = "This is a string. The number 2 = " + 2) $stringy #set($three = 3) #set($stringy = "This is a string." + " The value = " + $three ) $stringy #set($haiku = " New language feature allows newlines in the strings might make some happy" ) $haiku #set($shape = " V V EEEEE L OOOOO CCCCC I TTTTT Y Y V V E L O O C I T Y Y V V EEE L O O C I T Y VV E L O O C I T Y V EEEEE LLLL OOOOO CCCCC I T Y " ) $shape #set($shape = ' RRRRR OOOOO CCCCC K K SSSSS R R O O C K K S RRRR O O C KK SSSS R R O O C K K S R R O O C K K S R R OOOOO CCCCC K K SSSS ' ) $shape velocity-1.7/test/templates/templates.properties0000644000175000017500000000417010513464370022175 0ustar moellermoeller# 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. test.template.1 = arithmetic test.template.2 = array test.template.3 = block test.template.4 = comment test.template.5 = equality test.template.6 = escape test.template.7 = foreach-array test.template.8 = foreach-method test.template.9 = foreach-variable test.template.10 = formal test.template.11 = if test.template.12 = logical test.template.13 = loop test.template.14 = method test.template.15 = quotes test.template.16 = sample test.template.17 = shorthand test.template.18 = test test.template.19 = diabolical test.template.20 = pedantic test.template.21 = subclass test.template.22 = foreach-map test.template.23 = include test.template.24 = escape2 test.template.25 = parse test.template.26 = velocimacro test.template.27 = reference test.template.28 = interpolation test.template.29 = vm_test1 test.template.30 = map test.template.31 = literal test.template.32 = ifstatement test.template.33 = math test.template.34 = range test.template.35 = get test.template.36 = velocimacro2 test.template.37 = foreach-type test.template.38 = foreach-introspect test.template.39 = settest test.template.40 = newline test.template.41 = logical2 test.template.42 = string test.template.43 = stop1 test.template.44 = stop2 test.template.45 = foreach-null-list test.template.46 = curly-directive test.template.47 = comment-eof test.template.48 = commas test.template.49 = stop3 velocity-1.7/test/templates/encodingtest2.vm0000644000175000017500000000017210315733667021203 0ustar moellermoellerThis is an example of chinese code encoding: #set ($ch = "上网") The chinese string is $ch, its length is $ch.length() velocity-1.7/test/templates/test.txt0000644000175000017500000000001110315733667017577 0ustar moellermoeller--text-- velocity-1.7/test/templates/map.vm0000644000175000017500000000220610634417550017202 0ustar moellermoeller#* @test map.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# ## This is a valid Map and Bar is a valid ## element. $hashtable.Bar ## test the new Map support #set( $hashtable.Foo = "foovalue") $hashtable.get("Foo") $hashtable.Foo #set( $hashmap.Foo = "foovalue") $hashmap.Foo $hashmap.get("Foo") ## ## test the support for the Map creation syntax ## #set($key = 'key') #set($value = 'value') #set($mymap = { "a" : "aval", "bar" : "booboo", 'b' : 'bval', 1 : 2, $key : $value, 'hash' : $hashmap } ) $mymap.put("bar", { "aa" : "aaa" }) $mymap.a $mymap.get("a") $mymap.b $mymap.get('b') $mymap.get(1) $mymap.get($key) $mymap.hash.Foo $mymap.map.foo $mymap.bar ## ## test for empty map ## #set($emptymap = {}) $emptymap.size() #set($emptymap = { }) $emptymap.size() ## ## test for values given with reference ## #set($object = "aa") #set($mapz = {"a" : $object, "b" : "bb" }) #set($mapx = {"a" : "bb", "b" : $object }) #set($mapy = {"key": $object}) $mapz.a $mapz.b $mapx.a $mapx.b $mapy.key velocity-1.7/test/templates/test.vm0000644000175000017500000000607610315733667017423 0ustar moellermoeller#* @test test.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# $name #if ($customer) $customer.Name #end ## this is a comment. #if ($customer) this is the first line #end ## This is the test bed. this is testing for wild loose commas , , $100 #set($foo = "bar") This is the $foo way. #if ($foo) This is $bar. #elseif ($bar) This is the first elseif! #elseif ($foo) This is the second elseif! #else This is the else #end #if ($foo) This is the if. #else This is the else. #end \#set \$foo = "bar" \$foo => $foo \$foo; => $foo; \$foo. => $foo. \$foo.. => $foo.. \$foo/ => $foo/ \$foo" => $foo" \$foo\ => $foo\ \$foo< => $foo< \$foo- => $foo- \$fooo+ => $fooo+ \$foo-x => $foo-x \$foo$ => $foo$ #set($iam-cool = "jon") $iam-cool $!nada nothing here function preload(imgObj,imgSrc) { if (document.images) { eval(imgObj+' = new Image()') eval(imgObj+'.src = "'+imgSrc+'"') } } function changeImage(layer,imgName,imgObj) { if (document.images) { if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src') else document.images[imgName].src = eval(imgObj+".src") } } #if ($javascript) function changeImage(layer,imgName,imgObj) { if (document.images) { if (document.layers && layer!=null) eval('document.'+layer+'.document.images["'+imgName+'"].src = '+imgObj+'.src') else document.images[imgName].src = eval(imgObj+".src") } } #end $provider2.Title #set($a = "x") $a #set($b = $a) $b #set($c = $provider.Title) $c #set($d = $provider.getTitle()) $d #set($provider.Title = "crocodile hunter!") $provider.Title #set($provider.Title = $d) $provider.Title #set($provider.Title = $provider.Name) $provider.Title #set($provider.Title = $provider.getName()) $provider.Title #set($a = true) #set($b = false) #set($provider.State = true) #set($provider.State = false) #if ($provider.StateTrue) This is a property that returns a boolean value of true. #end #if (true) This expression is always (true). #end Foreach with a variable. #foreach ($element in $list) This is $element. #end Foreach with an array. #foreach ($element in $provider.Array) #end
This is $element
#foreach ($element in $provider.Vector) This is the $element. #end Foreach with a method. #foreach ($element in $provider.getCustomers()) This is $element. #end $10.00 "this is great" (this is also great) This is the \#stuff and this is the way \#to \#go. this = that I am a $provider.getTitle(). #if ($provider.theAPLRules()) Yes the APL rules! #else It still rules! #end velocity-1.7/test/templates/quotes.vm0000644000175000017500000000064710315733667017762 0ustar moellermoeller#* @test quotes.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($this = "that") #if (true) "what is $this" #end velocity-1.7/test/templates/method.vm0000644000175000017500000000044410315733667017715 0ustar moellermoeller#* @test method.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# $provider.concat(["I", "am", "a", $provider.concat(["running", "man"])]) velocity-1.7/test/templates/escape2.vm0000644000175000017500000000403510315733667017757 0ustar moellermoeller#* @test escape2.vm More interesting cases... This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# --- Schmoo --- These are not in the context, so they should render as they are here (schmoo). $foo \$foo \\$foo \#woogie \\#woogie \\\#woogie Now put $foo in the context : #set($foo = "bar") \$foo = $foo \\\$foo =\\$foo \\\\\$foo =\\\\$foo As we increase the number of \'s, we alternate renderings : $foo \$foo \\$foo \\\$foo \\\\$foo --- Pluggable Directives ---- We are doing an \#include("test.txt"), starting with 0 '\' preceeding : #include("test.txt") \#include("test.txt") \\#include("test.txt") \\\#include("test.txt") \\\\#include("test.txt") Now, foreach is a PD. Escape the first one, and then not the second so it renders. The third and fourth examples show the single 'unpleasantry' about this. The \ is only an escape when 'touching' VTL, otherwise, it's just schmoo. \#foreach( \\#foreach($a in $stringarray) $a \\#end \\#foreach($a in $stringarray) $a \ \\#end \\#foreach($a in $stringarray)$a\ \\#end --- Control Structures ---- First should be escaped... \#if(true) hi \#end This isn't. Note then that it has to render the \\ as a \ because it's stuck to the VTL \\#if(true) hi \\#end \\#if(true) hi #end And so forth... \\\#if(true) hi \\\#end \\\\#if(true) hi \\\\#end And more... \#if(true) hi \#else there \#end \\#if(true) hi \\#else there \\#end \\\#if(true) hi \\\#else there \\\#end \\#if(false) hi \\#elseif(true) there \\#end \\\#if(false) hi \\\#elseif(true) there \\\#end ## testing combinations like #$foo #$foo1 \#$foo1 #${foo1} \#$${foo1} #set($foo1 = "C0C0C0") #$foo1 \#$foo1 #${foo1} \#$${foo1} #\$${foo1} ## and wacky stuff that are not references, but ## because of the MORE tokens, get screwed up $(QUERY_STRING{forumid}) \$(QUERY_STRING{forumid}) \\$(QUERY_STRING{forumid}) ## ## and just slashes.... ## \ \\ \\\ \\\\ \\\\\ \\\\\\ \\\\\\\ \\\\\\\\ velocity-1.7/test/templates/foreach-method.vm0000644000175000017500000000050510315733667021320 0ustar moellermoeller#* @test foreach-method.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Foreach with a method. #foreach ($element in $provider.getCustomers()) This is $element. #end velocity-1.7/test/templates/pedantic.vm0000644000175000017500000000333510315733667020226 0ustar moellermoeller#* @test pedantic.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set( $pedantic = "pedantic") This is a test of the new #if($pedantic)$pedantic#end mode. There are a few things you can do in #if($foobar) GOOGLE! #else$pedantic#end mode. Like get the spacing between things #foreach($a in $stringarray)$a#end to be really, really tight. Further, it now binds any \n to the control structures, taking them out of the output. The hope that this is What You Expect. So... -- #if ($pedantic) $pedantic #end -- should come out looking like -- pedantic -- But pay attention to what follows the \#end statement : 1) First, follow with 'stuff' (not sure why you want to do this... but anway...) -- #if ($pedantic) $pedantic #end woogie! -- should be -- pedantic woogie! -- 2) Whitespace will be eaten if there is a following newline -- #if ($pedantic) $pedantic #end -- should be -- pedantic -- -- INLINE STUFF --- 1) respect spaces in the block >#foreach($a in $stringarray)$a#end< >#foreach($a in $stringarray) $a#end< >#foreach($a in $stringarray)$a #end< >#foreach($a in $stringarray) $a #end< 2) set statement has no output, incuding preceeding whitespace #foreach($a in $stringarray) #set($b = $a) $a is $b #end public void foo( String lala ) { #foreach($a in $stringarray) #set($b = $a) System.out.println("$b"); #end } public void foo( String lala ) { #foreach($a in $stringarray) #set($b = $a) System.out.println("$b"); #end } Inline set statement : Here are the prices :#set( $arr = ["$10.24","$15.32","$12.15"] ) #foreach($a in $arr) $a #end velocity-1.7/test/templates/arithmetic.vm0000644000175000017500000000203710315733667020566 0ustar moellermoeller#** @test arithmetic.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($foo = 5) #set($foo = $foo + 1) $foo #set($foo = $foo - 1) $foo #set($foo = $foo * 2) $foo #set($foo = $foo / 2) $foo Check the decimal literals #set($bar = 4.5e3) $bar #set($bar = 4.5e+3) $bar #set($bar = 4.5e-3) $bar #set($bar = 4.5e055) $bar #set($bar = 4.5) $bar #set($bar = $bar + 1) $bar #set($tbar = $bar * 2) $tbar Check that the system can handle integers greater than Integer.MAX_INT #set($baba = 100000000000) $baba #set($baba = $baba + 1) $baba #set ($foo = $foo / 2) $foo ## now lets try some string concatenation #set($stringy = "This is a very long string" + " that we are breaking up into multiple" + " lines for testing." ) $stringy #set($stringy = "This is a string. The number 2 = " + 2) $stringy #set($three = 3) #set($stringy = "This is a string." + " The value = " + $three ) $stringy velocity-1.7/test/templates/shorthand.vm0000644000175000017500000000006110315733667020422 0ustar moellermoeller velocity-1.7/test/templates/foreach-variable.vm0000644000175000017500000000134110315733667021624 0ustar moellermoeller#* @test foreach-variable.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Foreach with a variable. #foreach ($element in $list) This is $element. $velocityCount #end #foreach ($element in $list) -- inner foreach -- #foreach ($element in $list) This is $element. $velocityCount #end -- inner foreach -- -- outer foreach -- This is $element. $velocityCount -- outer foreach -- #end #foreach(${item} in ${list}) $item ${item} #end #foreach(${item} in $list) $item ${item} #end #foreach($item in ${list}) $item ${item} #end velocity-1.7/test/templates/parse1.vm0000644000175000017500000000063210315733667017627 0ustar moellermoeller#* @test parse1.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# This is content from parse1.vm #foreach($a in $stringarray ) Hello $a. #end Now using a reference to get the next one : #set($foo = "parse2.vm") -- #parse($foo) -- done with parse1.vm velocity-1.7/test/templates/logical2.vm0000644000175000017500000000625710315733667020141 0ustar moellermoeller#* @test logical.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($foo = 5) #if ($foo gt 1) \$foo is greater then 1 #end #if ($foo lt 10) \$foo is less than 10 #end #if ($foo ge 5) \$foo is great than or equal to 5 #end #if ($foo le 5) \$foo is less than or equal to 5 #end #set($foo = false) #if ( not ($foo eq true)) foo is false #end -- #set($t = true) #set($f = false) Logical OR : #if($t or $f) right #else wrong #end #if( not ($f or $t) ) wrong #else right #end #if( $null or $t ) right #else wrong #end #if( $t or $null ) right #else wrong #end #if( $f or $null) wrong #else right #end #if( $null or $null ) wrong #else right #end Logical AND : #if( $t and $t) right #else wrong #end #if( $f and $f ) wrong #else right #end #if( not ($f and $f) ) right #else wrong #end #if( $t and $f ) wrong #else right #end #if( $t and $null ) wrong #else right #end #if( $null and $t ) wrong #else right #end #if( $f and $null ) wrong #else right #end #if( not ($null and $null) ) right #else wrong #end ---------- equivalence ----------- #set($int = 1) #set($str = "str") #set($bool = true) #if( $int eq $str) wrong #else right #end #if( $int eq 1 ) right #else wrong #end #if ( $int eq 2 ) wrong #else right #end #if( $str eq 2 ) wrong #else right #end #if( $str eq "str") right #else wrong #end #if( $str eq $nonexistantreference ) wrong #else right #end #if( $str eq $bool ) wrong #else right #end #if ($bool eq true ) right #else wrong #end #if( $bool eq false ) wrong #else right #end ----------- comparisons ----------- #set($int = 1) #set($str = "str") #set($bool = true) #if( $int gt 0 ) right #else wrong #end #if( $str gt 0 ) wrong #else right #end #if( $nonexistant gt 0 ) wrong #else right #end #if( $int ge 0 ) right #else wrong #end #if( $str ge 0 ) wrong #else right #end #if( $nonexistant ge 0 ) wrong #else right #end #if( $int lt 10 ) right #else wrong #end #if( $str lt 10 ) wrong #else right #end #if( $nonexistant lt 10 ) wrong #else right #end #if( $int le 10 ) right #else wrong #end #if( $str le 10 ) wrong #else right #end #if( $nonexistant le 10 ) wrong #else right #end ---------------------- goofy but legal stuff ---------------------- #set($lala = ( false or true ) ) Should equal true : $lala #set($fofo = ( true and true ) ) Should equal true : $fofo #set($fofo = ( true and ( false or true ) ) ) Should equal true : $fofo #set($fofo = ( ($t or $f) and $t)) Should equal true : $fofo #set($x = not true) #if($x eq false) right #else wrong #end #set($y = not $x) #if($y eq true) right #else wrong #end Test to see if we can do logical assignment from any expression #set($val = (3 eq 3)) #if($val eq true) right #else wrong #end #set($val = (1 lt 2)) #if( $val eq true) right #else wrong #end #set($val = (1 le 2)) #if( $val eq true) right #else wrong #end #set($val = (7 gt 2)) #if( $val eq true) right #else wrong #end #set($val = (7 ge 2)) #if( $val eq true) right #else wrong #end #set($val = ( 1 ne 2)) #if( $val eq true) right #else wrong #end velocity-1.7/test/templates/literal.vm0000644000175000017500000000063010315733667020066 0ustar moellermoeller#* @test literal.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #literal() #foreach ($woogie in $boogie) nothing will happen to $woogie #end #if($skin) $!data.setLayoutTemplate($!skin.getLayout()) $!page.setCss($!skin.getCss()) #end #end velocity-1.7/test/templates/subdir/0000755000175000017500000000000011675166244017360 5ustar moellermoellervelocity-1.7/test/templates/subdir/test.txt0000644000175000017500000000003010315733667021070 0ustar moellermoellerThis is included text! velocity-1.7/test/templates/testCase644.vm0000644000175000017500000000032311112556471020432 0ustar moellermoeller #macro(arrayError) #set($foo = []) $foo.get(2) #end #macro(nullMethod) #set($foo = $NULL) $foo.bar #end #macro(badRef) $bar #end #macro(forloop) #set($val = 1) #foreach($i in $val) #end #end velocity-1.7/test/templates/curly-directive.vm0000644000175000017500000000065110315733667021547 0ustar moellermoeller#* Check to see if directives with curly braces around them parse properly. *# #{if} (true) this is a test #{elseif} (true) more text #{else} this is a test #end ## a more realistic example #if(true)sometext#{else}more text#{end}and yet more ### others #{set} ($a = 3) #{macro}(mymacro) hello #{end} #{mymacro}() #foreach ($a in [1..3])x#{end} ## Check escaped directives \#if \#else \#elseif \#set velocity-1.7/test/templates/parse.vm0000644000175000017500000000047610315733667017554 0ustar moellermoeller#* @test parse.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Test the \#parse pluggable directive Now calling parse1.vm : --- #parse("parse1.vm") --- all done! velocity-1.7/test/templates/sample.vm0000644000175000017500000000122610315733667017715 0ustar moellermoeller#* @test sample.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Sample velocity page

Hello from velocity!

Here's the list of people #foreach ($name in $provider.Customers) #end
Names
$name
velocity-1.7/test/templates/foreach-map.vm0000644000175000017500000000044110315733667020614 0ustar moellermoeller#** @test foreach-map.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #foreach ($element in $provider.Hashtable) $element #end velocity-1.7/test/templates/foreach-array.vm0000644000175000017500000000200610315733667021154 0ustar moellermoeller#* @test foreach-array.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# --Foreach with an array. 2 blank lines follow ##foreach ($element in $provider.Array) #foreach ($element in $stringarray) #end
This is $element and it is the $velocityCount item
--Foreach with a null array. 1 blank line follows #foreach ($element in $woogiefoogie) #end
This is $element and it is the $velocityCount item
-- And when we declare the array in-template : #set($colors=["red","blue","green"]) Choose among : #foreach( $color in $colors ) $color #end #set($bar= 'bar') #set($foo = [ 'a' ]) #set($foo2 = [ $bar ]) #set($foo2 = [$bar ]) #set($foo2 = [ $bar]) #set($foo2 = [ $bar] ) #foreach( $i in $foo ) \$foo : $i #end #foreach($i in $foo2) \$foo2 : $i #end velocity-1.7/test/templates/diabolical.vm0000644000175000017500000000215210315733667020516 0ustar moellermoeller#* @test diabolical.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. This is for wierd strangeness that doesn't have any other home. *# $f. $f $f. $f #set($f = "foo") $f. $f $f. $f $thingy.dingy "#FFFFFF" "$ow" "$row","var" #333333 #FFFFFF "#FFFFF #FFFFF" "#000000"> "#ffffff" $strings.getVillageType($col.Type) $strings.getVillageType( $col.Type) $strings.getVillageType($col.Type ) -#-# Inline loops #-#- blargh>#foreach($a in $stringarray)<$a>#end#foreach($a in $stringarray) <$a>#end#foreach($a in $stringarray)<$a> #end#foreach($a in $stringarray) <$a> #end0)$foo#end #set($bar = "bar") #if ($bar.length()>0)$bar#end #set($a=1) #0F $nullToString $nullToString.toString() $!nullToString $!nullToString.toString() velocity-1.7/test/templates/velocimacro2.vm0000644000175000017500000000244310315733667021023 0ustar moellermoeller#** @test velocimacro2.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #macro( foo $a ) Hello from foo : $a #end #macro( foo2 $a ) Hello from foo2 : $a #end #macro( foo_two $a ) Hello from foo_two : $a #end #foo( "hi" ) #foo2( "hi" ) #foo_two( "hi" ) #foo( $notincontext ) #foo( $notincontext.getThing() ) #macro( tester $a ) #if($a) $a : yes #else $a : no #end #end ## ## test to see if we can print these ## as schmoo ## #tester( $notincontext ) #tester( $notincontext.woogie() ) #set($foo = "bar") #tester($foo) #foo2( ${foo} ) #macro( poundthis $truth ) #if ($truth ) # # \# #end #end #poundthis( true ) ## ## test for bug reported when stringlit changed to on-init parsing ## #macro( blorp $bar ) $bar #end #macro( schlorp $i )#blorp( "hi $i" ) #end #schlorp("victor") ## ## test all directive arg types ## #macro(dirarg $a) >$a< #end #set($ref = 1) #dirarg(1) #dirarg(true) #dirarg(false) #dirarg("hello") #dirarg('hello') #dirarg($ref) #dirarg([1..10]) #dirarg(['a','b',$ref]) velocity-1.7/test/templates/foreach-type.vm0000644000175000017500000000107410315733667021023 0ustar moellermoeller#* @test foreach-type.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Using a Object [] #foreach( $i in $obarr) $i #end Using a Map #foreach( $i in $map ) $i #end Using a Collection #foreach($i in $collection ) $i #end Using an Iterator #foreach($i in $iterator ) $i #end Using an Enumeration #foreach($i in $enumerator) $i #end Using an array of primitives #foreach( $i in $intarr ) $i #end velocity-1.7/test/templates/encodingtest.vm0000644000175000017500000000015310315733667021120 0ustar moellermoellerThanks to Kent Johnson for this example and the nudge.

Chinese: 网站登录

Spanish: niño

velocity-1.7/test/templates/foreach-null-list.vm0000644000175000017500000000053510315733667021766 0ustar moellermoeller#* @test foreach-null-list.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# Foreach with a list that contains null. #foreach ($element in $nullList) This is $element. $velocityCount #end velocity-1.7/test/templates/math.vm0000644000175000017500000000360610315733667017371 0ustar moellermoeller#* @test escape.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests the basic integer math capabilities. *# Addition and subtraction : #set($foo = 1) #set($foo = $foo + 1) 1 + 1 = $foo $foo - 1 = #set($foo = $foo - 1 )$foo Multiplication, division, and modulus : #set($bar = 5) #set($rem = $bar % 2) #set($rem2 = $bar % 0) #set($rem3 = 7%2) $bar % 2 = $rem $bar % 0 = $rem2 7 % 2 = $rem3 $bar / 2 = #set($rem = $bar / 2 )$rem $bar / 0 = #set($rem4 = $bar / 0 )$rem4 $bar * 2 = #set($rem = $bar * 2 )$rem $bar * -1 = #set($rem = $bar * -1)$rem $bar * -2 = #set($rem = $bar *-2)$rem $bar * -2 = #set($rem = -2*$bar)$rem And now null nodes to make sure it doesn't throw an NPE : #set($flargh=$woogie + $wabbie) Some test for the new number-handling $int1 + $long1 = #set ($rem = $int1 + $long1)$rem $int1 - $long1 = #set ($rem = $int1 - $long1)$rem $int1 * $long1 = #set ($rem = $int1 * $long1)$rem $int1 / $long1 = #set ($rem = $int1 / $long1)$rem $int1 % $long1 = #set ($rem = $int1 % $long1)$rem $int1 + $float1 = #set ($rem = $int1 + $float1)$rem $int1 - $float1 = #set ($rem = $int1 - $float1)$rem $int1 * $float1 = #set ($rem = $int1 * $float1)$rem $int1 / $float1 = #set ($rem = $int1 / $float1)$rem This checks that an object implementing TemplateNumber can be used in arithmetic $int1 + $templatenumber1.AsNumber = #set ($rem = $int1 + $templatenumber1)$rem $int1 - $templatenumber1.AsNumber = #set ($rem = $int1 - $templatenumber1)$rem $int1 * $templatenumber1.AsNumber = #set ($rem = $int1 * $templatenumber1)$rem $int1 / $templatenumber1.AsNumber = #set ($rem = $int1 / $templatenumber1)$rem Test integer division 5 / 2 = #set($result = 5 / 2)$result Test decimal division 5 / 2.0 = #set($result = 5 / 2.0)$result 5.0 / 2 = #set($result = 5.0 / 2)$resultvelocity-1.7/test/templates/settest.vm0000644000175000017500000000060710315733667020131 0ustar moellermoeller* @test settest.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests #set parsing funkyness *# #macro( setthing $a ) I am setthing : $a #end #set($foo = "bar") #set ($foofoo = "barbar") #setthing( $foo ) SessionBean#setSessionContext velocity-1.7/test/templates/if.vm0000644000175000017500000000051010315733667017025 0ustar moellermoeller#* @test if.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #if (true) this is true #end #if (false) this is false #end #if ($foo) this isn't defined yet. #end velocity-1.7/test/templates/reference.vm0000644000175000017500000000252010315733667020370 0ustar moellermoeller#* @test reference.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($_foo = "bar") $_foo #if ($_foo.equals("bar")) \$_foo equals "bar" : $_foo #end Late introspection : $vector.firstElement().length() More stupid reference escaping ... When it does exist in the context : #set($foo = "foo") $foo \$foo \$!foo $\!foo $\\!foo \$\!foo And when it doesn't : $bar \$bar \$!bar (because it's just text...) $\!foo $\\!foo $\\\!foo $\\\\!foo \\$\!foo Misc tests : [$foo.bar] Test lower case property names $provider.Title $provider.title #foreach($i in $provider.vector) $i #end #foreach($i in $provider.Vector) $i #end Now test if we can use lowercase for propertes in set #set($oldtitle = $provider.title) Was : $oldtitle #set($provider.title = "geir") Now : $provider.title #set($provider.title = $oldtitle) Back : $provider.title Test what was a bug : #set($b = 'boy') #set($c = 'cat') $b${c}.java ${b}${c}.java More tests : $provider.title $$provider.title #$provider.title $foo.bar#if( $foo ) ($bar) #end Test boolean introspection isFoo() #if( $boolobj.boolean == true ) Correct #else Wrong #end #if ( $boolobj.notboolean == true ) Wrong #else Correct #end velocity-1.7/test/templates/foreach-introspect.vm0000644000175000017500000000031010315733667022224 0ustar moellermoeller## ## tests a difficult introspection problem - ## the iterator is a private inner class ## #set($array = [1..10]) #set($it = $array.iterator()) #foreach($num in [21..30]) $num $it.next() #end velocity-1.7/test/templates/comment.vm0000644000175000017500000000143210315733667020075 0ustar moellermoeller#* @test comment.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# ## this is a single line comment #* this is a multi line comment #if ( *# #** @author jason van zyl *# this is some text. The following is a 'Christoph Comment' ;) ## ## foo We can now comment after the inline set : #set( $foo = 1 ) ## and this is a set statement ## here is a Nathan Bubna bug : $bar## #set($foo = 'foo!' ) $foo ## here's one reported by Daniel Dekany $## there is a dollar before me Test of multiline/singleline combo ## fix for bug 7697 #* multiline ## embedded singline comment stuff *# with some closing text ##test velocity-1.7/test/templates/include.vm0000644000175000017500000000046010315733667020056 0ustar moellermoeller#* @test include.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #include("include.vm" "include.vm") #set($foo = "subdir/test.txt") #include($foo) velocity-1.7/test/templates/VM_global_library.vm0000644000175000017500000000046410315733667022025 0ustar moellermoeller#macro( quietnull $a) #if($a)$a#end #end #macro( recurse $a ) global recurse $a #set( $a = $a - 1) #if ($a > 0) #recurse( $a ) #end #end #macro( callrecurse ) #set( $count = 5) #recurse( $count ) #end #macro( testbool $b ) #if($b) arg true #end #if( ! $b ) arg false #end #end velocity-1.7/test/templates/stop3-include.vm0000644000175000017500000000010110405661436021106 0ustar moellermoellerA line from stop3-include.vm #stop This line should not be seen. velocity-1.7/test/templates/range.vm0000644000175000017500000000216410315733667017532 0ustar moellermoeller#* @test range.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. Tests the range operator [n..m] *# [1..5] #foreach($i in [1..5]) $i #end ----- [0..0] #foreach($i in [0..0]) $i #end ----- [-4..-5] #foreach($i in [-4..-5]) $i #end ----- [ 1 .. 5 ] #foreach($i in [ 1 .. 5 ]) $i #end ----- [5..1] #foreach($i in [5..1]) $i #end ----- [-5..5] #foreach($i in [-5..5]) $i #end ----- [5..-5] #foreach($i in [5..-5]) $i #end ----- #set($a = 1) #set($b = 5) refs \$a=$a \$b=$b [\$a..\$b] #foreach($i in [$a..$b]) $i #end ----- [\$a.. 7] #foreach($i in [$a.. 7]) $i #end ----- [-7 ..\$a] #foreach($i in [-7 ..$a]) $i #end ----- [ -7 ..\$a] #foreach($i in[ -7 ..$a]) $i #end ------ #set($foo = [0..5]) setting in \$foo -> [0..5] : #foreach($i in $foo )$i #end ---- Now some use-case examples. Suppose we want a table to have 10 rows #set($arr = ["a","b","c"]) #foreach($i in $arr) #end #foreach($i in [4..10]) #end
$i
 
=done= velocity-1.7/test/templates/equality.vm0000644000175000017500000000076310315733667020276 0ustar moellermoeller#* @test equality.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# #set($user = "jason") #set($login = false) #set($count = 5) #if ($user == "jason") the user $user is logged in! #end #if ($count == 5) the count is 5! #end #if ($login == false) the user isn't logged in. #end #if ($count != 3) \$count is not equal to 3 #end velocity-1.7/test/macroforwarddefine/0000755000175000017500000000000011675166244017733 5ustar moellermoellervelocity-1.7/test/macroforwarddefine/macros.vm0000644000175000017500000000066511142375333021560 0ustar moellermoeller#macro(test1 $p) #test2($p) #end #macro(test1b $p) #foreach($i $foo) #test2($p) #end #end #macro(test2 $p) $!p #end #macro(test3 $p) #test1($p) #end #macro(test4 $p) #test2($p) #end #test1("foo") #test2("foo") #test3("foo") #test4("foo") #test1() #test2() #test3() #test4() #test1("foo", "bar") #test2("foo", "bar") #test3("foo", "bar") #test4("foo", "bar") #@test1("foo", "bar")#end #@test1("foo")#end #@test1()#end velocity-1.7/test/macroforwarddefine/compare/0000755000175000017500000000000011675166244021361 5ustar moellermoellervelocity-1.7/test/macroforwarddefine/compare/velocity.log.cmp0000644000175000017500000000117311142375333024470 0ustar moellermoeller [debug] VM #test1: too few arguments to macro. Wanted 1 got 0 [debug] VM #test2: too few arguments to macro. Wanted 1 got 0 [debug] VM #test3: too few arguments to macro. Wanted 1 got 0 [debug] VM #test4: too few arguments to macro. Wanted 1 got 0 [debug] VM #test1: too many arguments to macro. Wanted 1 got 2 [debug] VM #test2: too many arguments to macro. Wanted 1 got 2 [debug] VM #test3: too many arguments to macro. Wanted 1 got 2 [debug] VM #test4: too many arguments to macro. Wanted 1 got 2 [debug] VM #test1: too many arguments to macro. Wanted 1 got 2 [debug] VM #test1: too few arguments to macro. Wanted 1 got 0 velocity-1.7/test/cpload/0000755000175000017500000000000011675166244015334 5ustar moellermoellervelocity-1.7/test/cpload/compare/0000755000175000017500000000000011675166244016762 5ustar moellermoellervelocity-1.7/test/cpload/compare/test2.cmp0000644000175000017500000000004707251021011020476 0ustar moellermoeller this is a template for test2.jar velocity-1.7/test/cpload/compare/test1.cmp0000644000175000017500000000004707251021011020475 0ustar moellermoeller this is a template for test1.jar velocity-1.7/test/cpload/test1.jar0000644000175000017500000000112607251020723017054 0ustar moellermoellerPK‰e* META-INF/þÊPKPK‰e*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK ãˆe* template/PKɈe*template/test1.vmãâ*ÉÈ,V¢D…’ÔÜ‚œÄ’T…´ü" §¸ÄP/+±H¸PK¶‚$'PK‰e* META-INF/þÊPK‰e*3ù5¤DD=META-INF/MANIFEST.MFPK ãˆe* Ãtemplate/PKɈe*¶‚$'êtemplate/test1.vmPKóMvelocity-1.7/test/cpload/test2.jar0000644000175000017500000000112607251020723017055 0ustar moellermoellerPK:‰e* META-INF/þÊPKPK:‰e*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK *‰e* template/PK%‰e*template/test2.vmãâ*ÉÈ,V¢D…’ÔÜ‚œÄ’T…´ü" §¸ÄH/+±H¸PK µï$'PK:‰e* META-INF/þÊPK:‰e*3ù5¤DD=META-INF/MANIFEST.MFPK *‰e* Ãtemplate/PK%‰e* µï$'êtemplate/test2.vmPKóMvelocity-1.7/test/texen-classpath/0000755000175000017500000000000011675166244017175 5ustar moellermoellervelocity-1.7/test/texen-classpath/compare/0000755000175000017500000000000011675166244020623 5ustar moellermoellervelocity-1.7/test/texen-classpath/compare/WeatherService.java0000644000175000017500000000212110513464370024371 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.Service; /** * * @author Jason van Zyl */ public interface WeatherService extends Service { public static final String SERVICE_NAME = "TurbineWeatherService"; } velocity-1.7/test/texen-classpath/compare/TurbineWeather.java0000644000175000017500000000250710513464370024411 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.TurbineServices; /** * * * @author Jason van Zyl */ public class TurbineWeather { /** * Utility method for accessing the service * implementation * * @return a WeatherService implementation instance */ protected static WeatherService getService() { return (WeatherService)TurbineServices .getInstance().getService(WeatherService.SERVICE_NAME); } } velocity-1.7/test/texen-classpath/compare/book.txt0000644000175000017500000000046210315733667022317 0ustar moellermoellerThis is the book of the week: Props retrieved using new method: Title: Consilience: The Unity of Knowledge Author: Edward O. Wilson Publisher: Knopf ISBN: 0965058305 Props retrieved using old method: Title: Consilience: The Unity of Knowledge Author: Edward O. Wilson Publisher: Knopf ISBN: 0965058305 velocity-1.7/test/texen-classpath/compare/TurbineWeatherService.java0000644000175000017500000000227210513464370025731 0ustar moellermoellerpackage org.apache.turbine.services.weather; /* * 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. */ import org.apache.turbine.services.TurbineBaseService; /** * * @author Jason van Zyl */ public class TurbineWeatherService extends TurbineBaseService implements WeatherService { /** * Initialize the TurbineWeather Service. */ public void init() { setInit(true); } } velocity-1.7/test/texen-classpath/compare/Test.txt0000644000175000017500000000015510315733667022303 0ustar moellermoeller# These should all evaluate to true true true true # These should all evaluate to false false false false velocity-1.7/test/texen-classpath/jar-contents/0000755000175000017500000000000011675166244021604 5ustar moellermoellervelocity-1.7/test/texen-classpath/jar-contents/Test.vm0000644000175000017500000000015610315733667023070 0ustar moellermoeller# These should all evaluate to true $one $two $three # These should all evaluate to false $four $five $six velocity-1.7/test/texen-classpath/jar-contents/license.txt0000644000175000017500000000145510513464370023763 0ustar moellermoeller/* * 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. */ velocity-1.7/test/texen-classpath/jar-contents/Control.vm0000644000175000017500000000160510315733667023571 0ustar moellermoeller#set ( $sourceFile = "Turbine${baseName}Service.java" ) $generator.parse("ServiceImplementation.vm",$sourceFile) #set ( $sourceFile = "${baseName}Service.java" ) $generator.parse("ServiceInterface.vm",$sourceFile) #set ( $sourceFile = "Turbine${baseName}.java" ) $generator.parse("ServiceStaticHelper.vm",$sourceFile) #set ( $sourceFile = "Test.txt" ) $generator.parse("Test.vm",$sourceFile) #set ( $props = $properties.load("test.props") ) ## This is to test a properties file that was once taken from ## the file system but is now taken from a JAR. We have to ## deprecate the use of $generator.TemplatePath if we want ## templates to work the same way from JARs and the file ## system. I have a hack in PropsUtil right now to deal ## with it. #set ( $props2 = $properties.load("$generator.TemplatePath/test.props") ) #set ( $sourceFile = "book.txt" ) $generator.parse("book.vm",$sourceFile) velocity-1.7/test/texen-classpath/jar-contents/test.props0000644000175000017500000000157710513464370023651 0ustar moellermoeller# 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. author = Edward O. Wilson title = Consilience: The Unity of Knowledge publisher = Knopf isbn = 0965058305 velocity-1.7/test/texen-classpath/jar-contents/ServiceInterface.vm0000644000175000017500000000040510315733667025367 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.Service; /** * * @author $name */ public interface ${baseName}Service extends Service { public static final String SERVICE_NAME = "Turbine${baseName}Service"; } velocity-1.7/test/texen-classpath/jar-contents/service.props0000644000175000017500000000206310513464370024321 0ustar moellermoellerbaseName=Weather package=org.apache.turbine.services.weather name=Jason van Zyl email=jvanzyl@apache.org # 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. license.file.contents = test/texen/license.txt # Test some properties that have be give some boolean # values. one = true two = yes three = on four = false five = no six = off velocity-1.7/test/texen-classpath/jar-contents/ServiceImplementation.vm0000644000175000017500000000056210315733667026460 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.TurbineBaseService; /** * * @author $name */ public class Turbine${baseName}Service extends TurbineBaseService implements ${baseName}Service { /** * Initialize the Turbine${baseName} Service. */ public void init() { setInit(true); } } velocity-1.7/test/texen-classpath/jar-contents/ServiceStaticHelper.vm0000644000175000017500000000100510315733667026053 0ustar moellermoellerpackage $package; $license import org.apache.turbine.services.TurbineServices; /** * * * @author $name */ public class Turbine$baseName { /** * Utility method for accessing the service * implementation * * @return a ${baseName}Service implementation instance */ protected static ${baseName}Service getService() { return (${baseName}Service)TurbineServices .getInstance().getService(${baseName}Service.SERVICE_NAME); } } velocity-1.7/test/texen-classpath/jar-contents/book.vm0000644000175000017500000000052210315733667023100 0ustar moellermoellerThis is the book of the week: Props retrieved using new method: Title: $props.get("title") Author: $props.get("author") Publisher: $props.get("publisher") ISBN: $props.get("isbn") Props retrieved using old method: Title: $props2.get("title") Author: $props2.get("author") Publisher: $props2.get("publisher") ISBN: $props2.get("isbn") velocity-1.7/test/texen-classpath/test.jar0000644000175000017500000001024610513464370020644 0ustar moellermoellerPKpŽL5 META-INF/þÊPKPKpŽL5META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ˜èÅ)h—æ)øf&åW—¤æ+xæ%ëiòrñrPK—c“¡GGPK|Œ.4book.vm…Ž? Â0G÷|Š£8èâ±›n.R°_À³9“?í×÷ZpˆÐ 7¿÷†×JÀ— ‚ò~ÿZÿql…è¢ "æH8¡†’È àp†7fã5+=e‹-¢žÌÇ&/Ss—ÂN¬ÙsÝvEYJxøÎ¬Ü×{M))Ç`£Ë[½Ñ%÷Âä¿2¹Ÿ&«¶PK%àhgŽRPK{Œ.4 Control.vmRMKÃ@½÷W i-È Þ=xëAŠ­xž¤“fM²v'‰EüïînŠ›b›åÍû˜™:˜ÃÌqk3º×Á-$›Ö¦ÚÐì#EGOXÓçšl§3RoØa‹ÉlG†, [Õ u4O˺©¨&#(šêêäêH|1™LGÿee„l޾ôR—Ó¾þvY‡N²ª²—‘%ï2®ÑóRåÆy•øCV49U1nç‰b„“Æ6…và?a( ü° q¤@°Éü K2[®[ ŠÜÞ Õ¶Ä ÷G…^óñîYÁ+A—à@ÝRc)C¡(Ò:Îá¨× ù—àáJ:‡ž|#ÑõÅÔ=Û2J8¿_²<½£4Ûïˆ8¤T°‚ ?²´U˜É‹è ¬Þ24À>#V×ëAÔ¯ߌùL×'ÃÝ|Ê\žß|DO6ÿPKN±†\…PK[ŽL5 license.txteRÁnÛ0 ½ç+ˆœÚ"‹‡·“×&¨ÑÂ"wEŠMÛÄlI“ä¹ùûQŠÝØIÄ÷øÞ#“» ÜÁ3U¨Öà5ø!5²âCèÆOÒ"õ¨jéI+¸IÅñøŠ´Â€ÖÍU•VÞÒyôüÐ_A¶q@åÝ@ Fú¼(³û4ÔG|MîŠcùŽkÈÁ¤íoh˜JÖ5…Ö²Rü0D!h±•¶&Õrks±Ôvô¤ÐºŽ ÷+ƒq\ĸ+ñÒ–½^ô8[Y¹žÃØÁ/& –¿í¿Â ÐvþÝÞþˆèA^@i£ÃOvÀ÷ g¹,l0=IUEôìî£k|›IôÙK®—Ñ èf]Ò3:tÞ›ïI2MÓ^F½{mÛdq˜/%¼¦§Sš—ÙA@q‚û"ÈʬÈùv„4 ȧ,Ør`Ü ß &X)…<±^mÓ¢!ìÊ<%g°¢†*¶§ÚQ¶­þ‹V…U1hra°ŽEÖ¼ù¸R.@ÿóÆø'ÙlþPK²8"ÊÍ-PK|Œ.4ServiceImplementation.vmmNÍjÃ0 ¾ë)Dñ¡ÍÁ¹¯]½í²K÷Jª5fŽl¥”•¼ûlÇŒÁ&Ÿ¿¿‰úOº2ªi=öÊšž]d3N>úpÕ”þÖ2‡Î8Ö‘Ã-±¢~_E>¯Xrh›0/¾Ð,ƒx •%QøkÜÑ(MïpMØ8®6AG¦•~òÛÐRÇë„¶JN` }ˆÆ »ŠJ2äù¬œÏâŽü¶Ë Ö¢ôB¢£2–ZÌÅ[cž]nÇCv?ïOn0¸Î¹ÿ­ƒ>ðPKº@έ¸PKjŒL5 service.propseSÑn›@|¿¯X9/‰ä⪭,ÕMb•6ÂR Ò·¸îèÝaì~}ç0n,õ vfgf÷ré8‘¯ŸYú†­èeñ*k^‡†#?Ø\iŽÛ½*ØEã\«ð›tFÓ^júylwRµë_8þ9¶Ÿgp qEkÇ%yCÀÓfúK©©ü(-ÓÖ º”^îz“noG¶d4l,uE…ÑÞª|ðøÐžIÖ–¹cí]D”2OìÉ.‹oï©Rm€—Ê`h?*ß D9}¥ L²,Uh,[RºIp–kiK¥k4îVÕ'3j¶®Q=ºeÁGº=Kq'Þ¹)|Í0Û¸p<±¤à v?DïéÀ,柋›O¸“GÒÆÓàø›øPpº¾UR<;û×_f“{‰r9ù S]–‘ôâ p¢Æûþãj5Žcô6»ÕÙÜê‰&éý;èOºeçÒïAY$›IöSÈ"[9†±MÓ™†Žþ£Eκ^ìÎs¿œÍ[Vgm°|Y€´dÌb“Rœ.èË&Ó%=ÇÙ×ÝSFÏ›ÇÇM’Å÷)íév—ÜÅY¼KpÚÒ&yð{œÜ-‰UØ`äØÛà2Uȑˋ :+ rŽë¹P•*`M×® ÕfÏV‡ýèÙvÊ…q:(,±òÓ9 ÿó…>DBÌÑFaªQØí°Å´&Ïί<XŸÓüÁ‡[”á²ë˜zkÐÔ«i뤧Fî™rhRxN¹1-Oqíe;àæ ÛèíÀ¯GvÂ7Þ±ò¢2ƒÅk%[Ç¢ Tk, pê ªJüPKɺ¨@j3PK|Œ.4ServiceStaticHelper.vmmPÍnÂ0 ¾ç),Ôí!½†@SÆal»N&˜6Z›V‰™4¡¾ûÜ’NÌŠÇþ~ìth>±$Hºk²P*©­!H)Ût­gh}©Qúi>ûƒu¤ù/Aýz-ìã[èy–)ˆÖxæªõ°D¨<g ÚšÛ‡„†d¶J6´Ìq%à\uçƒxƒ©1ˆÊÉí¥. $Fù!2xc[[þ††Äã'ñA#CëJàŠ N Aö©©!Çȶu±:5מd;Éeòìã^7L°.0:C‘›wç[&Ãt„0ÀÌ:%qLçéHº.5D´Ÿß³Ò›Oþ¥ ¡ErÇ™§úÁ½Þ/ïÛ§âc·y.ÒŨӫ^ýPKßþïPKjŒL5 test.propseRMoÚ@½ó+FpI$ ¨Uª6—€j%2†¢{0£Ú»îîºÿ¾oizBkæÍûš½HÆÚqNÞ?1EµÊ𓚣o•eZ™FçÊ‹Ñt¥«{“-̓K•ÁPf´·rh<>”—…¤ Ë\±önB”2wÛ“õ6^,é(e€çâ.0зâOG­±¿èˆM*Ï%«’DãCÕÉÎr¡l.ºq}¶Rœ<™V³u'©Á¶ >ÒÕUŠ»ìíIáólšÞÆã>ˆ1ýÄž`÷ãdFwfØÿ9¼ÿÖ+u&m<5Žßw¿e\{h…¬ª.Eé,€{gÿ ðµßa^a\u>ÈoÇHùÁp¢“÷õãtÚ¶íDuZ'ÆÓ«¹é MÒåèí;]²séw#ÉΤjÈÉÔ"KÕ†ÚºvºÒÁßZ䬋1ÀîÚûm7ïY]µÁòíÒR¡˜a”Rœé{”Æé˜öñöÇz·¥}´ÙDÉ6^¦´ÞÐb<ÅÛxൢ(yð9NžÆÄH DüVÛà2%äÈùÍ]„¹”ãjÎä(¬é¢QSaþ°Õá>j¶•¸P§ƒÂQ‰ïÎÈùŸ/ð TãOØ>§eŽ(rZOh/¥ÃéyñˆpN àÂPðcwm;-¾+ðY›¶ä¼àAÝJqÁÏ<|­qÇìëç‡Ù×O³‡Á_PK»þ  PK{Œ.4Test.vm}ËÁ À0@Ñ»SÉH]@¨Á€TˆšvüÚzù‡¯á!ìŒ.–z"©"oÒ¤` ÃXÉÝ.†·UdqöÏ©nX®êÜÅ}>ðPK?–JnPKpŽL5 META-INF/þÊPKpŽL5—c“¡GG=META-INF/MANIFEST.MFPK|Œ.4%àhgŽRÆbook.vmPK{Œ.4N±†\… ‰Control.vmPK[ŽL5²8"ÊÍ- license.txtPK|Œ.4ü²‡¬Ùr#ServiceImplementation.vmPK|Œ.4º@έ¸BServiceInterface.vmPKjŒL5ɺ¨@j3 ;service.propsPK|Œ.4ßþïà ServiceStaticHelper.vmPKjŒL5»þ   6 test.propsPK{Œ.4?–Jn{ Test.vmPK –ú velocity-1.7/test/texen-classpath/mkjar.sh0000755000175000017500000000154410513464370020633 0ustar moellermoeller# !/bin/sh # 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. ( cd jar-contents rm -f ../test.jar jar cvf ../test.jar * ) velocity-1.7/test/resourcecaching/0000755000175000017500000000000011675166244017236 5ustar moellermoellervelocity-1.7/test/resourcecaching/testincludeparse.vm0000644000175000017500000000012610315733667023156 0ustar moellermoellerline 1 #include("include/include1.vm") line 2 #parse("include/include1.vm") line 3velocity-1.7/test/resourcecaching/include/0000755000175000017500000000000011675166244020661 5ustar moellermoellervelocity-1.7/test/resourcecaching/include/include1.vm0000644000175000017500000000000610315733667022724 0ustar moellermoellertest velocity-1.7/test/evaluate/0000755000175000017500000000000011675166244015700 5ustar moellermoellervelocity-1.7/test/evaluate/evalvmcontext.vm0000644000175000017500000000030410702016743021124 0ustar moellermoeller## test of evaluate in a macro context whith local refs (foreach refs) #macro(testEval $expr) #foreach($value in ["val1", "val2"])value is : #evaluate( $expr );#end #end #testEval( "${value}" ) velocity-1.7/test/evaluate/compare/0000755000175000017500000000000011675166244017326 5ustar moellermoellervelocity-1.7/test/evaluate/compare/eval1.cmp0000644000175000017500000000012610601516613021021 0ustar moellermoeller basic string embedded reference zz zz reference zz changes to xx test1: zz velocity-1.7/test/evaluate/compare/eval2.cmp0000644000175000017500000000014511036460351021023 0ustar moellermoellertest 1: a: 12 basic string test 2: a: 22 test 3: inner eval: 33 basic string test 4: inner eval: 44 velocity-1.7/test/evaluate/compare/evalvmcontext.cmp0000644000175000017500000000004210702016743022706 0ustar moellermoeller value is : val1;value is : val2;velocity-1.7/test/evaluate/eval1.vm0000644000175000017500000000071310601516613017240 0ustar moellermoeller## Testing the evaluate directive #evaluate("basic string") #set($test1 = "zz") #set($test2 = '$test1') #evaluate("embedded reference $test2") #evaluate($test2) ## Now check that #evaluate doesn't change context ## Need to use single quote to surround #set to prevent premature evaluation #set($teststring = "reference $test2 changes to" + '#set($test1 = "xx") $test1') #evaluate($teststring) ## Check that test1 hasn't changed test1: $test1 velocity-1.7/test/evaluate/eval2.vm0000644000175000017500000000046211036460351017242 0ustar moellermoeller## ## Test evaluate preserves macros ## #macro (test $a) a: $a #end test 1: #test(12) #evaluate("basic string") test 2: #test(22) ## ## Test again while doing evaluate within macro ## #macro (test2 $a) #evaluate("inner eval: $a") #end test 3: #test2(33) #evaluate("basic string") test 4: #test2(44) velocity-1.7/test/ds/0000755000175000017500000000000011675166244014500 5ustar moellermoellervelocity-1.7/test/ds/create-db.sql0000644000175000017500000000306310513464370017040 0ustar moellermoeller-- 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. drop table velocity_template if exists; create table velocity_template ( id VARCHAR(64) not null, timestamp TIMESTAMP, def VARCHAR(255) not null ); insert into velocity_template (id, timestamp, def) VALUES ( 'testTemplate1', NOW(), 'I am a test through the data loader'); insert into velocity_template (id, timestamp, def) VALUES ( 'testTemplate2', NOW(), '$tool.message $tool.add(23, 19)'); insert into velocity_template (id, def) VALUES ( 'testTemplate3', 'This is a template with a null timestamp'); insert into velocity_template (id, timestamp, def) VALUES ( 'testTemplate4', NOW(), '#testMacro("foo")'); insert into velocity_template (id, timestamp, def) VALUES ( 'VM_global_library.vm', NOW(), '#macro (testMacro $param) I am a macro using $param #end'); velocity-1.7/test/ds/templates/0000755000175000017500000000000011675166244016476 5ustar moellermoellervelocity-1.7/test/ds/templates/testTemplate1.cmp0000644000175000017500000000004310503231015021702 0ustar moellermoellerI am a test through the data loadervelocity-1.7/test/ds/templates/testTemplate2.cmp0000644000175000017500000000002510503231015021703 0ustar moellermoellerAnd the result is: 42velocity-1.7/test/ds/templates/testTemplate3.cmp0000644000175000017500000000005010503231015021702 0ustar moellermoellerThis is a template with a null timestampvelocity-1.7/test/ds/templates/testTemplate4.cmp0000644000175000017500000000003010503231015021701 0ustar moellermoeller I am a macro using foo velocity-1.7/test/configuration/0000755000175000017500000000000011675166244016741 5ustar moellermoellervelocity-1.7/test/configuration/include1.properties0000644000175000017500000000146710513464370022562 0ustar moellermoeller# 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. include1.property = somnambulance velocity-1.7/test/configuration/include2.properties0000644000175000017500000000146210513464370022556 0ustar moellermoeller# 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. include2.property = insomnia velocity-1.7/test/configuration/compare/0000755000175000017500000000000011675166244020367 5ustar moellermoellervelocity-1.7/test/configuration/compare/output.cmp0000644000175000017500000000472207302024413022414 0ustar moellermoeller-------------------------------------------------- Testing order of keys ... -------------------------------------------------- 01 02 03 04 05 06 07 08 09 10 resource.loader file.resource.loader.class file.resource.loader.description file.resource.loader.path classpath.resource.loader.class classpath.resource.loader.description datasource.resource.loader.class datasource.resource.loader.description logger.type config.string.value config.boolean.value config.byte.value config.short.value config.int.value config.long.value config.float.value config.double.value escape.comma1 escape.comma2 include1.property include2.property -------------------------------------------------- Testing retrieval of CSV values ... -------------------------------------------------- file classpath datasource -------------------------------------------------- Testing subset(prefix).getKeys() ... -------------------------------------------------- class description path -------------------------------------------------- Testing getVector(prefix) ... -------------------------------------------------- /path01 /path02 /path03 -------------------------------------------------- Testing getString(key) ... -------------------------------------------------- string -------------------------------------------------- Testing getBoolean(key) ... -------------------------------------------------- true -------------------------------------------------- Testing getByte(key) ... -------------------------------------------------- 1 -------------------------------------------------- Testing getShort(key) ... -------------------------------------------------- 1 -------------------------------------------------- Testing getInt(key) ... -------------------------------------------------- 30000 -------------------------------------------------- Testing getLong(key) ... -------------------------------------------------- 1000000 -------------------------------------------------- Testing getFloat(key) ... -------------------------------------------------- 3.14 -------------------------------------------------- Testing getDouble(key) ... -------------------------------------------------- 3.14159265358793 -------------------------------------------------- Testing escaped-comma scalar... -------------------------------------------------- foo, -------------------------------------------------- Testing escaped-comma vector... -------------------------------------------------- bar,lala woogie,bjork! velocity-1.7/test/configuration/test-config.properties0000644000175000017500000000651610513464370023300 0ustar moellermoeller# 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. 01 = 01 02 = 02 03 = 03 04 = 04 05 = 05 06 = 06 07 = 07 08 = 08 09 = 09 10 = 10 # --------------------------------------------------------- # Test CSV properties # --------------------------------------------------------- resource.loader = file, classpath, datasource file.resource.loader.class = FileResourceLoader file.resource.loader.description = File Resource Loader file.resource.loader.path = /path01 file.resource.loader.path = /path02 file.resource.loader.path = /path03 classpath.resource.loader.class = ClasspathResourceLoader classpath.resource.loader.description = Classpath Resource Loader datasource.resource.loader.class = DataSourceResourceLoader datasource.resource.loader.description = Datasource Resource Loader # --------------------------------------------------------- # Test multi same value keys # --------------------------------------------------------- logger.type = file logger.type = console logger.type = db # --------------------------------------------------------- # Testing String retrieval # --------------------------------------------------------- config.string.value = string # --------------------------------------------------------- # Testing boolean retrieval # --------------------------------------------------------- config.boolean.value = true # --------------------------------------------------------- # Testing byte retrieval # --------------------------------------------------------- config.byte.value = 1 # --------------------------------------------------------- # Testing short retrieval # --------------------------------------------------------- config.short.value = 1 # --------------------------------------------------------- # Testing integer retrieval # --------------------------------------------------------- config.int.value = 30000 # --------------------------------------------------------- # Testing long retrieval # --------------------------------------------------------- config.long.value = 1000000 # --------------------------------------------------------- # Testing float retrieval # --------------------------------------------------------- config.float.value = 3.14 # --------------------------------------------------------- # Testing double retrieval # --------------------------------------------------------- config.double.value = 3.14159265358793 # --------------------------------------------------------- # Testing escaped commas # --------------------------------------------------------- escape.comma1 = foo\, escape.comma2 = bar\,lala,woogie\,,bjork! include = include1.properties include = ./include2.properties velocity-1.7/test/methodoverloading/0000755000175000017500000000000011675166244017604 5ustar moellermoellervelocity-1.7/test/methodoverloading/single.vm0000644000175000017500000000036310512533674021425 0ustar moellermoeller## ambiguous method -- should not be processed $test.overloadedMethod($nullValue) ## is the correct method cached after null parameter $test.overloadedMethod2( $nullValue ) $test.overloadedMethod2( "a string" ) $test.overloadedMethod2( 1234 )velocity-1.7/test/methodoverloading/main.vm0000644000175000017500000000020310512533674021061 0ustar moellermoeller#set($param = $nullObject) #parse ( "sub.vm" ) #set($param = "string") #parse ( "sub.vm" ) #set($param = 1234) #parse ( "sub.vm" ) velocity-1.7/test/methodoverloading/compare/0000755000175000017500000000000011675166244021232 5ustar moellermoellervelocity-1.7/test/methodoverloading/compare/single.cmp0000644000175000017500000000013010512533674023200 0ustar moellermoeller$test.overloadedMethod($nullValue) $test.overloadedMethod2( $nullValue ) String Integervelocity-1.7/test/methodoverloading/compare/main.cmp0000644000175000017500000000006110512533674022646 0ustar moellermoeller$test.overloadedMethod2( $param ) String Integer velocity-1.7/test/methodoverloading/sub.vm0000644000175000017500000000012710512533674020733 0ustar moellermoeller## is the correct method cached after null parameter $test.overloadedMethod2( $param ) velocity-1.7/test/macrolibs/0000755000175000017500000000000011675166244016045 5ustar moellermoellervelocity-1.7/test/macrolibs/vm_library_local.vm0000644000175000017500000000016210663062343021717 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo #foo(1) #bar(2) no macro definition #abc(2) velocity-1.7/test/macrolibs/compare/0000755000175000017500000000000011675166244017473 5ustar moellermoellervelocity-1.7/test/macrolibs/compare/vm_library.cmp0000644000175000017500000000016210663062343022330 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo #foo(1) #bar(2) no macro definition #abc(2) velocity-1.7/test/macrolibs/compare/vm_library_global.cmp0000644000175000017500000000031010663062343023643 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo 24 no macro definition #abc(2) This is a test file for loading macro libs programatically call foo 86 no macro definition #abc(2) velocity-1.7/test/macrolibs/compare/vm_library_duplicate.cmp0000644000175000017500000000014410673652637024376 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo 86 no macro definition #abc(2) velocity-1.7/test/macrolibs/compare/vm_library_local.cmp0000644000175000017500000000047210663062343023506 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo 24 no macro definition #abc(2) This is a test file for loading macro libs programatically call foo 86 no macro definition #abc(2) This is a test file for loading macro libs programatically call foo #foo(1) #bar(2) no macro definition #abc(2) velocity-1.7/test/macrolibs/vm_library.vm0000644000175000017500000000016210663062343020545 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo #foo(1) #bar(2) no macro definition #abc(2) velocity-1.7/test/macrolibs/vm_library_global.vm0000644000175000017500000000016210663062343022065 0ustar moellermoellerThis is a test file for loading macro libs programatically call foo #foo(1) #bar(2) no macro definition #abc(2) velocity-1.7/test/macrolibs/vm_library1.vm0000644000175000017500000000015010663062343020623 0ustar moellermoeller#macro(bar $a) #if($a)#set($a = $a + $a)$a#end #end #macro(foo $a) #if($a)#set($a = $a + 1)$a#end #end velocity-1.7/test/macrolibs/vm_library2.vm0000644000175000017500000000015710663062343020633 0ustar moellermoeller#macro( bar $a) #if($a)#set($a = $a + $a + $a)$a#end #end #macro( foo $a) #if($a)#set($a = $a * 8)$a#end #end velocity-1.7/test/issues/0000755000175000017500000000000011675166244015405 5ustar moellermoellervelocity-1.7/test/issues/velocity-580/0000755000175000017500000000000011675166244017555 5ustar moellermoellervelocity-1.7/test/issues/velocity-580/compare/0000755000175000017500000000000011675166244021203 5ustar moellermoellervelocity-1.7/test/issues/velocity-580/compare/velocity580.vm.cmp0000755000175000017500000000001511032277545024411 0ustar moellermoellerbeforeafter velocity-1.7/test/issues/velocity-580/templates/0000755000175000017500000000000011675166244021553 5ustar moellermoellervelocity-1.7/test/issues/velocity-580/templates/velocity580.vm0000755000175000017500000000007211032277545024206 0ustar moellermoeller#macro(someMacro ) before#* *#after #end #someMacro() velocity-1.7/test/issues/velocity-537/0000755000175000017500000000000011675166244017557 5ustar moellermoellervelocity-1.7/test/issues/velocity-537/compare/0000755000175000017500000000000011675166244021205 5ustar moellermoellervelocity-1.7/test/issues/velocity-537/compare/velocity537.vm.cmp0000755000175000017500000000000011032277545024407 0ustar moellermoellervelocity-1.7/test/issues/velocity-537/compare/velocity537b.vm.cmp0000644000175000017500000000000111034602537024542 0ustar moellermoellerbvelocity-1.7/test/issues/velocity-537/templates/0000755000175000017500000000000011675166244021555 5ustar moellermoellervelocity-1.7/test/issues/velocity-537/templates/velocity537b.vm0000644000175000017500000000004111034602537024340 0ustar moellermoeller#macro( test )#* a*#b#end #test()velocity-1.7/test/issues/velocity-537/templates/velocity537.vm0000755000175000017500000000003711032277545024213 0ustar moellermoeller#macro( test )#* *##end #test()velocity-1.7/test/resourceinstance/0000755000175000017500000000000011675166244017446 5ustar moellermoellervelocity-1.7/test/resourceinstance/testfile.vm0000644000175000017500000000035410315733667021632 0ustar moellermoeller#* @test testfile.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# I am testfile.vm velocity-1.7/test/resourceinstance/compare/0000755000175000017500000000000011675166244021074 5ustar moellermoellervelocity-1.7/test/resourceinstance/compare/testfile.cmp0000644000175000017500000000002310256120454023372 0ustar moellermoeller I am testfile.vm velocity-1.7/test/absolute/0000755000175000017500000000000011675166244015710 5ustar moellermoellervelocity-1.7/test/absolute/absolute.vm0000644000175000017500000000035410322177512020060 0ustar moellermoeller#* @test absolute.vm This template is used for Velocity regression testing. If you alter this template make sure you change the corresponding comparison file so that the regression test doesn't fail incorrectly. *# I am absolute.vm velocity-1.7/test/absolute/compare/0000755000175000017500000000000011675166244017336 5ustar moellermoellervelocity-1.7/test/absolute/compare/absolute.cmp0000644000175000017500000000002610321131310021620 0ustar moellermoeller I am absolute.vm velocity-1.7/xdocs/0000755000175000017500000000000011675166245014234 5ustar moellermoellervelocity-1.7/xdocs/images/0000755000175000017500000000000011675166244015500 5ustar moellermoellervelocity-1.7/xdocs/images/powered-by-logo.gif0000644000175000017500000000460407257216154021203 0ustar moellermoellerGIF89aM ÷ppqÏÏТ¢£wxzãäæ#\ W'`%^&^%]%[#Y!R3eRTW\^a)a*`(_(]'\'[&X7h-Mx-e+b-b*_([,[+YÂËÖ¡¥ª0g0e/d.c-`-_+],]+Z*Y)X(U%N.^/_/a=m *K;j=m>m0QDr@kHt!Fp8W&Ny9Y3M,Gd&=V*@X[y™tŒ§}”­„š²7@JZhws„—Q]jENX†•¥• ¬ž©µ´¿Ë—¤ÍÓÚ2f2e/a(R0b+W2d/\(O3e6i2a$F6g*P,R 2].U 6c 9h 0V;j#>>m?nBq5Y;b"Kv-F5R(Qz8S(:2X:_…Df‰5MfNo‘Qq“)9J -:4GZE]vVrŽf‚Ÿ+3;h{Ž‘¥ºHQZAGMzƒŒ8;>VZ^puzdhlÑ×ÝëîñéìïQRSÁÃÅíïñòóôñòóìíĶÄÑÏØàiot­´ºÝãèçíñîñóæéëáæéçëíøúûõ÷øôö÷òôõúûû÷øøûüûõöõôõôýþüKKI@@?þþüüüúýýüúúùùùøööõÞÞÝÎÎÍ””“ˆ‡…ÿþüúù÷ø÷õïîìâáߤ¡œÓÑθ¶³÷õòéçäÖÔÑòïëÈÄ¿‚{tãßÛŸœ™654¾»¸½º·µ²¯ywusqoÑÎËÁ¾»ì鿍¦¤¯­«õóñæäâåãáßÝÛÛÙ×ÍËÉŸž™˜—’‘ŽŒŒ‹Œ‹Š…„ƒüûúúùøñðïíìëæåäãâጉ‡˜•“¢ŸËÈÆÉÆÄ¿¼º¶´³›™˜†„„öõõéèè×ÖÖÿÿÿïïïßßßÛÛÛ¿¿¿¯¯¯ŸŸŸ€€€~~~```PPP@@@000 ,M ÿß H° Áƒ*\ÈPà¼ÿékH1á½÷>ŒØ/@Ń÷A¬÷±¤À‹BÜçïß>“7¾y/¿þÀƒøNß?{ùÁó)1ÀÅ|ÿèÕë÷¯_ÆzþüÝLùn㽩þx^Åíµ¤‡ôžÏú.ÚiϞˋ9ƒÎ»Y'½©#Ú÷_‰7Bððeáº7}Þä«£ÖwõŠ|‰2ï¿ypgjýGò+O|ûÁs›^K]¾c Þ=ÌßÕX¯ÞCÑ>©ZõéOvÓ^=ÿ#X¢ÐwHó­æüŽ^Ë‘•5‡‡´ol•zí d:ñ#¼yó ~ÿ÷z^¼wæÿ®þ]<óÓ“GàûyìÁß×L¯âªÿ(à€hàÿe£JSþ7е< „TKƒF(¡,øà †¾óJ#¤¼!$Œ”x`)•A‰-b8à(”Œ«h#‚¾3Hh4@¥ÜÁî´²c€ïl‚†A,óÎ’2¾C‰x!‚+ï”Òˆ%¤PI`F Aæ´ ˆ ,&ø#hl0Ç1SÊÈ$% hààøè€˜t§=BqE 8ÔÓÊ;•\Aå”R‹†9ÈÈ vây!¦yê*ï°£Ä|pÃÎ;e²H/Åÿ¨#©™¾Ó %`qÏ)¬VpÂÕ ” !ð*Цv3¥@œT‚'™:øN&ÎBòÎ(¡ˆS5â”J ¬ Ÿ‚┵ âÉ&¥Dª+wL Â¾¼sGV<ÐδD A uPrËœœÎ¡ì; qÿ9á©™QÿoC ¢WÐÁî0½Åà mL¦˜ l`txƲÞÑ„L   @úPÐ<0€ÀÃ0¤Àƒ &øÂ>Âà %X` @€úð Pì _؆¡Bp… ” b¨G-N!‡L¡Ø­uFAôAˆ(£ƒ€?a{(7ö?ü„øÅ;aÕ8ìÁé€E„|a<ô{€>ž??žZZ¥ÞÞéççô˜˜Ë@@’@@Ÿííæîîîii¹˜˜¢ûûûVV«XX«ððúžžÉzzœ''“ HH›77£FFF,,–..•ááèÜcQ ˆIDATxÚÔ™xEÇ÷nwv÷öµDr„MZ’cIL'´9!t’H ¤ Д¡JoF± Ø°¡Ø‘¦ØQ{±€]4:³ývç$!ñî}ÉÝîÛ·3¿›yï?³w!YúÀVDˆXTãÈÓ¡AZÞmÍÆôÐ@{ñ—²›CµÛ¾Ù'†iæ©l¾<2õ\•›ç»4) ~Ô‰'¦—qrUèUVú†ó¹ËZ¤7Ç_n>p`0ÉêùÜN-Ô„×Zyx÷uç2ƒ5¬Œš˜¿zñ k´–“s±ÿ«2³‚ 5«`õ¤Òi…I)egÃ?dn>—Ñ4zl¡N]Þf€ödÞ¦¼˜õii—Ò.åõËÍÈý›çÝ]R& jlä=‡<t¯ç?¿mRŸf~>ó§Z·>¹.£ŠorüH°$€/æ×Á…TznZúÆã Ç\÷ã±W'/X°à®o¶žÍ̉M8^Û‚ÃvÕPcÓ– pÿòïEÏŠïÞÜ߀Ãó㉬ñ‘o«¡6Š¢T ‡ß™bf“É\³Od19k‹êîÙ€3îШmÁ`˜¹½’³ŠýôÖn2™,Ê™žÙí™jŠjÑÜO×õÁ–`Úâá~Þ ·÷ ë8ÿPš…­;ä3xÂÒu@…& pc®ù¨š¨sÇOñpãT'HyÒlðØJÔÕ ?*W«;ШŽzbœÁ¿¨k%(Wìç#5€°Éº vŠ#j‹3j~¹qwйLKÆä—XJ´_Þ^j­ïûʽ¬÷[˜ ùqÀ«Ï J™u»œié‚YËX9cǤ~4‹K#N¨&Æ cífd0ñ‹N¾ÈÁ<ÖWBØŽÝ~‚A-hãÍnó÷q¨YáÈzÌ©GuÊW¤>i—쀙CIï„r¿I([³Z´Œž¨aû-}~›A½°Ç âô9ì’2Í¿ ½3JOÒp+¨VõŠÐ©&ÔBcQ…[8¥h JØã!›ŸÇ¦Æâ¶À3R_ "%5…Ðá|ÒvVÎbE²0ÄÆH©‚B-vÆZ` GJué@µÊÐà±’U.œæ{ŽâQŸÝ<ä)=*šlƒT&Þ!žŒj‘5M++†2´Fð)YB4ÙÍHµJc•pQ)ðî¹€!=¨Ï–öê½âÅIMYEp95hµc‡Ú™8|qáRÒÜPX%ÜÞ¬²²Mu笔Ý;6Vn!(iÈÐ(P¢™¥Ö¥Žíj²‰bÁÈù_¨r 0X%L «§õÀ’÷Ü_†Ü(õ8‹:ÛZÓ jÆ…P ê‰C•¦‰SrÖßB©_ŠñßýNŒ»UV¹)*]gT1Ö©(Nâ€A?¡Ý÷ܨž8TZƒEÈÅ+ájSw *syTTôâÂzü ¼3†ëUuðë-±¨„(ä.ysÊâ—IU„1"ý¤/м~{‰’²€¾ u;€ä¾•PmªM¡ ð+:+(½*V”fWFëQ-úIc±¤ÅåKá~ÏÓ9^ã›Ú>kuÄ£ Òʪ ­‰B=ÓN»‚Ê(9MK‹¥ åÌ”ªE< šEó|0q|T‘8>Ÿì4ò}É9<(z|í‹Eujš×G³YU“¼9°ˆW¤…Te̲j)¨VÑ/M8iÃFïáF|ôÙV?¯=6ù³É¯ÅMyqÌ?­=ð”¸JHúÊÇ1û°¨œ¶>jýÛ1c8ñÙI^òš¥„*¨+:)uÒô;•]ä|Z•Û4!!áݯ‡m¶-©Ý°Ç^:ùò3}a>€^£wÞ›E…4š¦Hi¿d–€då­M ,EëCI¿Q%f-ªË˜ÿ™#ú/‹àïLõùRónA¶>fSFJúBÀÛ,ùÌénP9Ò_ô Li&ŒÖœp¤.Ô!Iš¡EÕM饢6zºÃï¼»C*4ü/*ò¥´ózþ:´>D½ºfÅìTv…Eß:ÏWqpcÕ¦_?kô¡åâsöÿ‚*ì 1_/4Ê)‹>Rr­j­:³B¾:¢FÕ/¨˜´ø'-(V¾‡¨ç£v×;ª9à~_ÛÚ"¡ºº¬Ñ áõŒê²×ú®#«x¾z^÷òúDuWtÛ‰NÕ|Ѻ`ú-  •LŸ·²ß\"$,re—SBµ¤ñš¹å¡JÌ©ˆ Râì†àøõý_ t-þ$¬›¦IEND®B`‚velocity-1.7/xdocs/images/velocity_project_wide.png0000644000175000017500000003326010557734552022607 0ustar moellermoeller‰PNG  IHDR3µÐ¥ pHYs  šœtIMEÖ %øíIJ IDATxÚí}yXSG÷ÿɞŽbPTQAPÑV„"*V[mm]*ÚÖ¶Ö.¶Z»¡ï[ûvÑþ´Å.Z¾u«Eq¯"j¶ û„,÷÷ÇÄñöf1Tjsžûä¹wfîܹs&ó¹g™34‚ ÀJV²’•¬d% ˆÞƒumÛ¶ÍÚ¡V²’•¬dÅ’îÓåÜÜ¢êk‡ZÉJV²Ò¿KF޹úw» égþ¼œ› ¥%% ²v¨•¬d%+ý±$99yㆠ"‘óâ%K»Š(·n^¿~=¿´¤J¥j8qâDccÃÛ}öwíAD)Ö³OŸ={¶‰G/\¸ðÉîêÇÛž!C†è7iíÚµ ¯]»V¿ðСCŸ¤éF«ÎŸ??qâÄ^òWµµµõóó›7oÞñãÇ­ƒÜB®ÑÅbqrr2|¿m«HäãĉͿì¦(¹¿îÎÜþ=ìOzåË¡iCƒÑùþ¤Wšoܶâ¹ù¤V«ÿøãŽ=ju¦xxôÜsÏé'fff,|òäIýÄçŸþ_Û{W¯^‰‰ 3Öcžd2YIIIjjêÔ©Sg̘!“ɬƒ¼Û\£QVVvüøñ%K–àÔI“&}žœœÑ‰þ n"«Û”••eºÌÅ‹GõÄÈ%””Ç‹”ÞÞÞZ­–œÈb±š››ù|>9±½½](ªTª¿}¸ÑéåååOL‡˜Ùª›7o®]»vïÞ½8ýÑ4»«ßø‰‰‰¿ýöÛ¿|w›ktðööž2eJFF†»‹;J=qâDÈÈ‘#GŽzÑwc“·Ÿ‰š¼?é•' Ø‹‹‹ãããݼyó¤R)Î*//_°`››“Étqq™9sæíÛ¦µôôô>îÈ‘#Ö©‡D^^^”D•J•““CIÌÉÉ¡ DEEY$ÿ\ Ú³gOï—˜wíÚuúôië8ï×t~\ÞÞÞb±øüŸç-¾/äææNž<ÙÃÕØ³ï ›ëk4­Z;gš\Zq뺋«+”5µ@ÉåË}þê€Z¦ß"¡k<éö€p¥€!×òƒ —Š[Û :8)9g;Yrý‚džÞð>ºí ðxiôèÑlkkkooOMM]¹r%J¯ªª=zô/¿üR[[«Ñhêëë÷íÛRTTd NX±¤7¨¹ *žT¡G”I®7ÓO?ýÔÛzïqQW¹vß'ØÛÛÛÖ–ÿþ{ï^º| (P]W½dÉW·?úŒ2›ûí·%UVV38<‚'pttÐt´€¦¥®þ˜ÕtþNšRLó®e ¾`qú3}j™‚Z¦ RÛÚÊ¢hut䢕E‹×ò'¨8ÁÀ ÂkR•Ç itJVtJVÔ¹³QçΞ{1vÒ+™Û¿Ïýu÷?蟶hÑ"™Löã?¢ËÇ£“µk×VWW@jjª\.?pà´µµ­Y³Æ˜|£/µ8;;SRòòòªªª¬“þC¢™3gr¹\J¢¾iD?ÅÆÆfÆŒÖì ȧÑhîܹ£/bÀ¹sç¬]Ô=úÛú''‘···³HtþÏó[·n%gU×UÿgÝûƒ†ÌL|ç—/_þ⊕×/œÖ(å"/ßææ–Æ6EKÕ]”[‘Û\K³«¥Ùéj óûB[5]§V>ÇáhtòJ#¡k®ÔÑ9Ù,eCšØÄ(a«‹•p+¿ñÀÑÇô–àmWÇ&o‡×§ FöüÞO«V­²±±Áß³ :<>zô(:™;w.Ç‹G—ÙÙÙæ ï¾û®ù¢ Å]ä­·Þ€C‡ÅÄÄ8;;3™LggçØØØŒŒ ƒ·«Õê={ö¼øâ‹!!!...\.—N§s8''§ÆÄÄ|ñÅ&º"//ï­·Þ sssãr¹L&ÓÞÞ~À€qqqß|ó îÓÔÞÞþÑGq¹\>Ÿ?jÔ¨ï¿ÿÞÄ×\^^Þo¼1jÔ(¡PÈd2¹\®««ë¨Q£V¬X‘••ÕUn ‚ØØXJâÕ«WÉ/ÞÐÐpíÚ5J™øøx[[Û‡×02I$’õë×O˜0ÁÍÍÅb±Ùl77·ððð5kÖܺuËô½Ýà‘ O$cŽIä’#Gޤܾzõjrá””J   ‹f=:],ûí·úYäï0ÊC—/_®V«W¯^íââÂb±ú÷ïÿꫯZÞófúqY2ZºÊSs¸f–„ED{{»D"¹Yp ™ÐõiĈ¨˜D"I˜=ç£M›-^òÙæ”„Ùs>ÛœBÄW£¿ãÏÿŽ??‰~÷ÛÄ£coø~›øóÜhtlà ?Ï.a†–0C7ð†Ÿ¦j§ãã4}ÐN%eÓ?Eä¹_àÁ!Ãö-[Z|éñ8ÈAÕX ƒÁ06Ð >kòäÉ”’<O.—;99QÒ§OŸnºµˆ^ýuc>Ä«V­¢Ü{ëÖ-sþÀŽŽŽÇŽÓtkkëܹsMßËçó7mÚdZØ/,,ìß¿¿~úÂ… õÚØØ8kÖ,Ó +,,ìÓ:¤_Ò,#Ú½Û€Üüûï¿[Þ°þ ÅÊ•+™L¦±ji4Ú‚ Z[[{ŠG¦[eŽ” ¯B "×Ov BôñÇwéïi°mú-`±XÆnOJJJJJ"§Ì™3Çòž O-Æ=õ¿35À'NmòrwqߺuëÍ‚k7 ®%Ìžƒý",yßvy'ò}ÛåQ¾ãÏßÀްà Âtrš>J 3´¼ƒéR0ì`ú“/ÛéÁ qèNÀ¾eKOÜvâà¶ –¸ººâO¡>¨­­ÍfSú?**Š ˆ9sæè«SärùÿZ666&† úØGT__ïîînæGŸMii)ù¹õõõæH¾ùæ›&ÆtŸ>}LŠÈ­««8p 9O …7nÜ0Ÿé"ÕÛð•W^Á–.]JÉussS«Õ–7Ìô¿Z&“…‡‡›Só!Cšššz„G–cI[[›%½¬¬ W2|øpJî;w,Ç’ëׯëç:;;»}ìØ±”OòôôtË{Þ4O--=ø¿³K°€"‘HÈ6y}D™4iRFFƤI“0¢1×vÄ æbDA'X^Aƒ”fè¦ÿN¾,a†áPd”vzpŠÈÿàaí±áè84}Ì¡äwê{9–¼ð ø{G&“a‰;""B¿¶ýû÷ë÷üúõë ‚À–ƒ£¼Û6='''ü õöÛowéÞ7Þxƒü\cÒ­1Ÿð]º+!!Á´g‚U*•ù|_¶l¥œ+‹)¹+W®ì‘†™þWô 0Fñññ=Â#豀 únÙ²eÉår‹EÎ>|xWÿž”'ªTª«W¯t 3³ñ...˜5–ô¼ižZ2ZÞÿ®;X‚¨¡¡©¼fÏ1ñw÷#F¼½zõÖ­[ÉX‚)XBÖ€¡¬õ¢È+`P‚¤ìRˆCÑÑž"òGxs„"ò?4}Ìå»z'–”••é«§lmmóóóõk{饗ô;üÔ©SATVVêg‘?“MŒZ‡ôôt…B‘žž®ÿmˆøH„¾âôéÓr¹Y/(¹ƒ ÂE>zûí·+++•Jå™3g @É5jT7°¤oß¾ø¡Ø…I,;v¬½½½­­-33sذa”ÿ÷ÿg>ßÏŸ?¯ß€òòr‚ îÞ½«Ÿ•››Û# 3ñ¯>{ö¬¾²ôÓO?mhhhnnÞ¸q#N78~,ä‘9ZšÈËË£ˆ‰‰1ÖÕ6l°KLÓ{ï½gæí¯¾úªå=oºs,-òÔ®uKÈ*¯›×Þþ»eŒ'HL‘H$úX‚N¤‚q…¬Ã•óÜh,¯èC YLÁÒ F²Yåàa‡¦AǾeK÷-[Ú³òŠ%XBÄíÛ·g̘áääD§Ó§M›võêUýª´Z­¾Š‰Ëå* T`ðàÁ&&Vƒã»ï¾Ã¹›6m¢äÆÅÅaA;++ëÛo¿]¶lYDD„H$“#^)7r8œ›@É}ùå—É­ÊÍ͉DË–-ûöÛo³²²êêêŒ5xðàÁ·oß–J¥Xª#w®S_ïwåÊòCo’VA!š5kV—X¯o¶ùùçŸ ‚Ðw* 詆™ø{ëwEµjÕ*Jùóç[ΣÁ‚ (RÖÓ~ýõ×úö퇄%L&“\¹~ƒñË/¿Èåòëׯ㒖ô¼éαd´XÈÓ‡‹%dD‘H$ÉÉÉÆì(ˆB8‘!œHKB8‘èa Ʋ°‚_d=V‚‘¥–L} ÁX‚,óXñ…Ôe—û"sýCVzœ._¾¬ß½&LÀG…®]»öÀ¿Vuu5Î-..¦äz{{›h•R©<þüúõëõ‘Œ<ìúöíKɺd¶£„ 1Ü`¤|£··wWç‘þýûw‰)úa¸Ð¡¿ˆäóÏ?渚™xå~ýúQ²(nAA¥@¿~ý,çQOaIJJ ¥ DQ…††ZÒ0ÓôÉ'Ÿ˜¾ý¥—^ÒŠ%=oºs,-ò´XBëž$ØØØÐÞ.€ú††wßyÇÄòøN$ˆÙãÐ¥ŒVÌ'üp.¾tTç80{º5áùÚ² úßú1_[6‘&¼ïÏC”ÍRélÑ.Zåf _ÀYhŠ×ò™~È×´ÕTTœ»K(kõ`z gŒu¡—«<Çöôbúè£Ö­[×Õ»>ýôÓ÷Þ{âIBqYéììÄ—*•ŠbÞ·±±¡D(*,,+&“©ÑhÈY*•Ê„ë¤éѬÑh°öÙÄXçr¹äWëj›Í¤ÐÐЋ/’S<øÌ3ÏPÄG²û¿… ³K Ç3È_KxÔSX‚ÀcóæÍøÒ××7//ÏÑÑîj@3ÓXB£Ñø|¾¯¯oDDÄ¢E‹† òÀÛKKKõm‡–ôüÃÆò´XÂìR+¹\Þ“7ÿôkî)Ýr¶~ƒK þ€° ­M ÍÍÍa"ÎeŸ¢€Ju]u5Tƒò¾¤âÁqG@‚΀Rš#øÍ,ÏfBw4A>½)ˆ6¸À‹ÖÒìîváLÔ2D·šÎw×ÊŒ!€ÐHaÝ=aež£ä7;oå7^“ªü›‰Àh¦œ€[W·ð¤ÇÏîõ÷zŸv /ÔþÇt²¶¶Ö Žëtñâņ†}ïU2xÔÕÕ¹¸¸`}¥€££#:ÉÈȘ:u*9¦F ;vìÈ‘#ÇŒ£/æcrrrª««£è» ®1‡ô͘†ívîœRSSƒ°{Šž{î9 –|ðÁ”2•×Ãk˜§§'¥æ¢¢¢€€|YRRB¹KK=Ë£nÓ’%KÈXRZZºcÇòü5~üxËšY¤ÿYzªçÞ0~ô<íÚ¾Šåw‹7ÿô+ŒŠŽ+t°G@2|ÄH°Š/^üɺw‡FÊ_Fö}›Ê%eÖ%eVš4µJY-£Quôùô¦ûƒ‰æˆœRA eW5ŽßéÎzTÓù9´-¡H³‡Õ‰B¶0¤(ð—ºX©.Vî)mª©$›ødye OúÇ@Ú§½> ôµÝÛ 5¾ö›ý§_NÛ9:mç¹cdžŽ ûú•Гiߣ£±±ܺyýáq¨ÛaäµZ­¾…ÈÎúÑìýýýÑɇ~H Γ““sñâÅM›6Í;—¬—Ð'}kÊÏ?ÿL¾<}ú´‹‹KdddRRÒ–-[N:U__oa§3†’’ššÚ㬙3gÅ]õ¯¿þúû·wæÌ™¦aãÇ7ÝÏ;wî4vËÃæ¥—Ð7²Á¡Bé´¦ÄÄÄÇ«! ˆ–÷üÃÆ–óÔL®ý ¥Í¤ŒŒŒ6mþa×þUë>]µîÓE‹—,Z¼dÕºO7üŠÖº/Z¼D"‘lݺùe!£:²·¬þB(Æy| >¾$›å±zâ¦?vôÂKëpÈVzÊ–ÓôA)"l¢G.ÅäU qèå~›†2ŒºŠeú˜–w¢Ñq(ù݇dx·$ˆÅ7I¿€½½}ZZšB¡8uê”~h¯÷ßÝHÑ}ÀŽ;ärycccjjªA !~(%’¾¿øâ‹æææÖÖÖ½{÷êi6Ì량\}åp8_~ùe}}½B¡ÈÍÍÕ_ üôÓOwƒ;úÚsÊÜG)oaÃL¼²~¬bƒ±qãÆæææ–––M›6éë7rrr,ç‘9FZ}áø·ß~S©T·oß¾~ý:¹¤‰ÐŠ ƒâhdáZÅž2>[Òóo[ÈÓ.q­k¶÷[7¯Ÿý«øöÍ›ŽÎn."GX^äåëdǽs墓x¨BÚ6ØÒ¤I_‡ÎéóWçI¢ ™7òµeàÀ\Js,ì<ö· ÚTÈê/ƒöytÄVúc uVˆ­,iB¤é€4%²Õ“­ô{XZ…Í \ÕÒ†Ô^E„øÙ@¾¦íšTÙ"tÑÞWP Ë`,=|ï7r OºØço½ŒŒ.­ÌþÞö0vßÙ×gHp]T*•““S[[%=++k„ ä”ââb}ÖÞÞ¾¾¾_ti;ƒQTT„´ÃÎÎÎfËÒ×$¨Tª#FP>Ø(-!«ƒi­éÜI“&ÜÊ ‚¼¼<š:c´k×.}ÇMLMµ–4Ìô+?ûì³æo¿AޫÙ£X 3¸".\HöàR(ÍÍÍú%'Ožlz#83í%æKùæ ºÝóo[ÈÓ.q­k:®MÿÛÒPzgvÌ•R4¹4bâ¤À~T\\]Û¥-ÁÁÃÊÊÊü®þ宕õ…¶ašW¢ ‚èÞ^„t¼¶ÌƒãÍ Œ”¿'˜kZý•Åû¡°óLaç}%2Ë#eÒƒ!Í‚.¤øÚISѽkiv'‰&l–/`H “¡[¡sš4‚`ઋ•—Š[OVsЮ*H?–ŠtÙXÆkù.Z%RŽU•žҦeróf'ófç­üÆ]çj­Ilâ'6ñçs¢oE©im_m¹±þÕñaû“^9¼á½+ç~ï6–œ:uJH8Nhh(%ÑÏÏO_°hmmíö~ kÖ¬ÁfF}_uŠ,¬æA.—ãÜýû÷›‚eÅŠóu÷hÇŽúfRƒÄf³SSS»$+ f9;;O:õQ6ì‡~7nœ9%Q@L2*ž~úicY{—Ë?¾1"ôVêvÏ?¼al9OÍçZ°ärn®×À!'MÚ}丟yçÊÅð˜pêä‰þî¢ð˜uµµ³c¦89‰®ÿ¶5@#pUKEüvWµ” *®D›—ªJVèÁq_Ø‘€5`”'V×U“Í*T®`#ÊŸZ:’WJiŽ^ªJ@a‰ ‰2 6}¡ P”ûßéÎbšoŠÔ-‹ ç8<²'ØYhjeÑÆ‚ܤKI/,,Äçýû÷¿páBdd¤é—µ±±Ù¸q£þÚ´î‘»»ûÙ³g)Ò›>yyy;vlÚ´iÝV SBΙ3Ç ÛÌÃkŸÏÏÈÈxóÍ7… EâæÒ¥K³²²(a*^ýuc¡ôg¥Å‹œ(q í^HÝîù I–Œ yÚ%®ù>Áeee"‘H¡··ËRÓOFD†Ÿ>´oΜ9þù§»weÁÕ„„NN¢Ã±aQé Ø%”¡Ï|´£"Ú+‡Ö€fóZšVOåÓ›$Z²ÕçcrJ.`Hñ®ÃÀôãäkÚrl‰þÞöá÷ÇÍö£ *är‡ˆ½F8z‡EŽ˜7Ût·ûûû“'e,1|üñÇú…“““õCЋÅâ;wµZí¾}û¶oß~ùò妦&GGÇ1cƬX±B? R©Ü²eËÞ½{oܸÑÞÞÎçó ³téR‘HtõêÕàà`rùÕ«WS §ÈÜ·wïÞ?ÿü³´´´¹¹­hqqq ˜Œ»ÁÓnpÍ,,¡¬áú-ý˜4z¸H$:zô¨gPpe~ŠŠœ64xR> ²YJ´<ƒJCÚ¬Q÷gêäµ#LÆl‘ÑŠ«”Õ¦A…Œ+€—§ 70¼þ/Iù™É#[Vž#8 ÎBS;'éâà$Ñ„²0¹ª¥Ñe¥¶õ‡GÁž0¥Ü“n¤œ::ç,4 êË bØ©éîZAlèÆF¢â÷hÕWpëÃ÷½±àÛï"—½î8àá}=õÚ¥­d%2=ÿüóß§;vt)~b罹¦&6›½víZJì"ò2Æ™µ¾„Ïç“/oß¼9;fŠH$B;}úÙçŸö Êj¬êàSn¿§Jœ…&ô!_Ë´hþÒçõGøyp@,'@•²ú’ÒÀf/äÄ û[…­É"Kaç™hÖ` ¤!Hü€y³ó׿¦C#ƒB/BZ àJ´UÓù’þ·û{Ûhs£­þëRFÛ³ÁÁ¹”͵ýSNÓY7w³Ò¿ˆ233…BaKKKJJʯ¿þJÎ=bBë=$‘H|}} f¡°O,–PhvÌ_o0ÈoŒËÕ¹];¿•ï{¡(Ž,¦‹JYG縪¥}Y®p¬­Ò(†~ fëÖ3V)«)‚I·R§ŽÑ‰,ùô&Ð  ‚å‰-+…gÞeè¬&'‰&†n $ZW_‹d¢ ($Ê&Ò¼!UØ]°s` BZK³s%ÚvÒ”(·–)@"Ž#‹¯ÒA©ºXy€.;d3’Oø4WÐtJ3¹ßeXbsF{ V©Ñž *ÒÛÄgz¨2Š•¬Ô{hÞ¼y555Ær—,YBÙ’òŸNÆü£€´¨ë_%Î"^Îçó/^„—°—ß8~·ÙûØé;RMp»Œˆ)]ðOE¢êeWî§+!í¾*¬î-¶¯ÕèÞº‚ÉsР‰ý¢¥õÈI,ˆ„D“DSk Ò’UÐ^„Tçô|O@ÙÃê S2}Œa‰‹‹Ë;ï¼ó„½¯ ,¡,n}±„²6Í×çþ%—Ëñö;Å#†·~õ?³cÞ윜w¥äЊòRUÑ™4A>M4SÁeJÁìÌ'ü°Ò\!‰,ÛFѵjébú¸R …˜˜î@ Ù⥤‚Cnž|¯”¾Ds>½©EUI=IÑt!!æk y•L>½ifÇeäVGçüÈ‘¡¨–)È¡5°ÄŠþÞ Ø\a/|},¼èÁ¬¾ºõÿ½?¥•¬Ô ËCIDAT%òòò2qN ìÞ½ûŸ«ö1F.\0˜mÐíA´·¾Êd2´®íúŠg£h,8!‘N•s`OiŽºx€.›å+¼Ø1þBÓIäÜu’hšHbÓš¬±jˆl¢ÇVô|zù®<Ðn İ„MzpÜqµ¨n`y=P.:I^#‰Ì*טTWΧä»Ð»×Ñ9_°8x¹¥+Ñ&ë¼Ñéó…ØVênζ¢²Vç5^,‰ dªãÐ=ãoËb_8ö`f[mïVê•ôÝwßmß¾½ººº¡¡A­VÛÙÙõïßòäÉË—/·<W/¤>ø //ïÎ; R©ÔÆÆfàÀ‰‰‰¯½öZ—Â/>áX‚¨±±¡¾®ê¯/p°ß~´Ynå7@ÃÙfù à« Ó0úºG·£Å†ä ÉèrßnO M\É3¾…ÐBtŽc±‰ìvŒƒKîÕÙHîÃO˜êòsÑ*çÙB.ˤÚü0¥<¸(B>¦¯*:=Tíz€éÇÙ“2Âì8Ø·GÜWÛ‹mRS%àêEë¼H°G›²âqE¢´’•¬ôï$ÚÃû2mll€3Ç¿);}|ƒ=JD¸Â¼Ù ;ÆqqsF{’’ò$h͹¶B¢,œUÓùH‚A"Õæc÷Üd¶(H+Dú1²{1YÂ@'æC‹ ÕB¦.Þ'ö*þ™É# U§ã÷Jdð°”ãK4 4çf©Øä¨-Hb«bÙ’wg{{®,ö¡hù˜vÙt¸õáGw€ÌÓºÐl5å2W¿([¾—ÕÖb%+Yé%@Ú2«èê7Ž¥ DɹÑhÇ,P¤Ôº¿äZ uG;ÑŒ‰W¥ h!¯E/°• u*H‚ÁH#ë¼VžÁâ`kư£/Ä—n –¹  y%І¬ì¤)›™áøFGuΛ*%ÜwFXÍP4fȯ¯û¹¥•ëÁš;×RS%QÐ%¸õáß1á¡" Ò›™3в³³×­[—Ý¥¬ž¢òòò¾}û:;;SqK\½ôôz¸—Npªç==š¡k>=\Ýœ““ÎãËÖ6ÞÓtvÞ>° õ‚ {Õ\_â®:Àέ‰>4kÔ†­ôì–{s®Z ,À³mѽ¹øMìaå#Œq%ÚtÖº7’]@o!˽­S`*rë’õ9&Pã\ó1Ûöu¦Cåßä˜* ]—ô§–îAÚGò)m=€î™ëïÃ!цį{îaØÄG@ÂláIù#… žH»åÖ‡£¾€œ´ÔЏ¹=ö¡f"–ÃÃ";BÞØ…è²ØÙëòÉÏ „ñsUkBœ§ÝQ¦œñÅ÷E“0¥\ åžtr,‡e JâÞWü}rÕßÓ1Æô¥µ¹k9î ˹Wv"MXxW¼TMAtôîL¼ûo˜ª ;_‰Ù~ºeó²>ù¼² –§>̘F¼äåoî)ÊûÒÌŸà:Š¥EÃÔÅJ8D”…qfÇ ´Ûdž®¯¹T‡a#ót}M¹ ]¶v¤_ªÃ¢ êý4•ï˜0l\ü¿ÖŽ‚þxäŠL§ÿCÉêLaÒ‹èìINN"oLB–Ÿ¹9pêKW® ( ãü1¦Ć;õ6ÄØ1ý8!~öç8÷wžñPµãó$%ÑHT¸ª¥®ji˜RŽ¿ëQ”N.ﮕ¡ŸO¤ ¥Ú|É‘˜æí¥ª¯-¯-ó%šƒóµe®DÛDšpZŽD>á'fóยk£Y ;І+q‚¹(ø±Áà4sI™µY~jµüÊjù•çÕw.)³>mÿv=?c»º|»ºü.ØU±l³YÊl–²ŽÎ9D¤,fÜÐ/!ζÿ·p„›aq$5U’[#›;×gî\Ÿ¨ñÎèYó¾µ/†u5¸¤™¤T*—-[foo/‰^~ùeýØÆØ…ŒF£QÜÉLdáÄ´´´ÀÀ@‡dbƒ/ƒ5èt¤?â ¦ïÝ»—F£¡°@ˆfÍšE£ÑöîÝ«_szz:jÛàÁƒ:ÔÕ®+((˜>}º­­-ZÝ]TTd¬ä±cÇ‚ƒƒ9Ž@ ˆŒŒ$ï‚nºŒõpCC‡ÃqrrÂA@.—;99ñx¼ÆÆFsÚ¯ÑhÖ¬YÓ§O&“éààðÌ3Ï”——k˜9|4³B3;ÄÌñù(Y‰ºâÀB¡Ð`tá#GŽòx¼‰'J$c£ÚØ~lêÄÇõ!ƒ,óÈš"ïhM;ô»cç‘ĸgPf"ûx¶ œ"o1ÜóþBçYMó…po©9Ü{šÐyCŠb5’w†Ï¡5Mý(­u'›ýÉ—h<:GîÈxнÝQƒ½~`»º\̇¼ËÈb9ò R—Ím þžºWãz°Ì5å²i!ºÐl¹5²n|{± ºDŠ¢Jå3Ú!ÊöÿÞ©lZøÎW=µBòÄÄÄ]»váÄ^xáÇ48é>›È¹, ïéÆ`0rrrÂÂÂŒ5ÆàF{³gggGDD<0].—»ººj4šºº:>Ÿ/“ÉœÑ^L”õ.\¸0~üxµZÛ–••¥¿kž±†•––>¼¥åþ‚^ggçÜÜ\ý=\Ï;NŽúg0Ü¡Á™èáÙ³gïÙ³gÛ¶m‹éŒjÛ¶m[²dÉüùó)Ûð£µk×®_¿ž¢OËÌÌ4Ø0søhf…]êŽOóYiŒÌg%jƒÁÐh4S¦L9vìoÞügΜ™0a~/±XŒ¢»êcCúÉ—KôÅ$©ˆD"g9sæL™¿3{pè©4b†`—MG{„mË+"m´=;J S‘ P$ÔƒØÄÚJm«‹V‰Œ%êAl$Öt:JDéè¤Y£³TìZ\f©Ø¸,Äet„¢B¢ ?GpZ4ÐVzÒ©f‹æ/KZNÙg¥‚åéEHQ®+Ѷ٧°ó kL³Ùg!³Ç]Ì'f‹”¿ŒÂï¿o»<‰‘Ä‹ ‹5ÈÌßSx§²ép‘Ý/—Ôë¾-Ž{ñxÜ‹ÇÿØ_²'‡»/­r_Zeú¥:ÉÅ–ôKu™§ë[ ;Z ;ö¥UN qIˆó¬)—¥¦JRS% qžï.|ùäg=ËÍ–––’’¹\þŸÿü ºÇÿý½äLdazê©§jjjjkk§M›¦Ñh>ÿüscc5 8}…€Át×ÑÑ^äðáÃr¹<66V‹Ö 6¨ÕêÝ»w+Šƒj4š/¾øÂü~ûøã[ZZ¢££««««««£££ëëë×­[§_299Y£Ñ¼ð hgå3gÎtUñ¥ß?BÈñÆÑù+¯¼bfåÛ·o€;wªTªÜÜ\¸xñ¢±ÂæðÑÌ »Ô!Ÿ’•:åJRR{{û–-[ô›¡Ñhbbbêêꪫ«ýüüLˆA½JÇEë= VäôekËoo—É;Zoçí)Ì·Ûd­,vLo n(šRúŽpã€í©ö}?Hp˜÷Ìi\ÝœŽ­/X^Á :Ç 8p£°PrýR-’WîT6!È9\d7€W†å˜;•MþžBt/²£Àȉïõˆh‚>²ŠŠŠÐ ïèèàóùãf›˜UVVÖ·o_¸·}¤““S—öyì†WzzzLLÌŒ3öíÛ7cÆŒ¤¥¥ÅÆÆRй¸¸PvÉvss«®®6óÝÜÜjkkïܹ#‹ °°ÐßßßÝݽªªŠRR$566ÖÖÖ núAÆÒ ‚èׯŸD"9qâÄĉOœ81yòäaÆååå™ß½ííígΜÉÈÈ@ùk€™|4§Â.uˆ9ãÓLV#óY‰štûömƒ¡·Ð{£]­P=ú=ÐÛœ¸z–è¦`™L¡#õWceA¹ä­ó¢äb‹÷9å¤|Ú-ŸN·Í§µ°ãê3·Td³”šÿ×ÁÌ•-Õ{„ ´@X‚„œH>ÏE+‹†·-Ap‚[UGç#Ï“ §Wj[ÿkLŒ4(øã–;‚œÕHTüNw&+Äòµeø®ZÃ]°Ã®Ìr¿Ë~+ûDwFKIÚªµ°#·F†—˜ N@ú®šr™[þ7¿jf…+U**H?&¹Øòêwz K4 NïÞtfN–Z­F» ©Õj‹Åd2±ªÄ:vìØSO=5a„¬¬,sÒ@¥R¹¹¹Éåò’’___‡S[[«¿E“ɤÌJÛfì †V«¥¼‹Åêìì4ø r?÷–À'Ÿ|òÁÄÆÆ"°<|øðÖ­[Íä‘™™9sæLÊ®ºÆ`ͬ°KbÎø4“•ÆÈ|V¢ M€ôëAÍ Ô£ß`C÷_§ã2F|>©¿D"‘“gÀ°± ‡Fn{g×°C/~ÿJÕâØ+×dž®Ï<]Ÿ[#+~Ñn—PTâËZ°ÛD~éפûÏÇkùy @'g¡ ‰cAˆ6rG组2dêGª0¤õJR¸ Jœ¥bŸ…&té£e`ýØ,{«<éö_v”´hþò"¤è¢{©%H¥†žªªF‚èÞHÛ ÌQÖau2õçÐüÌR±ŸÒÖKµù(˧h€&Éfû É‹íÅ6#ÜøÈü5Þ9ýR½ØÆ^lƒÊŒpãønç™üåh® %¢“Fô‡;ðv^àääÔ¥Û»áÄÅb±ärù»ï¾«P(žyæƒ{ ÙÛÛ@]]qºrh[å’’·¤(›#!rppó?“ͧ_|‘Á`9rä?þHOOóæÍ3ÿöåË—777'%%¥§§Ün¯«|4³Â.uˆ9ãó‘±ëQM¼WYY6ÃtiH[±Ä0¨ k "[[þиø!s– ™³dìôèˆ{gWÜ­³)!þ'‚ˆÆªŽÝ«o!SÁÄýA™Ó¸·|:™~žÌò0¤y pÑ*ãµül–ΠÙ"<ÆS¨±ãŸvËrhª­± ÜÌ¡‘á’‹V ÜV •DÀƒÒ]´JòÔïJ´ñÙuP ¡ªj” )ªíM•[e‘¦H-A•OPq’”D!QÆÖÜF¹£~²ÿ~Æ BìÅ6sçú`o®ÔT ‚™¹s}rkd©©dœÇ‹QÒ/Õ…ÏÜüˆо³jjj(Ÿœ¦³­X±¢²²²±±ñ­·Þó-¢dͲ™N\˜ÐÆÃȘ˜h°Lhh(¬[·®££cÏž=4ÍØ¶¦)** ½]MMMMMÍŠ+ÀྼèAÉÉÉr¹|ß¾}4­KÔ›èaOOϧžzJ«ÕΚ5K«ÕΟ?ßà÷²1*..FýýÜ î h&ͬÐÂyŒ¬4 oÈaåÊ• •••Æ W½Í‰«7ê¸Ì´¬ü]»ª³²èr+ Ê% ìôqßJzuB"-NìšT…L#d{ɉ bÂÓ.}´nH¯Eß%”9yØ`ÿ±ªR(`èÂ#‰)Ó(ê2òòD…½ŠÀÅ€´¤Ÿœ…ÔhäíÏB“#ƒ‰ÝزYÊfëÖ ÒÊ÷…9ÈÎÁÓB\t«OÊeäð*5å÷Ŭ‘ß04¼KS†ùJc:ooï»wï@\\ÜÁƒÍÌBµ±Ùl¬+àp8.\6l˜ùž.9qaÒjµ^^^ÕÕÕB¡°¦¦©(”““Ežé~ýõ×¹sçšÙ°›7oŽ5ª½½¬v¿r劻»;¥ä©S§¢¢¢´Z-NÙ¸qãªU«Ì|‰€´´4¼ÙT~~¾ÁÊXÍ“&M:yò$¾tttlnnÆö‰nðÑÌ »Ý!Æ^䑱ÒôRüóçÏ?7#$$EP¦”ïmN\:Eä@ õäCrêO¦lÛ·lé¾eK%¿‹~QJŠÈÿ' EäŸ"ò?MÔN¾Ü/ð«¥£Ó~œÒòNtŠÈ¿„ÚNn§Ÿ¦:4}Ì¡écZÞ‰n o ? @Y%ÌБ¿Bª‡¶Óƒw0ý/÷ D—xÃK˜¡è8MtpÈ0]±ØðöØpT 3ô'ߢ‡¦ˆü7ð†Ÿ¦BOGõ2 Ý…nD­EGÒtqÅï3Ò~œ²uý¸¶¢çÚŠž#Ÿ·=·uý¸¯–Ž>øë‡ý0÷ìQÜ-=Õóú£Èظڽ{·‡‡‡Ã‰ŒŒ4? Õ–••5xð`6›=|øðììlóƒÈÎÎŽ¢¾0Žéµ×^€—_~ÙDz¢=© ee2ŸÏÇÁL­-_r,óì7û½å· :av>£þØ_2ü<͵‰D‡l–Rm_Â@‹`ÿW‚ešmAÊþÞö8À>Lò¨¸û~ø71°Øq0@ÚßÛžìoÙ"tÑ*ó@ÑÄ™ä#ÀM:!‘6Vu°[À‘Á€Z;u«³¿·=„Úm?Zá°@s˧ól´-öìB$¹ØÂõ`¹úEÀ°{áÐËr¹¼‘H‘àüäÆSê%¤R©îܹÑØØøÓO?-X°ÀÊÇÇøeÏf³Õjõ¡C‡¦NªP(~þùç+V 0àÖ­[½ý¯ú¯å.vÊ2ƒ0’c™eçî;K =©×+Å_–‡äë&ôVù5€±ıs*ï\”Ky‹nèëôhz<<<Š‹‹¹\®•‘öïßOIüüóÏ{ÿæ’4+wÉèB¾T(äÈc i áÌÅk¯àÚÆm´}؇Ên_BÖz¹JÛ‡U[œéίíÃêãJ”¶UU\å;û‹ÇuÚÚò¯¥Õ—™³­ªA5NàÙØ£§ë6áæ‘-F(ñŸ%Xç ÇEB¡°­­mèСß}÷]HHˆ•—¤Réš5k>\YYI„‡‡Ç³Ï>ûÉ'Ÿôþ=²¬Xb©LC™Ð)Àƒ§xŒ ”KýJð ~OfXÉJVúgöY±¤§¤ý Ý:×[ÉJVú—Ðÿ&-LK¨±IEND®B`‚velocity-1.7/xdocs/images/powered-by-logo.psd0000644000175000017500000007512607257216154021233 0ustar moellermoeller8BPS M ú8BIMéx(HHçRÿ÷ÿ÷[ (ühhƒ št2 šH¨K'd¡5La 8BIMíHH8BIM x8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM8BIM8BIM@@8BIM8BIMu M Untitled-1M 8BIM8BIM8BIM ÕM è¹ÿØÿàJFIFHHÿîAdobed€ÿÛ„            ÿÀ M"ÿÝÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?ÕÿÖõË:çGéÝÜ¡n]9qF&OÙKÞÆÔ÷Úç6¯ÐÇ©úOÌýç¡3ë—Ö^‘e}+=˜÷fa}Ž‹(°½ÙYŽÈ¥¿ ís+wÙþƒÝèßêYùë¤úÅõ¦ž‡Õ:v5ø¾«3IhÉܧ«kt7iÝôÛùég}i£ëV'AÞµ™ 9 pšË·ûvmýÊ÷}4î o]8¾C¿Zú¼¦GøÊú͌멷§ÒûqìÜÖXsžì°²¦zÅßf}õúžýþ£þš°ÿñ…õо±wN~,ãÜìk+.k,%ŒÞüÚ™n[rŽèõ«©˜oýý¬õ—·¼²_!åºLö|,,o¬fÿ®9]ØÌ Ǥ9¹3/t¶» #è~• ¿j$ ñÑæoÿ_Y±úgLË· ®ê•Û}veMmMCŸ——ŠÏ^Û=ßÏþޝOÓ«*ÕS¬}yë¹Á¸ÄÕÒ]Ý<šk±ßh´^·[EôÙéYƒþèYôýöÿƒ^œ[Žb‚vê+ÓO=‰í}¡†çGŒ]ü¤ùçøÔê=G©ôšq:…½>«ªÉ69™c°–†£wç7ìÿƒBéÿ]~²âô¾Ž+nUÝ[¶`då1åîÈ ÅÉnVË›êÕöW}¢›Fýž—.«ë?ZÍé™8 £¦~Ñ£!û-°jY%¡­cv»é}?r ÷ô¾»ãcd7!ýK“n0s§²öíq®ÞÛÝWòá5~‹±êM"&t¥:OoÿÿÐé?ƇO9WÛœÁú^Ÿklù/>“ÿéܹï«9=W¯õo¬Ûw;Æ€u÷Šý:Çùµ/Iê8ýG üM ,x?»ü¥CêçÕŒ«Ø×câ9ö ß¾Ç[6íÐjd=oþo̰À™ßOû§Éº^'Ö ÊÛÕz~.Mù¢ýǨ6Í sNÃü¯å®³üŠÿÆTÈÛ Àõ6,QC¶ÿžµ¬ÿ} Ù~½7äãÔ_ê}ž·ÃÝìÓsUìß©?/®Ó×uÔeTX^D?`ÚÝò?sØôùe‰¿zxñW̶8ä+Ï»æTãØÿ«ù?ZŸ—oíZóÊì߯¸nwò·-‹Öÿ­˜Rdzâ×g¤Ã¶I¨^÷·ùVX鷺|¯ñgÐ2s“¾ê¨{ýGâ1ÀT]ßnžÆ«ÝwêOIë.¢Òë0ïÇ`ª»h;NÁôXïê¤rÄž¿¥êýÎ.«§M?zž7ëo@Æú½ŸÑƒuî²ËvºË\b·Uémþ«lØ–gÕž›oøÅý˜M•ã[_Ú]µçpyµÛlwæo]…¿QúUØ]?ëo°tÇÑa¸Ékœ×éô=Mõ‡ê?Lë٬ζÛqòÐÇ:¢æ´Ë~úZ 2‰?)ýtIÆw¡¸4ð½O&ß«NúÇÐCÜjÊ v $ŸmŽiþ틯ý•ÿ¿ìýÎûOÙ=NLÏôOú¿˜¹Î¯…õ—ë7ì›ðìÅp§/&Ó¹¯¦·K\^Ú÷lÝþzõ ŒÙéDz6Ç”BY%ò×Íóï|©„~kÛaý×ÿÙ8BIM!UAdobe PhotoshopAdobe Photoshop 6.0Z8Z$ Mÿÿ‚‚‚‚8BIMnormÿ(è(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLayer 28BIMluniLayer 28BIMlnsrlayr8BIMlyid8BIMclbl8BIMinfx8BIMknko8BIMlspf8BIMlclr8BIMfxrpÀA  Kÿÿº*W8BIMnormÿ(è(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLayer 18BIMluniLayer 18BIMlnsrlayr8BIMlyid8BIMclbl8BIMinfx8BIMknko8BIMlspf8BIMlclr8BIMfxrp?áæåؘ@!šõÕ:hw AÿÿÆ***8BIMnormÿ(Bü(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ Powered By8BIMTyShB?ð?ð@@ ªªªªªª2TxLrTxt TEXT Powered ByTxtCObjcnullHrzndoubVrtcdoub textGriddingenum textGriddingNoneOrntenumOrntHrznAntAenumAnntAnSm EngineDatatdta@ << /EngineDict << /Editor << /Text (þÿPowered By ) >> /ParagraphRun << /DefaultRunData << /ParagraphSheet << /DefaultStyleSheet 1 /Properties << /Justification 0 /FirstLineIndent 0.0 /StartIndent 0.0 /EndIndent 0.0 /SpaceBefore 0.0 /SpaceAfter 0.0 /AutoHyphenate true /HyphenatedWordSize 8 /PreHyphen 3 /PostHyphen 3 /ConsecutiveHyphens 2 /Zone 36.0 /HyphenateCapitalized true /WordSpacing [ 0.80000 1.0 1.33000 ] /LetterSpacing [ 0.0 0.0 0.0 ] /GlyphSpacing [ 1.0 1.0 1.0 ] /AutoLeading 1.20000 /LeadingType 0 /Hanging false /Burasagari false /KinsokuOrder 0 /EveryLineComposer false >> >> /Adjustments << /Axis [ 1.0 0.0 1.0 ] /XY [ 0.0 0.0 ] >> >> /RunArray [ << /ParagraphSheet << /DefaultStyleSheet 1 /Properties << /Justification 0 /FirstLineIndent 0.0 /StartIndent 0.0 /EndIndent 0.0 /SpaceBefore 0.0 /SpaceAfter 0.0 /AutoHyphenate true /HyphenatedWordSize 8 /PreHyphen 3 /PostHyphen 3 /ConsecutiveHyphens 2 /Zone 36.0 /HyphenateCapitalized true /WordSpacing [ 0.80000 1.0 1.33000 ] /LetterSpacing [ 0.0 0.0 0.0 ] /GlyphSpacing [ 1.0 1.0 1.0 ] /AutoLeading 1.20000 /LeadingType 0 /Hanging false /Burasagari false /KinsokuOrder 0 /EveryLineComposer false >> >> /Adjustments << /Axis [ 1.0 0.0 1.0 ] /XY [ 0.0 0.0 ] >> >> ] /RunLengthArray [ 11 ] /IsJoinable 1 >> /StyleRun << /DefaultRunData << /StyleSheet << /StyleSheetData << /AutoKerning true /Font 0 /FontSize 10.0 /FauxBold false /FauxItalic false /AutoLeading true /Leading 0.0 /Tracking -35 /HorizontalScale 1.0 /VerticalScale 1.0 /BaselineShift 0.0 /FontCaps 0 /FontBaseline 0 /Underline false /YUnderline 1 /Strikethrough false /Ligatures true /OldStyleFigures false /ProportionalNumbers true /BaselineDirection 1 /Tsume 0.0 /StyleRunAlignment 2 /Language 0 /WariChuLineCount 1 /WariChuScale 1.0 /WariChuWidowPercentage 25 /WariChuOrphanPercentage 25 /NoBreak false /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /FillFlag true /StrokeFlag false /FillFirst false >> >> >> /RunArray [ << /StyleSheet << /StyleSheetData << /AutoKerning true /Font 0 /FontSize 10.0 /FauxBold false /FauxItalic false /AutoLeading true /Leading 0.0 /Tracking -35 /HorizontalScale 1.0 /VerticalScale 1.0 /BaselineShift 0.0 /FontCaps 0 /FontBaseline 0 /Underline false /YUnderline 1 /Strikethrough false /Ligatures true /OldStyleFigures false /ProportionalNumbers true /BaselineDirection 1 /Tsume 0.0 /StyleRunAlignment 2 /Language 0 /WariChuLineCount 1 /WariChuScale 1.0 /WariChuWidowPercentage 25 /WariChuOrphanPercentage 25 /NoBreak false /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /FillFlag true /StrokeFlag false /FillFirst false >> >> >> ] /RunLengthArray [ 11 ] /IsJoinable 2 >> /GridInfo << /GridIsOn false /ShowGrid false /GridSize 0.0 /GridLeading 0.0 /GridColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /GridLeadingFillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /AlignLineHeightToGridFlags false >> /AntiAlias 3 /UseFractionalGlyphWidths true /Rendered << /Version 1 /Shapes << /WritingDirection 0 /Children [ << /ShapeType 0 /Procession 0 /Lines << /WritingDirection 0 /Children [ << /Procession 0 /LineTop -9.12598 /Leading 12.0 /WordStarts [ 0 8 11 ] /CharacterCount 11 /Segments << /WritingDirection 0 /Children [ << /Range [ 0.0 30000.0 ] /Words << /WritingDirection 0 /Children [ << /Type 0 /Base << /CharacterCount 8 /Advance 47.92266 /TrailingAdvance 2.98496 /Leading 12.0 /TrailingCharacterCount 1 /StyleRunAlignment 2 /Language 0 /IsBrokenWord 0 /BreakType 0 /StartHang 0.0 /EndHang -0.35000 /MojiKumiFirst 0.0 /MojiKumiMiddle 0.0 /MojiKumiEnd 0.0 /Strikes << /WritingDirection 0 /Children [ << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 0.0 0.0 ] /GlyphMaps [ 51 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 6.87168 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 6.61289 0.0 ] /GlyphMaps [ 82 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 12.93281 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 12.75215 0.0 ] /GlyphMaps [ 90 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 21.84063 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 21.72832 0.0 ] /GlyphMaps [ 72 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 28.04824 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 28.04824 0.0 ] /GlyphMaps [ 85 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 32.13672 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 32.29785 0.0 ] /GlyphMaps [ 72 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 38.61777 0.0 ] >> << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 38.61777 0.0 ] /GlyphMaps [ 71 3 ] /LigatureMaps [ ] /Flags 4 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 47.92266 0.0 ] >> ] >> >> >> << /Type 0 /Base << /CharacterCount 3 /Advance 16.17168 /TrailingAdvance 2.98496 /Leading 12.0 /TrailingCharacterCount 1 /StyleRunAlignment 2 /Language 0 /IsBrokenWord 0 /BreakType 0 /StartHang 0.0 /EndHang -0.35000 /MojiKumiFirst 0.0 /MojiKumiMiddle 0.0 /MojiKumiEnd 0.0 /Strikes << /WritingDirection 0 /Children [ << /Font 0 /Direction 0 /GlyphDirection 0 /Scale [ 10.0 10.0 ] /FontSize 10.0 /Tracking -0.35000 /AntiAlias 3 /Kerning 0.0 /Origin [ 47.92266 0.0 ] /GlyphMaps [ 37 92 2 ] /LigatureMaps [ ] /Flags 68 /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /OriginEnd [ 64.09434 0.0 ] >> ] >> >> >> ] >> >> ] >> >> ] >> /Cookie << /Photoshop << /ShapeType 0 /PointBase [ 0.0 0.0 ] /Base << /ShapeType 0 /TransformPoint0 [ 1.0 0.0 ] /TransformPoint1 [ 0.0 1.0 ] /TransformPoint2 [ 0.0 0.0 ] >> >> >> >> ] >> >> >> /ResourceDict << /KinsokuSet [ << /Name (þÿPhotoshopKinsokuHard) /NoStart (þÿ!\),.:;?]}¢    0!! 0000 0 0 0000A0C0E0G0I0c0ƒ0…0‡0Ž0›0œ00ž0¡0£0¥0§0©0Ã0ã0å0ç0î0õ0ö0û0ü0ý0þÿÿÿ ÿ ÿÿÿÿÿ=ÿ]) /NoEnd (þÿ\([{£§  00 0 0000ÿÿÿÿ ÿ;ÿ[ÿå) /Keep (þÿ  %) /Hanging (þÿ,.00) >> << /Name (þÿPhotoshopKinsokuSoft) /NoStart (þÿ  0000 0 0 00000ž0û0ý0þÿÿ ÿ ÿÿÿÿÿ=ÿ]) /NoEnd (þÿ  00 0 000ÿÿ;ÿ[) /Keep (þÿ  %) /Hanging (þÿ,.00) >> ] /MojiKumiSet [ << /InternalName (þÿPhotoshop6MojiKumiSet1) >> << /InternalName (þÿPhotoshop6MojiKumiSet2) >> << /InternalName (þÿPhotoshop6MojiKumiSet3) >> << /InternalName (þÿPhotoshop6MojiKumiSet4) >> ] /TheNormalStyleSheet 0 /TheNormalParagraphSheet 0 /ParagraphSheetSet [ << /Name (þÿDefault) /DefaultStyleSheet 0 /Properties << /Justification 0 /FirstLineIndent 0.0 /StartIndent 0.0 /EndIndent 0.0 /SpaceBefore 0.0 /SpaceAfter 0.0 /AutoHyphenate true /HyphenatedWordSize 8 /PreHyphen 3 /PostHyphen 3 /ConsecutiveHyphens 2 /Zone 36.0 /HyphenateCapitalized true /WordSpacing [ 0.80000 1.0 1.33000 ] /LetterSpacing [ 0.0 0.0 0.0 ] /GlyphSpacing [ 1.0 1.0 1.0 ] /AutoLeading 1.20000 /LeadingType 0 /Hanging false /Burasagari false /KinsokuOrder 0 /EveryLineComposer false >> >> ] /StyleSheetSet [ << /Name (þÿNormal) /StyleSheetData << /Font 1 /FontSize 18.0 /FauxBold false /FauxItalic false /AutoLeading true /Leading 27.0 /Tracking 0 /HorizontalScale 1.0 /VerticalScale 1.0 /AutoKerning true /Kerning 0 /BaselineShift 0.0 /FontCaps 0 /FontBaseline 0 /Underline false /YUnderline 1 /Strikethrough false /Ligatures true /OldStyleFigures false /ProportionalNumbers true /BaselineDirection 1 /Tsume 0.0 /StyleRunAlignment 2 /Language 0 /WariChuLineCount 1 /WariChuScale 1.0 /WariChuWidowPercentage 25 /WariChuOrphanPercentage 25 /NoBreak false /FillColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /StrokeColor << /Type 1 /Values [ 1.0 0.0 0.0 0.0 ] >> /FillFlag true /StrokeFlag false /FillFirst true >> >> << /StyleSheetData << >> >> ] /FontSet [ << /Name (þÿArial-Black) /Script 0 /FontType 1 /Synthetic 0 /FontMetrics << /FontSize 1.0 /SpaceGlyphWidth 0.33350 /Ascent 0.91260 /Descent 0.21826 /CapHeight 0.72800 /DistanceToBaseline 0.91260 /UnderlinePosition 0.12500 /UnderlineThickness 0.06006 /HCJKProporitional false /VProporitional false >> >> << /Name (þÿHelvetica) /Script 0 /FontType 1 /Synthetic 0 /FontMetrics << /FontSize 1.0 /SpaceGlyphWidth 0.27783 /Ascent 1.02539 /Descent 0.44629 /CapHeight 0.73700 /DistanceToBaseline 1.02539 /UnderlinePosition 0.07568 /UnderlineThickness 0.04932 /HCJKProporitional false /VProporitional false >> >> ] /SuperscriptSize 0.58300 /SuperscriptPosition 0.33300 /SubscriptSize 0.58300 /SubscriptPosition 0.33300 /SmallCapSize 0.70000 >> >> ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªwarp warpStyleenum warpStylewarpNone warpValuedoubwarpPerspectivedoubwarpPerspectiveOtherdoub warpRotateenumOrntHrzn8BIMluni Powered By8BIMlnsrrend8BIMlyid8BIMclbl8BIMinfx8BIMknko8BIMlspf8BIMlclr8BIMfxrpÀ@´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿ´ÿá¹ðáô¹ÿôð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðð¹ÿðô¹ÿô&./;JKFKKJJIJJBII( ·þÿþýÿýþþÿõþýÿìþüÿîþÿþ ÿøèöÿþþÿìë÷ÿ÷þûµŠ§ûÿíþú¢tµúÿþýÿôþþÿ–-„õÿÿüDBÖýÿúþÿî )Ðÿÿïþ ÿ¨¡ûÿûéÐ÷ÿõþþÿ}1Ëÿÿî‘öÿúþÿë½ÿÿïþÿ þ[îÿ• ¯üÿöþþÿµ¡ýÿ»¢üûÿÿþÿë½ÿÿþûÿüþüÿ þÿöq!…öÿzp÷üÿÿþýÿþ þÿá~õÿ-ÍþÿܵÃôþÿë¾ýÿ乿èÿÿþþÿÿß¶Âíÿúôâ Ÿãüõvbãø÷íêþÿýæïûÿIþÿú@WéÿCRéÿÚ^7¬ùÿë¾ÿÿõ€€ðÿþÿÞX%™\# VêŸUF'ÁûÿË…öþÿÿ‡1Õçýü8 ÿì¾ÿÿgûgìÿï3ü*þ¤•(5Væÿ‹EáÿþGÿÆÀ²¨ÿ´"‚zBìî¾ÿÎ6j  ÿ‘ LwGR¤y Žì¨5*^ˆ•*Ëÿ[]ïÿþGÿõ1›p>Òÿ^F¶´¾í½ÿ‚ŸöjRç@8Êùå×øç üÿucãøñ1 £÷% Œýÿþÿÿ ri2hïý8þÿ Ÿè¿ÿh6ÌÿŽ1Äbñýÿô" üÿ~jôÿÿ}{Í !µÿþþFÿ´6 ˜ýú2™æ¿ÿe>Óÿ(´qôÿþþÿñ! üÿ|iñÿÿÊU‡DÖÿþþ*ÿí3ÈÿþGJŽ’”ÔéÁÿv;Òÿ,¼&põýÿñ! üÿ|kõÿÿù6/AtðÿþþFÿüBVåÿÿu_ñÿñÑôÿë·ÿ¨'ÈÿM=ÚOPóÿïþÿñ! üÿ{gãìÿÿiŸýÿþþÿÿDs…úÿÿÑ JW0 Šûò"ªí>DSrú² X`&¡øò ŒüÿŒFÞÿ¶6Êÿÿýþÿ°þ°ýÿü4ßþOþ8ãÐ$ü?Áÿýoü :Øõ ŒüÿÁþ Ÿÿô*[èÿþýþEÿíi2*U×ÿþþÿñ—D#)B…èÿÊHHÕÿ¿K""Qµöÿÿéx3)oÛýŸOK¬ýÿúˆ.6­ÿÿ¾3†ùÿþýþÿÿö×ÑÞúÿþþÿÿçÉ¿Ëáöþÿ/éÀ·ÑöÿÿìɶÂãÿÿþþÿúܼµÊëüÿþéåóþÿÿüÖ¶¹Òëíÿó0µÿÿþûþüÿüþúÿÿþûÿþúÿýþúÿþýÿþþüÿ „ b:<Øÿþþïþÿÿúþÿÿüþþÿùþþÿõþÿÿú>ý…öÿþþÄþÿÿ Í[#+yÛÿÿþþÃþÿüåÁ±Áéþÿþþ&./;JKKKKJJIJJHII(!·þÿþýÿýþþÿõþýÿìþüÿîþÿþÿùìøÿþþïîøÿ÷þüÛµùÿíþû´ŠÀùÿþýÿôþþÿ©M:“óÿÿüg7c×ýÿúþÿð<EÍÿÿïþ ÿ¸'!4¤úÿüìØøÿõþþÿ” *HÈÿÿñB(,‘öÿúþÿî<,7ºÿÿïþ ÿ±%.&^íÿ©38µûÿöþþÿÁ0/1 ýÿÇ0/-Ÿüûÿÿþÿî=,7ºÿÿþûÿüþüÿ þÿõ„9.„õÿ“)uõüÿÿþýÿþ þÿæ;/,õÿ–&-:ËþÿâÁÌõþÿî=,8»ýÿéÆÉëÿÿþþÿÿäÄÌïÿûöá žâü÷%+iäúùïíþÿþêñüÿIþÿúc),_æÿg*'Téÿàz:/0Y·øÿî=,8»ÿÿö—>10C”ïÿþÿäu:10K¨yDLGqæ±C=01:Dpf=NÂúÿÔ>@•õIþÿÿ›(-DÑí>0#}ýü^#)$+(1¥ÿï=,8»ÿÿƒ#-&(*(yéÿòZ#.%($4F),-.¡§++32*";N*(`äÿ¡$&NßÿþGÿÎ3.5¼Á//)¦ÿÂ-,,{ƒ5(Yéñ=,8»ÿ×40$5nA-2¢ÿ¦%2!KxWT¤}61*í¦N..2_‡ 3-@Èÿz(%]îÿþGÿöW*-™Š()BÑÿ|'(P¿¿>-9½ð>,8»ÿ™%/+œôƒ'+^åe*+;Éøã×öéH-+‹üý%+gá÷ñW*0¡øN-$‰ýÿþÿÿ)Š'-oW.$gîý^+267620.žë?,8¼ÿ„&,?Êÿ¢(-DÃH/'bñýÿöK-*Œüÿ–$+póÿÿ“'*Ó8,-²ÿþþFÿÀ0-K90)•ýúX,/(**,*,˜è?,8¼ÿ‚',GÑÿ£(.;´B/(rôÿþþÿóK-*Œûÿ”$+nðÿÿÑ6)e—.(GÕÿþþ*ÿîF.33->Æÿþi*(JŽŽ‘”Òì>,8½ÿ%-GÐÿ˜%.:¼P-+qôýÿóK-+Œüÿ”$+oóÿÿù[(J[-$rðÿþþFÿüe*12*Zäÿÿ%+kîýò×óÿî<,8¶ÿ·)->Äÿn)*BØp',]ïÿòýÿóK-+Œüÿ“$+mäïÿÿƒ%7;/+œüÿþþÿÿDŒ&22%„ùÿÿ×;+:iwX8—ùôH,3H²ì`&1`r30 pø¾/-7t~N©öôJ,*‹ûÿ¡'0@FcÝÿÂ./1-@Èÿÿýþÿ½(++%­ýÿ:’,)&%( FÝþo#/'LßÓG''&. ?Àÿü„'+&%"JÕ÷I&%‹ûÿÊ0+.),ŸþõQ*2)^çÿþýþEÿï}G=ZÖÿþþÿïX>8;G„èÿÏ_91PÔÿÂ`>54Rµöÿÿç„L838oÛýª\S¬ýÿú–H53A¬ÿÿÃN-%„ùÿþýþÿÿóÔÎÝúÿþþÿþ寽Èàöþÿ/ç¾µÏöÿÿêÆ³¿âÿÿþþÿøÙº²ÈëüÿüçäóþÿÿúÔ´¶ÑìðÿóU))²ÿÿþûþüÿüþúÿÿþûÿþúÿýþúÿþýÿþþüÿ œD~_0'?×ÿþþïþÿÿúþÿÿüþþÿùþþÿõþÿÿ úa!#)*"„öÿþþÄþÿÿ Ïi:/4wÛÿÿþþÃþÿûã¾­¿éþÿþþ*./GKKKKKIJJJIIIH;!·üÿüýþÿþýüþÿþõüþÿýìüýþÿþîüÿüþøïøþþüòñøÿøüýûвÃ÷ýîü ýúŦÌ÷ýüýÿÿýôüüþ¾xi£ñþþüŒh†ÙüýúüÿòkWbÊÿýïü ÿÈ[Xb©øþúïàøýõüüÿ®W`_Äÿÿòp_RõþúüÿðlbR·ÿýïü ÿÂ[eTbëÿ½egºúþöüüÿÎbdRŸüÿÓceFûýýþÿ þüüÿñmbS·ÿýüüýÿýüüýýÿüÿõ™X;ƒôÿ­WYzòÿþÿÿýþüÿÿýü üÿéjcXôÿ¯\`HÉþÿçÎ×õÿþÿðmbS¸ÿýþÿìÒÕíÿÿþüÿÿèÑÖðÿû÷á âüù¨[ZpæûùñðÿýýüîóûþIüþù‡^]häÿ‹_SWèÿç™ked€ÂõÿðmbS¸ÿþø°medp©îÿüÿê–jedv·—rxtãÃrmccgsŒ‡mwÄùÿÜmn¥óÿüGÿ±]bYÍñmfAzüü…ZUBW__«þòmbS¸ÿÿ¡ZaOS`\‹æÿô‚Y`LRZKdX^cPœºY[edXROia[lâÿ¶ZXXÞÿüGÿ×ddR¸Ñac:£ÿÑa]5tŒf^påõmbS¸ÿàeeF4qkb]¤ÿ»[e:JziV¤bgKŒî¥gd^8`…¬ebXÄÿš^O^îÿüGÿõ`U˜¥^WEÏÿ›]QZÈÉlb[»ómbS¸ÿ²[b;˜ò\^lä‹_Y>Ç÷à×õêtcKŠúû¦[Zmßöò}`V¡ùzc>‡üþü*ÿ¤\]v}eFgìý…_dijifgUínbS¹ÿ¡\^JÉÿ¸]bYÃudPcðýÿövbL‹úÿ¯ZZuòÿÿ«]Z„Úi`;°ÿþüFÿÌb``ge?“úù€`\NPPQQF—ënbS¹ÿŸ\]RÐÿ¹\cP´qdPsóÿüüÿôvbL‹úÿ­ZZtîÿÿÙg]t¨dTIÕÿþüFÿðsbXb_IÄÿüŒ`OHŒŽŽ“ÑðmbSºÿª[_UÎÿ±[bI»{bVròÿÿýÿôvcKŠúÿ­ZZtñÿÿø_eweBoïÿþüFþû‰_`dY]äÿÿ§[]xëýóÞóÿòlbT´ÿÇ^bV¿ÿ‘_ZGÖ’]^jêÿóüÿôvbL‹úÿ­Z[såóÿÿŸ]Zbe?™üþýüEÿ¦[dgFƒøþÿÜj`h‹˜i¦öõtaaoºë„]a~“ff9nöÊabd‘y±ôõubKŠúÿ·\bir‚ÛÿÎb_b_LÆÿüýüEÿÊ]ab8ªÿýþþ¤[_^]]QXÚþZe`aÛ×n^_^cC@¿ÿúš[a^^WYÒøt\F‰ùÿÔbadaSžýôy^fWbçÿüýüEþð‘\S^Õÿüüÿí¤nYSMMƒèÿÔyXLYÓÿÃv]QGS´õýÿæ‘fWOGpÛý·k\¬ûÿø¥eTMNªþÿÈodF„ùþüüüÿïÐËÝùýþüþüáĹÆßõþý/ä¼²Îõþþçı¼âþþüüÿö׸®Æëûýúäãóüüþ÷Ѳ²Îîòÿô}_:°ÿüüûüþþÿýüüýüÿþþüýÿýüýüÿýýüþüÿýüýÿÿþþüþýÿ ´qœ†eUBÖÿüüîüýúüÿýûüÿýùüÿýôü ýÿû†W\aY1‚õÿüüÄü ýþÓySF=uÛþþüÃüýúỪ¾éýýþü?>9?<< @ýÿ¯Ýÿþ@ýÿß0ú@ÿÿ¿ÿÿ`Þÿþ@ÿÿ¿ïÿ¿ú,@ÿÿ¿ÿ0Ïÿïÿÿ¯ÿp@ÿϯÿÿ¯0ÿŸÿP`ßÿß`ïïÏÿþ @ÿÿÏÿÿÿÿ,@ÿÿ¿ÿÿpïÿPŸÿ¯ÿ@ÿÿ¯ÿp¿ÿppÿ¿ÿï@ÿÏ@Ïÿ`ÿïPÏÿþ@ýÿïP ÿÏ0ÿ¯@ýÿ@ÿ¿@ÿ¿`ÿÏÿ¯ÿÏÿ ûÿÿüÿ¿ÿ¿ÿþ @ÿÿ@ÿï¿ÿÿ`@ÿÿþ& ÿßpÿŸïÿï0ÿÿ¿ßÿ0 @ÿ`ÿ¯``@ÿ߯ÿþ @ÿÿ¯ÿï`ÿßÿ@ÿÿý`þÿ ÏŸÿŸßÿ`Pïþÿ`ÿ¿þÿÏŸÿÿÏÿþ@üÿpßÿ¯@@ü@0þ @ 0@@@ @ þ0@0þÿ0@ þý@ þ¿ÿPÊp¿ÿßþÊ0 þÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ8BIMPattCA<B>> )12>LNINNLMLMLFMM,$CA<B>> )12>LNNNNLMLMLLMM,%CA<B>> &-12JNNNNNLMMNMMML?%´ÿþÿ¿ýPÝÿ€€þÿ¿ý Ïîÿþÿ¿@ŸÞÿ€€þÿ¿@@îÿþÿ,¿ÿ@€Ï0pïÿP¿0ïPPÏ€`¯Ÿ €ÿŸ0€þÿ ¿€0€ppÿïõÿþÿ,¿@¯`€P¿P€@@€p¿0¿0Ÿ¯0€þÿ¿ý¯ß0ÏPôÿþÿ¿ýp¿@ÿ¿@Ÿ0P0ßû€pÿ€ü@@ÿ€€þÿ ¿¿€ÿ@pŸôÿþÿ¿þÿ&ß ï`ïÏ@ÿ Ï߀¿€€ÿŸPÿŸŸ¿ ïP€þÿ ¿€PÿŸ ïôÿþÿ¿ýÿŸþ 0ïÿ``ÿ Ÿÿ¯þŸ€€ÿÿ@þ0ï`0€þÿ¿üÿÿ Póÿþÿï¿¿üÿï¿Ïþÿß¿ßÿÏ¿ïÿÿï¿¿ïÿß¿ßþÿÏ¿ÏþÿÿÏï¿ßþÿïý¿ßþÿ@¯óÿÿÈþŽ@ ôþÿÿÿþþýÿýþþÿõþýÿìþüÿÿþÎÞôþÿÿÿþþÿøèöÿþþÿìë÷ÿ÷þûµŠ§ûÿíþú¢tµúÿþýÿôþÿÿÿþÿ–-„õÿÿüDBÖýÿúþÿî )Ðÿÿïþ ÿ¨¡ûÿûéÐ÷ÿõþÿÿÿþÿ}1Ëÿÿî‘öÿúþÿë½ÿÿïþÿ þ[îÿ• ¯üÿöþÿÿÿþÿµ¡ýÿ»¢üûÿÿþÿë½ÿÿþûÿüþüÿ þÿöq!…öÿzp÷üÿÿþýÿþÿÿÿþÿá~õÿ-ÍþÿܵÃôþÿë¾ýÿ乿èÿÿþþÿÿß¶Âíÿúôâ Ÿãüõvbãø÷íêþÿýæïûþÿLÿþÿú@WéÿCRéÿÚ^7¬ùÿë¾ÿÿõ€€ðÿþÿÞX%™\# VêŸUF'ÁûÿË…÷ÿÿ ÿþÿÿ‡1Õçýü8 ÿì¾ÿÿgûgìÿï3ü*þ¤•(5Væÿ‹EãÿÿLÿþþÿÆÀ²¨ÿ´"‚zBìî¾ÿÎ6j  ÿ‘ LwGR¤y Žì¨5*^ˆ•*Ëÿ[]ðÿÿLÿþþÿõ1›p>Òÿ^F¶´¾í½ÿ‚ŸöjRç@8Êùå×øç üÿucãøñ1 £÷% Œýÿÿÿþþÿÿri2hïý8þÿ Ÿè¿ÿh6ÌÿŽ1Äbñýÿô" üÿ~jôÿÿ}{Í !µþÿÿþþEÿ´6 ˜ýú2™æ¿ÿe>Óÿ(´qôÿþþÿñ! üÿ|iñÿÿÊU‡DÖþÿÿþþ*ÿí3ÈÿþGJŽ’”ÔéÁÿv;Òÿ,¼&põýÿñ! üÿ|kõÿÿù6/AtðþÿÿþþEÿüBVåÿÿu_ñÿñÑôÿë·ÿ¨'ÈÿM=ÚOPóÿïþÿñ! üÿ{gãìÿÿiŸýþÿÿþþÿÿBs…úÿÿÑ JW0 Šûò"ªí>DSrú² X`&¡øò ŒüÿŒFÞÿ¶6Êýÿÿýþÿ°þ°ýÿü4ßþOþ8ãÐ$ü?Áÿýoü :Øõ ŒüÿÁþ Ÿÿô*[èÿþÿÿÿýþGÿíi2*U×ÿþþÿñ—D#)B…èÿÊHHÕÿ¿K""Qµöÿÿéx3)oÛýŸOK¬ýÿúˆ.6­ÿÿ¾3†ùÿþÿÿÿýþÿÿö×ÑÞúÿþþÿÿçÉ¿Ëáöþÿ1éÀ·ÑöÿÿìɶÂãÿÿþþÿúܼµÊëüÿþéåóþÿÿüÖ¶¹Òëíÿó0µÿÿþÿÿÿûþüÿüþúÿÿþûÿþúÿýþúÿþýÿþþüÿ „ b:<Øÿþþÿÿÿïþÿÿúþÿÿüþþÿùþþÿõþÿÿú>ý…öÿþþÿÿÿÄþÿÿ Í[#+yÛÿÿþþÿÿÿÃþÿüåÁ±Áéþÿþþÿÿ´ÿþÿ¿ýPÝÿ€€þÿ¿ý Ïîÿþÿ¿@ŸÞÿ€€þÿ¿@@îÿþÿ,¿ÿ@€Ï0pïÿP¿0ïPPÏ€`¯Ÿ €ÿŸ0€þÿ ¿€0€ppÿïõÿþÿ,¿@¯`€P¿P€@@€p¿0¿0Ÿ¯0€þÿ¿ý¯ß0ÏPôÿþÿ¿ýp¿@ÿ¿@Ÿ0P0ßû€pÿ€ü@@ÿ€€þÿ ¿¿€ÿ@pŸôÿþÿ¿þÿ&ß ï`ïÏ@ÿ Ï߀¿€€ÿŸPÿŸŸ¿ ïP€þÿ ¿€PÿŸ ïôÿþÿ¿ýÿŸþ 0ïÿ``ÿ Ÿÿ¯þŸ€€ÿÿ@þ0ï`0€þÿ¿üÿÿ Póÿþÿï¿¿üÿï¿Ïþÿß¿ßÿÏ¿ïÿÿï¿¿ïÿß¿ßþÿÏ¿ÏþÿÿÏï¿ßþÿïý¿ßþÿ@¯óÿÿÈþŽ@ ôþÿÿÿþþýÿýþþÿõþýÿìþüÿÿþÎÞôþÿÿÿþþÿùìøÿþþïîøÿ÷þüÛµùÿíþû´ŠÀùÿþýÿôþÿÿÿþÿ©M:“óÿÿüg7c×ýÿúþÿð<EÍÿÿïþ ÿ¸'!4¤úÿüìØøÿõþÿÿÿþÿ” *HÈÿÿñB(,‘öÿúþÿî<,7ºÿÿïþ ÿ±%.&^íÿ©38µûÿöþÿÿÿþÿÁ0/1 ýÿÇ0/-Ÿüûÿÿþÿî=,7ºÿÿþûÿüþüÿ þÿõ„9.„õÿ“)uõüÿÿþýÿþÿÿÿþÿæ;/,õÿ–&-:ËþÿâÁÌõþÿî=,8»ýÿéÆÉëÿÿþþÿÿäÄÌïÿûöá žâü÷%+iäúùïíþÿþêñüþÿLÿþÿúc),_æÿg*'Téÿàz:/0Y·øÿî=,8»ÿÿö—>10C”ïÿþÿäu:10K¨yDLGqæ±C=01:Dpf=NÂúÿÔ>@•öÿÿLÿþÿÿ›(-DÑí>0#}ýü^#)$+(1¥ÿï=,8»ÿÿƒ#-&(*(yéÿòZ#.%($4F),-.¡§++32*";N*(`äÿ¡$&NáÿÿLÿþþÿÎ3.5¼Á//)¦ÿÂ-,,{ƒ5(Yéñ=,8»ÿ×40$5nA-2¢ÿ¦%2!KxWT¤}61*í¦N..2_‡ 3-@Èÿz(%]ïÿÿLÿþþÿöW*-™Š()BÑÿ|'(P¿¿>-9½ð>,8»ÿ™%/+œôƒ'+^åe*+;Éøã×öéH-+‹üý%+gá÷ñW*0¡øN-$‰ýÿÿ.ÿþþÿÿŠ'-oW.$gîý^+267620.žë?,8¼ÿ„&,?Êÿ¢(-DÃH/'bñýÿöK-*Œüÿ–$+póÿÿ“'*Ó8,-²þÿÿþþEÿÀ0-K90)•ýúX,/(**,*,˜è?,8¼ÿ‚',GÑÿ£(.;´B/(rôÿþþÿóK-*Œûÿ”$+nðÿÿÑ6)e—.(GÕþÿÿþþ*ÿîF.33->Æÿþi*(JŽŽ‘”Òì>,8½ÿ%-GÐÿ˜%.:¼P-+qôýÿóK-+Œüÿ”$+oóÿÿù[(J[-$rðþÿÿþþEÿüe*12*Zäÿÿ%+kîýò×óÿî<,8¶ÿ·)->Äÿn)*BØp',]ïÿòýÿóK-+Œüÿ“$+mäïÿÿƒ%7;/+œüþÿÿþþÿÿBŒ&22%„ùÿÿ×;+:iwX8—ùôH,3H²ì`&1`r30 pø¾/-7t~N©öôJ,*‹ûÿ¡'0@FcÝÿÂ./1-@Èýÿÿýþÿ½(++%­ýÿ<’,)&%( FÝþo#/'LßÓG''&. ?Àÿü„'+&%"JÕ÷I&%‹ûÿÊ0+.),ŸþõQ*2)^çÿþÿÿÿýþGÿï}G=ZÖÿþþÿïX>8;G„èÿÏ_91PÔÿÂ`>54Rµöÿÿç„L838oÛýª\S¬ýÿú–H53A¬ÿÿÃN-%„ùÿþÿÿÿýþÿÿóÔÎÝúÿþþÿþ寽Èàöþÿ1ç¾µÏöÿÿêÆ³¿âÿÿþþÿøÙº²ÈëüÿüçäóþÿÿúÔ´¶ÑìðÿóU))²ÿÿþÿÿÿûþüÿüþúÿÿþûÿþúÿýþúÿþýÿþþüÿ œD~_0'?×ÿþþÿÿÿïþÿÿúþÿÿüþþÿùþþÿõþÿÿ úa!#)*"„öÿþþÿÿÿÄþÿÿ Ïi:/4wÛÿÿþþÿÿÿÃþÿûã¾­¿éþÿþþÿÿ´ÿþÿ¿ýPÝÿ€€þÿ¿ý Ïîÿþÿ¿@ŸÞÿ€€þÿ¿@@îÿþÿ,¿ÿ@€Ï0pïÿP¿0ïPPÏ€`¯Ÿ €ÿŸ0€þÿ ¿€0€ppÿïõÿþÿ,¿@¯`€P¿P€@@€p¿0¿0Ÿ¯0€þÿ¿ý¯ß0ÏPôÿþÿ¿ýp¿@ÿ¿@Ÿ0P0ßû€pÿ€ü@@ÿ€€þÿ ¿¿€ÿ@pŸôÿþÿ¿þÿ&ß ï`ïÏ@ÿ Ï߀¿€€ÿŸPÿŸŸ¿ ïP€þÿ ¿€PÿŸ ïôÿþÿ¿ýÿŸþ 0ïÿ``ÿ Ÿÿ¯þŸ€€ÿÿ@þ0ï`0€þÿ¿üÿÿ Póÿþÿï¿¿üÿï¿Ïþÿß¿ßÿÏ¿ïÿÿï¿¿ïÿß¿ßþÿÏ¿ÏþÿÿÏï¿ßþÿïý¿ßþÿ@¯óÿÿÈü? ôüÿÿÿüüýþÿþýüþÿþõüþÿýìüýþÿþüüÍ~~ÜôüÿÿÿüüþøïøþþüòñøÿøüýûвÃ÷ýîü ýúŦÌ÷ýüýÿÿýôüÿÿÿüþ¾xi£ñþþüŒh†ÙüýúüÿòkWbÊÿýïü ÿÈ[Xb©øþúïàøýõüÿÿÿüÿ®W`_Äÿÿòp_RõþúüÿðlbR·ÿýïü ÿÂ[eTbëÿ½egºúþöüÿÿÿüÿÎbdRŸüÿÓceFûýýþÿ þüüÿñmbS·ÿýüüýÿýüüýýÿüÿõ™X;ƒôÿ­WYzòÿþÿÿýþüÿÿýüÿÿÿüÿéjcXôÿ¯\`HÉþÿçÎ×õÿþÿðmbS¸ÿýþÿìÒÕíÿÿþüÿÿèÑÖðÿû÷á âüù¨[ZpæûùñðÿýýüîóûþÿÿLÿüþù‡^]häÿ‹_SWèÿç™ked€ÂõÿðmbS¸ÿþø°medp©îÿüÿê–jedv·—rxtãÃrmccgsŒ‡mwÄùÿÜmn¥ôÿÿLÿüüÿ±]bYÍñmfAzüü…ZUBW__«þòmbS¸ÿÿ¡ZaOS`\‹æÿô‚Y`LRZKdX^cPœºY[edXROia[lâÿ¶ZXXàÿÿLÿüüÿ×ddR¸Ñac:£ÿÑa]5tŒf^påõmbS¸ÿàeeF4qkb]¤ÿ»[e:JziV¤bgKŒî¥gd^8`…¬ebXÄÿš^O^ïÿÿLÿüüÿõ`U˜¥^WEÏÿ›]QZÈÉlb[»ómbS¸ÿ²[b;˜ò\^lä‹_Y>Ç÷à×õêtcKŠúû¦[Zmßöò}`V¡ùzc>‡üÿÿÿþü*ÿ¤\]v}eFgìý…_dijifgUínbS¹ÿ¡\^JÉÿ¸]bYÃudPcðýÿövbL‹úÿ¯ZZuòÿÿ«]Z„Úi`;°þÿÿþüEÿÌb``ge?“úù€`\NPPQQF—ënbS¹ÿŸ\]RÐÿ¹\cP´qdPsóÿüüÿôvbL‹úÿ­ZZtîÿÿÙg]t¨dTIÕþÿÿþüEÿðsbXb_IÄÿüŒ`OHŒŽŽ“ÑðmbSºÿª[_UÎÿ±[bI»{bVròÿÿýÿôvcKŠúÿ­ZZtñÿÿø_eweBoïþÿÿþüHþû‰_`dY]äÿÿ§[]xëýóÞóÿòlbT´ÿÇ^bV¿ÿ‘_ZGÖ’]^jêÿóüÿôvbL‹úÿ­Z[såóÿÿŸ]Zbe?™üþÿÿÿýüGÿ¦[dgFƒøþÿÜj`h‹˜i¦öõtaaoºë„]a~“ff9nöÊabd‘y±ôõubKŠúÿ·\bir‚ÛÿÎb_b_LÆÿüÿÿÿýüGÿÊ]ab8ªÿýþþ¤[_^]]QXÚþZe`aÛ×n^_^cC@¿ÿúš[a^^WYÒøt\F‰ùÿÔbadaSžýôy^fWbçÿüÿÿÿýüGþð‘\S^Õÿüüÿí¤nYSMMƒèÿÔyXLYÓÿÃv]QGS´õýÿæ‘fWOGpÛý·k\¬ûÿø¥eTMNªþÿÈodF„ùþüÿÿÿüüÿïÐËÝùýþüþüáĹÆßõþý1ä¼²Îõþþçı¼âþþüüÿö׸®Æëûýúäãóüüþ÷Ѳ²Îîòÿô}_:°ÿüüÿÿÿûüþþÿýüüýüÿþþüýÿýüýüÿýýüþüÿýüýÿÿþþüþýÿ ´qœ†eUBÖÿüüÿÿÿîüýúüÿýûüÿýùüÿýôüýÿû†W\aY1‚õÿüüÿÿÿÄü ýþÓySF=uÛþþüÿÿÿÃüýúỪ¾éýýþüÿÿvelocity-1.7/xdocs/images/velocity_project_wide.xcf0000644000175000017500000005622210557734552022606 0ustar moellermoellergimp xcf file3BB $gimp-image-grid(style intersections) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) ›™×‘%ÿ"Theÿ     fÿÿÿþ"gimp-text-layer(text "The") (font "Arial Black") (font-size 16.000000) (font-size-unit pixels) (hinting yes) (antialias yes) (language "en-us") (base-direction ltr) (color (color-rgba 0.000000 0.000000 0.000000 1.000000)) (justify center) (box-mode dynamic) (box-unit pixels) q"…"•Ì ÿÿ ÿÿÿÿÿÿù#¯òó¥ø¡èüê¬'ÿÿþìÿÿúæÿÿýò$ÿÿî‡ `ÿÿê›ÿÿYPÿÿ¨ÿÿöÿÿþåÿÿþèÿÿÿþüÿÿþýÿÿÿûèÿÿÿÿÿöŸÿÿ” kÿÿÀÿÿÿýìÿÿýó+ÿÿÿø&­ìýî´/«‰,Apache Velocity Projectÿ     Šÿÿÿø6gimp-text-layer(text "Apache Velocity Project") (font "Arial Black") (font-size 30.000000) (font-size-unit pixels) (hinting yes) (antialias yes) (language "en-us") (base-direction ltr) (color (color-rgba 0.000000 0.000000 0.000000 1.000000)) (justify center) (box-mode dynamic) (box-unit pixels) —‰,·³¿Ë‰,ß  u¬³-   þªÿÿþž2ýðÿÿýè1þAÿ ÿþ61þŒÿ ÿþ‚1þØÿ ÿþÎ0þ#ÿÿþêÿÿþ/þoÿÿþqÿÿþfÿöŒN´ëüë²EòUŸËêøþùíØ´sþºÿÿüöìÿÿþ²ÿýÿÿþŠý'Óÿ ÿýîGý ùÿÿü½§ÿÿýõÿþõÿÿþdýæÿ ÿýõ þQÿÿü}`ÿÿþJÿúì‰ÿ ÿþþœÿÿü>ÿÿþ–ÿúïJJòÿÿûfßÿÿúÓ< ~ÿÿþÖýæÿÿú÷Òÿÿþáÿþhþqÿÿõ°@k•Àë2þ ÿÿþøþ3ÿÿþ¿þ‹ÿÿþ.ÿþþ"ÿÿþàû8}Òÿÿþÿÿþzÿþúþÿÿþõú%d™ËùÿÿþÊÿÿþÆÿþùþÿÿþùýBÌÿ ÿýþÿÿýýÿþþÿÿúèEýÿÿúþÉŽZ!ÿÿþaÿÿþ^ÿþgþeÿÿûÂÇÿÿþ<þ0ÿÿþ­ÿÿþªÿúðN>êÿÿû„øÿÿú\Yàÿÿýòÿÿþ@þ#ÿÿýðÿúü ëÿÿþDÿÿýøþêÿÿþBÿþ€þ˜ÿÿýú×ÿÿü ÿÿþÂþ±ÿÿþŽÿþµÿÿý—ýÍÿÿüîI~ÿÿü.ÚÿÿþƒþxÿÿþÚÿ÷T¶êüë²EôqÅðüñÈ|0ÿÿþˆÿ9ÿ9ÿ9ÿ9ÿ9ÿ    ÿ9ÿ9ÿ9ÿ9ÿ9ÿ)ô1ŒÆèøüñÙ±mÿö ÔøõÊeõ1ŽÊîüøéÊ“A ý¥ÿÿýôqÿý$ÛÿÿþýªÿÿýÅ$ýÓÿ ÿþŒÿþâÿÿþKý×ÿ ÿýí*þ»ÿ ÿüHÿ ÿþ¬þºÿ ÿýÔþPÿÿú‰;ØÿÿüÉÿ ÿþáþIÿÿùÚG AÏÿÿþXþ¬ÿÿþ›ö2ëÀ•k@ÿÿûÒ& Ÿÿÿþ÷þ§ÿÿþ1þ(ÿÿþªþáÿÿþ4 ÿûHÿÿþàÿÿþÛþúÿÿþ ÿûÿÿþúÿÿþõþüÿÿþ ÿþÿþøÿÿþéÿÿþ$ ÿÿþßÿÿþþ¼ÿÿþƒö=ê¿•j?ÿÿÿþ¦ÿÿþqþfÿÿùûrSåÿÿüÏÿÿÿþIÿÿùøp2¥ÿÿþµýÒÿ ÿüPÿÿÿþ¼ÿ ÿýñ"ý$æÿ ÿþ’ÿÿýßÿ ÿýùKý¾ÿÿýõuÿÿý¿ÿÿýãA ô=‘Çèùþøâ¸sÿÿôC™ÍíûüñÕ¨^ˆ   þÒÿÿþþÿÿþÑÿþvÿÿþÃþÄÿÿþtÿýýÿÿýú ý úÿÿýýÿþ¾ÿÿþIþJÿÿþ»ÿþbÿÿþ‹þŒÿÿþ^ÿý÷ÿÿþÎþÏÿÿýõ ÿþ©ÿÿýþýþÿÿþ¤õ1ŽÊîüøéÊ“Aÿü ~ÀþMÿÿþTþUÿÿþHýªÿÿýÅ$ÿúŽûÿÿýëÿÿþ–þ—ÿÿùç×ÿ ÿýí*ÿý Áÿÿþ•ÿÿþÙþÚÿÿþŽþºÿ ÿýÔÿþ£ÿÿþ8ÿÿüÿÿû2IÿÿùÚG AÏÿÿþXÿþ:ÿÿþýþÛÿÿü^_ÿÿþÕþ§ÿÿþ1þ(ÿÿþªÿþŸÿÿþŒþ€ÿÿü¡¢ÿÿþxþàÿÿþÛÿþÝÿÿþ+þ$ÿÿüäåÿÿýþþúÿÿþõÿþúÿÿþþÈÿÿþOÿÿþ¿þøÿÿÿþúÿÿþþlÿÿþÒÿÿþbþßÿÿþ ÿþßÿÿþ*ýúÿÿý÷þ¦ÿÿþq ÿþ¢ÿÿþ‰ þ³ÿÿþ¨þIÿÿùøp2¥ÿÿþµÿþ=ÿÿþü þWÿÿþLþ¼ÿ ÿýñ"ÿþ§ÿÿ ý ñÿÿýêýßÿ ÿýùKÿý Ãÿÿ þŸÿÿþ’ý¿ÿÿýãAÿúŒüÿÿ þBÿÿþ6ôC™ÍíûüñÕ¨^ÿü}½   "ÿý9½-ÿû0´ÿÿ-ÿü)ªþÿÿ.ÿþýÿÿ9ÿ9ÿ øèûúè„(ô1ŒÆèøüñÙ±mÿ ÿýÌÿÿü‰ÿÿüþ ý¥ÿÿýôqÿ ÿýeÿÿüÓÿÿýÑýÓÿ ÿþŒÿ ÿü òÿÿýÿÿþ®þ»ÿ ÿþHÿ ÿþ—ÿÿøizuýÿÿû>Pÿÿú‰;ØÿÿþÉÿÿþ0ÿÿþ³þŠÿÿû¡¬ÿÿþ›ø2ëÀ•k@ÿÿþÉÿÿýõþ)ÿÿûÝáÿÿþ4 ÿÿþbÿÿþIþÿÿûöúÿÿþ ÿÿý ðÿÿþ“þÿÿûùüÿÿþ ÿÿþ”ÿÿþÞþ*ÿÿûÜéÿÿþ$ ÿÿþ-ÿÿþ†ÿÿûŸ¼ÿÿþƒø=ê¿•j?ÿþúÿÿþþÆÿÿúuqûÿÿû=fÿÿùûrSåÿÿþÏÿþëÿÿûW&-þ_ÿ ÿþ¨ýÒÿ ÿþPÿþÆÿÿþýîÿ ÿýÉ ý$æÿ ÿþ’ÿþ|ÿÿþ½þÿÿüü— ý¾ÿÿýõuÿý ÓÿÿþÝþ*ÿÿøçøûé‚$ô=‘Çèùþøâ¸sÿö‡ÑóýõåÆšüÂÿÿ;ü£ÿÿ6÷Bxþÿÿ6þçÿÿ7þÊÿÿ7þ®ÿÿ7÷iËäøüïˆÿ    ÿûôÝ¥G/ÿý® -ÿþ¨-ÿþ=,ÿþ,ÿû%Àÿÿþ×þcÿÿþÔ ÿþ,ÿÿþñÿø”‰êûÜ’÷ ~Àèû˜ÿÿþ| ÿþÿÿþúÿ”ÿþ§üŽûÿÿþÍÿÿþ% ÿþ-ÿÿþêÿýÄþÿÿúJ ÁÿÿüúÿÿþÍ ÿû/ÉÿÿþÅ ÿúé£ÿÿý8ÿÿþv ÿþ… ÿû‘:ÿÿúýzmÿÿþ ÿýûÿ÷ü]-ŸÿÿþŒþ£ÿÿþÇ ÿþ{ÿþœþÝÿÿþ+þØÿÿþo ÿüþ‰ÿþLþúÿÿúþÿÿýý ÿúþóÒ“.ÿþ þúÿÿûlÿÿþÀ ÿ ÿþ þßÿÿû*äÿÿþi ÿ ÿþþ¢ÿÿü‰ÿÿýü ÿ ÿþ=ÿÿüüuÿÿþºÿ ÿþ§ÿ ÿþbÿ ÿý Ãÿÿýùÿ ÿüŒüÿÿþ³ÿ ÿ ú}½çøÿÿþ\:ÿýñ :ÿþŠ;üÿé;ýñ?<þ>    ÿ9ÿ9ÿ,þ) ÿ,þý=þÿ=ùÿúè„(ÿõ1ŽÊîüøéÊ“Aô1ŒÆèøüñÙ±mÿüþ ÿýªÿÿýÅ$ý¥ÿÿýôqÿýÑÿý×ÿ ÿýí*ýÓÿ ÿþŒ ÿþ®ÿþºÿ ÿýÔþ»ÿ ÿüHÿÿüuýÿÿþ>ÿþIÿÿùÚG AÏÿÿûXPÿÿú‰;ØÿÿþÉûÿŠÿÿþ¡ÿþ§ÿÿþ1þ(ÿÿûª¬ÿÿþ›ø2ëÀ•k@ûÿ)ÿÿþÝÿþàÿÿûÛáÿÿþ4 ûÿÿÿþöÿþúÿÿûõúÿÿþ ûÿÿÿþùÿþøÿÿþüÿÿþ ûÿ*ÿÿþÜÿþßÿÿþ þéÿÿþ$ ûÿ†ÿÿþŸÿþ¦ÿÿþq þ¼ÿÿþƒø=ê¿•j?ûúqûÿÿþ=ÿþIÿÿùøp2¥ÿÿûµfÿÿùûrSåÿÿþÏþëÿÿþ¨ÿþ¼ÿ ÿùñ"Òÿ ÿþPþÆÿÿýÉ ÿýßÿ ÿýùKý$æÿ ÿþ’þ|ÿÿüü— þÿÿý¿ÿÿýãAý¾ÿÿýõuù ûé‚$þÿÿþýôC™ÍíûüñÕ¨^ô=‘Çèùþøâ¸sü ÿÿþö4þ ÿÿþä4þYÿÿþ¾4þ’ÿÿþj4þÊÿÿý¹4öƒ´ÚîüòÊs.ŒŒŒný9½û0´ÿÿýªþÿÿÿÿÿÿþÿÿþÿÿþÿÿþÿÿÿÿÿÿÿÿþÿûW&-ÿÿþÿÿý½Óÿÿõ݇ÑóýõåÆšXÄb 13 New Layerÿ     }3¡amy…3Ñáñ!1AQ À À À À À À À À À À À À À À À À À À À À À À À À À À À À À À À Àûûûû † C!-"h t t p : / / v e l o c i t y ...ÿ     ¿ Sgimp-text-layer7(text "h t t p : / / v e l o c i t y . a p a c h e . o r g /") (font "Arial Bold") (font-size 16.000000) (font-size-unit pixels) (hinting yes) (antialias yes) (language "en-us") (base-direction ltr) (color (color-rgba 0.000000 0.000000 0.000000 1.000000)) (justify center) (box-mode dynamic) (box-unit pixels) ²-Ò%Û%ç%ó-òÁ º"$DÀÀÀÁÿ ý@Àý@Àüÿêÿ ÿÿüHÿ¿ÿ ÿÿüsÿ•ÿù–ñìœ ÿÿÿúOÕùÔJÿüÿjÿþ¨ÿÿþŸÿÿÿþúÿÿýü:ÿüÈÿ?ÿù¸!tÿëÿÿÿù±´ÿ³üòÿÿù# ÿýÿÿÿù#ÿì üÿêÿþÿÿÿÿùÿû üHÿ¿ÿÿÿÿÿù) ÿè üsÿ•ÿÿûüÿûüÿÿù¼¬ÿ« üÿjÿÿûáÿÿ°ûáÿÿ°ÿþùÿÿýø0ÿüÈÿ?ÿÿûUåø¾ûUåø¾ÿú@ÒùÍ?ÿüòÿ$ÿ=ÿ=ÿ\ÀÀÀÁüÿêÿüHÿ¿ÿüsÿ•ÿüÿjüTÿ«ü«ÿTúKÕùÓNÿù*³ôò°$õHÏùò¿'Èÿ?ö òõ öó ý8ûÿÿýü=ÿý!ïÿÿýêý:üÿÿú³òÿø£ÿWXÿ¥ø¯ÿUOÿ°ÿ÷žÿ¹¹ÿõ²ÿŸPÿïÿêøKÿ­®ÿNþêÿÿþçÿ÷èÿ%%ÿæüìÿüHÿ¿øíö÷ðþüÿÿþûÿ÷ýÿÿúüüÿüsÿ•úšÿŸÿ üíÿÿ÷èÿ%&ÿãüìÿüÿjúAÿþÿIøµÿ• UÿÔÿ÷¦ÿ¸¹ÿ˜õ´ÿ“ SÿÞÈÿ?úæÿíý>üÿÿþZÿý)óÿÿýçý?ýÿÿûuòÿüÿ›úOÐùãlÿù-²ôó¯"ùPÔúäÿÀÀÀÆÿý@À4ÿÿ=ÿ5ÿÿûùí û í÷ ø„ãüð°ÿúOÕùÔJÿÿüªÿeüfÿ¡ þÿÿþ¾ÿþúÿÿþüÿÿüEÿÓüÔÿ8 øãÿ[2ÿõÿú±´ÿÿÿ÷ßÿCDÿÏ ù QÒÿÿÿú#ÿÿÿø|ÿ±²ÿf ýBîÿÿÿúÿÿÿøüýFýñ øÖÿ”Jÿÿÿú) ÿÿûüÿú³ÿñÿ“ ÷ùÿ= sÿÿÿú¼¬ÿÿûáÿÿ°þOÿÿþ+ÿþ¼ÿÿüîÿ#ÿþùÿÿþøÿûUåø¾ûæÿÂÿ÷´öî—+ÿ ÿú@ÒùÍ?ú+ìÿ_ÿÿýåÿûîûÌ5ÿDÀÀÀáÿ=ÿ=ÿ#ø„ãüð°ùHÏùò¿'ÿù–ñìœ úKÕùÓN þ:þÿÿþ¾ý:üÿÿþ³ÿþ¨ÿÿþŸý8ûÿÿýü=þ³øãÿ[2ÿõø²ÿŸPÿïÿù¸!tÿëø¯ÿUOÿ°þìù QÒÿÿüìÿÿù# ÿýþêÿÿþçþûýBîÿÿüüÿÿþÿþüÿÿþûþèøÖÿ”Jÿÿüìÿÿÿüíÿ þ«÷ùÿ= sÿÿø´ÿ“ SÿÞÿÿøµÿ• UÿÔþ0þ¼ÿÿüîÿ#ý?ýÿÿþuÿÿý>üÿÿþZÿ÷´öî—+ÿ ùPÔúäÿÿúOÐùãlÿWWW±üÿê(üHÿ¿(üsÿ•ù*³ôò°$ÿüQîÄøLÕ÷½ ÿÿüÿjý!ïÿÿýêÿüüÿ¸ý<üÿÿüÚÿÿüÈÿ?÷žÿ¹¹ÿÿü‘ "÷³ÿ³·ÿÿüòÿ÷èÿ%%ÿæÿþ&÷ìÿ"%ÿÿüÿê÷ýÿÿúÿþ ÷üÿÿÿüHÿ¿÷èÿ%&ÿãÿþ÷ìÿ"%ÿÿüsÿ•÷¦ÿ¸¹ÿ˜ÿ÷²ÿ±¼ÿÿüÿjý)óÿÿýçÿý9üÿÿüÊÿÿüÈÿ?ù-²ôó¯"ÿøQÙö¬ÿøüòÿöûÿM lÿØ#þ­ÿÿþx#÷’ßúûáˆ4– K%3Background (0ms)ÿ     &¬3&Ð\b\n\z\†3';†Rn\\&\2\>\J\VXÿþ™ÿ<ÿýËuÿ$ÿü3vìÿÿú´Ëÿªœÿ$ÿú»eìÿ ÿö׆ªÿ‰œ»ìuÿ!ÿýàˆýDàÿ ÿöª´œÿ†™vœÿÿõ̽ÿ­Ž°ÿ­­îÿÿýà™ýDËÿ ÿ㙟ÿˆuœ»ÿÿàŽÞÞ‰ôô´ôô´²ì½½ìÿÿüà»ý3»ÿÿ∟ˆu‰u»ÿÿ‘ÇÞ‰ÞÞÃÃÞôôÞ£Ãôø°­ÿÿàþeý™ÿÿíôuœ†veŸuœÿÝ®ÇljÞÞ£ÞÞýôôôùã´Ã£Ì²²þìÿÿûìàËüuìÿÿîˆS‰uvœu™ÿ­®®k®ÇkÇÇøÃ´ÞÞôôôôôÞÌøøôô²­½Ìÿÿàþ™åSàÿÿô´S†‰e‰e™ÿ‘——k®®‰®ÇljÞÞþ£ÞÞ´ôöøÌ£ÃÞøÌ°½ÿÿûôà×Dí3»ôààSe†S†ÿ‘——k—k®®ý‰®ÇÇù‰ÇÞÞ‰ÃôôýôôôûãÌÿÿàý»â™××SSSÿ‘{5{—k——‰‰®®ÇljÇljÃÞÞûô£ÃÞôôý£Þôô ÿûôààeòD»DSSÿZZO{5{{ôk——®®k®®‰‰ÇÞÞý£´ÞÞ´ô ÿûìà×Sñ3v™ÿZZOZOZ{{k——ûk——kÇÇþ‰ÇÇÞþ£ÞÞþÃÿ ÿàý×vôDàZZOZOZZOO{{úk{—k—®®ûÇk®®ÇÇü‰ÇÇÞÞþ´ÿÿàýˆ5OZö5ZZ{{O{{k——û®k——®®þ‰ÇÇý£ôÿÿúìààËD5ZþOZZúOZZk{——þk——þk®®ü‰ÞÞÿ ÿöìSu†ˆSS3û5OOZZú5OZ5Z{{þk{{—÷k——®‰£ÇÞÿ ÿüôàuSSöuS3SD3S5OZþOZZû{OZZ{{ùO{{——kÇÇÿí×uu‰‰eSSeSS™×DZ55û5OZOZZOZþO{{þk®® ÿ黜uueeu‰S†eà™—k{{Z55ù55ZZ5ZZý5OZZúk——®kÿ ÿåלu†œuu‰œv‰»ÿ‘®k——kk{Z555þOZZþOZZùOk{——Oÿ ÿëeˆËœv´´uvŸuìà´Ç‰Ç®k——ùO{ZO5ú55OOZZþO{{ýkOÿ ÿÞËËu™v´´u™´‰Ëÿ²ÞÞÞljǮ®k——{O{Z555OZý5Zÿ ÿÛàôìà†Åˆàª´™ìÿ²ôôÞÞ‰ÞÇlj®®—O{{OZZ555OþZÿ ÿôœíàôªÅªÿÿ°ôô´ôôÞÞ´£ÇÇ{öOZZOZZO55ÿáuËôÿàeìÿÿôô´ôôôôÞ£ÞÞÇk——OZZOZZúOZOO5ÿïËìÿÿôeôÿÿ²ôôÃôôôôô´ôÞÞ‰ÁÁOZZOZZþOZZû5O55ÿþàÿÿþËÿÿøì­Ìôô£ôôþ´ôôø‰ÁÁOZZOZZþOZZOZú5O55ÿÿþìÿÿôôཎôøø´ôô´ôôô‰ÁÁk—{O{{ZO{{úZOZZ5ZZþ5ÿÿõôàà²ôô°øø£ôôò£øÁ‰®®k®——k——{{ûOZZO{{þOÿÿíìבðŽôôÌÌøô£øø‰ÞljÇÇþk——÷k——{k——kÿÿìý°‘ððõŽôøøÁô‰ôô‰ÞÞþ‰®®÷‰Ç®®k——‰ÿÿîìà༑ðð²ðô‘ôôÞôô´ôôþ‰ÇÇúÞÞlj®®!ÿñì×°°¼ðð²ðð£ôô£ôôþ‰ÇÇú£ôôÞ‰ÇÇ"ÿþìààñÍ™™‘ä°øøô´ôôÃÃÞÞþ‰ôôþ‰ÇÇ&ÿìó×¼²‘²ôô°ôøø‰ÞÞþ£ôôü´ÞÞÿ&ÿìàõ׈™ðð²ððô´ôôþ°øøü‰ÞÞÿ)ÿêôìàà°±±™ää²ÞôôŽððô°Ãôÿ,ÿíìàìà×°äó²Ãôñääðôÿ.ÿïôììàͰ±‘°ôÌäóóä´ÿ1ÿþôààü½²²±±þ‘ÿ3ÿôìàìþàÿ:ÿì€ÿXÿþ™ÿ<ÿýÌ€ÿ$ÿü3wìÿÿúÃÌÿª©ÿ$ÿú»fìÿ ÿöÖ•ªÿœ©»ì€ÿ!ÿýàˆýDàÿ ÿöªÃ©ÿ•™wŽ©ÿÿõ¤ÿj..ÿjjÔÿÿýà™ýDÌÿ ÿ㙳ŽÿŽˆ€©»ÿÿà. ˆììÿÿüà»ý3»ÿÿâÌ•³ˆ€Žœ€»ÿÿ7 %.jÿÿàþfý™ÿÿðô€©•wf³€©ÿË  ýù"MˆˆþìÿÿûìàÌü€ìÿÿîˆVŽœ€w©€™ÿj  øô"%%NNMj¤ÿÿàþ™åVàÿÿôÃV•œfœf™ÿ7  ö%"%".ÿÿûôàÖDí3»ôààVŽf•V•ÿ7  ý ú  þü"ÿÿàý»â™ÖÖVVŽVŽÿ7    û ÿûôààfòD»DVVŽÿ    ô þ ÿûìàÖVñ3w™ÿ    û þ þÿ ÿàýÖwôDà     ú  û ü þÿÿàýˆ ö   û  þ ýÿÿúìààÌD þ  ú  þ  þ  ü ÿ ÿöìV€•ŽˆVV3û  ú   þ   ÷ ÿ ÿüôà€VVö€V3VD3V þ  û   ù ÿíÖ€€œœfVVfVV™ÖD û    þ  þ  ÿ黎©€€ff€œV•fà™ ù   ý  ú ÿ ÿåÖ©€•©€€œ©wœŽ»ÿ7 þ  þ  ù ÿ ÿëfˆÌŽ©wÃÀw³€ìà   ù ú  þ  ý ÿ ÿÞÌŽÌ€™wÃÀ™ÃœÌÿˆ    ý ÿ ÿÛàôìà•ÖˆàªÃ™ìÿM    þ ÿ ÿô©íàôªÖªÿÿ. ö  ÿí€Ìôÿàfìÿÿ÷    ú ÿõÌìÿÿôfôÿÿˆþô    þ  ûÿþàÿÿþÌÿÿøìj"þø    þ   úÿÿþìÿÿôôà.N%%ô     ú    þÿÿõôààMNN.%%ò%  û   þÿÿíìÖhx.NN""%%%  þ  ÷ ÿÿìý¥hxxõ.N%%N  þ  ÷  ÿÿîìàà°hxxMxN7NNþ ú  !ÿñìÖ¥¥°xxMxxþ ú "ÿþìààõÅ‚‚h·.%%þ þ &ÿìóÖ°ˆhMNN.N%% üÿ&ÿìàõÖˆ‚xxMxxNþ.%%ü ÿ)ÿêôìàय़Ÿ‚··M.xxN.ÿ,ÿöìàìàÖ¥·ÜMùŸ··xÿ.ÿïôììàÅ¥Ÿh."·ÜÜ·ÿ1ÿþôààüˆˆŸŸþhÿ3ÿôìàìþàÿ:ÿì€ÿXÿþ™ÿ<ÿýÌ…ÿ$ÿü3wëÿÿúÉÌÿª®ÿ$ÿú»gëÿ ÿöѪÿ¦®»ë…ÿ!ÿýàˆýDàÿ ÿöªÉ®ÿ™w•®ÿÿõ©šÿh*0ÿhhØÿÿýà™ýDÌÿ ÿ㙽•ÿ•ˆ…®»ÿÿà*88211*&11*yëššëÿÿüà»ý3»ÿÿâ̽ˆ…•¦…»ÿÿWF8288))8118&)180hÿÿàþgý™ÿÿíô…®wg½…®ÿËQFF288&88ý)*11ø)&*)&+9yyþëÿÿûëàÌü…ëÿÿîˆX•¦…w®…™ÿhQQ?QF?FFø)*881)*11ô8&+88>>9hš©ÿÿàþ™åXàÿÿôÉX¦g¦g™ÿW^^?QQ2QFF288þ&88*1ö8+&)88+0šÿÿûôàÑDí3»ôààX•gXÿW^^?^?QQý2QFFù2F882)11ý)*11û)&&+ÿÿàý»â™ÑÑXX•X•ÿWlAl^?^^22QQFF2FF2)88û1&)811ý&811 ÿûôààgòD»DXX•ÿ}}ZlAllô?^^QQ?QQ22F88ý&*88*1 ÿûëàÑXñ3w™ÿ}}Z}Z}ll?^^û?^^?FFþ2FF8þ&88þ)ÿ ÿàýÑwôDà}}Z}Z}}ZZllú?l^?^QQûF?QQFFü2FF88þ*ÿÿàýˆAZ}öA}}llZll?^^ûQ?^^QQþ2FFý&1ÿÿúëààÌDA}þZ}}úZ}}?l^^þ?^^þ?QQü288ÿ ÿöëX…•ˆXX3ûAZZ}}úAZ}A}llþ?ll^÷?^^Q2&F8ÿ ÿüôà…XXö…X3XD3XAZ}þZ}}ûlZ}}llùZll^^?FFÿíÑ……¦¦gXXgXX™ÑD}AAûAZ}Z}}Z}þZllþ?QQ ÿ黕®……gg…¦Xgà™^?ll}AAùAA}}A}}ýAZ}}ú?^^Q?ÿ ÿåÑ®…®……¦®w¦•»ÿWQ?^^??l}AAAþZ}}þZ}}ùZ?l^^Zÿ ÿëgˆÌ•®wÉÉ…w½…ëà*F2FQ?^^ùZl}ZAúAAZZ}}þZllý?Zÿ ÿÞ̅̕™wÉÉ…™É¦Ìÿy88&8F2FQQ?^^lZl}AAAZ}ýA}ÿ ÿÛàôëàÛˆàªÉ™ëÿ911&8828FF2QQ^ZllZ}}AAAZþ}ÿ ÿô®íàôªÛªÿÿ011*11&88*&FFlöZ}}Z}}ZAAÿá…Ìôÿàgëÿÿ&11*11&118&88F?^^Z}}Z}}úZ}ZZAÿïÌëÿÿôgôÿÿy11)11&11ô*1882uuZ}}Z}}þZ}}ûAZAAÿþàÿÿþÌÿÿøëh+&11&11þ*11ø2uuZ}}Z}}þZ}}Z}úAZAAÿÿþëÿÿôôàš*>88*11*11ô2uu?^lZll}Zllú}Z}}A}}þAÿÿõôàà9>>088&11ò&8u2QQ?Q^^?^^llûZ}}ZllþZÿÿíëÑ7F*>>++81&8828F2FFþ?^^÷?^^l?^^?ÿÿëý~7FFõ*>88u>211288þ2QQ÷2FQQ?^^2ÿÿîëààš7FF9F>W>>811*11þ2FFú&88F2QQ!ÿñëÑ~~šFF9FF&11&11þ2FFú&1182FF"ÿþëààñ¶<<7R0881*11))88þ211þ2FF&ÿëóÑšy79>>0>88288þ&11ü*88ÿ&ÿëàõш*11þ088ü288ÿ)ÿêôëàà~GG0)1ÿ,ÿíëàëàÑ~R\9)1)GRRF&1ÿ.ÿïôëëà¶~G701+R\\R*ÿ1ÿþôààüšyyGGþ7ÿ3ÿôëàëþàÿ:ÿë€ÿÀÿü°­Ýÿ;ÿùôø´­¼¼ÿ8ÿüô°ôô²þìÿ5ÿþ£øøýô´´ü²Ìÿ2ÿôüÞ£Þôôýð²²­þìÿ-ÿô÷Þ£ÞÞôôÌôôù£´Ḭ̀Ìÿ+ÿüÞô‰ÞÞù£ôøøÌ´ôôùŽ­°²Íÿ'ÿýÞ‰ÇÇþ£ôôÃôò°ôððô°²­²Ýÿ"ÿô´‰®ÇÇ£ÞôôÞ£ÞÞþ£øøüÌÃôôøúŽk‘°°½½þìÿÿùk—®®‰ÃÞÞú‰ÇÇ´´ôôý£´ôôô޲ðð°Ìôô²²þ‘¼¼ûì¼¼×ÿÿò{——k£ÇÇÞ‰®Ç´£ôôý‰ÇÞÞýÃôôý´ôôøûÌŽ°°ôô²ðþ²ÿÿ{ýk®ÇÇûk®®‰ÞÞó‰´ÇÇÞ´ÃøøÌÞôô£þÞøøþŽôôú޲²½Ýÿ ÿûZ{O—®®ík——kÇÞÞ´‰®ÇÇ£ÞôôÉÞÞüãÞôôýÞ£øøüÌ£ôô÷øŽ°²²­²ÍÿÿZþk——ú‰k{k‰ÇÇþk®®ý£Ãôôý‰ÇÞÞû£´ÞÞôôÃô쉴ÞÞôô£´øøôô𲑙²°°ÿÿýZ5{{ú—OZ{k®®ý‰{——þ‰ÞÞý‰®ÇÇý‰´ÞÞó£ÃôôÉÇÇÞÞ´ôôûøÌ޲ððŽì‰‘­Ìÿ55Z{{OOZZk——®O{{ùkÇÇÞ£—®®þkÇÇýÞ‰ÞÞüÉ®ÇÇö‰ÃÞôôÞ£Ìøôôk®Çù´k™55ïOZ5{——kOZ{{‰®ÇÇk——þk®®ÇókÇÇÞ‰k—®®Ç‰ÇÞÞîãôôøøO{——®®Ž²ðð5ûO{{OZZþ5®®úk{{—k——®î‰®Çljk{——®k®ÇÇÞ£´ôôü£OZ{{ý—Žôôþ‰ 5O—þO{{ók{{——kk—®®kO{{ö—k—®®Ç‰ÃÞôôý‰OZZ{ö£øøÌ‰®O55 5ýk5ZZý5Z{{ýOk——OZö{Ok——®®‰ÇÞÞý‰OZZ÷O£ôôÞk—®{{O5þ þ55ûOZ5O{{þ5ZZO{—ýk®ÇÇýÞ‰ZZù£ôôÞk{——þOZZO5þ þ55þOZZø5OZZ{{k®®Çý£OZZêO‰ÞÞôOZ{{—®ÇÇO{ZZOZZO{{5þþ55Oþ5——®þOZZþ‰ÞÞþ5ZZù{‰£ÞÞk——{þk——þk——O5þ5÷k5OOZZOkÇÇþkZZøkÞ£ôôÞ‰®®øk®—‰®®k——ûOZZO——O5þü55kk÷5OZZk´Þ‰ôôþ‰ÇÇû‰Çlj®®û‰®®k——úk®®‰OZZûk——kOO5þ5òkÃÞôô£ÇÞÞ£ÇljÇÇ÷‰ÇÇ®‰Ç®k®®ùk——{{k®®þOZZ÷Ok{{5ZOO55ùÞøøô£ÞÞø£ÞÞ´ÞÞ‰ÇÇþ‰ÞÞú‰ÇÇ®‰®®þ‰®®þk{{úO{——OZZýk{——û5ZOO55ýôôôþôôû£ôô£ÞÞþ‰ÞÞûÃôô£ÇÇþ‰ÇÇþ‰ÇÇúk®——k®®þOZZýO—®®ó—5ZZOk——Oôô²ððþôôø´ôô£ÞÞ£ÞÞþ£ôôþÞÞý‰ôÞÞþ‰ÇÇþ‰ÇÇþkÇÇþ5ZZýO®ÇÇú®OZZ5®®ôï´±ää²Ãôô£ôô£Þôô£ôôú£ôôôÞÞþ‰ôôýÞ‰ÞÞþ£ÞÞú‰ÞÞÃO{{þkÇÇïÞ£k{{kÇÇôô°äóó°ôôïÃôô£ÞôÞ£ôôÞøø£Þôôþ£ôôõÞ£ÞÞÃÃôôÞ‰ÞÞþk——þ£ÞÞÙ£k——‰Þì‘°Ž±äó²ÌøÌÌøø´Ãôô´ôôÞ°ôôÞôôÞ‰ôôú£ôô´Þôôú£ôô´‰®®þÃôô÷£®®‰´ìàìààðͰ°‘²ô°ŽôôÌÞÞ£ôôú°ðð°Þôôý°øøùÞ´ôôÃÃôôú£ôôÉÇÇý´Ãôôù‰ÇÇ´ÿÿììàÕì½­­²­²½­´ÃôÌ‘±ðÞôôò²ðôô´ôôÞøøô£Ìøø‰ÞÞöðøøôôÞÞÿÿüôÿìà àììÌ‘°°Ž‘±k´Ãô´²™ðð£ôôð޲ôô°°ôðÃôôÞŽ²ððýÞÿÿþôììàìþÌ­­²ô±ŽÃôôÃŽ²ðð²ððõ£Ãô²‘™™ŽÿÿôûìàììààéÌ´´²ìͰ°²°™²°Í̲½ììààÿ%ÿþôììùàììàììààüìààììàì*ÿôÿôÿÀÿü.jËÿ;ÿù%j°°ÿ8ÿü.NNüMˆìÿ5ÿþ%%ýNüM¤ÿ2ÿþ.MMjþìÿ-ÿý"NNù"".¤ÿ+ÿü ú%%"ù.j¥ˆÅÿ'ÿý þò.NxxN.MjˆËÿ"ÿö %ý"%ú.Mh¥¥þìÿÿù ú ýô.Mxx."NNMMþh°°ûì°°Öÿÿò  ý ýNNý%þ"..NMxþˆÿÿ ý û ó %%"%þ.NNú.MˆËÿ ÿû   ñ  þ ü%ü"÷%..MMjˆÅÿÿ þ   ü þ  þý üì %%NNxMh‚ˆ¥¥ÿÿý   ú   ý  þ ý ý ø û%".Mxx.ì 7j¤ÿ    ù   þ ý ü ö "%NN  ùM‚ï     þ  ó   î%% .Mxxû   þ  ú   î  ü  ý .NNþ  þ  ó   ö  ý    ö%%"  ý   ý  ý   ö  ý   ÷  þ þû   þ    ý ý  ù  þ  þ þþ  ø  ý  ê      þþþ   þ  þ þ  ý þ   þ  þ  þ÷   þ  ø   ø  û   þü  ÷  þ û   û  ú   û þø þ ÷    ù  þ  ÷  ú%%û þ ú   þ  þ  ú   ý  û ýNNþüþ þþ þ ú  þ  ý  ó   Mxxþüþý þ þ þ þ  ý ú    úŸ··M÷þþþ ý ú   þ ñ .·ÜÜ.ô%%þý þ  ê ì7..Ÿ·ÜM"%""%%ò.NN úú  ÷ ìàìààóÅ¥¥hMN..NN"ú.xx.ý.%%ýþþ þù ÿÿììàêìjjˆjˆj"hŸxMïxNN%%"%% ö.%%NNÿÿüôÿìà àüì¤7..òhŸMM‚xxö.MNN..Nxü.Mxxýÿÿþôììàìþ¤jjˆýŸ.ú.MxxMxxõMh‚‚.ÿÿôûìàììààé¤MìÅ¥¥ˆ¥‚ˆ¥Å¤ˆììààÿ%ÿþôììùàììàììààüìààììàì*ÿôÿôÿÀÿü0hËÿ;ÿù18*hššÿ8ÿü1&0>>ü9yëÿ5ÿþ&88ý>&**ü&9©ÿ2ÿ1ü8&811ý)099hþëÿ-ÿ1÷8&8811&+>>ù&*++0©ÿ+ÿü81288ù&188+*11ù&*h~y¶ÿ'ÿý82FFþ&11)1ò&0>FF>&&09hyËÿ"ÿô*2QFF&8118&88þ&88ü+&)118ú*%7~~ššþëÿÿù?^QQ2)88ú2FF**11ý&*11ô&*9FF&0&+>>99þ7ššûëššÑÿÿòl^^?&FF82QF*&11ý2F88ý)&>>ý&*118û+*00>>9Fþyÿÿlý?QFFû?QQ288ó2*FF8*)88+&811&8þ*>>&ú*9yšËÿ ÿû}lZ^QQí?^^?F88*2QFF&811)288ü)&811ý8&88ü+&&11÷8*099hy¶ÿÿ}þ?^^ú2?l?2FFþ?QQý&)11ý2F88û&*8811)1ì2*8811&*88>>F97>?QFù*%<AAïZ}Al^^?Z}ll2QFF?^^þ?QQFó?FF82?^QQF2F88î)&1188&Zl^^QQ*9FFAûZllZ}}þAQQú?ll^?^^Qî2QFF2?l^^Q?QFF8&*11ü&Z}llý^*>>þ2 AZ^þZlló?ll^^??^QQ?Zllö^?^QQF2)811ý2Z}}lö&88+2QZAA Aý?A}}ýA}llýZ?^^Z}ölZ?^^QQ2F88ý2Z}}÷Z&118?^QllZAþ þAAûZ}AZllþA}}Zl^ý?QFFý82}}ù&118?l^^þZ}}ZAþ þAAþZ}}øAZ}}ll?QQFý&Z}}êZ2881Z}ll^QFFZl}}Z}}ZllAþþAAZþA^^QþZ}}þ288þA}}ùl2&88?^^lþ?^^þ?^^ZAþA÷?AZZ}}Z?FFþ?}}ø?8&1182QQø?Q^2QQ?^^ûZ}}Z^^ZAþüAA??÷AZ}}?*8211þ2FFû2FF2QQû2QQ?^^ú?QQ2Z}}û?^^?ZZAþAò?)811&F88&FF2FF÷2FFQ2FQ?QQù?^^ll?QQþZ}}÷Z?llA}ZZAAù8&881&88ø&88*882FFþ288ú2FFQ2QQþ2QQþ?llúZl^^Z}}ý?l^^ûA}ZZAAý1&>>þ&11û&11&88þ288û)11&FFþ2FFþ2FFú?Q^^?QQþZ}}ýZ^QQó^A}}Z?^^Z119FFþ&11ø*11&88&88þ&11þ&88ý2188þ2FFþ2FFþ?FFþA}}ýZQFFúQZ}}AQQ1ï*GRR9)11&11&811&11ú&11)*88þ211ý8288þ&88ú288)Zllþ?FFï8&?ll?FF&110R\\011ï)11&818&118&88&811þ&11õ8&88))118288þ?^^þ&88Ù&?^^28ëW0&*GR\9+8++88*)11*1180>>&8118211ú&11*811ú&11*2QQþ)11÷&QQ2*ëàëààð¶~~79>0*>>+&88&11ú0FF0811ý&088ú*11))11ú&11)2FFý*)11ù2FF*ÿÿëëàÕëšhhyhyšh&*&&)1+7GF&811)99F>>*118&881&+88288ö)088>>&88ÿÿüôÿëà àìë©W00*7G%&*)1*9>00>F&)118*9FFý&8ÿÿþôëëàëþ©hhyôG*)11)*9FF9FF&)ù*97<<*ÿÿôûëàëëààé©&**9ë¶~~y~>ûF9*&88>ý9%GG'ÿü2)188ý2&11û8*7FRRø\<<~G~ëÿ!ÿþ811ý&2881ü&*>FFû>øF7<\\>ý&)11÷%RG<\\G<\\÷<7~~¶ààëÿÿü1)0>>î0&&**&*99F**)11+7GGû7<~~ààýëôÿÿú&18%9FFhþÑààëóšÑà»h99yÑššÑààþëÿÿúëšyàÑ~~ýÑàëëøàëàëëàëààëþôÿÿëüàëëààýëôÿÿôhÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿ Àÿûÿûÿûÿ † C!velocity-1.7/xdocs/images/pbv90x30.png0000644000175000017500000000442310557734552017505 0ustar moellermoeller‰PNG  IHDRZ›¿ùJPLTEppqÏÏТ¢£wxzãäæ#\ W'`%^&^%]%[#Y!R3eRTW\^a)a*`(_(]'\'[&X7h-Mx-e+b-b*_([,[+YÂËÖ¡¥ª0g0e/d.c-`-_+],]+Z*Y)X(U%N.^/_/a=m *K;j=m>m0QDr@kHt!Fp8W&Ny9Y3M,Gd&=V*@X[y™tŒ§}”­„š²7@JZhws„—Q]jENX†•¥• ¬ž©µ´¿Ë—¤ÍÓÚ2f2e/a(R0b+W2d/\(O3e6i2a$F6g*P,R 2].U 6c 9h 0V;j#>>m?nBq5Y;b"Kv-F5R(Qz8S(:2X:_…Df‰5MfNo‘Qq“)9J -:4GZE]vVrŽf‚Ÿ+3;h{Ž‘¥ºHQZAGMzƒŒ8;>VZ^puzdhlÑ×ÝëîñéìïQRSÁÃÅíïñòóôñòóìíĶÄÑÏØàiot­´ºÝãèçíñîñóæéëáæéçëíøúûõ÷øôö÷òôõúûû÷øøûüûõöõôõôýþüKKI@@?þþüüüúýýüúúùùùøööõÞÞÝÎÎÍ””“ˆ‡…ÿþüúù÷ø÷õïîìâáߤ¡œÓÑθ¶³÷õòéçäÖÔÑòïëÈÄ¿‚{tãßÛŸœ™654¾»¸½º·µ²¯ywusqoÑÎËÁ¾»ì鿍¦¤¯­«õóñæäâåãáßÝÛÛÙ×ÍËÉŸž™˜—’‘ŽŒŒ‹Œ‹Š…„ƒüûúúùøñðïíìëæåäãâጉ‡˜•“¢ŸËÈÆÉÆÄ¿¼º¶´³›™˜†„„öõõéèè×ÖÖÿÿÿïïïßßßÛÛÛ¿¿¿¯¯¯ŸŸŸ€€€~~~```PPP@@@000 yM bKGDˆH pHYs  šœtIMEÖ 7Yß'[™IDATHÇ•\SUÇ73 ‡©lX±G…l¢€X‰%b Ä?%ra‚$‚š˜æ?ư¢¨™b ÿ43M °z¡`ejþ7ÿ¤‰ù§B(å ÇÛØÞ¶Û}† OÁîç³½{î¹÷{ÎýÝóîã½énfèA3"£}¾•ÿài¼Îh!êQд Ñ=DŒ| ²ñt¸oF=²èÌx+|#2¡ÊЬF l6‹mÄ=âBºdm°¡2š6ÍFd ‘Á€h#‡ãè-ˆB¶Ë]Al-ÍÈÂçÖ‘×Uk  q¦™ñ¯±ÍˆS3²=û;Ñãx§4ž‰°Â`B&Œ¥ Å†mŠÍ“f=&üwWd<ÍÜÍ1êôúö'SPÍúfàëuì°ŽµÛŒ‡Ï×±vèÙZŠ.ù¿íÒWÈÚe€M¶¸'6IN&Ù¶ìëÖÖ=Ý¡¡|}A•[Ô‰­) /¨ädï*•ayoèûÑóLrÔiâiE“Ö>ÔÉAǸò†‚A ƒË@³~SÙ :ÌÁ9³@=O8ëb…=oÈM/9̸ú¸9O&m¹GËb¥£)-ÆJþ­!Û•„Ü‘mhÖ&;‰ ·&ŽÏ¨»…3òùh»“‡ýi²tª±Â\<•çñÀV™{1~0èC€×l+tßÎ0vº«`×ÎÔ…š¡ïµ½?+RåI~¹]­á(>(S½"k@áÓÿ6l I–HäUíhØöŠDâ¦Ã󶆌’HL ñ_°¬¦Àdl\’ÿ2ÅËãòÊ zŠûÑ$„‹ˆÌêOFz¤´j5iN¾)S… ƒAÕ†Îv"FÄ8‹VœµÜÉsDŒ 0h¸1úûœç½ãâ|ú)Ó>yrO½¾—«øÜ㥋N‘¦ž„BÂ+ãÇÕ3„Y'Ô,zS¼$ñçÍcˆwzáåo¥ì~,²¯Ö9~—6žL—¾°ÜôíñÄkõ"1@Ç…þBî<ûŸPápºBD1+e²¹Äøõ\.˜’qp¶Ë°Èë 7ïëËmªÚ@ø].%­÷Vm;¿Û«h‘ò§–óm uñÚ,wM\û6Í-núôé“=f_ØþžxId»xEœ‡¬X^€4Æt•Y±sá÷{)„ ¼7ã×!LämŒNòÌ8Ây‡àòóLO’¤þUZ&÷|{ÚÌ™³f.üm›½ª£‡(çI§ñŠ™Mæ3è+,‡Šž!š%õ]ÕÄVùó†FÜ„…ó´Ý— †‹ßԮǂ‡PÁÐÌj, ¡lXLLåá,É6tGÖåraP–kÊÑ«ÜhÂ-!ÎgÍuÀ¨aÖå³Å· „Dð°Tèqn©È+ò¨K:£{«p õÿ¾$õ –ÅÄMN¬û`Ý(ç$Eˆ<)ªòóqÂØ-×Ò²>ˆ÷H9Z){‰˜³,{ܤ*ìñ»|r\bÇ(Îâ¢z1vhD=œ÷5ÈDbqê)ÆõœÐ±¯¨_æYXê$é“þSôXÇ>ŽCi=”N$v|Â!³vG€K"F»ÇŠ¥gQdñb·ÉÃ܆n´jEfðš&挼™¼D¹ªî6ð³Æ®¬…¼¬àEÊ+H¨Yþj ’wG;)rå)-”E- Œ8—îšøoùÐ$œ®=¶§Œ¹„€ Developer's Guide Velocity Documentation Team

  1. Introduction and Getting Started
  2. Resources
  3. How Velocity Works
  4. To Singleton Or Not To Singleton...
  5. The Context
  6. Using Velocity in General Applications
  7. Application Attributes
  8. Configuring Event Handlers
  9. Velocity Configuration Keys and Values
  10. Configuring Logging
  11. Configuring the Resource Loaders (template loaders)
  12. Template Encoding for Internationalization
  13. Velocity and XML
  14. Summary

Velocity is a Java-based template engine, a simple and powerful development tool that allows you to easily create and render documents that format and present your data. In this guide, we hope to give an overview of the basics of development using Velocity.

Building Web Applications with Velocity

Velocity is often used for building web applications In order to use Velocity in a web app you'll need a servlet or servlet-based framework. The easiest way to get started is with VelocityViewServlet in the Velocity Tools subproject. You can also use any of a number of third party frameworks or build your own servlet using the techniques described in this document.

We suggest you read this article on getting started with web applications for more detail on the various options.

Downloading Velocity

You can download the latest release version of Velocity or Velocity Tools from the main Apache Velocity download site. For Velocity itself, source is included with the binary download.

If you want to download the latest source, you can do so via the Subversion (svn) source control system, or download a complete nightly snapshot.

Instructions for building Velocity from source can be found in the Build document.

Dependencies

Velocity uses elements of the Java 2 API such as collections, and therefore building requires the Java 2 Standard Edition SDK (Software Development Kit). To run Velocity, the Java 2 Standard Edition RTE (Run Time Environment) is required (or you can use the SDK, of course).

Velocity also is dependent upon a few packages for general functionality. They are included in the build/lib directory for convenience, but the default build target (see above) does not include them. If you use the default build target, you must add the dependencies to your classpath.

There are quite a few resources and examples available to the programmer, and we recommend that you look at our examples, documentation and even the source code. Some great sources are:

  • The user and developer community: join us via the mail-lists. Mail list archives are available from that page, too.
  • Wiki: http://wiki.apache.org/velocity/ The Velocity wiki contains articles, sample code, and other community-written content.
  • Frequently Asked Questions (FAQ): http://wiki.apache.org/velocity/VelocityFAQ please visit this page to read the latest FAQ and to contribute your own answers.
  • source code: src/java/...: all the source code to the Velocity project
  • application example 1: examples/app_example1: a simple example showing how to use Velocity in an application program.
  • application example 2: examples/app_example2: a simple example showing how to use Velocity in an application program using the Velocity application utility class.
  • logger example: examples/logger_example: a simple example showing how to create a custom logging class and register it with Velocity to receive all log messages.
  • XML example: examples/xmlapp_example: a simple example showing how to use JDOM to read and access XML document data from within a Velocity template. It also includes a demonstration of a recursive Velocimacro that walks the document tree.
  • event example: examples/event_example: An example that demonstrates the use of the event handling API.
  • Anakia application: examples/anakia: example application showing how to use Velocity for creating stylesheet renderings of xml data
  • documentation: docs: all the generated documentation for the Velocity project in html
  • API documentation: docs/api: the generated Javadoc documentation for the Velocity project
  • templates: test/templates: a large collection of template examples in our testbed directory, these are a great source of useage examples of VTL, the Velocity Template Language
  • context example: examples/context_example: two examples showing how the Velocity context can be extended. For advanced users.

All directory references above are relative to the distribution root directory.

'The Fundamental Pattern'

When using Velocity in an application program or in a servlet (or anywhere, actually), you will generally do the following:

  1. Initialize Velocity. This applies to both usage patterns for Velocity, the Singleton as well as the 'separate runtime instance' (see more on this below), and you only do this once.
  2. Create a Context object (more on what that is later).
  3. Add your data objects to the Context.
  4. Choose a template.
  5. 'Merge' the template and your data to produce the ouput.

In code, using the singleton pattern via the org.apache.velocity.app.Velocity class, this looks like

That's the basic pattern. It is very simple, isn't it? This is generally what happens when you use Velocity to render a template. You probably won't be writing code exactly like this - we provide a few tools to help make it even easier. However, no matter how to use Velocity the above sequence is what is happening either explicitly, or behind the scenes.

As of Velocity 1.2 and later, developers now have two options for using the Velocity engine, the singleton model and the separate instance model. The same core Velocity code is used for both approaches, which are provided to make Velocity easier to integrate into your Java application.

Singleton Model

This is the legacy pattern, where there is only one instance of the Velocity engine in the JVM (or web application, depending) that is shared by all. This is very convenient as it allows localized configuration and sharing of resources. For example, this is a very appropriate model for use in a Servlet 2.2+ compliant web application as each web application can have its own instance of Velocity, allowing that web application's servlet to share resources like templates, a logger, etc. The singleton is accessable via the org.apache.velocity.app.Velocity class, and and example of use:

Separate Instance

New in version 1.2, the separate instance allows you to create, configure and use as many instances of Velocity as you wish in the same JVM (or web application.) This is useful when you wish to support separate configurations, such as template directories, loggers, etc in the same application. To use separate instances, use the org.apache.velocity.app.VelocityEngine class. An example, which parallels the above singleton example, looks like:

As you can see, this is very simple and straightforward. Except for some simple syntax changes, using Velocity as a singleton or as separate instances requires no changes to the high-level structure of your application or templates.

As a programmer, the classes you should use to interact with the Velocity internals are the org.apache.velocity.app.Velocity class if using the singleton model, or org.apache.velocity.app.VelocityEngine if using the non-singleton model ('separate instance').

At no time should an application use the internal Runtime, RuntimeConstants, RuntimeSingleton or RuntimeInstance classes in the org.apache.velocity.runtime package, as these are intended for internal use only and may change over time. As mentioned above, the classes you should use are located in the org.apache.velocity.app package, and are the Velocity and VelocityEngine classes. If anything is missing or needed from those classes, do not hesitate to suggest changes - these classes are intended for the application developer.

The Basics

The concept of the 'context' is central to Velocity, and is a common technique for moving a container of data around between parts of a system. The idea is that the context is a 'carrier' of data between the Java layer (or you the programmer) and the template layer ( or the designer ). You as the programmer will gather objects of various types, whatever your application calls for, and place them in the context. To the designer, these objects, and their methods and properties, will become accessable via template elements called references. Generally, you will work with the designer to determine the data needs for the application. In a sense, this will become an 'API' as you produce a data set for the designer to access in the template. Therefore, in this phase of the development process it is worth devoting some time and careful analysis.

While Velocity allows you to create your own context classes to support special needs and techniques (like a context that accesses an LDAP server directly, for example), a good basic implementation class called VelocityContext is provided for you as part of the distribution.

VelocityContext is suitable for all general purpose needs, and we strongly recommended that you use it. Only in exceptional and advanced cases will you need to extend or create your own context implementation.

Using VelocityContext is as simple as using a normal Java Hashtable class. While the interface contains other useful methods, the two main methods you will use are

Please note that like a Hashtable, the value must be derived from java.lang.Object, and must not be null. Fundamental types like int or float must be wrapped in the appropriate wrapper classes.

That's really all there is to basic context operations. For more information, see the API documentation included in the distribution.

Support for Iterative Objects for #foreach()

As a programmer, you have great freedom in the objects that you put into the context. But as with most freedoms, this one comes with a little bit of responsibility, so understand what Velocity supports, and any issues that may arise. Velocity supports serveral types of collection types suitable for use in the VTL #foreach() directive.

  • Object [] Regular object array, not much needs to be said here. Velocity will internally wrap your array in a class that provides an Iterator interface, but that shouldn't concern you as the programmer, or the template author. Of more interest, is the fact that Velocity will now allow template authors to treat arrays as fixed-length lists (as of Velocity 1.6). This means they may call methods like size(), isEmpty() and get(int) on both arrays and standard java.util.List instances without concerning themselves about the difference.
  • java.util.Collection Velocity will use the iterator() method to get an Iterator to use in the loop, so if you are implementing a Collection interface on your object, please ensure that iterator() returns a working Iterator.
  • java.util.Map Here, Velocity depends upon the values() method of the interface to get a Collection interface, on which iterator() is called to retrieve an Iterator for the loop.
  • java.util.Iterator USE WITH CAUTION: This is currently supported only provisionally - the issue of concern is the 'non-resettablity' of the Iterator. If a 'naked' Iterator is placed into the context, and used in more than one #foreach(), subsequent #foreach() blocks after the first will fail, as the Iterator doesn't reset.
  • java.util.Enumeration USE WITH CAUTION: Like java.util.Iterator, this is currently supported only provisionally - the issue of concern is the 'non-resettablity' of the Enumeration. If a 'naked' Enumeration is placed into the context, and used in more than one #foreach(), subsequent #foreach() blocks after the first will fail, as the Enumeration doesn't reset.
  • Any public class with a public Iterator iterator() method that never returns null. As a last resort, Velocity will look for an iterator() method. This provides great flexibility and automatic support for Java 1.5's java.util.Iterable interface.

In the case of the Iterator and Enumeration, it is recommended that they are placed in the context only when it cannot be avoided, and you should let Velocity find the appropriate reusable iterative interface when that is sufficient and possible.

There are good reasons to use the java.util.Iterator interface directly (large data sets via JDBC, for example), but if it can be avoided, it might be better to use something else. By 'directly' , we meant doing something like:

where the Iterator itself is placed into the context. Instead, if you simply did:

then all would be fine: Velocity would figure out that Vector implement Collection (via List), and therefore will find the iterator() method, and use that to get a 'fresh' Iterator for its use each time it needs to. With just a plain Iterator (the first snippet above...), once velocity has used it in a #foreach(), Velocity has no way of getting a new one to use for the next #foreach() it is used in. The result is no output from any subsequent #foreach() blocks using that reference.

This above isn't meant to give the impression that iterating over collections in Velocity is something that requires great care and thought. Rather, the opposite is true, in general. Just be careful when you place an Iterator into the context.

Support for "Static Classes"

Not all classes are instantiable. Classes like java.lang.Math do not provide any public constructor, and yet may contain useful static methods. In order to access these static methods from a template, you can simply add the class itself to the context:

This will allow you to call any public static method in java.lang.Math on the $Math reference in the template.

Context Chaining

An innovative feature of Velocity's context design is the concept of context chaining. Also sometimes referred to as context wrapping, this advanced feature allows you to connect separate contexts together in a manner that makes it appear as one 'contiguous' context to the template.

This is best illustrated by an example:

In the code above, we have set up context2 such that it chains context1. This means that in the template, you can access any of the items that were put into either of the two VelocityContext objects, as long as there is no duplication of the keys used to add objects. If that is the case, as it is above for the key 'duplicate', the object stored in the nearest context in the chain will be available. In this example above, the object returned would be the string "I am in context2".

Note that this duplication, or 'covering', of a context item does not in any way harm or alter the covered object. So in the example above, the string "I am in context1" is alive and well, still accessable via context1.get("duplicate"). But in the example above, the value of the reference '$duplicate' in the template would be 'I am in context2', and the template has no access to the covered string 'I am in context1'.

Note also that you have to be careful when you are relying on the template to add information to a context that you will examine later after the rendering. The changes to the context via #set() statements in a template will affect only the outer context. So make sure that you don't discard the outer context, expecting the data from the template to have been placed onto the inner one.

This feature has many uses, the most common so far is providing layered data access and toolsets.

As mentioned before, the Velocity context mechanism is also extendable, but beyond the current scope of this guide. If you are interested, please see the classes in the package org.apache.velocity.context to see how the provided contexts are put together. Futher, there are a few examples in the examples/context_example directory in the distribution which show alternate implementations, including [a goofy] one that uses a database as the backing storage.

Please note that these examples are unsupported and are there for demonstration/educational purposes only.

Objects Created in the Template

There are two common situations where the Java code must deal with objects created at runtime in the template:

When a template author calls a method of an object placed into the context by Java code.

When a template adds objects to the context, the Java code can access those objects after the merge process is complete.

Dealing with these cases if very straighforward, as there are just a few things to know:

  • The VTL RangeOperator [ 1..10 ] and ObjectArray ["a","b"] are java.util.ArrayList objects when placed in the context or passed to methods. Therefore, your methods that are designed to accept arrays created in the template should be written with this in mind.
  • VTL Map references are unsurprisingly stored as java.util.Map.
  • Decimal numbers will be Doubles or BigDecimals in the context, integer numbers will be Integer, Long, or BigIntegers, and strings will be, of course, Strings.
  • Velocity will properly 'narrow' args to method calls, so calling setFoo( int i ) with an int placed into the context via #set() will work fine.
Other Context Issues

One of the features provided by the VelocityContext (or any Context derived from AbstractContext) is node specific introspection caching. Generally, you as a the developer don't need to worry about this when using the VelocityContext as your context. However, there is currently one known usage pattern where you must be aware of this feature.

The VelocityContext will accumulate intropection information about the syntax nodes in a template as it visits those nodes. So, in the following situation:

  • You are iterating over the same template using the same VelocityContext object.
  • Template caching is off.
  • You request the Template from getTemplate() on each iteration.

It is possible that your VelocityContext will appear to 'leak' memory (it is really just gathering more introspection information.) What happens is that it accumulates template node introspection information for each template it visits, and as template caching is off, it appears to the VelocityContext that it is visiting a new template each time. Hence it gathers more introspection information and grows. It is highly recommended that you do one or more of the following:

  • Create a new VelocityContext for each excursion down through the template render process. This will prevent the accumulation of introspection cache data. For the case where you want to reuse the VelocityContext because it's populated with data or objects, you can simply wrap the populated VelocityContext in another, and the 'outer' one will accumulate the introspection information, which you will just discard. Ex. VelocityContext useThis = new VelocityContext( populatedVC ); This works because the outer context will store the introspection cache data, and get any requested data from the inner context (as it is empty.) Be careful though - if your template places data into the context and it's expected that it will be used in the subsequent iterations, you will need to do one of the other fixes, as any template #set() statements will be stored in the outermost context. See the discussion in Context chaining for more information.
  • Turn on template caching. This will prevent the template from being re-parsed on each iteration, resulting the the VelocityContext being able to not only avoid adding to the introspection cache information, but be able to use it resulting in a performance improvement.
  • Reuse the Template object for the duration of the loop iterations. Then you won't be forcing Velocity, if the cache is turned off, to reread and reparse the same template over and over, so the VelocityContext won't gather new introspection information each time.

If you are using VelocityViewServlet or other web frameworks, you may never call Velocity directly. However, if you use Velocity for non-web purposes, or create your own web framework you will need to directly call the Velocity Engine similar to the fundamental pattern shown earlier. One important additional thing to remember is to initialize the Velocity Engine before using it to merge templates.

The Velocity Helper Class

Velocity contains an application utility class called Velocity ( org.apache.velocity.app.Velocity ). The purpose of this class is to provide the necessary methods required to initialize Velocity, as well as useful utility routines to make life easier in using Velocity. This class is documented in the project's javadoc, so please look there for definitive details. This documentation is intended to be of a tutorial nature; therefore for compete API information, the Javadoc is the definitive source.

The Velocity runtime engine is a singleton instance that provides resource, logging and other services to all Velocity users running in the same JVM. Therefore, the runtime engine is initialized only once. You can attempt to initialize Velocity more than once, but only the first initialization will apply. The rest of the attempts will be ignored. The Velocity utility class currently provides five methods used in configuration of the runtime engine.

The five configuration methods are:

  • setProperty( String key, Object o )
    Sets the property key with the value o. The value is typically a String, but in special cases can also be a comma-separated list of values (in a single String, ex."foo, bar, woogie") as well as other things that will arise.
  • Object getProperty( String key )
    Returns the value of the property key. Note that you must be aware of the type of the return value, as they can be things other than Strings.
  • init()
    Initializes the runtime with the default properties provided in the distribution.(These are listed below in the section pertaining to properties.)
  • init( Properties p )
    Initialize the runtime with the properties contained in the java.util.Properties object passed as an argument.
  • init( String filename )
    initilizes the runtime using the properties found in the properties file filename

Note that in each case, the default properties will be used as a base configuration, and any additional properties specified by the application will replace individual defaults. Any default properties not overwritten will remain in effect. This has the benefit that only the properties you are interested in changing need to be specified, rather than a complete set.

Another thing to note is that the init() calls may be called more than once without harm in an application. However, the first call to any of the init() functions will configure the engine with the configuration properties set at that point, and any further configuration changes or init() calls will be ignored.

The most common approaches to initializing Velocity will be something like:

  1. Setup the configuration values you wish to set in a file in the same format as org/apache/velocity/runtime/defaults/velocity.properties (the default set), or in a java.util.Properties, and then call either init( filename ) or init( Properties )
  2. Set the configuration values individually using setProperty() and then call init(). This method is generally used by more advanced applications that already have their own configuration management system - this allows the application so configure Velocity based upon values it generates at runtime, for example.

Once the runtime is initialized, you can do with it what you wish.. This mostly revolves around rendering templates into an output stream, and the Velocity utility class allows you to do this easily. Currently, here are the methods and a brief description of what they do:

  • evaluate( Context context, Writer out, String logTag, String instring )
    evaluate( Context context, Writer writer, String logTag, InputStream instream )
    These methods will render the input, in either the form of String or InputStream to an output Writer, using a Context that you provide. This is a very convenienient method to use for token replacement of strings, or if you keep 'templates' of VTL-containing content in a place like a database or other non-file storage, or simply generate such dynamically.
  • invokeVelocimacro( String vmName, String namespace, String params[], Context context, Writer writer )
    Allows direct access to Velocimacros. This can also be accomplished via the evaluate() method above if you wish. Here you simply name the vm you wish to be called, create an array of args to the VM, a Context of data, and Writer for the output. Note that the VM args must be the 'keys' of the data objects in the Context, rather than literal data to be used as the arg. This will probably change.
  • mergeTemplate( String templateName, Context context, Writer writer )
    Convenient access to the normal template handling and rendering services of Velocity. This method will take care of getting and rendering the template. It will take advantage of loading the template according to the properties setting for the file resource loader, and therefore provides the advantage of file and parsed template caching that Velocity offers. This is the most efficient way to access templates, and is recommended unless you have special needs.
  • boolean templateExists( String name )
    Determines if a template name is able to be found by the currently configured resource loaders.

Once we know about these basic helpers, it is easy to write Java program that uses Velocity. Here it is:

When we run this program, and have the template testtemplate.vm in the same directory as our program (because we used the default configuration properties, and the defaul place to load templates from is the current directory...), our output should be:

where the template we used, testtemplate.vm, is

That's all there is to it! Note that we didn't have to use both mergeTemplate() and evaluate() in our program. They are both included there for demonstration purposes. You will probably use only one of the methods, but depending on you application requirements, you are free to do what you wish.

This appears to be a little different from the 'fundamental pattern' that was mentioned at the beginning of this guide, but it really is the same thing. First, you are making a context and filling it with the data needed. Where this examples differs is that in the part of the above example where mergeTemplate() is used, mergeTemplate() is doing the work of getting the template and merging it for you, using the lower-level calls in the Runtime class. In the second example, you are making your template dynamically via the String, so that is analgous to the 'choose template' part of the process, and the evaluate() method does the merging for you using lower level calls.

So the example above sticks to the same simply pattern of using the Velocity template engine, but the utility functions do some of the repeated drudge work, or allow you other options for your template content other than template files.

Exceptions

Velocity may throw one of several exceptions during the parse / merge cycle. These exceptions extend RuntimeException and do not need to explicitly caught, although each includes specific properties that may help in presenting useful error messages to the end user. The exceptions are found in the package org.apache.velocity.exception and are:

  1. ResourceNotFoundException
    Thrown when the resource managment system cannot find a resource (template) that was requested.
  2. ParseErrorException
    Thrown when a VTL syntax error is found when parsing a resource (template).
  3. TemplateInitException
    Thrown during the first pass of template parsing; reports problems with macro and directive initialization.
  4. MethodInvocationException
    Thrown when a method of object in the context thrown an exception during render time. This exception wraps the thrown exception and propogates it to the application. This allows you to handle problems in your own objects at runtime.

In each case, a message is put into the runtime log. For more information, see the Javadoc API documentation.

Miscellaneous Details

While the above example used the default properties, setting your own properties is very simple. All you have to do is make a properties file somewhere and pass the name of that file to the init(String) method of the Velocity utility class, or make a java.util.Properties object, add the desired properties and values, and pass that to the init(Properties) method. The latter method is convenient, because you can either fill it directly from a separate properties file via the load() method, or even better, you can fill it dynamically from your own application / framework's property set at runtime. This gives you the freedom to combine all of the properties for your app into one properties file.

If we wanted to use a different directory than the current directory to load our template from, we could do something like this:

And, assuming you have a directory /opt/templates and the template testtemplate.vm is in there, then things would work just fine. If you try this and have a problem, be sure to look at the velocity.log for information - the error messages are pretty good for figuring out what is wrong.

If you need to place objects into the Velocity properties then you cannot use the Velocity.init(Properties p) method. Instead you should create a new instance of the org.apache.commons.collections.ExtendedProperties class, copy all properties from an existing Properties object into the ExtendedProperties and then add new properties with your objects to the ExtendedProperties object.

You may want to also consider using the Application Attributes feature described in the following section.

Application Attributes are name-value pairs that can be associated with a RuntimeInstance (either via the VelocityEngine or the Velocity singleton) and accessed from any part of the Velocity engine that has access to the RuntimeInstance.

This feature was designed for applications that need to communicate between the application layer and custom parts of the Velocity engine, such as loggers, resource loaders, resource managers, etc.

The Application Attribute API is very simple. From the application layer, there is a method of the VelocityEngine and the Velocity classes:

through which an application can store on Object under an application (or internal component) specified key. There are no restrictions on the key or the value. The value for a key may be set at any time - it is not required that this be set before init() is called.

Internal components can access the key-value pairs if they have access to the object via the RuntimeServices interface, using the method

Note that internal components cannot set the value of the key, just get it. if the internal component must communicate information to the application layer, it must do so via the Object passed as the value.

Velocity contains a fine-grained event handling system that allows you to customize the operation of the engine. For example, you may change the text of references that are inserted into a page, modify which templates are actually included with #include or #parse, or capture all invalid references.

All event handler interfaces available in Velocity are in the package org.apache.velocity.app.event. You may create your own implementation or use one of the sample implementations in the package org.apache.velocity.app.event.implement. (See the javadocs for more details on the provided implementations).

org.apache.velocity.app.event.IncludeEventHandler

The IncludeEventHandler can be used to modify the template that is included in a page with #include or #parse. For example, this may be used to make all includes relative to the current directory or to prevent access to unauthorized resources. Multiple IncludeEventHandler's may be chained, with the return value of the final call used as the name of the template to retrieve.
public IncludeEventHandler extends EventHandler
{
    public String includeEvent( String includeResourcePath, 
                                String currentResourcePath, 
                                String directiveName );
}

Available implementations include:
  • org.apache.velocity.app.event.implement.IncludeNotFound
  • org.apache.velocity.app.event.implement.IncludeRelativePath
  • org.apache.velocity.app.event.InvalidReferenceEventHandler
    Normally, when a template contains a bad reference an error message is logged and (unless it is part of a #set or #if), the reference is included verbatim in a page. With the InvalidReferenceEventHandler this behavior can be changed. Substitute values can be inserted, invalid references may be logged, or an exception can be thrown. Multiple InvalidReferenceEventHandler's may be chained. The exact manner in which chained method calls behave will differ per method. (See the javadoc for the details).
    public InvalidReferenceEventHandler extends EventHandler
    {
        public Object invalidGetMethod( Context context, 
                                        String reference, 
                                        Object object, 
                                        String property, 
                                        Info info);
    
        public boolean invalidSetMethod( Context context, 
                                         String leftreference, 
                                         String rightreference, 
                                         Info info);
    
        public Object invalidMethod( Context context, 
                                     String reference,  
                                     Object object, 
                                     String method, 
                                     Info info);
    }
    

    Available implementations include:
  • org.apache.velocity.app.event.implement.ReportInvalidReferences
  • org.apache.velocity.app.event.MethodExceptionEventHandler
    When a user-supplied method throws an exception, the MethodExceptionEventHandler is invoked with the Class, method name and thrown Exception. The handler can either return a valid Object to be used as the return value of the method call or throw the passed-in or new Exception, which will be wrapped and propogated to the user as a MethodInvocationException. While MethodExceptionEventHandler's can be chained only the first handler is actually called -- all others are ignored.
    public interface MethodExceptionEventHandler extends EventHandler
    {
        public Object methodException( Class claz, 
                                       String method, 
                                       Exception e )
             throws Exception;
    }
    

    Available implementations include:
  • org.apache.velocity.app.event.implement.PrintExceptions
  • org.apache.velocity.app.event.NullSetEventHandler
    When a #set() rejects an assignment due to the right hand side being an invalid or null reference, this is normally logged. The NullSetEventHandler allows you to 'veto' the logging of this condition. Multiple NullSetEventHandler's can be chained; each event handler is called in sequence until a false is returned.
    public interface NullSetEventHandler extends EventHandler
    {
        public boolean shouldLogOnNullSet( String lhs, 
                                           String rhs );
    }
    

    Available implementations include:
  • none provided
  • org.apache.velocity.app.event.ReferenceInsertionEventHandler
    A ReferenceInsertionEventHandler allows the developer to intercept each write of a reference ($foo) value to the output stream and modify that output. Multiple ReferenceInsertionEventHandler's may be chained with each step potentially altering the inserted reference.
    public interface  ReferenceInsertionEventHandler extends EventHandler
    {
        public Object referenceInsert( String reference, 
                                       Object value  );
    }
    

    Available implementations include:
  • org.apache.velocity.app.event.implement.EscapeHtmlReference
  • org.apache.velocity.app.event.implement.EscapeJavascriptReference
  • org.apache.velocity.app.event.implement.EscapeSqlReference
  • org.apache.velocity.app.event.implement.EscapeXmlReference
  • Registering Event Handlers

    You may register event handlers in either of two manners. The easiest way to register event handlers is to specify them in velocity.properties. (Event handlers configured in this manner are referred to as "global" event handlers). For example, the following property will escape HTML entities in any inserted reference.

    eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
    

    Most event handler interfaces will also permit event handlers to be chained together. Such a chain may be in a comma separated list or as additional lines with a property/value pair. For example, the following event handler properties install two ReferenceInsertionEventHandler's. The first will apply to references starting with "msg" (for example $msgText) and will escape HTML entities (e.g. turning & into &amp;). The second will escape all references starting with "sql" (for example $sqlText) according to SQL escaping rules. (note that in these examples, the first two properties given relate to the event handler configuration while the second two properties are used by the specific event handler implementation).

    eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
    eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeSqlReference
    eventhandler.escape.html.match = /msg.*/
    eventhandler.escape.sql.match = /sql.*/
    

    Event handlers may also be attached to a context via an EventCartridge. This allows event handlers to be tied more closely to a specific template merge or group of merges. The event handler will automatically be injected with the current context if it implements the ContextAware interface. (Due to thread-safety reasons this is not possible with global event handlers).

    The following code shows how to register an event handler with an EventCartridge and a context.

    Velocity's runtime configuration is controlled by a set of configuration keys listed below. Generally, these keys will have values that consist of either a String, or a comma-separated list of Strings, referred to as a CSV for comma-separated values.

    There is a set of default values contained in Velocity's jar, found in /src/java/org/apache/velocity/runtime/defaults/velocity.defaults, that Velocity uses as its configuration baseline. This ensures that Velocity will always have a 'correct' value for its configuration keys at startup, although it may not be what you want.

    Any values specified before init() time will replace the default values. Therefore, you only have toconfigure velocity with the values for the keys that you need to change, and not worry about the rest. Further, as we add more features and configuration capability, you don't have to change your configuration files to suit - the Velocity engine will always have default values.

    Please sees the section above Using Velocity for discussion on the configuration API.

    Below are listed the configuration keys that control Velocity's behavior. Organized by category, each key is listed with its current default value to the right of the '=' sign.

    Runtime Log

    runtime.log = velocity.log
    Full path and name of log file for error, warning, and informational messages. The location, if not absolute, is relative to the 'current directory'.

    runtime.log.logsystem
    This property has no default value. It is used to give Velocity an instantiated instance of a logging class that supports the interface org.apache.velocity.runtime.log.LogChute, which allows the combination of Velocity log messages with your other application log messages. Please see the section Configuring Logging for more information.

    runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogChute
    Class to be used for the Velocity-instantiated log system.

    runtime.log.invalid.references = true
    Property to turn off the log output when a reference isn't valid. Good thing to turn off in production, but very valuable for debugging.

    runtime.log.logsystem.avalon.logger = name
    Allows user to specify an existing logger name in the Avalon hierarchy without having to wrap with a LogChute interface. Note: You must also specify runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogChute as the default logsystem may change. There is no guarantee that the Avalon log system will remain the default log system.

    Character Encoding

    input.encoding = ISO-8859-1
    Character encoding for input (templates). Using this, you can use alternative encoding for your templates, such as UTF-8.

    output.encoding = ISO-8859-1
    Character encoding for output streams from the VelocityServlet and Anakia.

    #define() Directive

    define.provide.scope.control = false
    Used to turn on the automatic provision of the $define scope control during #define() calls. The default is false. Set it to true if you want a local, managed namespace you can put references in when within a #define block or if you want it for more advanced #break usage.

    #evaluate() Directive

    evaluate.provide.scope.control = false
    Used to turn on the automatic provision of the $evaluate scope during #evaluate() or Velocity[Engine].evaluate(...) calls. The default is false. Set it to true if you want a local, managed namespace you can put references in during an evaluation or if you want it for more advanced #break usage.

    #foreach() Directive

    foreach.provide.scope.control = true
    Used to control the automatic provision of the $foreach scope during #foreach calls. This gives access to the foreach status information (e.g. $foreach.index or $foreach.hasNext). The default is true. Set it to false if unused and you want a tiny performance boost.

    directive.foreach.maxloops = -1
    Maximum allowed number of loops for a #foreach() statement.

    directive.foreach.skip.invalid = true
    Tells #foreach to simply skip rendering when the object it is iterating over is not or cannot produce a valid Iterator.

    #if() Directive

    directive.if.tostring.nullcheck = true
    Default behavior is to check return value of toString() and treat an object with toString() that returns null as null. If all objects have toString() methods that never return null, this check is unnecessary and can be disabled to gain performance. In Velocity 1.5, no such null check was performed.

    #set() Directive

    directive.set.null.allowed = false
    If true, having a right hand side of a #set() statement with an invalid reference or null value will set the left hand side to null. If false, the left hand side will stay the same.

    #include() and #parse() Directive

    directive.include.output.errormsg.start =
    directive.include.output.errormsg.end = ]]>
    Defines the beginning and ending tags for an in-stream error message in the case of a problem with the #include() directive. If both the .start and .end tags are defined, an error message will be output to the stream, of the form '.start msg .end' where .start and .end refer to the property values. Output to the render stream will only occur if both the .start and .end (next) tag are defined.

    directive.parse.max.depth = 10
    Defines the allowable parse depth for a template. A template may #parse() another template which itself may have a #parse() directive. This value prevents runaway #parse() recursion.

    template.provide.scope.control = false
    Used to turn on the automatic provision of the $template scope control during #parse calls and template.merge(...) calls. The default is false. Set it to true if you want a secure namespace for your template variables or more advanced #break control.

    Resource Management

    resource.manager.logwhenfound = true
    Switch to control logging of 'found' messages from resource manager. When a resource is found for the first time, the resource name and classname of the loader that found it will be noted in the runtime log.

    resource.manager.cache.class
    Declares the class to be used for resource caching. The current default is org.apache.velocity.runtime.resource.ResourceCacheImpl. When resource.manager.defaultcache.size is set to 0, then the default implementation is the standard java ConcurrentHashMap. Otherwise, a non-zero cache size uses an LRU Map. The default cache size is 89. Note that the ConcurrentHashMap may be better at thread concurrency.

    resource.manager.defaultcache.size
    Sets the size of the default implementation of the resource manager cache size. The default is 89.

    resource.loader = <name> (default = file)
    Multi-valued key. Will accept CSV for value. Public name of a resource loader to be used. This public name will then be used in the specification of the specific properties for that resource loader. Note that as a multi-valued key, it's possible to pass a value like "file, class" (sans quotes), indicating that following will be configuration values for two loaders.

    <name>.loader.description = Velocity File Resource Loader
    Description string for the given loader.

    <name>.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
    Name of implementation class for the loader. The default loader is the file loader.

    <name>.resource.loader.path = .
    Multi-valued key. Will accept CSV for value. Root(s) from which the loader loads templates. Templates may live in subdirectories of this root. ex. homesite/index.vm This configuration key applies currently to the FileResourceLoader and JarResourceLoader.

    <name>.resource.loader.cache = false
    Controls caching of the templates in the loader. Default is false, to make life easy for development and debugging. This should be set to true for production deployment. When 'true', the modificationCheckInterval property applies. This allows for the efficiency of caching, with the convenience of controlled reloads - useful in a hosted or ISP environment where templates can be modifed frequently and bouncing the application or servlet engine is not desired or permitted.

    <name>.resource.loader.modificationCheckInterval = 2
    This is the number of seconds between modification checks when caching is turned on. When this is an integer > 0, this represents the number of seconds between checks to see if the template was modified. If the template has been modified since last check, then it is reloaded and reparsed. Otherwise nothing is done. When <= 0, no modification checks will take place, and assuming that the property cache (above) is true, once a template is loaded and parsed the first time it is used, it will not be checked or reloaded after that until the application or servlet engine is restarted.

    To illustrate, here is an example taken right from the default Velocity properties, showing how setting up the FileResourceLoader is managed

    Velocimacro

    velocimacro.library = VM_global_library.vm
    Multi-valued key. Will accept CSV for value. Filename(s) of Velocimacro library to be loaded when the Velocity Runtime engine starts. These Velocimacros are accessable to all templates. The file is assumed to be relative to the root of the file loader resource path.

    velocimacro.permissions.allow.inline = true
    Determines of the definition of new Velocimacros via the #macro() directive in templates is allowed. The default value is true, meaning any template can define and use new Velocimacros. Note that depending on other properties, those #macro() statements can replace global definitions.

    velocimacro.permissions.allow.inline.to.replace.global = false
    Controls if a Velocimacro defind 'inline' in a template can replace a Velocimacro defined in a library loaded at startup.

    velocimacro.permissions.allow.inline.local.scope = false
    Controls 'private' templates namespaces for Velocimacros. When true, a #macro() directive in a template creates a Velocimacro that is accessable only from the defining template. This means that Velocimacros cannot be shared unless they are in the global or local library loaded at startup. (See above.) It also means that templates cannot interfere with each other. This property also allows a technique where there is a 'default' Velocimacro definition in the global or local library, and a template can 'override' the implementation for use within that template. This occurrs because when this property is true, the template's namespace is searched for a Velocimacro before the global namespace, therefore allowing the override mechanism.

    velocimacro.context.localscope = false
    Controls whether reference access (set/get) within a Velocimacro will change the context, or be of local scope in that Velocimacro. This feature is deprecated and has been removed in Velocity 2.0. Instead, please use the $macro namespace for storage of references local to your Velocimacro. (e.g. #set( $macro.foo = 'bar') and $macro.foo)

    velocimacro.library.autoreload = false
    Controls Velocimacro library autoloading. When set to true the source Velocimacro library for an invoked Velocimacro will be checked for changes, and reloaded if necessary. This allows you to change and test Velocimacro libraries without having to restart your application or servlet container, just like you can with regular templates. This mode only works when caching is off in the resource loaders (e.g. file.resource.loader.cache = false ). This feature is intended for development, not for production.

    velocimacro.arguments.strict = false
    When set to true, will throw a ParseErrorException when parsing a template containing a macro with an invalid number of arguments. Is set to false by default to maintain backwards compatibility with templates written before this feature became available.

    velocimacro.body.reference = false
    Defines name of the reference that can be used to get the body content (an AST block) given for a block macro call (e.g. #@myMacro() has a body #end). The default reference name is "bodyContent" (e.g. $bodyContent). This block macro feature was introduced in Velocity 1.7.

    macro.provide.scope.control = false
    Used to turn on the automatic provision of the $macro scope control during #macro calls. The default is false. Set it to true if you need a local namespace in macros or more advanced #break controls.

    <somebodymacro>.provide.scope.control = false
    Used to turn on the automatic provision of the $<nameofthemacro> scope control during a call to a macro with a body (e.g. #@foo #set($foo.a=$b) ... $foo.a #end). The default is false. Set it to true if you happen to need a namespace just for your macro's body content or more advanced #break controls.

    Strict Reference Setting

    runtime.references.strict = false
    New in Velocity 1.6, when set to true Velocity will throw a MethodInvocationException for references that are not defined in the context, or have not been defined with a #set directive. This setting will also throw an exception if an attempt is made to call a non-existing property on an object or if the object is null. When this property is true then property 'directive.set.null.allowed' is also set to true. Also, 'directive.foreach.skip.invalid' defaults to true when this property is true, but explicitly setting 'directive.foreach.skip.invalid' will override this default. For a complete discussion see Strict References Setting.

    runtime.references.strict.escape = false Changes escape behavior such that putting a forward slash before a reference or macro always escapes the reference or macro and absorbs the forward slash regardless if the reference or macro is defined. For example "\$foo" always renders as "$foo", or "\#foo()" is always rendered as "#foo()". This escape behavior is of use in strict mode since unintended strings of characters that look like references or macros will throw an exception. This provides an easy way to escape these references. However, even in non-strict mode the developer may find this a more consistent and reliable method for escaping.

    String Interpolation

    runtime.interpolate.string.literals = true
    Controls interpolation mechanism of VTL String Literals. Note that a VTL StringLiteral is specifically a string using double quotes that is used in a #set() statement, a method call of a reference, a parameter to a VM, or as an argument to a VTL directive in general. See the VTL reference for further information.

    Math

    runtime.strict.math = false
    Affects all math operations in VTL. If changed to true, this will cause Velocity to throw a MathException whenever one side of a math operation has a null value (e.g. #set( $foo = $null * 5 )) or when trying to divide by zero. If this value is left false, then rendering will continue and that math operation will be ignored.

    Parser Configuration

    parser.pool.class = org.apache.velocity.runtime.ParserPoolImpl
    This property selects the implementation for the parser pool. This class must implement ParserPool. Generally there is no reason to change this though if you are building a high volume web application you might consider including an alternate implementation that automatically adjusts the size of the pool.

    parser.pool.size = 20
    This property is used by the default pooling implementation to set the number of parser instances that Velocity will create at startup and keep in a pool. The default of 20 parsers should be more than enough for most uses. In the event that Velocity does run out of parsers, it will indicate so in the log, and dynamically create overflow instances as needed. Note that these extra parsers will not be added to the pool, and will be discarded after use. This will result in very slow operation compared to the normal usage of pooled parsers, but this is considered an exceptional condition. A web application using Velocity as its view engine might exhibit this behavior under extremely high concurrency (such as when getting Slashdotted). If you see a corresponding message referencing the parser.pool.size property in your log files, please increment this property immediately to avoid performance degradation.

    Pluggable Introspection

    runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl
    This property sets the 'Uberspector', the introspection package that handles all introspection strategies for Velocity. You can specify a comma-separated list of Uberspector classes, in which case all Uberspectors are chained. The default chaining behaviour is to return the first non-null value for each introspection call among all provided uberspectors. You can modify this behaviour (for instance to restrict access to some methods) by subclassing org.apache.velocity.util.introspection.AbstractChainableUberspector (or implementing directly org.apache.velocity.util.introspection.ChainableUberspector). This allows you to create more interesting rules or patterns for Uberspection, rather than just returning the first non-null value.

    Velocity has a few nice logging features to allow both simplicity and flexibility. Without any extra configuration, Velocity will setup a file-based logger that will output all logging messages to a file called velocity.log in the 'current directory' where Velocity was initialized. For more advanced users, you may integrate your current logging facilities with Velocity to have all log messages sent to your logger.

    Starting with version 1.3, Velocity will automatically use either the Jakarta Avalon Logkit logger, or the Jakarta Log4j logger. It will do so by using whatever it finds in the current classpath, starting first with Logkit. If Logkit isn't found, it tries Log4j.

    To utilize this feature, simply use the 'non-dependency' Velocity jar (because Logkit is baked into the jar with dependencies) and place either the logkit or log4j jar in your classpath.

    In general, you have the following logging options:

    • Default Configuration
      By default, Velocity will create a file-based logger in the current directory. See the note above regarding automatic detection of Logkit or Log4j to use as the default logging system.
    • Existing Log4j Logger
      Starting with version 1.3, Velocity will log its output to an existing Log4j Logger setup elsewhere in the application. To use this feature you must
      1. Make sure that the Log4j jar is in your classpath. (You would do this anyway since you are using Log4j in the application using Velocity.)
      2. Configure Velocity to use the Log4JLogChute class by specifying the name of the existing Logger to use via the 'runtime.log.logsystem.log4j.logger' property.
      Note that this support for Logger is in version 1.5 of Velocity. Further, in version 1.5 we removed the now-ancient and very deprecated original Log4JLogSystem class and replaced with the current Log4JLogChute class which uses the Logger class. We apologize for the confusion, but we needed to move on.
    • Custom Standalone Logger
      You can create a custom logging class - you just need to implement the interface org.apache.velocity.runtime.log.LogChute and then simply set the configuration property runtime.log.logsystem.class with the classname, and Velocity will create an instance of that class at init time. You may specify the classname as you specify any other properties. See the information on the Velocity helper class as well as the configuration keys and values. Please note that the old org.apache.velocity.runtime.log.LogSystem interface has been deprecated for v1.5 in favor of the new LogChute interface. This is due to significant upgrades to our logging code that could not be supported by the LogSystem interface. But don't worry, if you specify a custom class that implements the LogSystem interface, it will still work. However, it will generate deprecation warnings. You should upgrade your custom logger to implement LogChute as soon as possible.
    • Integrated Logging
      You can integrate Velocity's logging capabilities with your applications existing logging system, simply by implementing the org.apache.velocity.runtime.log.LogChute interface. Then, pass an instance of your logging class to Velocity via the runtime.log.logsystem configuration key before initializing the Velocity engine, and Velocity will log messages to your application's logger. See the information on the Velocity helper class as well as the configuration keys and values.
    Using Log4j With Existing Logger

    Here is an example of how to configure Velocity to log to an existing Log4j Logger.

    Note that the above example can be found in examples/logger_example.

    Simple Example of a Custom Logger

    Here is an example of how to use an instantiation of your class that implements Velocity's logging system as the logger. Note that we are not passing the name of the class to use, but rather a living, existing instantiation of the class to be used. All that is required is that it support the LogChute interface.

    Resource Loaders

    One of the fundamental and important parts about Velocity is the resource management system and the resource loaders. They are referred to as 'resources' here rather than 'templates' because the resource management system will also handle non-template reasources, specifically things that are loaded via the #include() directive.

    The resource loader system if very flexible, allowing one or more resource loaders to be in operation at the same time. This allows tremendous flexibility in configuration and resource managment, and futher allows you to write your own resource loaders for your special needs.

    There are currently four kinds of resource loaders that are included with Velocity, each described below. Note that in the example configuration properties given, a common name for the loader is shown (ex.'file' in file.resource.loader.path). This 'common name' may not work for your configuration. Please read the section on resource configuration properties to understand how this system works. Also, each of these loaders is located in the package org.apache.velocity.runtime.resource.loader.

    • FileResourceLoader : This loader gets resources from the filesystem. Its configuration properties include:
      • file.resource.loader.path = <path to root of templates>
      • file.resource.loader.cache = true/false
      • file.resource.loader.modificationCheckInterval = <seconds between checks>
      This is the default loader, and is configured, by default to get templates from the 'current directory'. In the case of using Velocity with servlets, this can be a problem as you don't want to have to keep your templates in the directory from which you start your servlet engine. See the documentation for your servlet or web framework (for example VelocityViewServlet) for more info on how to configure the location of the Velocity templates.
    • JarResourceLoader : This loader gets resource from specific jar files. It is very similar to the FileResourceLoader, except that you have the convenience of bundling your templates into jars. The properties are identical, except for jar.resource.loader.path, where you provide the full location of the jar(s) you wish to load resources from. To specify a jar for the loader.path you use the standard JAR URL syntax of java.net.JarURLConnection.
    • ClasspathResourceLoader : This loader gets resources from the classloader. In general, this means that the ClasspathResourceLoader will load templates placed in the classpath (in jars, for example) While the classpath is a source of great pain and suffering in general, it is a very useful mechanism when working on a Servlet Spec 2.2 (or newer) compliant servlet runner. Tomcat is an example of such. To use this loader effectively, all you must do is jar your templates, and put that jar into the WEB-INF/lib directory of your webapp. There are no configuration options to worry about, nor is the absolute vs. relative path an issue, as it is with Jar and File resource loaders. Again, please note that the ClasspathResourceLoader is not only for use with a servlet container, but can be used in any application context.
    • URLResourceLoader : This loader gets resources from a URL connection. Its configuration properties include:
      • url.resource.loader.root = <root URL path of templates>
      • url.resource.loader.cache = true/false
      • url.resource.loader.modificationCheckInterval = <seconds between checks>
      This loader simply downloads resources from configured URLs. It works much like the FileResourceLoader, however, it can pull templates down from any valid URL to which the application can create a connection.
    • DataSourceResourceLoader : This loader will load resources from a DataSource such as a database. This loader is only available under JDK 1.4 and later. For more information on this loader, please see the javadoc for the class org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader.
    Configuration Examples

    Configuring the resource loaders for Velocity is straightforward. The properties that control the are listed in the resource configuration section, for further reference.

    The first step in configuring one or more resource loaders is do 'declare' them by name to Velocity. Use the property resource.loader and list one or more loader names. You can use anything you want - these names are used to associate configuration properties with a given loader.

    That entry declares that we will have a resource loader known as 'file'. The next thing to do is to set the important properties. The most critical is to declare the class to use as the loader:

    In this case, we are telling velocity that we are setting up a resource loadercalled 'file', and are using the class org.apache.velocity.runtime.resource.loader.FileResourceLoader to be the class to use. The next thing we do is set the properties important to this loader.

    Here, we set a few things. First, we set the path to find the templates to be /opt/templates. Second, we turned caching on, so that after a template or static file is read in, it is cached in memory. And finally, we set the modification check interval to 2 seconds, allowing Velocity to check for new templates.

    Those are the basics. What follows are a few examples of different configuraitons.

    Do-nothing Default Configuration: As the name says, there is nothing you have to do or configure to get the default configuration. This configuration uses the FileResourceLoader with the current directory as the default resource path, and caching is off. As a properties set, this is expressed as:

    Multiple Template Path Configuration: This configuration uses the FileResourceLoader with several directories as 'nodes' on the template search path. We also want to use caching, and have the templates checked for changes in 10 second intervals. As a properties set, this is expressed as:

    Multiple Loader Configuration : This configuration sets up three loaders at the same time, the FileResourceLoader, the ClasspathResourceLoader, and the JarResourceLoader. The loaders are set-up such that the FileResourceLoader is consulted first, then the ClasspathResourceLoader, and finally the JarResourceLoader. This would allow you to qickly drop a template into the file template area to replace on of the templates found in the classpath (usually via a jar) without having to rebuild the jar.

    Node that the three names 'file', 'class', and 'jar' are merely for your convenience and sanity. They can be anything you want - they are just used to associate a set of properties together. However, it is recommended that you use names that give some hint of the function.

    Note that while all three require very little configuration information for proper operation, the ClasspathResourceLoader is the simplest.

    Pluggable Resource Manager and Resource Cache

    The Resource Manager is the main part of the resource (template and static content) management system, and is responsible for taking application requests for templates, finding them in the available resource loaders, and then optionally caching the parsed template. The Resource Cache is the mechanism that the Resource Manager uses to cache templates for quick reuse. While the default versions of these two facilities are suitable for most applications, for advanced users it now is possible to replace the default resource manager and resource cache with custom implementations.

    A resource manager implementation must implement the org.apache.velocity.runtime.resource.ResourceManager interface. A description of the requirements of a resource manager is out of scope for this document. Implementors are encouraged to review the default implementation. To configure Velocity to load the replacement implementation, use the configuration key:

    This key is also defined as a contstant RuntimeConstants.RESOURCE_MANAGER_CLASS

    A resource cache implementation must implement the org.apache.velocity.runtime.resource.ResourceCache interface As with the resource manager, a description of the requirements of a resource manager is out of scope for this document. Implementors are encouraged to review the default implementation. To configure Velocity to load the replacement implementation, use the configuration key:

    This key is also defined as a contstant RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS

    A resource cache implementation may want to limit the cache size (rather than providing an unbounded cache which could consume all available memory). To configure Velocity to set the size for your cache, use the configuration key:

    This key is also defined as a contstant RuntimeConstants.RESOURCE_MANAGER_CACHE_SIZE

    Velocity allows you to specify the character encoding of your template resources on a template by template basis. The normal resource API's have been extended to take the encoding as an argument:

    org.apache.velocity.app.Velocity:

    public static Template getTemplate(String name, String encoding)

    public static boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer )

    The value for the encoding argument is the conventional encoding specification supported by your JVM, for example "UTF-8" or "ISO-8859-1". For the official names for character sets, see here.

    Note that this applies only to the encoding of the template itself - the output encoding is an application specific issue.

    Velocity's flexibility and simple template language makes it an ideal environment for working with XML data. Anakia is an example of how Velocity is used to replace XSL for rendering output from XML. The Velocity site, including this documentation, is generated from XML source using Anakia. The Jakarta site is also rendered using Anakia.

    Generally, the pattern for dealing with XML in Velocity is to use something like JDOM to process your XML into a data structure with convenient Java access. Then, you produce templates that access data directly out of the XML document - directly though the JDOM tree. For example, start with an XML document such as:

    Developer's Guide Velocity Doc Team ]]>

    Now make a little Java program that includes code similar to:

    (See the Anakia source for details on how to do this, or the Anakia example in the examples directory in the distribution.) Now, make a regular Velocity template:

    The document title is $root.getChild("document").getChild("properties") .getChild("title").getText() ]]>

    and render that template as you normally would, using the Context containing the JDOM tree. Of course, this isn't the prettiest of examples, but it shows the basics - that you can easily access XML data directly from a Velocity template.

    One real advantage of styling XML data in Velocity is that you have access to any other object or data that the application provides. You aren't limited to just using the data present in the XML document. You may add anything you want to the context to provide additional information for your output, or provide tools to help make working with the XML data easier. Bob McWhirter's Werken Xpath is one such useful tool - an example of how it is used in Anakia can be found in org.apache.velocity.anakia.XPathTool.

    One issue that arises with XML and Velocity is how to deal with XML entities. One technique is to combine the use of Velocimacros when you need to render an entity into the output stream:

    #xenc($sometext) ]]>

    where the escapeEntities() is a method that does the escaping for you. Another trick would be to create an encoding utility that takes the context as a constructor parameter and only implements a method:

    Put it into the context as "xenc". Then you can use it as:

    $xenc.sometext ]]>

    This takes advantage of Velocity's introspection process - it will try to call get("sometext") on the $xenc object in the Context - then the xenc object can then get the value from the Context, encode it, and return it.

    Alternatively, since Velocity makes it easy to implement custom Context objects, you could implement your own context which always applies the encoding to any string returned. Be careful to avoid rendering the output of method calls directly, as they could return objects or strings (which might need encoding). Place them first into the context with a #set() directive and the use that, for example:

    $sometext ]]>

    The previous suggestions for dealing with XML entities came from Christoph Reck, an active participant in the Velocity community.

    We hope this brief guide was a helpful introduction to using Velocity in your Java projects, and thank you for you interest in Velocity. We welcome any and all comments you may have about this documentation and the Velocity template engine itself.

    Please submit all detailed, thoughtful and constructive feedback through our mailing lists.

    velocity-1.7/xdocs/docs/jar-dependencies.xml0000644000175000017500000001174211110337554021076 0ustar moellermoeller Velocity dependencies Velocity Documentation Team

    Velocity has a number of external jar dependencies. However, not all of these are needed every time. This document should help you do decide which jars must also be present if you want to integrate Velocity into your application.

    All of these jars must be present when building Apache Velocity. The build process downloads all of them automatically from the Internet.

    jar nameRequiredExplanation
    commons-collectionsYes Needed for all parts of Velocity
    commons-langYes Needed for all parts of Velocity
    commons-loggingNo Must be present if log system is configured to use CommonsLogLogChute. Otherwise, it is not needed.
    oroYes Must be present if you have Velocity configured to automatically escape references. Otherwise, it is not needed.
    log4jNo Must be present if log4j Logging has been selected. Not needed if any other logging style has been selected.
    logkit (or avalon-logkit)No Must be present if Avalon Logging has been selected. Not needed if any other logging style has been selected.
    servletapiNo Only needed when the VelocityServlet or ServletLogChute are used. Should normally be supplied by the servlet container. VelocityServlet is deprecated and should be replaced with VelocityViewServlet from the velocity-tools distribution.
    jdomNo Only required for the deprecated Anakia tool / ant task
    werken-xpathNo Only required for the deprecated Anakia tool / ant task
    antlrNo Only required for the deprecated Anakia tool / ant task
    antNo Only needed for compilation.
    junitNo Only needed for running the tests during compilation.
    hsqldbNo Only needed for running the tests during compilation.

    The most common case is the integration of the Velocity runtime into your application. In this case, you must add commons-collections and commons-lang to your application (and optional Oro or commons-logging if required). If you already have one or more of these libraries in your application, you should check if you need to update their versions.

    The auto-generated dependency report lists all mandatory dependencies as compile and all optional dependencies as provided, though it fails to properly reflect the optional nature of the Oro and Commons-Logging dependencies.

    velocity-1.7/xdocs/docs/webapps.xml0000644000175000017500000003772311116323420017337 0ustar moellermoeller Getting Started with a Web Application Velocity Documentation Team

    Velocity is often used to generate web pages in applications, usually as a direct replacement for JSP. Some of the benefits of using Velocity to generate web pages are:

    • Simplicity - The pages can be written and maintained by non-technical web designers.
    • Ease of maintainance - Scripting is removed from web pages with the recommended MVC approach.
    • Access both methods and properties - Web designers can reference methods as well as properties of objects in a context.
    • Consistency - Velocity can be used for other text generation tasks (such as sending email) providing a consistent way to mark up text.

    This document provides some basic info on getting started with Velocity in a web application.

    The primary purpose of the Velocity engine is simply to generate text based on a template. Consequently, Velocity does not contain any web-related functionality in and of itself. To make a web application, you will need a framework to respond to HTTP requests, handle user authentication, make business logic calls, and generate a response. There are several strong contenders.

    1. Velocity Tools / VelocityViewServlet - The easiest way to get started is to download the companion Velocity Tools subproject and use the VelocityViewServlet. This servlet is easy to configure and install. You create a directory of templates on your web server, optionally edit an XML file that lists various "Tools" to place in the context and you are off. More details can be found in the tutorial below.
    2. Velocity Tools / VelocityStruts - You may be familiar with the popular Struts framework, originally designed to provide much needed application functionality to JSP. With the VelocityStruts module of Velocity Tools you can substitute Velocity for JSP as the page template language. This allows you to take advantage of the large base of Struts infrastructure while designing pages using Velocity.
    3. Third party frameworks - There are a number of third party frameworks listed on the PoweredByVelocity wiki page. Of these, Spring is probably the most sophisticated and well known. Apache Turbine has many features and can also be very useful. It was built with Velocity as the primary page language, which is not surprising since many of the original Velocity developers were involved in creating it. Simpler alternatives are the Click or Maverick frameworks, which provide a simple Controller architecture that integrates nicely with Velocity.
    4. Build your own - A final alternative is to build your own framework. Create a dispatcher servlet, retrieve templates from a file or database, integate with your business logic and send the results back to the user. Often you'll have an easier time starting with one of the existing frameworks and customizing it. In particular you can add new functionality to the VelocityViewServlet simply by creating a subclass.

    As a side note, you may also come across references to VelocityServlet, which is a deprecated servlet that was included in the Velocity Engine up to version 1.4. Since VelocityServlet is no longer being maintained we strongly recommend you use VelocityViewServlet in Velocity Tools instead.

    There are a few issues with Velocity that are specific to web applications. Here is a brief discussion of the most commonly encountered issues.

    The default Velocity Engine settings make use of the FileResourceLoader. This is great for most applications that are not deployed to a servlet engine. Once you need to build a web application and ship or deploy it as a WAR file, the FileResourceLoader can become your worst enemy. So, we explicitly recommend you do NOT use the FileResourceLoader for your web applications.

    Really, any of the other ResourceLoader implementations out there are preferred, but all the other ResourceLoaders shipped with Velocity Engine will require you to store your templates somewhere besides the standard file system (e.g. in the classpath, in a database, or on a remote server). If that works for you, then great! However, we recognize that these are not convenient for most people's development cycle.

    The simplest replacement for FileResourceLoader in a web application is actually a part of the VelocityTools project. It is the WebappResourceLoader. This ResourceLoader implementation is specifically designed to work just like the FileResourceLoader, but it is aware of the servlet context and allows you to configure resource paths relative to the servlet root, rather than the local file system.

    If you are using the VelocityViewServlet, then it is automatically configured and ready to use the WebappResourceLoader. So if you want to change the configured path(s), you need only add a line like the following to your velocity.properties:

    If you need to set the WebappResourceLoader up on your own, then you can make your properties something like this:

    You will also need to put the ServletContext into your VelocityEngine's application attributes before initializing that Engine. This is how the WebappResourceLoader knows how to find templates.

    Velocity provides the ability to call any method of an object acting as a reference. This can be useful when displaying information into the page but is dangerous when object or application state is modified.

    For example, the following code safely calls the size() method of a list and displays the result.

    An example of an unsafe operation concerns a financial web page with an object in the context that calculates data year by year. The method calculateNextYear() calculates data for the next year and advances an internal counter:

    The problem with this approach is that the code cannot be repeated in multiple parts of the page. You may not intend to do so, but it's easy to forget this when cutting and pasting or writing control statements (such as #if or #foreach). This becomes more of an issue when you are dealing with application or session-level state.

    The (strongly) recommended practice is to only use Velocity for inserting information into text. Method calls can be useful to retrieve information. However, it's generally a bad idea to use a method call to change object state, and it's always a bad idea to change application state.

    If you find yourself needing to change object state (as in the previous example) try precalculating all the possible values in the controller and putting them in a List or Map. Any changes to application state should always be done by the controller.

    On a related note, you should always put a List or Set into the context instead of an Iterator or Enumeration. This allows the collection to be used more than once in the page with no change in behavior.

    Any user-entered text that contains special HTML or XML entities (such as <, >, or &) needs to be escaped before included in the web page. This is required, both to ensure the text is visible, and also to prevent dangerous cross-site scripting. Unlike, for example, JSTL (the Java Standard Tag Language found in Java Server Pages), Velocity does not escape references by default.

    However, Velocity provides the ability to specify a ReferenceInsertionEventHandler which will alter the value of a reference before it is inserted into the page. Specifically, you can configure the EscapeHtmlReference handler into your velocity.properties file to escape all references (optionally) matching a regular expression. The following example will escape HTML entities in any reference that starts with "msg" (e.g. $msgText).

    eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
    eventhandler.escape.html.match = /msg.*/
    

    Note that other kinds of escaping are sometimes required. For example, in style sheets the @ character needs to be escaped, and in Javascript strings the single apostrophe ' needs to be escaped.

    Since a web application is running on a central server, that typically has multiple users and confidential resources, care must be taken to make certain that the web application is secure. Most standard web security principles apply to a web application built with Velocity. A few specific issues (such as system configuration, more on cross-site scripting, and method introspection) are written up in this article on Building Secure Applications with Velocity. In particular, you may want to prevent template designers from including "dangerous" reflection-related methods by specifying the SecureUberspector to get/set properties and execute method calls.

    runtime.introspector.uberspect = org.apache.velocity.util.introspection.SecureUberspector
    

    A minor point is that (in some circumstances) Velocity, in the absence of any log-related configuration, creates a log file in the current directory. When Velocity is used in a web application the "current directory" is usually the current directory from which the application server is started. If you start seeing the file "velocity.log" files in random places on your server filesystem, check the Velocity log configuration. This is due to the default use of the Avalon Log Kit when present in the classpath. Typically this occurs when Velocity is used within a web application outside of web page generation (e.g. for sending email). To solve this problem, remove any file labeled "avalon-logkit" from the classpath or properly configure the log file location.

    What follows is a brief tutorial on building a simple web app with VelocityViewServlet. Note that it suggests you compile VelocityViewServlet from the source. This isn't actually required to use VelocityViewServlet but we recommend it in this case in order to see the source and then compile the example files.

    Prerequisites for doing the following include the Java Developer's Kit (JDK) and Apache Ant.

    For more information, consult the Velocity Tools documentation.

    1. Download the Velocity Tools project source (you need the source for the examples) from the download page.
    2. Build the Velocity Tools jar and the "simple" example by typing:
    3. Take a look at the "examples" directory. You will see a file "index.vm". Here's an excerpt: I'm a velocity template. #if( $XHTML ) #set( $br = "
      " ) #else #set( $br = "
      " ) #end $br $br Here we use a custom tool: $toytool.message $br $br Here we get the date from the DateTool: $date.medium ]]> You can copy any additional velocity files into this same directory. In examples/WEB-INF you will see a file "tools.xml". This specifies a list of "Tools" that are automatically included in the context. this is foo this is bar. ]]> And finally the web.xml file specifies the name of the servlet and location of toolbox.properties. velocity org.apache.velocity.tools.view.VelocityViewServlet velocity *.vm index.vm ]]>
    4. Copy this directory into your "webapps" directory on Tomcat. You could also copy "simple.war", but copying in the entire directory will let you experiment with changes. You should now be able to access your simple one-page webapp with this URL. (or something similar):
    5. Experiment with adding new Velocity pages. Note that you can access any velocity page just by changing the URL. Try changing the entries in tools.xml or creating your own tools. Consult the Velocity Tools documentation, the "showcase" example application, and the Wiki for more info on the wide variety of tools available.
    velocity-1.7/xdocs/docs/translations/0000755000175000017500000000000011675166245017705 5ustar moellermoellervelocity-1.7/xdocs/docs/translations/user-guide_es.xml0000644000175000017500000021057111156517252023165 0ustar moellermoeller Guía del Usuario de Velocity Velocity Documentation Team John Castura Juan Pablo Morales
    1. Acerca de esta guía
    2. ¿Qué es Velocity?
    3. ¿Qué puede hacer Velocity por mi?
      1. El Ejemplo de la tienda de Lodo
    4. El Lenguaje de Plantillas de Velocity (VTL): Una Introducción
    5. ¡Hola Mundo Velocity!
    6. Comentarios
    7. Referencias
      1. Variables
      2. Propiedades
      3. Métodos
    8. Notación Formal de Referencias
    9. Notación Sileciosa de Referencias
    10. Literalmente
      1. Dinero
      2. Escapando Referencias VTL Válidas
    11. Sustitución de Mayúsculas y Minúsculas
    12. Directivas
      1. Set
      2. Cadenas de Caracteres
      3. Sentencias If-Else
        1. Operadores Lógicos y Relacionales
      4. Ciclos Foreach
      5. Include
      6. Parse
      7. Stop
      8. Velocimacros
    13. Escapando Directivas VTL
    14. VTL: Asuntos de Formato
    15. Otras Características y Miscelánea
      1. Matemáticas
      2. El Operador de Rango
      3. Temas Avanzados: Escapando y !
      4. Miscelánea de Velocimacro
      5. Concatenación de Cadenas
    16. Retroalimentación

    La Guía del usuario de Velocity busca ayudar a los diseñadores de páginas y a los proveedores de contenido a sentirse a gusto con Velocity y con la sintáxis de su simple pero poderoso lenguaje de script, el Lenguaje de Plantillas de Velocity (VTL por sus siglas en inglés). Muchos de los ejemplos de esta guía muestran como usar Velocity para incluir contenidos dinámicos en sitios web, pero todos los ejemplos de VTL son igualmente aplicables a otras páginas y plantillas.

    Gracias por escoger Velocity!

    Velocity es un motor de plantillas basado en Java. Le permite a los diseñadores de páginas hacer referencia a métodos definidos dentro del código Java. Los diseñadores Web pueden trabajar en paralelo con los programadores Java para desarrollar sitios de acuerdo al modelo de Modelo-Vista-Controlador (MVC), permitiendo que los diseñadores se concentren únicamente en crear un sitio bien diseñado y que los programadores se encarguen solamente de escribir código de primera calidad. Velocity separa el código Java de las páginas Web, haciendo el sitio más mantenible a largo plazo y presentando una alternativa viable a Java Server Pages (JSP) o PHP.

    Velocity se puede utilizar para crear páginas web, SQL, PostScript y cualquier otro tipo de salida de plantillas. Se puede utilizar como una aplicación independiente para generar código fuente y reportes, o como un componente integrado en otros sistemas. Cuando este completo Velocity proveerá servicios para el conjunto de aplicaciones web de Turbine. Velocity+Turbine proveerá un servicio de plantillas que facilitará el desarrollo de aplicaciones web de acuerdo a un verdadero modelo MVC.

    Suponga que usted es un diseñador para una tienda en línea que se especializa en vender lodo a la que llamaremos "La Tienda de Lodo en línea". Los negocios están muy bien. Sus clientes ordenan diferentes tipos y cantidades de lodo. Ellos ingresan en su sitio con su nombre de usuario y su clave secreta, lo que les permite ver sus órdenes y pedir más lodo. En estos momentos el Lodo Terracota, que es muy popular, esta en oferta. Una minoría de sus clientes usualmente compra Lodo Rojo Brillante, que también esta en oferta, pero no es tan popular y usualmente esta relegado al márgen de su página web. La información sobre cada cliente esta dentro de su base de datos por lo que surge la pregunta: ¿Por qué no usar Velocity para enfocar las ofertas especiales para los clientes que están más interesados en ciertas clases de lodo?

    Velocity hace fácil el personalizar las páginas para sus visitantes. Como un diseñador dentro de "El Cuarto de Lodo", usted quiere crear la página que sus usuarios verán después de entrar a su sitio.

    Usted se encuentra con los ingenieros de su compañía, y todos acuerdan que $cliente contendrá la información pertienente al cliente que está dentro de la página en un momento dado, que $lodosEnOferta contendrá todos los tipos de lodo que están en oferta hoy en día. Además, el objeto $flogger contendrá métodos para ayudar con la promoción. Para la tarea actual, solo se utilizarán estas tres referencias. Recuerde, usted no necesita preocuparse por como los ingenieros de software extraen la información necesaria de la base de datos; sólo tiene que saber que funciona. Esto le permite a usted continuar con su trabajo a la vez que deja a los ingenieros hacer el de ellos.

    Usted podría incluir el siguiente código VTL dentro de su página:

    Hello $cliente.Nombre! #foreach( $lodo in $lodosEnOferta ) #if ( $cliente.haComprado($lodo) ) #end #end
    $flogger.obtenerPromocion( $lodo )
    ]]>

    Los detalles exactos de la sentencia foreach serán descritos en profundidad próximamente; lo que es importante es el impacto que este pequeño script pueda tener en su sitio. Cuando un cliente con una debilidad por el Lodo Rojo Brillante ingrese, si el Lodo Rojo Brillante esta en oferta, eso será lo que el cliente verá, de manera prominente. Si otro cliente, con una historia larga de compras de Lodo Terracota ingresa, entonces para él la noticia de un rebaja de Lodo Terracota estará en un lugar muy importante. La flexibilidad de Velocity es enorme y sólo esta limitada por su creatividad.

    En la referencia de VTL están documentados muchos otros elementos de Velocity que, colectivamente le dan el poder y la flexibilidad que usted necesita para hacer de su sitio en la red una presencia en la red. A medida que usted se familiarice con estos elementos usted comenzará a aprovechar el poder de Velocity.

    El Lenguaje de Plantillas de Velocity (VTL) fue creado para prover la manera mas fácil, simple y limpia de incorporar contenido dinámico dentro de una página web. Incluso un desarrollador de páginas web con poca y ninguna experiencia puede rápidamente ser capaz de utilizar VTL para incluir contenido dinámico en un sitio web.

    VTL usa referencias para incluir contenido dinámico dentro de un sitio web. Una variable es un tipo de referencia que puede referirse a algo definido dentro del código Java o obtener su valor de un enunciado VTL en la página misma. A continuación hay un ejemplo de un enunciado VTL que se puede incluir en un documento HTML:

    Este enunciado VTL, como todos los enunciados VTL comienza con el caracter # y contiene una directiva: set. Cuando un visitante solicita su página, el Motor de Plantillas de Velocity buscará dentro del contenido de su página y encontrará todos los símbolos #, para luego determinar cuáles marcan el comienzo de enunciados VTL y cuáles no tienen nada que ver con VTL.

    El caracter # viene seguido por una directiva set. La directiva set utiliza una expresión (encerrada entre paréntesis) -- una ecuación que asigna un valor a una variable. La variable se encuentra en el lado derecho y el valor está en el lado izquierdo; los dos se encuentran separados por un signo igual (=).

    En el ejemplo en la parte superior, la variable es $a y el valor es Velocity. Esta variable, al igual que todas las referencias, comienza con el caracter $. Los valores siempre se encuentran ente comillas; con Velocity no hay confusión acerca de los tipos de datos, ya que solamente cadenas (información basada en texto) pueden ser pasados a las variables.

    La siguiente regla puede ser útil para entender mejor como funciona Velocity: Las Referencias comienzan con $ y se utilizan para obtener algo. Las directivas comienzan con # y se utilizan para hacer algo

    En el ejemplo anterior #set se utilizó para asignarle un valor a una variable. La variable, $a, puede utilizarse dentro de la plantilla para escribir la palabara "Velocity".

    Una vez un valor ha sido asignado a una variable, usted puede referenciar la variable en cualquier lugar dentro del documento HTML. En el ejemplo siguiente, un valor es asignado a la variable $foo, que luego es referenciada.

    #set( $foo = "Velocity" ) ¡Hola Mundo $foo! ]]>

    El resultado es una página web que imprime "¡Hola Mundo Velocity!"

    Para hacer los enunciados con directivas VTL más legibles, nosotros le recomendamos comenzar cada enunciado VTL en una nueva línea, aunque usted no esta obligado a hacerlo así. La directiva set ser verá con mayor detalle más adelante.

    Los comentarios es posible incluir texto que no aparecerá como parte de la salida del motor de plantillas. Los comentarios sirven para recordar e indicar a otros que es lo que están haciendo los enunciados VTL, o para cualquier otro propósito que usted considere útil. A continuación hay un ejemplo de un comentario de VTL.

    Un comentario de una sola línea comienza con ## y termina al final de la línea. Si usted desea escribir varias líneas de comentario no es necesario tener numerosos comentarios de una sóla línea. Los comentarios de varias líneas, que comienzan con #* y terminan con *# le permiten manejar fácilmente esta situación.

    A continuación hay algunos ejemplos para aclarar como funcionan los comentarios de una y varias líneas:

    Existe un tercer tipo de comentario, el bloque de comentario VTL, que puede ser utilizado para almacenar datos como el autor y la información de versiones:

    Existen tres tipos de referencias en VTL: variables, propiedades y métodos. Como un diseñador que utilizar VTL, usted y sus ingenieros deben llegar a un acuerdo respecto a los nombres de las referencias para que usted pueda utilizarlas correctamente en sus plantillas.

    Todo lo que entra y sale de una referencia se trata como una cadena de caracteres (un objeto String). Si existe un objeto que representa $foo (por ejemplo, un objeto Integer), entonces Velocity llamará el método .toString() de ese objeto para convertirlo en una cadena de caracteres.

    Variables
    La notación breve de una variable esta compuesta por un signo "$" inicial seguido de un Identificador. Un identificador VTL debe comenzar con un caracter alfabético (a .. z ó A .. Z). El resto de los caracteres deb ser de alguno de los siguiente tipos:

    • alfabético (a .. z, A .. Z)
    • numérico (0 .. 9)
    • línea ("-")
    • underscore ("_")

    A continuación hay algunos ejemplos de referencias válidas en VTL:

    Cuando VTL hace referencia una variable, po ejemplo, $foo, la variable puede obtener su valor de una directiva set dentro de la plantilla, o del código Java. Por ejemplo, si la variable de Java $foo tiene el valor bar en el momento en que se solicita la plantilla, entonces bar reemplaza todas las ocurrencias (o instancias) de $foo dentro de la página web. De manera alterna, si se incluye el enunciado

    La salida será la misma para todas las instancias de $foo que se encuentren a continuación es esta directiva.

    Propiedades
    El segundo sabor de referencias VTL son las propiedades; las propiedades tienen un formato particular. La versión corta se compone de un signo $ seguido de un identificador VTL, seguido de un punto y de otro identificador VTL. A continuación hay ejemplos de referencias de propiedades válidas en VTL:

    Tome el primer ejemplo, $cliente.Direccion. Puede tener dos significados. Puede significar, Busque en la tabla de hashing identificada como cliente y devuelva el valor asociado con la llave Direccion. Pero $customer.Address puede también referirse a un método (las referencias que se relacionan con métodos se discutirán en la sección siguiente); $customer.Address puede ser una manera corta de escribir $customer.getAddress(). Cuando su página sea solicitada Velocity determinará cuál de las dos posibilidades tiene sentido, y luego devolverá el valor apropiado.

    Methods
    Un método esta definido dentro del código de Java y es capaz de hacer algo útil, como desarrollar un cálculo o llegar a una decisión. Los métodos son referencias compuestas de un signo "$" inicial seguido en un identificador VTL, seguido de un Cuerpo de Método VTL. Un cuerpo de método VTL, a su vez esta formado por un identificador VTL seguido por un paréntesis izquierdo ("("), seguido, opcionalmente, por una lista de parámetros, para terminar en un paréntesis derecho. A continuación hay ejemplos de referencias de métodos válidas dentro de VTL:

    Los primeros dos ejemplos -- $cliente.getDireccion() y $compra.getTotal() -- pueden parecer similares a aquellos utilizados en la sección de propiedades, $cliente.Direccion y $compra.Total. Si usted supuso que estos ejemplos están relacionados de alguna manera, usted esta en lo cierto.

    Las Propiedades VTL pueden utilizarse como notación abreviada para los métodos de VTL. La propiedad $cliente.Direccion tiene exactamente el mismo efecto que el método $cliente.getDireccion() (Nótese el uso de la palabra inglesa get en lugar de la castellana obtener). Generalmente es preferible utilizar una Propiedad si esta disponible. La diferencia principal entre las propiedades y los métodos es que usted le puede dar una lista de parámetros a un Método.

    La notación breve se puede utilizar en los Métodos siguientes:

    Podríamos esperar que estos métodos devolvieran los nombres de los planetas que giran alrededor del sol, alimentaran un gusano de tierra y extrajeran una foro de un album. Los siguientes Métodos solo se pueden referenciar por medio de la notación larga:

    Notación Formal de Referncias
    La notación abreviada para referencias fue utilizada en los ejemplos anteriores, pero también existe una notación formal para referencias, que se demuestra a continuación:

    Casi en todos los casos usted utilizará la notación abreviada, pero existen escenarios en los cuales la notación formal se requiere para procesar corectamente la plantilla.

    Suponga que usted estuviera creando una frase en la que $vicio se utilizará como prefijo para el ajetivo de una clase. La idea es permitir a alguién escoger la palabra base para producir uno de los dos siguientes resultados: "Juan es un pirómano." ó "Juan es un cleptómano.". En este caso la notación abreviada no es apropiada; considere el siguiente ejemplo:

    Hay ambigüedad aquí, y Velocity asume que $viciomano, no $vicio, es el Identificador que usted quería utilizar. Al no encontrar ningún valor para $viciomano Velocity escribirá simplemente $viciomano. Este problema se resueklve usando notación formal.

    Ahora Velocity save que la referencia es $vicio y no $viciomano. La notación formal es útil cuando las referencias están ubicadas directamente al lado del texto dentro de una plantilla.

    Notación de Referenias Silenciosas
    Cuando Velocity encuentra una referencia indefinida, su comportamiento normal es es de escribir el nombre de la referencia. Por ejemplo, suponga que la siguiente referencia aparece como parte de una plantilla VTL.

    ]]>

    Cuando el formulario se carga por primera vez la referencia $correo no tiene valor, pero usted probablemente preferiría un texto en blanco a uno con el valor de "$correo". Usando la notación de referencias silenciosa se pasa por alto el comportamiento normal de Velocity. Para lograr eso en lugar de $correo en el VTL usted utilizaría $!correo. Con esta modificación el ejemplo anterior quedaría así:

    ]]>

    Ahora cuando el formulario se carga por primera vez y $correo no tenga valor una cadena vacía se escribirá en lugar de "$correo".

    La notación formal y la silenciosa se puede usar juntas como se muestra en el ejemplo siguiente:

    ]]>

    VTL hace uso de caracteres especiales, como $ y #, para hacer su trabajo por lo que se debe tener algo de cuidado en el momento de utilizar estos caracteres dentro de las plantillas. Esta sección habla de como escapar el caracter $.

    Dinero
    No hay ningún problema en escribir "Yo compré un saco de maíz de 2 kg. en el mercado de lagranja por sólo $2.50!". Como se mencionó anteriormente, un identificador VTL siempre comienza con una letra mayúscula o minúscula por lo que $2.50 no se confunde con una referencia.

    Escapando Referencias VTL Válidas
    Pueden existir casos en donde haya la posibilidad de que Velocity se confunda. Escapar caracteres especiales es la mejor manera de manejar los caracteres partículares de VTL dentro de sus plantillas, y esto se puede hacer utilizando el caracter palote o backslash ( \ ).

    Si Velocity encuentra una referencia en su plantilla VTL a $correo, el buscará el contexto ppor un valor correspondiente. En este caso el resultado será foo por qué $correo esta definido. Si $correo no esta definido el resultado será $correo.

    Suponga que $correo está definido (por ejemplo, que tiene el valor foo) y que usted desea escribir $correo. Existen varias maneras de hacer esto pero la más sencilla es usar el caracter de escape.

    se muestra como

    Note que el caracter \ se asocia con $ por la izquierda. La regla de asociación por la izquierda hace que \\\$correo se muestre como \\$correo. Compare estos ejemplos con lo siguientes, en los que $correo no esta definido.

    se muestra como

    Note que Velocity maneja de manera diferentes las referencias que están definidas de aquellas que no lo están. A continuación se encuentra una directiva que da a $foo el valor verde.

    La salida será: $luna = verde -- donde $luna se escribe literalmente porqué esta indefinido y verde se escribe en lugar de $foo

    También es posible escapar directivas de VTL; esto se describe con más detalle en la sección de Directivas.

    Ahora que usted esta familiarizado con las referencias, puede comenzar a aplicarlas de manera efectiva en sus plantillas. Las referencias de Velocity aprovechan algunos principios de Java que los diseñadores de plantillas encontraránm fáciles de utilizar. Por ejemplo:

    Estos ejemplos ilustran usos alternativos para la mismas referencias. Velocity se aprovechas de la instrospección y las capacidades de beans de Java para resolver los nombre de referencias tanto en el Contexto como en los métodos de los objetos. Es posible incluir y evaluar referencias casi en cualquier lugar de su plantilla.

    Velocity, que ha sido modelado con las especificaciones de Bean definidas por Sun Microsystems, distingue entre mayúsculas y minúsculas; sin embargo sus desarrolladores se han esforzado para encontrar y corregir los errores del usuario cuando sea posible. Cuando el método getFoo() es referenciado dentro de una plantilla como $bar.foo, Velocity intentará primero getfoo(). Si esto falla, intentará getFoo(). De la misma manera, cuando una plantilla se refiera a $bar.Foo, Velocity intentará $getFoo() primero y luego getfoo().

    Nota: Las Referencias a variables de instancia dentro de una plantilla no se resuelven. Solo las referencias a los atributos get y set de los JavaBeans se resuelven (i.e. $foo.Nombre se resuelve como el método de instancia getNombre() de la clase Foo, pero no como su variable de instancia Nombre).

    Las Referencias le permiten a los diseñadores de plantillas generar contenido dinámico para sitios web, mientras que las directivas -- elementos de script fáciles de usar que se pueden usar para manipular de manera creativa la salida del código Java -- les permiten a los diseñadores realmente estar a cargo de la apariencia y en contenido del sitio web.

    #set

    La directiva #set se utiliza para establecer el valor de una referencia. El valor se puede asignar a una referencia de variable o una referencia de propiedad, siempre entre paréntesis, como se muestra a continuación:

    El lado izquierdo (LI) de la asignación debe ser una referencia de variable o una referencia de propiedad. El lado derecho (LD) puede ser de alguno de los siguientes tipos:

    • Referencia de Variable
    • Constante de Cadena
    • Referencia de Propiedad
    • Referencia de Método
    • Literal Numérico
    • Lista de elementos como arreglo

    These examples demonstrate each of the aforementioned types:

    NOTA: En el último ejemplo los elementos definidos con el operador [..] son accesibles usando los métodos definidos en la clase ArrayList. Así, por ejemplo, usted podría acceder el primer elemento del arreglo utilizando $mono.Decir.get(0), con lo que obtendría la palabra "No".

    El lado derecho también puede ser una expresión aritmética sencilla:

    Si el Lado Derecho es una propiedad o referencia de método que se evalúa como null, no será asignada al lado izquierdo. No es posible remover una referencia existente del contexto utilizando este mecanismo. Esto puede ser confuso para los recién llegados a Velocity. Por ejemplo:

    Si $consulta.criterio("nombre") retorna la cadena "pedro", y $consulta.criterio("direccion") retorna null, el VTL anterio se mostraría de la siguiente manera:

    Esto tiende a confundir a quines están comenzando, que construyen ciclos #foreach que intentan hacer #set de una referencia por medio de una propiedad o un método e inmediatamente evalúan la referencia con una directiva #if. Por ejemplo:

    En el ejemplo anterior, no sería inteligente confiar en la evaluación de $resultado para determinar si una consulta tuvo éxito. Después de que $result ha sido agregado al contexto (por medio de una directiva #set), no puede volver a establecerse a null (quitarse del contexto). Los detalles de las directivas #if y #foreach son cubiertos con mayor detalle posteriormente en esta guía.

    Una solución para este problema puede ser predefinir $resultado a false. Luego, si la llamada a $consulta.criterios() falla, es posible verificar.

    A diferencia de algunas de las otras directivas de Velocity, la directiva #set no tiene un enunciado #end.

    Cadenas de Caracteres

    Cuando se utiliza la directiva #set, los literales de cadena que están encerrados en comillas dobles serán evaluados y mostrados en la plantilla, como se demuestra a continuación:

    La salida será:

    Sin embargo, cuando la cadena de caracteres esta encerrada en comillas sencillas, no será evaluada:

    Se muestra como:

    Por defecto, la característica de las comillas sencillas para mostrar texto sin evaluar esta disponible en Velocity; sin embargo este valor por defecto se puede cambiar editando el archivo velocity.properties de tal manera que stringliterals.interpolate=false.

    Condicionales

    La directiva #if en Velocity permite que se incluya texto dentro de la plantilla generada, con la condición de que el enunciado condicional evalue a verdadero. Por ejemplo:

    Velocity! #end ]]>

    La variable $foo se evalúa para determinar si es verdadera, cosa que ocurrirá bajo una de dos circunstancias: (i) $foo es un valor booleano (verdadero ó falso) que tiene un valor de verdadero, ó (ii) el valor no es null. Recuerde que el contexto de Velocity solamente contiene objetos, por lo que cuando se dice 'booleano' se habla en realidad de la clase Boolean. Esto es cierto incluso para los métodos que devuelven un valor de tipo boolean - la infraestructura de introspección devolverá un Boolean del mismo valor lógico.

    El contenido que se encuentra entre el enunciado #if y el enunciado #end es lo que se escribe en la plantilla si la evaluación resulta en un valor verdadero. En este caso, si $foo es verdadero, la salida será: "Velocity!". De manera análoga, si $foo tiene un valor null, o evalua a falso, entonces el enunciado completo es falso y no se escribe nada.

    Un elemento #elseif ó #else puede utilizarse junto con una sentencia #if para indicar condiciones adicionales o la labor por defecto. Note que el Motor de Plantillas de Velocity parará en la primera expresión que evalue a verdadero. En el ejemplo siguiente suponga que $foo tiene un valor de 15 y $bar tiene un valor de 6.

    Vaya hacía el Norte #elseif( $foo == 10 ) Vaya hacía el Este #elseif( $bar == 6 ) Vaya al Sur #else Vaya al Oeste #end ]]>

    En este ejemplo, $foo es mayor que diez, por lo que las dos primeras comparaciones fallan. A continuación se compara $bar con 6, como son iguales, la salida es Vaya al Sur

    Operadores Lógicos y Relacionales

    Velocity usa el operador de equivalencia para determinar las relaciones entre las variables. A continuación hay un ejemplo sencillo para ilustrar como se utiliza el operador de igualdad.

    Velocity tiene también operadores lógicos para el Y, el O y el NO (AND, OR y NOT). Para mayor información vea la Guía de Referencia VTL. A continuación se encuentran ejemplos que demuestran la utilización de los operadores lógicos AND, OR y NOT.

    Esto Y aquello #end ]]>

    La directiva #if() solamente evaluará a verdadero si tanto $foo como $bar son ciertos. Si $foo es falso la expresión evaluará a falso; $bar no será evaluada. Si $foo es verdadero el Motor de Plantillas de Velocity verificará el valor de $bar; si $bar es cierto, entonces toda la expresión es cierto y la salida es Esto Y aquello. Si $bar es falso, entonces no habrá ninguna salida porque toda la expresión es falsa.

    El O lógico trabaja de la misma manera, pero sólo una de las referencias debe evaluar a verdadero para que toda la expresión evalue a verdadero. Considere el ejemplo siguiente.

    Esto O Aquello #end ]]>

    Si $foo es verdadero, el Motor de Plantillas de Velocity no necesita consultar $bar,; sin importar si $bar es cierto o falso, la expresión será cierta, y Esto O Aquello será la salida. Si $foo es falso, en cambio, es necesario verificar $bar. En este caso, si $bar es falso, entonces la expresión es falsa y no se escribe nada. De otro lado, si $bar es verdadero, entonces toda la expresión es verdadera y el resultado es Esto O Aquello

    Con el operador lógico NO, solo hay un argumento :

    eso NO #end ]]>

    Aquí si $foo es cierto, entonces !$foo es falso, y no se escribe nada. Por el contrario, si $foo es falso, entonces !$foo será verdadero y eso NO será escrito. Tenga cuidado de no confundir este operador con la referencia sileciosa $!foo, que es algo completamente distinto.

    Ciclo Foreach

    El elemento #foreach permite la construcción de ciclos. Por ejemplo:

    #foreach( $producto in $todosProductos )
  • $producto
  • #end ]]>

    Este cilco #foreach hace que el objeto correspondiente a la lista de $todosProductos sea iterado buscando todos los productos de la lista. En cada iteración del ciclo, el valor de $todosProductos se asigna a la variable $producto.

    El contenido de la variable $todosProductos es un Vector, una tabla de Hashing (Hashtable) o un arreglo (Array). El valor asignado a la variable $producto es un objeto Java y se puede referenciar desde una variabkle como tal. Por ejemplo, si $product fuera realmente un elemento de la clase Producto en Java, su nombre se podría obtener referenciando el método $producto.Nombre (ie: $Product.getName()).

    Ahora supongamos que $todosProductos es una tabla de Hashing. Si usted quisiera recuperar los valores de las llaves de la tabla de Hashing, al igual que los objetos dentro de esta, usted podría utilizar código como el siguiente:

    #foreach( $llave in $todosProductos.keySet() )
  • Llave: $llave -> Valor: $todosProductos.get($llave)
  • #end ]]>

    Velocity proporciona una manera sencilla de obtener el contador del ciclo para que usted pueda hacer algo como lo siguiente:

    #foreach( $cliente in $listaClientes ) $foreach.count$cliente.Nombre #end ]]>

    El elemento de script #include le permite al diseñador de plantillas importar un archivo local, que después es insertado en la localización donde se encuentra la sentencia #include. Los contenidos del archivo no se muestran por intermedio del motor de plantillas por lo que si se hacen referencias dentro del archivo, estas no serán reemplazadas. Por motivos de seguridad el archivo que va a ser incluido debe encontrarse en el directorio indicado por la propiedad TEMPLATE_ROOT.

    El archivo al que se refiere la directiva #include se encierra entre comillas. Si mas de un archivo será incluido, los nombres de los archivos a incluir deben ir separados por comas.

    El archivo a incluir no tiene que ser referenciado por nombre, de hecho, muchas veces es preferible usar una variable, en lugar de un nombre de archivo. Esto puede ser útil para dirigir la salida de acuerdo a criterios determinados cuando la solicitud de la página es enviada, es decir, que dependa de factores como los datos del usuario que visita la página, el momento del día, etc. A continuación se muestra un ejemplo en el que se usan tanto un nombre como una variable.

    El elemento de script #parse le permite al diseñadore de plantillas importar un archivo local que contiene VTL. Velocity procesará el VTL y mostrará la plantilla especificada.

    Al igual que la directiva #include, #parse puede utilizar una variable, en lugar de una plantilla. Todas las plantillas a las que #parse se refiera deben incluirse bajo TEMPLATE_ROOT. A diferencia de la directva #include, #parse solo recibe un argumento.

    Las plantillas de VTL puede tener sentencias #parse que se refieran a plantillas que a su vez tengan sentencias #parse. La línea parse_directive.maxdepth del archivo velocity.properties, cuyo valor por defecto es 10, permite a los usuarios configurar el máximo número de referencias a #parse que pueden ocurrir desde una única plantilla. (Nota: Si la propiedad parse_directive.maxdepth no esta dentro del archivo velocity.properties, Velocity establecerá el valor por defecto en 10.) La recursión esta permitida, por ejemplo, si la plantilla hacerfoo.vm contiene las siguientes líneas:

    Hay una referencia a la plantilla parsefoo.vm, que contiene el siguiente código VTL:

    0 ) #parse( "parsefoo.vm" ) #else Listo parsefoo.vm! #end ]]>

    Después de que se muestra "Cuenta Regresiva.", Velocity pasa por parsefoo.vm, contando hacía abajo desde 8. Cuando el conteo llegue a 0, mostrará el mensaje "Listo parsefoo.vm!". En este punto Velocity volverá a dofoo.vm y escribirá el mensaje "Listo hacerfoo.vm!".

    El elemento de script #stop permite al diseñador parar la ejecución del motor de plantillas y volver. Esto es útil para propósitos de corrección de errores.

    El elemento de script #macro script permite definir un segmento de plantilla VTL repetitivo. Los Velocimacros son muy útiles en una amplia gama se situaciones, tanto simples como complejas. El siguiente Velocimacro, creado con el único propósito de ahorrar tecleo y minimizar errores tipográficos, provee una introducción al concepto de Velocimacros element allows template designers to.

    #end ]]>

    El Velocimacro que se define en este ejemplo es d, y se puede llamar de manera similar a cualquier otra directiva VTL:

    Cuando esta plantilla sea solicitada, Velocity reemplazará #d() por una fila conteniendo un única celda vacia.

    Un Velocimacro puiede tomar cualquier número de argumentos -- no tener ningún argumento, como se mostró en el primer ejemplo, es una opción -- pero cuando sea invocado el Velocimacro debe ser llamado con el mismo número de argumentos con el que fue definido. Muchos Velocimacros se relacionan con el entorno mucho más con su entorno que el ejemplo demostrado anteriormente. Aquí hay un Velocimacro que recibe dos argumentos, un color y un arreglo.

    $algo #end #end ]]>

    El Velocimacro que se define en este ejemplo, filastabla, toma dos argumentos. El primer argumento toma el lugar de $color, y el segundo argumento el de $algunalista

    Cualquier cosa que se pueda incluir dentro de una plantilla VTL puede formar parte delcuerpo de un Velocimacro. El Velocimacro filastabla es una sentencia foreach. Hay dos sentencias #end dentro del Velocimacro; la primera pertenece al foreach y a segunda termina la definición del Velocimacro.

    #filastabla( $color $grandeslagos ) ]]>

    Note que $grandeslagos toma el lugar de $algunalista. Cuando el Velocimacro es llamado en esta situación, la siguiente salida es generada:

    Superior Michigan Huron Erie Ontario ]]>

    Los Velocimacro pueden ser definidos inline dentro de una plantilla. Esto quiere decir que la definición del macro no esta disponible para otras plantillas dentro del mimso sitio Web. Definir un Velocimacro de tal forma que sea compartido por todas las plantillas tiene ventajas obvias: Reduce la necesidad de redefinir el macro en varias plantillas, ahorrando trabajo y disminuyendo las posiblidades de error, además de asegurar que un único cambio en un archivo quedará disponible para todas las plantillas.

    Si el Velocimacro #filastabla($color $lista) fuera definido en una librería, se podría utilizar en cualquiera de la plantillas normales; se podría utilizar muchas veces con propósitos distintos. En la plantilla vegetal.vm dedicado a todas las plantas, el Velocimacro #filastabla podría invocarse para listar las partes de un vegetal típico:

    #filastabla( $colorCelda $parts ) ]]>

    Cuando atendiera ls solicitud de vegetal.vm, Velocity encontraría el macro #filastabla en la librería de plantillas (definida en el archivo velocity.properties) y generaría el siguiente resultado:

    raíz tallo hojas flores frutos ]]> Argumentos de un Velocimacro

    Los Velocimacros pueden recibir como argumentos cualquiera de los siguientes elementos de VTL:

    • Referencia : cualquier cosa que comience con '$'
    • Cadena de caracteres : algo como "$foo" u 'hola'
    • Número : 1, 2 etc
    • Rango de enteros : [ 1..2] ó [$foo .. $bar]
    • ObjectArray : [ "a", "b", "c"]
    • El valor booleano "verdadero"
    • El valor booleano "falso"

    Cuando pase referencias como argumentos para los Velocimacros tenga en cuenta que las referencias se pasan 'por nombre'. Esto quiere decir que su valor es 'generado' cada vez que se usa dentro del Velocimacros. Esta característica le permite pasar referencias con las llamadas de método y hacer que el método se llame cada vez. Por ejemplo, cuando llame el siguiente Velocimacro

    Esa llamada hace que el método bar() de la referencia $foo sea llamado 3 veces.

    A primera vista, esta característica parece sorprendente, pero cuando se tiene en cuenta la motivación original de los Velocimacros -- eliminar la duplicación de "copiar y pegar" del VTL usado varias veces -- tiene mucho sentido. Permite pasar al Velocimacro objetos con estado, como un objeto que genera colores en una secuencia repetitiva para colorear las filas de una tabla.

    Si usted no desea utilizar esta característica siempre es posible simplemente obtener el valor del método como una nueva referencia y pasar ese valor:

    Propiedades de un Velocimacro

    Varias líneas en al archivo velocity.properties permiten flexibilizar la implementación de los Velocimacro. Tenga en cuenta que estas propiedades también están documentadas en la Guía de Desarrolladores.

    velocimacro.library - Una lista, separada por comas de todas la librerias de plantillas de Velocimacros. Por defecto, Velocity busca una sola librería: VM_global_library.vm. El directorio en el que se buscan las plantillas también se utiliza para localizar las librerías.

    velocimacro.permissions.allow.inline - Esta propiedad, que tiene como valores posibles verdadero y falso (true y false), determina si los Velocimacros pueden ser definidos dentro de las plantillas normales. El valor por defecto, verdadero, le permite a los diseñadores definir por si mismos macros en las plantillas.

    velocimacro.permissions.allow.inline.to.replace.global - Con valores posibles verdadero y falso (true y false), esta propiedad le permite al usuario decidir si un Velocimacro definido inline dentro de una plantilla puede reemplazar a la plantilla global, que fue cargada al comienzo por medio de la propiedad velocimacro.library. El valor por defecto, falso (false), evita que los Velocimacros definidos en una plantilla reemplacen a los que fueron cargados al inicio.

    velocimacro.permissions.allow.inline.local.scope - Con valores posibles verdadero y falso (true y false), valor por defecto falso, esta propiedad dice si los Velocimacros definidos inline son 'visibles' únicamente para la plantilla que los define. Usted puede usar esta característica para hacer algunos trucos de VM - si un VM global llama a otro VM global, con ancance inline, una plantilla puede definir una implementación privada del segundo VM, que será llamada por el primer VM cuando sea invocado en esa plantilla. Ninguna de las otras templates es afectada.

    velocimacro.library.autoreload - Esta propiedad controla el cargado automático de la libreria de Velocimacros. El valor por defecto es false. Cuando es verdadero (true) la librería fuente de un Velocimacro que ha sido invocado será verificada para comprobar que no haya cambiado, y si lo ha hecho será recargada. Esta característica le permite cambiar y probar librerías de macros sin necesidad de reiniciar la aplicación o el contenedor de servlets, de la misma manera que se hace con plantillas normales. Este modo solo funciona cuando el caché esta apagado en los cargadores de recursos( e.g. file.resource.loader.cache = false). Esta característica esta pensada para el proceso de desarrollo, no el de producción. This property

    Cosas y Casos de Velocimacros

    Actualmente los Velocimacros deben ser definidos antes de ser utilizados por primera vez dentro de una plantilla. Esto significa que sus declaraciones de #macro() deben aparecerantes de que usted utilice los Velocimacros.

    Esto es importante recordarlo cuando usted intenta hacerle #parse() a una plantilla que contiene directivas #macro(). Como el #parse() ocurre en tiempo de ejecución, y el parser decide si un elemento que parece una VM es realmente un VM cuando esta haciendo el #parse(), entonces probablemente el #parse() de un conjunto de declaraciones no funciona como se esperaría. Para evitar este problema, simplemente utilice la propiedad velocimacro.librarypara cargar todos sus VM cuando se inicie la aplicación.

    Las directivas de VTL se pueden escapar con el palote invertido o backslash ("\") de manera similar a como se escapan las referencias de VTL válidas.

    #include( "a.txt" ) ## \#include( "a.txt" ) se muestra como #include( "a.txt" ) \#include( "a.txt" ) ## \\#include ( "a.txt" ) se muestra como \ \\#include ( "a.txt" ) ]]>

    Se debe tener especial cuidado cuando se escapan directivas de VTL que contienen varios elementos de script en una misma directiva (como en las sentencias if-else-end). A continuación seencuentra un ejemplo de un condicional típico de VTL:

    Si $jazz es cierto la salida es

    Si $jazz es fals, no hay salida. Escapar elementos de script altera la salida. Considere el siguiente caso:

    Sin importar si $jazz es verdadero o falso, la salida será:

    De hecho, como todos los elementos de script están escapados, $jazz nunca se evalúa por su valor booleano. Suponga que los palotes invertidos preceden a elementos de script que están legitimamente escapados:

    En este caso, si $jazz es verdadero, la salida es

    Para entender esto tenga en cuenta que #if( arg ), cuando es terminado por un caracter de fin de línea (retorno) omitirá ese caracter de la salida. Por lo tanto, el cuerpo del bloque #if() va a continuación del primer '\', que se generó a partir del '\\' que precedía el #if() dentro de la pantilla. El último \ está en una línea distinta que el texto porqué hay un retorno después de 'Ganelin', por lo que el \\ final, que precede el #end hace parte del cuerpo del bloque.

    Si $jazz es falso, la salida es

    Tenga en cuenta que las cosas dejan de funcionar si los elementos de script no son escapados de manera correcta.

    Aquí el #if esta escapado, pero hay un #end que sobra; al haber demasiados cierres (end) sin sus correspondientes aperturas (foreach ó if) se generará un error de procesamiento.

    A pesar de que el VTL mostrado en esta guía del usuario se muestra en la mayoría de los casos con cambios de línea y espacios en blanco, el VTL que se muestra a continuación

    es tan válido como el siguiente trozo de código que Geir Magnusson Jr. publicó a la lista de correo de usuarios de Velocity para ilustrar un punto sin ninguna relación:

    El comportamiento de Velocity es el de ingnorar el espacio vacío de exceso. La directiva descrita anteriormente puede reescribirse como:

    o como

    En cada caso la salida será la misma

    Velocity tiene varias funciones matemáticas incluidas que pueden ser utilizadas en plantillas con la directiva set. Las siguientes ecuaciones son ejemplos de suma, resta, multiplicación y división respectivamente:

    Cuando una operación de división se realiza entre dos operandos enteros, el resultado será un valor entero, correspondiente al valor truncado de la división. El valor del resto puede obtenerse utilizando el operador módulo (%).

    El operador de rango se puede usar en conjunción con las directivas #set y #foreach. Es muy útil por su capacidad para crear arreglos de objetos compuestos por enteros. La construcción del operador rango es como sigue:

    Tanto n como m debe ser o producir enteros. El hecho de que m sea mayor o menor que n no importa; en ese caso el rango cimplemente contará hacía abajo. A continuación se muestran varios ejemplos de uso del operador rango:

    Produce lo siguiente:

    enga en cuenta que el operador de rango solamente produce un arreglo cuando se utiliza junto con las directivas #set y #foreach, como se demuestra en el cuarto ejemplo.

    Los diseñadores de páginas preocupados con hacer los tamaños de las tablas iguales, pero con información que puede no se suficiente para llenar la tabla, encontrarán el operador de rango particularmente útil.

    Cuando una referencia se hace silenciona con el caracter ! y el caracter ! viene precedido por un caracter de escape \ la referencia se maneja de una manera diferente. Observe las diferencias entre el escape sencillo y el caso especial en el que \ precede a !:

    Se muestra como:

    A diferencia del escape normal, donde \ precede a $:

    Se muestra como:

    Esta sección contiene un conjunto de preguntas frecuentes (FAQ) relacionadas con Velocimacros. Esta sección cambiará con el tiempo, por lo que es bueno revisar si hay información nueva de cuando en cuando.

    Nota : A través de esta sección 'Velocimacro' será abreviado como 'VM'.

    ¿Puedo usar una directiva u otro VM como argumento para un VM?

    Ejemplo : #center( #bold("hola") )

    No. Una directiva no es un argumento válido para una directiva y, para la mayoría de los propósitos prácticos, un VM es una directiva.

    Sin embargo..., hay cosas que usted puede hacer. Una solución sencilla es aprovechar el hecho de que la doble comilla (") muestra sus contenidos, por lo que usted puede hacer algo como

    Puede tener un paso...

    Tenga en cuenta que en segundo ejemplo el argumentos es evaluado dentro de la VM, no a nivel del llamador. En otras palabras, el argumento para el VM es pasado completo y evaluado dentro del VM al que se le pasa. Esto le permite hacer cosas como :

    Donde la salida es

    la evaluación de "#interno($bar)" se lleva a cabo dentro de #externo(), por lo que el valor $bar establecido dentro de #externo() es el que se utiliza.

    Estas es una característica intencional y celosamente protegina - los argumentos se pasan por nombre a los VM para que usted le pueda 'entregar' a los VMs referencias con estado como

    Hola Todos #end #foo( $bar.colorFila() ) ]]>

    Y lograr que colorFila() se llame varias veces, en lugar de solo una. Par evitar que eso ocurra invoque el método fuera del VM y pásele el valor al VM.

    ¿Puedo registrar Velocimacros por medio de #parse() ?

    Actualmente, los Velocimacros deben ser definidos antes de ser usados por primera vez dentro de una plantilla. Esto significa que sus declaraciones de #macro() deben venir antes de que usted use los Velocimacros.

    Esto es importante recordarlo cuando usted intenta hacerle #parse() a una plantilla que contiene directivas #macro(). Como el #parse() ocurre en tiempo de ejecución, y el parser decide si un elemento que parece una VM es realmente un VM cuando esta haciendo el #parse(), entonces probablemente el #parse() de un conjunto de declaraciones no funciona como se esperaría. Para evitar este problema, simplemente utilice la propiedad velocimacro.librarypara cargar todos sus VM cuando se inicie la aplicación.

    ¿Qué es la auto recarga de Velocimacros?

    Existe una propiedad, pensada para usarse en desarrollo, no en producción :

    velocimacro.library.autoreload

    que tiene como valor por defecto falso. Cuando se hace verdadera junto con <tipo>.resource.loader.cache = false (where <tipo> es el nombre del cargador de recursos que usted esta utilizando, como 'file' para archivos) entonces el motor de Velocity recargará automáticamente los cambios en su librerías en el momento en que los haga para que usted no tenga que reinicar el motor de servlets o la aplicación, o hacer otros trucos para lograr que sus Velocimacros se recarguen.

    A continuación se muestra un conjunto sencillo de propiedades de configuración.

    No utilice esto en producción

    Una pregunta común que los desarrolladores formulan es ¿Cómo concateno cadenas de caracteres? ¿Existe algún análogo al operador '+' en Java?

    Para concatenar referencias en VTL usted solo tiene que 'ponerlos juntos'. El contenido del contexto en donde usted desee juntar las referencias es importante, por lo que ilustraremos con algunos ejemplos.

    En el código regular de una plantilla (cuando usted lo mezcla con contenido normal)

    y la salida será 'El reloj es BigBen'. Para caso más interesantes, como cuando ested desea concatenar las cadenas que pasará a un método, o establecer el valor de una nueva referencia use

    Que resultará en la mismo que el ejemplo anterior. Como un ejemplo final, cuando usted desea mezclar cadenas 'estáticas' con sus referencias usted puede necesitar 'referencias formales':

    Ahora el resultado es 'El reloj es BigAltoBen'. La notación formal es necesaria para que el procesador de las plantillas sepa que usted quiso usar la referencia '$tam', en lugar de '$tamAlto', que sería lo que entendería si los corchetes '{}' no estuvieran presentes.

    Si encuentra algún error en este manual o tiene algún otro comentario o retroalimentación relacionada con la guía del usuario de Velocity, por favor envie un correo a La lista de usuarios de Velocity. Gracias!

    velocity-1.7/xdocs/docs/translations/user-guide_fr.xml0000644000175000017500000024142511156517252023167 0ustar moellermoeller Guide de l'utilisateur Velocity Velocity Documentation Team John Castura Jean-François El Fouly Claude Brisson
    1. A propos de ce document
    2. Velocity, qu'est-ce que c'est?
    3. Qu'est-ce que Velocity peut faire pour moi?
      1. L'exemple de MudStore
    4. Introduction au Velocity Template Language (VTL)
    5. Hello Velocity World!
    6. Les commentaires
    7. Les références
      1. Variables
      2. Propriétés
      3. Méthodes
      4. Règles de recherche des méthodes
      5. Rendu
    8. Références formelles
    9. Références silencieuses
    10. Mode de notation stricte des références
    11. Substitution de cas
    12. Directives
      1. Set
      2. Chaînes de caractères littérales
      3. Conditions
        1. Opérateurs relationnels et logiques
      4. Boucles
      5. Include
      6. Parse
      7. Stop
      8. Evaluate
      9. Define
      10. Velocimacros
    13. Sortie littérale
      1. Devise
      2. Echapper des références VTL valides
      3. Echapper des références VTL invalides
      4. Echappement des directives VTL
    14. VTL: Questions de format
    15. Autres caractéristiques et sujets divers
      1. Math
      2. Opérateur de portée (range)
      3. Questions pointues: Echappement et !
      4. Compléments divers sur les Velocimacros
      5. Concaténation de chaînes
    16. Donnez votre avis

    Le Guide de l'utilisateur Velocity a pour but d'aider les concepteurs de page et les fournisseurs de contenu à se familiariser avec Velocity et avec la syntaxe de son langage de script, simple mais puissant, le Velocity Template Language (VTL). Beaucoup d'exemples dans ce guide concernent l'utilisation de Velocity pour l'inclusion de contenu dynamique dans des sites web, mais tous les exemples du VTL pourraient aussi bien s'appliquer à d'autres pages ou gabarits.

    Merci de choisir Velocity !

    Velocity est un moteur de substitution, basé sur Java. Il permet aux concepteurs de pages web de faire référence à des méthodes définies dans du code Java. Les concepteurs de pages peuvent travailler en équipe avec des programmeurs Java pour développer des sites web dans l'architecture MVC (Modèle-Vue-Contrôleur), ce qui signifie que les infographistes peuvent se concentrer sur la création d'un site au désign attractif et les programmeurs peuvent se consacrer entièrement à l'écriture de code de qualité. Velocity sépare le code Java des pages web, ce qui rend le site plus facile à maintenir dans le long terme et fournit une alternative réaliste aux Java Server Pages (JSPs) ou à PHP.

    Velocity peut être utilisé pour générer des pages web, du SQL, du Postcript et tout ce qui peut être généré à partir d'un gabarit. Vous pouvez l'utiliser comme un utilitaire indépendant pour générer du code source ou des états imprimés, ou bien comme un composant intégré dans d'autres systèmes. A terme, Velocity fournira les services d'inclusion pour le framework d'applications web Turbine. Velocity et Turbine fournissent un service d'inclusion qui permettra de développer des applications web dans une véritable architecture MVC.

    Supposons que vous soyez un concepteur de pages pour une boutique en ligne spécialisée dans la vente de terre cuite. Appelons-la "The Online Mud Store". Les affaires marchent fort. Les clients passent commande pour différents types et diverses quantités de terre cuite. Ils s'identifient sur votre site avec un nom d'utilisateur et un mot de passe, ce qui leur permet de suivre leurs commandes et d'en passer de nouvelles. Pour l'instant, vous vendez de la glaise Terracotta, un produit qui marche bien. Quelques-uns de vos clients achètent régulièrement de la glaise Bright Red, que vous vendez aussi, bien sûr, mais qui n'a pas autant la cote et qui se trouve d'habitude reléguée dans les marges de vos pages. Les informations relatives à chaque client sont suivies dans votre base de données, et donc un jour la question se pose: pourquoi ne pas utiliser Velocity pour proposer des offres spéciales à une clientèle ciblée, celle qui est la plus intéressée à un type de marchandise?

    Avec Velocity, il est très facile de personnaliser les pages web pour certains visiteurs. En tant que concepteur de pages du MudRoom, vous voulez maintenant réaliser la page d'accueil que verra votre client après s'être identifié sur votre site.

    Vous tenez une réunion avec les ingénieurs développement de votre entreprise, et tout le monde s'accorde sur le fait que $customer contiendra les informations relatives au client qui s'est connecté et $mudsOnSpecial tous les types de terre disponibles à la vente en ce moment. L'objet $flogger contient différentes méthodes pour aider à la promotion de certains produits. Pour la tâche qui nous concerne, occupons-nous seulement de ces trois références. Rappelez-vous que vous n'avez pas à vous soucier de la manière dont les développeurs vont extraire les informations nécessaires de la base de données, vous supposez seulement que ça fonctionne -- ce qui vous permet de vous occuper de votre part du boulot et les développeurs de la leur.

    Vous pouvez inclure l'instruction VTL suivante dans votre page web:

    Hello $customer.Name! #foreach( $mud in $mudsOnSpecial ) #if ( $customer.hasPurchased($mud) ) #end #end
    $flogger.getPromo( $mud )
    ]]>

    Les détails précis de l'instruction foreach seront décrits un peu plus loin; ce qui compte pour l'instant, c'est l'impact que peut avoir ce petit script sur votre site web. Quand un client qui apprécie habituellement la glaise BrightRed se connecte, et que ce produit est en vente, c'est ce qu'il verra en premier lieu. Si un client qui a acheté beaucoup de Terracotta se connecte, c'est la vente de Terracotta qui sera affichée en tête et au centre. La flexibilité de Velocity est très grande, limitée seulement par votre créativité.

    Dans le manuel de référence du VTL, vous trouverez la documentation de beaucoup d'autres éléments de Velocity, qui ensemble vous donnent la puissance et la souplesse dont vous avez besoin pour faire de votre site web une présence sur le web. Lorsque vous deviendrez de plus en plus familiers avec ces éléments, vous mettrez à votre service toute la puissance de Velocity.

    Le Velocity Template Language (VTL) a été conçu pour inclure du contenu dynamique dans une page web de la manière la plus facile, la plus simple et la plus propre. Même un infographiste avec peu ou pas de bagage en programmation sera rapidement capable d'utiliser le VTL pour incorporer du contenu dynamique dans un site web.

    VTL utilise des références pour embarquer du contenu dynamique dans un site web, et une variable est un type de référence. Une variable fait référence à quelque chose qui est défini dans le code Java, ou elle peut prendre sa valeur d'une instruction VTL dans la page web. Voici un exemple d'instruction VTL

    Cette instruction VTL -- comme toutes les instructions VTL d'ailleurs -- commence par le caractère # et contient une directive set. Quand un visiteur demande votre page web, le moteur de substitution Velocity (Velocity Templating Engine) recherche dans votre page tous les caractères #, détermine lesquels marquent le début d'instructions VTL, et quels caractères # n'ont rien à voir avec le VTL.

    Le caractère #est suivi d'une directive, set. La directive setutilise une expression (entre parenthèses) -- une équation qui assigne une valeurà une variable. La variable est écrite à gauche et sa valeur à droite; les deux sont séparés par un caractère =.

    Dans l'exemple ci-dessus, la variable est $aet la valeur est Velocity. Cette variable, comme toutes les références, commence par le caractère $. Les valeurs sont toujours entourées d'apostrophes; dans Velocity, il n'y a jamais de confusion possible entre les types de données puisque seules des chaînes de caractères (informations de type texte) peuvent être passées à des variables.

    Le truc suivant peut être utile pour mieux comprendre comment Velocity fonctionne :Les références commencent par $ et sont utilisées pour récupérer quelque chose. Les directives commencent par #et sont utilisées pour faire quelque chose.

    Dans l'exemple ci-dessus, #setest utilisé pour assigner une valeur à une variable. La variable, $a, peut alors être utilisée dans le gabarit pour produire "Velocity".

    Une fois qu'une valeur a été assignée à une variable, vous pouvez faire référence à cette variable n'importe où dans votre document HTML. Dans l'exemple suivant, une valeur est assignée à $foo et référencée plus loin.

    #set( $foo = "Velocity" ) Hello $foo World! ]]>

    Le résultat est une page web où s'imprime "Hello Velocity World!".

    Pour rendre les instructions contenant des directives VTL plus lisibles, nous vous encourageons à débuter chaque instruction VTL sur une nouvelle ligne -- mais vous n'êtes pas obligé de procéder ainsi. La directive set sera revue avec davantage de détails plus loin.

    Les commentaires permettent d'inclure du texte descriptif qui ne sera pas reporté dans la sortie du moteur d'inclusion. Les commentaires sont une manière utile de se rappeler et d'expliquer à d'autres ce que font les instructions VTL, ou à toute autre fin utile. Voici un exemple de commentaire en VTL.

    Un commentaire d'une ligne commence par ## et se termine à la fin de la ligne. Si vous voulez écrire quelques lignes de commentaires, pas besoin de multiplier ces commentaires d'une ligne. Les commentaires multi-lignes, qui commencent par #* et se terminent par *#, sont là pour ce cas de figure.

    Voici quelques exemples pour clarifier la manière dont les commentaires d'une et plusieurs lignes fonctionnent:

    Il y a un troisième type de commentaires, le bloc de commentaires VTL, que vous pouvez utiliser pour écrire des informations telles que l'auteur du document ou la version.

    Il y a trois types de références en VTL: les variables, les propriétés et les méthodes. En tant que concepteur utilisant le VTL, vous et vos ingénieurs devez vous mettre d'accord sur les noms des références, de manière à pouvoir les utiliser correctement dans vos gabarits de pages.

    Tout ce qui entre et sort d'une référence est traité comme un objet chaîne de caractères. S'il y a un objet qui représente $foo(un objet Integer par exemple), Velocity appellera sa méthode .toString() pour convertir l'objet en String.

    Variables
    La notation abrégée pour une variable consiste en un caractère "$" initial suivi d'un IdentificateurVTL. Un identificateur VTL doit commencer par une lettre (a .. z ou A .. Z). Le reste des caractères est limité aux types suivants:

    • lettre (a .. z, A .. Z)
    • chiffre (0 .. 9)
    • tiret ("-")
    • trait de soulignement ("_")

    Voici quelques exemples de références valides en VTL:

    Lorsque VTL référence une variable, telle que $foo, la variable peut prendre sa valeur soit d'une directive set dans le gabarit, soit d'un programme Java. Par exemple, si la variable Java $foo a la valeur bar à la ligne à laquelle il est fait appel au gabarit, bar remplace toutes les instances de $foo dans la page web. Autrement, si j'inclus l'instruction

    la sortie sera la même pour toutes les instances de $foo qui suivent cette directive.

    Propriétés
    Les propriétés sont la seconde espèce de références en VTL et elles ont un format qui les distingue. La notation abrégée consiste en un caractère $ initial suivi d'un identifiant VTL, suivi d'un point (".") et d'un autre identifiant VTL. Quelques exemples de références valides de propriétés en VTL:

    Prenons le premier exemple, $customer.Address. Cette expression peut avoir deux significations. Elle peut signifier: "Regarde dans la table de hachage identifiée par customer et renvoie la valeur associée à la clé Address". Mais $customer.Address peut aussi faire référence à une méthode (les références qui désignent des méthodes seront discutées dans la section suivante); $customer.Address pourrait être une manière abrégée d'écrire $customer.getAddress(). Quand quelqu'un demande votre page, Velocity va déterminer laquelle de ces deux possibilités a un sens, et retournera la valeur appropriée.

    Méthodes
    Une méthode est définie dans le code Java et peut faire quelque chose d'utile, comme effectuer un calcul ou prendre une décision. Les méthodes sont des références qui consistent en un caractère "$" initial, suivi d'un identifiant VTL, suivi d'un corps de méthode. Un corps de méthode VTL consiste en un identifiant VTL suivi du caractère parenthèse ouvrante ("("), éventuellement suivi d'une liste de paramètres, suivi du caractère parenthèse fermante (")"). Quelques exemples de références de méthodes valides en VTL:

    Les deux premiers exemples -- $customer.getAddress() et $purchase.getTotal() -- peuvent avoir l'air semblables à ceux utilisés dans la section précédente, consacrée aux Propriétés, $customer.Address et $purchase.Total. Si vous avez deviné que ces exemples sont liés entre eux d'une manière ou d'une autre, vous avez raison!

    Les propriétés VTL peuvent être utilisées comme une notation abrégée pour des méthodes VTL. La propriété $customer.Address a exactement le même effet que l'utilisation de la méthode $customer.getAddress(). Il est généralement préférable d'utiliser une propriété lorsqu'il y en a une de disponible. La principale différence entre les Propriétés et les Méthodes est que pour les méthodes, on peut spécifier une liste de paramètres.

    La notation abrégée peut être utilisée pour les méthodes suivantes

    On s'attend logiquement à ce que ces méthodes retournent les noms des planètes qui tournent autour du soleil, qu'elles nourissent notre ver de terre ou prennent une photo dans un album. Il n'y a que la notation longue qui fonctionne pour les méthodes suivantes:

    Depuis Velocity 1.6, toutes les références à des tableaux sont "magiquement" considérées comme des listes de taille fixe. Cela signifie que vous pouvez appeler les méthodes de java.util.List sur les références contenant des tableaux. Ainsi, si vous avez une référence sur un tableau (mettons que celui-ci soit un tableau de String avec trois valeurs), vous pouvez écrire :

    Autre nouveauté de Velocity 1.6, la reconnaissance des méthodes à nombre variable d'arguments. Une méthode telle que public void setPlanets(String... planets) ou même simplement public void setPlanets(String[] planets) (si vous utilisez une version de Java antérieure au JDK5) peut maintenant accepter un nombre variable d'arguments quand elle est appelée depuis un gabarit.

    Règles de recherche des méthodes
    Comme mentionné plus haut, les propriétés font souvent référence à des méthodes de l'objet parent. Velocity est relativement malin quand il s'agit de déterminer à quelle méthode correspond une propriété demandée. Il essaye différentes alternatives basées sur plusieurs conventions de nommage établies. L'ordre exact de recherche dépend de ce que le nom la propriété commence ou non avec une majuscule. Pour des noms en minuscule, comme $customer.address, la séquence de recherche est :

    1. getaddress()
    2. getAddress()
    3. get("address")
    4. isAddress()
    Pour des noms de propriété en majuscules, comme $customer.Address, c'est légèrement différent :
    1. getAddress()
    2. getaddress()
    3. get("Address")
    4. isAddress()

    Rendu
    La valeur finale résultant de toute référence (que ce soit une variable, une propriété ou une méthode) est convertie en objet String quand elle est intégrée à la sortie finale. S'il y a un objet qui représente $foo (tel qu'un objet Integer), alors Velocity appellera sa méthode .toString() pour résoudre l'objet en une chaîne de caractère.

    Notation formelle des références
    Dans les exemples ci-dessus, nous avons utilisé la notation abrégée pour les références, mais il y a aussi une notation formelle pour les références, illustrée ci-dessous:

    Dans presque tous les cas, vous utiliserez pour les références la notation abrégée, mais dans certains cas la notation formelle est requise pour une exécution correcte.

    Supposons que vous soyez en train de construire dynamiquement une phrase dans laquelle $vice doit être utilisé comme base pour la construction d'un nom de la phrase. Le but est de permettre à quelqu'un de choisir le mot de base et de produire l'un des deux résultats suivants: "Jacques est pyromane" ou "Jacques est cleptomane". L'utilisation de la notation abrégée ne convient pas pour cette tâche. Considérons en effet l'exemple suivant:

    La syntaxe est ici ambiguë, et Velocity suppose que $vicemane, et non $vice, est l'identifiant que vous pensiez utiliser. Ne trouvant pas de valeur pour $vicemane, il renverra $vicemane. L'utilisation de la notation formelle peut résoudre ce problème.

    Cette fois Velocity sait que $vice, et non $vicemane, est la référence. La notation formelle est souvent utile quand les références sont directement adjacentes à du texte au sein d'un gabarit.

    Notation silencieuse des références
    Lorsque Velocity rencontre une référence non définie, son comportement normal est de produire une image de la référence. Par exemple, supposons que la référence suivante apparaisse dans un gabarit VTL:

    ]]>

    Quand le formulaire est chargé pour la première fois, la variable référencée par $email n'a pas de valeur, mais vous préfèreriez un champ de texte vide à la valeur "$email". L'utilisation de la notation silencieuse contourne le comportement normal de Velocity; au lieu d'utiliser $email dans le code VTL, utilisez $!email. L'exemple précédent ressemblerait donc à ceci:

    ]]>

    A présent, quand le formulaire est chargé pour la première fois et que $email n'a toujours pas de valeur, une chaîne vide sera produite au lieu de "$email".

    La notation formelle et la notation silencieuse peuvent être utilisées ensemble, comme illustré ci-dessous.

    ]]>

    Velocity 1.6 introduit le concept de références strictes, qui est activé en mettant à true le paramètre de configuration Velocity runtime.references.strict. Dans cette configuration les références doivent être soit placées explicitement dans le contexte, soit définies avec une directive #set, sinon Velocity jettera une exception. Les références qui sont dans le contexte avec une valeur nulle ne produiront pas d'exception. De plus, si une tentative est faite d'appeler une méthode ou une propriété sur un objet contenu dans une référence qui ne définit pas cette méthode ou cette propriété, alors Velocity jettera une exception. Cela reste vrai pour une tentative d'appeler une propriété ou une méthode sur une valeur nulle.

    Dans les exemples suivants $bar est défini mais pas $foo, et toutes ces expressions jetteront une exception :

    Les expressions suivantes montrent des exemples pour lesquels Velocity jettera une exception lors d'une tentative d'appel à des méthodes ou propriétés qui n'existent pas. Dans ces exemples, $bar contient un objet définissant la propriété foo qui renvoie une chaîne de caractères, et la propriété retnull qui renvoie null.

    En général ce comportement de référence stricte est vrai pour toutes les situations dans lesquelles des références sont utilisées excepté dans un cas spécifique à l'intérieure de la directive #if. Si une référence est utilisée à l'intérieur d'une directive #if ou #elseif sans méthode ou propriété, et si elle n'est pas en train d'être comparée à une autre valeur, alors les références indéfinies sont autorisées. Ce comportement fournit un moyen simple de tester si une réference est définie avant de l'utiliser dans un gabarit. Dans l'exemple suivant, ou $foo n'est pas définit, les expressions ne produiront pas d'exceptions:

    Une remarque supplémentaire : les références à des macros indéfinies jetteront également une exception.

    Maintenant que les références vous sont familières, vous pouvez commencer à les mettre en pratique dans vos propres gabarits. Les références, dans Velocity, tirent avantage de certains principes Java que les concepteurs de gabarits vont trouver commodes. Par exemple:

    Ces exemples illustrent différentes manières d'utiliser les mêmes références. Velocity tire parti de l'introspection Java et des caractéristiques des beans pour résoudre les noms de référence en objets du contexte et aussi en leurs méthodes. Il est possible d'inclure et d'évaluer des références à peu près partout dans votre gabarit.

    Velocity utilise comme modèles les spécifications des Beans telles qu'elles ont été définies par Sun Microsystems; il est donc sensible à la casse (majuscules/minuscules); les développeurs se sont toutefois battus pour intercepter et corriger les erreurs des utilisateurs chaque fois que c'est possible. Lorsque la méthode getFoo() est référencée dans un gabarit par $bar.foo, Velocity essayera d'abord $getfoo. Si ceci échoue, Velocity essayera $getFoo. De même, si un gabarit fait référence à $bar.Foo, Velocity essayera d'abord $getFoo() et ensuite getfoo().

    Note: Dans un gabarit, les références à des variables d'instance ne sont pas résolues. Il n'y a que les références équivalentes aux attributs des accesseurs (getter / setter) des JavaBeans qui sont résolues (autrement dit $foo.Name est résolu par l'appel de la méthode d'instance getName() de la classe Foo, mais pas en une variable d'instance publique Name de cette classe Foo).

    Les références permettent aux concepteurs de pages de générer du contenu dynamique pour des sites web alors que les directives -- des éléments de script, faciles à utiliser, qui peuvent être mis en oeuvre pour manipuler de manière créative la sortie d'un code Java -- permet aux concepteurs de vraiment prendre en charge l'apparence et le contenu du site web.

    Les directives commencent toujours par un #. Comme les références, le nom des directives peut être entouré par des accolades { et }. C'est utile quand les directives sont immédiatement suivies par du texte. Par exemple, l'expression suivante produit une erreur :

    Dans ce cas, il faut utiliser des accolades pour séparer le #else du reste de la ligne :

    #set

    La directive #set s'utilise pour donner une valeur à une référence. Une valeur peut être assignée soit à une référence de type variable, soit à une référence de type propriété, et ceci toujours entre parenthèses, comme montré ici:

    Le côté gauche (left hand side -- LHS) de l'assignation doit être une référence variable ou propriété. Le membre de droite (right hand side -- RHS) peut être de l'un des types suivants:

    • Une variable
    • Une chaîne de caractères littérale
    • Une propriété
    • Une méthode
    • Un nombre littéral
    • Une liste
    • Un dictionnaire

    Les exemples suivants montrent chacun des types susmentionnés:

    NOTE: Pour l'exemple de la liste, les éléments définis avec l'opérateur [..] sont accessibles en utilisant les méthodes définies dans la classe ArrayList. Ainsi, par exemple, on peut accéder au premier élément en écrivant $monkey.Say.get(0)

    De même, pour l'exemple du dictionnaire, les éléments définis avec l'opérateur { } sont accessibles en utilisant les méthodes définies dans la classe Map. Ainsi, par exemple, on peut accéder au premier élément en écrivant $monkey.Map.get("banana") pour retourner la chaîne 'good', ou même $monkey.Map.banana pour retourner la même valeur.

    Le membre de droite peut aussi être une expression arithmétique simple:

    Si le membre de droite est une référence à une méthode ou à une propriété dont la valeur est null, il ne sera pas affecté au membre de gauche. Il n'est pas possible d'enlever une référence existante du contexte par ce biais-là. Ceci peut troubler les débutants en Velocity. Par exemple:

    Si $query.criteria("name") renvoie la chaîne "bill", et que $query.criteria("address") renvoie null, le code VTL ci-dessus sera rendu de la manière suivante:

    Ceci induit en confusion les nouveaux venus, qui construisent des boucles #foreach qui tentent de faire un #set sur une référence à partir d'une référence à une propriété ou une méthode et testent immédiatement cette référence avec une directive #if. Par exemple:

    Dans l'exemple ci-dessus, il ne serait pas avisé de se reposer sur l'évaluation de $result pour déterminer si une requête a été couronnée de succès. Une fois que $result a reçu une valeur par un #set (et a donc été ajouté au contexte), il ne peut pas recevoir la valeur null (et se trouver ainsi enlevé du contexte). Les détails des directives #if et #foreach sont traités plus loin dans ce document.

    Une solution à ce problème serait de pré-positionner $result à false. Si l'appel à $query.criteria() échoue, il est possible de faire la vérification.

    Contrairement à d'autres directives Velocity, la directive #set n'a pas d'instruction #end.

    Chaînes de caractères littérales

    Lorsque vous utilisez la directive #set, les chaînes de caractères littérales délimitées par des guillements sont interprétées et rendues de la manière suivante:

    La sortie produite sera

    Toutefois, lorsque la chaîne de caractères littérale est délimitée par des apostrophes, elle n'est pas interprétée.

    Ce qui est rendu de la manière suivante:

    Cette caractéristique d'utilisation des apostrophes pour rendre du texte non interprété est le comportement par défaut de Velocity. Ce comportement peut être changé en éditant le fichier velocity.properties et en y écrivant l'entrée: stringliterals.interpolate=false.

    Également, la directive #[[ ]]# permet au concepteur de gabarits de facilement utiliser de gros morceaux de contenu non interprété de code VTL. Ceci peut être particulièrement utile en remplacement de multiples échappements de directives.

    Sera rendu comme :

    If / ElseIf / Else

    La directive #if de Velocity permet à du texte d'être inclus à la génération d'une page web seulement si la condition qui suit l'instruction if est vérifiée. Par exemple:

    Velocity! #end ]]>

    La variable $foo est évaluée pour déterminer si elle vaut true, ce qui se produit dans l'une des deux cas suivants; (i) $foo est une variable booléenne (true/false) dont la valeur est vrai (true), ou (ii) la valeur de $foo est différente de null. On se rappelle que le contexte de Velocity ne contient que des Objets, et donc lorsqu'on dit un booléen, il sera représenté comme un objet de la classe Boolean contenant la valeur logique appropriée.

    Ce qui est contenu entre l'instruction #if et l'instruction #end sera produit en sortie si la condition est évaluée comme vraie. Dans l'exemple précédent, si $foo est true, la sortie sera: "Velocity!". A l'inverse, si $foo a la valeur null, ou si c'est un booléen de valeur false, l'instruction est évaluée comme fausse, et il n'y a pas de sortie produite.

    Un élément #elseif ou #else peut être utilisé dans la directive #if. Notez que le moteur Velocity (Velocity Template Engine) s'arrêtera à la première expression évaluée comme vraie. Dans l'exemple suivant, supposons que $foo vaut 15 et que $bar vaut 6.

    Go North #elseif( $foo == 10 ) Go East #elseif( $bar == 6 ) Go South #else Go West #end ]]>

    Dans cet exemple, $foo est plus grand que 10, donc les deux premières comparaisons échouent. Ensuite, $bar est comparé à 6, ce qui donne vrai, et dont la sortie produit est Go South.

    Opérateurs logiques et relationnels

    Velocity utilise l'opérateur d'équivalence pour déterminer les relations entre des variables. Voici un exemple simple pour illustrer la manière d'utiliser l'opérateur d'équivalence.

    Velocity a aussi des opérateurs ET, OU et NON. Pour plus d'informations, référez-vous au VTL Reference Guide (en anglais). Ci-dessous, quelques exemples illustrent l'utilisation des opérateurs logiques ET, OU et NON.

    Ceci ET cela. #end ]]>

    La directive #if() ne sera évaluée comme true que si $foo et $bar sont true tous les deux. Si $foo est false, l'expression sera globalement évaluée comme false et $bar ne sera pas évalué. Si $foo vaut true, le moteur Velocity testera la valeur de $bar; si $bar vaut true, alors l'expression dans son entièreté vaut true et la sortie Ceci ET cela est produite. Si $bar est false, alors il n'y aura pas de sortie produite puisque l'expression entière est fausse.

    Les opérateurs logiques OU fonctionnent de la même manière, si ce n'est qu'une seule des références doit être évaluée à true pour que l'expression entière soit considérée comme vraie. Voyez l'exemple suivant:

    Ceci OU cela #end ]]>

    Si $foo vaut true, le moteur Velocity n'a pas besoin d'évaluer $bar; que $bar soit vrai ou faux ne change rien à l'affaire, l'expression sera vraie, et Ceci OU cela sera produit en sortie. Mais si $foo est false, la valeur de $bar doit être vérifiée. Dans ce cas, si $bar est faux lui aussi, l'expression sera fausse et il n'y aura pas de sortie produite. Sinon, si $bar est vrai, alors l'expression entière est vraie, et la sortie est Ceci OU cela.

    Avec l'opérateur logique NON, il n'y a qu'un seul argument :

    PAS ça #end ]]>

    Cette fois, si $foo vaut true, alors !$foo est évalué comme false, et il n'y a pas de sortie. Si $foo est false, alors !$foo est évalué à true et PAS ça est produit en sortie. Attention à ne pas confondre ceci avec la référence silencieuse $!foo que nous avons déjà rencontrée et qui représente quelque chose de complètement différent.

    Il y a des versions textes de tous les opérateurs logiques, incluant eq (égal), ne (différent), and (et), or (ou), not (négation), gt (strictement plus grand), ge (plus grand ou égal), lt (strictement plus petit) et le (plus petit ou égal).

    Une dernière remarque. Quand on souhaite inclure du texte immédiatement après une directive #else, on doit utiliser des accolades directement autour de la directive pour la différencier du texte qui suit (toutes les directives peuvent être délimitées avec des accolades, même si c'est principalement utile avec #else).

    Boucle Foreach

    L'élément #foreach permet d'itérer. Par exemple:

    #foreach( $product in $allProducts )
  • $product
  • #end ]]>

    Cette boucle #foreach parcourt un à un tous les produits (cibles) de la liste $allProducts (objet). A chaque passage dans la boucle, une valeur de $allProducts est placée dans la variable $product.

    Le contenu de la variable $allProducts est un vecteur (Vector), une table de hachage (Hashtable) ou un tableau (Array). La valeur assignée à $product est un objet Java, et peut être référencée en tant que telle par une variable. Par exemple, si $product est en effet une classe Product en Java, son nom peut être récupéré en référençant la méthode $product.Name (c'est-à-dire $Product.getName()).

    Supposons que $allProducts soit une Hashtable. Si vous voulez retrouver les valeurs des clés et les objets de la Hashtable, vous pouvez utiliser un bout de code comme celui-ci:

    #foreach( $key in $allProducts.keySet() )
  • Key: $key -> Value: $allProducts.get($key)
  • #end ]]>

    Velocity fournit un moyen simple de connaître le compteur de boucle, de sorte qu'on puisse faire quelque chose comme:

    #foreach( $customer in $customerList ) $foreach.count$customer.Name #end ]]>

    Velocity fournit aussi un moyen simple de savoir si l'on est sur la dernière itération d'une boucle :

    Il est possible de définir le maximum autorisé du nombre de fois qu'une boucle peut être exécutée. Par défaut il n'y a pas de maximum (c'est indiqué par la valeur 0 ou moins), mais on peut le fixer à un nombre arbitraire dans le fichier velocity.properties. Cela peut être utile comme garde-fou.

    Si l'on veut arrêter de boucler depuis l'intérieur d'un #foreach, on peut maintenant utiliser la directive #break à n'importe quelle itération de la boucle :

    5 ) #break #end $customer.Name #end ]]>

    L'élément de script #include permet au concepteur de gabarits d'importer un fichier local, qui est alors inséré à l'endroit où la directive #include est définie. Le contenu du fichier n'est pas rendu en passant par le moteur de substitution. Pour des raisons de sécurité, le fichier à inclure ne peut se trouver que sous TEMPLATE_ROOT.

    Le fichier auquel la directive #include fait référence est inclus entre des guillemets. Si plusieurs fichiers doivent être inclus, leurs noms doivent être séparés par des virgules.

    Le fichier à inclure ne doit pas nécessairement être appelé par son nom; en fait, il est souvent préférable d'utiliser une variable plutôt qu'un nom de fichier. Ce qui peut être utile pour cibler ce qui est produit en fonction de critères déterminés au moment où la page est demandée. Voici un exemple qui utilise à la fois un nom de fichier et une variable.

    L'élément de script #parse permet au concepteur de gabarits d'importer un fichier local contenant du VTL. Velocity va alors interpréter le VTL et rendre le gabarit spécifié.

    Comme la directive #include, #parse peut prendre en argument une variable plutôt qu'un nom de gabarit. Tous les gabarits auxquels il est fait référence par #parse doivent se trouver sous TEMPLATE_ROOT. Contrairement à la directive #include, #parse ne peut prendre qu'un seul argument.

    Les gabarits VTL peuvent contenir des instructions #parse faisant référence à des gabarits qui à leur tour contiennent des #parse. Par défaut à 10, la ligne parse_directive.maxdepth du fichier velocity.properties permet aux utilisateurs de personnaliser le nombre de références #parse que l'on peut rencontrer dans un gabarit. (Note: Si la propriété parse_directive.maxdepth est absente du fichier velocity.properties, Velocité positionne cette valeur par défaut à 10). La récursion est permise; par exemple si le gabarit dofoo.vm contient les lignes suivantes:

    Il fait référence au gabarit parsefoo.vm, qui peut contenir le VTL suivant:

    0 ) #parse( "parsefoo.vm" ) #else All done with parsefoo.vm! #end ]]>

    Après que "Count down." soit affiché, Velocity passe par parsefoo.vm, comptant à rebours à partir de 8. Lorsque le compte à rebours atteint 0, il affiche le message "All done with parsefoo.vm!". A ce stade, Velocity va retourner à dofoo.vm et produire le message "All done with dofoo.vm!".

    L'élément de script #stop permet au concepteur de gabarits d'arrêter l'exécution du moteur de substitution. Cette directive peut être utile pour le débogage.

    La directive #evaluate peut être utilisée pour évaluer dynamiquement du code VTL. Cela permet au gabarit d'évaluer une chaîne qui est construite au moment du rendu. Une telle chaîne pourrait être utilisée pour internationaliser le gabarit ou pour include des fragments de gabarit depuis une base de donnée.

    L'exemple ci-dessous affiche abs

    La directive #define permet d'assigner un bloc de VTL à une référence.

    L'exemple ci-dessous affiche Hello World!

    L'élément de script #macro permet aux concepteurs de définir un segment répétable d'un gabarit VTL. Les "Velocimacros" sont très utiles dans un grand nombre de scénarios, simples ou complexes. Une Velocimacro, écrite dans le seul but de s'économiser un peu de frappe et de minimiser les fautes, servira d'introduction au concept de Velocimacro.

    #end ]]>

    La Velocimacro définie dans cet exemple est d; elle peut être appelée d'une manière semblable à toute autre directive VTL:

    Lorsque ce gabarit est appelé, Velocity remplace #d() par une ligne contenant une cellule de données vide.

    Une Velocimacro peut prendre n'importe quel nombre d'arguments -- même zéro, comme on l'a vu dans l'exemple -- mais lorsque la macro est appelée, elle doit l'être avec le même nombre d'arguments que dans la définition. Beaucoup de Velocimacros sont plus sophistiquées que celle définie ci-dessus; voici une Velocimacro qui prend deux arguments, une couleur et un tableau.

    $something #end #end ]]>

    La Velocimacro définie dans cet exemple, tablerows, prend deux arguments. Le premier argument prend la place de $color et le second argument prend la place de $somelist.

    Tout ce qui peut être mis dans un gabarit VTL peut aussi trouver place dans le corps d'une Velocimacro. La Velocimacro tablerows contient une instruction foreach. On remarquera qu'il y a deux instructions #end dans la définition de la Velocimacro #tablerows; la première termine le #foreach, la seconde termine la définition de la Velocimacro.

    #tablerows( $color $greatlakes ) ]]>

    Notez que $greatlakes prend la place de $somelist. Quand la Velocimacro #tablerows est appelée dans ce contexte, la sortie suivante est produite:

    Superior Michigan Huron Erie Ontario ]]>

    Les Velocimacros peuvent être définies inline dans un gabarit Velocity; elles ne sont pas disponibles dans ce cas pour d'autres gabarits Velocity sur le même site web. Définir une Velocimacro pour qu'elle puisse être partagée par tous les gabarits a des avantages évidents: cela réduit le besoin de redéfinir la Velocimacro dans de nombreux gabarits, cela économise du travail et réduit les occasions de se tromper, cela assure qu'un chagement fait une seule fois dans une macro est aussitôt disponible dans tous les gabarits.

    Si la Velocimacro #tablerows($color $list) avait été définie dans une bibliothèque de gabarits Velocimacros, cette macro aurait pu être utilisée dans n'importe lequel des gabarits usuels. Elle pourrait être utilisée de nombreuses fois et dans des buts différents. Dans le gabarit mushroom.vm consacré à toute espèce de champignons, la Velocimacro #tablerows pourrait être appelée pour donner la liste des parties d'un champignon typique.

    #tablerows( $cellbgcol $parts ) ]]>

    Lors de l'exécution d'une requête pour mushroom.vm, Velocity trouverait la Velocimacro #tablerows dans la bibliothèque de gabarits (définie dans le fichier velocity.properties) et produirait la sortie suivante:

    volva stipe annulus gills pileus ]]> Arguments d'une Velocimacro

    Les Velocimacros peuvent prendre comme argument tout élément VTL parmi les suivants:

    • Référence: tout ce qui commence par '$'
    • Chaîne de caractères littérale: quelque chose comme "$foo" ou 'hello'
    • Nombre littéral: 1, 2 etc
    • Intervalle d'entiers (IntegerRange) : [ 1..2] ou [$foo .. $bar]
    • ObjectArray : [ "a", "b", "c"]
    • Valeur booléenne true
    • Valeur booléenne false

    Lorsqu'on passe des références comme arguments à des Velocimacros, notez que ces références sont passées "par nom". Ce qui veut dire que leur valeur est "générée" à chaque utilisation à l'intérieur d'une Velocimacro. Cette particularité vous permet de passer des références contenant des appels de méthodes et que la méthode soit appelée à chaque fois. Par exemple, en appelant la Velocimacro suivante comme indiqué:

    le résultat est que la méthode bar() de la référence $foo est appelée trois fois.

    A première vue, cette particularité est surprenante mais si vous considérez la raison d'être originelle des Velocimacros (éliminer la duplication par couper/coller de VTL d'usage courant), ça a bien sûr un sens. Cela vous permet de faire des choses étonnantes telles que passer à la Velocimacro des objets ayant un état, comme un objet qui génère des couleurs en séquences répétées pour colorer les lignes d'un tableau.

    Si vous éprouvez le besoin de contourner ce comportement, vous pouvez toujours assigner la valeur reçue de la méthode à une nouvelle référence et passer cette référence:

    Propriétés des Velocimacros

    Plusieurs entrées du fichier velocity.properties permettent une implémentation flexible des Velocimacros. Ces lignes sont commentées en détail dans le Developer Guide (en anglais).

    velocimacro.library - Une liste (délimitée par des virgules, de toutes les bibliothèques de gabarits Velocimacro. Par défaut, Velocity ne recherche qu'une bibliothèque: VM_global_library.vm. Le chemin de gabarits donné ici est utilisé pour trouver les bibliothèques de Velocimacros.

    velocimacro.permissions.allow.inline - Cette propriété, qui peut prendre les valeurs true ou false, détermine si les Velocimacros peuvent être définies dans des gabarits ordinaires. La valeur par défaut, true, permet aux concepteurs de gabarits de définir des Velocimacros dans les gabarits eux-mêmes.

    velocimacro.permissions.allow.inline.to.replace.global - Les valeurs possibles sont true ou false, pour cette propriété qui permet à l'utilisateur de spécifier si une Velocimacro définie en ligne dans un gabarit peut remplacer un gabarit défini globalement, celui qui a été défini au démarrage par la propriété velocimacro.library. La valeur par défaut, false, empêche les Velocimacros défines inline dans un gabarit de remplacer celles qui sont définies dans les bibliothèques de gabarits chargées au démarrage.

    velocimacro.permissions.allow.inline.local.scope - Cette propriété, qui peut prendre les valeurs true ou false (false par défaut), contrôle si les Velocimacros définies inline ont leur visibilité limitée au gabarit qui les définit. En d'autres mots, avec cette propriété définie à true, un gabarit peut définir des Velocimacros inline qui ne seront utilisables que par le gabarit qui les définit. Vous pouvez utiliser cette possibilité pour concocter quelques artifices amusants: si une VM globale appelle une autre VM globale, définie inline, un gabarit peut définir une implémentation "privée" de la seconde VM, qui sera appellée par la première VM quand celle-ci est appelée elle-même dans le gabarit. Aucun autre gabarit n'est affecté.

    velocimacro.library.autoreload - Cette propriété contrôle le chargement automatique de la bibliothèque de Velocimacro. La valeur par défaut est false. Quand elle est positionnée à true la bibliothèque source appelée pour une Velocimacro sera vérifiée pour voir si elle a changé et sera rechargée si nécessaire. Ceci vous permet de modifier et de tester des bibliothèques de Velocimacro sans avoir à redémarrer votre application ou votre moteur de servlets, exactement comme vous pouvez le faire pour des gabarits ordinaires. Ce mode ne fonctionne que quand le cache est désactivé dans les resource loaders (par exemple file.resource.loader.cache = false). Cette possibilité a été conçue pour le développement, pas pour la production.

    Autres remarques sur les Velocimacros

    A ce stade, les Velocimacros doivent être définies avant d'être utilisées dans un gabarit. Cela signifie que vos déclarations #macro() doivent précéder l'usage des Velocimacros.

    Il est important de s'en souvenir si l'on essaye d'interpréter (#parse()) un gabarit contenant des directives #macro() inline. Puisque l'interprétation se fait au moment de l'exécution, et que l'interpréteur décide au moment de l'interprétation si, dans un gabarit, un élément qui a l'air d'une VM en est vraiment une, #parse()-er un ensemble de déclarations de VM ne produira pas le résultat escompté. Pour contourner ce problème potentiel, on peut utiliser la propriété velocimacro.library pour que Velocity charge vos VMs au démarrage.

    VTL utilise des caractères spéciaux, comme $ et # pour accomplir sa tâche; il faut donc prendre quelques précautions pour utiliser ces caractères dans vos gabarits. Cette section est consacrée à l'échappement du caractère $.

    Devise
    Il n'y a pas de problème particulier à écrire "J'ai acheté un sac de 2 kg de patates au marché de la ferme pour seulement $2.50!". Comme dit plus haut, un identifiant VTL commence toujours par une lettre, majuscule ou minuscule, et donc $2.50 ne serait pas pris par erreur pour une référence.

    Echapper des références VTL valides
    Il peut se produire dans certains cas que Velocity se trouve induit en confusion. Echapper les caractères spéciaux est le meilleur moyen de traiter les caractères spéciaux du VTL dans vos gabarits, et ceci se fait en utilisant le caractère backslash (\).

    Lorsque Velocity rencontre une référence à $email dans votre gabarit VTL, il cherche dans le contexte la valeur correspondante. Ici, la sortie sera foo, parce que $email est défini. Si $email n'était pas défini, la sortie serait $email.

    Supposons que $email soit défini (par exemple, cette référence a la valeur foo) et que vous vouliez produire $email. Il y a différentes manières de le faire, mais la plus simple est d'utiliser le caractère d'échappement.

    sera rendu comme:

    Notez que le caractère \ s'applique au $ à partir de la gauche. Cette règle d'application à partir de la gauche fait que \\\$email est rendu comme \\$email. Comparons maintenant ces examples à ce qui se passe lorsque $email n'est pas défini.

    sera rendu comme:

    Remarquez comment Velocity traite les références définies différemment de celles qui n'ont pas été définies. Voici par exemple une directive set qui donne à $foo la valeur gibbous.

    La sortie sera: $moon = gibbous -- où $moon est rendu littéralement puisqu'il n'est pas défini, alors que gibbous est rendu au lieu de $foo.

    Echapper des références VTL valides
    Velocity a parfois des problèmes à interpréter un gabarit quand il rencontre une "référence invalide" pour du texte dont on n'a jamais souhaité que ce soit une référence. Échapper les caractères spéciaux est de nouveau le meilleur moyen de gérer ces situations, mais le caractère \ risque de ne pas fonctionner dans ce cas. Au lieu d'essayer de juste échapper le caractère $ ou # problématique, il faut probabement simplement remplacer :

    Par :

    Vous pouvez bien sûr mettre vos chaînes $ et # directement dans le contexte depuis votre code Java (i.e. context.put("D","$");) pour éviter les directives #set additionnelles dans vos gabarits. Ou, si vous utilisez VelocityTools, vous pouvez tout simplement utiliser l'outil EscapeTool comme suit :

    Echappement des directives VTL

    Les directives VTL peuvent être échappées avec le caractère barre de fraction inversée ("\"), de la même manière que les références VTL valides.

    #include( "a.txt" ) ## \#include( "a.txt" ) renders as #include( "a.txt" ) \#include( "a.txt" ) ## \\#include ( "a.txt" ) renders as \ \\#include ( "a.txt" ) ]]>

    Il faut prendre des précautions particulières lorsqu'on échappe des directives VTL qui contiennent plusieurs éléments de script en une seule directive (comme dans le cas d'une instruction conditionnelle if-else-end). Voici un exemple typique d'instruction VTL if:

    Si $jazz est vrai, la sortie produite est:

    Si $jazz, il n'y a pas de sortie produite. Echapper des éléments de script modifie la sortie. Considérons le cas suivant:

    Que $jazz soit vrai ou faux, la sortie sera:

    En fait, puisque tous les éléments de script sont échappés, $jazz n'est jamais évalué en vue d'en connaître la valeur logique. Supposons que les barres de fraction inverses précèdent les éléments de script qui sont légitimement échappés:

    Dans ce cas, si $jazz est vrai, la sortie est

    Pour comprendre, notons que le #if( arg ) , lorsqu'il est terminé par un retour à la ligne, omettra ce retour à la ligne de la sortie produite. Donc, le corps du bloc #if() suit la première barre '\', rendue par le '\\' qui précède #if(). Le dernier \ est sur une ligne différente du texte qui précède parce qu'il y a un retour chariot après 'Ganelin', et donc le \\ final, qui précède le #end fait partie du corps du bloc.

    Si $jazz est faux, la sortie est

    Notons que les choses vont commencer à mal se passer si des éléments de script ne sont pas échappés correctement.

    Ici le #if est échappé, mais il y a un #end qui reste là, et trop de terminaisons vont causer une erreur dans l'interprétation.

    Bien que le VTL soit souvent montré dans ce guide de l'utilisateur avec des sauts de ligne et des espaces, le VTL ci-dessous:

    est tout aussi valide que le bout de code suivant, posté par Geir Magnusson Jr. à la liste de diffusion Velocity (pour illustrer un point sans rapport avec notre sujet):

    Velocity digère les blancs inutiles. La directive qui précède peut donc s'écrire de la manière suivante:

    ou encore:

    Dans tous les cas, la sortie sera identique.

    Velocity a quelques fonctions mathématiques intégrées, fonctions que l'on peut utiliser dans les gabarits avec la directive set. Les équations suivantes sont des exemples d'addition, soustraction, multiplication et division respectivement:

    Lorsqu'une opération de division est exécutée entre deux entiers, le résultat sera un entier. Le reste éventuel de la division peut être obtenu en utilisant l'opérateur modulo (%).

    L'opérateur d'intervalle peut être utilisé en conjonction avec les instructions #set et #foreach. C'est assez commode pour produire un tableau d'objets contenant des entiers; l'opérateur d'intervalle est construit comme ceci:

    n et m doivent tous deux être ou renvoyer des entiers. Que m soit plus grand ou plus petit que n importe peu, si cela se produit le tableau décompte. Voici quelques exemples de l'opérateur de portée:

    Produit la sortie suivante:

    Il est à noter que l'opérateur d'intervalle ne produit le tableau qu'utilisé en conjonction avec les directives #set et #foreach, comme démontré dans le quatrième exemple.

    Les concepteurs de pages web soucieux de construire des tables de taille standard, mais dans lequelles il n'y a pas assez de données pour remplir la table, trouveront cet opérateur d'intervalle particulièrement utile.

    Lorsqu'une référence est annulée par le caractère ! et que ce caractère ! est précédé par un caractère d'échappement \, la référence est traitée de manière particulière. A noter: les différences entre l'échappement ordinaire et le cas particulier où \ précède ! comme ici:

    Ceci produit la sortie suivante:

    A comparer avec l'échappement ordinaire, où \ précède $:

    Ce qui produit la sortie suivante:

    Cette section est une mini-FAQ sur différents sujets relatifs aux Velocimacros. Cette section évoluera au fil du temps, et cela vaudra donc la peine d'y revenir occasionnellement pour y chercher de nouvelles informations.

    Note: tout au long de cette section, 'Velocimacro' sera habituellement abrégé en 'VM'.

    Puis-je utiliser une directive ou une autre VM comme argument d'une VM?

    Exemple : #center( #bold("hello") )

    Non. Une directive n'est pas un argument valide d'une directive, et en pratique, pour l'essentiel, une VM est une directive.

    Pourtant..., il y a des choses que vous pouvez faire. Une solution, simple, est de tirer avantage du fait que l'apostrophe (") restitue son contenu. Vous pouvez donc écrire quelque chose comme

    Vous pouvez même vous épargner une étape...

    Mais il est à noter, dans ce dernier exemple, que l'argument est évalué à l'intérieur de la VM, pas au niveau de l'appel. En d'autres termes, l'argument passé à la VM est passé dans son intégralité et évalué dans la VM à laquelle il a été passé. Ceci permet d'écrire des choses comme:

    La sortie produite est

    puisque l'évaluation de "#inner($bar)" se produit à l'intérieur de #outer(), et c'est donc la valeur $bar positionnée à l'intérieur de #outer() qui est utilisée.

    Ceci est tout à fait intentionnel, et c'est une caractéristique jalousement gardée - les arguments sont passés 'par nom' aux VM, de sorte qu'on puisse passer aux VM un genre de "références avec état" telles que

    Hi There #end #foo( $bar.rowColor() ) ]]>

    et appeler rowColor() plusieurs fois, plutôt qu'une fois. Pour éviter cela, il faut appeler la méthode hors de la VM et passer la valeur à la VM.

    Peut-on enregistrer des Velocimacros avec #parse() ?

    Oui ! C'est devenu possible avec Velocity 1.6.

    Si vous utilisez un version antérieure, les Velocimacros doivent être définies avant d'être utilisées dans un gabarit. Ce qui signifie que les déclarations #macro() doivent précéder l'usage des Velocimacros.

    Il est important de s'en souvenir si l'on essaye d'interpréter avec #parse() un gabarit qui contient des directives #macro() définies inline. Puisque le #parse() a lieu au moment de l'exécution, et que l'interpréteur décide à ce moment si quelque chose qui ressemble syntaxiquement à une VM dans le gabarit en est vraiment une au moment de l'interprétation, #parse()-r un ensemble de déclarations de VM ne fonctionnera pas comme on pourrait le prévoir. Pour contourner ce comportement, il suffit d'utiliser velocimacro.library pour que Velocity charge vos VM's au démarrage.

    Qu'est-ce que le Velocimacro Autoreloading?

    Il existe une propriété, conçue pour le développement, pas pour la production:

    velocimacro.library.autoreload

    dont la valeur par défaut est false. Lorsque cette propriété est positionnée à true, en même temps que

    <type>.resource.loader.cache = false

    (où <type> est le nom du chargeur de ressources que vous utilisez, par exemple 'file'), le moteur Velocity va automatiquement prendre en compte les changements apportés à vos fichiers de bibliothèques Velocimacro, au fur et à mesure que vous les modifiez, de sorte que vous n'ayez pas à arrêter le moteur de servlet (ou l'application) ou avoir recours à tout autre subterfuge de ce genre pour recharger vos Velocimacros.

    Voici à quoi peut ressembler un ensemble simple de propriétés.

    Ne gardez pas cette configuration en production.

    Une question habituelle parmi les développeurs est: Comment concaténer des chaînes de caractères? Y a-t'il quelque chose de semblable à l'opérateur '+' en Java?.

    Pour concaténer des références en VTL, il suffit de les 'mettre ensemble'. Le contexte dans lequel vous voulez les assembler ainsi a une certaine importance, il faut donc illustrer notre propos par quelques exemples.

    Dans le flux habituel d'un gabarit (lorsqu'on mélange les références avec du contenu ordinaire):

    produira 'Cette horloge sonne comme BigBen'. Pour prendre des exemples plus intéressants, lorsqu'on veut concaténer des chaînes pour les passer à une méthode ou les assigner à une nouvelle référence, il suffit d'écrire:

    Ce qui produit le même résultat. Dernier exemple, lorsqu'on veut mélanger des chaînes "statiques" avec des références, il peut être nécessaire d'utiliser les "références formelles" rencontrées plus haut:

    Et maintenant le résultat produit est 'Cette horloge sonne comme BigTallBen'. La notation formelle est requise pour que l'interpréteur comprenne que l'on souhaite utiliser '$size' et non '$sizeTall', ce qui serait le cas si les accolades n'étaient pas présentes.

    Si vous rencontrez des erreurs dans le manuel (autres que des erreurs de traduction), ou si vous voulez faire part de votre avis sur le Guide de l'utilisateur Velocity, envoyez un mail à la Velocity user list. Merci!

    velocity-1.7/xdocs/docs/translations/user-guide_fi.xml0000644000175000017500000020600611156517252023152 0ustar moellermoeller Velocity käyttäjän opas Velocity Documentation Team John Castura Juha Kilpi
    1. Tietoja tästä oppaasta
    2. Mikä on Velocity?
    3. Miten voin käyttää Velocityä?
      1. Kurakauppa esimerkki
    4. Velocity Template Language (VTL): Johdanto
    5. Hei Velocity Maailma!
    6. Kommentit
    7. Viittaukset
      1. Muuttujat
      2. Ominaisuudet
      3. Metodit
    8. Muodollinen viittausten merkintä
    9. Hiljainen viittausten merkintä
    10. Kirjaimellisesti
      1. Dollari
      2. VTL viittausten suojaaminen
    11. Kirjainkoon muutos
    12. Ohjeet
      1. Set
      2. Tekstivakiot
      3. If-Else ehtolauseet
        1. Relaatio- ja loogiset operaattorit
      4. Foreach silmukat
      5. Include
      6. Parse
      7. Stop
      8. Velocimakrot
    13. VTL ohjeiden suojaaminen
    14. VTL: Muotoilu
    15. Muita ominaisuuksia ja sekalaista
      1. Matematiikka
      2. Vaihteluväli (Range Operator)
      3. Edistyneet kysymykset: Suojaaminen ja !
      4. Yleistä Velocimakroista
      5. Merkkijonojen yhdistäminen
    16. Palaute

    Velocity käyttäjän opas on tarkoitettu sivusuunnittelijoille ja sisällöntuottajille avuksi tutustuttaessa Velocityyn ja sen yksinkertaiseen mutta tehokkaaseen skriptikieleen, Velocity Template Language:en (VTL). Useat tämän oppaan esimerkeistä käsittelevät Velocityn käyttämistä dynaamisen sisällön lisäämiseksi web sivuille, mutta kaikki VTL esimerkit toimivat HTML sivujen lisäksi yhtä hyvin myös muiden sivujen ja sivupohjien kanssa.

    Kiitos että valitsit Velocityn!

    Velocity on javapohjainen sivumoottori (template engine). Sen avulla sivusuunnittelijat voivat viitata java -koodissa määriteltyihin metodeihin. Sivusuunnittelijat voivat työskennellä java ohjelmoijien kanssa samanaikaisesti käyttäen Malli-Näkymä-Ohjain (Model-View-Controller, MVC) suunnittelumallia. MVC mallissa sivusuunnittelijat voivat keskittyä täysin luomaan hyvin suunniteltua sivustoa, ja ohjelmoijat voivat keskittyä koodaamaan ykkösluokan koodia. Velocity erottaa java -koodin web sivuista, tehden sivustosta pitkällä aikavälillä helpommin ylläpidettävän ja antamalla varteenotettavan vaihtoehdon JSP:lle (Java Server Pages) ja PHP:lle.

    Velocityä voidaan käyttää web sivujen, SQL:n, PostScriptin ja muunlaisten tulosteiden tuottamiseen sivupohjista (template). Sitä voidaan käyttää joko itsenäisenä työkaluna lähdekoodin ja raporttien luomiseen, tai muihin järjestelmiin integroituna komponenttina. Velocity tarjoaa sivupohjaratkaisun Turbine web sovelluskehykselle. Yhdessä Velocity ja Turbine tarjoavat sivupohjaratkaisun jonka avulla web sovelluksia voidaan kehittää todellisen MVC -mallin mukaisesti.

    Oletetaan että olet kuraa myyvän onlinekaupan sivusuunnittelija. Kutsumme kauppaa "Kurakauppa Online":ksi. Kauppa käy hyvin. Asiakkaat tilaavat vaihtelevia määriä eri kuratyyppejä. He pääsevät tutkimaan tekemiään tilauksia sekä tekemään uusia ostoja kirjautumalla sivullesi käyttäen käyttäjätunnustaan ja salasanaansa. Tällä hetkellä suosittu Terracotta -kura on alennusmyynnissä. Pieni osa asiakkaistasi ostaa säännöllisesti Kirkkaanpunaista Kuraa, joka myös on alennusmyynnissä, mutta pienemmän suosionsa vuoksi yleensä mainittu sivulla hieman syrjässä. Tiedot kustakin asiakkaasta talletetaan tietokantaan, joten eräänä päivänä herää kysymys; Miksipä emme käyttäisi Velocityä kohdentamaan erikoistarjouksia kurasta asiakkaille jotka ovat kiinnostuneita juuri tuosta kuratyypistä?

    Velocityn avulla verkkosivut on helppo personoida kävijöidesi mukaan. Kurakauppa Onlinen sivusuunnittelijana haluat tehdä sivun jonka asiakas näkee kirjauduttuaan järjestelmään.

    Tapaat yrityksesi ohjelmoijat ja sovitte, että muuttuja $asiakas pitää sisällään tiedot parhaillaan kirjautuneena olevasta asiakkaasta. Muuttujassa $kuratTarjouksessa ovat tiedot kuratyypeistä jotka ovat parhaillaan erikoistarjouksessa. $tarjous objektissa on metodeja jotka auttavat mainostamisessa. Tällä kertaa keskitymme vain näihin kolmeen viittaukseen. Muista, että sinun ei tarvitse huolehtia siitä kuinka ohjelmoijat hakevat tarvittavat tiedot tietokannasta, sinun tarvitsee tietää vain että se toimii. Näin pääset tekemään omaa työtäsi ja ohjelmoijat pääsevät tekemään omaansa.

    Voisit lisätä seuraavat VTL lauseen sivulle:

    Hei $asiakas.Nimi! #foreach( $kura in $kuratTarjouksessa ) #if ( $asiakas.onOstanut($kura) ) #end #end
    $tarjous.haePromo( $kura )
    ]]>

    foreach lauseen toiminta kuvataan yksityiskohtaisemmin jäljempänä; tärkeää tässä on tämän lyhyen skriptin tekemä vaikutus sivullesi. Kun Kirkkaanpunainen Kura on alennusmyynnissä ja sitä joskus aiemmin ostanut asiakas kirjautuu sisään, asiakas näkee ilmoituksen alennuksesta parhaalla mahdollisella paikalla. Jos toinen, Terracottakuraa ostanut asiakas kirjautuu järjestelmään, ilmoitus Terracottakuran alennusmyynnistä näkyy hänelle ensimmäisenä. Velocity on joustava ja sen käytössä vain mielikuvituksesi on rajana.

    VTL hakemistossa on kuvattu Velocityn kaikki elementit jotka yhdessä antavat käyttöösi tehokkaan ja joustavan työkalun jota tarvitset luodaksesi web sivuistasi dynaamisen. Pääset hyödyntämään Velocityn voimaa jatkuvasti paremmin sitä mukaa kun opit käyttämään näitä elementtejä.

    Velocityn sivunkuvauskieli (Velocity Template Language, VTL) tarjoaa helpon ja yksinkertaisen keinon liittää dynaamista sisältöä web sivulle. Dynaamisen sisällön käyttäminen pitäisi onnistua nopeasti jopa sellaiselta sivusuunnittelijalta jolla on ohjelmointikokemusta vain vähän, tai ei ollenkaan.

    VTL käyttää viittauksia dynaamisen aineiston lisäämiseen verkkosivulle. Muuttujat ovat yhdentyyppisiä viittauksia. Muuttujat voivat viitata johonkin java -koodissa määriteltyyn, tai niiden arvo voidaan määrittää web -sivulla annetun VTL lauseen avulla. Seuraavassa on esimerkki VTL lauseesta joka voidaan lisätä HTML -dokumenttiin:

    Kuten kaikki VTL lauseet (statement), tämäkin lause alkaa # merkillä ja sisältää ohjeen (directive): set. Kun verkkosivun käyttäjä hakee sivun Velocity etsii sivupohjastasi kaikki # -merkit. Sitten se tulkitsee mitkä niistä merkitsevät VTL lausetta, ja mitkä # merkeistä ovat osa sivujesi normaalia HTML -koodia, eivätkä kuulu VTL -koodiin.

    # merkkiä seuraa ohje, set. set ohjeen jälkeen tulee suluissa ilmaus (expression), -- yhtälö joka määrittää arvon muuttujalle. Muuttuja on ilmaistu vasemmalla ja arvo oikealla puolella. Nämä on erotettu = merkillä.

    Yllä olevassa esimerkissä muuttuja on $a ja arvo on Velocity. Kaikkien viittausten tapaan tämäkin muuttuja alkaa $ merkillä. Arvot ovat aina lainausmerkkien sisällä; Velocityssä muuttujien datatyypeistä ei tule sekaannuksia, koska vain merkkijonoja (string) voi antaa muuttujien arvoksi.

    Seuraava nyrkkisääntö voi auttaa ymmärtämään Velocityn toimintaa: Viittaukset alkavat $ merkillä ja niitä käytetään jonkin hakemiseen. Ohjeet alkavat # merkillä ja niitä käytetään jonkin suorittamiseen.

    Yllä olevassa esimerkissä #set -ohjetta käytetään arvon määrittämiseksi muuttujaan. Muuttujaa $a voidaan tämän jälkeen käyttää sivupohjassa tulostamaan "Velocity".

    Kun muuttujalle on määritelty arvo, voidaan siihen viitata missä tahansa paikassa HTML dokumenttia. Seuraavassa esimerkissä muuttujalle $foo määritellään arvo. Myöhemmin muuttujaan viitataan.

    #set( $foo = "Velocity" ) Hei $foo Maailma! ]]>

    Tuloksena on web sivu jossa lukee "Hei Velocity Maailma!".

    Jotta VTL lauseet olisivat helpommin luettavissa on suositeltavaa aloittaa jokainen lause uudelta riviltä, vaikkakaan tämä ei ole pakollista. set ohjeeseen palaamme tarkemmin myöhemmin.

    Kommenttien avulla sivulle voidaan lisätä aputekstejä jotka eivät tule näkymään sivun tulosteessa. Voit käyttää kommentteja muistuttaaksesi itseäsi jostakin tai selittääksesi muille mitä VTL komennot tekevät, tai mihin tahansa muuhun tarkoitukseen. Alla on esimerkki kommentin käytöstä.

    Yhden rivin pituinen kommentti alkaa ## merkeillä ja loppuu kyseisen rivin lopussa. Jos aiot kirjoittaa usean rivin mittaisen kommentin, ei sinun tarvitse kirjoittaa useita yhden rivin kommentteja. Usean rivin kommentit alkavat #* merkeillä ja loppuvat *# merkkeihin.

    Tässä on muutamia esimerkkejä yksi- ja monirivisten kommenttien toiminnan selvittämiseksi:

    On olemassa vielä kolmaskin kommenttityyppi; VTL kommenttilohko, jota voidaan käyttää mm. dokumentin tekijä- ja versiotietojen tallettamiseen

    VTL:ssä on kolme erityyppistä viittausta: muuttujat, ominaisuudet ja metodit. VTL:ää käyttävänä sivusuunnittelijana sinun, ja javapuolta koodaavien ohjelmoijien on sovittava viittausten nimistä, jotta voit käyttää niitä sivupohjissasi.

    Kaikkea viittauksissa olevaa ja niihin määriteltävää tietoa käsitellään tekstityyppisenä. Jos on esimerkiksi määritelty objekti $foo (Integer objekti), Velocity kutsuu objektin .toString() metodia objektin arvon muuntamiseksi tekstityyppiseksi.

    Muuttujat
    Muuttujan lyhyt merkintätapa koostuu ensimmäisenä olevasta "$" merkistä, jonka jälkeen tulee VTL tunniste. VTL tunnisteen on alettava aakkosnumeerisella merkillä (a..z tai A..Z). Muuttujan loput merkit ovat rajoitettu seuraaviin:

    • aakkoset (a .. z, A .. Z)
    • numerot (0 .. 9)
    • viiva ("-")
    • alaviiva ("_")

    Seuraavassa muutamia esimerkkejä toimivista muuttujaviittauksista:

    Kun VTL viittaa muuttujaan, kuten $foo, muuttuja voi saada arvonsa joko sivupohjassa olevalta set ohjeelta, tai java -koodista. Jos esimerkiksi javamuuttujalla $foo on arvo bar silloin kun sivupohjaa haetaan, bar korvaa kaikki $foo muuttujan esiintymiskohdat web sivulla. Toisaalta jos sivulle lisätään lause

    Sivun tuloste on sama kaikilla $foo muuttujan esiintymiskohdille jotka tulevat tämän lauseen jälkeen.

    Ominaisuudet
    Toinen VTL:n viittaustyyppi ovat ominaisuudet joilla on oma tunnusomainen muotonsa. Lyhyt merkintätapa muodostuu ensimmäisenä olevasta $ merkistä, jonka jälkeen tulee VTL tunniste, jota seuraa piste (".") ja toinen VTL tunniste. Seuraavassa on esimerkkejä toimivista ominaisuusviittauksista:

    Käsittelemme ensimmäisen esimerkin $asiakas.Osoite tarkemmin. Viittauksella voi olla kaksi merkitystä. Se saattaa tarkoittaa; hae asiakas nimisestä hashtable taulukosta arvo joka on liitetty avaimelle Osoite. Toisaalta $asiakas.Osoite voi myös viitata metodiin (käsittelemme metodeihin viittaavat viittaukset seuraavassa kappaleessa); $asiakas.Osoite saattaa olla lyhennetty muoto viittauksesta $asiakas.getOsoite(). Velocity tulkitsee sivua haettaessa kumpaa näistä vaihtoehdoista tarkoitetaan, ja palauttaa vastaavan arvon.

    Metodit
    Metodit ovat määritelty java -koodissa ja niiden avulla voidaan suorittaa jokin toimenpide; esimerkiksi laskutoimitus tai jonkin päätöksen tekeminen. Metodit ovat viittauksia jotka muodostuvat aloittavasta "$" merkistä, jota seuraa VTL tunniste, jonka jälkeen tulee VTL Metodirunko. VTL Metodirunko koostuu VTL tunnisteesta jota seuraa vasen sulkumerkki "(", jota seuraa valinnainen parametrilista, jota seuraa oikeanpuoleinen sulkumerkki ")". Seuraavassa on esimerkkejä toimivista metodiviittauksista:

    Metodirungossa esiintyvä get tarkoittaa "hae" ja set "aseta".

    Kaksi ensimmäistä esimerkkiä -- $asiakas.getOsoite() ja $ostos.getSumma() -- näyttävät samanlaisilta kuin Ominaisuudet -osiossa aiemmin; $asiakas.Osoite ja $ostos.Summa. Jos arvasit että näillä esimerkeillä on jotakin yhteyttä toisiinsa, olit oikeassa!

    VTL ominaisuuksia voidaan käyttää lyhyempinä muotoina VTL metodeista. Ominaisuudella $asiakas.Osoite on täysin sama vaikutus kuin käyttämällä metodia $asikas.getOsoite(). Yleisesti ottaen ominaisuuksien käyttö on suositeltavaa silloin kuin se vain on mahdollista. Suurin ero ominaisuuksien ja metodien välillä on se, että metodeille voi antaa parametreja.

    Seuraavien metodien kanssa voidaan käyttää lyhyttä muotoa:

    Näiden metodien voisimme olettaa palauttavan auringolle kuuluvien planeettojen nimet, syöttävän matomme, tai hakevan valokuvan albumista. Seuraavissa metodeissa toimii vain pitkä muoto:

    Muodollinen viittausten merkintä
    Edellisissä esimerkeissä käytettiin viittauksille lyhyttä merkintätapaa. Viittauksille on olemassa myös muodollinen merkintätapa, jota käytetään seuraavissa esimerkeissä:

    Voit käyttää lyhyttä muotoa viittauksiin lähes aina, mutta joissain tapauksissa muodollista viittausta tarvitaan virheettömän toiminnan turvaamiseksi.

    Oletetaan että olet luomassa lausetta jonka sisältö riippuu muuttujasta. Muuttujaa $pahe käytetään pohjana luotaessa muuttujasta riippuvaista sanaa. Tarkoituksena on sallia käyttäjän valita pohjasana ja tuottaa toinen seuraavista tuloksista: "Juha on pyromaani." tai "Juha on kleptomaani.". Tässä tapauksessa lyhyen viittausmuodon käyttäminen ei toimisi. Tutki seuraavaa esimerkkiä:

    Velocity olettaa että tarkoitat muuttujaa $pahemaani, vaikka käytettävä muuttuja oli $pahe. Koska Velocity ei löydä arvoa muuttujalle $pahemaani, se palauttaa $pahemaani. Tämä ongelma voidaan ratkaista käyttämällä muodollista viittausta.

    Nyt Velocity ymmärtää että haluttu viittaus on $pahe, ei $pahemaani. Muodollinen viittausten merkintä on usein hyödyllinen silloin kun viittaukset ovat kiinni muussa tekstissä.

    Hiljainen viittausten merkintä
    Kun Velocityltä haetaan viittaus jolle ei ole määritelty arvoa, palauttaa se normaalisti viittauksen tekstinä. Oletetaan esimerkiksi että seuraavat viittaukset ovat osa VTL sivupohjaa:

    ]]>

    Kun lomake latautuu ensimmäisen kerran muuttujaviittauksella $email ei ole arvoa. Oletuksena Velocity täyttää lomakkeen tekstillä "$email". Haluaisit kuitenkin kenttään mieluummin tyhjän arvon. Käyttämällä hiljaista viittausten merkintää voidaan Velocityn normaali toiminta estää; $email koodin sijaan käytät viittausta $!email. Yllä oleva koodi näyttäisi siis seuraavalta:

    ]]>

    Kun lomake latautuu ensimmäisen kerran eikä muuttujalla $email ole arvoa, tulostetaankin kenttään tyhjä teksti "$email" tekstin sijaan.

    Muodollista ja hiljaista muuttujien merkintää voidaan käyttää myös yhdessä;

    ]]>

    VTL käyttää erikoismerkkejä kuten $ ja # omassa toiminnassaan, joten näiden merkkien käyttö sivupohjassa vaatii erityistä huolellisuutta. Tässä kappaleessa käsittelemme $ merkin suojaamisen (escape).

    Dollari
    Seuraavassa lauseessa dollarimerkin käytössä ei ole ongelmaa: "Ostin markkinoilta säkin perunoita hintaan $2.50!". Kuten mainittu, VTL tunniste alkaa aina aakkosmerkillä, joten merkintää $2.50 ei ole vaaraa sekoittaa viittaukseksi.

    VTL viittausten suojaaminen
    Ongelmatilanne saattaa syntyä silloin, kun Velocity ei osaa päätellä tarkoitetaanko dollarinmerkillä merkkiä itseään, vai viittausta. Erikoismerkkien suojaaminen on paras keino käsitellä VTL erikoismerkkejä sivupohjissa. Suojaamiseen käytetään kenoviivaa ( \ ).

    Kun Velocity käsittelee $email viittauksen sivupohjassasi, se etsii löytyykö sen nimiselle muuttujalle arvoa. Tässä tapauksessa tuloste tulee olemaan foo, koska $email on määritelty. Jos $email muuttujaa ei olisi määritelty tulisi tulosteeksi $email.

    Oletetaan että $email on määritelty (sillä on esimerkiksi arvo foo), ja että haluat muuttujan arvon sijaan tulostaa sen nimen $email. Tämä saavuttamiseksi on useita keinoja, joista helpoin on suojausmerkin käyttäminen.

    tulosteeksi tulee

    Huomaa $ merkin eteen liitetty \ merkki. Suojausmerkit tulkitaan vasemmalta oikealle, joten \\\$email tulostuu \\$email. Vertaa näitä esimerkkejä tulosteeseen joka saadaan kun $email muuttujaa ei ole määritelty.

    tulosteeksi tulee

    Huomaa kuinka Velocity käsittelee eri tavalla viittaukset joiden arvo on määritelty niistä joita ei ole määritelty. Seuraavassa on set ohje joka asettaa $foo muuttujalle arvon gibbous.

    Tulosteeksi tulee: $kuu = gibbous -- missä $kuu tulostetaan muuttujan nimenä, koska sen arvoa ei ole määritelty ja gibbous tulostetaan muuttujan $foo arvona.

    Myös VTL ohjeiden suojaaminen on mahdollista; tämä kuvataan tarkemmin Ohjeet -kappaleessa.

    Kun nyt olet tutustunut viittauksiin, voit alkaa käyttämään niitä tehokkaasti omissa sivupohjissasi. Viittaukset Velocityssä käyttävät hyväkseen joitakin java kielen perusperiaatteita, joiden käyttö helpottaa sivusuunnittelijoiden työtä. Esimerkiksi:

    Nämä esimerkit havainnollistavat viittauksen vaihtoehtoisia merkitsemistapoja. Velocity käyttää hyväkseen javan introspection ja bean -ominaisuuksia objektien sekä niiden metodien viittausnimiä ratkaistaessa. Viittauksia voidaan lisätä lähes mihin kohtaan tahansa sivupojassa.

    Velocity on tehty Sun Microsystemsin määrittelemän Bean määrityksen mukaiseksi, ja on tästä syystä pieni-iso-eroava (ts. pienet ja isot kirjaimet käsitellään eri merkkeinä). Velocityn kehittäjät ovat tehneet parhaansa jotta mahdolliset kirjoitusvirheet voitaisiin korjata automaattisesti. Kun sivupohjassa viitataan metodiin getFoo() koodilla $bar.foo, Velocity kokeilee ensin viittausta $getfoo. Jos tämä ei tuota tulosta, seuraavaksi yritetään viittausta $getFoo. Samalla tavalla, kun sivupohjassa viitataan muuttujaan $bar.Foo, ensin yritetään viittausta $getFoo() ja sitten getfoo().

    Huomaa: Viittauksia ilmentymämuuttujiin (instance variables) ei ratkaista. Vain viittaukset JavaBeanin mukaisiin haku/asetus (getter/setter) metodeihin ratkaistaan (toisin sanoen $foo.Name ratkaistaan Foo -luokan getName() ilmentymämetodiin (instance method), mutta ei luokan Foo julkiseen (public) Name ilmentymämuuttujaan).

    Ohjeet ovat helppokäyttöisiä skriptielementtejä joita voidaan käyttää web sivun tulosteen manipuloimiseen. Viittausten avulla sivupohjien suunnittelijat voivat tuottaa web sivuille dynaamista sisältöä, kun taas ohjeet antavat mahdollisuuden määritellä sivuston ulkoasun ja sisällön.

    #set

    #set ohjetta käytetään arvon määrittämiseksi viittaukselle. Arvo voidaan määrittää joko muuttujaviittaukselle tai ominaisuusviittaukselle. Määritys tehdään suluissa, kuten seuraavassa esimerkissä:

    Määrityksen vasemman puolen (left hand side, LHS) tulee olla muuttuja- tai ominaisuusviittaus. Oikea puoli (right hand side, RHS) voi olla jokin seuraavista tyypeistä:

    • Muuttujaviittaus
    • Tekstivakio
    • Ominaisuusviittaus
    • Metodiviittaus
    • Numeerinen vakio
    • ArrayList taulukko

    Seuraavassa esimerkit kustakin mainitusta tyypistä:

    HUOMAA: Viimeisessä esimerkissä [..] operaattorilla määritetyt elementit ovat käytettävissä ArrayList -luokan metodien avulla. Voisit siis esimerkiksi viitata taulukon ensimmäiseen elementtiin koodilla $apina.Sano.get(0).

    Oikeanpuoleinen arvo (RHS) voi olla myös yksinkertainen matemaattinen operaatio:

    Jos määrityksen oikeanpuoleinen ominaisuus- tai metodiviittaus on arvoa null, sitä ei anneta vasemman puolen arvoksi. Tätä keinoa ei voida käyttää olemassa olevan viittauksen poistamiseen. Tämä saattaa olla hämäävää Velocityn uusille käyttäjille. Esimerkiksi:

    Jos $kysely.kriteeri("nimi") palauttaa merkkijonon "pete", ja $kysely.kriteeri("osoite") palauttaa arvon null, on esimerkin tuloste seuraava:

    Tällä on vaara hämätä aloittelijoita jotka muodostavat #foreach silmukoita joissa yritetään asettaa #set ohjeella viittausta ominaisuus- tai metodiviittauksella, ja sen jälkeen testataan tuota viittausta #if ohjeella. Esimerkiksi:

    Yllä olevassa esimerkissä ei kannata luottaa $tulos muuttujan vertaamiseen kyselyn onnistumisen selville saamiseksi. Kun $tulos on asetettu #set ohjeella (lisatty kontekstiin), sitä ei voida asettaa null:iksi (poistaa kontekstista). #if ja #foreach ohjeet käsitellään tarkemmin myöhemmin tässä dokumentissa.

    Yksi ratkaisu ongelmaan olisi asettaa $tulos etukäteen arvoon false (epätosi). Tämän jälkeen jos kutsu $kysely.kriteeri() epäonnistuu, voit tarkastaa arvon.

    Muutamista muista Velocityn ohjeista poiketen, #set ohje ei käytä #end lausetta.

    Tekstivakiot

    #set ohjetta käytettäessä lainausmerkkeihin (" ") suljettu teksti tulkitaan ja tulostetaan kuten seuraavasta esimerkistä käy ilmi:

    Tulosteeksi tulee

    Jos teksti on suljettu hipsuihin (' '), sitä ei tulkita:

    Tulosteeksi tulee:

    Tulkitsemattoman tekstin tulostaminen hipsumerkkien sisällä olevavasta tekstistä on oletuksena käytössä Velocityssä. Oletusarvo voidaan muuttaa vaihtamalla velocity.properties siten että stringliterals.interpolate=false.

    If / ElseIf / Else

    #if ohjeen avulla voidaan teksti sisällyttää web sivulle sillä ehdolla että if lauseen arvo on tosi. Esimerkiksi:

    Velocity! #end ]]>

    Muuttuja $foo testataan jotta nähdään onko se tosi, joka tapahtuu kahdessa eri tapauksessa: (i) $foo on boolean arvo (tosi/epätosi) jolla on tosi -arvo, tai (ii) arvo on eri kuin null (eli muuttuja ei ole tyhjä). #if ja #end lauseiden väliin jäävä sisältö tulostetaan mikäli testimuuttuja on tosi. Esimerkkitapauksessamme, jos muuttujalla $foo on null arvo, tai jos se on boolean epätosi, on testimuuttuja epätosi, eikä tulostetta tule lainkaan.

    #if ja #end lauseiden välissä oleva teksti tulee tulosteeksi mikäli ehto on tosi. Tässä tapauksessa jos $foo on tosi, tulosteeksi tulee: "Velocity!". Toisaalta, mikäli $foo on epätosi, on myös ehtolause epätosi eikä tulostetta tule.

    #elseif tai #else elementtejä voidaan käyttää #if elementin kanssa. Huomaa, että Velocityn sivumoottori lopettaa ensimmäisen tosiarvon saaneen testimuuttujan kohdalla. Oletetaan seuraavassa esimerkissä että muuttujalla $foo on arvo 15 ja muuttujalla $bar on arvo 6.

    Mene pohjoiseen #elseif( $foo == 10 ) Mene itään #elseif( $bar == 6 ) Mene etelään #else Mene länteen #end ]]>

    Tässä esimerkissä $foo on suurempi kuin 10, joten kaksi ensimmäistä vertailua eivät ole tosia. Seuraavaksi muuttujaa $bar verrataan lukuun 6, joka on tosi, joten tulosteeksi tulee Mene etelään.

    Relaatio- ja loogiset operaattorit

    Velocity käyttää vastaavuusoperaattoria muuttujien välisten suhteiden tulkitsemiseen. Seuraavassa on yksinkertainen esimerkki vastaavuusoperaattorin käytöstä.

    Velocity tukee myös loogisia AND ja OR operaattoreita. Lisätietoja löydät dokumentista VTL Reference Guide. Alla on esimerkkilause joka käyttää loogista AND:iä.

    Tämä JA tuo #end ]]>

    If lause on tosi vain mikäli sekä $foo että $bar ovat tosia. Jos $foo on epätosi, tulee lauseesta epätosi eikä $bar muuttujaa tarvitse edes testata. Jos $foo on tosi, testataan sen jälkeen muuttujan $bar arvo; jos myös $bar on tosi, silloin koko ilmaus on tosi ja Tämä JA tuo tulee tulosteeksi. Jos $bar on epätosi, silloin koko ilmaus on epätosi eikä tulostetta tule.

    Looginen OR operaattori toimii samaan tapaan, paitsi että vain toisen viittauksen pitää olla tosi jotta koko ilmaus olisi tosi. Katso seuraavaa esimerkkiä.

    Tämä TAI tuo #end ]]>

    Jos $foo on tosi, ei $bar muuttujaa tarvitse edes testata. Oli $bar sitten tosi tai epätosi, koko lauseke on tosi, ja Tämä TAI tuo on tulosteena. Toisaalta mikäli $foo on epätosi, on muuttujan $bar arvo testattava. Jos tässä tapauksessa myös $bar on epätosi, koko ilmauksesta tulee epätosi eikä tulostetta tule. Jos $bar on tosi, silloin koko ilmauksesta tulee tosi, ja tulosteena on Tämä TAI tuo.

    Loogisella EI (NOT) operaattorilla on vain yksi argumentti :

    EI tuota #end ]]>

    Jos $foo on tosi, silloin !$foo on epätosi, eikä tulostetta tämän vuoksi tule. Mikäli $foo on epätosi, silloin !$foo on tosi ja EI tuota on tulosteena. Älä sekoita tätä merkintää hiljaiseen viittaukseen $!foo joka tarkoittaa jotakin aivan muuta.

    Foreach silmukat

    #foreach mahdollistaa silmukoiden tekemisen. Esimerkiksi:

    #foreach( $tuote in $kaikkiTuotteet )
  • $tuote
  • #end ]]>

    Tämä #foreach silmukka käy läpi yksi kerrallaan kaikki $kaikkiTuotteet listassa olevat tuotteet. Jokaisella kierroksella seuraavan tuotteen arvo kopioidaan $kaikkiTuotteet listasta muuttujaan $tuote.

    $kaikkiTuotteet lista on tyyppiä Vector, Hashtable tai Array. $tuote muuttujaan kopioitu arvo on java objekti (Object), joten siihen voidaan myös viitata objektina. Jos esimerkiksi $tuote muuttuja olisi tyyppiä Tuote, sen nimi voitaisiin hakea viittaamalla $tuote.Name metodiin (ts. $Tuote.getName().

    Oletetaan että $kaikkiTuotteet on tyyppiä Hashtable. Jos haluat hakea Hashtablen avainarvot sekä niihin liittyvät objektit, voit käyttää seuraavanlaista koodia:

    #foreach( $avain in $kaikkiTuotteet.keySet() )
  • Avain: $avain -> Arvo: $kaikkiTuotteet.get($avain)
  • #end ]]>

    Velocityllä on helppo keino silmukkalaskurin käyttämiseen. Voit käyttää laskuria esimerkiksi seuraavasti:

    #foreach( $asiakas in $asiakasLista ) $foreach.count$asiakas.Nimi #end ]]>

    #include elementin avulla sivusuunnittelija voi hakea paikallisesta tiedostojärjestelmästä tiedoston, jonka sisältö lisätään sivun siihen kohtaan jossa #include määritys tehtiin. Tiedoston sisältö liitetään sellaisenaan eikä sitä siis käytetä Velocityn sivumoottorin kautta. Turvallisuussyistä haettava tiedosto voi sijaita vain TEMPLATE_ROOT vakion määrittämän hakemiston alla.

    Tiedosto johon #include ohje viittaa on lainausmerkeissä. Jos halutaan sisällyttää useampia kuin yksi tiedosto, tiedostonimet tulee erotella toisistaan pilkuilla.

    Sisällytettävään tiedoston ei ole pakko viitata nimen perusteella; itse asiassa usein on parempi käyttää muuttujaa tiedostonimen asemesta. Tämä on hyödyllistä esimerkiksi silloin kun sivun ulkoasu riippuu sivupyynnön aikana päätettävästä ehdosta. Seuraavassa on esimerkki jossa käytetään sekä tiedostonimeä että muuttujaa.

    #parse elementin avulla sivusuunnittelija voi sisällyttää paikallisesta levyjärjestelmästä tiedostoja jotka sisältävät VTL elementtejä. Velocity tulkitsee VTL komennot ja tulostaa tuloksen.

    #include ohjeen tapaan #parse voi ottaa parametrikseen nimen lisäksi myös muuttujan. Kaikkien sivupohjien joihin #parse ohjeella viitataan tulee sijaita TEMPLATE_ROOT vakion määrittämän hakemiston alla. #include ohjeesta poiketen #parse voi ottaa vain yhden argumentin.

    VTL sivupohjissa voi olla #parse ohjeita jotka viittaavat sivupohjiin joissa niissäkin on #parse ohjeita. velocity.properties tiedostossa oleva rivi parse_directive.maxdepth määrittää sen kuinka monta peräkkäistä #parse viittausta voidaan tehdä. Mikäli parse_directive.maxdepth määritys puuttuu, käytetään oletusarvoa 10. Rekursiivisuus on sallittu. Jos esimerkiksi sivupohja dofoo.vm sisältää seuraavat rivit:

    Koodi viittaisi sivupohjaan parsefoo.vm, jossa puolestaan voisi olla seuraavat VTL komennot:

    0 ) #parse( "parsefoo.vm" ) #else Kaikki valmista: parsefoo.vm! #end ]]>

    Kun "Laske alaspäin." on näytetty, Velocity lataa ja siirtää kontrollin sivupohjalle parsefoo.vm, joka laskee alas luvusta 8. Kun laskuri saavuttaa arvon 0, tulostetaan "Kaikki valmista: parsefoo.vm!". Tämän jälkeen Velocity palaa sivupohjaan dofoo.vm ja tulostaa "Kaikki valmista: dofoo.vm!" tekstin.

    #stop elementin avulla sivupohjan suunnittelija voi pysäyttää sivun tulkitsemisen. Tämä on hyödyllistä sivupohjan virheidenetsinnän aikana.

    #macro elementin avulla sivupohjan suunnittelija voi määrittää toistuvasti käytetyn VTL sivupohjan osan. Velocimakrot ovat erittäin käyttökelpoisia sekä monimutkaisissa, että yksinkertaisissa tehtävissä. Seuraava Velocimakro toimii johdantona Velocimakroihin. Se on luotu kirjoitettavan tekstin määrän vähentämiseksi, sekä kirjoitusvirheiden määrän minimoimiseksi.

    #end ]]>

    Esimerkissä määriteltiin Velocimakro nimeltään d, ja sitä voidaan kutsua muiden VTL ohjeiden tapaan:

    Kun tätä sivupohjaa haetaan, Velocity korvaa ohjeen #d() rivillä joka sisältää yhden tyhjän solun.

    Velocimakro voi ottaa kuinka monta parametria tahansa -- tai ei yhtään parametria, kuten ensimmäisessä esimerkissämme -- mutta kun Velocimakroa kutsutaan, tulee kutsussa olla täsmälleen yhtä monta parametria kuin makroa määriteltäessä. Useimmat Velocimakrot ovat hieman monimutkaisempia kuin edellinen esimerkki. Seuraavassa on Velocimakro joka ottaa kaksi argumenttia; värin ja listan.

    $jotain #end #end ]]>

    Tässä esimerkissä määriteltiin Velocimakro taulurivit joka ottaa kaksi parametria. Ensimmäinen parametri on $vari ja toinen $jokulista.

    Velocimakroon voidaan kirjoittaa mitä tahansa koodia jota voidaan käyttää muuallakin VTL sivupohjassa. taulurivit Velocimakro on foreach lause. taulurivit Velocimakrossa on kaksi #end lausetta; ensimmäinen kuuluu #foreach lauseelle, jälkimmäinen päättää Velocimakron määrityksen.

    #taulurivit( $vari $suuretjarvet ) ]]>

    Huomaa että $suuretjarvet on makron parametrin $jokulista arvona. Kun Velocimakroa #taulurivit tässä tapauksessa kutsutaan, on tuloksena seuraavaa:

    Superior Michigan Huron Erie Ontario ]]>

    Velocimakroja voidaan määrittää inline, eli Velocity sivupohjassa itsessään, jolloin ko. makro ei ole käytettävissä muissa sivupohjissa. Velocimakron määrittäminen siten että se on kaikkien sivupohjien käytössä on hyödyllistä; samaa makroa ei tarvitse määrittää erikseen jokaisessa sivupohjassa jossa sitä tarvitaan, jolloin työmäärä ja virheiden mahdollisuus vähenee. Lisäksi makroon tehty muutos vaikuttaa heti kaikkiin sivupohjiin joissa se on käytössä.

    Oletetaan että Velocityssä on määriteltynä Velocimakro #tablerows($vari $lista). Tätä makroa voitaisiin käyttää missä tahansa sivupohjassa. Sitä voitaisiin käyttää useaan kertaan ja moneen eri käyttötarkoitukseen. Sieniasioita käsittelevässä sivupohjassa sieni.vm, #tablerows Velocimakroa voitaisiin käyttää listaamaan tyypillisen sienen osat:

    #tablerows( $cellbgcol $osat ) ]]>

    Kun Velocity luo sivun sivupohjasta sieni.vm, se etsii Velocimakron #tablerows sivupohjakirjastosta (joka on määritelty velocity.properties tiedostossa) ja tuottaa seuraavan tulosteen:

    volva stipe annulus gills pileus ]]> Velocimakron argumentit

    Velocimakrot voivat ottaa argumenteiksi mitä tahansa seuraavista VTL elementeistä:

    • Viittaus : mitä tahansa '$' merkillä alkavaa
    • Tekstivakio : esimerkiksi "$foo" tai 'hei'
    • Numerovakio : 1, 2 jne
    • Numeroväli : [ 1..2] tai [$foo .. $bar]
    • ObjectArray : [ "a", "b", "c"]
    • boolean arvo true (tosi)
    • boolean arvo false (epätosi)

    Kun siirrät viittauksia argumentteina Velocimakroille, huomaa, että viittaukset siirretään 'nimen mukaan' ('by name'). Tämä tarkoittaa sitä, että viittausten arvo 'haetaan' Velocimakrossa itsessään. Tämän ominaisuuden avulla voit siirtää viittauksia jotka ovat metodikutsuja, ja näin ko. metodeja kutsutaan Velocimakrossa. Esimerkiksi kun Velocimakroa kutsutaan seuraavasti:

    tuloksena viittauksen $foo metodia bar() kutsutaan 3 kertaa.

    Ensi katsomalta tämä ominaisuus saattaa vaikuttaa yllättävältä, mutta kun otat huomioon Velocimakrojen alkuperäisen tarkoituksen -- usein käytettyjen VTL komentojen leikkaa-liimaa kopioimisen vähentäminen -- ominaisuus on perusteltu. Sen avulla voit esimerkiksi siirtää Velocimakroon argumenttina tilansa muistavia (stateful) objekteja, kuten objektin joka generoi värejä peräkkäisessä järjestyksessä taulukon rivien värien määrittämiseksi.

    Jos sinun tarvitsee kiertää tämä ominaisuus, voit hakea arvon metodista uudeksi viittaukseksi, ja antaa sen argumentiksi:

    Velocimakro ominaisuudet

    velocity.properties tiedostossa on useita rivejä joiden avulla Velocimakrojen toimintaa voidaan muuttaa joustavasti. Huomaa että nämä arvot on dokumentoitu myös Kehittäjän oppaassa.

    velocimacro.library - Pilkulla eroteltu lista Velocimakro sivupohjakirjastoja. Oletuksena Velocity etsii yhtä kirjastoa: VM_global_library.vm. Velocimakro kirjastoja etsitään määritellystä sivupohjahakemistosta.

    velocimacro.permissions.allow.inline - Tämä ominaisuus päättää voidaanko Velocimakroja määrittää tavallisissa sivupohjissa. Ominaisuus voi saada arvon true (tosi) tai false (epätosi). Oletuksena on tosi, jolloin sivusuunnittelijat voivat määrittää Velocimakroja suoraan omissa sivupohjissaan.

    velocimacro.permissions.allow.inline.to.replace.global - Tämän ominaisuuden avulla voidaan määrittää voivatko sivupohjassa määritellyt Velocimakrot korvata yleisesti määritellyt, velocimacro.library ominaisuuden kautta ladatut Velocimakrot. Ominaisuus voi saada arvon true tai false. Oletuksena false, epätosi, jolloin sivupohjassa määritellyt Velocimakrot eivät voi korvata sivupohjakirjastoista ladattuja makroja.

    velocimacro.permissions.allow.inline.local.scope - Mahdolliset arvot ovat true tai false, oletuksena false. Tämä ominaisuus päättää ovatko sivupohjassa määritetyt Velocimakrot 'näkyviä' ainoastaan siinä sivupohjassa jossa ne on määritelty. Toisin sanoen kun tämä ominaisuus on asetettu arvoon true (tosi), sivupohja voi määrittää inline Velocimakroja jotka ovat käytettävissä vain sivupohjasta joka ne määritti. Tämän ominaisuuden avulla voidaan aikaansaada erikoisia vaikutuksia; jos yleisesti määritelty Velocimakro kutsuu toista yleisesti määriteltyä makroa, tämän ominaisuuden avulla sivupohja voi määrittää oman toteutuksensa jälkimmäisestä makrosta, jota ensimmäinen makro kutsuu. Sivupohjan paikallista makroa käytetään vain kun ensimmäistä makroa kutsutaan ko. sivupohjasta. Uusi makro ei vaikuta muihin sivupohjiin.

    velocimacro.library.autoreload - Tämä ominaisuus ohjaa Velocimakrokirjaston automaattista uudelleenlatausta. Kun ominaisuus on asetettu arvoon true kutsutun Velocimakron koodi tutkitaan mahdollisten muutosten varalta, ja se ladataan uudelleen mikäli tarpeellista. Näin voit muuttaa ja testata Velocimakrokirjastoa ilman että sinun tarvitsee käynnistää uudelleen sovellustasi tai sovellusalustaa, aivan kuten voit tehdä normaalien sivupohjienkin kanssa. Tämä asetus toimii vain kun resurssilataajien välimuisti on pois päältä (off, esim. file.resource.loader.cache = false). Tämä ominaisuus on tarkoitettu käytettäväksi vain sovelluksen kehitysvaiheessa, ei tuotantokäyttöön.

    Velocimakro Trivia

    Nykyisellään Velocimakrot tulee olla määriteltyinä ennen kuin niitä käytetään sivupohjissa. Tämä tarkoittaa sitä että #macro() määritystesi tulee sijaita ennen rivejä joissa käytät Velocimakroja.

    Tämä on tärkeää muistaa jos yrität käyttää ohjetta #parse() sivupohjaan jossa on inline #macro() ohjeita. Koska #parse() suoritetaan ajon aikana, ja parseri päättää ajon aikana onko sivupohjassa oleva Velocimakrolta näyttävä elementti Velocimakro, ei Velocimakrojen #parse():aminen toimi niin kuin olettaisi. Ongelma voidaan välttää helposti käyttämällä velocimacro.library toimintoa jonka avulla Velocity lataa Velocimakrosi käynnistyksen yhteydessä.

    VTL ohjeet voidaan suojata kenoviivalla ("\") samalla tavalla kuin VTL viittauksetkin.

    #include( "a.txt" ) ## \#include( "a.txt" ) tulostuu #include( "a.txt" ) \#include( "a.txt" ) ## \\#include ( "a.txt" ) tulostuu \ \\#include ( "a.txt" ) ]]>

    Eritystä tarkkaavaisuutta tarvitaan tapauksissa joissa suojataan VTL ohjeita jotka sisältävät useita skriptielementtejä samassa ohjeessa (kuten if-else-end lause). Seuraavassa on tyypillinen VTL if-lause:

    Jos $jazz on tosi (true), tuloste on

    Jos $jazz on epätosi (false), tulostetta ei tule. Skriptielementtien suojaaminen muuttaa tulostetta. Katso seuraavaa esimerkkiä:

    Riippumatta siitä onko $jazz tosi vai epätosi, tuloste on aina:

    Itse asiassa koska kaikki skriptielementit on suojattu, $jazz muuttujan totuusarvoa ei edes tutkita. Oletetaan että kenoviiva edeltää skriptielementtejä jotka on suojattu:

    Mikäli $jazz on tässä tapauksessa tosi, tuloste on:

    Tämän ymmärtämiseksi huomaa, että #if( arg ) rivillä olevaa rivinvaihtoa (return) ei kopioida tulosteeseen. Tämän vuoksi #if() lauseen runko ('Vyacheslav Ganelin') on '\\' merkinnästä saadun ensimmäisen '\' merkin kanssa samalla rivillä. Jälkimmäinen '\' merkki on toisella rivillä kuin teksti, koska tekstin lopussa on rivinvaihto ja jälkimmäinen '\\' merkinnästä saatu '\' merkki on ennen #end ohjetta, joten merkki kuuluu edelleen #if() lauseen runkoon.

    Jos $jazz on epätosi, tuloste on:

    Huomaa että ongelmia tulee mikäli skriptielementtejä ei ole suojattu oikein.

    Esimerkissä #if on suojattu, mutta #end elementti on edelleen käytössä. Liian monta lopetuselementtiä sivupohjassa aiheuttaa virheen sivua luotaessa.

    Vaikka tässä ohjeessa oleva VTL on usein muotoiltu rivivaihdoin ja välilyönnein, alla oleva VTL

    on yhtä toimiva kuin seuraava kodinpätkä jonka Geir Magnusson Jr. lähetti Velocityn käyttäjien postituslistalle:

    Velocity syö ylimääräiset välilyönnit. Edellinen koodinpätkä voitaisiin kirjoittaa seuraavasti:

    tai

    Kussakin tapauksessa tulos on sama.

    Velocitylla on muutamia sisäänrakennettuja matemaattisia funktioita joita voidaan käyttää sivupohjissa #set ohjeen kanssa. Seuraavat yhtälöt ovat esimerkkejä yhteen-, vähennys-, kerto- sekä jakolaskuista.

    Kun kaksi kokonaislukua jaetaan keskenään, tuloksena on kokonaisluku, jonka arvo on jakolaskun kokonaisosa. Jakojäännös voidaan laskea modulo-operaattorilla (%).

    Velocityllä on sisäänrakennettu keino nollalla jakamisen käsittelemiseen. Seuraavassa esimerkissä:

    Viittaukseen $uhoh asetetaan tulos operaatiosta viisi jaettuna nollalla. Kun Velocity näyttää tämän sivupohjan, tuloste on:

    Suunnittelijoiden on otettava huomioon myös, että #set tuottaa merkkijonoja, jotka on muunnettava kokonaisluvuiksi jotta niitä voidaan käyttää vaihteluväliä määritettäessä (range operator). Seuraavassa esimerkki tällaisesta muunnoksesta:

    Tuloksena on 17.

    Vaihteluväliä voidaan käyttää #set ja #foreach lauseiden yhteydessä. Vaihteluväli tuottaa kokonaislukuja sisältäviä oliotaulukoita seuraavalla tavalla:

    Sekä n että m pitää olla tai niiden tulee tuottaa kokonaislukuja. Mikäli m on pienempi kuin n lasketaan vaihteluvälin luvut alaspäin. Seuraavassa esimerkkejä vaihteluvälin käytöstä:

    Tuottaa seuraavan tulosteen:

    Huomaa että vaihteluvälioperaattori tuottaa taulukon vain kun sitä käytetään #set tai #foreach ohjeiden kanssa, kuten neljännestä esimerkistä käy selville.

    Vaihteluvälioperaattori on erityisen käyttökelpoinen kun halutaan tehdä verkkosivun taulukko standardikokoiseksi, mutta joissain tapauksissa taulukon täyttämiseksi ei ole riittävästi dataa.

    Kun viittaus hiljennetään ! merkillä ja ! merkkiä edeltää suojausmerkki \ käsitellään viittaus erityisellä tavalla. Huomaa erot normaalin suojauksen ja tilanteen jossa \ edeltää ! merkkiä, välillä.

    Tulosteena on:

    Vertaa tätä normaaliin suojaukseen, jossa \ on $ merkin edellä:

    Tulosteena on:

    Tämä osio on Velocimakroaiheinen mini-FAQ. Osio muuttuu ajan myötä, joten uutta tietoa hakevien kannattanee palata sivulle aika ajoin.

    Huom! : Tässä osiossa 'Velocimakro':ihin viitataan usein lyhenteellä 'VM'.

    Voinko käyttää ohjetta tai toista VM:a argumenttina VM:oon?

    Esimerkki : #center( #bold("hello") )

    Et. Ohje ei ole sallittu argumentti ohjeelle, ja VM on käytännöllisesti katsoen ohje.

    Kuitenkin..., voit kiertää rajoituksen. Yksinkertainen ratkaisu on käyttää hyväksi sitä että lainausmerkeissä (") oleva teksti tulkitaan. Tämä ansiosta voit tehdä seuraavasti:

    Voit myös säästää rivin...

    Huomaa että jälkimmäisessä esimerkissä parametri käsitellään VM:n sisällä, ei kutsun tasolla. Toisin sanoen VM:lle annettu parametri siirretään kokonaisuudessaan ja käsitellään VM:ssa johon se siirrettiin. Tämän ansiosta voit tehdä esimerkiksi seuraavaa:

    Tulosteeksi tulee

    koska parametrin "#inner($bar)" tulkitseminen tapahtuu lauseen #outer() sisällä, käytetään muuttujan $bar arvoa joka asetettiin #outer VM:ssa.

    Tämä on tarkoituksellinen ja tarkkaan vaalittu ominaisuus - parametrit siirretään 'nimen mukaan' ('by name') VM:oon, jotta voit siirtää VM:oon tilansa muistavia (stateful) viittauksia kuten

    Hei Siellä #end #foo( $bar.rivinVari() ) ]]>

    jossa rivinVari() metodia kutsutaan toistuvasti, ei vain kerran. Sen välttämiseksi kutsu metodia VM:n ulkopuolelta ja siirrä arvo VM:oon.

    Voinko rekisteröidä Velocimakroja #parse() :n kautta?

    Nykyisellään Velocimakrot tulee olla määriteltyinä ennen ensimmäistä käyttöä. Tämä tarkoittaa sitä että #macro() määritystesi tulisi tulla ennen kuin käytät Velocimakroja.

    Tämä on tärkeää muistaa jos yrität käyttää ohjetta #parse() sivupohjaan jossa on inline #macro() ohjeita. Koska #parse() suoritetaan ajon aikana, ja parseri päättää ajon aikana onko sivupohjassa oleva Velocimakrolta näyttävä elementti Velocimakro, ei Velocimakrojen #parse():aminen toimi niin kuin olettaisi. Ongelma voidaan välttää helposti käyttämällä velocimacro.library toimintoa jonka avulla Velocity lataa Velocimakrosi käynnistyksen yhteydessä.

    Mitä tarkoittaa Velocimakrojen automaattinen uudelleenlataus?

    On olemassa asetus joka on tarkoitettu käytettäväksi järjestelmän kehityksen aikana, ei käytössä olevassa järjestelmässä :

    velocimacro.library.autoreload

    joka on oletuksena pois käytöstä (false). Kun ominaisuus on asetettu käyttöön (true) yhdessä asetuksen

    <type>.resource.loader.cache = false

    kanssa (jossa <type> on resurssilataajan nimi jota käytät, kuten 'file'), silloin Velocity lataa automaattisesti Velocitymakroihin tekemäsi muutokset silloin kun teet niitä, joten sinun ei tarvitse käynnistää uudelleen sovellusalustaa (tai ohjelmaa) tai turvautua johonkin muuhun kikkaan saadaksesi muuttuneet Velocitymakrosi käyttöön.

    Yksinkertainen konfiguraatio saattaisi näyttää seuraavalta:

    Älä käytä näitä asetuksia tuotantokäytössä.

    Yleinen kehittäjien kysymä kysymys on Kuinka yhdistän merkkijonoja? Onko olemassa Javan '+' operaattoria vastaavaa toimintoa?.

    Viittausten liittämiseksi yhteen VTL:ssa, sinun tarvitsee vain 'laittaa ne yhteen'. Konteksti jossa yhdistät viittaukset vaikuttaa tuloksiin, joten esimerkit ovat paikallaan.

    Normaalissa tapauksessa (jolloin sekoitat muuttujat sivupohjan muuhun sisältöön) :

    tulosteena on 'Kello on BigBen'. Hieman mielenkiintoisemmassa tapauksessa, kuten silloin kun haluat liittää merkkijonot siirrettäväksi parametrina metodille, tai asettaaksesi uuden viittauksen, tee seuraavasti:

    Josta tulee sama tuloste. Viimeisenä esimerkkinä, kun haluat sekoittaa 'staattisia' merkkijonoja viittauksiin, saatat joutua käyttämään 'muodollista viittausten merkintää' :

    Nyt tuloste on 'Kello on BigTallBen'. Muodollista viittausten merkintää käytetään, jotta parseri tietäisi että tarkoitat viittauksellasi muuttujaa '$size' eikä '$sizeTall', jota se käyttäisi mikäli et olisi käyttänyt '{}' merkkejä.

    Mikäli löydät tästä ohjeesta virheitä tai haluat antaa ohjetta koskevaa palautetta, ole hyvä ja lähetä sähköpostia Velocity käyttäjälistalle. Kiitos!

    velocity-1.7/xdocs/docs/glossary.xml0000755000175000017500000003371411156517252017554 0ustar moellermoeller Glossary Velocity Documentation Team
    Anakia
    An XML transformation tool that uses JDOM and Velocity to transform XML documents into the format of your choice.
    Block Directive
    A directive that spans multiple lines. The block starts with a block directive such as #if, #foreach, or #macro and ends with the #end directive.
    #break
    A directive that stops the rendering of the current (innermost) content directive or a specified content directive if the scope control provided for that content directive is passed to #break as an argument: (e.g. #break($foreach.parent)).
    Comment
    Allow descriptive text to be included in the template that will not be placed into the output of the template engine. Single line comments begin with ##. Multi-line comments begin with #* and end with *#
    Content Directive
    A directive that outputs content when rendering a template. The default ones automatically have a scope control made available in the during their rendering.
    Context
    A means to import Java objects into a Velocity template.
    Directive
    Easy to use "active" elements that manipulate template output. There are both line and block directives.
    DocBook Framework
    A framework inteded to help create high quality documentation suitable for online viewing and printing.
    DVSL
    Declarative Velocity Style Language. A tool modeled after XSLT that is used for general XML transformations using the VTL as the templating language.
    #else
    A directive that must be used with an #if. It allows text to be included only if the #if was false.
    #elseif
    A directive that must be used with an #if. It allows text to be included if the #if was false and if its own statement is true.
    Equivalence Operator
    == Used to directly compare numbers, strings, or objects. If the objects that are being compared are different classes, toString() is called first and then they are compared.
    #end
    Ends block directives such as #if, #foreach and #macro.
    Escaping
    Removing the special meaning of a # or $ so that you can use these characters without Velocity interpretting it as the start of a reference or directive. Escaping is done by putting a \ character before the # or $.
    #evaluate
    A directive which dynamically evaluates a string literal or reference.
    #foreach
    A directive that allows you to repeat something on every value in a Collection, Array, Iterable, Map or (as of Velocity 1.6+) object with a public Iterator iterator() method.
    #include
    A directive that allows the template designer to import a local file, which is then inserted into the location where the #include directive is defined. Multiple files may be included by seperating the file names with commas.
    Identifier
    The name of a variable. Identifiers must start with an alphabetic character (a .. z, A .. Z). The rest of the characters are limited to alphabetic, numberic (0 .. 9), hyphens ("-"), and underscores ("_").
    #if
    A directive that allows for text to only be included if a statement is true.
    Formal Reference Notation
    A notation for references that is more formal than the shorthand. The formal notation consists of a $ character followed by a { character and then the identifiers used in the shorthand notation and then a } character. Formal notation is often useful when references are directly adjacent to text in a template.
    LHS
    Left Hand Side of an assignment
    Line Directive
    A directive that is done all on one line, such as #set.
    Literal
    A string enclosed in double quotes
    #macro
    See Velocimacro.
    Method
    A type of reference. Methods are defined in the Java code and are capable of doing something useful. The shorthand notation consists of a leading $ character followed by an identifier, folowed by a VTL Method Body.
    MVC
    Model-View-Controller design pattern. Allows web page designers to focus on creating a well-designed site and allows programmers to focus on writing good code
    #parse
    A directive that includes a local file that contains VTL. Velocity then parses the VTL and renders the template.
    Property
    A type of reference. The shorthand notation consists of a leading $ character followed by an identifier, followed by a . character and another identifier.
    Quiet Reference Notation
    Another notation for references. A ! character is inserted between the $ and the identifier. This overrides Velocity's default behavior if the reference is undefined. Normally, if a reference is undefined, the name of the reference that was given is used instead. With this notation, a blank text field is used.
    Reference
    Begins with $ and are used to get something. There are three types: variables, properties, and methods.
    Resource
    A general text resource that can be loaded from a variety of sources using a Resource Loader.
    Resource Loader
    A class used by a Velocity Engine to load resources from the file system, classpath, URLs or even a database depending on the implementation.
    RHS
    Right Hand Side of an assignment
    Scope Control
    The reference automatically provided as a way of scoping/namespacing references (to avoid polluting the global context) within the given content directive and also providing a "label" for #break to use when breaking out of multiple content directives at once.
    #set
    The directive that is used for setting the value of a reference.
    #stop
    A directive that stops the execution of the template engine. #stop is useful for debugging templates.
    String Interpolation
    Using a variable inside of a string. For example, "Hello $name" would be "Hello" and then whatever value is stored in $name.
    Template
    A file containing code in a template language such as the VTL that can be run through a template engine like Velocity to produce dynamic output.
    Template Engine
    An engine that merges a context with a template to produce output.
    Template Language
    A language such as the VTL that can be used to create templates.
    Texen
    Texen is a general purpose text generating utility that is driven by Ant.
    Tool
    A plain old Java object that is useful in a template but it is not meant to be rendered in output. Tools are meant to be used but not to be seen.
    Turbine
    A servlet based framework that allows experienced Java developers to quickly build web applications. Turbine allows you to personalize the web sites and to use user logins to restrict access to parts of your application.
    Variable
    A type of reference. Variables represents values that can change. The shorthand notation consists of a leading $ character followed by an identifier
    Velocimacro
    The #macro directive allows designers to define a repeated segment of template. To create a macro "d", you would use #macro(d) followed by the segment of template followed by #end. Macros can have as many arguments as necessary by adding them inside the parentheses such as #macro(d $arg1 $arg2).
    Velocity
    A Java-based template engine.
    VelocityEngine
    The engine that generates web pages and other output from templates containing VTL code.
    Velocity Singleton
    A singleton wrapper around a Velocity engine that is shared across the JVM (or ClassLoader) and may thus be referenced directly without needing to pass an instance around. This allows localized configuration and sharing of resources.
    VelocityTools
    A collection of Tools and infrastructure to easily, automatically and transparently make tools and static data available to Velocity templates.
    VTL
    Velocity Template Language. The powerful template language that is used with Velocity.
    VTL Method Call
    Consists of an identifier followed by a ( character, followed by an optional parameter list, followed by a ) character. VTL allows template designers to call any public method declared in a public class on values placed in the context.
    velocity-1.7/xdocs/docs/getting-started.xml0000644000175000017500000000710011273713211020772 0ustar moellermoeller Velocity Getting Started Velocity Documentation Team

    Velocity is easy to use! A quick way to get started is to skim the references below, then look at the examples and source provided in the distribution. For developers writing web-based applications, the Web Application Guide is highly recommended!

    The best place to start is with the examples provided in the distribution, and with the source code itself, which is included.

    You can download the latest release version of Velocity or Velocity Tools from the main Apache Velocity download site. For Velocity itself, source is included with the binary download.

    If you want to download the latest source, you can do so via the Subversion (svn) source control system, or download a complete nightly snapshot.

    Instructions for building Velocity from source can be found in the Build document.

    Our API documentation is available online, as part of the distribution package, and of course, you can generate it yourself from the included source code.

    If you would like to create a full set of detailed API documentation for Velocity, go to the build directory and run:

    The docs will be found in the /bin/apidocs/ directory.

    Note: Velocity uses the Apache Ant build tool for all code and documentation generation, so you will need to have it installed. Velocity requires at least Apache Ant 1.7.

    velocity-1.7/xdocs/docs/committers.xml0000644000175000017500000000442511365612260020066 0ustar moellermoeller Velocity Committers Velocity Documentation Team

    While many individuals have contributed to Velocity in past and present, the following are the currently active committers for the project.

    Listed alphabetically:

    Name Email Affiliation
    Will Glass-Husain wglass@apache.org Forio Business Simulations
    Geir Magnusson Jr. geirm@apache.org Independent
    Daniel L. Rall dlr@finemaltcoding.com CollabNet
    Henning Schmiedehausen hps@intermeta.de INTERMETA - Gesellschaft für Mehrwertdienste mbH
    Nathan Bubna nbubna@apache.org ESHA Research
    Claude Brisson cbrisson@apache.org
    Byron Foster byron@apache.org
    velocity-1.7/xdocs/docs/overview.xml0000644000175000017500000001504710557734552017563 0ustar moellermoeller Velocity Overview Velocity Documentation Team

    Velocity is a template engine that can be used for many purposes. Some common types of applications which use Velocity are:

    • Web applications. Web designers create HTML pages with placeholders for dynamic information. The page is processed with VelocityViewServlet or any of a number of frameworks which support Velocity. This approach to web application development is called Model-View-Controller or MVC and is intended to be a direct replacement for applications developed with Java Server Pages (JSPs) or PHP.
    • Source code generation. Velocity can be used to generate Java source code, SQL, or PostScript based on templates. The PoweredByVelocity page lists a number of open source and commercial development software packages which use Velocity in this manner.
    • Automatic emails. Many applications generate automatic emails for account signup, password reminders or automatically sent reports. Using Velocity, the email template can be stored in a text file rather than directly embedded in your Java code.
    • XML transformation. Velocity provides an ant task called Anakia which reads an XML file and makes it available to a Velocity template. A common application is to convert documentation stored in a generic "xdoc" format into a styled HTML document.

    Velocity allows web page designers and other template writers to include markup statements called references in the page. These references are pulled from a Context object -- essentially a hashtable that provides get and set methods for retrieving and setting objects -- and the corresponding values are inserted directly in a page. Velocity provides basic control statements, that can loop over a collection of values (foreach) or conditionally show a block of text (if/else). The ability to call arbitrary Java methods, include other files, and to create macros that can be repeatedly used make this a powerful yet easy-to-use approach for creating dynamic web page or other text files.

    Velocity enforces a Model-View-Controller (MVC) style of development by separating Java code from HTML template code. Unlike JSPs, Velocity does not allow Java code to be embedded in pages. Unlike PHP, Velocity does not implement features with other functions. The MVC approach is one of Velocity's great strengths, and allows for more maintainable and better-designed web pages.

    Although MVC-style development can sometimes lead to longer incubation periods for web sites, particularly if the developers involved are new to MVC, this approach saves time over the long term (believe us, we have been doing this for a long time now). The MVC abstraction prevents web page designers from messing with a software engineer's Java code, and programmers from unduly influencing the look of web sites. Velocity enforces a contract that defines what roles people play in the web site development process.

    While Velocity is generally useful within an application as is, there are a number of ways its capabilities can be extended.

    • Special types of objects, generically called "Tools", contain methods but no data. When placed into the Velocity context the template can call these methods to do basic tasks like formatting numbers or escaping HTML entities.
    • Velocity provides a selection of resource loaders that can retrieve templates from text files, the classpath, even a database. But if that's not enough you can write your own resource loader to retrieve in a custom manner.
    • Event Handlers provide hooks to perform custom actions upon certain events, such as the insertion of a reference into text.
    • Advanced users can write a custom Introspector which retrieves reference properties and methods. For example, you might create an introspector that retrieves data from Lucene or other search engine indexes.
    • Finally, for the truly adept, the grammar for Velocity is processed in a parser generated by JavaCC (Java Compiler Compiler) using the JJTree extension to create an Abstract Syntax Tree. By changing the JavaCC specification file and recompiling, the Velocity syntax itself can be changed.

    Velocity's design concept is borrowed from WebMacro. Those involved in the Velocity project acknowledge and appreciate the development and design work that went into the WebMacro project.

    velocity-1.7/xdocs/docs/index.xml0000644000175000017500000001323511470267434017014 0ustar moellermoeller Velocity Velocity Documentation Team

    Velocity is a Java-based template engine. It permits anyone to use a simple yet powerful template language to reference objects defined in Java code.

    When Velocity is used for web development, Web designers can work in parallel with Java programmers to develop web sites according to the Model-View-Controller (MVC) model, meaning that web page designers can focus solely on creating a site that looks good, and programmers can focus solely on writing top-notch code. Velocity separates Java code from the web pages, making the web site more maintainable over its lifespan and providing a viable alternative to Java Server Pages (JSPs) or PHP.

    Velocity's capabilities reach well beyond the realm of the web; for example, it can be used to generate SQL, PostScript and XML (see Anakia for more information on XML transformations) from templates. It can be used either as a standalone utility for generating source code and reports, or as an integrated component of other systems. For instance, Velocity provides template services for the Turbine web application framework, together resulting in a view engine facilitating development of web applications according to a true MVC model.

    The current stable release version is version 1.7.

    The release distribution is available as a combined source/binary distribution in tar.gz and zip formats, and can be downloaded through the Apache Mirror system.

    The Velocity jars are also available through the central Maven repository.

    Older releases are archived at the Apache Velocity archives.

    Nightly snapshots of the Velocity subversion source code tree can be found on our nightly snapshot site.

    Caveat! These snapshots are generated automatically from the project source code repository. As this is our live development workspace, there are no guarantees as to what you will find there, although we do our best to maintain a buildable source tree. If you are looking for the stable supported release, please use the current release of Velocity.

    Please be aware that these snapshots are not official releases of Apache Velocity software. They are provided for developer convenience only!

    If you are willing to risk getting dirty, we invite you to try the nightly snapshot to see the current state of affairs. (and help out!) Public Subversion access is also available.

    The Velocity project appreciates any contributions, including documentation help, source code and feedback. Suggested changes should come in the form of source code and/or feedback.

    velocity-1.7/xdocs/docs/user-guide.xml0000644000175000017500000023637511156517252017767 0ustar moellermoeller Velocity User Guide Velocity Documentation Team
    1. About this Guide
    2. What is Velocity?
    3. What can Velocity do for me?
      1. The Mud Store example
    4. Velocity Template Language (VTL): An Introduction
    5. Hello Velocity World!
    6. Comments
    7. References
      1. Variables
      2. Properties
      3. Methods
      4. Property Lookup Rules
      5. Rendering
      6. Index Notation
    8. Formal Reference Notation
    9. Quiet Reference Notation
    10. Strict Reference Mode
    11. Case Substitution
    12. Directives
      1. Set
      2. Literals
      3. If-Else Statements
        1. Relational and Logical Operators
      4. Foreach Loops
      5. Include
      6. Parse
      7. Break
      8. Stop
      9. Evaluate
      10. Define
      11. Velocimacros
    13. Getting literal
      1. Currency
      2. Escaping Valid VTL References
      3. Escaping Invalid VTL References
      4. Escaping VTL Directives
    14. VTL: Formatting Issues
    15. Other Features and Miscellany
      1. Math
      2. Range Operator
      3. Advanced Issues: Escaping and !
      4. Velocimacro Miscellany
      5. String Concatenation
    16. Feedback

    The Velocity User Guide is intended to help page designers and content providers get acquainted with Velocity and the syntax of its simple yet powerful scripting language, the Velocity Template Language (VTL). Many of the examples in this guide deal with using Velocity to embed dynamic content in web sites, but all VTL examples are equally applicable to other pages and templates.

    Thanks for choosing Velocity!

    Velocity is a Java-based template engine. It permits web page designers to reference methods defined in Java code. Web designers can work in parallel with Java programmers to develop web sites according to the Model-View-Controller (MVC) model, meaning that web page designers can focus solely on creating a well-designed site, and programmers can focus solely on writing top-notch code. Velocity separates Java code from the web pages, making the web site more maintainable over the long run and providing a viable alternative to Java Server Pages (JSPs) or PHP.

    Velocity can be used to generate web pages, SQL, PostScript and other output from templates. It can be used either as a standalone utility for generating source code and reports, or as an integrated component of other systems. When complete, Velocity will provide template services for the Turbine web application framework. Velocity+Turbine will provide a template service that will allow web applications to be developed according to a true MVC model.

    Suppose you are a page designer for an online store that specializes in selling mud. Let's call it "The Online Mud Store". Business is thriving. Customers place orders for various types and quantities of mud. They login to your site using their username and password, which allows them to view their orders and buy more mud. Right now, Terracotta Mud is on sale, which is very popular. A minority of your customers regularly buys Bright Red Mud, which is also on sale, though not as popular and usually relegated to the margin of your web page. Information about each customer is tracked in your database, so one day the question arises, Why not use Velocity to target special deals on mud to the customers who are most interested in those types of mud?

    Velocity makes it easy to customize web pages to your online visitors. As a web site designer at The Mud Room, you want to make the web page that the customer will see after logging into your site.

    You meet with software engineers at your company, and everyone has agreed that $customer will hold information pertaining to the customer currently logged in, that $mudsOnSpecial will be all the types mud on sale at present. The $flogger object contains methods that help with promotion. For the task at hand, let's concern ourselves only with these three references. Remember, you don't need to worry about how the software engineers extract the necessary information from the database, you just need to know that it works. This lets you get on with your job, and lets the software engineers get on with theirs.

    You could embed the following VTL statement in the web page:

    Hello $customer.Name! #foreach( $mud in $mudsOnSpecial ) #if ( $customer.hasPurchased($mud) ) #end #end
    $flogger.getPromo( $mud )
    ]]>

    The exact details of the foreach statement will be described in greater depth shortly; what's important is the impact this short script can have on your web site. When a customer with a penchant for Bright Red Mud logs in, and Bright Red Mud is on sale, that is what this customer will see, prominently displayed. If another customer with a long history of Terracotta Mud purchases logs in, the notice of a Terracotta Mud sale will be front and center. The flexibility of Velocity is enormous and limited only by your creativity.

    Documented in the VTL Reference are the many other Velocity elements, which collectively give you the power and flexibility you need to make your web site a web presence. As you get more familiar with these elements, you will begin to unleash the power of Velocity.

    The Velocity Template Language (VTL) is meant to provide the easiest, simplest, and cleanest way to incorporate dynamic content in a web page. Even a web page developer with little or no programming experience should soon be capable of using VTL to incorporate dynamic content in a web site.

    VTL uses references to embed dynamic content in a web site, and a variable is one type of reference. Variables are one type of reference that can refer to something defined in the Java code, or it can get its value from a VTL statement in the web page itself. Here is an example of a VTL statement that could be embedded in an HTML document:

    This VTL statement, like all VTL statements, begins with the # character and contains a directive: set. When an online visitor requests your web page, the Velocity Templating Engine will search through your web page to find all # characters, then determine which mark the beginning of VTL statements, and which of the # characters that have nothing to do with VTL.

    The # character is followed by a directive, set. The set directive uses an expression (enclosed in brackets) -- an equation that assigns a value to a variable. The variable is listed on the left hand side and its value on the right hand side; the two are separated by an = character.

    In the example above, the variable is $a and the value is Velocity. This variable, like all references, begins with the $ character. String values are always enclosed in quotes, either single or double quotes. Single quotes will ensure that the quoted value will be assigned to the reference as is. Double quotes allow you to use velocity references and directives to interpolate, such as "Hello $name", where the $name will be replaced by the current value before that string literal is assigned to the left hand side of the =

    The following rule of thumb may be useful to better understand how Velocity works: References begin with $ and are used to get something. Directives begin with # and are used to do something.

    In the example above, #set is used to assign a value to a variable. The variable, $a, can then be used in the template to output "Velocity".

    Once a value has been assigned to a variable, you can reference the variable anywhere in your HTML document. In the following example, a value is assigned to $foo and later referenced.

    #set( $foo = "Velocity" ) Hello $foo World! ]]>

    The result is a web page that prints "Hello Velocity World!".

    To make statements containing VTL directives more readable, we encourage you to start each VTL statement on a new line, although you are not required to do so. The set directive will be revisited in greater detail later on.

    Comments allows descriptive text to be included that is not placed into the output of the template engine. Comments are a useful way of reminding yourself and explaining to others what your VTL statements are doing, or any other purpose you find useful. Below is an example of a comment in VTL.

    A single line comment begins with ## and finishes at the end of the line. If you're going to write a few lines of commentary, there's no need to have numerous single line comments. Multi-line comments, which begin with #* and end with *#, are available to handle this scenario.

    Here are a few examples to clarify how single line and multi-line comments work:

    There is a third type of comment, the VTL comment block, which may be used to store any sort of extra information you want to track in the template (e.g. javadoc-style author and versioning information):

    There are three types of references in the VTL: variables, properties and methods. As a designer using the VTL, you and your engineers must come to an agreement on the specific names of references so you can use them correctly in your templates.

    Variables
    The shorthand notation of a variable consists of a leading "$" character followed by a VTL Identifier. A VTL Identifier must start with an alphabetic character (a .. z or A .. Z). The rest of the characters are limited to the following types of characters:

    • alphabetic (a .. z, A .. Z)
    • numeric (0 .. 9)
    • hyphen ("-")
    • underscore ("_")

    Here are some examples of valid variable references in the VTL:

    When VTL references a variable, such as $foo, the variable can get its value from either a set directive in the template, or from the Java code. For example, if the Java variable $foo has the value bar at the time the template is requested, bar replaces all instances of $foo on the web page. Alternatively, if I include the statement

    The output will be the same for all instances of $foo that follow this directive.

    Properties
    The second flavor of VTL references are properties, and properties have a distinctive format. The shorthand notation consists of a leading $ character followed a VTL Identifier, followed by a dot character (".") and another VTL Identifier. These are examples of valid property references in the VTL:

    Take the first example, $customer.Address. It can have two meanings. It can mean, Look in the hashtable identified as customer and return the value associated with the key Address. But $customer.Address can also be referring to a method (references that refer to methods will be discussed in the next section); $customer.Address could be an abbreviated way of writing $customer.getAddress(). When your page is requested, Velocity will determine which of these two possibilities makes sense, and then return the appropriate value.

    Methods
    A method is defined in the Java code and is capable of doing something useful, like running a calculation or arriving at a decision. Methods are references that consist of a leading "$" character followed a VTL Identifier, followed by a VTL Method Body. A VTL Method Body consists of a VTL Identifier followed by an left parenthesis character ("("), followed by an optional parameter list, followed by right parenthesis character (")"). These are examples of valid method references in the VTL:

    The first two examples -- $customer.getAddress() and $purchase.getTotal() -- may look similar to those used in the Properties section above, $customer.Address and $purchase.Total. If you guessed that these examples must be related some in some fashion, you are correct!

    VTL Properties can be used as a shorthand notation for VTL Methods. The Property $customer.Address has the exact same effect as using the Method $customer.getAddress(). It is generally preferable to use a Property when available. The main difference between Properties and Methods is that you can specify a parameter list to a Method.

    The shorthand notation can be used for the following Methods

    We might expect these methods to return the names of planets belonging to the sun, feed our earthworm, or get a photograph from an album. Only the long notation works for the following Methods.

    As of Velocity 1.6, all array references are now "magically" treated as if they are fixed-length lists. This means that you can call java.util.List methods on array references. So, if you have a reference to an array (let's say this one is a String[] with three values), you can do:

    Also new in Velocity 1.6 is support for vararg methods. A method like public void setPlanets(String... planets) or even just public void setPlanets(String[] planets) (if you are using a pre-Java 5 JDK), can now accept any number of arguments when called in a template.

    Property Lookup Rules
    As was mentioned earlier, properties often refer to methods of the parent object. Velocity is quite clever when figuring out which method corresponds to a requested property. It tries out different alternatives based on several established naming conventions. The exact lookup sequence depends on whether or not the property name starts with an upper-case letter. For lower-case names, such as $customer.address, the sequence is

    1. getaddress()
    2. getAddress()
    3. get("address")
    4. isAddress()
    For upper-case property names like $customer.Address, it is slightly different:
    1. getAddress()
    2. getaddress()
    3. get("Address")
    4. isAddress()

    Rendering
    The final value resulting from each and every reference (whether variable, property, or method) is converted to a String object when it is rendered into the final output. If there is an object that represents $foo (such as an Integer object), then Velocity will call its .toString() method to resolve the object into a String.

    Index Notation
    Using the notation of the form $foo[0] can be used to access a given index of an object. This form is synonymous with calling the get(Object) method on a given object i.e, $foo.get(0), and provides essentially a syntactic shorthand for such operations. Since this simply calls the get method all of the following are valid uses:

    $foo[0] ## $foo takes in an Integer look up $foo[$i] ## Using another reference as the index $foo["bar"] ## Passing a string where $foo may be a Map

    The bracketed syntax also works with Java arrays since Velocity wraps arrays in an access object that provides a get(Integer) method which returns the specified element.

    The bracketed syntax is valid anywhere .get is valid, for example:

    $foo.bar[1].junk $foo.callMethod()[1] $foo["apple"][4]

    A reference can also be set using index notation, for example:

    #set($foo[0] = 1) #set($foo.bar[1] = 3) #set($map["apple"] = "orange")

    The specified element is set with the given value. Velocity tries first the 'set' method on the element, then 'put' to make the assignment.

    Formal Reference Notation
    Shorthand notation for references was used for the examples listed above, but there is also a formal notation for references, which is demonstrated below:

    In almost all cases you will use the shorthand notation for references, but in some cases the formal notation is required for correct processing.

    Suppose you were constructing a sentence on the fly where $vice was to be used as the base word in the noun of a sentence. The goal is to allow someone to choose the base word and produce one of the two following results: "Jack is a pyromaniac." or "Jack is a kleptomaniac.". Using the shorthand notation would be inadequate for this task. Consider the following example:

    There is ambiguity here, and Velocity assumes that $vicemaniac, not $vice, is the Identifier that you mean to use. Finding no value for $vicemaniac, it will return $vicemaniac. Using formal notation can resolve this problem.

    Now Velocity knows that $vice, not $vicemaniac, is the reference. Formal notation is often useful when references are directly adjacent to text in a template.

    Quiet Reference Notation
    When Velocity encounters an undefined reference, its normal behavior is to output the image of the reference. For example, suppose the following reference appears as part of a VTL template.

    ]]>

    When the form initially loads, the variable reference $email has no value, but you prefer a blank text field to one with a value of "$email". Using the quiet reference notation circumvents Velocity's normal behavior; instead of using $email in the VTL you would use $!email. So the above example would look like the following:

    ]]>

    Now when the form is initially loaded and $email still has no value, an empty string will be output instead of "$email".

    Formal and quiet reference notation can be used together, as demonstrated below.

    ]]>

    Velocity 1.6 introduces the concept of strict reference mode which is activated by setting the velocity configuration property 'runtime.references.strict' to true. The general intent of this setting is to make Velocity behave more strictly in cases that are undefined or ambiguous, similar to a programming language, which may be more appropriate for some uses of Velocity. In such undefined or ambiguous cases Velocity will throw an exception. The following discussion outlines the cases in which strict behavior is different from traditional behavior.

    With this setting references are required to be either placed explicitly into the context or defined with a #set directive or Velocity will throw an exception. References that are in the context with a value of null will not produce an exception. Additionally, if an attempt is made to call a method or a property on an object within a reference that does not define the specified method or property then Velocity will throw an exception. This is also true if there is an attempt to call a method or property on a null value.

    In the following examples $bar is defined but $foo is not, and all these statements will throw an exception:

    Also, The following statements show examples in which Velocity will throw an exception when attempting to call methods or properties that do not exist. In these examples $bar contains an object that defines a property 'foo' which returns a string, and 'retnull' which returns null.

    In general strict reference behavior is true for all situations in which references are used except for a special case within the #if directive. If a reference is used within a #if or #elseif directive without any methods or properties, and if it is not being compared to another value, then undefined references are allowed. This behavior provides an easy way to test if a reference is defined before using it in a template. In the following example where $foo is not defined the statements will not throw an exception.

    Strict mode requires that comparisons of >, <, >= or <= within an #if directive makes sense. Also, the argument to #foreach must be iterable (this behavior can be modified with the property directive.foreach.skip.invalid). Finally, undefined macro references will also throw an exception in strict mode.

    References that Velocity attempts to render but evaluate to null will cause an Exception. To simply render nothing in this case the reference can be preceded by '$!' instead of '$', similar to non strict mode. Keep in mind this is different from the reference not existing in the context which will always throw an exception when attempting to render it in strict mode. For example, below $foo has a value of null in the context

    Now that you are familiar with references, you can begin to apply them effectively in your templates. Velocity references take advantage of some Java principles that template designers will find easy to use. For example:

    These examples illustrate alternative uses for the same references. Velocity takes advantage of Java's introspection and bean features to resolve the reference names to both objects in the Context as well as the objects methods. It is possible to embed and evaluate references almost anywhere in your template.

    Velocity, which is modelled on the Bean specifications defined by Sun Microsystems, is case sensitive; however, its developers have strove to catch and correct user errors wherever possible. When the method getFoo() is referred to in a template by $bar.foo, Velocity will first try $getfoo. If this fails, it will then try $getFoo. Similarly, when a template refers to $bar.Foo, Velocity will try $getFoo() first and then try getfoo().

    Note: References to instance variables in a template are not resolved. Only references to the attribute equivalents of JavaBean getter/setter methods are resolved (i.e. $foo.Name does resolve to the class Foo's getName() instance method, but not to a public Name instance variable of Foo).

    References allow template designers to generate dynamic content for web sites, while directives -- easy to use script elements that can be used to creatively manipulate the output of Java code -- permit web designers to truly take charge of the appearance and content of the web site.

    Directives always begin with a #. Like references, the name of the directive may be bracketed by a { and a } symbol. This is useful with directives that are immediately followed by text. For example the following produces an error:

    In such a case, use the brackets to separate #else from the rest of the line.

    #set

    The #set directive is used for setting the value of a reference. A value can be assigned to either a variable reference or a property reference, and this occurs in brackets, as demonstrated:

    The left hand side (LHS) of the assignment must be a variable reference or a property reference. The right hand side (RHS) can be one of the following types:

    • Variable reference
    • String literal
    • Property reference
    • Method reference
    • Number literal
    • ArrayList
    • Map

    These examples demonstrate each of the aforementioned types:

    NOTE: For the ArrayList example the elements defined with the [..] operator are accessible using the methods defined in the ArrayList class. So, for example, you could access the first element above using $monkey.Say.get(0).

    Similarly, for the Map example, the elements defined within the { } operator are accessible using the methods defined in the Map class. So, for example, you could access the first element above using $monkey.Map.get("banana") to return a String 'good', or even $monkey.Map.banana to return the same value.

    The RHS can also be a simple arithmetic expression:

    If the RHS is a property or method reference that evaluates to null, it will not be assigned to the LHS. Depending on how Velocity is configured, it is usually not possible to remove an existing reference from the context via this mechanism. (Note that this can be permitted by changing one of the Velocity configuration properties). This can be confusing for newcomers to Velocity. For example:

    If $query.criteria("name") returns the string "bill", and $query.criteria("address") returns null, the above VTL will render as the following:

    This tends to confuse newcomers who construct #foreach loops that attempt to #set a reference via a property or method reference, then immediately test that reference with an #if directive. For example:

    In the above example, it would not be wise to rely on the evaluation of $result to determine if a query was successful. After $result has been #set (added to the context), it cannot be set back to null (removed from the context). The details of the #if and #foreach directives are covered later in this document.

    One solution to this would be to pre-set $result to false. Then if the $query.criteria() call fails, you can check.

    Unlike some of the other Velocity directives, the #set directive does not have an #end statement.

    Literals

    When using the #set directive, string literals that are enclosed in double quote characters will be parsed and rendered, as shown:

    The output will be

    However, when the string literal is enclosed in single quote characters, it will not be parsed:

    This renders as:

    By default, this feature of using single quotes to render unparsed text is available in Velocity. This default can be changed by editing velocity.properties such that stringliterals.interpolate=false.

    Alternately, the #[[don't parse me!]]# syntax allows the template designer to easily use large chunks of uninterpreted and unparsed content in VTL code. This can be especially useful in place of escaping multiple directives or escaping sections which have content that would otherwise be invalid (and thus unparseable) VTL.

    Renders as:

    If / ElseIf / Else

    The #if directive in Velocity allows for text to be included when the web page is generated, on the conditional that the if statement is true. For example:

    Velocity! #end ]]>

    The variable $foo is evaluated to determine whether it is true, which will happen under one of two circumstances: (i) $foo is a boolean (true/false) which has a true value, or (ii) the value is not null. Remember that the Velocity context only contains Objects, so when we say 'boolean', it will be represented as a Boolean (the class). This is true even for methods that return boolean - the introspection infrastructure will return a Boolean of the same logical value.

    The content between the #if and the #end statements become the output if the evaluation is true. In this case, if $foo is true, the output will be: "Velocity!". Conversely, if $foo has a null value, or if it is a boolean false, the statement evaluates as false, and there is no output.

    An #elseif or #else element can be used with an #if element. Note that the Velocity Templating Engine will stop at the first expression that is found to be true. In the following example, suppose that $foo has a value of 15 and $bar has a value of 6.

    Go North #elseif( $foo == 10 ) Go East #elseif( $bar == 6 ) Go South #else Go West #end ]]>

    In this example, $foo is greater than 10, so the first two comparisons fail. Next $bar is compared to 6, which is true, so the output is Go South.

    Relational and Logical Operators

    Velocity uses the equivalent operator to determine the relationships between variables. Here is a simple example to illustrate how the equivalent operator is used.

    Note that the semantics of == are slightly different than Java where == can only be used to test object equality. In Velocity the equivalent operator can be used to directly compare numbers, strings, or objects. When the objects are of different classes, the string representations are obtained by calling toString() for each object and then compared.

    Velocity has logical AND, OR and NOT operators as well. Below are examples demonstrating the use of the logical AND, OR and NOT operators.

    This AND that #end ]]>

    The #if() directive will only evaluate to true if both $foo and $bar are true. If $foo is false, the expression will evaluate to false; $bar will not be evaluated. If $foo is true, the Velocity Templating Engine will then check the value of $bar; if $bar is true, then the entire expression is true and This AND that becomes the output. If $bar is false, then there will be no output as the entire expression is false.

    Logical OR operators work the same way, except only one of the references need evaluate to true in order for the entire expression to be considered true. Consider the following example.

    This OR That #end ]]>

    If $foo is true, the Velocity Templating Engine has no need to look at $bar; whether $bar is true or false, the expression will be true, and This OR That will be output. If $foo is false, however, $bar must be checked. In this case, if $bar is also false, the expression evaluates to false and there is no output. On the other hand, if $bar is true, then the entire expression is true, and the output is This OR That

    With logical NOT operators, there is only one argument :

    NOT that #end ]]>

    Here, the if $foo is true, then !$foo evaluates to false, and there is no output. If $foo is false, then !$foo evaluates to true and NOT that will be output. Be careful not to confuse this with the quiet reference $!foo which is something altogether different.

    There are text versions of all logical operators, including eq, ne, and, or, not, gt, ge, lt, and le.

    One more useful note. When you wish to include text immediately following a #else directive you will need to use curly brackets immediately surrounding the directive to differentiate it from the following text. (Any directive can be delimited by curly brackets, although this is most useful for #else).

    ]]>
    Foreach Loop

    The #foreach element allows for looping. For example:

    #foreach( $product in $allProducts )
  • $product
  • #end ]]>

    This #foreach loop causes the $allProducts list (the object) to be looped over for all of the products (targets) in the list. Each time through the loop, the value from $allProducts is placed into the $product variable.

    The contents of the $allProducts variable is a Vector, a Hashtable or an Array. The value assigned to the $product variable is a Java Object and can be referenced from a variable as such. For example, if $product was really a Product class in Java, its name could be retrieved by referencing the $product.Name method (ie: $Product.getName()).

    Lets say that $allProducts is a Hashtable. If you wanted to retrieve the key values for the Hashtable as well as the objects within the Hashtable, you can use code like this:

    #foreach( $key in $allProducts.keySet() )
  • Key: $key -> Value: $allProducts.get($key)
  • #end ]]>

    Velocity provides an easy way to get the loop counter so that you can do something like the following:

    #foreach( $customer in $customerList ) $foreach.count$customer.Name #end ]]>

    Velocity also now provides an easy way to tell if you are on the last iteration of a loop:

    If you want a zero-based index of the #foreach loop, you can just use $foreach.index instead of $foreach.count. Likewise, $foreach.first and $foreach.last are provided to compliment $foreach.hasNext. If you want to access these properties for an outer #foreach loop, you can reference them directly through the $foreach.parent or $foreach.topmost properties (e.g. $foreach.parent.index or $foreach.topmost.hasNext).

    It's possible to set a maximum allowed number of times that a loop may be executed. By default there is no max (indicated by a value of 0 or less), but this can be set to an arbitrary number in the velocity.properties file. This is useful as a fail-safe.

    If you want to stop looping in a foreach from within your template, you can now use the #break directive to stop looping at any time:

    5 ) #break #end $customer.Name #end ]]>

    The #include script element allows the template designer to import a local file, which is then inserted into the location where the #include directive is defined. The contents of the file are not rendered through the template engine. For security reasons, the file to be included may only be under TEMPLATE_ROOT.

    The file to which the #include directive refers is enclosed in quotes. If more than one file will be included, they should be separated by commas.

    The file being included need not be referenced by name; in fact, it is often preferable to use a variable instead of a filename. This could be useful for targeting output according to criteria determined when the page request is submitted. Here is an example showing both a filename and a variable.

    The #parse script element allows the template designer to import a local file that contains VTL. Velocity will parse the VTL and render the template specified.

    Like the #include directive, #parse can take a variable rather than a template. Any templates to which #parse refers must be included under TEMPLATE_ROOT. Unlike the #include directive, #parse will only take a single argument.

    VTL templates can have #parse statements referring to templates that in turn have #parse statements. By default set to 10, the directive.parse.max.depth line of the velocity.properties allows users to customize maximum number of #parse referrals that can occur from a single template. (Note: If the directive.parse.max.depth property is absent from the velocity.properties file, Velocity will set this default to 10.) Recursion is permitted, for example, if the template dofoo.vm contains the following lines:

    It would reference the template parsefoo.vm, which might contain the following VTL:

    0 ) #parse( "parsefoo.vm" ) #else All done with parsefoo.vm! #end ]]>

    After "Count down." is displayed, Velocity passes through parsefoo.vm, counting down from 8. When the count reaches 0, it will display the "All done with parsefoo.vm!" message. At this point, Velocity will return to dofoo.vm and output the "All done with dofoo.vm!" message.

    The #break directive stops any further rendering of the current execution scope. An "execution scope" is essentially any directive with content (i.e. #foreach, #parse, #evaluate, #define, #macro, or #@somebodymacro) or any "root" scope (i.e. template.merge(...), Velocity.evaluate(...) or velocityEngine.evaluate(...)). Unlike #stop, #break will only stop the innermost, immediate scope, not all of them.

    If you wish to break out of a specific execution scope that is not necessarily the most immediate one, then you can pass the scope control reference (i.e. $foreach, $template, $evaluate, $define, $macro, or $somebodymacro) as an argument to #break. (e.g. #break($macro)). This will stop rendering of all scopes up to the specified one. When within nested scopes of the same type, remember that you can always access the parent(s) via $<scope>.parent or $<scope>.topmost and pass those to #break instead (e.g. #break($foreach.parent) or #break($macro.topmost)).

    The #stop directive stops any further rendering and execution of the template. This is true even when the directive is nested within another template accessed through #parse or located in a velocity macro. The resulting merged output will contain all the content up to the point the #stop directive was encountered. This is handy as an early exit from a template. For debugging purposes, you may provide a message argument (e.g. #stop('$foo was not in context') ) that will be written to the logs (DEBUG level, of course) upon completion of the stop command.

    The #evaluate directive can be used to dynamically evaluate VTL. This allows the template to evaluate a string that is created at render time. Such a string might be used to internationalize the template or to include parts of a template from a database.

    The example below will display abc.

    The #define directive lets one assign a block of VTL to a reference.

    The example below will display Hello World!.

    The #macro script element allows template designers to define a repeated segment of a VTL template. Velocimacros are very useful in a wide range of scenarios both simple and complex. This Velocimacro, created for the sole purpose of saving keystrokes and minimizing typographic errors, provides an introduction to the concept of Velocimacros.

    #end ]]>

    The Velocimacro being defined in this example is d, and it can be called in a manner analogous to any other VTL directive:

    When this template is called, Velocity would replace #d() with a row containing a single, empty data cell. If we want to put something in that cell, we can alter the macro to allow for a body:

    $!bodyContent #end ]]>

    Now, if we call the macro just a bit differently, using #@ before the name and providing a body and #end to the call, then Velocity will render the body when it gets to the $!bodyContent:

    You can still call the macro as you did before, and since we used the silent reference notation for the body reference ($!bodyContent instead of $bodyContent), it will still render a row with a single, empty data cell.

    A Velocimacro can also take any number of arguments -- even zero arguments, as demonstrated in the first example, is an option -- but when the Velocimacro is invoked, it must be called with the same number of arguments with which it was defined. Many Velocimacros are more involved than the one defined above. Here is a Velocimacro that takes two arguments, a color and an array.

    $something #end #end ]]>

    The Velocimacro being defined in this example, tablerows, takes two arguments. The first argument takes the place of $color, and the second argument takes the place of $somelist.

    Anything that can be put into a VTL template can go into the body of a Velocimacro. The tablerows Velocimacro is a foreach statement. There are two #end statements in the definition of the #tablerows Velocimacro; the first belongs to the #foreach, the second ends the Velocimacro definition.

    #tablerows( $color $greatlakes ) ]]>

    Notice that $greatlakes takes the place of $somelist. When the #tablerows Velocimacro is called in this situation, the following output is generated:

    Superior Michigan Huron Erie Ontario ]]>

    Velocimacros can be defined inline in a Velocity template, meaning that it is unavailable to other Velocity templates on the same web site. Defining a Velocimacro such that it can be shared by all templates has obvious advantages: it reduces the need to redefine the Velocimacro on numerous templates, saving work and reducing the chance of error, and ensures that a single change to a macro available to more than one template.

    Were the #tablerows($color $list) Velocimacro defined in a Velocimacros template library, this macro could be used on any of the regular templates. It could be used many times and for many different purposes. In the template mushroom.vm devoted to all things fungi, the #tablerows Velocimacro could be invoked to list the parts of a typical mushroom:

    #tablerows( $cellbgcol $parts ) ]]>

    When fulfilling a request for mushroom.vm, Velocity would find the #tablerows Velocimacro in the template library (defined in the velocity.properties file) and generate the following output:

    volva stipe annulus gills pileus ]]> Velocimacro Arguments

    Velocimacros can take as arguments any of the following VTL elements :

    • Reference : anything that starts with '$'
    • String literal : something like "$foo" or 'hello'
    • Number literal : 1, 2 etc
    • IntegerRange : [ 1..2] or [$foo .. $bar]
    • ObjectArray : [ "a", "b", "c"]
    • boolean value true
    • boolean value false

    When passing references as arguments to Velocimacros, please note that references are passed 'by name'. This means that their value is 'generated' at each use inside the Velocimacro. This feature allows you to pass references with method calls and have the method called at each use. For example, when calling the following Velocimacro as shown

    results in the method bar() of the reference $foo being called 3 times.

    At first glance, this feature appears surprising, but when you take into consideration the original motivation behind Velocimacros -- to eliminate cut'n'paste duplication of commonly used VTL -- it makes sense. It allows you to do things like pass stateful objects, such as an object that generates colors in a repeating sequence for coloring table rows, into the Velocimacro.

    If you need to circumvent this feature, you can always just get the value from the method as a new reference and pass that :

    Velocimacro Properties

    Several lines in the velocity.properties file allow for flexible implementation of Velocimacros. Note that these are also documented in the Developer Guide.

    velocimacro.library - A comma-separated list of all Velocimacro template libraries. By default, Velocity looks for a single library: VM_global_library.vm. The configured template path is used to find the Velocimacro libraries.

    velocimacro.permissions.allow.inline - This property, which has possible values of true or false, determines whether Velocimacros can be defined in regular templates. The default, true, allows template designers to define Velocimacros in the templates themselves.

    velocimacro.permissions.allow.inline.to.replace.global - With possible values of true or false, this property allows the user to specify if a Velocimacro defined inline in a template can replace a globally defined template, one that was loaded on startup via the velocimacro.library property. The default, false, prevents Velocimacros defined inline in a template from replacing those defined in the template libraries loaded at startup.

    velocimacro.permissions.allow.inline.local.scope - This property, with possible values of true or false, defaulting to false, controls if Velocimacros defined inline are 'visible' only to the defining template. In other words, with this property set to true, a template can define inline VMs that are usable only by the defining template. You can use this for fancy VM tricks - if a global VM calls another global VM, with inline scope, a template can define a private implementation of the second VM that will be called by the first VM when invoked by that template. All other templates are unaffected.

    velocimacro.library.autoreload - This property controls Velocimacro library autoloading. The default value is false. When set to true the source Velocimacro library for an invoked Velocimacro will be checked for changes, and reloaded if necessary. This allows you to change and test Velocimacro libraries without having to restart your application or servlet container, just like you can with regular templates. This mode only works when caching is off in the resource loaders (e.g. file.resource.loader.cache = false ). This feature is intended for development, not for production.

    VTL uses special characters, such as $ and #, to do its work, so some added care should be taken where using these characters in your templates. This section deals with escaping these characters.

    Currency
    There is no problem writing "I bought a 4 lb. sack of potatoes at the farmer's market for only $2.50!" As mentioned, a VTL identifier always begins with an upper- or lowercase letter, so $2.50 would not be mistaken for a reference.

    Escaping Valid VTL References
    Cases may arise where you do not want to have a reference rendered by Velocity. Escaping special characters is the best way to output VTL's special characters in these situations, and this can be done using the backslash ( \ ) character when those special characters are part of a valid VTL reference. *

    If Velocity encounters a reference in your VTL template to $email, it will search the Context for a corresponding value. Here the output will be foo, because $email is defined. If $email is not defined, the output will be $email.

    Suppose that $email is defined (for example, if it has the value foo), and that you want to output $email. There are a few ways of doing this, but the simplest is to use the escape character. Here is a demonstration:

    renders as

    If, for some reason, you need a backslash before either line above, you can do the following:

    which renders as

    Note that the \ character bind to the $ from the left. The bind-from-left rule causes \\\$email to render as \$email. Compare these examples to those in which $email is not defined.

    renders as

    Notice Velocity handles references that are defined differently from those that have not been defined. Here is a set directive that gives $foo the value gibbous.

    The output will be: $moon = gibbous -- where $moon is output as a literal because it is undefined and gibbous is output in place of $foo.

    Escaping Invalid VTL References
    Sometimes Velocity has trouble parsing your template when it encounters an "invalid reference" that you never intended to be a reference at all. Escaping special characters is, again, the best way to handle these situations, but in these situations, the backslash will likely fail you. Instead of simply trying to escape the problematic $ or #, you should probably just replace this:

    with something like this

    You can, of course, put your $ or # string directly into the context from your java code (e.g. context.put("D","$");) to avoid the extra #set() directive in your template(s). Or, if you are using VelocityTools, you can just use the EscapeTool like this:

    Escaping of both valid and invalid VTL directives is handled in much the same manner; this is described in more detail in the Directives section.

    Escaping VTL Directives
    VTL directives can be escaped with the backslash character ("\") in a manner similar to valid VTL references.

    #include( "a.txt" ) ## \#include( "a.txt" ) renders as #include( "a.txt" ) \#include( "a.txt" ) ## \\#include ( "a.txt" ) renders as \ \\#include ( "a.txt" ) ]]>

    Extra care should be taken when escaping VTL directives that contain multiple script elements in a single directive (such as in an if-else-end statements). Here is a typical VTL if-statement:

    If $jazz is true, the output is

    If $jazz is false, there is no output. Escaping script elements alters the output. Consider the following case:

    This causes the directives to be escaped, but the rendering of $jazz proceeds as normal. So, if $jazz is true, the output is

    Suppose backslashes precede script elements that are legitimately escaped:

    In this case, if $jazz is true, the output is

    To understand this, note that the #if( arg ) when ended by a newline (return) will omit the newline from the output. Therefore, the body of the #if() block follows the first '\', rendered from the '\\' preceding the #if(). The last \ is on a different line than the text because there is a newline after 'Ganelin', so the final \\, preceding the #end is part of the body of the block.

    If $jazz is false, the output is

    Note that things start to break if script elements are not properly escaped.

    Here the #if is escaped, but there is an #end remaining; having too many endings will cause a parsing error.

    Although VTL in this user guide is often displayed with newlines and whitespaces, the VTL shown below

    is equally valid as the following snippet that Geir Magnusson Jr. posted to the Velocity user mailing list to illustrate a completely unrelated point:

    Velocity's behaviour is to gobble up excess whitespace. The preceding directive can be written as:

    or as

    In each case the output will be the same.

    Velocity has a handful of built-in mathematical functions that can be used in templates with the set directive. The following equations are examples of addition, subtraction, multiplication and division, respectively:

    When a division operation is performed between two integers, the result will be an integer, as the fractional portion is discarded. Any remainder can be obtained by using the modulus (%) operator.

    The range operator can be used in conjunction with #set and #foreach statements. Useful for its ability to produce an object array containing integers, the range operator has the following construction:

    Both n and m must either be or produce integers. Whether m is greater than or less than n will not matter; in this case the range will simply count down. Examples showing the use of the range operator as provided below:

    Produces the following output:

    Note that the range operator only produces the array when used in conjunction with #set and #foreach directives, as demonstrated in the fourth example.

    Web page designers concerned with making tables a standard size, but where some will not have enough data to fill the table, will find the range operator particularly useful.

    When a reference is silenced with the ! character and the ! character preceded by an \ escape character, the reference is handled in a special way. Note the differences between regular escaping, and the special case where \ precedes ! follows it:

    This renders as:

    Contrast this with regular escaping, where \ precedes $:

    This renders as:

    This section is a mini-FAQ on topics relating to Velocimacros. This section will change over time, so it's worth checking for new information from time to time.

    Note : Throughout this section, 'Velocimacro' will commonly be abbreviated as 'VM'.

    Can I use a directive or another VM as an argument to a VM?

    Example : #center( #bold("hello") )

    No. A directive isn't a valid argument to a directive, and for most practical purposes, a VM is a directive.

    However..., there are things you can do. One easy solution is to take advantage of the fact that 'doublequote' (") renders its contents. So you could do something like

    You can save a step...

    Please note that in the latter example the arg is evaluated inside the VM, not at the calling level. In other words, the argument to the VM is passed in in its entirety and evaluated within the VM it was passed into. This allows you to do things like :

    Where the output is

    because the evaluation of the "#inner($bar)" happens inside #outer(), so the $bar value set inside #outer() is the one that's used.

    This is an intentional and jealously guarded feature - args are passed 'by name' into VMs, so you can hand VMs things like stateful references such as

    Hi There #end #foo( $bar.rowColor() ) ]]>

    And have rowColor() called repeatedly, rather than just once. To avoid that, invoke the method outside of the VM, and pass the value into the VM.

    Can I register Velocimacros via #parse() ?

    Yes! This became possible in Velocity 1.6.

    If you are using an earlier version, your Velocimacros must be defined before they are first used in a template. This means that your #macro() declarations should come before using the Velocimacros.

    This is important to remember if you try to #parse() a template containing inline #macro() directives. Because the #parse() happens at runtime, and the parser decides if a VM-looking element in the template is a VM at parsetime, #parse()-ing a set of VM declarations won't work as expected. To get around this, simply use the velocimacro.library facility to have Velocity load your VMs at startup.

    What is Velocimacro Autoreloading?

    There is a property, meant to be used in development, not production :

    velocimacro.library.autoreload

    which defaults to false. When set to true along with

    <type>.resource.loader.cache = false

    (where <type> is the name of the resource loader that you are using, such as 'file') then the Velocity engine will automatically reload changes to your Velocimacro library files when you make them, so you do not have to dump the servlet engine (or application) or do other tricks to have your Velocimacros reloaded.

    Here is what a simple set of configuration properties would look like.

    Don't keep this on in production.

    A common question that developers ask is How do I do String concatenation? Is there any analogue to the '+' operator in Java?.

    To do concatenation of references in VTL, you just have to 'put them together'. The context of where you want to put them together does matter, so we will illustrate with some examples.

    In the regular 'schmoo' of a template (when you are mixing it in with regular content) :

    and the output will render as 'The clock is BigBen'. For more interesting cases, such as when you want to concatenate strings to pass to a method, or to set a new reference, just do

    Which will result in the same output. As a final example, when you want to mix in 'static' strings with your references, you may need to use 'formal references' :

    Now the output is 'The clock is BigTallBen'. The formal notation is needed so the parser knows you mean to use the reference '$size' versus '$sizeTall' which it would if the '{}' weren't there.

    If you encounter any mistakes in this manual or have other feedback related to the Velocity User Guide, please email the Velocity developers list. Thanks!

    velocity-1.7/xdocs/docs/vtl-reference-guide.xml0000644000175000017500000004136311156517252021541 0ustar moellermoeller VTL Reference Velocity Documentation Team

    This guide is the reference for the Velocity Template Language (VTL). For more information, please also refer to the Velocity User Guide.

    Notation:

    $ [ ! ][ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ][ } ]

    Examples:

    • Shorthand notation: $mud-Slinger_9
    • Silent Shorthand notation: $!mud-Slinger_9
    • Formal notation: ${mud-Slinger_9}
    • Silent Formal notation: $!{mud-Slinger_9}

    Notation:

    $ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[a..z, A..Z ][ a..z, A-Z, 0..9, -, _ ]* [ } ]

    Examples:

    • Regular Notation: $customer.Address
    • Formal Notation: ${purchase.Total}

    Notation:

    $ [ { ][ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]* .[ a..z, A..Z ][ a..z, A..Z, 0..9, -, _ ]*( [ optional parameter list... ] ) [ } ]

    Examples:

    • Regular Notation: $customer.getAddress()
    • Formal Notation: ${purchase.getTotal()}
    • Regular Notation with Parameter List: $page.setTitle( "My Home Page" )

    VTL Properties can be used as a shorthand notation for VTL Methods that take get and set. Either $object.getMethod() or $object.setMethod() can be abbreviated as $object.Method. It is generally preferable to use a Property when available. The main difference between Properties and Methods is that you can specify a parameter list to a Method.

    Format:

    # [ { ] set [ } ] ( $ref = [ ", ' ]arg[ ", ' ] )

    Usage:

    • $ref - The LHS of the assignment must be a variable reference or a property reference.
    • arg - The RHS of the assignment, arg is parsed if enclosed in double quotes, and not parsed if enclosed in single quotes. If the RHS evaluates to null, it is not assigned to the LHS.

    Examples:

    • Variable reference: #set( $monkey = $bill )
    • String literal: #set( $monkey.Friend = 'monica' )
    • Property reference: #set( $monkey.Blame = $whitehouse.Leak )
    • Method reference: #set( $monkey.Plan = $spindoctor.weave($web) )
    • Number literal: #set( $monkey.Number = 123 )
    • Range operator: #set( $monkey.Numbers = [1..3] )
    • Object list: #set( $monkey.Say = ["Not", $my, "fault"] )
    • Object map: #set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"})

    The RHS can also be a simple arithmetic expression, such as:

    • Addition: #set( $value = $foo + 1 )
    • Subtraction: #set( $value = $bar - 1 )
    • Multiplication: #set( $value = $foo * $bar )
    • Division: #set( $value = $foo / $bar )
    • Remainder: #set( $value = $foo % $bar )

    Format:

    # [ { ] if [ } ] ( [condition] ) [output] [ # [ { ] elseif [ } ] ( [condition] ) [output] ]* [ # [ { ] else [ } ] [output] ] # [ { ] end [ } ]

    Usage:

    • condition - If a boolean, considered true if it has a true false; if not a boolean, considered true if not null.
    • output - May contain VTL.

    Examples (showing different operators):

    Operator Name Symbol Alternative Symbol Example
    Equals Number == eq #if( $foo == 42 )
    Equals String == eq #if( $foo == "bar" )
    Object Equivalence == eq #if( $foo == $bar )
    Not Equals != ne #if( $foo != $bar )
    Greater Than > gt #if( $foo > 42 )
    Less Than < lt #if( $foo < 42 )
    Greater Than or Equal To >= ge #if( $foo >= 42 )
    Less Than or Equal To <= le #if( $foo <= 42 )
    Boolean NOT ! not #if( !$foo )

    Notes:

    1. The == operator can be used to compare numbers, strings, objects of the same class, or objects of different classes. In the last case (when objects are of different classes), the toString() method is called on each object and the resulting Strings are compared.
    2. You can also use brackets to delimit directives. This is especially useful when text immediately follows an #else directive.
    ]]>

    Format:

    # [ { ] foreach [ } ] ( $ref in arg ) statement # [ { ] end [ } ]

    Usage:

    • $ref - The first variable reference is the item.
    • arg - May be one of the following: a reference to a list (i.e. object array, collection, or map), an array list, or the range operator.
    • statement - What is output each time Velocity finds a valid item in the list denoted above as arg. This output is any valid VTL and is rendered each iteration of the loop.

    Examples of the #foreach(), omitting the statement block :

    • Reference: #foreach ( $item in $items )
    • Array list: #foreach ( $item in ["Not", $my, "fault"] )
    • Range operator: #foreach ( $item in [1..3] )

    Velocity provides an easy way to get the loop counter so that you can do something like the following:

    #foreach( $customer in $customerList ) $foreach.count$customer.Name #end ]]>

    Additionally, the maximum allowed number of loop iterations can be controlled engine-wide (an ability introduced in Velocity 1.5). By default, there is no limit:

    Format:

    # [ { ] include [ } ] ( arg[ arg2 ... argn] )

    • arg - Refers to a valid file under TEMPLATE_ROOT.

    Examples:

    • String: #include( "disclaimer.txt" "opinion.txt" )
    • Variable: #include( $foo $bar )

    Format:

    # [ { ] parse [ } ] ( arg )

    • arg - Refers to a template under TEMPLATE_ROOT.

    Examples:

    • String: #parse( "lecorbusier.vm" )
    • Variable: #parse( $foo )

    Recursion permitted. See parse_directive.maxdepth in velocity.properties to change from parse depth. (The default parse depth is 10.)

    Format:

    # [ { ] stop [ } ]

    Usage:

    This will stop execution of the current template. This is good for debugging a template.

    Format:

    # [ { ] break [ } ]

    Usage:

    This will break execution of the current content directive. This is good for exiting a #foreach loop early, but also works in other scopes. You can even pass the scope control reference for a specific outer scope to break execution of all scopes outward to the specified one.

    Format:

    # [ { ] evaluate [ } ] ( arg )

    • arg - String literal or reference to be dynamically evaluated.

    Examples:

    • String: #evaluate( 'string with VTL #if(true)will be displayed#end' )
    • Variable: #include( $foo )

    Format:

    # [ { ] define [ } ] ( $ref ) statement # [ { ] end [ } ]

    • $ref - Reference that is assigned the VTL block as a value.
    • statement - Statement that is assigned to the reference.

    Example:

    • #define( $hello ) Hello $who #end #set( $who = "World!") $hello ## displays Hello World!

    Format:

    # [ { ] macro [ } ] ( vmname $arg1 [ $arg2 $arg3 ... $argn ] ) [ VM VTL code... ] # [ { ] end [ } ]

    • vmname - Name used to call the VM (#vmname)
    • $arg1 $arg2 [ ... ] - Arguments to the VM. There can be any number of arguments, but the number used at invocation must match the number specified in the definition.
    • [ VM VTL code... ] - Any valid VTL code, anything you can put into a template, can be put into a VM.

    Once defined, the VM is used like any other VTL directive in a template.

    Except, that when you wish to call a VM with a body, then you must prefix the name of the VM with @. The content of that body may be referenced in the macro definition via $!bodyContent as many or few times as you like.

    VMs can be defined in one of two places:

    1. Template library: can be either VMs pre-packaged with Velocity or custom-made, user-defined, site-specific VMs; available from any template
    2. Inline: found in regular templates, only usable when velocimacro.permissions.allowInline=true in velocity.properties.

    Comments are not rendered at runtime.

    Example:

    ## This is a comment.

    Example:

    #*
    This is a multiline comment.
    This is the second line
    *#

    Unparsed content is rendered at runtime, but is not parsed or interpreted.

    Example:

    #[[
    This has invalid syntax that would normally need "poor man's escaping" like:

    • #define()
    • ${blah
    ]]#

    velocity-1.7/xdocs/docs/build.xml0000644000175000017500000002447411273713211017001 0ustar moellermoeller Building Velocity from Source Velocity Documentation Team

    Velocity runs on a variety of platforms that have installed the Java 2 Virtual Machine. The J2SDK is required for users who want to compile Velocity from its source code.

    Everything required to build Velocity comes with the distribution, which can be obtained from Subversion or from the nightly snapshots. However, you will need to install Ant to build the Velocity sources.

    Ant is also an Apache project, and can be found here. To build Apache Velocity, you need at least Version 1.7 of Apache Ant.

    The directory tree of the distribution looks like:

    To make building Velocity easy and consistent, we require an Apache project called Ant version 1.7 or higher to perform the build process. We assume that you have followed Ant's installation instructions and have it properly installed.

    Velocity requires JDK 1.4 or greater to compile. It's possible to use JDK 1.3 to compile but several useful features will not be included. Velocity requires a minimum of JDK 1.3 to run.

    Finally, if you wish to modify Velocity's grammar you will need to a tool called JavaCC. We recommend version 3.2 or greater (for compatibility with JDK 1.5 syntax changes).

    Velocity requires various third party jar files for compiling and for running. Not all jar files are required in all cases. When building, all dependencies will be downloaded automatically. You can control the download with the skip.jar.loading and force.jar.loading properties in the build.properties file.

    Jar Purpose Required at Runtime?
    antlr-2.7.5.jar XML parsing (XPath queries in particular) Only for Anakia
    avalon-logkit-2.1.jar Possible means of logging No
    commons-collection-3.1.jar Used in parsing configuration Yes
    commons-lang-2.1.jar Various String utility functions Yes
    commons-logging-1.1.jar To redirect log output to commons-logging Only for those using commons-logging
    jdom-1.0.jar XML parsing Only for Anakia
    log4j.1.2.12.jar Possible means of logging No
    oro-2.0.8.jar For regular expression parsing in tests and event handlers Only for reference escaping event handlers
    servletapi-2.3.jar For the deprecated VelocityServlet and redirecting log output to the servlet log. Only for VelocityServlet or ServletLogChute
    werken-xpath-0.9.4.jar XML parsing Only for Anakia
    junit-3.8.1.jar For running unit tests No
    hsqldb-1.7.1.jar For running database related unit tests No
    ant.jar Required for compilation. Provided by the ant build tool. No

    Note that you can always create a jar with all required run-time dependencies by executing the jar-dep task.

    In each case below, it is assumed that you were successful in getting the distribution from Subversion or as a nightly build, and with the latter, were successful in unpacking. Also, it is assumed that you are starting in the 'velocity' directory, the root of the distribution tree. All directory references will be relative to 'velocity'.

    Change to the build directory (cd build). Then, to build the jar file, simply type:

    Executing this script will create a bin directory within the Velocity distribution directory. The bin directory will contain the compiled class files (inside a classes directory) as well as a velocity-XX.jar file, where XX is the current version number. Be sure to update your classpath to include Velocity's .jar file.

    Note that to build any of the specific build targets simply add the target name to the command line. For example, to build the Javadoc API documentation:

    Some of the most useful targets are:

    • jar builds the complete Velocity jar in the bin directory. This jar will be called 'velocity-X.jar', where 'X' is the current version number. This jar does not include necessary dependencies for Velocity. If you use this target, you must put the required dependent jars in your CLASSPATH (or WEB-INF/lib). For convenience, you can use the jar-dep target to build a jar with all required dependent classes included.
    • jar-dep builds the complete Velocity jar in the bin directory.
    • clean deletes all generated classes, jars, documentation, and other files.
    • real-clean like clean but also deletes all downloaded jars.
    • docs builds these docs in the docs directory using Velocity's Anakia XML transformation tool. Allows you to use Velocity templates in place of stylesheets - give it a try!
    • examples builds the example code in the example programs found in the examples directory.
    • jar-src bundles all the Velocity source code into a single jar, placed in the bin directory.
    • javadocs builds the Javadoc class documentation in the docs/api directory
    • package will generate the complete Velocity distribution package.
    • parser will compile the JavaCC parser files from src/Parser.jjt into the appropriate Java source files. Requires JavaCC 3.2+ to be installed, and the property javacc.home to contain a path to the installed JavaCC directory.
    • test (after jar) will test Velocity against its testbed suite of test routines.

    Velocity should build 'out of the box', independent of your classpath. If you get an error building Velocity, try a different nightly build (as sometimes we make a mistake and the Subversion at the time of the nightly snapshot isn't complete) or refresh from Subversion (you might have gotten a Subversion snapshot while a developer was checking things in.)

    If the problems persist, do not hesitate to ask the Velocity community via our mail lists. They can be found here.

    The Velocity developers use an automated test facility, and it is included in the distribution. You can use it to make sure that all is well with your build of Velocity.

    To run the test suite, simply use the build target test when you build:

    If all is well, you should see output similar to:

    Note that the number of tests may vary from those shown above, but if you see 'OK' after the tests are run, all is well.

    velocity-1.7/xdocs/site.css0000644000175000017500000001064610557734552015721 0ustar moellermoeller/* * 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. */ /** defined standard tags **/ body { background-color: #ffffff; color: #000000; } a:link, a:active, a:visited { color: #525D76; } h1 { background-color: #525D76; color: #ffffff; font-family: arial,helvetica,sanserif; font-size: large; padding-left:2px; } h2 { background-color: #828DA6; color: #ffffff; font-family: arial,helvetica,sanserif; font-size: medium; padding-left:2px; } table { border: none; border-spacing:0px; border-collapse: collapse; } img { border: none 0px; } /** define layout **/ /** table used to force footer to end of page **/ table#layout { width:100%; } table#layout td { padding:0px; } div#container { width: 95%; margin: 10px; margin-left: 0; margin-right: auto; padding: 10px; } div#header { padding: 5px; margin: 0px; margin-top:5px; margin-bottom:5px; height:80px; border-bottom: 1px solid #333333; } div#menu { float: left; width: 200px; margin: 0; margin-left: 0px; margin-right: 5px; /** little higher margin since it doesn't start with a header **/ margin-top:10px; margin-bottom:0px; padding: 5px; } div#body { margin-right:0px; margin-left: 215px; margin-top:5px; margin-bottom:0px; padding: 5px; } div#footer { clear: both; padding-top:15px; margin-top:25px; border-top: 1px solid #333333; text-align:center; color: #525D76; font-style: italic; font-size: smaller; } div#logo1 { float:left; margin-left:5px; margin-top:10px; } div#logo2 { float:right; margin-top:10px; } /** define body tag redefinitions **/ div#body th { background-color: #039acc; color: #000000; font-family: arial,helvetica,sanserif; font-size: smaller; vertical-align: top; text-align:left; border:1px #FFFFFF solid; padding: 2px; } div#body td { background-color: #a0ddf0; color: #000000; font-family: arial,helvetica,sanserif; font-size: smaller; vertical-align: top; text-align:left; border:1px #FFFFFF solid; padding: 2px; } div#body li { margin-top:3px; } /** define other body styles **/ div.section { margin-left: 25px; } div.subsection { margin-left: 25px; } div.source { margin-left:25px; margin-top:20px; margin-bottom:20px; padding-left:4px; padding-right:4px; padding-bottom:4px; padding-top:5px; width:600; border: 1px solid #333333; background-color: #EEEEEE; color: #333333; /** bug: puts a extra line before the block in IE and after the block in FireFox **/ white-space: pre; font-family: Courier; font-size: smaller; text-align: left; overflow:auto; } div.license { margin-left:0px; margin-top:20px; margin-bottom:20px; padding:5px; border: 1px solid #333333; background-color: #EEEEEE; color: #333333; text-align: left; } /** define menu styles **/ div.menusection { margin-bottom:10px; } .menuheader { font-weight:bold; margin-bottom:0px; } div.menusection ul { margin-top:5px; } div.menusection li { } /** printing **/ @page Section1 { size:8.5in 11.0in; margin:1.0in .75in 1.0in .75in; } @media print { /** make sure this fits the page **/ div#container { width:100%; min-height:0px; } div#menu { display:none; } div#header { display:none; } div#body { margin-left:5px; } div.source { width:95%; margin-left:0px; } /** make a bit more room on the page **/ div.section { margin-left: 0px; } div.subsection { margin-left: 0px; } h1 { background-color: #FFFFFF; color: #000000; } h2 { background-color: #FFFFFF; color: #000000; } div#body td { background-color: #FFFFFF; color: #000000; border: #333333 1px solid; } div#body th { background-color: #FFFFFF; color: #000000; border: #333333 1px solid; font-style:bold; } } velocity-1.7/xdocs/stylesheets/0000755000175000017500000000000011675166245016610 5ustar moellermoellervelocity-1.7/xdocs/stylesheets/project.xml0000644000175000017500000001017411110330417020755 0ustar moellermoeller Velocity Velocity velocity-1.7/xdocs/stylesheets/site.vsl0000644000175000017500000002116710573260455020303 0ustar moellermoeller## 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. #document() ## This is where the macro's live #macro ( table $table) #foreach ( $items in $table.getChildren() ) #if ($items.getName().equals("tr")) #tr ($items) #end #end
    #end #macro ( tr $tr) #foreach ( $items in $tr.getChildren() ) #if ($items.getName().equals("td")) #td ($items) #elseif ($items.getName().equals("th")) #th ($items) #end #end #end #macro ( td $value) #if ($value.getAttributeValue("colspan")) #set ($colspan = $value.getAttributeValue("colspan")) #end #if ($value.getAttributeValue("rowspan")) #set ($rowspan = $value.getAttributeValue("rowspan")) #end #foreach ( $items in $value.getContent() ) #if($items.name) #display($items) #else $items.value #end #end #end #macro ( th $value) #if ($value.getAttributeValue("colspan")) #set ($colspan = $value.getAttributeValue("colspan")) #end #if ($value.getAttributeValue("rowspan")) #set ($rowspan = $value.getAttributeValue("rowspan")) #end #foreach ( $items in $value.getContent() ) #if($items.name) #display($items) #else $items.value #end #end #end #macro ( projectanchor $name $value ) #if ($value.startsWith("http://")) $name #elseif ($value.startsWith("https://")) $name #else $name #end #end #macro ( metaauthor $author $email ) #end #macro ( image $value ) #if ($value.getAttributeValue("width")) #set ($width=$value.getAttributeValue("width")) #end #if ($value.getAttributeValue("height")) #set ($height=$value.getAttributeValue("height")) #end #if ($value.getAttributeValue("align")) #set ($align=$value.getAttributeValue("align")) #end #end #macro ( source $value)
    $escape.getText($value.getText())
    #end ## need these to catch special macros within lists #macro(list $node) <$node.getName()> #foreach ( $items in $node.getChildren() ) #listitem($items) #end #end #macro (listitem $node) <$node.getName()> ## use getContent instead of getChildren ## to include both text and nodes #foreach ( $items in $node.getContent() ) #if($items.name) #display($items) #else $items.value #end #end #end ## # displays a basic node, calling macros if appropriate #macro ( display $node ) #if ($node.getName().equals("img")) #image ($node) #elseif ($node.getName().equals("source")) #source ($node) #elseif ($node.getName().equals("table")) #table ($node) #elseif ($node.getName().equals("ul")) #list ($node) #elseif ($node.getName().equals("ol")) #list ($node) #else $node #end #end #macro ( section $section)

    $section.getAttributeValue("name")

    #foreach ( $items in $section.getChildren() ) #if ($items.getName().equals("subsection")) #subsection ($items) #else #display($items) #end #end
    #end #macro ( subsection $subsection)

    $subsection.getAttributeValue("name")

    #foreach ( $items in $subsection.getChildren() ) #display($items) #end
    #end #macro ( anchorName $section) #if ($section.getAttributeValue("href")) $section.getAttributeValue("href")## #else $section.getAttributeValue("name")## #end #end #macro ( makeProject ) #set ($menus = $project.getChild("body").getChildren("menu")) #foreach ( $menu in $menus ) #end #end #macro (getProjectImage)
    #if ($project.getChild("logo"))
    #set ( $logoString = $project.getChild("logo").getAttributeValue("href") ) #if ( $logoString.startsWith("/") ) $project.getChild( #else $project.getChild( #end
    #end #end #macro (printMeta $metaElement) #end #macro (document) #set ($authors = $root.getChild("properties").getChildren("author")) #foreach ( $au in $authors ) #metaauthor ( $au.getText() $au.getAttributeValue("email") ) #end #set ($metas = $root.getChildren("meta")) ## Parse meta directives such as ## #foreach ($meta in $metas) #printMeta($meta) #end ## Support for tags. #if ($root.getChild("properties").getChild("base")) #set ($url = $root.getChild("properties").getChild("base").getAttributeValue("href")) #end $project.getChild("title").getText() - $root.getChild("properties").getChild("title").getText() ## use a relative CSS for when the page is displayed locally (will overwrite ## previous CSS settings) ## use a table in order to force footer to end of page
    #set ($allSections = $root.getChild("body").getChildren("section")) #foreach ( $section in $allSections ) #section ($section) #end
    #end velocity-1.7/NOTICE0000644000175000017500000000025710557734552014024 0ustar moellermoellerApache Velocity Copyright (C) 2000-2007 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). velocity-1.7/LICENSE0000644000175000017500000002613610513457575014130 0ustar moellermoeller Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. velocity-1.7/src/0000755000175000017500000000000011675166252013701 5ustar moellermoellervelocity-1.7/src/test/0000755000175000017500000000000011675166245014662 5ustar moellermoellervelocity-1.7/src/test/org/0000755000175000017500000000000011675166245015451 5ustar moellermoellervelocity-1.7/src/test/org/apache/0000755000175000017500000000000011675166245016672 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/0000755000175000017500000000000011675166247020532 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/0000755000175000017500000000000011675166247021511 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/IndexTestCase.java0000644000175000017500000001350211144461301025034 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.ArrayList; import org.apache.velocity.runtime.RuntimeConstants; /** * Test index syntax e.g, $foo[1] */ public class IndexTestCase extends BaseTestCase { public IndexTestCase(String name) { super(name); //DEBUG = true; } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); engine.setProperty(RuntimeConstants.COUNTER_INITIAL_VALUE, new Integer(0)); context.put("NULL", null); context.put("red", "blue"); int[] a = {1, 2, 3}; context.put("a", a); String[] str = {"a", "ab", "abc"}; context.put("str", str); ArrayList alist = new ArrayList(); alist.add(new Integer(1)); alist.add(new Integer(2)); alist.add(new Integer(3)); alist.add(a); alist.add(null); context.put("alist", alist); Foo foo = new Foo(); foo.bar = alist; context.put("foo", foo); Boo boo = new Boo(); context.put("boo", boo); } public void testCallingIndex() { assertEvalEquals("1 -3-", "$a[0] -$a[ 2 ]-"); assertEvalEquals("x21", "#set($i = 1)x$a[$i]1"); assertEvalEquals("3", "$a[ $a[ $a[0] ] ]"); assertEvalEquals("ab", "$str[1]"); assertEvalEquals("123", "$alist[0]$alist[1]$alist[2]"); assertEvalEquals("1][2-[3]", "$alist[0]][$alist[$a[0]]-[$alist[2]]"); assertEvalEquals("2", "$alist[3][1]"); assertEvalEquals("3 [1]", "$alist[2] [1]"); assertEvalEquals("4", "#set($bar = [3, 4, 5])$bar[1]"); assertEvalEquals("21", "#set($i = 1)#set($bar = [3, $a[$i], $a[0]])$bar[1]$bar[2]"); assertEvalEquals("2", "$foo.bar[1]"); assertEvalEquals("2", "$foo.getBar()[1]"); assertEvalEquals("2", "$foo.getBar()[3][1]"); assertEvalEquals(" a ab abc ", "#foreach($i in $foo.bar[3]) $str[$velocityCount] #end"); assertEvalEquals("apple", "#set($hash = {'a':'apple', 'b':'orange'})$hash['a']"); assertEvalEquals("xx ", "#if($alist[4] == $NULL)xx#end #if($alist[4])yy#end"); assertEvalEquals("BIG TRUEaBIG FALSE", "$foo[true]a$foo[false]"); assertEvalEquals("junk foobar ", "$foo[\"junk\"]"); assertEvalEquals("GOT NULL", "#set($i=$NULL)$boo[$i]"); assertEvalEquals("321", "$a[-1]$a[ -2]$a[-3 ]"); assertEvalEquals("67xx", "#set($hash={1:11, 5:67, 23:2})$hash[5]$!hash[6]#if(!$hash[1000])xx#end"); // Some cases that should be evaluated as text assertEvalEquals("[]", "[]"); assertEvalEquals("$[]", "$[]"); assertEvalEquals("$.[]", "$.[]"); assertEvalEquals("$[1]", "$[1]"); assertEvalEquals("$[1]1", "$[1]1"); assertEvalEquals("$1[1]1", "$1[1]1"); assertEvalEquals("blue.[]", "$red.[]"); assertEvalEquals("blue[]", "${red}[]"); assertEvalEquals("blue][", "$red]["); assertEvalEquals("1[]", "${a[0]}[]"); assertEvalEquals("1a$[]", "$a[0]a$[]"); assertEvalEquals("$![]", "$![]"); assertEvalEquals("$\\![]", "$\\![]"); } public void testIndexSetting() { assertEvalEquals("foo", "#set($str[1] = \"foo\")$str[1]"); assertEvalEquals("5150", "#set($alist[1] = 5150)$alist[1]"); assertEvalEquals("15", "$alist[3][0]#set($alist[3][0] = 5)$alist[3][0]"); assertEvalEquals("orange","#set($blaa = {\"apple\":\"grape\"})#set($blaa[\"apple\"] = \"orange\")$blaa[\"apple\"]"); assertEvalEquals("null","#set($str[0] = $NULL)#if($str[0] == $NULL)null#end"); assertEvalEquals("null","#set($blaa = {\"apple\":\"grape\"})#set($blaa[\"apple\"] = $NULL)#if($blaa[\"apple\"] == $NULL)null#end"); assertEvalEquals("2112", "#set($a[-1] = 2112)$a[2]"); assertEvalEquals("3344","#set($hash = {1:11, 2:22, 5:66})#set($hash[2]=33)#set($hash[3]=44)$hash[2]$hash[3]"); } public void testErrorHandling() { assertEvalExceptionAt("$boo['throwex']", 1, 5); assertEvalExceptionAt("$boo[]", 1, 6); assertEvalExceptionAt("$boo[blaa]", 1, 6); assertEvalExceptionAt("#set($foo[1] = 3)", 1, 10); assertEvalExceptionAt("$a[500]", 1, 3); } public static class Foo { public Object bar = null; public Object getBar() { return bar; } public String get(Boolean bool) { if (bool.booleanValue()) return "BIG TRUE"; else return "BIG FALSE"; } public String get(String str) { return str + " foobar "; } } public static class Boo { public Object get(Object obj) { if (obj == null) return "GOT NULL"; else if (obj.equals("throwex")) throw new RuntimeException("Generated Exception"); return obj; } } } velocity-1.7/src/test/org/apache/velocity/test/VelocityServletTestCase.java0000644000175000017500000002240210513464370027137 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Properties; import java.util.Set; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.servlet.VelocityServlet; /** * Tests our VelocityServlet implementation. * * @author Daniel Rall */ public class VelocityServletTestCase extends TestCase { /** * Default constructor. */ public VelocityServletTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(VelocityServletTestCase.class); } /** * Runs the test. */ public void testVelocityServlet() throws Exception { /* * Assure we have the encoding we think we should. */ MockVelocityServlet servlet = new MockVelocityServlet(); servlet.init(new MockServletConfig()); System.out.println(RuntimeConstants.OUTPUT_ENCODING + "=" + RuntimeSingleton.getProperty (RuntimeConstants.OUTPUT_ENCODING)); HttpServletResponse res = new MockHttpServletResponse(); servlet.visibleSetContentType(null, res); assertEquals("Character encoding not set to UTF-8", "UTF-8", res.getCharacterEncoding()); } class MockVelocityServlet extends VelocityServlet { void visibleSetContentType(HttpServletRequest req, HttpServletResponse res) { setContentType(req, res); } protected Properties loadConfiguration(ServletConfig config) throws IOException { Properties p = new Properties(); p.setProperty(RuntimeConstants.OUTPUT_ENCODING, "UTF-8"); return p; } public ServletConfig getServletConfig() { return new MockServletConfig(); } } static class MockServletConfig implements ServletConfig { public String getInitParameter(String ignored) { return null; } public Enumeration getInitParameterNames() { return null; } public ServletContext getServletContext() { return new MockServletContext(); } public String getServletName() { return "VelocityServlet"; } } static class MockServletContext implements ServletContext { public Object getAttribute(String ignored) { return null; } public Enumeration getAttributeNames() { return null; } public ServletContext getContext(String ignored) { return this; } public String getServletContextName() { return "VelocityTestContext"; } public String getInitParameter(String ignored) { return null; } public Enumeration getInitParameterNames() { return null; } public int getMajorVersion() { return -1; } public String getMimeType(String ignored) { return null; } public Set getResourcePaths(String string) { return null; } public int getMinorVersion() { return -1; } public RequestDispatcher getNamedDispatcher(String ignored) { return null; } public String getRealPath(String ignored) { return null; } public RequestDispatcher getRequestDispatcher(String ignored) { return null; } public URL getResource(String ignored) throws MalformedURLException { return null; } public InputStream getResourceAsStream(String ignored) { return null; } public String getServerInfo() { return "Velocity Test Suite"; } public Servlet getServlet(String ignored) throws ServletException { return null; } public Enumeration getServletNames() { return null; } public Enumeration getServlets() { return null; } public void log(Exception e, String msg) { } public void log(String msg) { } public void log(String msg, Throwable t) { } public void removeAttribute(String name) { } public void setAttribute(String name, Object value) { } } static class MockHttpServletResponse implements HttpServletResponse { private String encoding; // ---- ServletResponse implementation ----------------------------- public void flushBuffer() throws IOException { } public void resetBuffer() { } public int getBufferSize() { return -1; } public String getCharacterEncoding() { return (encoding != null ? encoding : "ISO-8859-1"); } public java.util.Locale getLocale() { return null; } public javax.servlet.ServletOutputStream getOutputStream() throws IOException { return null; } public java.io.PrintWriter getWriter() throws IOException { return null; } public boolean isCommitted() { return false; } public void reset() { } public void setBufferSize(int i) { } public void setContentLength(int i) { } /** * Records the character encoding. */ public void setContentType(String contentType) { if (contentType != null) { int index = contentType.lastIndexOf(';') + 1; if (0 <= index || index < contentType.length()) { index = contentType.indexOf("charset=", index); if (index != -1) { index += 8; this.encoding = contentType.substring(index).trim(); } } } } public void setLocale(java.util.Locale l) { } // ---- HttpServletResponse implementation ------------------------- public void addCookie(javax.servlet.http.Cookie c) { } public void addDateHeader(String s, long l) { } public void addHeader(String name, String value) { } public void addIntHeader(String name, int value) { } public boolean containsHeader(String name) { return false; } public String encodeRedirectURL(String url) { return url; } public String encodeRedirectUrl(String url) { return url; } public String encodeURL(String url) { return url; } public String encodeUrl(String url) { return url; } public void sendError(int i) throws IOException { } public void sendError(int i, String s) throws IOException { } public void sendRedirect(String s) throws IOException { } public void setDateHeader(String s, long l) { } public void setHeader(String name, String value) { } public void setIntHeader(String s, int i) { } public void setStatus(int i) { } public void setStatus(int i , String s) { } } } velocity-1.7/src/test/org/apache/velocity/test/FilteredEventHandlingTestCase.java0000644000175000017500000001773710513464370030220 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; /** * Tests event handling for all event handlers when multiple event handlers are * assigned for each type. * * @author Will Glass-Husain * @version $Id: FilteredEventHandlingTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class FilteredEventHandlingTestCase extends BaseTestCase implements LogChute { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/includeevent/compare"; private String logString = null; /** * Default constructor. */ public FilteredEventHandlingTestCase(String name) { super(name); } /** * Required by LogChute */ public void init( RuntimeServices rs ) { /* don't need it...*/ } public static Test suite () { return new TestSuite(FilteredEventHandlingTestCase.class); } public void testFilteredEventHandling() throws Exception { String handler1 = "org.apache.velocity.test.eventhandler.Handler1"; String handler2 = "org.apache.velocity.test.eventhandler.Handler2"; String sequence1 = handler1 + "," + handler2; String sequence2 = handler2 + "," + handler1; assureResultsDirectoryExists(RESULTS_DIR); /** * Set up two VelocityEngines that will apply the handlers in both orders */ VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this); ve.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, sequence1); ve.setProperty(RuntimeConstants.EVENTHANDLER_NULLSET, sequence1); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, sequence1); ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, sequence1); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); VelocityEngine ve2 = new VelocityEngine(); ve2.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this); ve2.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, sequence2); ve2.setProperty(RuntimeConstants.EVENTHANDLER_NULLSET, sequence2); ve2.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, sequence2); ve2.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, sequence2); ve2.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve2.init(); VelocityContext context; StringWriter w; // check reference insertion with both sequences context = new VelocityContext(); w = new StringWriter(); context.put("test","abc"); ve.evaluate( context, w, "test", "$test" ); if ( !w.toString().equals( "ABCABC" )) { fail( "Reference insertion test 1"); } context = new VelocityContext(); w = new StringWriter(); context.put("test","abc"); ve2.evaluate( context, w, "test", "$test" ); if ( !w.toString().equals( "ABCabc" )) { fail( "Reference insertion test 2"); } // check method exception with both sequences // sequence 1 context = new VelocityContext(); w = new StringWriter(); context.put("test",new ArrayList()); try { ve.evaluate( context, w, "test", "$test.get(0)"); fail ( "Method exception event test 1" ); } catch( MethodInvocationException mee ) { // do nothing } // sequence2 context = new VelocityContext(); w = new StringWriter(); context.put("test",new ArrayList()); ve2.evaluate( context, w, "test", "$test.get(0)"); // check log on null set with both sequences // sequence 1 context = new VelocityContext(); w = new StringWriter(); logString = null; ve.evaluate( context, w, "test", "#set($test1 = $test2)" ); if ( logString != null) { fail( "log null set test 1"); } // sequence 2 context = new VelocityContext(); w = new StringWriter(); logString = null; ve2.evaluate( context, w, "test", "#set($test1 = $test2)" ); if ( logString != null) { fail( "log null set test 2"); } // check include event handler with both sequences // sequence 1 Template template; FileOutputStream fos; Writer fwriter; template = ve.getTemplate( getFileName(null, "test4", TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "test4", RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test4", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } // sequence 2 template = ve2.getTemplate( getFileName(null, "test5", TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "test5", RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test5", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } /** * handler for LogChute interface */ public void log(int level, String message) { logString = message; } public void log(int level, String message, Throwable t) { logString = message; } public boolean isLevelEnabled(int level) { return true; } } velocity-1.7/src/test/org/apache/velocity/test/VelocimacroTestCase.java0000644000175000017500000001125511273703572026247 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.MacroOverflowException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.misc.TestLogChute; /** * This class tests strange Velocimacro issues. * * @author Geir Magnusson Jr. * @version $Id: VelocimacroTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class VelocimacroTestCase extends TestCase { private String template1 = "#macro(foo $a)$a#end #macro(bar $b)#foo($b)#end #foreach($i in [1..3])#if($i == 3)#foo($i)#else#bar($i)#end#end"; private String result1 = " 123"; private String template2 = "#macro(bar $a)#set($a = $a + 1)$a#bar($a)#end#bar(0)"; private String template3 = "#macro(baz $a)#set($a = $a + 1)$a#inner($a)#end#macro(inner $b)#baz($b)#end#baz(0)"; private String template4 = "#macro(bad $a)#set($a = $a + 1)$a#inside($a)#end#macro(inside $b)#loop($b)#end#macro(loop $c)#bad($c)#end#bad(0)"; VelocityEngine engine = new VelocityEngine(); public VelocimacroTestCase(String name) { super(name); } public void setUp() throws Exception { /* * setup local scope for templates */ engine.setProperty( RuntimeConstants.VM_PERM_INLINE_LOCAL, Boolean.TRUE); engine.setProperty( RuntimeConstants.VM_MAX_DEPTH, new Integer(5)); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public static Test suite() { return new TestSuite(VelocimacroTestCase.class); } /** * Runs the test. */ public void testVelociMacro () throws Exception { VelocityContext context = new VelocityContext(); StringWriter writer = new StringWriter(); engine.evaluate(context, writer, "vm_chain1", template1); String out = writer.toString(); if( !result1.equals( out ) ) { fail("output incorrect."); } } /** * Test case for evaluating max calling depths of macros */ public void testVelociMacroCallMax() throws Exception { VelocityContext context = new VelocityContext(); StringWriter writer = new StringWriter(); try { engine.evaluate(context, writer, "vm_chain2", template2); fail("Did not exceed max macro call depth as expected"); } catch (MacroOverflowException e) { assertEquals("Max calling depth of 5 was exceeded in macro 'bar'"+ " with Call Stack:bar->bar->bar->bar->bar at vm_chain2[line 1, column 15]", e.getMessage()); } try { engine.evaluate(context, writer, "vm_chain3", template3); fail("Did not exceed max macro call depth as expected"); } catch (MacroOverflowException e) { assertEquals("Max calling depth of 5 was exceeded in macro 'inner'"+ " with Call Stack:baz->inner->baz->inner->baz at vm_chain3[line 1, column 64]", e.getMessage()); } try { engine.evaluate(context, writer, "vm_chain4", template4); fail("Did not exceed max macro call depth as expected"); } catch (MacroOverflowException e) { assertEquals("Max calling depth of 5 was exceeded in macro 'loop'"+ " with Call Stack:bad->inside->loop->bad->inside at vm_chain4[line 1, column 94]", e.getMessage()); } } } velocity-1.7/src/test/org/apache/velocity/test/VMLibraryTestCase.java0000644000175000017500000002333711075007114025644 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.misc.TestLogChute; /** * Macro library inclution via the Template.merge method is tested using this * class. */ public class VMLibraryTestCase extends BaseTestCase { /** * This engine is used with local namespaces */ private VelocityEngine ve1 = new VelocityEngine(); /** * This engine is used with global namespaces */ private VelocityEngine ve2 = new VelocityEngine(); private static final String RESULT_DIR = TEST_RESULT_DIR + "/macrolibs"; private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/macrolibs/compare"; public VMLibraryTestCase(String name) { super(name); } public void setUp() throws Exception { /* * setup local scope for templates */ ve1.setProperty( Velocity.VM_PERM_INLINE_LOCAL, Boolean.TRUE); ve1.setProperty("velocimacro.permissions.allow.inline.to.replace.global", Boolean.FALSE); /** * Turn on the cache */ ve1.setProperty("file.resource.loader.cache", Boolean.TRUE); ve1.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); ve1.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve1.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEST_COMPARE_DIR + "/macrolibs"); ve1.init(); /** * Set to global namespaces */ ve2.setProperty( Velocity.VM_PERM_INLINE_LOCAL, Boolean.FALSE); ve2.setProperty("velocimacro.permissions.allow.inline.to.replace.global", Boolean.TRUE); /** * Turn on the cache */ ve2.setProperty("file.resource.loader.cache", Boolean.FALSE); ve2.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); ve2.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve2.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEST_COMPARE_DIR + "/macrolibs"); ve2.init(); } public static junit.framework.Test suite() { return new TestSuite(VMLibraryTestCase.class); } /** * Runs the tests with local namespace. */ public void testVelociMacroLibWithLocalNamespace() throws Exception { assureResultsDirectoryExists(RESULT_DIR); /** * Clear the file before proceeding */ File file = new File(getFileName( RESULT_DIR, "vm_library_local", RESULT_FILE_EXT)); if (file.exists()) { file.delete(); } /** * Create a file output stream for appending */ FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "vm_library_local", RESULT_FILE_EXT), true); List templateList = new ArrayList(); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); templateList.add("vm_library1.vm"); Template template = ve1.getTemplate("vm_library_local.vm"); template.merge(context, writer, templateList); /** * remove the first template library and includes a new library * with a new definition for macros */ templateList.remove(0); templateList.add("vm_library2.vm"); template = ve1.getTemplate("vm_library_local.vm"); template.merge(context, writer, templateList); /* *Show that caching is working */ Template t1 = ve1.getTemplate("vm_library_local.vm"); Template t2 = ve1.getTemplate("vm_library_local.vm"); assertEquals("Both templates refer to the same object", t1, t2); /** * Remove the libraries */ template = ve1.getTemplate("vm_library_local.vm"); template.merge(context, writer); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, "vm_library_local", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } /** * Runs the tests with global namespace. */ public void testVelociMacroLibWithGlobalNamespace() throws Exception { assureResultsDirectoryExists(RESULT_DIR); /** * Clear the file before proceeding */ File file = new File(getFileName( RESULT_DIR, "vm_library_global", RESULT_FILE_EXT)); if (file.exists()) { file.delete(); } /** * Create a file output stream for appending */ FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "vm_library_global", RESULT_FILE_EXT), true); List templateList = new ArrayList(); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); templateList.add("vm_library1.vm"); Template template = ve1.getTemplate("vm_library_global.vm"); template.merge(context, writer, templateList); /** * remove the first template library and includes a new library * with a new definition for macros */ templateList.remove(0); templateList.add("vm_library2.vm"); template = ve1.getTemplate("vm_library_global.vm"); template.merge(context, writer, templateList); /* *Show that caching is not working (We have turned off cache) */ Template t1 = ve2.getTemplate("vm_library_global.vm"); Template t2 = ve2.getTemplate("vm_library_global.vm"); assertNotSame("Defferent objects", t1, t2); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, "vm_library_global", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } /** * Runs the tests with global namespace. */ public void testVelociMacroLibWithDuplicateDefinitions() throws Exception { assureResultsDirectoryExists(RESULT_DIR); /** * Clear the file before proceeding */ File file = new File(getFileName( RESULT_DIR, "vm_library_duplicate", RESULT_FILE_EXT)); if (file.exists()) { file.delete(); } /** * Create a file output stream for appending */ FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "vm_library_duplicate", RESULT_FILE_EXT), true); List templateList = new ArrayList(); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); templateList.add("vm_library1.vm"); templateList.add("vm_library2.vm"); Template template = ve1.getTemplate("vm_library.vm"); template.merge(context, writer, templateList); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, "vm_library_duplicate", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } /** * Test whether the literal text is given if a definition cannot be * found for a macro. * * @throws Exception */ public void testMacrosWithNoDefinition() throws Exception { assureResultsDirectoryExists(RESULT_DIR); FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "vm_library", RESULT_FILE_EXT)); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); Template template = ve1.getTemplate("vm_library.vm"); template.merge(context, writer, null); /** * Write to the file */ writer.flush(); writer.close(); /** * outputs the macro calls */ if (!isMatch(RESULT_DIR, COMPARE_DIR, "vm_library", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } } velocity-1.7/src/test/org/apache/velocity/test/ResourceLoaderInstanceTestCase.java0000644000175000017500000001217711057300641030401 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.runtime.resource.loader.FileResourceLoader; import org.apache.velocity.runtime.resource.loader.ResourceLoader; /** * Test that an instance of a ResourceLoader can be successfully passed in. * * @author Will Glass-Husain * @version $Id: ResourceLoaderInstanceTestCase.java 691334 2008-09-02 18:10:41Z nbubna $ */ public class ResourceLoaderInstanceTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/resourceinstance"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/resourceinstance"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/resourceinstance/compare"; private TestLogChute logger = new TestLogChute(); /** * Default constructor. */ public ResourceLoaderInstanceTestCase(String name) { super(name); } public void setUp() throws Exception { ResourceLoader rl = new FileResourceLoader(); // pass in an instance to Velocity Velocity.setProperty( "resource.loader", "testrl" ); Velocity.setProperty( "testrl.resource.loader.instance", rl ); Velocity.setProperty( "testrl.resource.loader.path", FILE_RESOURCE_LOADER_PATH ); // actual instance of logger logger.on(); Velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, logger); Velocity.setProperty("runtime.log.logsystem.test.level", "debug"); Velocity.init(); } public static Test suite () { return new TestSuite(ResourceLoaderInstanceTestCase.class); } /** * Runs the test. */ public void testResourceLoaderInstance () throws Exception { //caveman hacks to get gump to give more info try { assureResultsDirectoryExists(RESULTS_DIR); Template template = RuntimeSingleton.getTemplate( getFileName(null, "testfile", TMPL_FILE_EXT)); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, "testfile", RESULT_FILE_EXT)); //caveman hack to get gump to give more info System.out.println("All needed files exist"); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template.merge(context, writer); writer.flush(); writer.close(); } catch (Exception e) { System.out.println("Log was: "+logger.getLog()); System.out.println(e); e.printStackTrace(); } if ( !isMatch(RESULTS_DIR, COMPARE_DIR, "testfile", RESULT_FILE_EXT, CMP_FILE_EXT) ) { String result = getFileContents(RESULT_DIR, "testfile", RESULT_FILE_EXT); String compare = getFileContents(COMPARE_DIR, "testfile", CMP_FILE_EXT); String msg = "Processed template did not match expected output\n"+ "-----Result-----\n"+ result + "----Expected----\n"+ compare + "----------------"; //caveman hack to get gump to give more info System.out.println(msg); System.out.println("Log was: "+logger.getLog()); fail(msg); } } } velocity-1.7/src/test/org/apache/velocity/test/EvaluateTestCase.java0000644000175000017500000002215011206073012025527 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.event.implement.EscapeHtmlReference; import org.apache.velocity.context.Context; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.runtime.RuntimeConstants; /** * Test #evaluate directive. * * @author Will Glass-Husain * @version $Id: EvaluateTestCase.java 778045 2009-05-23 22:17:46Z nbubna $ */ public class EvaluateTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/evaluate"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/evaluate"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/evaluate/compare"; /** * Default constructor. * @param name */ public EvaluateTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); assureResultsDirectoryExists(RESULTS_DIR); } /** * Test basic functionality. * @throws Exception */ public void testEvaluate() throws Exception { Map props = new HashMap(); props.put(RuntimeConstants.EVALUATE_CONTEXT_CLASS, VelocityContext.class.getName()); testFile("eval1", props); } /** * Test evaluate directive preserves macros (VELOCITY-591) * @throws Exception */ public void testEvaluateMacroPreserve() throws Exception { Map properties = new HashMap(); properties.clear(); properties.put(RuntimeConstants.VM_CONTEXT_LOCALSCOPE,"false"); testFile("eval2", properties); properties.clear(); properties.put(RuntimeConstants.VM_CONTEXT_LOCALSCOPE,"true"); testFile("eval2", properties); properties.clear(); properties.put(RuntimeConstants.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL,"false"); testFile("eval2", properties); } /** * Test in a macro context. * @throws Exception */ public void testEvaluateVMContext() throws Exception { testFile("evalvmcontext", new HashMap()); } /** * Test #stop and #break * @throws Exception */ public void testStopAndBreak() { engine.setProperty("evaluate.provide.scope.control", "true"); assertEvalEquals("t ", "t #stop t2 #evaluate('t3')"); assertEvalEquals("t ", "t #break t2 #evaluate('t3')"); //assertEvalEquals("t t2 t3 ", "t t2 #evaluate('t3 #stop t4') t5"); assertEvalEquals("t t2 t3 t5", "t t2 #evaluate('t3 #break t4') t5"); assertEvalEquals("t t2 t3 ", "t t2 #evaluate('t3 #break($evaluate.topmost) t4') t5"); } /** * Test that the event handlers work in #evaluate (since they are * attached to the context). Only need to check one - they all * work the same. * @throws Exception */ public void testEventHandler() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, EscapeHtmlReference.class.getName()); ve.init(); Context context = new VelocityContext(); context.put("lt","<"); context.put("gt",">"); StringWriter writer = new StringWriter(); ve.evaluate(context, writer, "test","${lt}test${gt} #evaluate('${lt}test2${gt}')"); assertEquals("<test> <test2>", writer.toString()); } /** * Test errors are thrown * @throws Exception */ public void testErrors() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); Context context = new VelocityContext(); // no arguments StringWriter writer = new StringWriter(); try { ve.evaluate(context, writer, "test", "#evaluate()"); fail("Expected exception"); } catch (ParseErrorException e) { assertEquals("test",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(1,e.getColumnNumber()); } // too many arguments writer = new StringWriter(); try { ve.evaluate(context, writer, "test", "#evaluate('aaa' 'bbb')"); fail("Expected exception"); } catch (ParseErrorException e) { assertEquals("test",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(17,e.getColumnNumber()); } // argument not a string or reference writer = new StringWriter(); try { ve.evaluate(context, writer, "test", "#evaluate(10)"); fail("Expected exception"); } catch (ParseErrorException e) { assertEquals("test",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(11,e.getColumnNumber()); } // checking line/col for parse error writer = new StringWriter(); try { String eval = "this is a multiline\n\n\n\n\n test #foreach() with an error"; context.put("eval",eval); ve.evaluate(context, writer, "test", "first line\n second line: #evaluate($eval)"); fail("Expected exception"); } catch (ParseErrorException e) { // should be start of #evaluate assertEquals("test",e.getTemplateName()); assertEquals(2,e.getLineNumber()); assertEquals(15,e.getColumnNumber()); } } /** * Test a file parses with no errors and compare to existing file. * @param basefilename * @throws Exception */ private void testFile(String basefilename, Map properties) throws Exception { info("Test file: "+basefilename); VelocityEngine ve = engine; ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); for (Iterator i = properties.keySet().iterator(); i.hasNext();) { String key = (String) i.next(); String value = (String) properties.get(key); ve.addProperty(key, value); info("Add property: "+key+" = "+value); } ve.init(); Template template; FileOutputStream fos; Writer fwriter; template = ve.getTemplate( getFileName(null, basefilename, TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, basefilename, RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, basefilename, RESULT_FILE_EXT, CMP_FILE_EXT)) { String result = getFileContents(RESULTS_DIR, basefilename, RESULT_FILE_EXT); String compare = getFileContents(COMPARE_DIR, basefilename, CMP_FILE_EXT); String msg = "Output was incorrect\n"+ "-----Result-----\n"+ result + "----Expected----\n"+ compare + "----------------"; fail(msg); } } } velocity-1.7/src/test/org/apache/velocity/test/StringResourceLoaderRepositoryTestCase.java0000644000175000017500000001701511322700447032202 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.TestCase; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.runtime.log.SystemLogChute; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl; /** * Tests ability to have multiple repositories in the same app. * * @author Nathan Bubna * @version $Id: StringResourceLoaderRepositoryTestCase.java 479058 2006-11-25 00:26:32Z henning $ */ public class StringResourceLoaderRepositoryTestCase extends TestCase { private VelocityContext context; public StringResourceLoaderRepositoryTestCase(String name) { super(name); } public void setUp() throws Exception { Velocity.setProperty(Velocity.RESOURCE_LOADER, "string"); Velocity.addProperty("string.resource.loader.class", StringResourceLoader.class.getName()); Velocity.addProperty("string.resource.loader.modificationCheckInterval", "1"); Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, SystemLogChute.class.getName()); Velocity.init(); StringResourceRepository repo = getRepo(null, null); // this will fail when run as part of suite of tests in one process // but it's only required for several tests if (repo != null) { repo.putStringResource("foo", "This is $foo"); repo.putStringResource("bar", "This is $bar"); } context = new VelocityContext(); context.put("foo", "wonderful!"); context.put("bar", "horrible!"); context.put("woogie", "a woogie"); } protected VelocityEngine newStringEngine(String repoName, boolean isStatic) { VelocityEngine engine = new VelocityEngine(); engine.setProperty(Velocity.RESOURCE_LOADER, "string"); engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName()); if (repoName != null) { engine.addProperty("string.resource.loader.repository.name", repoName); } if (!isStatic) { engine.addProperty("string.resource.loader.repository.static", "false"); } engine.addProperty("string.resource.loader.modificationCheckInterval", "1"); engine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, SystemLogChute.class.getName()); return engine; } protected StringResourceRepository getRepo(String name, VelocityEngine engine) { if (engine == null) { if (name == null) { return StringResourceLoader.getRepository(); } else { return StringResourceLoader.getRepository(name); } } else { if (name == null) { return (StringResourceRepository)engine.getApplicationAttribute(StringResourceLoader.REPOSITORY_NAME_DEFAULT); } else { return (StringResourceRepository)engine.getApplicationAttribute(name); } } } protected String render(Template template) throws Exception { StringWriter out = new StringWriter(); template.merge(this.context, out); return out.toString(); } public void testSharedRepo() throws Exception { // this engine's string resource loader should share a repository // with the singleton's string resource loader VelocityEngine engine = newStringEngine(null, true); // get and merge the same template from both runtimes with the same context String engineOut = render(engine.getTemplate("foo")); String singletonOut = render(RuntimeSingleton.getTemplate("foo")); // make sure they're equal assertEquals(engineOut, singletonOut); } public void testAlternateStaticRepo() throws Exception { VelocityEngine engine = newStringEngine("alternate.repo", true); // should be null be for init StringResourceRepository repo = getRepo("alternate.repo", null); assertNull(repo); engine.init(); // and not null after init repo = getRepo("alternate.repo", null); assertNotNull(repo); repo.putStringResource("foo", "This is NOT $foo"); // get and merge template with the same name from both runtimes with the same context String engineOut = render(engine.getTemplate("foo")); String singletonOut = render(RuntimeSingleton.getTemplate("foo")); // make sure they're NOT equal assertFalse(engineOut.equals(singletonOut)); } public void testPreCreatedStaticRepo() throws Exception { VelocityEngine engine = newStringEngine("my.repo", true); MyRepo repo = new MyRepo(); repo.put("bar", "This is NOT $bar"); StringResourceLoader.setRepository("my.repo", repo); String out = render(engine.getTemplate("bar")); assertEquals(out, "This is NOT horrible!"); } public void testAppRepo() throws Exception { VelocityEngine engine = newStringEngine(null, false); engine.init(); StringResourceRepository repo = getRepo(null, engine); assertNotNull(repo); repo.putStringResource("woogie", "What is $woogie?"); String out = render(engine.getTemplate("woogie")); assertEquals(out, "What is a woogie?"); } public void testAlternateAppRepo() throws Exception { VelocityEngine engine = newStringEngine("alternate.app.repo", false); engine.init(); StringResourceRepository repo = getRepo("alternate.app.repo", engine); assertNotNull(repo); repo.putStringResource("you/foo.vm", "You look $foo"); String out = render(engine.getTemplate("you/foo.vm")); assertEquals(out, "You look wonderful!"); } public void testPreCreatedAppRepo() throws Exception { VelocityEngine engine = newStringEngine("my.app.repo", false); MyRepo repo = new MyRepo(); repo.put("you/bar.vm", "You look $bar"); engine.setApplicationAttribute("my.app.repo", repo); String out = render(engine.getTemplate("you/bar.vm")); assertEquals(out, "You look horrible!"); } public static class MyRepo extends StringResourceRepositoryImpl { public void put(String name, String template) { putStringResource(name, template); } } } velocity-1.7/src/test/org/apache/velocity/test/UnicodeEscapeTestCase.java0000644000175000017500000000407111142425303026475 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.runtime.parser.node.ASTStringLiteral; /** * Test Case for Velocity Tools Issue 520. */ public class UnicodeEscapeTestCase extends BaseTestCase { public UnicodeEscapeTestCase(final String name) throws Exception { super(name); } public void testUnicodeEscape() throws Exception { assertEvalEquals("a", "#set($v = \"\\u0061\")$v"); } private void assertUnescape(String expected, String escaped) { String unescaped = ASTStringLiteral.unescape(escaped); assertEquals(expected, unescaped); if (escaped.equals(expected)) { // checking that no new string allocated, for perfomance assertSame(unescaped, escaped); } } public void testASTStringLiteralUnescape() { assertUnescape("", ""); assertUnescape("bebe", "bebe"); assertUnescape("as\\nsd", "as\\nsd"); assertUnescape("a", "\\u0061"); assertUnescape("abc", "\\u0061bc"); assertUnescape("\u0061bc\u0064", "\\u0061bc\\u0064"); assertUnescape("z\u0061bc\u0064f", "z\\u0061bc\\u0064f"); } } velocity-1.7/src/test/org/apache/velocity/test/NumberMethodCallsTestCase.java0000644000175000017500000001236010513464370027346 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.test.provider.NumberMethods; /** * Used to check that method calls with number parameters are executed correctly. * * @author Peter Romianowski * @author Will Glass-Husain */ public class NumberMethodCallsTestCase extends TestCase { private VelocityEngine ve = null; private final static boolean PRINT_RESULTS = false; /** * Default constructor. */ public NumberMethodCallsTestCase(String name) { super(name); } public void setUp() throws Exception { ve = new VelocityEngine(); ve.init(); } public void init( RuntimeServices rs ) { // do nothing with it } public static Test suite () { return new TestSuite(NumberMethodCallsTestCase.class); } /** * Runs the test. */ public void testNumberMethodCalls () throws Exception { VelocityContext vc = new VelocityContext(); // context object with overloaded methods with number arguments vc.put("Test",new NumberMethods()); // numbers for context vc.put("AByte",new Byte("10")); vc.put("AShort",new Short("10")); vc.put("AInteger",new Integer(10)); vc.put("ALong",new Long(10)); vc.put("ADouble",new Double(10)); vc.put("AFloat",new Float(10)); vc.put("ABigDecimal",new BigDecimal(10)); vc.put("ABigInteger",new BigInteger("10")); // check context objects System.out.println("Testing: method calls with arguments as context objects"); checkResults(vc,"$Test.numMethod($AByte)","byte (10)"); checkResults(vc,"$Test.numMethod($AShort)","short (10)"); checkResults(vc,"$Test.numMethod($AInteger)","int (10)"); checkResults(vc,"$Test.numMethod($ADouble)","double (10.0)"); checkResults(vc,"$Test.numMethod($AFloat)","double (10.0)"); checkResults(vc,"$Test.numMethod($ALong)","long (10)"); checkResults(vc,"$Test.numMethod($ABigDecimal)","BigDecimal (10)"); checkResults(vc,"$Test.numMethod($ABigInteger)","BigInteger (10)"); // check literals // -- will cast floating point literal to smallest possible of Double, BigDecimal // -- will cast integer literal to smallest possible of Integer, Long, BigInteger System.out.println("Testing: method calls with arguments as literals"); checkResults(vc,"$Test.numMethod(10.0)","double (10.0)"); checkResults(vc,"$Test.numMethod(10)","int (10)"); checkResults(vc,"$Test.numMethod(10000000000)","long (10000000000)"); checkResults(vc,"$Test.numMethod(10000000000000000000000)","BigInteger (10000000000000000000000)"); // check calculated results // -- note calculated value is cast to smallest possible type // -- method invoked is smallest relevant method // -- it's an unusual case here of both byte and int methods, but this works as expected System.out.println("Testing: method calls with arguments as calculated values"); checkResults(vc,"#set($val = 10.0 + 1.5)$Test.numMethod($val)","double (11.5)"); checkResults(vc,"#set($val = 100 + 1)$Test.numMethod($val)","int (101)"); checkResults(vc,"#set($val = 100 * 1000)$Test.numMethod($val)","int (100000)"); checkResults(vc,"#set($val = 100 + 1.5)$Test.numMethod($val)","double (101.5)"); checkResults(vc,"#set($val = $ALong + $AInteger)$Test.numMethod($val)","long (20)"); checkResults(vc,"#set($val = $ABigInteger + $AInteger)$Test.numMethod($val)","BigInteger (20)"); } private void checkResults(Context vc, String template, String compare) throws Exception { StringWriter writer = new StringWriter(); ve.evaluate( vc, writer, "test", template); assertEquals("Incorrect results for template '" + template + "'.",compare,writer.toString()); if (PRINT_RESULTS) System.out.println ("Method call successful: " + template); } } velocity-1.7/src/test/org/apache/velocity/test/BaseTestCase.java0000644000175000017500000003526411322700447024655 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.File; import java.io.IOException; import java.io.StringWriter; import junit.framework.TestCase; import org.apache.oro.text.perl.Perl5Util; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.util.StringUtils; /** * Base test case that provides utility methods for * the rest of the tests. * * @author Daniel Rall * @author Nathan Bubna * @version $Id: BaseTestCase.java 898032 2010-01-11 19:51:03Z nbubna $ */ public abstract class BaseTestCase extends TestCase implements TemplateTestBase { protected VelocityEngine engine; protected VelocityContext context; protected boolean DEBUG = false; protected TestLogChute log; protected String stringRepoName = "string.repo"; public BaseTestCase(String name) { super(name); // if we're just running one case, then have DEBUG // automatically set to true String testcase = System.getProperty("testcase"); if (testcase != null) { DEBUG = testcase.equals(getClass().getName()); } } protected void setUp() throws Exception { engine = new VelocityEngine(); //by default, make the engine's log output go to the test-report log = new TestLogChute(false, false); log.setEnabledLevel(TestLogChute.INFO_ID); log.setSystemErrLevel(TestLogChute.WARN_ID); engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, log); // use string resource loader by default, instead of file engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file,string"); engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName()); engine.addProperty("string.resource.loader.repository.name", stringRepoName); engine.addProperty("string.resource.loader.repository.static", "false"); setUpEngine(engine); context = new VelocityContext(); setUpContext(context); } protected void setUpEngine(VelocityEngine engine) { // extension hook } protected void setUpContext(VelocityContext context) { // extension hook } protected StringResourceRepository getStringRepository() { StringResourceRepository repo = (StringResourceRepository)engine.getApplicationAttribute(stringRepoName); if (repo == null) { engine.init(); repo = (StringResourceRepository)engine.getApplicationAttribute(stringRepoName); } return repo; } protected void addTemplate(String name, String template) { info("Template '"+name+"': "+template); getStringRepository().putStringResource(name, template); } protected void removeTemplate(String name) { info("Removed: '"+name+"'"); getStringRepository().removeStringResource(name); } public void tearDown() { engine = null; context = null; } protected void info(String msg) { if (DEBUG) { if (engine == null) { Velocity.getLog().info(msg); } else { engine.getLog().info(msg); } } } protected void info(String msg, Throwable t) { if (DEBUG) { if (engine == null) { Velocity.getLog().info(msg); } else { engine.getLog().info(msg, t); } } } public void testBase() { if (DEBUG && engine != null) { assertSchmoo(""); assertSchmoo("abc\n123"); } } /** * Compare an expected string with the given loaded template */ protected void assertTmplEquals(String expected, String template) { info("Expected: " + expected + " from '" + template + "'"); StringWriter writer = new StringWriter(); try { engine.mergeTemplate(template, "utf-8", context, writer); } catch (RuntimeException re) { info("RuntimeException!", re); throw re; } catch (Exception e) { info("Exception!", e); throw new RuntimeException(e); } info("Result: " + writer.toString()); assertEquals(expected, writer.toString()); } /** * Ensure that a context value is as expected. */ protected void assertContextValue(String key, Object expected) { info("Expected value of '"+key+"': "+expected); Object value = context.get(key); info("Result: "+value); assertEquals(expected, value); } /** * Ensure that a template renders as expected. */ protected void assertEvalEquals(String expected, String template) { info("Expectation: "+expected); assertEquals(expected, evaluate(template)); } /** * Ensure that the given string renders as itself when evaluated. */ protected void assertSchmoo(String templateIsExpected) { assertEvalEquals(templateIsExpected, templateIsExpected); } /** * Ensure that an exception occurs when the string is evaluated. */ protected Exception assertEvalException(String evil) { return assertEvalException(evil, null); } /** * Ensure that a specified type of exception occurs when evaluating the string. */ protected Exception assertEvalException(String evil, Class exceptionType) { try { if (!DEBUG) { log.off(); } if (exceptionType != null) { info("Expectation: "+exceptionType.getName()); } evaluate(evil); fail("Template '"+evil+"' should have thrown an exception."); } catch (Exception e) { if (exceptionType != null && !exceptionType.isAssignableFrom(e.getClass())) { fail("Was expecting template '"+evil+"' to throw "+exceptionType+" not "+e); } return e; } finally { if (!DEBUG) { log.on(); } } return null; } /** * Ensure that the error message of the expected exception has the proper location info. */ protected Exception assertEvalExceptionAt(String evil, String template, int line, int col) { String loc = template+"[line "+line+", column "+col+"]"; info("Expectation: Exception at "+loc); Exception e = assertEvalException(evil); info("Result: "+e.getClass().getName()+" - "+e.getMessage()); if (e.getMessage().indexOf(loc) < 1) { fail("Was expecting exception at "+loc+" instead of "+e.getMessage()); } return e; } /** * Only ensure that the error message of the expected exception * has the proper line and column info. */ protected Exception assertEvalExceptionAt(String evil, int line, int col) { return assertEvalExceptionAt(evil, "", line, col); } /** * Evaluate the specified String as a template and return the result as a String. */ protected String evaluate(String template) { StringWriter writer = new StringWriter(); try { info("Template: "+template); // use template as its own name, since our templates are short // unless it's not that short, then shorten it... String name = (template.length() <= 15) ? template : template.substring(0,15); engine.evaluate(context, writer, name, template); String result = writer.toString(); info("Result: "+result); return result; } catch (RuntimeException re) { info("RuntimeException!", re); throw re; } catch (Exception e) { info("Exception!", e); throw new RuntimeException(e); } } /** * Concatenates the file name parts together appropriately. * * @return The full path to the file. */ protected String getFileName(final String dir, final String base, final String ext) { return getFileName(dir, base, ext, false); } protected String getFileName(final String dir, final String base, final String ext, final boolean mustExist) { StringBuffer buf = new StringBuffer(); try { File baseFile = new File(base); if (dir != null) { if (!baseFile.isAbsolute()) { baseFile = new File(dir, base); } buf.append(baseFile.getCanonicalPath()); } else { buf.append(baseFile.getPath()); } if (org.apache.commons.lang.StringUtils.isNotEmpty(ext)) { buf.append('.').append(ext); } if (mustExist) { File testFile = new File(buf.toString()); if (!testFile.exists()) { String msg = "getFileName() result " + testFile.getPath() + " does not exist!"; info(msg); fail(msg); } if (!testFile.isFile()) { String msg = "getFileName() result " + testFile.getPath() + " is not a file!"; info(msg); fail(msg); } } } catch (IOException e) { fail("IO Exception while running getFileName(" + dir + ", " + base + ", "+ ext + ", " + mustExist + "): " + e.getMessage()); } return buf.toString(); } /** * Assures that the results directory exists. If the results directory * cannot be created, fails the test. */ protected void assureResultsDirectoryExists(String resultsDirectory) { File dir = new File(resultsDirectory); if (!dir.exists()) { info("Template results directory ("+resultsDirectory+") does not exist"); if (dir.mkdirs()) { info("Created template results directory"); if (DEBUG) { info("Created template results directory: "+resultsDirectory); } } else { String errMsg = "Unable to create '"+resultsDirectory+"'"; info(errMsg); fail(errMsg); } } } //TODO: drop this for JDK regex once we move to JDK 1.5 private static Perl5Util perl = new Perl5Util(); /** * Normalizes lines to account for platform differences. Macs use * a single \r, DOS derived operating systems use \r\n, and Unix * uses \n. Replace each with a single \n. * * @author Sam Ruby * @return source with all line terminations changed to Unix style */ protected String normalizeNewlines (String source) { return perl.substitute("s/\r[\r]?[\n]/\n/g", source); } /** * Returns whether the processed template matches the * content of the provided comparison file. * * @return Whether the output matches the contents * of the comparison file. * * @exception Exception Test failure condition. */ protected boolean isMatch (String resultsDir, String compareDir, String baseFileName, String resultExt, String compareExt) throws Exception { String result = getFileContents(resultsDir, baseFileName, resultExt); return isMatch(result,compareDir,baseFileName,compareExt); } protected String getFileContents(String dir, String baseFileName, String ext) { String fileName = getFileName(dir, baseFileName, ext, true); return StringUtils.fileContentsToString(fileName); } /** * Returns whether the processed template matches the * content of the provided comparison file. * * @return Whether the output matches the contents * of the comparison file. * * @exception Exception Test failure condition. */ protected boolean isMatch (String result, String compareDir, String baseFileName, String compareExt) throws Exception { String compare = getFileContents(compareDir, baseFileName, compareExt); // normalize each wrt newline result = normalizeNewlines(result); compare = normalizeNewlines(compare); if (DEBUG) { info("Expection: "+compare); info("Result: "+result); } return result.equals(compare); } /** * Turns a base file name into a test case name. * * @param s The base file name. * @return The test case name. */ protected static final String getTestCaseName(String s) { StringBuffer name = new StringBuffer(); name.append(Character.toTitleCase(s.charAt(0))); name.append(s.substring(1, s.length()).toLowerCase()); return name.toString(); } } velocity-1.7/src/test/org/apache/velocity/test/TestBaseTestCase.java0000644000175000017500000000516610513464370025516 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.File; import junit.framework.Test; import junit.framework.TestSuite; /** * I keep breaking the getFileName method all the time... */ public class TestBaseTestCase extends BaseTestCase { public TestBaseTestCase(final String name) { super(name); } public static Test suite() { return new TestSuite(TestBaseTestCase.class); } public void testGetFileName() throws Exception { String fs = System.getProperty("file.separator"); String pwd = System.getProperty("user.dir"); String root = new File("/").getCanonicalPath(); assertEquals(pwd + fs + "baz" + fs + "foo.bar", getFileName("baz", "foo", "bar")); assertEquals(root + "baz" + fs + "foo.bar", getFileName(root + "baz", "foo", "bar")); assertEquals(root + "foo.bar", getFileName("baz", root + "foo", "bar")); assertEquals(root + "foo.bar", getFileName(root + "baz", root + "foo", "bar")); assertEquals("", getFileName(null, "", "")); assertEquals(root + "", getFileName("", "", "")); assertEquals(".x", getFileName(null, "", "x")); assertEquals(root + ".x", getFileName("", "", "x")); assertEquals("foo.bar", getFileName(null, "foo", "bar")); assertEquals(root + "foo.bar", getFileName(null, root + "foo", "bar")); assertEquals(root + "foo.bar", getFileName("", "foo", "bar")); assertEquals(root + "foo.bar", getFileName("", root + "foo", "bar")); } } velocity-1.7/src/test/org/apache/velocity/test/MethodOverloadingTestCase.java0000644000175000017500000001374310513464370027416 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; /** * Test a reported bug in which method overloading throws IllegalArgumentException * after a null return value. * (VELOCITY-132). * * @author Will Glass-Husain * @version $Id: MethodOverloadingTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class MethodOverloadingTestCase extends BaseTestCase implements LogChute { String logData; /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/methodoverloading"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/methodoverloading"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/methodoverloading/compare"; /** * Default constructor. */ public MethodOverloadingTestCase(String name) { super(name); } public void setUp() { assureResultsDirectoryExists(RESULTS_DIR); } public static Test suite() { return new TestSuite(MethodOverloadingTestCase.class); } public void testMethodOverloading() throws Exception { /** * test overloading in a single template */ testFile("single"); assertTrue(logData.indexOf("IllegalArgumentException") == -1); } public void testParsedMethodOverloading() throws Exception { /** * test overloading in a file included with #parse */ testFile("main"); assertTrue(logData.indexOf("IllegalArgumentException") == -1); } public void testFile(String basefilename) throws Exception { VelocityEngine ve = new VelocityEngine(); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this ); ve.init(); Template template; FileOutputStream fos; Writer fwriter; Context context; template = ve.getTemplate( getFileName(null, basefilename, TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, basefilename, RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); setupContext(context); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, basefilename, RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } public void setupContext(Context context) { context.put("test", this); context.put("nullValue", null); } public String overloadedMethod ( Integer s ) { return "Integer"; } public String overloadedMethod ( String s ) { return "String"; } public String overloadedMethod2 ( Integer s ) { return "Integer"; } public String overloadedMethod2 ( String i ) { return "String"; } public void log(int level, String message) { String out = ""; /* * Start with the appropriate prefix */ switch( level ) { case DEBUG_ID : out = DEBUG_PREFIX; break; case INFO_ID : out = INFO_PREFIX; break; case TRACE_ID : out = TRACE_PREFIX; break; case WARN_ID : out = WARN_PREFIX; break; case ERROR_ID : out = ERROR_PREFIX; break; default : out = INFO_PREFIX; break; } logData += "\n" + out + message; } public void init( RuntimeServices rs ) { // do nothing with it } public void log(int level, String message, Throwable t) { // ignore the Throwable, we're not testing this method here log(level, message); } public boolean isLevelEnabled(int level) { return true; } } velocity-1.7/src/test/org/apache/velocity/test/StringConcatenationTestCase.java0000755000175000017500000000371711322700447027760 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ /** * This class tests support for string concatenation. */ public class StringConcatenationTestCase extends BaseTestCase { public StringConcatenationTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); context.put("foo", "foo"); context.put("baz", "baz"); } public void testStringRefLeft() { assertEvalEquals("foobar", "#set( $o = $foo + 'bar' )$o"); assertEvalEquals("foo$bar", "#set( $o = $foo + $bar )$o"); assertEvalEquals("foo1", "#set( $o = $foo + 1 )$o"); assertEvalEquals("foobaz", "#set( $o = $foo + $baz )$o"); } public void testStringRefRight() { assertEvalEquals("barfoo", "#set( $o = 'bar' + $foo )$o"); assertEvalEquals("$barfoo", "#set( $o = $bar + $foo )$o"); assertEvalEquals("1foo", "#set( $o = 1 + $foo )$o"); } public void testNoRef() { assertEvalEquals("bar1", "#set( $o = 'bar' + 1 )$o"); } public void testAll() { assertEvalEquals("foobar$bar1baz", "#set( $o = $foo + 'bar' + $bar + 1 + $baz )$o"); } } velocity-1.7/src/test/org/apache/velocity/test/EvaluateContextTestCase.java0000644000175000017500000001106711156301414027105 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.TestCase; import org.apache.velocity.VelocityContext; import org.apache.velocity.context.EvaluateContext; import org.apache.velocity.context.InternalContextAdapterImpl; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.test.misc.TestContext; /** * Tests scope of EvaluateContext. * * @author Will Glass-Husain * @version $Id: EvaluateContextTestCase.java 753027 2009-03-12 21:47:56Z nbubna $ */ public class EvaluateContextTestCase extends TestCase { public void testLocalscopePutDoesntLeakButGetDoes() throws Exception { RuntimeInstance instance; instance = new RuntimeInstance(); instance.setProperty(RuntimeConstants.EVALUATE_CONTEXT_CLASS, VelocityContext.class.getName()); instance.init(); VelocityContext base = new VelocityContext(); base.put("outsideVar", "value1"); EvaluateContext evc = new EvaluateContext(new InternalContextAdapterImpl(base), instance); evc.put("newLocalVar", "value2"); // New variable put doesn't leak assertNull(base.get("newLocalVar")); assertEquals("value2", evc.get("newLocalVar")); // But we can still get to "outsideVar" assertEquals("value1", evc.get("outsideVar")); // If we decide to try and set outsideVar it won't leak evc.put("outsideVar", "value3"); assertEquals("value3", evc.get("outsideVar")); assertEquals("value1", base.get("outsideVar")); assertEquals(2, evc.getKeys().length); } /** * Test that local context can be configured. * @throws Exception */ public void testSetLocalContext() throws Exception { RuntimeInstance instance = new RuntimeInstance(); instance.setProperty(RuntimeConstants.EVALUATE_CONTEXT_CLASS, TestContext.class.getName()); instance.init(); VelocityContext base = new VelocityContext(); base.put("outsideVar", "value1"); EvaluateContext evc = new EvaluateContext(new InternalContextAdapterImpl(base), instance); // original entry assertEquals(1,evc.getKeys().length); // original plus local entry evc.put("test","result"); assertEquals(2,evc.getKeys().length); // local context is case insensitive, so the count remains the same evc.put("TEST","result"); assertEquals(2,evc.getKeys().length); assertEquals("result",evc.get("test")); assertEquals("result",evc.get("TEst")); assertNull(evc.get("OUTSIDEVAR")); } public void testSetLocalContextWithErrors() throws Exception { VelocityContext base = new VelocityContext(); try { // initialize with bad class name RuntimeInstance instance = new RuntimeInstance(); instance.setProperty(RuntimeConstants.EVALUATE_CONTEXT_CLASS, "org.apache"); instance.init(); EvaluateContext evc = new EvaluateContext(new InternalContextAdapterImpl(base), instance); fail ("Expected an exception"); } catch (Exception e) {} try { // initialize with class not implementing Context RuntimeInstance instance = new RuntimeInstance(); instance.setProperty(RuntimeConstants.EVALUATE_CONTEXT_CLASS, org.apache.velocity.test.EvaluateContextTestCase.class.getName()); instance.init(); EvaluateContext evc = new EvaluateContext(new InternalContextAdapterImpl(base), instance); fail ("Expected an exception"); } catch (Exception e) {} } } velocity-1.7/src/test/org/apache/velocity/test/AbsoluteFileResourceLoaderTestCase.java0000644000175000017500000001042211322700447031205 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; 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.test.misc.TestLogChute; /** * Test use of an absolute path with the FileResourceLoader * * @author Will Glass-Husain * @version $Id: AbsoluteFileResourceLoaderTestCase.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class AbsoluteFileResourceLoaderTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path to template file. This will get combined with the * application directory to form an absolute path */ private final static String TEMPLATE_PATH = TEST_COMPARE_DIR + "/absolute/absolute"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/absolute/results"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/absolute/compare"; VelocityEngine engine; /** * Default constructor. */ AbsoluteFileResourceLoaderTestCase() { super("AbsoluteFileResourceLoaderTest"); try { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); // signify we want to use an absolute path engine.addProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, ""); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } catch (Exception e) { fail("Cannot setup AbsoluteFileResourceLoaderTest!"); } } public static Test suite () { return new AbsoluteFileResourceLoaderTestCase(); } /** * Runs the test. */ public void runTest () { try { String curdir = System.getProperty("user.dir"); String f = getFileName(curdir, TEMPLATE_PATH, TMPL_FILE_EXT); System.out.println("Retrieving template at absolute path: " + f); Template template1 = engine.getTemplate(f); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULTS_DIR, "absolute", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template1.merge(context, writer1); writer1.flush(); writer1.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "absolute", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } catch (Exception e) { fail(e.getMessage()); } } } velocity-1.7/src/test/org/apache/velocity/test/EventHandlingTestCase.java0000644000175000017500000003105310513464370026524 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.app.event.NullSetEventHandler; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; import org.apache.velocity.util.ContextAware; import org.apache.velocity.util.RuntimeServicesAware; /** * Tests event handling for all event handlers except IncludeEventHandler. This is tested * separately due to its complexity. * * @author Geir Magnusson Jr. * @version $Id: EventHandlingTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class EventHandlingTestCase extends TestCase implements LogChute { private static String NO_REFERENCE_VALUE = ""; private static String REFERENCE_VALUE = ""; private static String logString = null; /** * Default constructor. */ public EventHandlingTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(EventHandlingTestCase.class); } public void testManualEventHandlers() throws Exception { TestEventCartridge te = new TestEventCartridge(); /** * Test attaching the event cartridge to the context */ VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this); ve.init(); /* * lets make a Context and add the event cartridge */ VelocityContext inner = new VelocityContext(); /* * Now make an event cartridge, register all the * event handlers (at once) and attach it to the * Context */ EventCartridge ec = new EventCartridge(); ec.addEventHandler(te); ec.attachToContext( inner ); /* * now wrap the event cartridge - we want to make sure that * we can do this w/o harm */ doTestReferenceInsertionEventHandler1(ve, inner); doTestReferenceInsertionEventHandler2(ve, inner); doTestNullValueEventHandler(ve, inner); doTestSetNullValueEventHandler(ve, inner); doTestMethodExceptionEventHandler1(ve, inner); doTestMethodExceptionEventHandler2(ve, inner); } /** * Test assigning the event handlers via properties */ public void testConfigurationEventHandlers() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this); ve.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, TestEventCartridge.class.getName()); ve.setProperty(RuntimeConstants.EVENTHANDLER_NULLSET, TestEventCartridge.class.getName()); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, TestEventCartridge.class.getName()); ve.init(); doTestReferenceInsertionEventHandler1(ve, null); doTestReferenceInsertionEventHandler2(ve, null); doTestNullValueEventHandler(ve, null); doTestSetNullValueEventHandler(ve, null); doTestMethodExceptionEventHandler1(ve, null); doTestMethodExceptionEventHandler2(ve, null); } /** * Test all the event handlers using the given engine. * @param ve * @param vcontext */ private void doTestReferenceInsertionEventHandler1(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); context.put("name", "Velocity"); /* * First, the reference insertion handler */ String s = "$name$name$name"; StringWriter w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); if ( !w.toString().equals( REFERENCE_VALUE + REFERENCE_VALUE + REFERENCE_VALUE )) { fail( "Reference insertion test 1"); } } private void doTestReferenceInsertionEventHandler2(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); context.put("name", "Velocity"); /* * using the same handler, we can deal with * null references as well */ String s = "$floobie"; Writer w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); if ( !w.toString().equals( NO_REFERENCE_VALUE )) { fail( "Reference insertion test 2"); } } private void doTestNullValueEventHandler(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); /* * now lets test setting a null value - this test * should result in *no* log output. */ String s = "#set($settest = $NotAReference)"; Writer w = new StringWriter(); clearLogString(); ve.evaluate( context, w, "mystring", s ); if( getLogString() != null) { fail( "NullSetEventHandler test 1"); } } private void doTestSetNullValueEventHandler(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); /* * now lets test setting a null value - this test * should result in log output. */ String s = "#set($logthis = $NotAReference)"; Writer w = new StringWriter(); clearLogString(); ve.evaluate( context, w, "mystring", s ); if( getLogString() == null) { fail( "NullSetEventHandler test 2"); } } private void doTestMethodExceptionEventHandler1(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); /* * finally, we test a method exception event - we do this * by putting this class in the context, and calling * a method that does nothing but throw an exception. * we use flag in the context to turn the event handling * on and off * * Note also how the reference insertion process * happens as well */ context.put("allow_exception",Boolean.TRUE); context.put("this", this ); String s = " $this.throwException()"; Writer w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); } private void doTestMethodExceptionEventHandler2(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); context.put("this", this ); /* * now, we remove the exception flag, and we can see that the * exception will propgate all the way up here, and * wil be caught by the catch() block below */ String s = " $this.throwException()"; Writer w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("No MethodExceptionEvent received!"); } catch( MethodInvocationException mee ) { // Do nothing } } /** * silly method to throw an exception to test * the method invocation exception event handling */ public void throwException() throws Exception { throw new Exception("Hello from throwException()"); } /** * Required by LogChute */ public void init( RuntimeServices rs ) { /* don't need it...*/ } /** * handler for LogChute interface */ public void log(int level, String message) { setLogString(message); } public void log(int level, String message, Throwable t) { setLogString(message); } public boolean isLevelEnabled(int level) { return true; } public static void clearLogString() { logString = null; } public static void setLogString(String message) { logString = message; } public static String getLogString() { return logString; } public static class TestEventCartridge implements ReferenceInsertionEventHandler, NullSetEventHandler, MethodExceptionEventHandler, RuntimeServicesAware,ContextAware { private RuntimeServices rs; public TestEventCartridge() { } /** * Required by EventHandler */ public void setRuntimeServices( RuntimeServices rs ) { // make sure this is only called once if (this.rs == null) this.rs = rs; else fail("initialize called more than once."); } /** * Event handler for when a reference is inserted into the output stream. */ public Object referenceInsert( String reference, Object value ) { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); /* * if we have a value * return a known value */ String s = null; if( value != null ) { s = REFERENCE_VALUE; } else { /* * we only want to deal with $floobie - anything * else we let go */ if ( reference.equals("$floobie") ) { s = NO_REFERENCE_VALUE; } } return s; } /** * Event handler for when the right hand side of * a #set() directive is null, which results in * a log message. This method gives the application * a chance to 'vote' on msg generation */ public boolean shouldLogOnNullSet( String lhs, String rhs ) { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); if (lhs.equals("$settest")) return false; return true; } /** * Handles exceptions thrown during in-template method access */ public Object methodException( Class claz, String method, Exception e ) throws Exception { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); // only do processing if the switch is on if (context != null) { boolean exceptionSwitch = context.containsKey("allow_exception"); if( exceptionSwitch && method.equals("throwException")) { return "handler"; } else throw e; } else throw e; } Context context; public void setContext(Context context) { this.context = context; } } } velocity-1.7/src/test/org/apache/velocity/test/IntrospectionCacheDataTestCase.java0000644000175000017500000000516510513464370030361 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.IOException; import java.io.StringWriter; import junit.framework.TestCase; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.util.introspection.IntrospectionCacheData; /** * Checks that arrays are cached correctly in the Introspector. * * @author alex+news@olmisoft.com * @version $Id: IntrospectionCacheDataTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class IntrospectionCacheDataTestCase extends TestCase { private static class CacheHitCountingVelocityContext extends VelocityContext { public int cacheHit = 0; public IntrospectionCacheData icacheGet(Object key) { final IntrospectionCacheData result = super.icacheGet(key); if (result != null) { ++cacheHit; } return result; } } public void testCache() throws ParseErrorException, MethodInvocationException, ResourceNotFoundException, IOException { CacheHitCountingVelocityContext context = new CacheHitCountingVelocityContext(); context.put("this", this); StringWriter w = new StringWriter(); Velocity.evaluate(context, w, "test", "$this.exec('a')$this.exec('b')"); assertEquals("[a][b]", w.toString()); assertTrue(context.cacheHit > 0); } /** * For use when acting as a context reference. * * @param value * @return */ public String exec(String value) { return "[" + value + "]"; } } velocity-1.7/src/test/org/apache/velocity/test/StrictCompareTestCase.java0000644000175000017500000000471511322700447026557 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; /** * Make sure exceptions are thrown for strict comparisons that * cannot be compared. */ public class StrictCompareTestCase extends BaseTestCase { public StrictCompareTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); context.put("NULL", null); context.put("a", "abc"); context.put("b", new Integer(3)); context.put("TRUE", Boolean.TRUE); } public void testCompare() { assertVelocityEx("#if($a > $NULL)#end"); assertVelocityEx("#if($a < $NULL)#end"); assertVelocityEx("#if($a >= $NULL)#end"); assertVelocityEx("#if($a <= $NULL)#end"); assertVelocityEx("#if($NULL > $a)#end"); assertVelocityEx("#if($NULL < $a)#end"); assertVelocityEx("#if($NULL >= $a)#end"); assertVelocityEx("#if($NULL <= $a)#end"); assertVelocityEx("#if($NULL >= $NULL)#end"); assertVelocityEx("#if($a >= $b)#end"); assertVelocityEx("#if($a <= $b)#end"); assertVelocityEx("#if($a > $b)#end"); assertVelocityEx("#if($a < $b)#end"); assertVelocityEx("#if($a < 5)#end"); assertVelocityEx("#if($a > 5)#end"); } /** * Assert that we get a VelocityException when calling evaluate */ public void assertVelocityEx(String template) { assertEvalException(template, VelocityException.class); } } velocity-1.7/src/test/org/apache/velocity/test/AnakiaTestCase.java0000644000175000017500000000477010513464370025170 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.Test; import junit.framework.TestSuite; /** * This is a test case for Anakia. Right now, it simply will compare * two index.html files together. These are produced as a result of * first running Anakia and then running this test. * * @author Jon S. Stevens * @version $Id: AnakiaTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class AnakiaTestCase extends BaseTestCase { private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/anakia/compare"; private static final String RESULTS_DIR = TEST_RESULT_DIR + "/anakia"; private static final String CONTEXT_FILE_EXT = "context.html"; /** * Creates a new instance. * */ public AnakiaTestCase(String name) { super(name); } public static Test suite() { return new TestSuite(AnakiaTestCase.class); } /** * Runs the test. This is empty on purpose because the * code to do the Anakia output is in the .xml file that runs * this test. */ public void testAnakiaResults () throws Exception { assureResultsDirectoryExists(RESULTS_DIR); /** if (!isMatch(RESULTS_DIR,COMPARE_DIR,"index",FILE_EXT,FILE_EXT)) { fail("Output is incorrect!"); } **/ if (!isMatch( RESULTS_DIR, COMPARE_DIR, "index", CONTEXT_FILE_EXT, CONTEXT_FILE_EXT)) { fail("Custom Context Output is incorrect"); } else { System.out.println ("Passed!"); } } } velocity-1.7/src/test/org/apache/velocity/test/ExternalLoggerTestCase.java0000644000175000017500000000665710513464370026734 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; /** * Tests if we can hand Velocity an arbitrary class for logging. * * @author Geir Magnusson Jr. * @version $Id: ExternalLoggerTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class ExternalLoggerTestCase extends TestCase implements LogChute { private String logString = null; private VelocityEngine ve = null; /** * Default constructor. */ public ExternalLoggerTestCase(String name) { super(name); } public void setUp() throws Exception { /* * use an alternative logger. Set it up here and pass it in. */ ve = new VelocityEngine(); ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this ); ve.init(); } public void init( RuntimeServices rs ) { // do nothing with it } public static Test suite () { return new TestSuite(ExternalLoggerTestCase.class); } /** * Runs the test. */ public void testExternalLogger () { /* * simply log something and see if we get it. */ logString = null; String testString = "This is a test."; ve.getLog().warn(testString); if (logString == null || !logString.equals(WARN_PREFIX + testString ) ) { fail("Didn't recieve log message."); } } public void log(int level, String message) { String out = ""; /* * Start with the appropriate prefix */ switch( level ) { case DEBUG_ID : out = DEBUG_PREFIX; break; case INFO_ID : out = INFO_PREFIX; break; case TRACE_ID : out = TRACE_PREFIX; break; case WARN_ID : out = WARN_PREFIX; break; case ERROR_ID : out = ERROR_PREFIX; break; default : out = INFO_PREFIX; break; } logString = out + message; } public void log(int level, String message, Throwable t) { // ignore the Throwable, we're not testing this method here log(level, message); } public boolean isLevelEnabled(int level) { return true; } } velocity-1.7/src/test/org/apache/velocity/test/EncodingTestCase.java0000644000175000017500000001323511075007114025517 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.test.misc.TestLogChute; /** * Tests input encoding handling. The input target is UTF-8, having * chinese and and a spanish enyay (n-twiddle) * * Thanks to Kent Johnson for the example input file. * * * @author Geir Magnusson Jr. * @version $Id: EncodingTestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class EncodingTestCase extends BaseTestCase implements TemplateTestBase { public EncodingTestCase(String name) { super(name); } public void setUp() throws Exception { Velocity.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); Velocity.setProperty( Velocity.INPUT_ENCODING, "UTF-8" ); Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public static Test suite() { return new TestSuite(EncodingTestCase.class); } /** * Runs the test. */ public void testChineseEncoding () throws Exception { VelocityContext context = new VelocityContext(); assureResultsDirectoryExists(RESULT_DIR); /* * get the template and the output */ /* * Chinese and spanish */ Template template = Velocity.getTemplate( getFileName(null, "encodingtest", TMPL_FILE_EXT), "UTF-8"); FileOutputStream fos = new FileOutputStream ( getFileName(RESULT_DIR, "encodingtest", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8")); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"encodingtest", RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output 1 incorrect."); } } public void testHighByteChinese() throws Exception { VelocityContext context = new VelocityContext(); assureResultsDirectoryExists(RESULT_DIR); /* * a 'high-byte' chinese example from Michael Zhou */ Template template = Velocity.getTemplate( getFileName( null, "encodingtest2", TMPL_FILE_EXT), "UTF-8"); FileOutputStream fos = new FileOutputStream ( getFileName(RESULT_DIR, "encodingtest2", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8")); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"encodingtest2", RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output 2 incorrect."); } } public void testHighByteChinese2() throws Exception { VelocityContext context = new VelocityContext(); assureResultsDirectoryExists(RESULT_DIR); /* * a 'high-byte' chinese from Ilkka */ Template template = Velocity.getTemplate( getFileName( null, "encodingtest3", TMPL_FILE_EXT), "GBK"); FileOutputStream fos = new FileOutputStream ( getFileName(RESULT_DIR, "encodingtest3", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos, "GBK")); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"encodingtest3", RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output 3 incorrect."); } } public void testRussian() throws Exception { VelocityContext context = new VelocityContext(); assureResultsDirectoryExists(RESULT_DIR); /* * Russian example from Vitaly Repetenko */ Template template = Velocity.getTemplate( getFileName( null, "encodingtest_KOI8-R", TMPL_FILE_EXT), "KOI8-R"); FileOutputStream fos = new FileOutputStream ( getFileName(RESULT_DIR, "encodingtest_KOI8-R", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos, "KOI8-R")); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"encodingtest_KOI8-R", RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output 4 incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/TexenTestCase.java0000644000175000017500000000442610513464370025065 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.TestSuite; /** * This is a test case for Texen. Simply executes a simple * generative task and compares the output. * * @author Jason van Zyl * @version $Id: TexenTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class TexenTestCase extends BaseTestCase { /** * Directory where results are generated. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/texen"; /** * Directory where comparison output is stored. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/texen/compare"; /** * Creates a new instance. * */ public TexenTestCase(String name) { super(name); } public static junit.framework.Test suite() { return new TestSuite(TexenTestCase.class); } /** * Runs the test. */ public void testTexenResults () throws Exception { assureResultsDirectoryExists(RESULTS_DIR); if (!isMatch(RESULTS_DIR,COMPARE_DIR,"TurbineWeather","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"TurbineWeatherService","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"WeatherService","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"book","txt","txt") || !isMatch(RESULTS_DIR,COMPARE_DIR,"Test","txt","txt")) { fail("Output is incorrect!"); } } } velocity-1.7/src/test/org/apache/velocity/test/ArithmeticTestCase.java0000644000175000017500000002263510513464370026075 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.math.BigDecimal; import java.math.BigInteger; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.runtime.parser.node.MathUtils; /** * Test arithmetic operations. Introduced after extending from Integer-only * to Number-handling. * * @author Peter Romianowski */ public class ArithmeticTestCase extends TestCase { public ArithmeticTestCase(String testName) { super(testName); } public static Test suite() { return new TestSuite(ArithmeticTestCase.class); } public void testAdd() { addHelper (new Integer(10), new Short( (short)20), 30, Integer.class); addHelper (new Byte((byte)10), new Short( (short)20), 30, Short.class); addHelper (new Float(10), new Short( (short)20), 30, Float.class); addHelper (new Byte((byte)10), new Double( 20), 30, Double.class); addHelper (BigInteger.valueOf(10), new Integer( 20), 30, BigInteger.class); addHelper (new Integer( 20), BigDecimal.valueOf(10), 30, BigDecimal.class); // Test overflow addHelper (new Integer(Integer.MAX_VALUE), new Short( (short)20), (double)Integer.MAX_VALUE+20, Long.class); addHelper (new Integer (20), new Long(Long.MAX_VALUE), (double)Long.MAX_VALUE+20, BigInteger.class); addHelper (new Integer (-20), new Long(Long.MIN_VALUE), (double)Long.MIN_VALUE-20, BigInteger.class); } private void addHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.add( n1, n2); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } public void testSubtract() { subtractHelper (new Integer(100), new Short( (short)20), 80, Integer.class); subtractHelper (new Byte((byte)100), new Short( (short)20), 80, Short.class); subtractHelper (new Float(100), new Short( (short)20), 80, Float.class); subtractHelper (new Byte((byte)100), new Double( 20), 80, Double.class); subtractHelper (BigInteger.valueOf(100), new Integer( 20), 80, BigInteger.class); subtractHelper (new Integer( 100), BigDecimal.valueOf(20), 80, BigDecimal.class); // Test overflow subtractHelper (new Integer(Integer.MIN_VALUE), new Short( (short)20), (double)Integer.MIN_VALUE-20, Long.class); subtractHelper (new Integer (-20), new Long(Long.MAX_VALUE), -20d-(double)Long.MAX_VALUE, BigInteger.class); subtractHelper (new Integer (Integer.MAX_VALUE), new Long(Long.MIN_VALUE), (double)Long.MAX_VALUE+(double)Integer.MAX_VALUE, BigInteger.class); } private void subtractHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.subtract( n1, n2); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } public void testMultiply() { multiplyHelper (new Integer(10), new Short( (short)20), 200, Integer.class); multiplyHelper (new Byte((byte)100), new Short( (short)20), 2000, Short.class); multiplyHelper (new Byte((byte)100), new Short( (short)2000), 200000, Integer.class); multiplyHelper (new Float(100), new Short( (short)20), 2000, Float.class); multiplyHelper (new Byte((byte)100), new Double( 20), 2000, Double.class); multiplyHelper (BigInteger.valueOf(100), new Integer( 20), 2000, BigInteger.class); multiplyHelper (new Integer( 100), BigDecimal.valueOf(20), 2000, BigDecimal.class); // Test overflow multiplyHelper (new Integer(Integer.MAX_VALUE), new Short( (short)10), (double)Integer.MAX_VALUE*10d, Long.class); multiplyHelper (new Integer(Integer.MAX_VALUE), new Short( (short)-10), (double)Integer.MAX_VALUE*-10d, Long.class); multiplyHelper (new Integer (20), new Long(Long.MAX_VALUE), 20d*(double)Long.MAX_VALUE, BigInteger.class); } private void multiplyHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.multiply( n1, n2); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } public void testDivide() { divideHelper (new Integer(10), new Short( (short)2), 5, Integer.class); divideHelper (new Byte((byte)10), new Short( (short)2), 5, Short.class); divideHelper (BigInteger.valueOf(10), new Short( (short)2), 5, BigInteger.class); divideHelper (new Integer(10), new Short( (short)4), 2, Integer.class); divideHelper (new Integer(10), new Float( 2.5f), 4, Float.class); divideHelper (new Integer(10), new Double( 2.5), 4, Double.class); divideHelper (new Integer(10), new BigDecimal( 2.5), 4, BigDecimal.class); } private void divideHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.divide( n1, n2); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } public void testModulo() { moduloHelper (new Integer(10), new Short( (short)2), 0, Integer.class); moduloHelper (new Byte((byte)10), new Short( (short)3), 1, Short.class); moduloHelper (BigInteger.valueOf(10), new Short( (short)4), 2, BigInteger.class); moduloHelper (new Integer(10), new Float( 5.5f), 4.5, Float.class); try { moduloHelper (new Integer(10), new BigDecimal( 2.5), 4, BigDecimal.class); fail ("Modulo with BigDecimal is not allowed! Should have thrown an ArithmeticException."); } catch( ArithmeticException e) { // do nothing } } private void moduloHelper (Number n1, Number n2, double expectedResult, Class expectedResultType) { Number result = MathUtils.modulo( n1, n2); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result.doubleValue(), 0.01); assertEquals ("ResultType does not match.", expectedResultType, result.getClass()); } public void testCompare() { compareHelper (new Integer(10), new Short( (short)10), 0); compareHelper (new Integer(10), new Short( (short)11), -1); compareHelper (BigInteger.valueOf(10), new Short( (short)11), -1); compareHelper (new Byte((byte)10), new Short( (short)3), 1); compareHelper (new Float(10), new Short( (short)11), -1); compareHelper (new Double(10), new Short( (short)11), -1); } private void compareHelper (Number n1, Number n2, int expectedResult) { int result = MathUtils.compare( n1, n2 ); assertEquals ("The arithmetic operation produced an unexpected result.", expectedResult, result); } /* * * COMMENT OUT FOR PERFORMANCE-MEASSUREMENTS * * public void testProfile() * { * * long start = System.currentTimeMillis(); * * Number v1 = new Long (1000); * Number v2 = new Double (10.23); * Number result = null; * for (int a = 0; a < 10000; a++) * { * * result = MathUtils.typeConvert ( * new BigDecimal (v1.doubleValue()).add ( * new BigDecimal (v2.doubleValue())), v1, v2, false); * * } * * System.out.println ("took: "+(System.currentTimeMillis()-start)); * * start = System.currentTimeMillis(); * for (int a = 0; a < 10000; a++) * { * * result = MathUtils.divide( v1, v2); * } * * Number result2 = result; * System.out.println ("took: "+(System.currentTimeMillis()-start)); * } * */ /** * Test additional functions */ public void testIsZero() { assertTrue (MathUtils.isZero (new Integer (0))); assertTrue (!MathUtils.isZero (new Integer (1))); assertTrue (!MathUtils.isZero (new Integer (-1))); assertTrue (MathUtils.isZero (new Float (0f))); assertTrue (!MathUtils.isZero (new Float (0.00001f))); assertTrue (!MathUtils.isZero (new Float (-0.00001f))); } } velocity-1.7/src/test/org/apache/velocity/test/ParseExceptionTestCase.java0000644000175000017500000002111311135356612026723 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ParseErrorException; /** * Test parser exception is generated with appropriate info. * * @author Will Glass-Husain * @version $Id: ParseExceptionTestCase.java 736027 2009-01-20 14:19:54Z byron $ */ public class ParseExceptionTestCase extends BaseTestCase { /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = "test/parseexception"; /** * Default constructor. * @param name name of test */ public ParseExceptionTestCase(String name) { super(name); } public void setUp() throws Exception { } public static Test suite () { return new TestSuite(ParseExceptionTestCase.class); } /** * Tests that parseException has useful info when called by template.marge() * @throws Exception */ public void testParseExceptionFromTemplate () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty("file.resource.loader.cache", "true"); ve.setProperty("file.resource.loader.path", FILE_RESOURCE_LOADER_PATH); ve.init(); Writer writer = new StringWriter(); VelocityContext context = new VelocityContext(); try { Template template = ve.getTemplate("badtemplate.vm"); template.merge(context, writer); fail("Should have thown a ParseErrorException"); } catch (ParseErrorException e) { assertEquals("badtemplate.vm",e.getTemplateName()); assertEquals(5,e.getLineNumber()); assertEquals(9,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info when thrown in VelocityEngine.evaluate() * @throws Exception */ public void testParseExceptionFromEval () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); try { ve.evaluate(context,writer,"test"," #set($abc) "); fail("Should have thown a ParseErrorException"); } catch (ParseErrorException e) { assertEquals("test",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(13,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info when thrown in VelocityEngine.evaluate() * and the problem comes from a macro definition * @throws Exception */ public void testParseExceptionFromMacroDef () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); try { ve.evaluate(context,writer,"testMacro","#macro($blarg) foo #end"); fail("Should have thown a ParseErrorException"); } catch (ParseErrorException e) { assertEquals("testMacro",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(7,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info when thrown in VelocityEngine.evaluate() * and the problem comes from a macro definition * @throws Exception */ public void testParseExceptionFromMacroDefBody () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); try { ve.evaluate(context,writer,"testMacro","#macro(aa $blarg) #set(!! = bb) #end #aa('aa')"); fail("Should have thown a ParseErrorException"); } catch (ParseErrorException e) { assertEquals("testMacro",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(24,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info when thrown in VelocityEngine.evaluate() * and the problem comes from a macro invocation * @throws Exception */ public void testParseExceptionFromMacroInvoke () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); try { ve.evaluate(context,writer,"testMacroInvoke", "#macro( foo $a) $a #end #foo(woogie)"); fail("Should have thown a ParseErrorException"); } catch (org.apache.velocity.exception.TemplateInitException e) { assertEquals("testMacroInvoke",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(27,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info with macro calls with * invalid number of arguments * @throws Exception */ public void testParseExceptionMacroInvalidArgumentCount () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty("velocimacro.arguments.strict","true"); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); try { ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')"); fail("Should have thown a ParseErrorException"); } catch (ParseErrorException e) { assertEquals("testMacroInvoke",e.getTemplateName()); assertEquals(1,e.getLineNumber()); assertEquals(24,e.getColumnNumber()); } finally { if (writer != null) { writer.close(); } } } /** * Tests that parseException has useful info with macro calls with * invalid number of arguments * @throws Exception */ public void testParseExceptionMacroInvalidArgumentCountNoException () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); VelocityContext context = new VelocityContext(); Writer writer = new StringWriter(); // will not throw an exception try { ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')"); } finally { if (writer != null) { writer.close(); } } } } velocity-1.7/src/test/org/apache/velocity/test/StrictEscapeTestCase.java0000644000175000017500000001107311322700447026364 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.runtime.RuntimeConstants; /** * Test Strict escape mode * property: RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE set to true */ public class StrictEscapeTestCase extends BaseTestCase { public StrictEscapeTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, Boolean.TRUE); context.put("pow", "bang"); context.put("NULL", null); context.put("animal", new Animal()); // DEBUG = true; } public void testReferenceEscape() { engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); assertEvalException("\\\\$bogus"); assertEvalException("\\\\\\\\$bogus"); assertEvalEquals("$bogus", "\\$bogus"); assertEvalEquals("$bogus.xyz", "\\$bogus.xyz"); assertEvalEquals("${bogus}", "\\${bogus}"); assertEvalEquals("${bogus.xyz}", "\\${bogus.xyz}"); assertEvalEquals("\\$bogus", "\\\\\\$bogus"); assertEvalEquals("\\xyz","#set($foo = \"xyz\")\\\\$foo"); assertEvalEquals("\\$foo","#set($foo = \"xyz\")\\\\\\$foo"); assertEvalEquals("$foo\\","#set($foo = \"xyz\")\\$foo\\"); assertEvalEquals("$pow", "#set($foo = \"\\$pow\")$foo"); assertEvalEquals("\\bang", "#set($foo = \"\\\\$pow\")$foo"); assertEvalEquals("\\$pow", "#set($foo = \"\\\\\\$pow\")$foo"); assertEvalEquals("\\$%", "\\$%"); // This should work but does not... may be related to VELOCITY-679 // This is broken from existing escape behavior // assertEvalEquals("\\$bang", "\\$$pow"); assertEvalEquals("$!foo", "#set($foo = $NULL)\\$!foo"); assertEvalEquals("$!animal.null", "\\$!animal.null"); assertEvalEquals("$!animal", "\\$!animal"); } public void testMacroEscape() { engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); assertEvalException("\\\\#bogus()"); // define the foo macro assertEvalEquals("", "#macro(foo)bar#end"); assertEvalEquals("#foo()", "\\#foo()"); assertEvalEquals("\\bar", "\\\\#foo()"); assertEvalEquals("\\#foo()", "\\\\\\#foo()"); assertEvalEquals("bar", "#set($abc = \"#foo()\")$abc"); assertEvalEquals("#foo()", "#set($abc = \"\\#foo()\")$abc"); assertEvalEquals("\\bar", "#set($abc = \"\\\\#foo()\")$abc"); assertEvalEquals("#@foo()", "\\#@foo()"); assertEvalEquals("\\bar", "\\\\#@foo()#end"); assertEvalEquals("#@foo()#end", "\\#@foo()\\#end"); assertEvalEquals("#end #foreach #define() #elseif", "\\#end \\#foreach \\#define() \\#elseif"); assertEvalEquals("#{end} #{foreach} #{define}() #{elseif}", "\\#{end} \\#{foreach} \\#{define}() \\#{elseif}"); assertEvalEquals("#macro(foo) #end", "\\#macro(foo) \\#end"); assertEvalException("\\\\#end"); assertEvalException("\\\\#if()"); // This should work but does not, probably related to VELOCITY-678 // this is broken from existing behavior //assertEvalEquals("\\$bar", "\\$#foo()"); } /** * Tests for non strict-mode */ public void testStrictMode() { assertEvalEquals("#bogus()", "\\#bogus()"); assertEvalEquals("\\#bogus", "\\\\#bogus"); assertEvalEquals("\\$bogus", "\\\\$bogus"); assertEvalEquals("\\\\$bogus", "\\\\\\\\$bogus"); assertEvalEquals("\\$bogus", "#set($foo = \"\\\\$bogus\")$foo"); } /** * Test object for escaping */ public static class Animal { public Object getNull() { return null; } public String toString() { return null; } } } velocity-1.7/src/test/org/apache/velocity/test/IncludeEventHandlingTestCase.java0000644000175000017500000002114211322700447030023 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.util.RuntimeServicesAware; /** * Tests event handling * * @author Geir Magnusson Jr. * @version $Id: IncludeEventHandlingTestCase.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class IncludeEventHandlingTestCase extends BaseTestCase implements IncludeEventHandler,RuntimeServicesAware { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/includeevent/compare"; private static final int PASS_THROUGH=0; private static final int RELATIVE_PATH=1; private static final int BLOCK=2; private int EventHandlerBehavior = PASS_THROUGH; VelocityEngine engine; /** * Default constructor. */ public IncludeEventHandlingTestCase(String name) { super(name); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); engine.addProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public static Test suite () { return new TestSuite(IncludeEventHandlingTestCase.class); } /** * Runs the test. */ public void testIncludeEventHandlingPassThrough () throws Exception { Template template1 = engine.getTemplate( getFileName(null, "test1", TMPL_FILE_EXT)); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULTS_DIR, "test1", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); // set up handler Context context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(this); ec.attachToContext( context ); // BEHAVIOR A: pass through #input and #parse with no change EventHandlerBehavior = PASS_THROUGH; template1.merge(context, writer1); writer1.flush(); writer1.close(); assertTrue("Output incorrect.", isMatch(RESULTS_DIR, COMPARE_DIR, "test1", RESULT_FILE_EXT, CMP_FILE_EXT)); } /** * Runs the test. */ public void testIncludeEventHandlingRelative() throws Exception { Template template2 = engine.getTemplate( getFileName(null, "subdir/test2", TMPL_FILE_EXT)); FileOutputStream fos2 = new FileOutputStream ( getFileName(RESULTS_DIR, "test2", RESULT_FILE_EXT)); Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); // set up handler Context context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(this); ec.attachToContext( context ); // BEHAVIOR B: pass through #input and #parse with using a relative path EventHandlerBehavior = RELATIVE_PATH; template2.merge(context, writer2); writer2.flush(); writer2.close(); assertTrue("Output incorrect.", isMatch(RESULTS_DIR, COMPARE_DIR, "test2", RESULT_FILE_EXT, CMP_FILE_EXT)); } /** * Runs the test. */ public void testIncludeEventHandlingBlock() throws Exception { Template template3 = engine.getTemplate( getFileName(null, "test3", TMPL_FILE_EXT)); FileOutputStream fos3 = new FileOutputStream ( getFileName(RESULTS_DIR, "test3", RESULT_FILE_EXT)); Writer writer3 = new BufferedWriter(new OutputStreamWriter(fos3)); // set up handler Context context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(this); ec.attachToContext( context ); // BEHAVIOR C: refuse to pass through #input and #parse EventHandlerBehavior = BLOCK; template3.merge(context, writer3); writer3.flush(); writer3.close(); assertTrue("Output incorrect.", isMatch(RESULTS_DIR, COMPARE_DIR, "test3", RESULT_FILE_EXT, CMP_FILE_EXT)); } /** * Check bug VELOCITY-717. */ public void testIncludeEventHandlingBlockMacros() throws Exception { Template template = engine.getTemplate( getFileName(null, "test7", TMPL_FILE_EXT)); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, "test7", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); // set up handler Context context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(this); ec.attachToContext( context ); EventHandlerBehavior = BLOCK; template.merge(context, writer); writer.flush(); writer.close(); assertTrue("Output incorrect.", isMatch(RESULTS_DIR, COMPARE_DIR, "test7", RESULT_FILE_EXT, CMP_FILE_EXT)); } public void setRuntimeServices( RuntimeServices rs ) { } /** * Sample handler with different behaviors for the different tests. */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName) { if (EventHandlerBehavior == PASS_THROUGH) return includeResourcePath; // treat as relative path else if (EventHandlerBehavior == RELATIVE_PATH) { // if the resource name starts with a slash, it's not a relative path if (includeResourcePath.startsWith("/") || includeResourcePath.startsWith("\\") ) { return includeResourcePath; } int lastslashpos = Math.max( currentResourcePath.lastIndexOf("/"), currentResourcePath.lastIndexOf("\\") ); // root of resource tree if ( (lastslashpos == -1)) return includeResourcePath; // prepend path to the input path else return currentResourcePath.substring(0,lastslashpos) + "/" + includeResourcePath; } else if (EventHandlerBehavior == BLOCK) return null; // should never happen else return null; } } velocity-1.7/src/test/org/apache/velocity/test/TemplateTestSuite.java0000644000175000017500000000641211075007114025761 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.FileInputStream; import java.util.Properties; import junit.framework.TestSuite; import org.apache.velocity.app.Velocity; import org.apache.velocity.test.misc.TestLogChute; /** * Test suite for Templates. * * @author Daniel Rall * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Jon S. Stevens * @version $Id: TemplateTestSuite.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class TemplateTestSuite extends TestSuite implements TemplateTestBase { private Properties testProperties; /** * Creates an instace of the Apache Velocity test suite. */ public TemplateTestSuite() { try { Velocity.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); testProperties = new Properties(); testProperties.load(new FileInputStream(TEST_CASE_PROPERTIES)); } catch (Exception e) { System.err.println("Cannot setup TemplateTestSuite!"); e.printStackTrace(); System.exit(1); } addTemplateTestCases(); } /** * Adds the template test cases to run to this test suite. Template test * cases are listed in the TEST_CASE_PROPERTIES file. */ private void addTemplateTestCases() { String template; for (int i = 1 ;; i++) { template = testProperties.getProperty(getTemplateTestKey(i)); if (template != null) { System.out.println("Adding TemplateTestCase : " + template); addTest(new TemplateTestCase(template)); } else { // Assume we're done adding template test cases. break; } } } /** * Macro which returns the properties file key for the specified template * test number. * * @param nbr The template test number to return a property key for. * @return The property key. */ private static final String getTemplateTestKey(int nbr) { return ("test.template." + nbr); } } velocity-1.7/src/test/org/apache/velocity/test/ClasspathResourceTestCase.java0000644000175000017500000001240211075007114027416 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.test.misc.TestLogChute; /** * Load templates from the Classpath. * * @author Jason van Zyl * @author Dave Bryson * @version $Id: ClasspathResourceTestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class ClasspathResourceTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/cpload"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/cpload/compare"; /** * Default constructor. */ public ClasspathResourceTestCase(String name) { super(name); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); Velocity.setProperty(Velocity.RESOURCE_LOADER, "classpath"); /* * I don't think I should have to do this, these should * be in the default config file. */ Velocity.addProperty( "classpath." + Velocity.RESOURCE_LOADER + ".class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.setProperty( "classpath." + Velocity.RESOURCE_LOADER + ".cache", "false"); Velocity.setProperty( "classpath." + Velocity.RESOURCE_LOADER + ".modificationCheckInterval", "2"); Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public static Test suite () { return new TestSuite(ClasspathResourceTestCase.class); } /** * Runs the test. */ public void testClasspathResource () throws Exception { /* * lets ensure the results directory exists */ assureResultsDirectoryExists(RESULTS_DIR); Template template1 = RuntimeSingleton.getTemplate("template/test1." + TMPL_FILE_EXT); // Uncomment when http://jira.codehaus.org/browse/MPTEST-57 has been resolved // Template template2 = RuntimeSingleton.getTemplate( // getFileName(null, "template/test2", TMPL_FILE_EXT)); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULTS_DIR, "test1", RESULT_FILE_EXT)); // Uncomment when http://jira.codehaus.org/browse/MPTEST-57 has been resolved // FileOutputStream fos2 = // new FileOutputStream ( // getFileName(RESULTS_DIR, "test2", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); // Uncomment when http://jira.codehaus.org/browse/MPTEST-57 has been resolved // Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template1.merge(context, writer1); writer1.flush(); writer1.close(); // Uncomment when http://jira.codehaus.org/browse/MPTEST-57 has been resolved // template2.merge(context, writer2); // writer2.flush(); // writer2.close(); if (!isMatch(RESULTS_DIR,COMPARE_DIR,"test1",RESULT_FILE_EXT,CMP_FILE_EXT) // Uncomment when http://jira.codehaus.org/browse/MPTEST-57 has been resolved // || !isMatch(RESULTS_DIR,COMPARE_DIR,"test2",RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output is incorrect!"); } } } velocity-1.7/src/test/org/apache/velocity/test/SetTestCase.java0000644000175000017500000001067210723271545024540 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; /** * Test that an instance of a ResourceLoader can be successfully passed in. * * @author Will Glass-Husain * @version $Id: SetTestCase.java 599003 2007-11-28 13:55:49Z cbrisson $ */ public class SetTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/set"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/set"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/set/compare"; /** * Default constructor. */ public SetTestCase(String name) { super(name); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); } public static Test suite () { return new TestSuite(SetTestCase.class); } /** * Runs the test. */ public void testSetNull() throws Exception { /** * Check that #set does not accept nulls */ VelocityEngine ve = new VelocityEngine(); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); checkTemplate(ve,"set1"); /** * Check that setting the property is the same as the default */ ve = new VelocityEngine(); ve.addProperty(RuntimeConstants.SET_NULL_ALLOWED, "false"); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); checkTemplate(ve,"set1"); /** * Check that #set can accept nulls, and has the correct behaviour for complex LHS */ ve = new VelocityEngine(); ve.addProperty(RuntimeConstants.SET_NULL_ALLOWED, "true"); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); checkTemplate(ve,"set2"); } public void checkTemplate(VelocityEngine ve, String templateName) throws Exception { Template template; FileOutputStream fos; Writer fwriter; Context context; template = ve.getTemplate( getFileName(null, templateName, TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, templateName, RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, templateName, RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/IntrospectorTestCase.java0000644000175000017500000001625610513464370026501 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.lang.reflect.Method; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeSingleton; /** * Test case for the Velocity Introspector which uses * the Java Reflection API to determine the correct * signature of the methods used in VTL templates. * * This should be split into separate tests for each * of the methods searched for but this is a start * for now. * * @author Jason van Zyl * @version $Id: IntrospectorTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class IntrospectorTestCase extends BaseTestCase { private static MethodProvider mp; public void setUp() { mp = new MethodProvider(); } /** * Creates a new instance. */ public IntrospectorTestCase (String name) { super(name); } /** * Get the containing TestSuite. This is always * VelocityTestSuite. * * @return The TestSuite to run. */ public static Test suite () { return new TestSuite(IntrospectorTestCase.class); } public void testIntrospectorBoolean() throws Exception { // Test boolean primitive. Object[] booleanParams = { new Boolean(true) }; String type = "boolean"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", booleanParams); String result = (String) method.invoke(mp, booleanParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorByte() throws Exception { // Test byte primitive. Object[] byteParams = { new Byte("1") }; String type = "byte"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", byteParams); String result = (String) method.invoke(mp, byteParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorChar() throws Exception { // Test char primitive. Object[] characterParams = { new Character('a') }; String type = "character"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", characterParams); String result = (String) method.invoke(mp, characterParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorDouble() throws Exception { // Test double primitive. Object[] doubleParams = { new Double((double)1) }; String type = "double"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", doubleParams); String result = (String) method.invoke(mp, doubleParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorFloat() throws Exception { // Test float primitive. Object[] floatParams = { new Float((float)1) }; String type = "float"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", floatParams); String result = (String) method.invoke(mp, floatParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorInteger() throws Exception { // Test integer primitive. Object[] integerParams = { new Integer((int)1) }; String type = "integer"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", integerParams); String result = (String) method.invoke(mp, integerParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorPrimitiveLong() throws Exception { // Test long primitive. Object[] longParams = { new Long((long)1) }; String type = "long"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", longParams); String result = (String) method.invoke(mp, longParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorPrimitiveShort() throws Exception { // Test short primitive. Object[] shortParams = { new Short((short)1) }; String type = "short"; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, type + "Method", shortParams); String result = (String) method.invoke(mp, shortParams); assertEquals("Method could not be found", type, result); } public void testIntrospectorUntouchable() throws Exception { // Test untouchable Object[] params = {}; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "untouchable", params); assertNull("able to access a private-access method.", method); } public void testIntrospectorReallyUntouchable() throws Exception { // Test really untouchable Object[] params = {}; Method method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "reallyuntouchable", params); assertNull("able to access a private-access method.", method); } public static class MethodProvider { /* * Methods with native parameter types. */ public String booleanMethod (boolean p) { return "boolean"; } public String byteMethod (byte p) { return "byte"; } public String characterMethod (char p) { return "character"; } public String doubleMethod (double p) { return "double"; } public String floatMethod (float p) { return "float"; } public String integerMethod (int p) { return "integer"; } public String longMethod (long p) { return "long"; } public String shortMethod (short p) { return "short"; } String untouchable() { return "yech";} // don't remove! Used through introspection for testing! private String reallyuntouchable() { return "yech!"; } } } velocity-1.7/src/test/org/apache/velocity/test/MiscTestCase.java0000644000175000017500000000604410525400214024661 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.ArrayList; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.util.StringUtils; /** * Test case for any miscellaneous stuff. If it isn't big, and doesn't fit * anywhere else, it goes here * * @author Geir Magnusson Jr. * @version $Id: MiscTestCase.java 473760 2006-11-11 16:55:40Z wglass $ */ public class MiscTestCase extends BaseTestCase { public MiscTestCase (String name) { super(name); } public static Test suite () { return new TestSuite(MiscTestCase.class); } public void testRuntimeInstanceProperties() { // check that runtime instance properties can be set and retrieved RuntimeInstance ri = new RuntimeInstance(); ri.setProperty("baabaa.test","the answer"); assertEquals("the answer",ri.getProperty("baabaa.test")); } public void testStringUtils() { /* * some StringUtils tests */ String eol = "XY"; String arg = "XY"; String res = StringUtils.chop(arg, 1, eol ); assertTrue( "Test 1", res.equals("") ); arg = "X"; res = StringUtils.chop( arg, 1, eol ); assertTrue( "Test 2", res.equals("") ); arg = "ZXY"; res = StringUtils.chop( arg, 1, eol ); assertTrue( "Test 3", res.equals("Z") ); arg = "Hello!"; res = StringUtils.chop( arg, 2, eol ); assertTrue( "Test 4", res.equals("Hell")); arg = null; res = StringUtils.nullTrim(arg); assertNull(arg); arg = " test "; res = StringUtils.nullTrim(arg); assertEquals("test",res); arg = "test"; res = StringUtils.nullTrim(arg); assertEquals("test",res); List list = null; assertNull(StringUtils.trimStrings(list)); list = new ArrayList(); assertEquals(new ArrayList(),StringUtils.trimStrings(list)); list.add("test"); list.add(" abc"); StringUtils.trimStrings(list); assertEquals("test",list.get(0)); assertEquals("abc",list.get(1)); } } velocity-1.7/src/test/org/apache/velocity/test/UberspectorTestCase.java0000644000175000017500000002215110513464370026272 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.HashMap; import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.test.misc.GetPutObject; import org.apache.velocity.test.misc.UberspectorTestObject; import org.apache.velocity.util.introspection.Uberspect; import org.apache.velocity.util.introspection.VelPropertyGet; import org.apache.velocity.util.introspection.VelPropertySet; public class UberspectorTestCase extends BaseTestCase { private RuntimeInstance ri; public UberspectorTestCase(String name) { super(name); } public static Test suite() { return new TestSuite(UberspectorTestCase.class); } public void setUp() throws Exception { ri = new RuntimeInstance(); ri.init(); } public void testNullObjects() throws Exception { // How about some null objects... Gee, I'm mean. ;-) Uberspect u = ri.getUberspect(); VelPropertyGet getter = u.getPropertyGet(null, "foo", null); assertNull(getter); VelPropertySet setter = u.getPropertySet(null, "foo", Object.class, null); assertNull(setter); } public void testEmptyPropertyGetter() throws Exception { Uberspect u = ri.getUberspect(); Map map = new HashMap(); VelPropertyGet getter = u.getPropertyGet(map, "", null); // Don't screw up on empty properties. That should map to get("") assertNotNull(getter); assertEquals("Found wrong method", "get", getter. getMethodName()); } public void testEmptyPropertySetter() throws Exception { Uberspect u = ri.getUberspect(); Map map = new HashMap(); VelPropertySet setter = u.getPropertySet(map, "", Object.class, null); // Don't screw up on empty properties. That should map to put("", Object) assertNotNull(setter); assertEquals("Found wrong method", "put", setter.getMethodName()); } public void testNullPropertyGetter() throws Exception { Uberspect u = ri.getUberspect(); GetPutObject gpo = new GetPutObject(); Map map = new HashMap(); VelPropertyGet getter = u.getPropertyGet(gpo, null, null); // Don't screw up on null properties. That should map to get() on the GPO. assertNotNull(getter); assertEquals("Found wrong method", "get", getter.getMethodName()); // And should be null on a Map which does not have a get() getter = u.getPropertyGet(map, null, null); assertNull(getter); } public void testNullPropertySetter() throws Exception { Uberspect u = ri.getUberspect(); GetPutObject gpo = new GetPutObject(); Map map = new HashMap(); // Don't screw up on null properties. That should map to put() on the GPO. VelPropertySet setter = u.getPropertySet(gpo, null, "", null); assertNotNull(setter); assertEquals("Found wrong method", "put", setter.getMethodName()); // And should be null on a Map which does not have a put() setter = u.getPropertySet(map, null, "", null); assertNull(setter); } public void testNullParameterType() throws Exception { VelPropertySet setter; Uberspect u = ri.getUberspect(); UberspectorTestObject uto = new UberspectorTestObject(); // setRegular() setter = u.getPropertySet(uto, "Regular", null, null); assertNotNull(setter); assertEquals("Found wrong method", "setRegular", setter.getMethodName()); // setAmbigous() - String and StringBuffer available setter = u.getPropertySet(uto, "Ambigous", null, null); assertNull(setter); // setAmbigous() - same with Object? setter = u.getPropertySet(uto, "Ambigous", new Object(), null); assertNull(setter); } public void testMultipleParameterTypes() throws Exception { VelPropertySet setter; Uberspect u = ri.getUberspect(); UberspectorTestObject uto = new UberspectorTestObject(); // setAmbigous() - String setter = u.getPropertySet(uto, "Ambigous", "", null); assertNotNull(setter); assertEquals("Found wrong method", "setAmbigous", setter.getMethodName()); // setAmbigous() - StringBuffer setter = u.getPropertySet(uto, "Ambigous", new StringBuffer(), null); assertNotNull(setter); assertEquals("Found wrong method", "setAmbigous", setter.getMethodName()); } public void testRegularGetters() throws Exception { VelPropertyGet getter; Uberspect u = ri.getUberspect(); UberspectorTestObject uto = new UberspectorTestObject(); // getRegular() getter = u.getPropertyGet(uto, "Regular", null); assertNotNull(getter); assertEquals("Found wrong method", "getRegular", getter.getMethodName()); // Lowercase regular getter = u.getPropertyGet(uto, "regular", null); assertNotNull(getter); assertEquals("Found wrong method", "getRegular", getter.getMethodName()); // lowercase: getpremium() getter = u.getPropertyGet(uto, "premium", null); assertNotNull(getter); assertEquals("Found wrong method", "getpremium", getter.getMethodName()); // test uppercase: getpremium() getter = u.getPropertyGet(uto, "Premium", null); assertNotNull(getter); assertEquals("Found wrong method", "getpremium", getter.getMethodName()); } public void testBooleanGetters() throws Exception { VelPropertyGet getter; Uberspect u = ri.getUberspect(); UberspectorTestObject uto = new UberspectorTestObject(); // getRegular() getter = u.getPropertyGet(uto, "RegularBool", null); assertNotNull(getter); assertEquals("Found wrong method", "isRegularBool", getter.getMethodName()); // Lowercase regular getter = u.getPropertyGet(uto, "regularBool", null); assertNotNull(getter); assertEquals("Found wrong method", "isRegularBool", getter.getMethodName()); // lowercase: getpremiumBool() getter = u.getPropertyGet(uto, "premiumBool", null); assertNotNull(getter); assertEquals("Found wrong method", "ispremiumBool", getter.getMethodName()); // test uppercase: () getter = u.getPropertyGet(uto, "PremiumBool", null); assertNotNull(getter); assertEquals("Found wrong method", "ispremiumBool", getter.getMethodName()); } public void testRegularSetters() throws Exception { VelPropertySet setter; Uberspect u = ri.getUberspect(); UberspectorTestObject uto = new UberspectorTestObject(); // setRegular() setter = u.getPropertySet(uto, "Regular", "", null); assertNotNull(setter); assertEquals("Found wrong method", "setRegular", setter.getMethodName()); // Lowercase regular setter = u.getPropertySet(uto, "regular", "", null); assertNotNull(setter); assertEquals("Found wrong method", "setRegular", setter.getMethodName()); // lowercase: setpremium() setter = u.getPropertySet(uto, "premium", "", null); assertNotNull(setter); assertEquals("Found wrong method", "setpremium", setter.getMethodName()); // test uppercase: getpremium() setter = u.getPropertySet(uto, "Premium", "", null); assertNotNull(setter); assertEquals("Found wrong method", "setpremium", setter.getMethodName()); } /* * * public void testMapGetSet() * throws Exception * { * Uberspect u = ri.getUberspect(); * Map map = new HashMap(); * * VelPropertyGet getter = u.getPropertyGet(map, "", null); * VelPropertySet setter = u.getPropertySet(map, "", Object.class, null); * * assertNotNull("Got a null getter", getter); * assertNotNull("Got a null setter", setter); * * assertEquals("Got wrong getter", "foo", getter.getMethodName()); * assertEquals("Got wrong setter", "bar", setter.getMethodName()); * } */ } velocity-1.7/src/test/org/apache/velocity/test/CommonsExtPropTestCase.java0000644000175000017500000001331010513464370026727 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.FileWriter; import java.util.Iterator; import java.util.Vector; import junit.framework.TestSuite; import org.apache.commons.collections.ExtendedProperties; /** * Tests for the Commons ExtendedProperties class. This is an identical * copy of the ConfigurationTestCase, which will disappear when * the Configuration class does * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: CommonsExtPropTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class CommonsExtPropTestCase extends BaseTestCase { /** * Comparison directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/configuration/compare"; /** * Results directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/configuration"; /** * Test configuration */ private static final String TEST_CONFIG = TEST_COMPARE_DIR + "/configuration/test-config.properties"; /** * Creates a new instance. * */ public CommonsExtPropTestCase(String name) { super(name); } public static junit.framework.Test suite() { return new TestSuite(CommonsExtPropTestCase.class); } /** * Runs the test. */ public void testExtendedProperties () throws Exception { assureResultsDirectoryExists(RESULTS_DIR); ExtendedProperties c = new ExtendedProperties(TEST_CONFIG); FileWriter result = new FileWriter( getFileName(RESULTS_DIR, "output", "res")); message(result, "Testing order of keys ..."); showIterator(result, c.getKeys()); message(result, "Testing retrieval of CSV values ..."); showVector(result, c.getVector("resource.loader")); message(result, "Testing subset(prefix).getKeys() ..."); ExtendedProperties subset = c.subset("file.resource.loader"); showIterator(result, subset.getKeys()); message(result, "Testing getVector(prefix) ..."); showVector(result, subset.getVector("path")); message(result, "Testing getString(key) ..."); result.write(c.getString("config.string.value")); result.write("\n\n"); message(result, "Testing getBoolean(key) ..."); result.write(new Boolean(c.getBoolean("config.boolean.value")).toString()); result.write("\n\n"); message(result, "Testing getByte(key) ..."); result.write(new Byte(c.getByte("config.byte.value")).toString()); result.write("\n\n"); message(result, "Testing getShort(key) ..."); result.write(new Short(c.getShort("config.short.value")).toString()); result.write("\n\n"); message(result, "Testing getInt(key) ..."); result.write(new Integer(c.getInt("config.int.value")).toString()); result.write("\n\n"); message(result, "Testing getLong(key) ..."); result.write(new Long(c.getLong("config.long.value")).toString()); result.write("\n\n"); message(result, "Testing getFloat(key) ..."); result.write(new Float(c.getFloat("config.float.value")).toString()); result.write("\n\n"); message(result, "Testing getDouble(key) ..."); result.write(new Double(c.getDouble("config.double.value")).toString()); result.write("\n\n"); message(result, "Testing escaped-comma scalar..."); result.write( c.getString("escape.comma1")); result.write("\n\n"); message(result, "Testing escaped-comma vector..."); showVector(result, c.getVector("escape.comma2")); result.write("\n\n"); result.flush(); result.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "output","res","cmp")) { fail("Output incorrect."); } } private void showIterator(FileWriter result, Iterator i) throws Exception { while(i.hasNext()) { result.write((String) i.next()); result.write("\n"); } result.write("\n"); } private void showVector(FileWriter result, Vector v) throws Exception { for (int j = 0; j < v.size(); j++) { result.write((String) v.get(j)); result.write("\n"); } result.write("\n"); } private void message(FileWriter result, String message) throws Exception { result.write("--------------------------------------------------\n"); result.write(message + "\n"); result.write("--------------------------------------------------\n"); result.write("\n"); } } velocity-1.7/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java0000644000175000017500000002315111075007114027471 0ustar moellermoellerpackage org.apache.velocity.test; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.Velocity; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.VelocityContext; import org.apache.velocity.Template; import junit.framework.TestSuite; import java.io.*; /* * 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. */ /** * Test case for including macro libraries via the #parse method. */ public class ParseWithMacroLibsTestCase extends BaseTestCase { private static final String RESULT_DIR = TEST_RESULT_DIR + "/parsemacros"; private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/parsemacros/compare"; public ParseWithMacroLibsTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); } /** * Test suite * @return test suite */ public static junit.framework.Test suite() { return new TestSuite(ParseWithMacroLibsTestCase.class); } public void testParseMacroLocalCacheOn() throws Exception { /* * local scope, cache on */ VelocityEngine ve = createEngine(true, true); // render twice to make sure there is no difference with cached templates testParseMacro(ve, "vm_library1.vm", "parseMacro1_1", false); testParseMacro(ve, "vm_library1.vm", "parseMacro1_1", false); // run again with different macro library testParseMacro(ve, "vm_library2.vm", "parseMacro1_1b", false); testParseMacro(ve, "vm_library2.vm", "parseMacro1_1b", false); } /** * Runs the tests with global namespace. */ public void testParseMacroLocalCacheOff() throws Exception { /* * local scope, cache off */ VelocityEngine ve = createEngine(false, true); testParseMacro(ve, "vm_library1.vm", "parseMacro1_2", true); // run again with different macro library testParseMacro(ve, "vm_library2.vm", "parseMacro1_2b", true); } public void testParseMacroGlobalCacheOn() throws Exception { /* * global scope, cache on */ VelocityEngine ve = createEngine(true, false); // render twice to make sure there is no difference with cached templates testParseMacro(ve, "vm_library1.vm", "parseMacro1_3", false); testParseMacro(ve, "vm_library1.vm", "parseMacro1_3", false); // run again with different macro library testParseMacro(ve, "vm_library2.vm", "parseMacro1_3b", false); testParseMacro(ve, "vm_library2.vm", "parseMacro1_3b", false); } public void testParseMacroGlobalCacheOff() throws Exception { /* * global scope, cache off */ VelocityEngine ve = createEngine(false, false); testParseMacro(ve, "vm_library1.vm", "parseMacro1_4", true); // run again with different macro library testParseMacro(ve, "vm_library2.vm", "parseMacro1_4b", true); } /** * Test #parse with macros. Can be used to test different engine configurations * @param ve * @param outputBaseFileName * @param testCachingOff * @throws Exception */ private void testParseMacro(VelocityEngine ve, String includeFile, String outputBaseFileName, boolean testCachingOff) throws Exception { assureResultsDirectoryExists(RESULT_DIR); FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, outputBaseFileName, RESULT_FILE_EXT)); VelocityContext context = new VelocityContext(); context.put("includefile", includeFile); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); Template template = ve.getTemplate("parseMacro1.vm"); template.merge(context, writer); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, outputBaseFileName, RESULT_FILE_EXT,CMP_FILE_EXT)) { String result = getFileContents(RESULT_DIR, outputBaseFileName, RESULT_FILE_EXT); String compare = getFileContents(COMPARE_DIR, outputBaseFileName, CMP_FILE_EXT); String msg = "Processed template did not match expected output\n"+ "-----Result-----\n"+ result + "----Expected----\n"+ compare + "----------------"; fail(msg); } /* * Show that caching is turned off */ if (testCachingOff) { Template t1 = ve.getTemplate("parseMacro1.vm"); Template t2 = ve.getTemplate("parseMacro1.vm"); assertNotSame("Different objects", t1, t2); } } /** * Return and initialize engine * @return */ private VelocityEngine createEngine(boolean cache, boolean local) throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty( Velocity.VM_PERM_INLINE_LOCAL, Boolean.TRUE); ve.setProperty("velocimacro.permissions.allow.inline.to.replace.global", new Boolean(local)); ve.setProperty("file.resource.loader.cache", new Boolean(cache)); ve.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEST_COMPARE_DIR + "/parsemacros"); ve.init(); return ve; } /** * Test whether the literal text is given if a definition cannot be * found for a macro. * * @throws Exception */ public void testParseMacrosWithNoDefinition() throws Exception { /* * ve1: local scope, cache on */ VelocityEngine ve1 = new VelocityEngine(); ve1.setProperty( Velocity.VM_PERM_INLINE_LOCAL, Boolean.TRUE); ve1.setProperty("velocimacro.permissions.allow.inline.to.replace.global", Boolean.FALSE); ve1.setProperty("file.resource.loader.cache", Boolean.TRUE); ve1.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); ve1.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve1.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEST_COMPARE_DIR + "/parsemacros"); ve1.init(); assureResultsDirectoryExists(RESULT_DIR); FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "parseMacro2", RESULT_FILE_EXT)); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); Template template = ve1.getTemplate("parseMacro2.vm"); template.merge(context, writer); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, "parseMacro2", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } /** * Test that if a macro is duplicated, the second one takes precendence * * @throws Exception */ public void testDuplicateDefinitions() throws Exception { /* * ve1: local scope, cache on */ VelocityEngine ve1 = new VelocityEngine(); ve1.setProperty( Velocity.VM_PERM_INLINE_LOCAL, Boolean.TRUE); ve1.setProperty("velocimacro.permissions.allow.inline.to.replace.global", Boolean.FALSE); ve1.setProperty("file.resource.loader.cache", Boolean.TRUE); ve1.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); ve1.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve1.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEST_COMPARE_DIR + "/parsemacros"); ve1.init(); assureResultsDirectoryExists(RESULT_DIR); FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, "parseMacro3", RESULT_FILE_EXT)); VelocityContext context = new VelocityContext(); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); Template template = ve1.getTemplate("parseMacro3.vm"); template.merge(context, writer); /** * Write to the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR, COMPARE_DIR, "parseMacro3", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template did not match expected output"); } } } velocity-1.7/src/test/org/apache/velocity/test/ExceptionTestCase.java0000644000175000017500000001277310513464370025744 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.misc.ExceptionGeneratingDirective; import org.apache.velocity.test.misc.ExceptionGeneratingEventHandler; import org.apache.velocity.test.misc.ExceptionGeneratingResourceLoader; import org.apache.velocity.test.provider.TestProvider; /** * Test case for miscellaneous Exception related issues. * * @author Will Glass-Husain * @version $Id: ExceptionTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class ExceptionTestCase extends BaseTestCase implements TemplateTestBase { VelocityEngine ve; /** * Default constructor. */ public ExceptionTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(ExceptionTestCase.class); } public void testReferenceInsertionEventHandlerException() throws Exception { ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION,ExceptionGeneratingEventHandler.class.getName()); ve.init(); assertException(ve); } /** * Note - this is the one case where RuntimeExceptions *are not* passed through * verbatim. * @throws Exception */ public void testMethodExceptionEventHandlerException() throws Exception { ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION,ExceptionGeneratingEventHandler.class.getName()); ve.init(); Context context = new VelocityContext(); context.put ("test",new TestProvider()); assertMethodInvocationException(ve,context,"$test.getThrow()"); assertMethodInvocationException(ve,context,"$test.throw"); } public void testNullSetEventHandlerException() throws Exception { ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_NULLSET,ExceptionGeneratingEventHandler.class.getName()); ve.init(); assertException(ve,"#set($test = $abc)"); } public void testIncludeEventHandlerException() throws Exception { ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE,ExceptionGeneratingEventHandler.class.getName()); ve.init(); assertException(ve,"#include('dummy')"); } public void testResourceLoaderException() throws Exception { ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER,"except"); ve.setProperty("except.resource.loader.class",ExceptionGeneratingResourceLoader.class.getName()); try { ve.init(); // tries to get the macro file ve.getTemplate("test.txt"); fail("Should have thrown RuntimeException"); } catch (RuntimeException E) { // do nothing } } public void testDirectiveException() throws Exception { ve = new VelocityEngine(); ve.setProperty("userdirective",ExceptionGeneratingDirective.class.getName()); ve.init(); assertException(ve,"#Exception() test #end"); } public void assertException(VelocityEngine ve) throws Exception { Context context = new VelocityContext(); context.put ("test","test"); assertException(ve,context,"this is a $test"); } public void assertException(VelocityEngine ve, String input) throws Exception { Context context = new VelocityContext(); context.put ("test","test"); assertException(ve,context,input); } public void assertException(VelocityEngine ve, Context context, String input) throws Exception { try { StringWriter writer = new StringWriter(); ve.evaluate(context,writer,"test",input); fail("Expected RuntimeException"); } catch (RuntimeException E) { // do nothing } } public void assertMethodInvocationException(VelocityEngine ve, Context context, String input) throws Exception { try { StringWriter writer = new StringWriter(); ve.evaluate(context,writer,"test",input); fail("Expected MethodInvocationException"); } catch (MethodInvocationException E) { // do nothing } } } velocity-1.7/src/test/org/apache/velocity/test/view/0000755000175000017500000000000011675166247022463 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/view/TemplateNodeView.java0000644000175000017500000000517110513464370026532 0ustar moellermoellerpackage org.apache.velocity.test.view; /* * 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. */ import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.visitor.NodeViewMode; /** * Simple class for dumping the AST for a template. * Good for debugging and writing new directives. */ public class TemplateNodeView { /** * Root of the AST node structure that results from * parsing a template. */ private SimpleNode document; /** * Visitor used to traverse the AST node structure * and produce a visual representation of the * node structure. Very good for debugging and * writing new directives. */ private NodeViewMode visitor; /** * Default constructor: sets up the Velocity * Runtime, creates the visitor for traversing * the node structure and then produces the * visual representation by the visitation. */ public TemplateNodeView(String template) { try { RuntimeSingleton.init("velocity.properties"); InputStreamReader isr = new InputStreamReader( new FileInputStream(template), RuntimeSingleton.getString(RuntimeSingleton.INPUT_ENCODING)); BufferedReader br = new BufferedReader( isr ); document = RuntimeSingleton.parse( br, template); visitor = new NodeViewMode(); visitor.setContext(null); visitor.setWriter(new PrintWriter(System.out)); document.jjtAccept(visitor, null); } catch (Exception e) { System.out.println(e); e.printStackTrace(); } } } velocity-1.7/src/test/org/apache/velocity/test/ClassloaderChangeTestCase.java0000644000175000017500000001206211043672125027335 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.File; import java.io.FileInputStream; import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; import org.apache.velocity.util.introspection.IntrospectorCacheImpl; /** * Tests if we can hand Velocity an arbitrary class for logging. * * @author Geir Magnusson Jr. * @version $Id: ClassloaderChangeTestCase.java 680817 2008-07-29 19:49:41Z nbubna $ */ public class ClassloaderChangeTestCase extends TestCase implements LogChute { private VelocityEngine ve = null; private boolean sawCacheDump = false; private static String OUTPUT = "Hello From Foo"; /** * Default constructor. */ public ClassloaderChangeTestCase(String name) { super(name); } public void setUp() throws Exception { ve = new VelocityEngine(); ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this ); ve.init(); } public void init( RuntimeServices rs ) { // do nothing with it } public static Test suite () { return new TestSuite(ClassloaderChangeTestCase.class); } /** * Runs the test. */ public void testClassloaderChange() throws Exception { sawCacheDump = false; VelocityContext vc = new VelocityContext(); Object foo = null; /* * first, we need a classloader to make our foo object */ TestClassloader cl = new TestClassloader(); Class fooclass = cl.loadClass("Foo"); foo = fooclass.newInstance(); /* * put it into the context */ vc.put("foo", foo); /* * and render something that would use it * that will get it into the introspector cache */ StringWriter writer = new StringWriter(); ve.evaluate( vc, writer, "test", "$foo.doIt()"); /* * Check to make sure ok. note the obvious * dependency on the Foo class... */ if ( !writer.toString().equals( OUTPUT )) { fail("Output from doIt() incorrect"); } /* * and do it again :) */ cl = new TestClassloader(); fooclass = cl.loadClass("Foo"); foo = fooclass.newInstance(); vc.put("foo", foo); writer = new StringWriter(); ve.evaluate( vc, writer, "test", "$foo.doIt()"); if ( !writer.toString().equals( OUTPUT )) { fail("Output from doIt() incorrect"); } if (!sawCacheDump) { fail("Didn't see introspector cache dump."); } } /** * method to catch Velocity log messages. When we * see the introspector dump message, then set the flag */ public void log(int level, String message) { if (message.equals( IntrospectorCacheImpl.CACHEDUMP_MSG) ) { sawCacheDump = true; } } /** * method to catch Velocity log messages. When we * see the introspector dump message, then set the flag */ public void log(int level, String message, Throwable t) { // ignore the Throwable for this test log(level, message); } public boolean isLevelEnabled(int level) { return true; } } /** * Simple (real simple...) classloader that depends * on a Foo.class being located in the classloader * directory under test */ class TestClassloader extends ClassLoader { private final static String testclass = "test/classloader/Foo.class"; private Class fooClass = null; public TestClassloader() throws Exception { File f = new File( testclass ); byte[] barr = new byte[ (int) f.length() ]; FileInputStream fis = new FileInputStream( f ); fis.read( barr ); fis.close(); fooClass = defineClass("Foo", barr, 0, barr.length); } public Class findClass(String name) { return fooClass; } } velocity-1.7/src/test/org/apache/velocity/test/StrictForeachTestCase.java0000755000175000017500000000526211322700447026541 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.ArrayList; import java.util.Iterator; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests support for strict foreach mode. */ public class StrictForeachTestCase extends BaseTestCase { public StrictForeachTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.SKIP_INVALID_ITERATOR, Boolean.FALSE); context.put("good", new GoodIterable()); context.put("bad", new BadIterable()); context.put("ugly", new UglyIterable()); } public void testGood() { try { evaluate("#foreach( $i in $good )$i#end"); } catch (VelocityException ve) { fail("Doing #foreach on $good should not have exploded!"); } } public void testBad() { try { evaluate("#foreach( $i in $bad )$i#end"); fail("Doing #foreach on $bad should have exploded!"); } catch (VelocityException ve) { // success! } } public void testUgly() { try { evaluate("#foreach( $i in $ugly )$i#end"); fail("Doing #foreach on $ugly should have exploded!"); } catch (VelocityException ve) { // success! } } public static class GoodIterable { public Iterator iterator() { return new ArrayList().iterator(); } } public static class BadIterable { public Object iterator() { return new Object(); } } public static class UglyIterable { public Iterator iterator() { return null; } } } velocity-1.7/src/test/org/apache/velocity/test/ResourceCachingTestCase.java0000644000175000017500000000520710513464370027044 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; /** * Test resource caching related issues. * * @author Will Glass-Husain * @version $Id: ResourceCachingTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class ResourceCachingTestCase extends BaseTestCase { /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = "test/resourcecaching"; /** * Default constructor. */ public ResourceCachingTestCase(String name) { super(name); } public void setUp() throws Exception { } public static Test suite () { return new TestSuite(ResourceCachingTestCase.class); } /** * Tests for fix of bug VELOCITY-98 where a #include followed by #parse * of the same file throws ClassCastException when caching is on. * @throws Exception */ public void testIncludeParseCaching () throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty("file.resource.loader.cache", "true"); ve.setProperty("file.resource.loader.path", FILE_RESOURCE_LOADER_PATH); ve.init(); Template template = ve.getTemplate("testincludeparse.vm"); Writer writer = new StringWriter(); VelocityContext context = new VelocityContext(); // will produce a ClassCastException if Velocity-98 is not solved template.merge(context, writer); writer.flush(); writer.close(); } } velocity-1.7/src/test/org/apache/velocity/test/ArrayMethodsTestCase.java0000644000175000017500000001332711142425303026374 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.lang.reflect.Array; import java.util.Arrays; import java.util.ArrayList; import java.util.List; /** * Used to check that method calls on Array references work properly * and that they produce the same results as the same methods would on * a fixed-size {@link List}. */ public class ArrayMethodsTestCase extends BaseTestCase { public ArrayMethodsTestCase(final String name) { super(name); } /** * Runs the test. */ public void testArrayMethods() throws Exception { // test an array of string objects Object array = new String[] { "foo", "bar", "baz" }; checkResults(array, "woogie", true); // test an array of primitive ints array = new int[] { 1, 3, 7 }; checkResults(array, new Integer(11), false); // test an array of mixed objects, including null array = new Object[] { new Double(2.2), null }; checkResults(array, "whatever", true); // then set all the values to null checkResults(array, null, true); // then try an empty array array = new Object[] {}; checkResults(array, null, true); // while we have an empty array and list in the context, // make sure $array.get(0) and $list.get(0) throw // the same type of exception (MethodInvocationException) Throwable lt = null; Throwable at = null; try { evaluate("$list.get(0)"); } catch (Throwable t) { lt = t; } try { evaluate("$array.get(0)"); } catch (Throwable t) { at = t; } assertEquals(lt.getClass(), at.getClass()); } private void checkResults(Object array, Object setme, boolean compareToList) throws Exception { context.put("array", array); if (compareToList) { // create a list to match... context.put("list", new ArrayList(Arrays.asList((Object[])array))); } // if the object to be set is null, then remove instead of put if (setme != null) { context.put("setme", setme); } else { context.remove("setme"); } info("Changing to an array of: " + array.getClass().getComponentType()); info("Changing setme to: " + setme); int size = Array.getLength(array); checkResult("size()", String.valueOf(size), compareToList); boolean isEmpty = (size == 0); checkResult("isEmpty()", String.valueOf(isEmpty), compareToList); // check that the wrapping doesn't apply to java.lang.Object methods // such as toString() (for backwards compatibility). assertFalse(evaluate("$array").equals(evaluate("$list"))); for (int i=0; i < size; i++) { // put the index in the context, so we can try // both an explicit index and a reference index context.put("index", new Integer(i)); Object value = Array.get(array, i); String get = "get($index)"; String set = "set("+i+", $setme)"; if (value == null) { checkEmptyResult(get, compareToList); // set should return null checkEmptyResult(set, compareToList); } else { checkResult(get, value.toString(), compareToList); // set should return the old get value checkResult(set, value.toString(), compareToList); } // check that set() actually changed the value assertEquals(setme, Array.get(array, i)); // and check that get() now returns setme if (setme == null) { checkEmptyResult(get, compareToList); } else { checkResult(get, setme.toString(), compareToList); // now check that contains() properly finds the new value checkResult("contains($setme)", "true", compareToList); } } } private void checkEmptyResult(String method, boolean compareToList) throws Exception { checkResult(method, "", compareToList); } private void checkResult(String method, String expected, boolean compareToList) throws Exception { String result = evaluate("$!array."+method); assertEquals(expected, result); String listResult = null; if (compareToList) { listResult = evaluate("$!list."+method); assertEquals(result, listResult); } info(" <$!array."+method+"> resolved to <"+result+">"); if (compareToList) { info(" <$!list."+method+"> resolved to "+listResult+">"); } } } velocity-1.7/src/test/org/apache/velocity/test/SecureIntrospectionTestCase.java0000644000175000017500000001201710566231325030004 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.Collection; import java.util.HashSet; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.util.introspection.SecureUberspector; /** * Checks that the secure introspector is working properly. * * @author wglass@forio.com * @version $Id: SecureIntrospectionTestCase.java 509094 2007-02-19 05:17:09Z wglass $ */ public class SecureIntrospectionTestCase extends BaseTestCase { /** * Default constructor. * @param name */ public SecureIntrospectionTestCase(String name) { super(name); } public static Test suite() { return new TestSuite(SecureIntrospectionTestCase.class); } private String [] badTemplateStrings = { "$test.Class.Methods", "$test.Class.ClassLoader", "$test.Class.ClassLoader.loadClass('java.util.HashMap').newInstance().size()" }; private String [] goodTemplateStrings = { "#foreach($item in $test.collection)$item#end", "$test.Class.Name", "#set($test.Property = 'abc')$test.Property", "$test.aTestMethod()" }; /** * Test to see that "dangerous" methods are forbidden * @exception Exception */ public void testBadMethodCalls() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.UBERSPECT_CLASSNAME, SecureUberspector.class.getName()); ve.init(); /* * all of the following method calls should not work */ doTestMethods(ve, badTemplateStrings, false); } /** * Test to see that "dangerous" methods are forbidden * @exception Exception */ public void testGoodMethodCalls() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.UBERSPECT_CLASSNAME, SecureUberspector.class.getName()); ve.init(); /* * all of the following method calls should not work */ doTestMethods(ve, goodTemplateStrings, true); } private void doTestMethods(VelocityEngine ve, String[] templateStrings, boolean shouldeval) { Context c = new VelocityContext(); c.put("test", this); try { for (int i=0; i < templateStrings.length; i++) { if (shouldeval && !doesStringEvaluate(ve,c,templateStrings[i])) { fail ("Should have evaluated: " + templateStrings[i]); } if (!shouldeval && doesStringEvaluate(ve,c,templateStrings[i])) { fail ("Should not have evaluated: " + templateStrings[i]); } } } catch (Exception e) { fail(e.toString()); } } private boolean doesStringEvaluate(VelocityEngine ve, Context c, String inputString) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException, IOException { // assume that an evaluation is bad if the input and result are the same (e.g. a bad reference) // or the result is an empty string (e.g. bad #foreach) Writer w = new StringWriter(); ve.evaluate(c, w, "foo", inputString); String result = w.toString(); return (result.length() > 0 ) && !result.equals(inputString); } private String testProperty; public String getProperty() { return testProperty; } public int aTestMethod() { return 1; } public void setProperty(String val) { testProperty = val; } public Collection getCollection() { Collection c = new HashSet(); c.add("aaa"); c.add("bbb"); c.add("ccc"); return c; } } velocity-1.7/src/test/org/apache/velocity/test/StringResourceLoaderTestCase.java0000644000175000017500000001521111273703572030105 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; 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.resource.loader.StringResourceLoader; import org.apache.velocity.test.misc.TestLogChute; /** * Multiple paths in the file resource loader. * * @author Jason van Zyl * @version $Id: StringResourceLoaderTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class StringResourceLoaderTestCase extends BaseTestCase { /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/stringloader"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/stringloader/compare"; VelocityEngine engine; /** * Default constructor. */ public StringResourceLoaderTestCase(String name) { super(name); } public static Test suite() { return new TestSuite(StringResourceLoaderTestCase.class); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "string"); engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName()); engine.addProperty("string.resource.loader.modificationCheckInterval", "1"); // Silence the logger. engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public void testSimpleTemplate() throws Exception { StringResourceLoader.getRepository().putStringResource("simpletemplate.vm", "This is a test for ${foo}"); Template template = engine.getTemplate(getFileName(null, "simpletemplate", TMPL_FILE_EXT)); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, "simpletemplate", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); context.put("foo", "a foo object"); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "simpletemplate", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } public void testMultipleTemplates() throws Exception { StringResourceLoader.getRepository().putStringResource("multi1.vm", "I am the $first template."); StringResourceLoader.getRepository().putStringResource("multi2.vm", "I am the $second template."); Template template1 = engine.getTemplate(getFileName(null, "multi1", TMPL_FILE_EXT)); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, "multi1", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); context.put("first", new Integer(1)); context.put("second", "two"); template1.merge(context, writer); writer.flush(); writer.close(); Template template2 = engine.getTemplate(getFileName(null, "multi2", TMPL_FILE_EXT)); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "multi2", RESULT_FILE_EXT)); writer = new BufferedWriter(new OutputStreamWriter(fos)); template2.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "multi1", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Template 1 incorrect."); } if (!isMatch(RESULTS_DIR, COMPARE_DIR, "multi2", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Template 2 incorrect."); } } public void testContentChange() throws Exception { StringResourceLoader.getRepository().putStringResource("change.vm", "I am the $first template."); Template template = engine.getTemplate(getFileName(null, "change", TMPL_FILE_EXT)); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, "change1", RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); context.put("first", new Integer(1)); context.put("second", "two"); template.merge(context, writer); writer.flush(); writer.close(); StringResourceLoader.getRepository().putStringResource("change.vm", "I am the $second template."); Thread.sleep(2000L); template = engine.getTemplate(getFileName(null, "change", TMPL_FILE_EXT)); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "change2", RESULT_FILE_EXT)); writer = new BufferedWriter(new OutputStreamWriter(fos)); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "change1", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Template 1 incorrect."); } if (!isMatch(RESULTS_DIR, COMPARE_DIR, "change2", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Template 2 incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/ForeachTestCase.java0000644000175000017500000001061111322700447025337 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.provider.ForeachMethodCallHelper; /** * This class tests the Foreach loop. * * @author Daniel Rall * @author Will Glass-Husain */ public class ForeachTestCase extends BaseTestCase { public ForeachTestCase(String name) { super(name); } /** * Tests limiting of the number of loop iterations. */ public void testMaxNbrLoopsConstraint() throws Exception { // Limit the loop to three iterations. engine.setProperty(RuntimeConstants.MAX_NUMBER_LOOPS, new Integer(3)); assertEvalEquals("1 2 3 ", "#foreach ($item in [1..10])$item #end"); } /** * Tests proper method execution during a Foreach loop over a Collection * with items of varying classes. */ public void testCollectionAndMethodCall() throws Exception { List col = new ArrayList(); col.add(new Integer(100)); col.add("STRVALUE"); context.put("helper", new ForeachMethodCallHelper()); context.put("col", col); assertEvalEquals("int 100 str STRVALUE ", "#foreach ( $item in $col )$helper.getFoo($item) #end"); } /** * Tests that #foreach will be able to retrieve an iterator from * an arbitrary object that happens to have an iterator() method. * (With the side effect of supporting the new Java 5 Iterable interface) */ public void testObjectWithIteratorMethod() throws Exception { context.put("iterable", new MyIterable()); assertEvalEquals("1 2 3 ", "#foreach ($i in $iterable)$i #end"); } public void testNotReallyIterableIteratorMethod() throws Exception { context.put("nri", new NotReallyIterable()); assertEvalEquals("", "#foreach ($i in $nri)$i #end"); } public void testVelocityHasNextProperty() throws Exception { List list = new ArrayList(); list.add("test1"); list.add("test2"); list.add("test3"); context.put("list", list); assertEvalEquals("test1 SEPARATOR test2 SEPARATOR test3 ", "#foreach ($value in $list)$value #if( $velocityHasNext )SEPARATOR #end#end"); } public void testNestedVelocityHasNextProperty() throws Exception { List list = new ArrayList(); list.add("test1"); list.add("test2"); list.add("test3"); list.add("test4"); context.put("list", list); List list2 = new ArrayList(); list2.add("a1"); list2.add("a2"); list2.add("a3"); context.put("list2", list2); assertEvalEquals("test1 (a1;a2;a3)-test2 (a1;a2;a3)-test3 (a1;a2;a3)-test4 (a1;a2;a3)", "#foreach ($value in $list)$value (#foreach ($val in $list2)$val#if( $velocityHasNext );#end#end)#if( $velocityHasNext )-#end#end"); } public static class MyIterable { private List foo; public MyIterable() { foo = new ArrayList(); foo.add(new Integer(1)); foo.add(new Long(2)); foo.add("3"); } public Iterator iterator() { return foo.iterator(); } } public static class NotReallyIterable { public Object iterator() { return new Object(); } } } velocity-1.7/src/test/org/apache/velocity/test/BuiltInEventHandlerTestCase.java0000644000175000017500000003463111247126663027656 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.implement.EscapeHtmlReference; import org.apache.velocity.app.event.implement.EscapeJavaScriptReference; import org.apache.velocity.app.event.implement.EscapeReference; import org.apache.velocity.app.event.implement.EscapeSqlReference; import org.apache.velocity.app.event.implement.EscapeXmlReference; import org.apache.velocity.app.event.implement.InvalidReferenceInfo; import org.apache.velocity.app.event.implement.ReportInvalidReferences; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; /** * Tests the operation of the built in event handlers. * * @author Will Glass-Husain * @version $Id: BuiltInEventHandlerTestCase.java 809816 2009-09-01 05:14:27Z nbubna $ */ public class BuiltInEventHandlerTestCase extends BaseTestCase { protected boolean DEBUG = false; /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/includeevent"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/includeevent/compare"; /** * Default constructor. */ public BuiltInEventHandlerTestCase(String name) { super(name); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); super.setUp(); } public static Test suite() { return new TestSuite(BuiltInEventHandlerTestCase.class); } protected void log(String out) { if (DEBUG) { System.out.println (out); } } /** * Test reporting of invalid syntax * @throws Exception */ public void testReportInvalidReferences1() throws Exception { VelocityEngine ve = new VelocityEngine(); ReportInvalidReferences reporter = new ReportInvalidReferences(); ve.init(); VelocityContext context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(reporter); ec.attachToContext(context); context.put("a1","test"); context.put("b1","test"); Writer writer = new StringWriter(); ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()"); List errors = reporter.getInvalidReferences(); assertEquals(2,errors.size()); assertEquals("$c1",((InvalidReferenceInfo) errors.get(0)).getInvalidReference()); assertEquals("$a1.foobar()",((InvalidReferenceInfo) errors.get(1)).getInvalidReference()); log("Caught invalid references (local configuration)."); } public void testReportInvalidReferences2() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty("eventhandler.invalidreference.exception","true"); ReportInvalidReferences reporter = new ReportInvalidReferences(); ve.init(); VelocityContext context = new VelocityContext(); EventCartridge ec = new EventCartridge(); ec.addEventHandler(reporter); ec.attachToContext(context); context.put("a1","test"); context.put("b1","test"); Writer writer = new StringWriter(); ve.evaluate(context,writer,"test","$a1 no problem"); try { ve.evaluate(context,writer,"test","$a1 $c1 $a1.length() $a1.foobar()"); fail ("Expected exception."); } catch (RuntimeException E) {} log("Caught invalid references (global configuration)."); } /** * Test escaping * @throws Exception */ public void testEscapeHtml() throws Exception { EscapeReference esc = new EscapeHtmlReference(); assertEquals("test string&another<b>bold</b>test",esc.referenceInsert("","test string&anotherboldtest")); assertEquals("<">",esc.referenceInsert("","<\">")); assertEquals("test string",esc.referenceInsert("","test string")); log("Correctly escaped HTML"); } /** * Test escaping * @throws Exception */ public void testEscapeXml() throws Exception { EscapeReference esc = new EscapeXmlReference(); assertEquals("test string&another<b>bold</b>test",esc.referenceInsert("","test string&anotherboldtest")); assertEquals("<">",esc.referenceInsert("","<\">")); assertEquals("'",esc.referenceInsert("","'")); assertEquals("test string",esc.referenceInsert("","test string")); log("Correctly escaped XML"); } /** * Test escaping * @throws Exception */ public void testEscapeSql() throws Exception { EscapeReference esc = new EscapeSqlReference(); assertEquals("Jimmy''s Pizza",esc.referenceInsert("","Jimmy's Pizza")); assertEquals("test string",esc.referenceInsert("","test string")); log("Correctly escaped SQL"); } /** * Test escaping * @throws Exception */ public void testEscapeJavaScript() throws Exception { EscapeReference esc = new EscapeJavaScriptReference(); assertEquals("Jimmy\\'s Pizza",esc.referenceInsert("","Jimmy's Pizza")); assertEquals("test string",esc.referenceInsert("","test string")); log("Correctly escaped Javascript"); } /** * test that escape reference handler works with no match restrictions * @throws Exception */ public void testEscapeReferenceMatchAll() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, "org.apache.velocity.app.event.implement.EscapeHtmlReference"); ve.init(); Context context; Writer writer; // test normal reference context = new VelocityContext(); writer = new StringWriter(); context.put("bold",""); ve.evaluate(context,writer,"test","$bold test & test"); assertEquals("<b> test & test",writer.toString()); // test method reference context = new VelocityContext(); writer = new StringWriter(); context.put("bold",""); ve.evaluate(context,writer,"test","$bold.substring(0,1)"); assertEquals("<",writer.toString()); log("Escape matched all references (global configuration)"); } /** * test that escape reference handler works with match restrictions * @throws Exception */ public void testEscapeReferenceMatch() throws Exception { // set up HTML match on everything, JavaScript match on _js* VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION, "org.apache.velocity.app.event.implement.EscapeHtmlReference,org.apache.velocity.app.event.implement.EscapeJavaScriptReference"); ve.setProperty("eventhandler.escape.javascript.match", "/.*_js.*/"); ve.init(); Writer writer; // Html no JavaScript writer = new StringWriter(); ve.evaluate(newEscapeContext(),writer,"test","$test1"); assertEquals("Jimmy's <b>pizza</b>",writer.toString()); // comment out bad test -- requires latest commons-lang /** // JavaScript and HTML writer = new StringWriter(); ve.evaluate(newEscapeContext(),writer,"test","$test1_js"); assertEquals("Jimmy\\'s <b>pizza</b>",writer.toString()); // JavaScript and HTML writer = new StringWriter(); ve.evaluate(newEscapeContext(),writer,"test","$test1_js_test"); assertEquals("Jimmy\\'s <b>pizza</b>",writer.toString()); // JavaScript and HTML (method call) writer = new StringWriter(); ve.evaluate(newEscapeContext(),writer,"test","$test1_js.substring(0,7)"); assertEquals("Jimmy\\'s",writer.toString()); **/ log("Escape selected references (global configuration)"); } private Context newEscapeContext() { Context context = new VelocityContext(); context.put("test1","Jimmy's pizza"); context.put("test1_js","Jimmy's pizza"); context.put("test1_js_test","Jimmy's pizza"); return context; } public void testPrintExceptionHandler() throws Exception { VelocityEngine ve1 = new VelocityEngine(); ve1.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions"); ve1.init(); VelocityEngine ve2 = new VelocityEngine(); ve2.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions"); ve2.setProperty("eventhandler.methodexception.message","true"); ve2.init(); VelocityEngine ve3 = new VelocityEngine(); ve3.setProperty(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION, "org.apache.velocity.app.event.implement.PrintExceptions"); ve3.setProperty("eventhandler.methodexception.stacktrace","true"); ve3.init(); Context context; StringWriter writer; context = new VelocityContext(); context.put("list",new ArrayList()); // exception only writer = new StringWriter(); ve1.evaluate(context,writer,"test","$list.get(0)"); assertTrue(writer.toString().indexOf("IndexOutOfBoundsException") != -1); assertTrue(writer.toString().indexOf("Index: 0, Size: 0") == -1); assertTrue(writer.toString().indexOf("ArrayList") == -1); // message writer = new StringWriter(); ve2.evaluate(context,writer,"test","$list.get(0)"); assertTrue(writer.toString().indexOf("IndexOutOfBoundsException") != -1); assertTrue(writer.toString().indexOf("Index: 0, Size: 0") != -1); assertTrue(writer.toString().indexOf("ArrayList") == -1); // stack trace writer = new StringWriter(); ve3.evaluate(context,writer,"test","$list.get(0)"); assertTrue(writer.toString().indexOf("IndexOutOfBoundsException") != -1); assertTrue(writer.toString().indexOf("ArrayList") != -1); log("PrintException handler successful."); } public void testIncludeNotFound() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeNotFound"); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); Template template; FileOutputStream fos; Writer fwriter; Context context; template = ve.getTemplate( getFileName(null, "test6", TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "test6", RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test6", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } log("IncludeNotFound handler successful."); } public void testIncludeNotFoundMissingResourceName() throws Exception { // uses base test support engine.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeNotFound"); addTemplate("notfound.vm", "$missingResource"); assertEvalEquals("foo", "#parse('foo')"); } public void testIncludeRelativePath() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, "org.apache.velocity.app.event.implement.IncludeRelativePath"); ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); ve.init(); Template template; FileOutputStream fos; Writer fwriter; Context context; template = ve.getTemplate( getFileName(null, "subdir/test2", TMPL_FILE_EXT) ); fos = new FileOutputStream ( getFileName(RESULTS_DIR, "test2", RESULT_FILE_EXT)); fwriter = new BufferedWriter( new OutputStreamWriter(fos) ); context = new VelocityContext(); template.merge(context, fwriter); fwriter.flush(); fwriter.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "test2", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } log("IncludeRelativePath handler successful."); } } velocity-1.7/src/test/org/apache/velocity/test/URLResourceLoaderTimeoutTestCase.java0000755000175000017500000000476511142425303030653 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.URLResourceLoader; import org.apache.velocity.test.misc.TestLogChute; /** * This class tests support for custom timeouts in URLResourceLoader. */ public class URLResourceLoaderTimeoutTestCase extends BaseTestCase { private static boolean isJava5plus; static { try { Class.forName("java.lang.annotation.Annotation"); isJava5plus = true; } catch (ClassNotFoundException cnfe) { isJava5plus = false; } } private TestLogChute logger = new TestLogChute(); private URLResourceLoader loader = new URLResourceLoader(); private int timeout = 2000; public URLResourceLoaderTimeoutTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty("resource.loader", "url"); engine.setProperty("url.resource.loader.instance", loader); engine.setProperty("url.resource.loader.timeout", new Integer(timeout)); // actual instance of logger logger.on(); engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, logger); engine.setProperty("runtime.log.logsystem.test.level", "debug"); engine.init(); } public void testTimeout() { if (isJava5plus) { System.out.println("Testing a 1.5+ JDK"); assertEquals(timeout, loader.getTimeout()); } else { System.out.println("Testing a pre-1.5 JDK"); assertEquals(-1, loader.getTimeout()); } } } velocity-1.7/src/test/org/apache/velocity/test/ScopeTestCase.java0000755000175000017500000003243211440022314025040 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.util.HashMap; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests the directive scope controls */ public class ScopeTestCase extends BaseTestCase { public ScopeTestCase(String name) { super(name); } protected void setUpEngine(VelocityEngine engine) { engine.setProperty("a.provide.scope.control", "true"); engine.setProperty("define.provide.scope.control", "true"); engine.setProperty("evaluate.provide.scope.control", "true"); engine.setProperty("foo.provide.scope.control", "true"); engine.setProperty("macro.provide.scope.control", "true"); engine.setProperty("template.provide.scope.control", "true"); engine.setProperty("vm.provide.scope.control", "true"); engine.setProperty(RuntimeConstants.SET_NULL_ALLOWED, Boolean.TRUE); } public void testScopeGetLeakIntoInner() { addTemplate("foo", "#foreach($i in [1..1])#set($foreach.a=$i)"+ "#foreach($j in [2..2])$foreach.a#set($foreach.a=$j)"+ "#foreach($k in [3..3])$foreach.a#end#end$foreach.a#end"); assertTmplEquals("121", "foo"); } public void testScopeGetLeakDoesntHideNullset() { addTemplate("a", "#macro(a)#set($macro.a='a')#b()$macro.a#end"+ "#macro(b)$macro.a#set($macro.a=$null)$!macro.a#end"+ "#a()"); assertTmplEquals("aa", "a"); } public void testRootTemplateMergeScope() { addTemplate("foo", "foo#break($template)bar"); assertTmplEquals("foo", "foo"); assertNull(context.get("template")); } public void testParseScope() { addTemplate("test", "$template.info.depth"+ "$!parse.parent.info.depth"+ "#set( $template.foo = 'bar' )"+ "$template.foo"+ "#break($template)"+ "woogie"); assertEvalEquals("1bar", "#parse( 'test' )"); assertNull(context.get("template")); } public void testNestedParseScope() { HashMap grab = new HashMap(); context.put("grab", grab); addTemplate("inner", "Inner depth: $template.info.depth"+ "#set( $template.foo = '?' )"+ "$!grab.put('inner',$template)"+ "#break($template)$template.foo"); addTemplate("outer", "#set( $template.foo = '!' )"+ "Outer depth: $template.info.depth "+ "#parse('inner')"+ "$!grab.put('outer', $template)"+ "$template.foo"); assertEvalEquals("Outer depth: 1 Inner depth: 2!", "#parse('outer')"); // make extra sure that the outer control was restored after the stop assertFalse(grab.get("inner") == grab.get("outer")); // make sure the outer control was cleaned up assertNull(context.get("template")); addTemplate("3", "$template.topmost.foo#set( $template.topmost.foo = 'bar' )"); addTemplate("2", "#parse( '3' )$!parse.foo"); addTemplate("1", "#set( $template.foo = 'foo' )#parse('2')$template.foo"); assertEvalEquals("foobar", "#parse('1')$!parse"); // make sure the top control was cleaned up assertNull(context.get("template")); } public void testForeachScope() { String template = "#foreach( $i in [0..2] )"+ "#if( $i > 1 )#break($foreach)#end"+ "$foreach.index:$foreach.count:$foreach.hasNext,"+ "#end"; assertEvalEquals("0:1:true,1:2:true,", template); assertNull(context.get("foreach")); } public void testNestedForeachScope() { String template = "#foreach( $i in [1..5] )"+ "#foreach( $j in [1..2] )"+ "#if ( $i > $foreach.count + $foreach.index + $foreach.info.depth )#break($foreach.topmost)#end"+ "#end"+ "$i"+ "#end"; assertEvalEquals("123", template); assertNull(context.get("foreach")); } public void testMacroScope() { String template = "#macro( foo $i )"+ "#if($i > 2 )#break($macro)#end"+ "$i#end"+ "#foo( 0 )#foo( 1 )#foo( 2 )"; assertEvalEquals("012", template); assertNull(context.get("macro")); } public void testRecursiveMacroScope() { String template = "#macro( foo )$macro.info.depth"+ "#if($macro.info.depth > 2 )#break($macro.topmost)#end"+ "#foo()#end#foo()"; assertEvalEquals("123", template); assertNull(context.get("macro")); } public void testNestedMacroScope() { String template = "#macro( a )$macro.info.depth#set($macro.c = 'a')$macro.c#end"+ "#macro( b )#set($macro.c = 'b' )#a()$macro.c#end"+ "#b()"; assertEvalEquals("2ab", template); assertNull(context.get("macro")); } public void testBodyMacroScope() { String template = "#macro( foo $bar )$bodyContent$macro.bar#end"+ "#@foo( 'bar' )#set( $macro.bar = 'foo'+$bar )"+ "#set( $foo.d = $foo.info.depth )$foo.d #end"; assertEvalEquals("1 foobar", template); assertNull(context.get("foo")); assertNull(context.get("macro")); } public void testRecursiveBodyMacroScope() { engine.setProperty(RuntimeConstants.VM_MAX_DEPTH, "5"); String template = "#macro( foo )$bodyContent$macro.i#end"+ "#@foo()#set( $macro.i = \"$!macro.i$foo.info.depth,\" )"+ "$!bodyContent#end"; assertEvalEquals("1,2,3,4,5,", template); assertNull(context.get("foo")); assertNull(context.get("macro")); } public void testDefineScope() { String template = "#define( $foo )#set( $define.bar = 'bar'+$define.info.depth )$define.bar#end$foo"; assertEvalEquals("bar1", template); assertNull(context.get("define")); } public void testNestedDefineScope() { String template = "#define($a)$b c#end"+ "#define($b)$define.info.depth#break($define.topmost)#end"+ "$a"; assertEvalEquals("2", template); assertNull(context.get("define")); } public void testRecursiveDefineScope() { engine.setProperty(RuntimeConstants.DEFINE_DIRECTIVE_MAXDEPTH, "10"); String template = "#define($a)$define.info.depth"+ "#if($define.info.depth == 5)#break($define)#end,$a#end$a"; assertEvalEquals("1,2,3,4,5", template); assertNull(context.get("define")); } public void testRootEvaluateScope() { assertEvalEquals("1", "$evaluate.info.depth"); assertEvalEquals("foo", "foo#break($evaluate)bar"); assertNull(context.get("evaluate")); } public void testEvaluateScope() { context.put("h", "#"); context.put("d", "$"); String template = "${h}set( ${d}evaluate.foo = 'bar' )"+ "${d}evaluate.foo ${d}evaluate.info.depth"; addTemplate("eval", "#evaluate(\""+template+"\")"); assertTmplEquals("bar 1", "eval"); assertNull(context.get("evaluate")); assertNull(context.get("template")); } public void testNestedEvaluateScope() { context.put("h", "#"); context.put("d", "$"); addTemplate("e", "#evaluate(\"${h}evaluate( '${d}evaluate.info.depth${h}stop(${d}evaluate) blah' )\")"); assertTmplEquals("2", "e"); assertNull(context.get("evaluate")); assertNull(context.get("template")); } public void testTurningOffTemplateScope() { engine.setProperty("template."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); // root addTemplate("test", "$template.info.depth"); assertTmplEquals("$template.info.depth", "test"); // #parse assertEvalEquals("$template.info.depth", "#parse('test')"); } public void testTurningOffEvaluateScope() { engine.setProperty("evaluate."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); // root assertSchmoo("$evaluate.info.depth"); // #evaluate assertEvalEquals("$evaluate.info.depth", "#evaluate( '$evaluate.info.depth' )"); } public void testTurningOffMacroScope() { engine.setProperty("macro."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); engine.setProperty("foo."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); // macro definition assertEvalEquals("$macro", "#macro(a)$macro#end#a()"); // macro body assertEvalEquals("$macro $foo", "#macro(foo)$bodyContent#end#@foo()$macro $foo#end"); } public void testTurningOffDefineScope() { engine.setProperty("define."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); assertEvalEquals("$define", "#define($a)$define#end$a"); } public void testTurningOffForeachScope() { engine.setProperty("foreach."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, "false"); assertEvalEquals("$foreach$foreach", "#foreach($i in [0..1])$foreach#end"); } public void testTemplateReplaced() { context.put("template", "foo"); addTemplate("test", "$template.replaced"); assertTmplEquals("foo", "test"); assertEvalEquals("foo", "#parse('test')"); assertContextValue("template", "foo"); } public void testEvaluateReplaced() { context.put("evaluate","foo"); assertEvalEquals("foo", "$evaluate.replaced"); assertEvalEquals("foo", "#evaluate('$evaluate.replaced')"); assertContextValue("evaluate", "foo"); } public void testMacroReplaced() { context.put("macro", "foo"); assertEvalEquals("foo foo foo", "$macro #macro(a)$macro.replaced#end#a() $macro"); assertContextValue("macro", "foo"); } public void testForeachReplaced() { context.put("foreach", "foo"); assertEvalEquals("foofoofoo", "$foreach#foreach($i in [1..1])$foreach.replaced#end$foreach"); assertEquals("foo", context.get("foreach")); context.put("foreach", "a"); assertEvalEquals("a", "#foreach($i in [1..1])#foreach($j in [1..1])$foreach.replaced#end#end"); assertContextValue("foreach", "a"); } public void testDefineReplaced() { context.put("define", "a"); assertEvalEquals("a", "#define($a)$define.replaced#end$a"); assertContextValue("define", "a"); } public void testBodyContentReplaced() { context.put("vm", "a"); assertEvalEquals("a", "#macro(vm)$bodyContent#end#@vm()$vm.replaced#end"); assertContextValue("vm", "a"); } public void testInfoDepth() { String template = "#foreach($i in [1..1])"+ "#foreach($j in [0..0])"+ "$foreach.info.depth"+ "#end"+ "#end"; assertEvalEquals("2", template); } public void testInfoName() { String template = "#foreach($i in [1..1])"+ "$foreach.info.name #evaluate('$evaluate.info.name')"+ "#end"; assertEvalEquals("foreach evaluate", template); } public void testInfoType() { addTemplate("info", "#foreach($i in [1..1])"+ "$foreach.info.type"+ "#end "+ "#evaluate('$evaluate.info.type') "+ "$template.info.type"); assertTmplEquals("block line utf-8", "info"); } public void testInfoLineAndColumn() { String template = " #evaluate('$evaluate.info.line, $evaluate.info.column')"; assertEvalEquals(" 1, 2", template); assertEvalEquals("\n\n 3, 4", "\n\n "+template); } public void testInfoTemplate() { addTemplate("test", "#evaluate('$evaluate.info.template')"); assertTmplEquals("test", "test"); assertEvalEquals("test", "#parse('test')"); } } velocity-1.7/src/test/org/apache/velocity/test/VarargMethodsTestCase.java0000644000175000017500000001502511322700447026542 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.VelocityContext; /** * Used to check that vararg method calls on references work properly */ public class VarargMethodsTestCase extends BaseTestCase { public VarargMethodsTestCase(final String name) { super(name); } protected void setUpContext(VelocityContext context) { context.put("nice", new NiceTool()); context.put("nasty", new NastyTool()); context.put("objects", new Object[] { this, VelocityContext.class }); context.put("strings", new String[] { "one", "two" }); context.put("doubles", new double[] { 1.5, 2.5 }); context.put("float", new Float(1f)); context.put("ints", new int[] { 1, 2 }); } public void testStrings() { assertEvalEquals("onetwo", "$nice.var($strings)"); assertEvalEquals("onetwo", "$nice.var('one','two')"); assertEvalEquals("one", "$nice.var('one')"); assertEvalEquals("", "$nice.var()"); } public void testDoubles() { assertEvalEquals("4.0", "$nice.add($doubles)"); assertEvalEquals("3.0", "$nice.add(1,2)"); assertEvalEquals("1.0", "$nice.add(1)"); assertEvalEquals("0.0", "$nice.add()"); } public void testFloatToDoubleVarArg() { assertEvalEquals("1.0", "$nice.add($float)"); } public void testStringVsStrings() { assertEvalEquals("onlyone", "$nasty.var('one')"); assertEvalEquals("onlynull", "$nasty.var($null)"); assertEvalEquals("", "$nasty.var()"); } public void testIntVsDoubles() { assertEvalEquals("1", "$nasty.add(1)"); assertEvalEquals("1.0", "$nasty.add(1.0)"); assertEvalEquals("3.0", "$nasty.add(1.0,2)"); } public void testInts() { assertEvalEquals("3", "$nasty.add($ints)"); assertEvalEquals("3", "$nasty.add(1,2)"); assertEvalEquals("1", "$nasty.add(1)"); // add(int[]) wins because it is "more specific" assertEvalEquals("0", "$nasty.add()"); } public void testStringsVsObjectsAKASubclassVararg() { assertEvalEquals("objects", "$nice.test($objects)"); assertEvalEquals("objects", "$nice.test($nice,$nasty,$ints)"); assertEvalEquals("strings", "$nice.test('foo')"); } public void testObjectVarArgVsObjectEtc() { assertEvalEquals("object,string", "$nasty.test($nice,'foo')"); } public void testObjectVarArgVsObjectVelocity605() { assertEvalEquals("string", "$nasty.test('joe')"); assertEvalEquals("object", "$nasty.test($nice)"); } public void testNoArgs() { assertEvalEquals("noargs", "$nasty.test()"); } public void testPassingArrayToVarArgVelocity642() { assertEvalEquals("[one, two]", "$nasty.test642($strings)"); assertEvalEquals("[1, 2]", "#set( $list = [1..2] )$nasty.test642($list.toArray())"); } public void testNullToPrimitiveVarArg() { assertEvalEquals("int[]", "$nasty.test649($null)"); } public void testArgsBeforeVarargWithNoArgs() { assertEvalEquals("String,String,Object[]", "$nasty.test651('a','b')"); } public void testVelocity651() { assertEvalEquals("String,List", "$nasty.test651('test',['TEST'])"); } public static class NiceTool { public String var(String[] ss) { StringBuffer out = new StringBuffer(); for (int i=0; i < ss.length; i++) { out.append(ss[i]); } return out.toString(); } public double add(double[] dd) { double total = 0; for (int i=0; i < dd.length; i++) { total += dd[i]; } return total; } public String test(Object[] oo) { return "objects"; } public String test(String[] oo) { return "strings"; } } public static class NastyTool extends NiceTool { public String var(String s) { return "only"+s; } public int add(int[] ii) { int total = 0; for (int i=0; i < ii.length; i++) { total += ii[i]; } return total; } public int add(int i) { return i; } public String test() { return "noargs"; } public Object test(Object arg) { return "object"; } public Object test(String arg) { return "string"; } public String test(Object[] array) { return "object[]"; } public String test(Object object, String property) { return "object,string"; } public String test642(Object[] array) { //JDK5: return Arrays.deepToString(array); if (array == null) { return null; } StringBuffer o = new StringBuffer("["); for (int i=0; i < array.length; i++) { if (i > 0) { o.append(", "); } o.append(String.valueOf(array[i])); } o.append("]"); return o.toString(); } public String test649(int[] array) { return "int[]"; } public String test651(String s, String s2, Object[] args) { return "String,String,Object[]"; } public String test651(String s, java.util.List l) { return "String,List"; } } } velocity-1.7/src/test/org/apache/velocity/test/MethodCacheKeyTestCase.java0000644000175000017500000000642410513464370026617 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.TestCase; import org.apache.commons.lang.ArrayUtils; import org.apache.velocity.runtime.parser.node.ASTMethod; /** * Checks that the equals method works correctly when caching method keys. * * @author wglass@forio.com * @version $Id: MethodCacheKeyTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class MethodCacheKeyTestCase extends TestCase { public void testMethodKeyCacheEquals() { Class [] elements1 = new Class [] { Object.class }; ASTMethod.MethodCacheKey mck1 = new ASTMethod.MethodCacheKey("test",elements1); selfEqualsAssertions(mck1); Class [] elements2 = new Class [] { Object.class }; ASTMethod.MethodCacheKey mck2 = new ASTMethod.MethodCacheKey("test",elements2); assertTrue(mck1.equals(mck2)); Class [] elements3 = new Class [] { String.class }; ASTMethod.MethodCacheKey mck3 = new ASTMethod.MethodCacheKey("test",elements3); assertFalse(mck1.equals(mck3)); Class [] elements4 = new Class [] { Object.class }; ASTMethod.MethodCacheKey mck4 = new ASTMethod.MethodCacheKey("boo",elements4); assertFalse(mck1.equals(mck4)); /** check for potential NPE's **/ Class [] elements5 = ArrayUtils.EMPTY_CLASS_ARRAY; ASTMethod.MethodCacheKey mck5 = new ASTMethod.MethodCacheKey("boo",elements5); selfEqualsAssertions(mck5); Class [] elements6 = null; ASTMethod.MethodCacheKey mck6 = new ASTMethod.MethodCacheKey("boo",elements6); selfEqualsAssertions(mck6); Class [] elements7 = new Class [] {}; ASTMethod.MethodCacheKey mck7 = new ASTMethod.MethodCacheKey("boo",elements7); selfEqualsAssertions(mck7); Class [] elements8 = new Class [] {null}; ASTMethod.MethodCacheKey mck8 = new ASTMethod.MethodCacheKey("boo",elements8); selfEqualsAssertions(mck8); Class [] elements9 = new Class [] { Object.class }; ASTMethod.MethodCacheKey mck9 = new ASTMethod.MethodCacheKey("boo",elements9); selfEqualsAssertions(mck9); } private void selfEqualsAssertions(ASTMethod.MethodCacheKey mck) { assertTrue(mck.equals(mck)); assertTrue(!mck.equals(null)); assertTrue(!mck.equals((ASTMethod.MethodCacheKey) null)); } } velocity-1.7/src/test/org/apache/velocity/test/misc/0000755000175000017500000000000011675166246022443 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/misc/GetPutObject.java0000644000175000017500000000203110513464370025626 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ public class GetPutObject { private Object value; public Object get() { return value; } public void put(final Object value) { this.value = value; } } velocity-1.7/src/test/org/apache/velocity/test/misc/ExceptionGeneratingDirective.java0000644000175000017500000000370710513464370031103 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.parser.node.Node; /** * that always throws an exception. Used to test * that RuntimeExceptions are passed through. * * @author Will Glass-Husain * @version $Id: ExceptionGeneratingDirective.java 463298 2006-10-12 16:10:32Z henning $ */ public class ExceptionGeneratingDirective extends Directive { public String getName() { return "Exception"; } public int getType() { return Directive.BLOCK; } public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { throw new RuntimeException("exception"); } } velocity-1.7/src/test/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java0000644000175000017500000000352410513464370032100 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import java.io.InputStream; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.runtime.resource.loader.ResourceLoader; /** * Resource Loader that always throws an exception. Used to test * that RuntimeExceptions are passed through. * * @author Will Glass-Husain * @version $Id: ExceptionGeneratingResourceLoader.java 463298 2006-10-12 16:10:32Z henning $ */ public class ExceptionGeneratingResourceLoader extends ResourceLoader { public void init(ExtendedProperties configuration) { } public InputStream getResourceStream(String source) throws ResourceNotFoundException { throw new RuntimeException("exception"); } public boolean isSourceModified(Resource resource) { return false; } public long getLastModified(Resource resource) { return 0; } } velocity-1.7/src/test/org/apache/velocity/test/misc/ExceptionGeneratingEventHandler.java0000644000175000017500000000414110513464370031535 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.app.event.NullSetEventHandler; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; /** * Event handlers that always throws an exception. Used to test * that RuntimeExceptions are passed through. * * @author Will Glass-Husain * @version $Id: ExceptionGeneratingEventHandler.java 463298 2006-10-12 16:10:32Z henning $ */ public class ExceptionGeneratingEventHandler implements IncludeEventHandler, MethodExceptionEventHandler, NullSetEventHandler, ReferenceInsertionEventHandler { public String includeEvent(String includeResourcePath, String currentResourcePath, String directiveName) { throw new RuntimeException("exception"); } public Object methodException(Class claz, String method, Exception e) throws Exception { throw new RuntimeException("exception"); } public boolean shouldLogOnNullSet(String lhs, String rhs) { throw new RuntimeException("exception"); } public Object referenceInsert(String reference, Object value) { throw new RuntimeException("exception"); } } velocity-1.7/src/test/org/apache/velocity/test/misc/TestContext.java0000644000175000017500000000443610601646507025570 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import java.util.HashMap; import java.util.Map; import org.apache.velocity.VelocityContext; import org.apache.velocity.context.Context; /** * Used for testing EvaluateContext. For testing purposes, this is a case insensitive * context. * * @author Will Glass-Husain * @version $Id: TestContext.java 522413 2007-03-26 04:34:15Z wglass $ */ public class TestContext implements Context { Context innerContext = new VelocityContext(); Map originalKeys = new HashMap(); public boolean containsKey(Object key) { return innerContext.containsKey(normalizeKey(key)); } public Object get(String key) { return innerContext.get(normalizeKey(key)); } public Object[] getKeys() { return originalKeys.values().toArray(); } public Object put(String key, Object value) { String normalizedKey = normalizeKey(key); originalKeys.put(key, normalizedKey); return innerContext.put(normalizedKey, value); } public Object remove(Object key) { originalKeys.remove(key); return innerContext.remove(normalizeKey(key)); } private String normalizeKey(Object key) { if (key == null) { return null; } else if (key.toString() == null) { return null; } else { return key.toString().toUpperCase(); } } } velocity-1.7/src/test/org/apache/velocity/test/misc/UberspectorTestObject.java0000644000175000017500000000502010513464370027554 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ public class UberspectorTestObject { private String regular; private String premium; private boolean regularBool; private boolean premiumBool; private String ambigous; /** * @return the premium */ public String getpremium() { return premium; } /** * @param premium the premium to set */ public void setpremium(String premium) { this.premium = premium; } /** * @return the premiumBool */ public boolean ispremiumBool() { return premiumBool; } /** * @param premiumBool the premiumBool to set */ public void setpremiumBool(boolean premiumBool) { this.premiumBool = premiumBool; } /** * @return the regular */ public String getRegular() { return regular; } /** * @param regular the regular to set */ public void setRegular(String regular) { this.regular = regular; } /** * @return the regularBool */ public boolean isRegularBool() { return regularBool; } /** * @param regularBool the regularBool to set */ public void setRegularBool(boolean regularBool) { this.regularBool = regularBool; } /** * @return the ambigous */ public String getAmbigous() { return ambigous; } /** * @param ambigous the ambigous to set */ public void setAmbigous(String ambigous) { this.ambigous = ambigous; } /** * @param ambigous the ambigous to set */ public void setAmbigous(StringBuffer ambigous) { this.ambigous = ambigous.toString(); } } velocity-1.7/src/test/org/apache/velocity/test/misc/TestLogChute.java0000644000175000017500000000604011153274430025642 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import java.io.ByteArrayOutputStream; import java.io.PrintStream; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.SystemLogChute; /** * LogChute implementation that can easily capture output * or suppress it entirely. By default, both capture and suppress * are on. To have this behave like a normal SystemLogChute, * you must turn it on() and stopCapture(). * * @author Will Glass-Husain * @author Nathan Bubna * @version $Id: TestLogChute.java 749684 2009-03-03 18:38:16Z nbubna $ */ public class TestLogChute extends SystemLogChute { public static final String TEST_LOGGER_LEVEL = "runtime.log.logsystem.test.level"; private ByteArrayOutputStream log; private PrintStream systemDotIn; private boolean suppress = true; private boolean capture = true; public TestLogChute() { log = new ByteArrayOutputStream(); systemDotIn = new PrintStream(log, true); } public TestLogChute(boolean suppress, boolean capture) { this(); this.suppress = suppress; this.capture = capture; } public void init(RuntimeServices rs) throws Exception { super.init(rs); String level = rs.getString(TEST_LOGGER_LEVEL); if (level != null) { setEnabledLevel(toLevel(level)); } } public void on() { suppress = false; } public void off() { suppress = true; } public void startCapture() { capture = true; } public void stopCapture() { capture = false; } public boolean isLevelEnabled(int level) { return (!suppress || capture) && super.isLevelEnabled(level); } protected void write(PrintStream ps, String prefix, String message, Throwable t) { if (capture) { super.write(systemDotIn, prefix, message, t); } else { super.write(ps, prefix, message, t); } } /** * Return the captured log messages to date. * @return log messages */ public String getLog() { return log.toString(); } } velocity-1.7/src/test/org/apache/velocity/test/misc/UberspectTestException.java0000644000175000017500000000340310513464370027746 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import org.apache.velocity.util.introspection.Info; /** * Exception that returns an Info object for testing after a introspection problem. * This extends Error so that it will stop parsing and allow * internal info to be examined. * * @author Will Glass-Husain * @author Llewellyn Falco * @version $Id: UberspectTestException.java 463298 2006-10-12 16:10:32Z henning $ */ public class UberspectTestException extends RuntimeException { /** * Version Id for serializable */ private static final long serialVersionUID = 3956896150436225712L; Info info; public UberspectTestException(String message, Info i) { super(message); info = i; } public Info getInfo() { return info; } public String getMessage() { return super.getMessage() + "\n failed at " + info; } } velocity-1.7/src/test/org/apache/velocity/test/misc/UberspectTestImpl.java0000644000175000017500000000440011202566437026712 0ustar moellermoellerpackage org.apache.velocity.test.misc; /* * 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. */ import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.UberspectImpl; import org.apache.velocity.util.introspection.VelMethod; import org.apache.velocity.util.introspection.VelPropertyGet; /** * A introspector that allows testing when methods are not found. */ public class UberspectTestImpl extends UberspectImpl { public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { VelMethod method = super.getMethod(obj, methodName, args, i); if (method == null) { if (obj == null) throw new UberspectTestException("Can't call method '" + methodName + "' on null object",i); else throw new UberspectTestException("Did not find method "+ obj.getClass().getName()+"."+methodName, i); } return method; } public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { VelPropertyGet propertyGet = super.getPropertyGet(obj, identifier, i); if (propertyGet == null) { if (obj == null) throw new UberspectTestException("Can't call getter '" + identifier + "' on null object",i); else throw new UberspectTestException("Did not find "+ obj.getClass().getName()+"."+identifier, i); } return propertyGet; } } velocity-1.7/src/test/org/apache/velocity/test/BlockMacroTestCase.java0000644000175000017500000001045311366631123026012 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests the BlockMacro functionality. */ public class BlockMacroTestCase extends BaseTestCase { public BlockMacroTestCase(String name) { super(name); // DEBUG = true; } public void testMultipleBodyContentIncludes() throws Exception { String template = "#macro(foo $txt) Yeah, $txt! $bodyContent $bodyContent#end #@foo(\"woohoo\")jee#end"; String result = " Yeah, woohoo! jee jee"; assertEvalEquals(result, template); } public void testNestedVelocityLogic() throws Exception { String template = "#macro(foo $txt) Yeah, $txt! $bodyContent#end #@foo(\"woohoo\")#foreach($i in [1..3])$i:#{end}#end"; String result = " Yeah, woohoo! 1:2:3:"; assertEvalEquals(result, template); } public void testEmptyBody() throws Exception { String template = "#macro(foo $txt) Yeah, $txt! $bodyContent#end #@foo(\"woohoo\")#end"; String result = " Yeah, woohoo! "; assertEvalEquals(result, template); } public void testNoArgumentsEmptyBodyCall() throws Exception { String template = "#macro(foo) Yeah! $bodyContent#end #@foo()#end"; String result = " Yeah! "; assertEvalEquals(result, template); } public void testCustomBodyReference() throws Exception { engine.setProperty(RuntimeConstants.VM_BODY_REFERENCE, "myBody"); String template = "#macro(foo) Yeah! $myBody#end #@foo()#end"; String result = " Yeah! "; assertEvalEquals(result, template); } public void testVelocity671() throws Exception { engine.setProperty(RuntimeConstants.VM_PERM_INLINE_LOCAL, Boolean.TRUE); String template = "#macro(echo)$bodyContent#end #@echo()Yeah!#end"; String result = " Yeah!"; assertEvalEquals(result, template); } public void testVelocity675() throws Exception { assertEvalEquals("#@foo", "#@foo"); } public void testVelocity685() throws Exception { engine.setProperty(RuntimeConstants.VM_ARGUMENTS_STRICT, Boolean.TRUE); assertEvalEquals(" ", "#macro(foo)#end #@foo() junk #end"); } public void testVelocity686() throws Exception { String template = "#macro(foo)#set( $x = $bodyContent )#end"+ "#@foo()b#end a $x "; assertEvalEquals(" a b ", template); } public void testNestedBlockMacro() { String template = "#macro(foo)foo:$bodyContent#end"+ "#macro(bar)bar:$bodyContent#end"+ "#@foo()foo,#@bar()bar#end#end"; assertEvalEquals("foo:foo,bar:bar", template); } public void testRecursiveBlockMacro() { engine.setProperty(RuntimeConstants.VM_MAX_DEPTH, "3"); String template = "#macro(foo)start:$bodyContent#end"+ "#@foo()call:$bodyContent#end"; assertEvalEquals("start:call:call:call:$bodyContent", template); } public void testBlueJoesProblem() { engine.setProperty("macro."+RuntimeConstants.PROVIDE_SCOPE_CONTROL, Boolean.TRUE); addTemplate("a", "#macro(wrap $layout)$!macro.put($layout,$bodyContent)#parse($layout)#end"+ "#@wrap('b')a#end"); addTemplate("b", "#@wrap('c')b$!macro.get('b')b#end"); addTemplate("c", "c$!macro.get('c')c"); assertTmplEquals("cbabc", "a"); } } velocity-1.7/src/test/org/apache/velocity/test/MultipleFileResourcePathTestCase.java0000644000175000017500000001060411273703572030721 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; 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.test.misc.TestLogChute; /** * Multiple paths in the file resource loader. * * @author Jason van Zyl * @version $Id: MultipleFileResourcePathTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class MultipleFileResourcePathTestCase extends BaseTestCase { /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH1 = TEST_COMPARE_DIR + "/multi/path1"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH2 = TEST_COMPARE_DIR + "/multi/path2"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/multi"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/multi/compare"; VelocityEngine engine; /** * Default constructor. */ public MultipleFileResourcePathTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(MultipleFileResourcePathTestCase.class); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); engine.addProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH1); engine.addProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH2); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } /** * Runs the test. */ public void testMultipleFileResources () throws Exception { Template template1 = engine.getTemplate( getFileName(null, "path1", TMPL_FILE_EXT)); Template template2 = engine.getTemplate( getFileName(null, "path2", TMPL_FILE_EXT)); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULTS_DIR, "path1", RESULT_FILE_EXT)); FileOutputStream fos2 = new FileOutputStream ( getFileName(RESULTS_DIR, "path2", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template1.merge(context, writer1); writer1.flush(); writer1.close(); template2.merge(context, writer2); writer2.flush(); writer2.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, "path1", RESULT_FILE_EXT, CMP_FILE_EXT) || !isMatch(RESULTS_DIR, COMPARE_DIR, "path2", RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/sql/0000755000175000017500000000000011675166246022307 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/sql/HsqlDataSource.java0000644000175000017500000000430110540246067026020 0ustar moellermoellerpackage org.apache.velocity.test.sql; /* * 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. */ import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import javax.sql.DataSource; import org.hsqldb.jdbcDriver; public class HsqlDataSource implements DataSource { private final String url; private PrintWriter logWriter = null; private int loginTimeout = 0; public HsqlDataSource(final String url) throws Exception { this.url = url; Class.forName(jdbcDriver.class.getName()); } public Connection getConnection() throws SQLException { return DriverManager.getConnection(url, "sa", ""); } public Connection getConnection(final String username, final String password) throws SQLException { return DriverManager.getConnection(url, username, password); } public PrintWriter getLogWriter() throws SQLException { return logWriter; } public int getLoginTimeout() throws SQLException { return loginTimeout; } public void setLogWriter(final PrintWriter logWriter) throws SQLException { this.logWriter = logWriter; } public void setLoginTimeout(final int loginTimeout) throws SQLException { this.loginTimeout = loginTimeout; } public boolean isWrapperFor(final Class iface) throws SQLException { return false; } public Object unwrap(final Class iface) throws SQLException { throw new SQLException("Not implemented"); } } velocity-1.7/src/test/org/apache/velocity/test/sql/DataSourceResourceLoaderTestCase.java0000644000175000017500000001523111322700447031463 0ustar moellermoellerpackage org.apache.velocity.test.sql; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import javax.sql.DataSource; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader; import org.apache.velocity.test.misc.TestLogChute; public class DataSourceResourceLoaderTestCase extends BaseSQLTest { /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Path to template file. This will get combined with the * application directory to form an absolute path */ private final static String DATA_PATH = TEST_COMPARE_DIR + "/ds"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/ds"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/ds/templates"; /** * String (not containing any VTL) used to test unicode */ private String UNICODE_TEMPLATE = "\\u00a9 test \\u0410 \\u0411"; /** * Name of template for testing unicode. */ private String UNICODE_TEMPLATE_NAME = "testUnicode"; VelocityEngine engine; public DataSourceResourceLoaderTestCase(final String name) throws Exception { super(name, DATA_PATH); setUpUnicode(); } public static Test suite() { return new TestSuite(DataSourceResourceLoaderTestCase.class); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); DataSource ds = new HsqlDataSource("jdbc:hsqldb:."); DataSourceResourceLoader rl = new DataSourceResourceLoader(); rl.setDataSource(ds); engine = new VelocityEngine(); // pass in an instance to Velocity engine.addProperty( "resource.loader", "ds" ); engine.setProperty( "ds.resource.loader.instance", rl ); engine.setProperty( "ds.resource.loader.resource.table", "velocity_template"); engine.setProperty( "ds.resource.loader.resource.keycolumn", "id"); engine.setProperty( "ds.resource.loader.resource.templatecolumn", "def"); engine.setProperty( "ds.resource.loader.resource.timestampcolumn", "timestamp"); Velocity.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public void setUpUnicode() throws Exception { String insertString = "insert into velocity_template (id, timestamp, def) VALUES " + "( '" + UNICODE_TEMPLATE_NAME + "', NOW(), '" + UNICODE_TEMPLATE + "');"; executeSQL(insertString); } /** * Tests loading and rendering of a simple template. If that works, we are able to get data * from the database. */ public void testSimpleTemplate() throws Exception { Template t = executeTest("testTemplate1"); assertFalse("Timestamp is 0", 0 == t.getLastModified()); } public void testUnicode() throws Exception { Template template = engine.getTemplate(UNICODE_TEMPLATE_NAME); Writer writer = new StringWriter(); VelocityContext context = new VelocityContext(); template.merge(context, writer); writer.flush(); writer.close(); String outputText = writer.toString(); if (!normalizeNewlines(UNICODE_TEMPLATE).equals( normalizeNewlines( outputText ) )) { fail("Output incorrect for Template: " + UNICODE_TEMPLATE_NAME); } } /** * Now we have a more complex example. Run a very simple tool. * from the database. */ public void testRenderTool() throws Exception { Template t = executeTest("testTemplate2"); assertFalse("Timestamp is 0", 0 == t.getLastModified()); } /** * Will a NULL timestamp choke the loader? */ public void testNullTimestamp() throws Exception { Template t = executeTest("testTemplate3"); assertEquals("Timestamp is not 0", 0, t.getLastModified()); } /** * Does it load the global Macros from the DB? */ public void testMacroInvocation() throws Exception { Template t = executeTest("testTemplate4"); assertFalse("Timestamp is 0", 0 == t.getLastModified()); } protected Template executeTest(final String templateName) throws Exception { Template template = engine.getTemplate(templateName); FileOutputStream fos = new FileOutputStream ( getFileName(RESULTS_DIR, templateName, RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); context.put("tool", new DSRLTCTool()); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, templateName, RESULT_FILE_EXT, CMP_FILE_EXT)) { fail("Output incorrect for Template: " + templateName); } return template; } public static final class DSRLTCTool { public int add(final int a, final int b) { return a + b; } public String getMessage() { return "And the result is:"; } } } velocity-1.7/src/test/org/apache/velocity/test/sql/BaseSQLTest.java0000644000175000017500000000353511322700447025234 0ustar moellermoellerpackage org.apache.velocity.test.sql; /* * 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. */ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.apache.velocity.test.BaseTestCase; /** * A base class to implement tests that need a running * Velocity engine and an initialized Hsql Database. Yeah, I should probably * use Derby at some point... * * @author Henning P. Schmiedehausen * @version $Id: BaseSQLTest.java 898032 2010-01-11 19:51:03Z nbubna $ */ public abstract class BaseSQLTest extends BaseTestCase { private static HsqlDB hsqlDB = null; public BaseSQLTest(String name, String path) throws Exception { super(name); if (hsqlDB == null) { hsqlDB = new HsqlDB("jdbc:hsqldb:.", path + "/create-db.sql"); } } public void executeSQL(String sql) throws SQLException { Connection connection = hsqlDB.getConnection(); Statement statement = connection.createStatement(); statement.executeUpdate(sql); } } velocity-1.7/src/test/org/apache/velocity/test/sql/HsqlDB.java0000644000175000017500000000606110513464370024257 0ustar moellermoellerpackage org.apache.velocity.test.sql; /* * 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. */ import org.apache.commons.lang.StringUtils; import org.hsqldb.jdbcDriver; import java.io.FileReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class HsqlDB { private Connection connection = null; public HsqlDB(String uri, String loadFile) throws Exception { Class.forName(jdbcDriver.class.getName()); this.connection = DriverManager.getConnection(uri, "sa", ""); if (StringUtils.isNotEmpty(loadFile)) { loadSqlFile(loadFile); } } public Connection getConnection() { return connection; } public void close() { try { connection.close(); } catch (Exception e) { System.out.println("While closing Connection" + e.getMessage()); } } private void loadSqlFile(String fileName) throws Exception { Statement statement = null; try { statement = connection.createStatement(); String commands = getFileContents(fileName); for (int targetPos = commands.indexOf(';'); targetPos > -1; targetPos = commands.indexOf(';')) { String cmd = commands.substring(0, targetPos + 1); try { statement.execute(cmd); } catch (SQLException sqle) { System.out.println("Statement: " + cmd + ": " + sqle.getMessage()); } commands = commands.substring(targetPos + 2); } } finally { if (statement != null) { statement.close(); } } } private String getFileContents(String fileName) throws Exception { FileReader fr = null; try { fr = new FileReader(fileName); char[] fileBuf = new char[1024]; StringBuffer sb = new StringBuffer(1000); int res = -1; while ((res = fr.read(fileBuf, 0, 1024)) > -1) { sb.append(fileBuf, 0, res); } return sb.toString(); } finally { if (fr != null) { fr.close(); } } } } velocity-1.7/src/test/org/apache/velocity/test/StopDirectiveTestCase.java0000644000175000017500000000556311203164124026560 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.runtime.RuntimeConstants; /** * Test the #stop directive */ public class StopDirectiveTestCase extends BaseTestCase { public StopDirectiveTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "test/stop/"); engine.setProperty(RuntimeConstants.VM_LIBRARY, "vmlib1.vm"); } public void testStop() { // Make it works through the evaluate method call assertEvalEquals("Text1", "Text1#{stop}Text2"); // Make sure stop works in a template assertTmplEquals("Text 1", "stop1.vm"); // Make sure stop works when called from a velocity macro assertTmplEquals("Text123stuff1", "stop2.vm"); // Make sure stop works when called located in another parsed file assertTmplEquals("text1blaa1", "stop3.vm"); } public void testNestedStopAll() { addTemplate("ns", ",template"+ "#macro(vm),macro${bodyContent}macro#end"+ "#define($define),define"+ "#foreach($i in [1..2]),foreach"+ "#{stop}foreach"+ "#{end}define"+ "#{end}"+ "#@vm(),bodyContent"+ "${define}bodyContent"+ "#{end}template"); String expected = "evaluate,template,macro,bodyContent,define,foreach"; assertEvalEquals(expected, "#evaluate('evaluate#parse(\"ns\")evaluate')"); } public void testStopMessage() { log.setEnabledLevel(TestLogChute.DEBUG_ID); log.off(); context.put("log", log); assertEvalEquals("a", "a$!log.startCapture()#stop('woogie!')b"); info("Log: "+log.getLog()); assertTrue(log.getLog().indexOf("StopCommand: woogie!") >= 0); } }velocity-1.7/src/test/org/apache/velocity/test/TemplateTestCase.java0000644000175000017500000001710511050417060025542 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Vector; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.FieldMethodizer; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.test.provider.BoolObj; import org.apache.velocity.test.provider.NullToStringObject; import org.apache.velocity.test.provider.TestNumber; import org.apache.velocity.test.provider.TestProvider; /** * Easily add test cases which evaluate templates and check their output. * * NOTE: * This class DOES NOT extend RuntimeTestCase because the TemplateTestSuite * already initializes the Velocity runtime and adds the template * test cases. Having this class extend RuntimeTestCase causes the * Runtime to be initialized twice which is not good. I only discovered * this after a couple hours of wondering why all the properties * being setup were ending up as Vectors. At first I thought it * was a problem with the Configuration class, but the Runtime * was being initialized twice: so the first time the property * is seen it's stored as a String, the second time it's seen * the Configuration class makes a Vector with both Strings. * As a result all the getBoolean(property) calls were failing because * the Configurations class was trying to create a Boolean from * a Vector which doesn't really work that well. I have learned * my lesson and now have to add some code to make sure the * Runtime isn't initialized more then once :-) * * @author Daniel Rall * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Jon S. Stevens * @version $Id: TemplateTestCase.java 685369 2008-08-12 23:35:12Z nbubna $ */ public class TemplateTestCase extends BaseTestCase implements TemplateTestBase { /** * The base file name of the template and comparison file (i.e. array for * array.vm and array.cmp). */ protected String baseFileName; private TestProvider provider; private ArrayList al; private Hashtable h; private VelocityContext context; private VelocityContext context1; private VelocityContext context2; private Vector vec; /** * Creates a new instance. * * @param baseFileName The base name of the template and comparison file to * use (i.e. array for array.vm and array.cmp). */ public TemplateTestCase (String baseFileName) { super(getTestCaseName(baseFileName)); this.baseFileName = baseFileName; } public static junit.framework.Test suite() { return new TemplateTestSuite(); } /** * Sets up the test. */ protected void setUp () { provider = new TestProvider(); al = provider.getCustomers(); h = new Hashtable(); h.put("Bar", "this is from a hashtable!"); h.put("Foo", "this is from a hashtable too!"); /* * lets set up a vector of objects to test late introspection. See ASTMethod.java */ vec = new Vector(); vec.addElement(new String("string1")); vec.addElement(new String("string2")); /* * set up 3 chained contexts, and add our data * throught the 3 of them. */ context2 = new VelocityContext(); context1 = new VelocityContext( context2 ); context = new VelocityContext( context1 ); context.put("provider", provider); context1.put("name", "jason"); context1.put("name2", new StringBuffer("jason")); context1.put("name3", new StringBuffer("geoge")); context2.put("providers", provider.getCustomers2()); context.put("list", al); context1.put("hashtable", h); context2.put("hashmap", new HashMap()); context2.put("search", provider.getSearch()); context.put("relatedSearches", provider.getRelSearches()); context1.put("searchResults", provider.getRelSearches()); context2.put("stringarray", provider.getArray()); context.put("vector", vec ); context.put("mystring", new String()); context.put("runtime", new FieldMethodizer( "org.apache.velocity.runtime.RuntimeSingleton" )); context.put("fmprov", new FieldMethodizer( provider )); context.put("Floog", "floogie woogie"); context.put("boolobj", new BoolObj() ); /* * we want to make sure we test all types of iterative objects * in #foreach() */ Object[] oarr = { "a","b","c","d" } ; int intarr[] = { 10, 20, 30, 40, 50 }; context.put( "collection", vec ); context2.put("iterator", vec.iterator()); context1.put("map", h ); context.put("obarr", oarr ); context.put("enumerator", vec.elements()); context.put("intarr", intarr ); // Add some Numbers context.put ("int1", new Integer (1000)); context.put ("long1", new Long (10000000000l)); context.put ("float1", new Float (1000.1234)); context.put ("double1", new Double (10000000000d)); // Add a TemplateNumber context.put ("templatenumber1", new TestNumber (999.125)); /** * Test #foreach() with a list containing nulls */ ArrayList nullList = new ArrayList(); nullList.add("a"); nullList.add("b"); nullList.add(null); nullList.add("d"); context.put("nullList", nullList); // test silent references with a null tostring context.put("nullToString",new NullToStringObject()); } /** * Runs the test. */ public void runTest () throws Exception { Template template = RuntimeSingleton.getTemplate (getFileName(null, baseFileName, TMPL_FILE_EXT)); assureResultsDirectoryExists(RESULT_DIR); /* get the file to write to */ FileOutputStream fos = new FileOutputStream (getFileName( RESULT_DIR, baseFileName, RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); /* process the template */ template.merge( context, writer); /* close the file */ writer.flush(); writer.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,baseFileName, RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Processed template "+getFileName( RESULT_DIR, baseFileName, RESULT_FILE_EXT)+" did not match expected output"); } } } velocity-1.7/src/test/org/apache/velocity/test/InvalidEventHandlerTestCase.java0000644000175000017500000004117211273740157027673 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.InvalidReferenceEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; import org.apache.velocity.util.introspection.Info; /** * Tests event handling for all event handlers except IncludeEventHandler. This is tested * separately due to its complexity. * * @author Geir Magnusson Jr. * @version $Id: InvalidEventHandlerTestCase.java 832302 2009-11-03 05:32:31Z wglass $ */ public class InvalidEventHandlerTestCase extends TestCase { /** * Default constructor. */ public InvalidEventHandlerTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(InvalidEventHandlerTestCase.class); } public void testManualEventHandlers() throws Exception { TestEventCartridge te = new TestEventCartridge(); /** * Test attaching the event cartridge to the context */ VelocityEngine ve = new VelocityEngine(); ve.init(); /* * lets make a Context and add the event cartridge */ VelocityContext inner = new VelocityContext(); /* * Now make an event cartridge, register all the * event handlers (at once) and attach it to the * Context */ EventCartridge ec = new EventCartridge(); ec.addEventHandler(te); ec.attachToContext( inner ); doTestInvalidReferenceEventHandler1(ve, inner); doTestInvalidReferenceEventHandler2(ve, inner); doTestInvalidReferenceEventHandler3(ve, inner); doTestInvalidReferenceEventHandler4(ve, inner); } /** * Test assigning the event handlers via properties */ public void testConfigurationEventHandlers() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES, TestEventCartridge.class.getName()); ve.init(); doTestInvalidReferenceEventHandler1(ve, null); doTestInvalidReferenceEventHandler2(ve, null); doTestInvalidReferenceEventHandler3(ve, null); doTestInvalidReferenceEventHandler4(ve, null); } /** * Test deeper structures * @param ve * @param vc * @throws Exception */ private void doTestInvalidReferenceEventHandler4(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); Tree test = new Tree(); test.setField("10"); Tree test2 = new Tree(); test2.setField("12"); test.setChild(test2); context.put("tree",test); String s; Writer w; // show work fine s = "$tree.Field $tree.field $tree.child.Field"; w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); s = "$tree.x $tree.field.x $tree.child.y $tree.child.Field.y"; w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); } /** * Test invalid #set * @param ve * @param vc * @throws Exception */ private void doTestInvalidReferenceEventHandler3(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); context.put("a1",new Integer(5)); context.put("a4",new Integer(5)); context.put("b1","abc"); String s; Writer w; // good object, bad right hand side s = "#set($xx = $a1.afternoon())"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // good object, bad right hand reference s = "#set($yy = $q1)"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} } /** * Test invalid method calls * @param ve * @param vc * @throws Exception */ private void doTestInvalidReferenceEventHandler2(VelocityEngine ve, VelocityContext vc) throws Exception { VelocityContext context = new VelocityContext(vc); context.put("a1",new Integer(5)); context.put("b1",new Integer(5)); context.put("a4",new Integer(5)); context.put("b4",new Integer(5)); context.put("z1","abc"); String s; Writer w; // good object, bad method s = "$a1.afternoon()"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // good object, bad method s = "$!b1.afternoon()"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // bad object, bad method -- fails on get s = "$zz.daylight()"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // change result s = "$z1.baby()"; w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); assertEquals("www",w.toString()); } /** * Test invalid gets/references * @param ve * @param vc * @throws Exception */ private void doTestInvalidReferenceEventHandler1(VelocityEngine ve, VelocityContext vc) throws Exception { String result; VelocityContext context = new VelocityContext(vc); context.put("a1",new Integer(5)); context.put("b1",new Integer(5)); context.put("a4",new Integer(5)); context.put("b4",new Integer(5)); context.put("z1","abc"); // normal - should be no calls to handler String s = "$a1 $a1.intValue() $z1 $z1.length() #set($c1 = '5')"; Writer w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); // good object, bad property s = "$a1.foobar"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // good object, bad property / silent s = "$!b1.foobar"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // bad object, bad property s = "$a2.foobar"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // bad object, bad property / silent s = "$!b2.foobar"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // bad object, no property s = "$a3"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // bad object, no property / silent s = "$!b3"; w = new StringWriter(); try { ve.evaluate( context, w, "mystring", s ); fail("Expected exception."); } catch (RuntimeException e) {} // good object, bad property; change the value s = "$a4.foobar"; w = new StringWriter(); ve.evaluate( context, w, "mystring", s ); result = w.toString(); assertEquals("zzz", result); } /** * Test assigning the event handlers via properties */ public static class TestEventCartridge implements InvalidReferenceEventHandler, RuntimeServicesAware { private RuntimeServices rs; public TestEventCartridge() { } /** * Required by EventHandler */ public void setRuntimeServices( RuntimeServices rs ) { // make sure this is only called once if (this.rs == null) this.rs = rs; else fail("initialize called more than once."); } public Object invalidGetMethod(Context context, String reference, Object object, String property, Info info) { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); // good object, bad property if (reference.equals("$a1.foobar")) { assertEquals(new Integer(5),object); assertEquals("foobar",property); throw new RuntimeException("expected exception"); } // good object, bad property else if (reference.equals("$!b1.foobar")) { assertEquals(new Integer(5),object); assertEquals("foobar",property); throw new RuntimeException("expected exception"); } // good object, bad property else if (reference.equals("$a1.foobar")) { assertEquals(new Integer(5),object); assertEquals("foobar",property); throw new RuntimeException("expected exception"); } // good object, bad property else if (reference.equals("$!b1.foobar")) { assertEquals(new Integer(5),object); assertEquals("foobar",property); throw new RuntimeException("expected exception"); } // bad object, bad property else if (reference.equals("$a2")) { assertNull(object); assertNull(property); throw new RuntimeException("expected exception"); } // bad object, bad property else if (reference.equals("$!b2")) { assertNull(object); assertNull(property); throw new RuntimeException("expected exception"); } // bad object, no property else if (reference.equals("$a3")) { assertNull(object); assertNull(property); throw new RuntimeException("expected exception"); } // bad object, no property else if (reference.equals("$!b3")) { assertNull(object); assertNull(property); throw new RuntimeException("expected exception"); } // good object, bad property; change the value else if (reference.equals("$a4.foobar")) { assertEquals(new Integer(5),object); assertEquals("foobar",property); return "zzz"; } // bad object, bad method -- fail on the object else if (reference.equals("$zz")) { assertNull(object); assertNull(property); throw new RuntimeException("expected exception"); } // pass q1 through else if (reference.equals("$q1")) { } else if (reference.equals("$tree.x")) { assertEquals("x",property); } else if (reference.equals("$tree.field.x")) { assertEquals("x",property); } else if (reference.equals("$tree.child.y")) { assertEquals("y",property); } else if (reference.equals("$tree.child.Field.y")) { assertEquals("y",property); } else { fail("invalidGetMethod: unexpected reference: " + reference); } return null; } public Object invalidMethod(Context context, String reference, Object object, String method, Info info) { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); // good reference, bad method if (object.getClass().equals(Integer.class)) { if (reference.equals("$a1.afternoon()")) { assertEquals("afternoon",method); throw new RuntimeException("expected exception"); } else if (reference.equals("$!b1.afternoon()")) { assertEquals("afternoon",method); throw new RuntimeException("expected exception"); } else { fail("Unexpected invalid method. " + method); } } else if (object.getClass().equals(String.class) && "baby".equals(method)) { return "www"; } else { fail("Unexpected invalid method. " + method); } return null; } public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info) { // as a test, make sure this EventHandler is initialized if (rs == null) fail ("Event handler not initialized!"); // good object, bad method if (leftreference.equals("xx")) { assertEquals("q1.afternoon()",rightreference); throw new RuntimeException("expected exception"); } if (leftreference.equals("yy")) { assertEquals("$q1",rightreference); throw new RuntimeException("expected exception"); } else { fail("Unexpected left hand side. " + leftreference); } return false; } } public static class Tree { String field; Tree child; public Tree() { } public String getField() { return field; } public void setField(String field) { this.field = field; } public Tree getChild() { return child; } public void setChild(Tree child) { this.child = child; } public String testMethod() { return "123"; } } } velocity-1.7/src/test/org/apache/velocity/test/TemplateTestBase.java0000644000175000017500000000513210513464370025547 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ /** * This is a base interface that contains a bunch of static final * strings that are of use when testing templates. * * @author Jon S. Stevens * @version $Id: TemplateTestBase.java 463298 2006-10-12 16:10:32Z henning $ */ public interface TemplateTestBase { /** * Directory relative to the distribution root, where the * values to compare test results to are stored. */ public static final String TEST_COMPARE_DIR = "@test.dir@"; /** * Directory relative to the distribution root, where the * test cases should put their output */ public static final String TEST_RESULT_DIR = "@build.test@"; /** * VTL file extension. */ public final static String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ public final static String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ public final static String RESULT_FILE_EXT = "res"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ public final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/templates"; /** * Properties file that lists which template tests to run. */ public final static String TEST_CASE_PROPERTIES = FILE_RESOURCE_LOADER_PATH + "/templates.properties"; /** * Results relative to the build directory. */ public final static String RESULT_DIR = TEST_RESULT_DIR + "/templates"; /** * Results relative to the build directory. */ public final static String COMPARE_DIR = FILE_RESOURCE_LOADER_PATH + "/compare"; } velocity-1.7/src/test/org/apache/velocity/test/ResourceExistsTestCase.java0000755000175000017500000000705211057661100026764 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; import org.apache.velocity.test.misc.TestLogChute; /** * Test the resource exists method * * @version $Id: ResourceExistsTestCase.java 687191 2008-08-19 23:02:41Z nbubna $ */ public class ResourceExistsTestCase extends BaseTestCase { private VelocityEngine velocity; private String path = TEST_COMPARE_DIR + "/resourceexists"; private TestLogChute logger = new TestLogChute(); public ResourceExistsTestCase(String name) { super(name); } public void setUp() throws Exception { try { velocity = new VelocityEngine(); velocity.setProperty("resource.loader", "file,string"); velocity.setProperty("file.resource.loader.path", path); velocity.setProperty("string.resource.loader.class", StringResourceLoader.class.getName()); // actual instance of logger logger.on(); velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, logger); velocity.setProperty("runtime.log.logsystem.test.level", "debug"); } catch (Exception e) { System.out.println("exception via gump: "+e); e.printStackTrace(); System.out.println("log: "+logger.getLog()); } } public void testFileResourceExists() throws Exception { try { if (!velocity.resourceExists("testfile.vm")) { String msg = "testfile.vm was not found in path "+path; System.out.println(msg); System.out.println("Log was: "+logger.getLog()); path = path+"/testfile.vm"; java.io.File file = new java.io.File(path); if (file.exists()) { System.out.println("file system found "+path); } else { System.out.println(file+" could not be found as a file"); } fail(msg); } if (velocity.resourceExists("nosuchfile.vm")) { String msg = "nosuchfile.vm should not have been found in path "+path; System.out.println(msg); fail(msg); } } catch (Exception e) { System.out.println("exception via gump: "+e); e.printStackTrace(); System.out.println("log: "+logger.getLog()); } } public void testStringResourceExists() throws Exception { try { assertFalse(velocity.resourceExists("foo.vm")); StringResourceLoader.getRepository().putStringResource("foo.vm", "Make it so!"); assertTrue(velocity.resourceExists("foo.vm")); } catch (Exception e) { System.out.println("exception via gump: "+e); e.printStackTrace(); System.out.println("log: "+logger.getLog()); } } } velocity-1.7/src/test/org/apache/velocity/test/InlineScopeVMTestCase.java0000644000175000017500000000761211273703572026461 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; 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.test.misc.TestLogChute; /** * Tests if the VM template-locality is working. * * @author Geir Magnusson Jr. * @author Daniel Rall * @version $Id: InlineScopeVMTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class InlineScopeVMTestCase extends BaseTestCase implements TemplateTestBase { VelocityEngine engine; public InlineScopeVMTestCase(String name) { super(name); } public void setUp() throws Exception { engine = new VelocityEngine(); engine.setProperty( RuntimeConstants.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL, "true"); engine.setProperty( RuntimeConstants.VM_PERM_INLINE_LOCAL, "true"); engine.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public static Test suite () { return new TestSuite(InlineScopeVMTestCase.class); } /** * Runs the test. */ public void testInlineScopeVM () throws Exception { assureResultsDirectoryExists(RESULT_DIR); /* * Get the template and the output. Do them backwards. * vm_test2 uses a local VM and vm_test1 doesn't */ Template template2 = engine.getTemplate( getFileName(null, "vm_test2", TMPL_FILE_EXT)); Template template1 = engine.getTemplate( getFileName(null, "vm_test1", TMPL_FILE_EXT)); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULT_DIR, "vm_test1", RESULT_FILE_EXT)); FileOutputStream fos2 = new FileOutputStream ( getFileName(RESULT_DIR, "vm_test2", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template1.merge(context, writer1); writer1.flush(); writer1.close(); template2.merge(context, writer2); writer2.flush(); writer2.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"vm_test1", RESULT_FILE_EXT,CMP_FILE_EXT) || !isMatch(RESULT_DIR,COMPARE_DIR,"vm_test2", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Output incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/StrictReferenceTestCase.java0000644000175000017500000002002511322700447027057 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.runtime.RuntimeConstants; /** * Test strict reference mode turned on by the velocity property * runtime.references.strict */ public class StrictReferenceTestCase extends BaseTestCase { public StrictReferenceTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); context.put("NULL", null); context.put("bar", null); context.put("TRUE", Boolean.TRUE); } /** * Test the modified behavior of #if in strict mode. Mainly, that * single variables references in #if statements use non strict rules */ public void testIfStatement() { Fargo fargo = new Fargo(); fargo.next = new Fargo(); context.put("fargo", fargo); assertEvalEquals("", "#if($bogus)xxx#end"); assertEvalEquals("xxx", "#if($fargo)xxx#end"); assertEvalEquals("", "#if( ! $fargo)xxx#end"); assertEvalEquals("xxx", "#if($bogus || $fargo)xxx#end"); assertEvalEquals("", "#if($bogus && $fargo)xxx#end"); assertEvalEquals("", "#if($fargo != $NULL && $bogus)xxx#end"); assertEvalEquals("xxx", "#if($fargo == $NULL || ! $bogus)xxx#end"); assertEvalEquals("xxx", "#if(! $bogus1 && ! $bogus2)xxx#end"); assertEvalEquals("xxx", "#if($fargo.prop == \"propiness\" && ! $bogus && $bar == $NULL)xxx#end"); assertEvalEquals("", "#if($bogus && $bogus.foo)xxx#end"); assertMethodEx("#if($bogus.foo)#end"); assertMethodEx("#if(!$bogus.foo)#end"); } /** * We make sure that variables can actuall hold null * values. */ public void testAllowNullValues() throws Exception { evaluate("$!bar"); assertEvalEquals("true", "#if($bar == $NULL)true#end"); assertEvalEquals("true", "#set($foobar = $NULL)#if($foobar == $NULL)true#end"); assertEvalEquals("13", "#set($list = [1, $NULL, 3])#foreach($item in $list)#if($item != $NULL)$item#end#end"); } /** * Test that variables references that have not been defined throw exceptions */ public void testStrictVariableRef() throws Exception { // We expect a Method exception on the following assertMethodEx("$bogus"); assertMethodEx("#macro(test)$bogus#end #test()"); assertMethodEx("#set($bar = $bogus)"); assertMethodEx("#if($bogus == \"bar\") #end"); assertMethodEx("#if($bogus != \"bar\") #end"); assertMethodEx("#if(\"bar\" == $bogus) #end"); assertMethodEx("#if($bogus > 1) #end"); assertMethodEx("#foreach($item in $bogus)#end"); // make sure no exceptions are thrown here evaluate("#set($foo = \"bar\") $foo"); evaluate("#macro(test1 $foo1) $foo1 #end #test1(\"junk\")"); evaluate("#macro(test2) #set($foo2 = \"bar\") $foo2 #end #test2()"); } /** * Test that exceptions are thrown when methods are called on * references that contains objects that do not contains those * methods. */ public void testStrictMethodRef() { Fargo fargo = new Fargo(); fargo.next = new Fargo(); context.put("fargo", fargo); // Mainly want to make sure no exceptions are thrown here assertEvalEquals("propiness", "$fargo.prop"); assertEvalEquals("", "$!fargo.nullVal"); assertEvalEquals("propiness", "$fargo.next.prop"); assertMethodEx("$fargo.foobar"); assertMethodEx("$fargo.next.foobar"); assertMethodEx("$fargo.foobar()"); assertMethodEx("#set($fargo.next.prop = $TRUE)"); assertMethodEx("$fargo.next.setProp($TRUE)"); } /** * Make sure exceptions are thrown when when we attempt to call * methods on null values. */ public void testStrictMethodOnNull() { Fargo fargo = new Fargo(); fargo.next = new Fargo(); context.put("fargo", fargo); assertVelocityEx("$NULL.bogus"); assertVelocityEx("$fargo.nullVal.bogus"); assertVelocityEx("$fargo.next.nullVal.bogus"); assertVelocityEx("#if (\"junk\" == $fargo.nullVal.bogus)#end"); assertVelocityEx("#if ($fargo.nullVal.bogus > 2)#end"); assertVelocityEx("#set($fargo.next.nullVal.bogus = \"junk\")"); assertVelocityEx("#set($foo = $NULL.bogus)"); assertVelocityEx("#foreach($item in $fargo.next.nullVal.bogus)#end"); evaluate("$fargo.prop.toString()"); assertVelocityEx("#set($fargo.prop = $NULL)$fargo.prop.next"); // make sure no exceptions are thrown here evaluate("$!fargo.next.next"); evaluate("$!fargo.next.nullVal"); evaluate("#foreach($item in $fargo.nullVal)#end"); } /** * Make sure undefined macros throw exceptions */ public void testMacros() { assertVelocityEx("#bogus()"); assertVelocityEx("#bogus ( )"); assertVelocityEx("#bogus( $a )"); assertVelocityEx("abc#bogus ( $a )a "); assertEvalEquals(" true ", "#macro(test1) true #end#test1()"); assertEvalEquals(" true ", "#macro(test2 $a) $a #end#test2 ( \"true\")"); assertEvalEquals("#CCFFEE", "#CCFFEE"); assertEvalEquals("#F - ()", "#F - ()"); assertEvalEquals("#F{}", "#F{}"); } public void testRenderingNull() { Fargo fargo = new Fargo(); fargo.next = new Fargo(); context.put("fargo", fargo); assertVelocityEx("#set($foo = $NULL)$foo"); assertEvalEquals("", "#set($foo = $NULL)$!foo"); assertVelocityEx("$fargo.nullVal"); assertEvalEquals("", "$!fargo.nullVal"); assertVelocityEx("$fargo.next.next"); assertEvalEquals("", "$!fargo.next.next"); assertVelocityEx("$fargo.next.nullVal"); assertEvalEquals("", "$!fargo.next.nullVal"); } /** * Assert that we get a MethodInvocationException when calling evaluate */ public void assertMethodEx(String template) { assertEvalException(template, MethodInvocationException.class); } /** * Assert that we get a VelocityException when calling evaluate */ public void assertVelocityEx(String template) { assertEvalException(template, VelocityException.class); } /** * Assert that we get a MethodInvocationException when calling evaluate */ public void assertParseEx(String template) { assertEvalException(template, ParseErrorException.class); } public static class Fargo { String prop = "propiness"; Fargo next = null; public String getProp() { return prop; } public void setProp(String val) { this.prop = val; } public String getNullVal() { return null; } public Fargo getNext() { return next; } } } velocity-1.7/src/test/org/apache/velocity/test/IfNullTestCase.java0000755000175000017500000001017711243536636025204 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.VelocityContext; import org.apache.velocity.runtime.RuntimeConstants; /** * Used to check that nulls are properly handled in #if statements */ public class IfNullTestCase extends BaseTestCase { public IfNullTestCase(final String name) { super(name); } protected void setUpContext(VelocityContext context) { context.put("nullToString", new NullToString()); context.put("notnull", new Object()); } public void testIfEquals() { // both null assertEvalEquals("foo", "#if( $null == $otherNull )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $null == $nullToString )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $nullToString == $null )foo#{else}bar#end"); // left null, right not assertEvalEquals("bar", "#if( $nullToString == $notnull )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $null == $notnull )foo#{else}bar#end"); // right null, left not assertEvalEquals("bar", "#if( $notnull == $nullToString )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $notnull == $null )foo#{else}bar#end"); } public void testIfNotEquals() { // both null assertEvalEquals("bar", "#if( $null != $otherNull )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $null != $nullToString )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $nullToString != $null )foo#{else}bar#end"); // left null, right not assertEvalEquals("foo", "#if( $nullToString != $notnull )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $null != $notnull )foo#{else}bar#end"); // right null, left not assertEvalEquals("foo", "#if( $notnull != $nullToString )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $notnull != $null )foo#{else}bar#end"); } public void testIfValue() { assertEvalEquals("bar", "#if( $null )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $nullToString )foo#{else}bar#end"); assertEvalEquals("foo", "#if( !$null )foo#{else}bar#end"); assertEvalEquals("foo", "#if( !$nullToString )foo#{else}bar#end"); } public void testIfAnd() { assertEvalEquals("bar", "#if( $null && $nullToString )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $nullToString && $null )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $null && $notnull )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $notnull && $nullToString )foo#{else}bar#end"); } public void testIfOr() { assertEvalEquals("bar", "#if( $null || $nullToString )foo#{else}bar#end"); assertEvalEquals("bar", "#if( $nullToString || $null )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $null || $notnull )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $notnull || $nullToString )foo#{else}bar#end"); } public void testToStringNullCheckConfig() { engine.setProperty(RuntimeConstants.DIRECTIVE_IF_TOSTRING_NULLCHECK, Boolean.FALSE); assertEvalEquals("bar", "#if( $null )foo#{else}bar#end"); assertEvalEquals("foo", "#if( $nullToString )foo#{else}bar#end"); } public static class NullToString { public String toString() { return null; } } } velocity-1.7/src/test/org/apache/velocity/test/CommentsTestCase.java0000644000175000017500000000614210663467564025602 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; /** * Test comments * * @author Will Glass-Husain * @version $Id: CommentsTestCase.java 569256 2007-08-24 05:41:08Z wglass $ */ public class CommentsTestCase extends BaseTestCase { public static Test suite() { return new TestSuite(CommentsTestCase.class); } /** * Default constructor. * @param name */ public CommentsTestCase(String name) { super(name); } /** * Test multiline comments * @throws Exception */ public void testMultiLine() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); Context context = new VelocityContext(); StringWriter writer = new StringWriter(); ve.evaluate(context, writer, "test","abc #* test\r\ntest2*#\r\ndef"); assertEquals("abc \r\ndef", writer.toString()); } /** * Test single line comments * @throws Exception */ public void testSingleLine() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); Context context = new VelocityContext(); StringWriter writer = new StringWriter(); ve.evaluate(context, writer, "test","123 ## test test\r\nabc"); assertEquals("123 abc", writer.toString()); context = new VelocityContext(); writer = new StringWriter(); ve.evaluate(context, writer, "test","123 \r\n## test test\r\nabc"); assertEquals("123 \r\nabc", writer.toString()); } /** * Test combined comments * @throws Exception */ public void testCombined() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); Context context = new VelocityContext(); StringWriter writer = new StringWriter(); ve.evaluate(context, writer, "test","test\r\n## #* *# ${user \r\nabc"); assertEquals("test\r\nabc", writer.toString()); } } velocity-1.7/src/test/org/apache/velocity/test/MethodInvocationExceptionTestCase.java0000644000175000017500000001710511075007114031122 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.test.misc.TestLogChute; /** * Tests if we can hand Velocity an arbitrary class for logging. * * @author Geir Magnusson Jr. * @version $Id: MethodInvocationExceptionTestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class MethodInvocationExceptionTestCase extends TestCase { protected boolean DEBUG = false; /** * Default constructor. * @param name */ public MethodInvocationExceptionTestCase(String name) { super(name); } public void setUp() throws Exception { /* * init() Runtime with defaults */ Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public static Test suite () { return new TestSuite(MethodInvocationExceptionTestCase.class); } protected void log(String out) { Velocity.getLog().debug(out); if (DEBUG) { System.out.println(out); } } /** * Runs the test : * * uses the Velocity class to eval a string * which accesses a method that throws an * exception. * @throws Exception */ public void testNormalMethodInvocationException () throws Exception { String template = "$woogie.doException() boing!"; VelocityContext vc = new VelocityContext(); vc.put("woogie", this ); StringWriter w = new StringWriter(); try { Velocity.evaluate( vc, w, "test", template ); fail("No exception thrown"); } catch( MethodInvocationException mie ) { log("Caught MIE (good!) :" ); log(" reference = " + mie.getReferenceName() ); log(" method = " + mie.getMethodName() ); Throwable t = mie.getWrappedThrowable(); log(" throwable = " + t ); if( t instanceof Exception) { log(" exception = " + ( (Exception) t).getMessage() ); } } } public void testGetterMethodInvocationException () throws Exception { VelocityContext vc = new VelocityContext(); vc.put("woogie", this ); StringWriter w = new StringWriter(); /* * second test - to ensure that methods accessed via get+ construction * also work */ String template = "$woogie.foo boing!"; try { Velocity. evaluate( vc, w, "test", template ); fail("No exception thrown, second test."); } catch( MethodInvocationException mie ) { log("Caught MIE (good!) :" ); log(" reference = " + mie.getReferenceName() ); log(" method = " + mie.getMethodName() ); Throwable t = mie.getWrappedThrowable(); log(" throwable = " + t ); if( t instanceof Exception) { log(" exception = " + ( (Exception) t).getMessage() ); } } } public void testCapitalizedGetterMethodInvocationException () throws Exception { VelocityContext vc = new VelocityContext(); vc.put("woogie", this ); StringWriter w = new StringWriter(); String template = "$woogie.Foo boing!"; try { Velocity. evaluate( vc, w, "test", template ); fail("No exception thrown, third test."); } catch( MethodInvocationException mie ) { log("Caught MIE (good!) :" ); log(" reference = " + mie.getReferenceName() ); log(" method = " + mie.getMethodName() ); Throwable t = mie.getWrappedThrowable(); log(" throwable = " + t ); if( t instanceof Exception) { log(" exception = " + ( (Exception) t).getMessage() ); } } } public void testSetterMethodInvocationException () throws Exception { VelocityContext vc = new VelocityContext(); vc.put("woogie", this ); StringWriter w = new StringWriter(); String template = "#set($woogie.foo = 'lala') boing!"; try { Velocity. evaluate( vc, w, "test", template ); fail("No exception thrown, set test."); } catch( MethodInvocationException mie ) { log("Caught MIE (good!) :" ); log(" reference = " + mie.getReferenceName() ); log(" method = " + mie.getMethodName() ); Throwable t = mie.getWrappedThrowable(); log(" throwable = " + t ); if( t instanceof Exception) { log(" exception = " + ( (Exception) t).getMessage() ); } } } /** * test that no exception is thrown when in parameter to macro. * This is the way we expect the system to work, but it would be better * to throw an exception. * @throws Exception */ public void testMacroInvocationException () throws Exception { VelocityContext vc = new VelocityContext(); vc.put("woogie", this ); StringWriter w = new StringWriter(); String template = "#macro (macro1 $param) $param #end #macro1($woogie.getFoo())"; try { Velocity. evaluate( vc, w, "test", template ); fail("No exception thrown, macro invocation test."); } catch( MethodInvocationException mie ) { log("Caught MIE (good!) :" ); log(" reference = " + mie.getReferenceName() ); log(" method = " + mie.getMethodName() ); Throwable t = mie.getWrappedThrowable(); log(" throwable = " + t ); if( t instanceof Exception) { log(" exception = " + ( (Exception) t).getMessage() ); } } catch( Exception e) { fail("Wrong exception thrown, test of exception within macro parameter"); } } public void doException() throws Exception { throw new NullPointerException(); } public void getFoo() throws Exception { throw new Exception("Hello from getFoo()" ); } public void setFoo( String foo ) throws Exception { throw new Exception("Hello from setFoo()"); } } velocity-1.7/src/test/org/apache/velocity/test/Introspector3TestCase.java0000644000175000017500000001014210513464370026550 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeSingleton; /** * Simple introspector test case for primitive problem found in 1.3 * * @author Geir Magnusson Jr. * @version $Id: Introspector3TestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class Introspector3TestCase extends BaseTestCase { /** * Creates a new instance. */ public Introspector3TestCase(String name) { super(name); } public static Test suite() { return new TestSuite(Introspector3TestCase.class); } public void testSimple() throws Exception { Method method; String result; MethodProvider mp = new MethodProvider(); /* * string integer */ Object[] listIntInt = { new ArrayList(), new Integer(1), new Integer(2) }; Object[] listLongList = { new ArrayList(), new Long(1), new ArrayList() }; Object[] intInt = { new Integer(1), new Integer(2) }; Object[] longInt = { new Long(1), new Integer(2) }; Object[] longLong = { new Long(1), new Long(2) }; method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "lii", listIntInt); result = (String) method.invoke(mp, listIntInt); assertTrue(result.equals("lii")); method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "ii", intInt); result = (String) method.invoke(mp, intInt); assertTrue(result.equals("ii")); method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "ll", longInt); result = (String) method.invoke(mp, longInt); assertTrue(result.equals("ll")); /* * test overloading with primitives */ method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "ll", longLong); result = (String) method.invoke(mp, longLong); assertTrue(result.equals("ll")); method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "lll", listLongList); result = (String) method.invoke(mp, listLongList); assertTrue(result.equals("lll")); /* * test invocation with nulls */ Object [] oa = {null, new Integer(0)}; method = RuntimeSingleton.getIntrospector().getMethod( MethodProvider.class, "lll", oa ); result = (String) method.invoke(mp, oa); assertTrue(result.equals("Listl")); } public static class MethodProvider { public String ii(int p, int d) { return "ii"; } public String lii(List s, int p, int d) { return "lii"; } public String lll(List s, long p, List d) { return "lll"; } public String lll(List s, long p, int d) { return "lli"; } public String lll(List s, long p) { return "Listl"; } public String ll(long p, long d) { return "ll"; } } } velocity-1.7/src/test/org/apache/velocity/test/InfoTestCase.java0000644000175000017500000000664310513464370024700 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.test.misc.UberspectTestException; import org.apache.velocity.util.introspection.Info; /** * Test that the Info class in the Introspector holds the correct information. * * @author Will Glass-Husain * @author Llewellyn Falco * @version $Id: InfoTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class InfoTestCase extends BaseTestCase implements TemplateTestBase { VelocityEngine ve; /** * Default constructor. */ public InfoTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(InfoTestCase.class); } public void setUp() throws Exception { ve = new VelocityEngine(); ve.setProperty( "runtime.introspector.uberspect", "org.apache.velocity.test.misc.UberspectTestImpl"); ve.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, "test/info"); ve.init(); } public void testInfoProperty() throws Exception { // check property checkInfo("info1.vm", 1, 7); } public void testInfoMethod() throws Exception { // check method checkInfo("info2.vm", 1, 7); } public void checkInfo(String templateName, int expectedLine, int expectedCol) throws Exception { Context context = new VelocityContext(); StringWriter writer = new StringWriter(); Template template = ve.getTemplate(templateName, "UTF-8"); Info info = null; context.put("main", this); try { template.merge(context, writer); writer.flush(); fail("Uberspect should have thrown an exception"); } catch (UberspectTestException E) { info = E.getInfo(); } finally { writer.close(); } assertInfoEqual(info, templateName, expectedLine, expectedCol); } private void assertInfoEqual(Info i, String name, int line, int column) { assertEquals("Template Name", name, i.getTemplateName()); assertEquals("Template Line", line, i.getLine()); assertEquals("Template Column", column, i.getColumn()); } } velocity-1.7/src/test/org/apache/velocity/test/TexenClasspathTestCase.java0000644000175000017500000000454110513464370026726 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import junit.framework.Test; import junit.framework.TestSuite; /** * This is a test case for Texen. Simply executes a simple * generative task and compares the output. * * @author Jason van Zyl * @version $Id: TexenClasspathTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class TexenClasspathTestCase extends BaseTestCase { /** * Directory where results are generated. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/texen-classpath"; /** * Directory where comparison output is stored. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/texen-classpath/compare"; /** * Creates a new instance. * */ public TexenClasspathTestCase(String name) { super(name); } public static Test suite() { return new TestSuite(TexenClasspathTestCase.class); } /** * Runs the test. */ public void testTexenClasspath () throws Exception { assureResultsDirectoryExists(RESULTS_DIR); if (!isMatch(RESULTS_DIR,COMPARE_DIR,"TurbineWeather","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"TurbineWeatherService","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"WeatherService","java","java") || !isMatch(RESULTS_DIR,COMPARE_DIR,"book","txt","txt") || !isMatch(RESULTS_DIR,COMPARE_DIR,"Test","txt","txt")) { fail("Output is incorrect!"); } } } velocity-1.7/src/test/org/apache/velocity/test/VMContextLocalscopeTestCase.java0000644000175000017500000000541511150640003027660 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.VelocityContext; import org.apache.velocity.context.InternalContextAdapterImpl; import org.apache.velocity.context.ProxyVMContext; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeInstance; /** * Tests scope of velocimacros with localscope setting. * * @author Stephen Habermann * @version $Id: VMContextLocalscopeTestCase.java 747235 2009-02-24 00:32:03Z nbubna $ */ public class VMContextLocalscopeTestCase extends BaseTestCase { public VMContextLocalscopeTestCase(String name) { super(name); } public void testViaEval() { engine.setProperty(RuntimeConstants.VM_CONTEXT_LOCALSCOPE, Boolean.TRUE); assertEvalEquals("$a", "#macro(a)#set($a = 'b')#end#a$a"); context.put("b", "b"); assertEvalEquals("b", "#macro(b)$b#set($b = 'c')#end#b"); assertContextValue("b", "b"); } public void testLocalscopePutDoesntLeakButGetDoes() { RuntimeInstance instance = new RuntimeInstance(); instance.setProperty(RuntimeConstants.VM_CONTEXT_LOCALSCOPE, Boolean.TRUE); instance.init(); VelocityContext base = new VelocityContext(); base.put("outsideVar", "value1"); ProxyVMContext vm = new ProxyVMContext(new InternalContextAdapterImpl(base), instance, true); vm.put("newLocalVar", "value2"); // New variable put doesn't leak assertNull(base.get("newLocalVar")); assertEquals("value2", vm.get("newLocalVar")); // But we can still get to "outsideVar" assertEquals("value1", vm.get("outsideVar")); // If we decide to try and set outsideVar it won't leak vm.put("outsideVar", "value3"); assertEquals("value3", vm.get("outsideVar")); assertEquals("value1", base.get("outsideVar")); } } velocity-1.7/src/test/org/apache/velocity/test/DefineTestCase.java0000755000175000017500000000650011322700447025167 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ /** * This class tests the #define directive */ public class DefineTestCase extends BaseTestCase { public DefineTestCase(String name) { super(name); } protected String defAndEval(String block) { return defAndEval("def", block); } protected String defAndEval(String key, String block) { return evaluate("#define( $"+key+" )"+block+"#end$"+key); } public void testSimple() { assertEquals("abc", defAndEval("abc")); assertEvalEquals("abc abc abc", "#define( $a )abc#end$a $a $a"); } public void testNotSimple() { assertEquals("true", defAndEval("#if( $def )true#end")); assertEquals("123", defAndEval("#foreach( $i in [1..3] )$i#end")); assertEquals("hello world", defAndEval("#macro( test )hello world#end#test()")); } public void testOverridingDefinitionInternally() { assertEvalEquals("truefalse", "#define( $or )true#set( $or = false )#end$or$or"); } public void testLateBinding() { context.put("baz", "foo"); assertEvalEquals("foobar", "#define( $lb )$baz#end${lb}#set( $baz = 'bar' )${lb}"); } public void testRerendering() { context.put("inc", new Inc()); assertEvalEquals("1 2 3", "#define( $i )$inc#end$i $i $i"); } public void testAssignation() { assertEvalEquals("[][hello]","#define( $orig )hello#end[#set( $assig = $orig )][$assig]"); } public void testNonRenderingUsage() { String template = "#define($foo)\n" + " foo_contents\n" + "#end\n" + "#if ($foo)\n" + " found foo\n" + "#end"; assertEvalEquals(" found foo\n", template); } public void testRecursionLimit() { try { assertEvalEquals("$r", "#define( $r )$r#end$r"); } catch (Exception t) { fail("Recursion should not have thrown an exception"); } catch (Error e) { fail("Infinite recursion should not be possible."); } } public void testThingsOfQuestionableMorality() { // redefining $foo within $foo assertEquals("foobar", defAndEval("foo", "foo#define( $foo )bar#end$foo")); } public static class Inc { int foo = 1; public String toString() { return String.valueOf(foo++); } } } velocity-1.7/src/test/org/apache/velocity/test/ParserTestCase.java0000644000175000017500000001161710513464370025236 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import java.util.Map; import java.util.HashMap; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ParseErrorException; /** * More specific parser tests where just templating * isn't enough. * * @author Geir Magnusson Jr. * @version $Id: ParserTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class ParserTestCase extends TestCase { public ParserTestCase(String testName) { super(testName); } public static Test suite() { return new TestSuite(ParserTestCase.class); } /** * Test to make sure that using '=' in #if() throws a PEE */ public void testEquals() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); /* * this should parse fine -> uses == */ String template = "#if($a == $b) foo #end"; ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); /* * this should throw an exception */ template = "#if($a = $b) foo #end"; try { ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); fail("Could evaluate template with errors!"); } catch(ParseErrorException pe) { // Do nothing } } /** * Test to see if we force the first arg to #macro() to be a word */ public void testMacro() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); /* * this should work */ String template = "#macro(foo) foo #end"; ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); /* * this should throw an exception */ template = "#macro($x) foo #end"; try { ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); fail("Could evaluate macro with errors!"); } catch(ParseErrorException pe) { // Do nothing } } /** * Test to see if don't tolerage passing word tokens in anything but the * 0th arg to #macro() and the 1th arg to foreach() */ public void testArgs() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); /* * this should work */ String template = "#macro(foo) foo #end"; ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); /* * this should work - spaces intentional */ template = "#foreach( $i in $woogie ) end #end"; ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); /* * this should bomb */ template = "#macro( foo $a) $a #end #foo(woogie)"; try { ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template); fail("Evaluation of macro with errors succeeded!"); } catch(ParseErrorException pe) { // Do nothing } } /** * Test to see if we toString is called multiple times on references. */ public void testASTReferenceToStringOnlyCalledOnce() throws Exception { VelocityEngine ve = new VelocityEngine(); ve.init(); String template = "$counter"; ToStringCounter counter = new ToStringCounter(); Map m = new HashMap(); m.put("counter", counter); ve.evaluate(new VelocityContext(m), new StringWriter(), "foo", template); assertEquals(1, counter.timesCalled); } public static class ToStringCounter { public int timesCalled = 0; public String toString() { this.timesCalled++; return "foo"; } } } velocity-1.7/src/test/org/apache/velocity/test/issues/0000755000175000017500000000000011675166247023024 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/issues/Velocity689TestCase.java0000755000175000017500000000350611322700447027360 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.VelocityContext; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-689. */ public class Velocity689TestCase extends BaseTestCase { public Velocity689TestCase(String name) { super(name); //DEBUG = true; } public void setUpContext(VelocityContext ctx) { ctx.put("foo", new Foo()); } public void testIt() { String template = "$foo.baz, $foo.bar"; assertEvalEquals("baz, bar", template); } public static interface HasMethod { String getBar(); } public static interface HasOtherMethod extends HasMethod { String getBaz(); } public static interface NoMethod extends HasOtherMethod { // nada! } private static class Foo implements NoMethod { public String getBar() { return "bar"; } public String getBaz() { return "baz"; } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity62TestCase.java0000755000175000017500000000401711322700447027257 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-62. */ public class Velocity62TestCase extends BaseTestCase { public Velocity62TestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.VM_CONTEXT_LOCALSCOPE, Boolean.TRUE); context.put("foo", "foo"); } public void testNested() { String template = "#macro( outer )#set( $foo = 'bar' )#inner()#end"+ "#macro( inner )$foo#end"+ "#inner()#outer()#inner()"; assertEvalEquals("foobarfoo", template); } public void testRecursive() { context.put("i", new Integer(1)); String template = "#macro( recurse )"+ "$i"+ "#if( $i < 5 )"+ "#set( $i = $i + 1 )"+ "#recurse()"+ "#end"+ "#end"+ "#recurse()"; assertEvalEquals("12345", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/VelTools66TestCase.java0000644000175000017500000001026311075007114027225 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import java.lang.reflect.Method; import java.security.AccessControlException; import java.security.Permission; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.util.introspection.Introspector; /** * Test Case for Velocity Tools Issue 66. */ public class VelTools66TestCase extends BaseTestCase { protected static boolean DEBUG = false; public VelTools66TestCase(final String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(VelTools66TestCase.class); } public void setUp() throws Exception { Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); System.setSecurityManager(new TestSecurityManager()); } protected static void log(String out) { Velocity.getLog().debug(out); if (DEBUG) { System.out.println(out); } } public void tearDown() { System.setSecurityManager(null); } public void testVelTools66() throws Exception { Method verifyMethod = TestInterface.class.getMethod("getTestValue", new Class[0]); RuntimeInstance ri = new RuntimeInstance(); Introspector introspector = ri.getIntrospector(); Method testMethod = introspector.getMethod(TestObject.class, "getTestValue", new Object[0]); assertNotNull(testMethod); assertEquals("Method object does not match!", verifyMethod, testMethod); } public static interface TestInterface { String getTestValue(); void setTestValue(String testValue); } public static final class TestObject implements TestInterface { String testValue = null; public TestObject() { } public String getTestValue() { return testValue; } public void setTestValue(final String testValue) { this.testValue = testValue; } } public static final class TestSecurityManager extends SecurityManager { private final Class clazz = TestObject.class; public TestSecurityManager() { super(); } public void checkMemberAccess(final Class c, final int i) { log("checkMemberAccess(" + c.getName() + ", " + i + ")"); if (c.equals(clazz)) { throw new AccessControlException("You are not allowed to access TestObject directly!"); } } public void checkRead(final String file) { log("checkRead(" + file + ")"); } public void checkPackageAccess(final String s) { log("checkPackageAccess(" + s + ")"); } public void checkPropertyAccess(final String s) { log("checkPropertyAccess(" + s + ")"); } public void checkPermission(final Permission p) { log("checkPermission(" + p + ")"); } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity701TestCase.java0000755000175000017500000000347611322700447027347 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-701. */ public class Velocity701TestCase extends BaseTestCase { public Velocity701TestCase(String name) { super(name); //DEBUG = true; } public void testAbstractClass() { context.put("foo", new Foo() { public String getBar() { return "bar"; } }); assertEvalEquals("bar", "$foo.bar"); } public static abstract class Foo { public abstract String getBar(); } /* TODO: uncomment for jdk 1.5+ public void testEnum() { context.put("bar", Bar.ONE); assertEvalEquals("foo", "$bar.foo"); } public static enum Bar { ONE(){ public String getFoo() { return "foo"; } }; //This was an abstract method, but Velocity 1.6 quit working with it. public abstract String getFoo(); }*/ } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity630TestCase.java0000755000175000017500000000327611322700447027346 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-630. */ public class Velocity630TestCase extends BaseTestCase { public Velocity630TestCase(String name) { super(name); DEBUG = false; } public void test630() { // this template is logically equivalent to the demo in VELOCITY-630 String template = "#macro( test $a )" + "#foreach( $i in [1..3] )" + "$a" + "#end" + "#end" + "#test( \"#if($i == 2)" + " yes" + "#else" + " no" + "#end\" )"; assertEvalEquals(" no yes no", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity614TestCase.java0000755000175000017500000000561511142425303027342 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-614. */ public class Velocity614TestCase extends BaseTestCase { public Velocity614TestCase(String name) { super(name); } public void testSchmoo() { String template = "#something(Stuff)"; assertEvalEquals(template, template); } public void testEscapeSchmooButNotReallySinceSchmooHasNoEscaping() { String template = "\\#something(Stuff)"; assertEvalEquals(template, template); } public void testEscapeMacroWithBadArg() { String template = "#macro( evil $arg )$arg#end \\#evil(bar)"; assertEvalEquals(" #evil(bar)", template); } public void testEarlyDefinedMacroWithBadArg() { // make sure this still bombs, but don't spam sysout log.off(); assertEvalException("#macro( evil $arg )$arg#end #evil(bar)"); log.on(); } // just make sure this doesn't get broken public void testLateDefinedMacroWithGoodArg() { String good = "#good('bar') #macro( good $arg )$arg#end"; assertEvalEquals("bar ", good); } public void testDirectivesWithBadArg() { // make sure these all still bomb, but don't spam sysout log.off(); assertEvalException("#foreach(Stuff in That)foo#end"); assertEvalException("#include(Stuff)"); assertEvalException("#parse(Stuff)"); assertEvalException("#define(Stuff)foo#end"); assertEvalException("#macro( name Stuff)foo#end"); assertEvalException("#foreach($i in [1..3])#break(Stuff)#end"); assertEvalException("#literal(Stuff)foo#end"); assertEvalException("#evaluate(Stuff)", ParseErrorException.class); log.on(); } public void testLateDefinedMacroWithBadArg() { String evil = "#evil(bar) #macro( evil $arg )$arg#end"; assertEvalException(evil, TemplateInitException.class); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity616TestCase.java0000755000175000017500000000404511142425303027340 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-616. */ public class Velocity616TestCase extends BaseTestCase { public Velocity616TestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); context.put("bar", "bar"); context.put("foo", Boolean.FALSE); } public void testIfNoBrackets() { String template = "\\#if ($foo) \\$bar \\#end"; String expected = "#if (false) $bar #end"; assertEvalEquals(expected, template); } public void testForeachBrackets() { String template = "\\#{foreach}( $i in [1..3] )$i\\#{end}"; String expected = "#{foreach}( $i in [1..3] )$i#{end}"; assertEvalEquals(expected, template); } public void testIfBrackets() { String template = "\\#{if} ($foo) \\$bar \\#{end}"; String expected = "#{if} (false) $bar #{end}"; assertEvalEquals(expected, template); } public void testIfBracketsOnEndOnly() { String template = "\\#if( $foo ) \\$bar \\#{end}"; String expected = "#if( false ) $bar #{end}"; assertEvalEquals(expected, template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity644TestCase.java0000644000175000017500000000400511142425303027332 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests VELOCITY-644. Make sure the reported filename * is correct in exceptions when an error occurs in another template file. */ public class Velocity644TestCase extends BaseTestCase { public Velocity644TestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "test/templates/"); engine.setProperty(RuntimeConstants.VM_LIBRARY, "testCase644.vm"); engine.setProperty(RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE); context.put("NULL", null); } public void test629() { // Calling a null method assertEvalExceptionAt("#nullMethod()", "testCase644.vm", 9, 8); // An invalid array assertEvalExceptionAt("#arrayError()", "testCase644.vm", 4, 8); // An invalid reference assertEvalExceptionAt("#badRef()", "testCase644.vm", 13, 3); // Non iterable object assertEvalExceptionAt("#forloop()", "testCase644.vm", 18, 18); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity753TestCase.java0000755000175000017500000000351711354303320027344 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import java.text.NumberFormat; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-753. */ public class Velocity753TestCase extends BaseTestCase { public Velocity753TestCase(String name) { super(name); } public void testFloatArg() throws Exception { // verify precedence outside of Velocity Tool tool = new Tool(); Float f = new Float(5.23); assertEquals("object", tool.test(f)); context.put("tool", tool); context.put("float", f); String template = "$tool.test($float)"; // in reflection-land, Float and float are equivalent, so double is selected assertEvalEquals("double", template); } public static class Tool { public String test(double d) { return "double"; } public String test(Object o) { return "object"; } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity537TestCase.java0000755000175000017500000000766211322700447027357 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.test.misc.TestLogChute; /** * Test Case for Velocity Issue 537. */ public class Velocity537TestCase extends BaseTestCase { /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/issues/velocity-537"; /** * Template Directory */ private static final String TEMPLATE_DIR = TEST_COMPARE_DIR + "/issues/velocity-537/templates"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/issues/velocity-537/compare"; public Velocity537TestCase(final String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(Velocity537TestCase.class); } private VelocityEngine velocityEngine; public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); velocityEngine = new VelocityEngine(); velocityEngine.addProperty(Velocity.FILE_RESOURCE_LOADER_PATH, TEMPLATE_DIR); velocityEngine.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); velocityEngine.init(); } public void testVelocity537() throws Exception { executeTest("velocity537.vm"); } public void testVelocity537Again() throws Exception { executeTest("velocity537b.vm"); } protected Template executeTest(final String templateName) throws Exception { Template template = velocityEngine.getTemplate(templateName); FileOutputStream fos = new FileOutputStream(getFileName(RESULTS_DIR, templateName, RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, templateName, RESULT_FILE_EXT, CMP_FILE_EXT)) { // just to be useful, output the output in the fail message StringWriter out = new StringWriter(); template.merge(context, out); String compare = getFileContents(COMPARE_DIR, templateName, CMP_FILE_EXT); fail("Output incorrect for Template: " + templateName + ": \""+out+"\""+ "; it did not match: \""+compare+"\""); } return template; } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity727TestCase.java0000644000175000017500000000241611317163206027345 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.VelocityException; /** * This class tests VELOCITY-727. */ public class Velocity727TestCase extends BaseTestCase { public Velocity727TestCase(String name) { super(name); DEBUG = false; } public void testDefineWithNoArgument() { assertEvalException("#define() foo bar #end", VelocityException.class); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity709TestCase.java0000644000175000017500000000343511353715726027361 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.VelocityException; /** * This class tests VELOCITY-709. */ public class Velocity709TestCase extends BaseTestCase { public Velocity709TestCase(String name) { super(name); // DEBUG = true; } public void testEscapedBackslashInSetDirective() { String backslash = "\\"; String template = "#set($var = \"" + backslash + "\" )#set($var2 = \"${var}\")$var2"; System.out.println(template); assertEvalEquals("\\", template); } public void testEscapedDoubleQuote() { String template = "#set($foo = \"jeah \"\"baby\"\" jeah! \"\"\"\"\")$foo"; assertEvalEquals("jeah \"baby\" jeah! \"\"", template); } public void testEscapedSingleQuote() { String template = "#set($foo = 'jeah ''baby'' jeah!')$foo"; assertEvalEquals("jeah 'baby' jeah!", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity682TestCase.java0000644000175000017500000000413711142425303027342 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests VELOCITY-682. */ public class Velocity682TestCase extends BaseTestCase { public Velocity682TestCase(String name) { super(name); //DEBUG = true; } public void test682() { engine.setProperty(RuntimeConstants.VM_PERM_INLINE_LOCAL, Boolean.TRUE); assertEvalEquals("foo1foo2", "#macro(eval $e)#evaluate($e)#end#eval('foo1')#eval('foo2')"); } public void test682b() { String template = "#macro( eval $e )#evaluate($e)#end" + "#eval('foo')" + "#eval('bar')"; String expected = "foo"+ "bar"; assertEvalEquals(expected, template); } public void test682c() { //NOTE: #eval call is apparently swallowing preceding newlines. :( // appears to be a parser issue unrelated to VELOCITY-682 String template = "#macro( eval $e )#evaluate($e)#end" + "\n#eval('foo')" + "\n\n#eval('bar')"; String expected = "foo"+ "\nbar"; assertEvalEquals(expected, template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity755TestCase.java0000755000175000017500000000252711353722777027372 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-755. */ public class Velocity755TestCase extends BaseTestCase { public Velocity755TestCase(String name) { super(name); } public void testMapOrder() { String template = "#set( $map = {'a': 1, 'b': true, 'c': 3, 'd': false, 'e': 5} )"+ "#foreach( $i in $map )$i#end"; assertEvalEquals("1true3false5", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity729TestCase.java0000644000175000017500000000265511352464351027360 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.VelocityException; /** * This class tests VELOCITY-729. */ public class Velocity729TestCase extends BaseTestCase { public Velocity729TestCase(String name) { super(name); // DEBUG = true; } public void testDotRightAfterDollarReference() { String s = "$.x schmoo $jee"; context.put("jee", "foo"); assertEvalEquals("$.x schmoo foo", s); } public void testVelocity754jQueryPost() { assertSchmoo("$.post(\"someUrl\", \"\")"); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity785TestCase.java0000644000175000017500000000276511465334133027363 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.VelocityException; /** * This class tests VELOCITY-785. */ public class Velocity785TestCase extends BaseTestCase { public Velocity785TestCase(String name) { super(name); // DEBUG = true; } public void testQuoteEscapes() { assertEvalEquals("\"", "#set($double_double = \"\"\"\")$double_double"); assertEvalEquals("'", "#set($single_single = '''')$single_single"); assertEvalEquals("''", "#set($double_single = \"''\")$double_single"); assertEvalEquals("\"\"", "#set($single_double = '\"\"')$single_double"); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity587TestCase.java0000755000175000017500000000373311142425303027352 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-587. */ public class Velocity587TestCase extends BaseTestCase { public Velocity587TestCase(String name) { super(name); } // remember, they're all doubled, since java will use them as escapes first. public void testLiteralTwoBackslashes() { String template = "#set( $bs2 = \'\\\\\' )$bs2"; String expected = "\\\\"; assertEvalEquals(expected, template); } public void testLiteralOneBackslash() { String template = "#set( $bs = \'\\\' )$bs"; String expected = "\\"; assertEvalEquals(expected, template); } // remember, they're all doubled, since java will use them as escapes first. public void testInterpolatedTwoBackslashes() { String template = "#set( $bs2 = \"\\\\\" )$bs2"; String expected = "\\\\"; assertEvalEquals(expected, template); } public void testInterpolatedOneBackslash() { String template = "#set( $bs = \"\\\" )$bs"; String expected = "\\"; assertEvalEquals(expected, template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity579TestCase.java0000755000175000017500000000444611142425303027355 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-579 and with some related stuff * from VELOCITY-70 thrown in. */ public class Velocity579TestCase extends BaseTestCase { public Velocity579TestCase(String name) { super(name); } public void testPublicMethodInPrivateImplOfPublicInterface() { context.put("foo", new Foobar()); assertEvalEquals("bar", "$foo.foo('bar')"); assertEvalEquals("$foo.bar()", "$foo.bar()"); } public void testPublicMethodInheritedFromPrivateClass() throws Exception { context.put("bar", new MyBar()); // ugly hack to avoid failed test when running JDK 1.5 or earlier try { Class.forName("java.util.Deque"); assertEvalEquals("bar", "$bar.bar()"); } catch (ClassNotFoundException cnfe) { //ignore this test in jdk 1.5- System.out.println("Skipping testPublicMethodInheritedFromPrivateClass for pre-1.6 JDK"); } } public static interface Foo { String foo(String s); } private static abstract class FooImpl implements Foo { public String foo(String s) { return s == null ? "foo" : s; } } private static class Foobar extends FooImpl { public String bar() { return "bar"; } } public static class MyBar extends Foobar { } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity589TestCase.java0000755000175000017500000000226311142425303027351 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-589. */ public class Velocity589TestCase extends BaseTestCase { public Velocity589TestCase(String name) { super(name); } public void testIt() { context.put("id", "test"); assertEvalEquals("#test_bg", "#${id}_bg"); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity355And552TestCase.java0000755000175000017500000000305011142425303030212 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-355 and its twin, VELOCITY-552. */ public class Velocity355And552TestCase extends BaseTestCase { public Velocity355And552TestCase(String name) { super(name); } public void testMissingDollar() { String base = "export $VAR=$(echo $testme)\n"; assertEvalEquals(base, base); String literal = "#literal()\n"+base+"#end"; assertEvalEquals(base, literal); } public void testMissingPound() { String base = "#!/usr/bin/perl\n"; assertEvalEquals(base, base); String literal = "#literal()\n"+base+"#end"; assertEvalEquals(base, literal); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity702TestCase.java0000755000175000017500000000645611322700447027351 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-702. */ public class Velocity702TestCase extends BaseTestCase { public Velocity702TestCase(String name) { super(name); } public void setUpEngine(VelocityEngine engine) { engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "high,low"); engine.addProperty("high.resource.loader.class", StringResourceLoader.class.getName()); engine.addProperty("high.resource.loader.cache", "false"); engine.addProperty("high.resource.loader.repository.name", "high"); engine.addProperty("high.resource.loader.repository.static", "false"); engine.addProperty("high.resource.loader.modificationCheckInterval", "1"); engine.addProperty("low.resource.loader.class", StringResourceLoader.class.getName()); engine.addProperty("low.resource.loader.cache", "true"); engine.addProperty("low.resource.loader.repository.name", "low"); engine.addProperty("low.resource.loader.repository.static", "false"); engine.addProperty("low.resource.loader.modificationCheckInterval", "1"); engine.init(); } public void testIt() throws Exception { addToHigh("foo", "foo"); addToLow("foo", "bar"); assertTmplEquals("foo", "foo"); removeFromHigh("foo"); assertTmplEquals("bar", "foo"); Thread.sleep(1500); addToHigh("foo", "woogie"); assertTmplEquals("woogie", "foo"); } private void addToHigh(String name, String content) { getHighRepo().putStringResource(name, content); } private void removeFromHigh(String name) { getHighRepo().removeStringResource(name); } private StringResourceRepository getHighRepo() { return (StringResourceRepository)engine.getApplicationAttribute("high"); } private void addToLow(String name, String content) { getLowRepo().putStringResource(name, content); } private void removeFromLow(String name) { getLowRepo().removeStringResource(name); } private StringResourceRepository getLowRepo() { return (StringResourceRepository)engine.getApplicationAttribute("low"); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity532TestCase.java0000755000175000017500000000325311142425303027335 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-532. */ public class Velocity532TestCase extends BaseTestCase { public Velocity532TestCase(String name) { super(name); } public void test532() { String template = "#macro( test )$velocityCount#end"+ "#foreach( $i in [1..5] )#test()#end"; assertEvalEquals("12345", template); } public void test532b() { // try something a little more like Matt's example String template = "#macro( test $baz )"+ "#if( $foo == $null )"+ "#if( $velocityCount == 3 )bar#end"+ "#end#end"+ "#foreach( $i in [1..5] )#test($i)#end"; assertEvalEquals("bar", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity631TestCase.java0000755000175000017500000000246411322700447027345 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-631. */ public class Velocity631TestCase extends BaseTestCase { public Velocity631TestCase(String name) { super(name); } public void test631() { assertEvalEquals("$a", "$a #set($b = 1)"); assertEvalEquals("$a", "$a#set($b = 1)"); assertEvalEquals("$a.b", "$a.b#set($b = 1)"); assertEvalEquals("$a.b(", "$a.b(#set($b = 1)"); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity730TestCase.java0000755000175000017500000000571411234415123027342 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.VelocityContext; /** * This class tests VELOCITY-730. */ public class Velocity730TestCase extends BaseTestCase { public Velocity730TestCase(String name) { super(name); //DEBUG = true; } public void setUpContext(VelocityContext ctx) { ctx.put("foo", new Foo()); } public void testIt() { String template = "$foo.foo #set( $foo.bar = 'foo' ) $foo.bar"; assertEvalEquals("bar foo", template); } public static interface MyMap extends Map { } public abstract static class MyMapImpl { private HashMap map = new HashMap(); protected Map map() { return map; } public void clear() { map.clear(); } public boolean containsKey(Object key) { return map.containsKey(key); } public boolean containsValue(Object value) { return map.containsValue(value); } public boolean isEmpty() { return map.isEmpty(); } public Set keySet() { return map.keySet(); } public void putAll(Map t) { map.putAll(t); } public Object remove(Object key) { return map.remove(key); } public int size() { return map.size(); } public Collection values() { return map.values(); } public Set entrySet() { return map.entrySet(); } } private final static class Foo extends MyMapImpl implements MyMap { public Foo() { super(); put("foo","bar"); } public Object get(Object key) { return map().get(key); } public Object put(Object k, Object v) { return map().put(k, v); } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity615TestCase.java0000755000175000017500000001041611322700447027343 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-615. */ public class Velocity615TestCase extends BaseTestCase { public Velocity615TestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty("velocimacro.permissions.allow.inline", "true"); engine.setProperty("velocimacro.permissions.allow.inline.to.replace.global", "false"); engine.setProperty("velocimacro.permissions.allow.inline.local.scope", "true"); engine.setProperty("velocimacro.context.localscope", "false"); engine.setProperty("velocimacro.arguments.strict", "true"); } public void testIt() { String template = "#set( $foo = 'old' )"+ "#macro( test $foo )"+ "#set( $foo = \"new $foo \" )"+ "$foo"+ "#end"+ "#test( 'foo' )"+ "$foo"; assertEvalEquals("new foo new foo ", template); } public void testForIrrationallyFearedRelatedPossibleProblem() { context.put("i", new Inc()); String template = "#macro( test $a )"+ "$a"+ "$a"+ "#end"+ "#test( \"$i\" )$i"; assertEvalEquals("012", template); } public void testForIrrationallyFearedRelatedPossibleProblem2() { context.put("i", new Inc()); String template = "#macro( test $a )"+ "#set( $a = 'a' )"+ "$a"+ "$a"+ "#end"+ "#test( \"$i\" )$i"; assertEvalEquals("aa0", template); } public void testForIrrationallyFearedRelatedPossibleProblem3() { context.put("i", new Inc()); String template = "#macro( test $a )"+ "$a"+ "$a"+ "#end"+ "#test( $i )$i"; assertEvalEquals("012", template); } public void testForIrrationallyFearedRelatedPossibleProblem4() { context.put("i", new Inc()); String template = "#macro( test $a )"+ "$a"+ "$a"+ "#end"+ "#test( $i.plus() )$i"; assertEvalEquals("012", template); } public void testForIrrationallyFearedRelatedPossibleProblem5() { context.put("i", new Inc()); String template = "#macro( test $a )"+ "#set( $a = $i )"+ "$a"+ "$a"+ "#end"+ "#test( 'a' )$i"; assertEvalEquals("012", template); } public void testVelocity681() { String template = "#macro(myMacro $result)"+ " #set($result = 'some value')"+ "#end"+ "#myMacro($x)"+ "$x"; assertEvalEquals("$x", template); } public static class Inc { private int i=0; public int plus() { return i++; } public String toString() { return String.valueOf(i++); } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity625TestCase.java0000755000175000017500000000231211322700447027340 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-625. */ public class Velocity625TestCase extends BaseTestCase { public Velocity625TestCase(String name) { super(name); } public void test1() { String template = "#macro(test $a $b)test#end#test('x')"; assertEvalEquals("test", template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity580TestCase.java0000755000175000017500000000746711273703572027367 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; 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.test.BaseTestCase; import org.apache.velocity.test.misc.TestLogChute; /** * Test Case for Velocity Issue 580. */ public class Velocity580TestCase extends BaseTestCase { /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/issues/velocity-580"; /** * Template Directory */ private static final String TEMPLATE_DIR = TEST_COMPARE_DIR + "/issues/velocity-580/templates"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/issues/velocity-580/compare"; VelocityEngine engine; public Velocity580TestCase(final String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(Velocity580TestCase.class); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); engine.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, TEMPLATE_DIR); engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public void testVelocity580() throws Exception { executeTest("velocity580.vm"); } protected Template executeTest(final String templateName) throws Exception { Template template = engine.getTemplate(templateName); FileOutputStream fos = new FileOutputStream(getFileName(RESULTS_DIR, templateName, RESULT_FILE_EXT)); Writer writer = new BufferedWriter(new OutputStreamWriter(fos)); VelocityContext context = new VelocityContext(); template.merge(context, writer); writer.flush(); writer.close(); if (!isMatch(RESULTS_DIR, COMPARE_DIR, templateName, RESULT_FILE_EXT, CMP_FILE_EXT)) { // just to be useful, output the output in the fail message StringWriter out = new StringWriter(); template.merge(context, out); String compare = getFileContents(COMPARE_DIR, templateName, CMP_FILE_EXT); fail("Output incorrect for Template: " + templateName + ": \""+out+"\""+ "; it did not match: \""+compare+"\""); } return template; } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity544TestCase.java0000644000175000017500000000410611142425303027333 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.test.BaseTestCase; /** * @see https://issues.apache.org/jira/browse/VELOCITY-544 */ public class Velocity544TestCase extends BaseTestCase { public Velocity544TestCase(final String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(Velocity544TestCase.class); } public void testBooleanPropertyExecutor() throws Exception { context.put("foobarTrue", new Foobar(true)); context.put("foobarFalse", new Foobar(false)); String template = "$foobarTrue.True $foobarFalse.True $foobarTrue.TrueObject $foobarFalse.TrueObject"; String result = evaluate(template); super.assertEquals("true false true false", result); } public static class Foobar { private boolean value; public Foobar(boolean value) { this.value = value; } public boolean isTrue() { return(value); } public Boolean isTrueObject() { return(new Boolean(value)); } } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity742TestCase.java0000644000175000017500000000403211317167355027347 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.ResourceNotFoundException; /** * This class tests VELOCITY-742. */ public class Velocity742TestCase extends BaseTestCase { public Velocity742TestCase(String name) { super(name); } protected void setUpEngine(VelocityEngine engine) { // we need to call init here because otherwise it is not called until assertEvalEquals // and therefore the removeDirective call is ignored. engine.init(); } public void testDisableAndRestoreDirective() { String s = "#include('doesnotexist.vm') directive is disabled"; // first remove the #include directive and see that is treated as normal text engine.removeDirective("include"); assertEvalEquals(s, s); // now reload the directive and see that the include directive works again and // Velocity throws ResourceNotFoundException because it can't find the template engine.loadDirective("org.apache.velocity.runtime.directive.Include"); assertEvalException(s, ResourceNotFoundException.class); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity762TestCase.java0000755000175000017500000000361611437522714027360 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-762. */ public class Velocity762TestCase extends BaseTestCase { public Velocity762TestCase(String name) { super(name); } public void testForeachIsLast() { String template = "#foreach( $i in [1..3] )$foreach.last #end"; assertEvalEquals("false false true ", template); } public void testAllForeachProps() { String template = "#foreach( $number in [1..3] )"+ "number:$number hasNext:$foreach.hasNext "+ "first:$foreach.first last:$foreach.last "+ "count:$foreach.count index:$foreach.index \n"+ "#end"; String expect = "number:1 hasNext:true first:true last:false count:1 index:0 \n"+ "number:2 hasNext:true first:false last:false count:2 index:1 \n"+ "number:3 hasNext:false first:false last:true count:3 index:2 \n"; assertEvalEquals(expect, template); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity627TestCase.java0000644000175000017500000000301611142425303027334 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests VELOCITY-627. Make sure Foreach * Error message reports correct line numbers. */ public class Velocity627TestCase extends BaseTestCase { public Velocity627TestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.SKIP_INVALID_ITERATOR, Boolean.FALSE); } public void test627() { // Make sure the error ouput contains "line 3, column 16" assertEvalExceptionAt("##\n##\n#foreach($i in \"junk\")blaa#end", 3, 16); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity728TestCase.java0000644000175000017500000000237711317162464027361 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.exception.VelocityException; /** * This class tests VELOCITY-728. */ public class Velocity728TestCase extends BaseTestCase { public Velocity728TestCase(String name) { super(name); DEBUG = false; } public void testParseWithNoArgument() { assertEvalException("#parse()", VelocityException.class); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity629TestCase.java0000644000175000017500000000350211322700447027343 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-629. Make sure string literals * Error message reports correct line and column numbers. */ public class Velocity629TestCase extends BaseTestCase { public Velocity629TestCase(String name) { super(name); } public void test629() { String template = "##\n"+ "##\n"+ "#set($list=[1])#set($x=\"\n"+ "$list.get(1)\n"+ "\")"; // Make sure the error ouput contains "line 4, column 7" if not throw assertEvalExceptionAt(template, 4, 7); template = "##\n"+ "##\n"+ "#set($x=\"#if\")"; assertEvalExceptionAt(template, 3, 9); template = "##\n"+ "##\n"+ "#macro(test $i)$i#end#set($list=[1])#test(\"$list.get(1)\")"; assertEvalExceptionAt(template, 3, 50); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity667TestCase.java0000644000175000017500000000236111322700447027347 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-667. Make "#macro" throws a parse exception */ public class Velocity667TestCase extends BaseTestCase { public Velocity667TestCase(String name) { super(name); } public void test667() { assertEvalExceptionAt("#macro", 1, 1); assertEvalExceptionAt("#macro #macro", 1, 1); } } velocity-1.7/src/test/org/apache/velocity/test/issues/Velocity758TestCase.java0000644000175000017500000000402111353451142027342 0ustar moellermoellerpackage org.apache.velocity.test.issues; /* * 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. */ import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.test.BaseTestCase; /** * This class tests VELOCITY-758. */ public class Velocity758TestCase extends BaseTestCase { public Velocity758TestCase(String name) { super(name); } public void testNullArgumentForParse() { assertEvalEquals("", "#parse($foo)"); } public void testOverrideNullArgumentForParse() { String nullContent = "Parse arg was null"; addTemplate("null.vm", nullContent); EventCartridge ec = new EventCartridge(); ec.addEventHandler(new Handler()); ec.attachToContext(context); assertEvalEquals(nullContent, "#parse($foo)"); } public static class Handler implements IncludeEventHandler { public String includeEvent(String parsePath, String parentPath, String directive) { if (parsePath == null) { parsePath = "null.vm"; } return parsePath; } } } velocity-1.7/src/test/org/apache/velocity/test/IncludeErrorTestCase.java0000644000175000017500000000657010513464370026401 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; /** * Test that #parse and #include pass errors to calling code. * Specifically checking against VELOCITY-95 and VELOCITY-96. * * @author Will Glass-Husain * @version $Id: IncludeErrorTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class IncludeErrorTestCase extends BaseTestCase implements TemplateTestBase { VelocityEngine ve; /** * Default constructor. */ public IncludeErrorTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(IncludeErrorTestCase.class); } public void setUp() throws Exception { ve = new VelocityEngine(); ve.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, "test/includeerror"); ve.init(); } public void testMissingParseError() throws Exception { checkException("missingparse.vm",ResourceNotFoundException.class); } public void testMissingIncludeError() throws Exception { checkException("missinginclude.vm",ResourceNotFoundException.class); } public void testParseError() throws Exception { checkException("parsemain.vm",ParseErrorException.class); } public void testParseError2() throws Exception { checkException("parsemain2.vm",ParseErrorException.class); } /** * Check that an exception is thrown for the given template * @param templateName * @param exceptionClass * @throws Exception */ private void checkException(String templateName,Class exceptionClass) throws Exception { Context context = new VelocityContext(); StringWriter writer = new StringWriter(); Template template = ve.getTemplate(templateName, "UTF-8"); try { template.merge(context, writer); writer.flush(); fail("File should have thrown an exception"); } catch (Exception E) { assertTrue(exceptionClass.isAssignableFrom(E.getClass())); } finally { writer.close(); } } } velocity-1.7/src/test/org/apache/velocity/test/VelocityAppTestCase.java0000644000175000017500000000563111075007114026231 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.test.misc.TestLogChute; /** * This class is intended to test the app.Velocity.java class. * * @author Geir Magnusson Jr. * @author Jon S. Stevens * @version $Id: VelocityAppTestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class VelocityAppTestCase extends BaseTestCase implements TemplateTestBase { private StringWriter compare1 = new StringWriter(); private String input1 = "My name is $name -> $Floog"; private String result1 = "My name is jason -> floogie woogie"; public VelocityAppTestCase(String name) { super(name); } public void setUp() throws Exception { Velocity.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public static Test suite() { return new TestSuite(VelocityAppTestCase.class); } /** * Runs the test. */ public void testVelocityApp () throws Exception { VelocityContext context = new VelocityContext(); context.put("name", "jason"); context.put("Floog", "floogie woogie"); Velocity.evaluate(context, compare1, "evaltest", input1); /* * @todo FIXME: Not tested right now. * * StringWriter result2 = new StringWriter(); * Velocity.mergeTemplate("mergethis.vm", context, result2); * * StringWriter result3 = new StringWriter(); * Velocity.invokeVelocimacro("floog", "test", new String[2], * context, result3); */ if (!result1.equals(compare1.toString())) { fail("Output incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/ContextSafetyTestCase.java0000644000175000017500000001057011075007114026570 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Vector; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.test.misc.TestLogChute; /** * Tests if we are context safe : can we switch objects in the context * and re-merge the template safely. * * NOTE: * This class should not extend RuntimeTestCase because this test * is run from the VelocityTestSuite which in effect a runtime * test suite and the test suite initializes the Runtime. Extending * RuntimeTestCase causes the Runtime to be initialized twice. * * @author Geir Magnusson Jr. * @version $Id: ContextSafetyTestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class ContextSafetyTestCase extends BaseTestCase implements TemplateTestBase { public ContextSafetyTestCase(String name) { super(name); } public void setUp() throws Exception { Velocity.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public static Test suite() { return new TestSuite(ContextSafetyTestCase.class); } /** * Runs the test. */ public void testContextSafety () throws Exception { /* * make a Vector and String array because * they are treated differently in Foreach() */ Vector v = new Vector(); v.addElement( new String("vector hello 1") ); v.addElement( new String("vector hello 2") ); v.addElement( new String("vector hello 3") ); String strArray[] = new String[3]; strArray[0] = "array hello 1"; strArray[1] = "array hello 2"; strArray[2] = "array hello 3"; VelocityContext context = new VelocityContext(); assureResultsDirectoryExists(RESULT_DIR); /* * get the template and the output */ Template template = RuntimeSingleton.getTemplate( getFileName(null, "context_safety", TMPL_FILE_EXT)); FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULT_DIR, "context_safety1", RESULT_FILE_EXT)); FileOutputStream fos2 = new FileOutputStream ( getFileName(RESULT_DIR, "context_safety2", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); /* * put the Vector into the context, and merge */ context.put("vector", v); template.merge(context, writer1); writer1.flush(); writer1.close(); /* * now put the string array into the context, and merge */ context.put("vector", strArray); template.merge(context, writer2); writer2.flush(); writer2.close(); if (!isMatch(RESULT_DIR,COMPARE_DIR,"context_safety1", RESULT_FILE_EXT,CMP_FILE_EXT) || !isMatch(RESULT_DIR,COMPARE_DIR,"context_safety2", RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Output incorrect."); } } } velocity-1.7/src/test/org/apache/velocity/test/TextblockTestCase.java0000644000175000017500000001132211322700447025727 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.runtime.parser.node.ASTTextblock; /** * This class tests the Textblock directive. */ public class TextblockTestCase extends BaseTestCase { // these are all here so that the test case adapts instantly // to changes in the textblock start/end sequences private static final String START = ASTTextblock.START; private static final String END = ASTTextblock.END; private static final String PARTIAL_START = START.substring(0, START.length() - 1); private static final String PARTIAL_END = END.substring(1, END.length()); private static final String END_OF_START = START.substring(START.length() - 1, START.length()); private static final String START_OF_END = END.substring(0, 1); public TextblockTestCase(String name) { super(name); //DEBUG = true; } public String textblock(String s) { return START + s + END; } public void assertTextblockEvalEquals(String s) throws Exception { assertEvalEquals(s, textblock(s)); } /** * https://issues.apache.org/jira/browse/VELOCITY-661 */ public void testTextblockAjaxcode() throws Exception { String s = "var myId = 'someID';$('#test).append($.template('
    ').apply({myId: myId}));"; assertEvalEquals(s + " 123", textblock(s)+" #foreach($i in [1..3])$i#end"); } public void testLooseTextblockEnd() throws Exception { // just like a multi-line comment end (*#), this must be // followed by a character. by itself, it bombs for some reason. assertEvalEquals(END+" ", END+" "); } public void testTextblockStartInTextblock() throws Exception { assertTextblockEvalEquals(START); } public void testTextblockEndBetweenTwoTextblockHalves() throws Exception { // just like a multi-line comment end (*#), the end token // in the middle must be followed by some character. // by itself, it bombs. not sure why that is, but the // same has been true of multi-line comments without complaints, // so i'm not going to worry about it just yet. assertEvalEquals(" "+END+" ", textblock(" ")+END+" "+textblock(" ")); } public void testZerolengthTextblock() throws Exception { assertTextblockEvalEquals(""); } public void testTextblockInsideForeachLoop() throws Exception { String s = "var myId = 'someID';$('#test).append($.template('
    ').apply({myId: myId}));"; assertEvalEquals("1 "+s+"2 "+s+"3 "+s, "#foreach($i in [1..3])$i "+ textblock(s) + "#end"); } public void testSingleHashInsideTextblock() throws Exception { assertTextblockEvalEquals(" # "); } public void testDollarInsideTextblock() throws Exception { assertTextblockEvalEquals("$"); } public void testTextblockInsideComment() throws Exception { String s = "FOOBAR"; assertEvalEquals("", "#* comment "+textblock(s) + " *#"); } public void testPartialStartEndTokensInsideTextblock() throws Exception { assertTextblockEvalEquals(PARTIAL_START+"foo"+PARTIAL_END); } public void testDupeTokenChars() throws Exception { assertTextblockEvalEquals(END_OF_START+START_OF_END); assertTextblockEvalEquals(END_OF_START+END_OF_START+START_OF_END+START_OF_END); assertTextblockEvalEquals(END_OF_START+END_OF_START+"#"+START_OF_END+START_OF_END); } /** * https://issues.apache.org/jira/browse/VELOCITY-584 */ public void testServerSideIncludeEscaping() throws Exception { assertTextblockEvalEquals(" "); } /** * https://issues.apache.org/jira/browse/VELOCITY-676 */ public void testLineCommentInsideTextblock() throws Exception { assertTextblockEvalEquals("##x"); } } velocity-1.7/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java0000644000175000017500000000770711273703572027514 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; 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.test.misc.TestLogChute; /** * Make sure that a forward referenced macro inside another macro definition does * not report an error in the log. * (VELOCITY-71). * * @author Henning P. Schmiedehausen * @version $Id: MacroForwardDefineTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class MacroForwardDefineTestCase extends BaseTestCase { /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/macroforwarddefine"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/macroforwarddefine"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/macroforwarddefine/compare"; /** * Collects the log messages. */ private TestLogChute logger = new TestLogChute(); VelocityEngine engine; /** * Default constructor. */ public MacroForwardDefineTestCase(String name) { super(name); } public void setUp() throws Exception { assureResultsDirectoryExists(RESULTS_DIR); engine = new VelocityEngine(); // use Velocity.setProperty (instead of properties file) so that we can use actual instance of log engine.setProperty(RuntimeConstants.RESOURCE_LOADER,"file"); engine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH ); engine.setProperty(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID,"true"); // actual instance of logger logger = new TestLogChute(true, false); engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM,logger); engine.setProperty(TestLogChute.TEST_LOGGER_LEVEL, "debug"); engine.init(); } public static Test suite() { return new TestSuite(MacroForwardDefineTestCase.class); } public void testLogResult() throws Exception { VelocityContext context = new VelocityContext(); Template template = engine.getTemplate("macros.vm"); // try to get only messages during merge logger.startCapture(); template.merge(context, new StringWriter()); logger.stopCapture(); String resultLog = logger.getLog(); if ( !isMatch(resultLog, COMPARE_DIR, "velocity.log", "cmp")) { String compare = getFileContents(COMPARE_DIR, "velocity.log", CMP_FILE_EXT); String msg = "Log output was incorrect\n"+ "-----Result-----\n"+ resultLog + "----Expected----\n"+ compare + "----------------"; fail(msg); } } } velocity-1.7/src/test/org/apache/velocity/test/StaticUtilityMethodsTestCase.java0000755000175000017500000000316211322700447030135 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ /** * This class tests support for putting static utility classes * like java.lang.Math directly into the context in order to * use their methods. */ public class StaticUtilityMethodsTestCase extends BaseTestCase { public StaticUtilityMethodsTestCase(String name) { super(name); } public void testMath() { context.put("Math", Math.class); assertEvalEquals("java.lang.Math", "$Math.name"); assertEvalEquals("3.0", "$Math.ceil(2.5)"); } public void testFoo() { context.put("Foo", Foo.class); assertEvalEquals("test", "$Foo.foo('test')"); } public static class Foo { private Foo() {} public static String foo(String s) { return s == null ? "foo" : s; } } } velocity-1.7/src/test/org/apache/velocity/test/util/0000755000175000017500000000000011675166247022466 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/util/introspection/0000755000175000017500000000000011675166247025366 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/util/introspection/ClassMapTestCase.java0000644000175000017500000000603711075007114031353 0ustar moellermoellerpackage org.apache.velocity.test.util.introspection; /* * 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. */ import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.util.introspection.ClassMap; /** * Test the ClassMap Lookup */ public class ClassMapTestCase extends BaseTestCase { public ClassMapTestCase(final String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(ClassMapTestCase.class); } public void setUp() throws Exception { Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); } public void tearDown() { } public void testPrimitives() throws Exception { Log log = Velocity.getLog(); ClassMap c = new ClassMap(TestClassMap.class, log); assertNotNull(c.findMethod("setBoolean", new Object[] { Boolean.TRUE })); assertNotNull(c.findMethod("setByte", new Object[] { new Byte((byte) 4)})); assertNotNull(c.findMethod("setCharacter", new Object[] { new Character('c')})); assertNotNull(c.findMethod("setDouble", new Object[] { new Double(8.0) })); assertNotNull(c.findMethod("setFloat", new Object[] { new Float(15.0) })); assertNotNull(c.findMethod("setInteger", new Object[] { new Integer(16) })); assertNotNull(c.findMethod("setLong", new Object[] { new Long(23) })); assertNotNull(c.findMethod("setShort", new Object[] { new Short((short)42)})); } public static final class TestClassMap { public void setBoolean(boolean b) { } public void setByte(byte b) { } public void setCharacter(char c) { } public void setDouble(double d) { } public void setFloat(float f) { } public void setInteger(int i) { } public void setLong(long l) { } public void setShort(short s) { } } } velocity-1.7/src/test/org/apache/velocity/test/util/introspection/ChainedUberspectorsTestCase.java0000644000175000017500000001026711273703572033617 0ustar moellermoellerpackage org.apache.velocity.test.util.introspection; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.test.BaseTestCase; import org.apache.velocity.test.misc.TestLogChute; import org.apache.velocity.util.introspection.AbstractChainableUberspector; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.UberspectImpl; import org.apache.velocity.util.introspection.VelPropertyGet; import org.apache.velocity.util.introspection.VelPropertySet; /** * Tests uberspectors chaining */ public class ChainedUberspectorsTestCase extends BaseTestCase { VelocityEngine engine; public ChainedUberspectorsTestCase(String name) throws Exception { super(name); } public static Test suite() { return new TestSuite(ChainedUberspectorsTestCase.class); } public void setUp() throws Exception { engine = new VelocityEngine(); engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.addProperty(RuntimeConstants.UBERSPECT_CLASSNAME,"org.apache.velocity.util.introspection.UberspectImpl"); engine.addProperty(RuntimeConstants.UBERSPECT_CLASSNAME,"org.apache.velocity.test.util.introspection.ChainedUberspectorsTestCase$ChainedUberspector"); engine.addProperty(RuntimeConstants.UBERSPECT_CLASSNAME,"org.apache.velocity.test.util.introspection.ChainedUberspectorsTestCase$LinkedUberspector"); engine.init(); } public void tearDown() { } public void testChaining() throws Exception { VelocityContext context = new VelocityContext(); context.put("foo",new Foo()); StringWriter writer = new StringWriter(); engine.evaluate(context,writer,"test","$foo.zeMethod()"); assertEquals(writer.toString(),"ok"); engine.evaluate(context,writer,"test","#set($foo.foo = 'someValue')"); writer = new StringWriter(); engine.evaluate(context,writer,"test","$foo.bar"); assertEquals(writer.toString(),"someValue"); writer = new StringWriter(); engine.evaluate(context,writer,"test","$foo.foo"); assertEquals(writer.toString(),"someValue"); } // replaces getFoo by getBar public static class ChainedUberspector extends AbstractChainableUberspector { public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info info) throws Exception { identifier = identifier.replaceAll("foo","bar"); return inner.getPropertySet(obj,identifier,arg,info); } } // replaces setFoo by setBar public static class LinkedUberspector extends UberspectImpl { public VelPropertyGet getPropertyGet(Object obj, String identifier, Info info) throws Exception { identifier = identifier.replaceAll("foo","bar"); return super.getPropertyGet(obj,identifier,info); } } public static class Foo { private String bar; public String zeMethod() { return "ok"; } public String getBar() { return bar; } public void setBar(String s) { bar = s; } } } velocity-1.7/src/test/org/apache/velocity/test/eventhandler/0000755000175000017500000000000011675166247024170 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/eventhandler/Handler2.java0000644000175000017500000000444010513464370026460 0ustar moellermoellerpackage org.apache.velocity.test.eventhandler; /* * 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. */ import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.app.event.NullSetEventHandler; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; /** * This is a test set of event handlers, used to test event handler sequences. * * @author Will Glass-Husain * @version $Id: Handler2.java 463298 2006-10-12 16:10:32Z henning $ */ public class Handler2 implements NullSetEventHandler, ReferenceInsertionEventHandler, MethodExceptionEventHandler, IncludeEventHandler { /** * always log */ public boolean shouldLogOnNullSet(String lhs, String rhs) { return true; } /** * convert output to upper case */ public Object referenceInsert(String reference, Object value) { if (value == null) return null; else return value.toString().toUpperCase(); } /** * print the exception */ public Object methodException(Class claz, String method, Exception e) throws Exception { return "Exception: " + e; } /* * redirect all requests to a new directory "subdir" (simulates localization). */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName) { return "subdir/" + includeResourcePath; } } velocity-1.7/src/test/org/apache/velocity/test/eventhandler/Handler1.java0000644000175000017500000000467410513464370026470 0ustar moellermoellerpackage org.apache.velocity.test.eventhandler; /* * 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. */ import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.app.event.NullSetEventHandler; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; /** * This is a test set of event handlers, used to test event handler sequences. * * @author Will Glass-Husain * @version $Id: Handler1.java 463298 2006-10-12 16:10:32Z henning $ */ public class Handler1 implements NullSetEventHandler, ReferenceInsertionEventHandler, MethodExceptionEventHandler, IncludeEventHandler { /** * never log */ public boolean shouldLogOnNullSet(String lhs, String rhs) { return false; } /** * display output twice, once uppercase and once lowercase */ public Object referenceInsert(String reference, Object value) { if (value == null) return null; else return value.toString().toUpperCase() + value.toString().toLowerCase(); } /** * throw the exception */ public Object methodException(Class claz, String method, Exception e) throws Exception { throw e; } /* * redirect all requests to a page "login.vm" (simulates access control). */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName) { return "notfound.vm"; } } velocity-1.7/src/test/org/apache/velocity/test/PropertyMethodPrecedenceTestCase.java0000755000175000017500000000531211142425303030733 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.VelocityContext; /** * Used to check that vararg method calls on references work properly */ public class PropertyMethodPrecedenceTestCase extends BaseTestCase { public PropertyMethodPrecedenceTestCase(final String name) { super(name); // DEBUG = true; } protected void setUpContext(VelocityContext context) { context.put("geta", new getGetgetisTool()); context.put("getA", new GetgetisTool()); context.put("geta2", new get2getisTool()); context.put("get_a", new getisTool()); context.put("isA", new isTool()); } public void testLowercasePropertyMethods() { assertEvalEquals("getfoo", "$geta.foo"); assertEvalEquals("getFoo", "$getA.foo"); assertEvalEquals("get(foo)", "$get_a.foo"); assertEvalEquals("true", "$isA.foo"); } public void testUppercasePropertyMethods() { assertEvalEquals("getFoo", "$geta.Foo"); assertEvalEquals("getfoo", "$geta2.Foo"); assertEvalEquals("getFoo", "$getA.Foo"); assertEvalEquals("get(Foo)", "$get_a.Foo"); assertEvalEquals("true", "$isA.Foo"); } public static class isTool { public boolean isFoo() { return true; } } public static class getisTool extends isTool { public String get(String s) { return "get("+s+")"; } } public static class GetgetisTool extends getisTool { public String getFoo() { return "getFoo"; } } public static class getGetgetisTool extends GetgetisTool { public String getfoo() { return "getfoo"; } } public static class get2getisTool extends getisTool { public String getfoo() { return "getfoo"; } } } velocity-1.7/src/test/org/apache/velocity/test/Introspector2TestCase.java0000644000175000017500000000777611075007114026563 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.lang.reflect.Method; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.test.misc.TestLogChute; /** * Test case for the Velocity Introspector which * tests the ability to find a 'best match' * * * @author Geir Magnusson Jr. * @version $Id: Introspector2TestCase.java 704299 2008-10-14 03:13:16Z nbubna $ */ public class Introspector2TestCase extends BaseTestCase { /** * Creates a new instance. */ public Introspector2TestCase(String name) { super(name); } /** * Get the containing TestSuite. * * @return The TestSuite to run. */ public static Test suite () { return new TestSuite(Introspector2TestCase.class); } public void testIntrospector() throws Exception { Velocity.setProperty( Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); Velocity.init(); Method method; String result; Tester t = new Tester(); Object[] params = { new Foo(), new Foo() }; method = RuntimeSingleton.getIntrospector() .getMethod( Tester.class, "find", params ); if ( method == null) fail("Returned method was null"); result = (String) method.invoke( t, params); if ( !result.equals( "Bar-Bar" ) ) { fail("Should have gotten 'Bar-Bar' : received '" + result + "'"); } /* * now test for failure due to ambiguity */ method = RuntimeSingleton.getIntrospector() .getMethod( Tester2.class, "find", params ); if ( method != null) fail("Introspector shouldn't have found a method as it's ambiguous."); } public interface Woogie { } public static class Bar implements Woogie { int i; } public static class Foo extends Bar { int j; } public static class Tester { public static String find(Woogie w, Object o ) { return "Woogie-Object"; } public static String find(Object w, Bar o ) { return "Object-Bar"; } public static String find(Bar w, Bar o ) { return "Bar-Bar"; } public static String find( Object o ) { return "Object"; } public static String find( Woogie o ) { return "Woogie"; } } public static class Tester2 { public static String find(Woogie w, Object o ) { return "Woogie-Object"; } public static String find(Object w, Bar o ) { return "Object-Bar"; } public static String find(Bar w, Object o ) { return "Bar-Object"; } public static String find( Object o ) { return "Object"; } public static String find( Woogie o ) { return "Woogie"; } } } velocity-1.7/src/test/org/apache/velocity/test/provider/0000755000175000017500000000000011675166247023343 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/test/provider/Child.java0000644000175000017500000000227110513464370025217 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ /** * Rudimentary class used in the testbed to test * introspection with subclasses of a particular * class. * * @author Jason van Zyl * @version $Id: Child.java 463298 2006-10-12 16:10:32Z henning $ */ public class Child extends Person { public String getName() { return "Child"; } } velocity-1.7/src/test/org/apache/velocity/test/provider/ForeachMethodCallHelper.java0000644000175000017500000000234010513464370030635 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ /** * Provides overloaded methods for testing method execution within a foreach * @author Will Glass-Husain * @version $Id: ForeachMethodCallHelper.java 463298 2006-10-12 16:10:32Z henning $ */ public class ForeachMethodCallHelper { public String getFoo(Integer v) { return "int "+v; } public String getFoo(String v) { return "str "+v; } } velocity-1.7/src/test/org/apache/velocity/test/provider/BoolObj.java0000644000175000017500000000252010513464370025517 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ /** * simple class to test boolean property * introspection - can't use TestProvider * as there is a get( String ) * and that comes before isProperty * in the search pattern * * @author Geir Magnusson Jr. */ public class BoolObj { public boolean isBoolean() { return true; } /* * not isProperty as it's not * boolean return valued... */ public String isNotboolean() { return "hello"; } } velocity-1.7/src/test/org/apache/velocity/test/provider/Person.java0000644000175000017500000000235610513464370025446 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ /** * Rudimentary class used in the testbed to test * introspection with subclasses of a particular * class. * * This class need to be greatly extended to * be useful :-) * * @author Jason van Zyl * @version $Id: Person.java 463298 2006-10-12 16:10:32Z henning $ */ public class Person { public String getName() { return "Person"; } } velocity-1.7/src/test/org/apache/velocity/test/provider/TestNumber.java0000644000175000017500000000243210513464370026263 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ import org.apache.velocity.util.TemplateNumber; /** * Used for testing purposes to check that an object implementing TemplateNumber * will be treated as a Number. * * @author Will Glass-Husain */ public class TestNumber implements TemplateNumber { private Number n; public TestNumber(double val) { n = new Double(val); } public Number getAsNumber() { return n; } } velocity-1.7/src/test/org/apache/velocity/test/provider/TestProvider.java0000644000175000017500000002012310513464370026622 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Stack; import java.util.Vector; /** * This class is used by the testbed. Instances of the class * are fed into the context that is set before the AST * is traversed and dynamic content generated. * * @author Jason van Zyl * @version $Id: TestProvider.java 463298 2006-10-12 16:10:32Z henning $ */ public class TestProvider { String title = "lunatic"; boolean state; Object ob = null; public static String PUB_STAT_STRING = "Public Static String"; int stateint = 0; public String getName() { return "jason"; } public Stack getStack() { Stack stack = new Stack(); stack.push("stack element 1"); stack.push("stack element 2"); stack.push("stack element 3"); return stack; } public List getEmptyList() { List list = new ArrayList(); return list; } public List getList() { List list = new ArrayList(); list.add("list element 1"); list.add("list element 2"); list.add("list element 3"); return list; } public Hashtable getSearch() { Hashtable h = new Hashtable(); h.put("Text", "this is some text"); h.put("EscText", "this is escaped text"); h.put("Title", "this is the title"); h.put("Index", "this is the index"); h.put("URL", "http://periapt.com"); ArrayList al = new ArrayList(); al.add(h); h.put("RelatedLinks", al); return h; } public Hashtable getHashtable() { Hashtable h = new Hashtable(); h.put("key0", "value0"); h.put("key1", "value1"); h.put("key2", "value2"); return h; } public ArrayList getRelSearches() { ArrayList al = new ArrayList(); al.add(getSearch()); return al; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Object[] getMenu() { //ArrayList al = new ArrayList(); Object[] menu = new Object[3]; for (int i = 0; i < 3; i++) { Hashtable item = new Hashtable(); item.put("id", "item" + Integer.toString(i+1)); item.put("name", "name" + Integer.toString(i+1)); item.put("label", "label" + Integer.toString(i+1)); //al.add(item); menu[i] = item; } //return al; return menu; } public ArrayList getCustomers() { ArrayList list = new ArrayList(); list.add("ArrayList element 1"); list.add("ArrayList element 2"); list.add("ArrayList element 3"); list.add("ArrayList element 4"); return list; } public ArrayList getCustomers2() { ArrayList list = new ArrayList(); list.add(new TestProvider()); list.add(new TestProvider()); list.add(new TestProvider()); list.add(new TestProvider()); return list; } public Object me() { return this; } public String toString() { return ("test provider"); } public Vector getVector() { Vector list = new Vector(); list.addElement("vector element 1"); list.addElement("vector element 2"); return list; } public String[] getArray() { String[] strings = new String[2]; strings[0] = "first element"; strings[1] = "second element"; return strings; } public boolean theAPLRules() { return true; } public boolean getStateTrue() { return true; } public boolean getStateFalse() { return false; } public String objectArrayMethod(Object[] o) { return "result of objectArrayMethod"; } public String concat(Object[] strings) { StringBuffer result = new StringBuffer(); for (int i = 0; i < strings.length; i++) { result.append((String) strings[i]).append(' '); } return result.toString(); } public String concat(List strings) { StringBuffer result = new StringBuffer(); for (int i = 0; i < strings.size(); i++) { result.append((String) strings.get(i)).append(' '); } return result.toString(); } public String objConcat(List objects) { StringBuffer result = new StringBuffer(); for (int i = 0; i < objects.size(); i++) { result.append(objects.get(i)).append(' '); } return result.toString(); } public String parse(String a, Object o, String c, String d) { return a + o.toString() + c + d; } public String concat(String a, String b) { return a + b; } // These two are for testing subclasses. public Person getPerson() { return new Person(); } public Child getChild() { return new Child(); } public String showPerson(Person person) { return person.getName(); } /** * Chop i characters off the end of a string. * * @param string String to chop. * @param i Number of characters to chop. * @return String with processed answer. */ public String chop(String string, int i) { return(string.substring(0, string.length() - i)); } public boolean allEmpty(Object[] list) { int size = list.length; for (int i = 0; i < size; i++) if (list[i].toString().length() > 0) return false; return true; } /* * This can't have the signature * * public void setState(boolean state) * * or dynamically invoking the method * doesn't work ... you would have to * put a wrapper around a method for a * real boolean property that takes a * Boolean object if you wanted this to * work. Not really sure how useful it * is anyway. Who cares about boolean * values you can just set a variable. * */ public void setState(Boolean state) { } public void setBangStart( Integer i ) { System.out.println("SetBangStart() : called with val = " + i ); stateint = i.intValue(); } public Integer bang() { System.out.println("Bang! : " + stateint ); Integer ret = new Integer( stateint ); stateint++; return ret; } /** * Test the ability of vel to use a get(key) * method for any object type, not just one * that implements the Map interface. */ public String get(String key) { return key; } /** * Test the ability of vel to use a put(key) * method for any object type, not just one * that implements the Map interface. */ public String put(String key, Object o) { ob = o; return key; } public String getFoo() throws Exception { throw new Exception("From getFoo()"); } public String getThrow() throws Exception { throw new Exception("From getThrow()"); } } velocity-1.7/src/test/org/apache/velocity/test/provider/NullToStringObject.java0000644000175000017500000000222510513464370027726 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ /** * Used to confirm that a null to string is processed properly * @author Will Glass-Husain * @version $Id: NullToStringObject.java 463298 2006-10-12 16:10:32Z henning $ */ public class NullToStringObject { public String toString() { return null; } } velocity-1.7/src/test/org/apache/velocity/test/provider/NumberMethods.java0000644000175000017500000000324710513464370026754 0ustar moellermoellerpackage org.apache.velocity.test.provider; /* * 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. */ import java.math.BigDecimal; import java.math.BigInteger; /** * Used to check that method calls with number parameters are executed correctly. * * @author Will Glass-Husain */ public class NumberMethods { public String numMethod(byte val) { return "byte (" + val + ")"; } public String numMethod(short val) { return "short (" + val + ")"; } public String numMethod(int val) { return "int (" + val + ")"; } public String numMethod(double val) { return "double (" + val + ")"; } public String numMethod(long val) { return "long (" + val + ")"; } public String numMethod(BigInteger val) { return "BigInteger (" + val + ")"; } public String numMethod(BigDecimal val) { return "BigDecimal (" + val + ")"; } } velocity-1.7/src/test/org/apache/velocity/test/WrappedExceptionTestCase.java0000644000175000017500000000532610513464370027263 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.test.provider.TestProvider; import org.apache.velocity.util.ExceptionUtils; /** * Test thrown exceptions include a proper cause (under JDK 1.4+). * * @author Will Glass-Husain * @version $Id: WrappedExceptionTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class WrappedExceptionTestCase extends BaseTestCase implements TemplateTestBase { VelocityEngine ve; /** * Default constructor. */ public WrappedExceptionTestCase(String name) { super(name); } public static Test suite () { return new TestSuite(WrappedExceptionTestCase.class); } public void setUp() throws Exception { ve = new VelocityEngine(); ve.init(); } public void testMethodException() throws Exception { // accumulate a list of invalid references Context context = new VelocityContext(); StringWriter writer = new StringWriter(); context.put("test",new TestProvider()); try { ve.evaluate(context,writer,"test","$test.getThrow()"); fail ("expected an exception"); } catch (MethodInvocationException E) { assertEquals(Exception.class,E.getCause().getClass()); assertEquals("From getThrow()",E.getCause().getMessage()); } } public void testExceptionUtils() { Error e = new Error("Inside"); RuntimeException re = ExceptionUtils.createRuntimeException("Outside", e); assertEquals("cause was set", e,re.getCause()); } } velocity-1.7/src/test/org/apache/velocity/test/MultiLoaderTestCase.java0000644000175000017500000001505611273703572026230 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import junit.framework.Test; import junit.framework.TestSuite; 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.test.misc.TestLogChute; /** * Load templates from the Classpath. * * @author Jason van Zyl * @author Dave Bryson * @version $Id: MultiLoaderTestCase.java 832247 2009-11-03 01:29:30Z wglass $ */ public class MultiLoaderTestCase extends BaseTestCase { /** * VTL file extension. */ private static final String TMPL_FILE_EXT = "vm"; /** * Comparison file extension. */ private static final String CMP_FILE_EXT = "cmp"; /** * Comparison file extension. */ private static final String RESULT_FILE_EXT = "res"; /** * Results relative to the build directory. */ private static final String RESULTS_DIR = TEST_RESULT_DIR + "/multiloader"; /** * Path for templates. This property will override the * value in the default velocity properties file. */ private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/multiloader"; /** * Results relative to the build directory. */ private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/multiloader/compare"; VelocityEngine engine; /** * Default constructor. */ public MultiLoaderTestCase(String name) { super(name); } public void setUp() throws Exception { engine = new VelocityEngine(); assureResultsDirectoryExists(RESULTS_DIR); /* * Set up the file loader. */ engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); engine.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH); engine.addProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); engine.addProperty(RuntimeConstants.RESOURCE_LOADER, "jar"); /* * Set up the classpath loader. */ engine.setProperty( "classpath." + RuntimeConstants.RESOURCE_LOADER + ".class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); engine.setProperty( "classpath." + RuntimeConstants.RESOURCE_LOADER + ".cache", "false"); engine.setProperty( "classpath." + RuntimeConstants.RESOURCE_LOADER + ".modificationCheckInterval", "2"); /* * setup the Jar loader */ engine.setProperty( "jar." + RuntimeConstants.RESOURCE_LOADER + ".class", "org.apache.velocity.runtime.resource.loader.JarResourceLoader"); engine.setProperty( "jar." + RuntimeConstants.RESOURCE_LOADER + ".path", "jar:file:" + FILE_RESOURCE_LOADER_PATH + "/test2.jar" ); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, TestLogChute.class.getName()); engine.init(); } public static Test suite () { return new TestSuite(MultiLoaderTestCase.class); } /** * Runs the test. */ public void testMultiLoader () throws Exception { /* * lets ensure the results directory exists */ assureResultsDirectoryExists(RESULTS_DIR); /* * Template to find with the file loader. */ Template template1 = engine.getTemplate( getFileName(null, "path1", TMPL_FILE_EXT)); /* * Template to find with the classpath loader. */ Template template2 = engine.getTemplate("template/test1." + TMPL_FILE_EXT); /* * Template to find with the jar loader */ Template template3 = engine.getTemplate("template/test2." + TMPL_FILE_EXT); /* * and the results files */ FileOutputStream fos1 = new FileOutputStream ( getFileName(RESULTS_DIR, "path1", RESULT_FILE_EXT)); FileOutputStream fos2 = new FileOutputStream ( getFileName(RESULTS_DIR, "test2", RESULT_FILE_EXT)); FileOutputStream fos3 = new FileOutputStream ( getFileName(RESULTS_DIR, "test3", RESULT_FILE_EXT)); Writer writer1 = new BufferedWriter(new OutputStreamWriter(fos1)); Writer writer2 = new BufferedWriter(new OutputStreamWriter(fos2)); Writer writer3 = new BufferedWriter(new OutputStreamWriter(fos3)); /* * put the Vector into the context, and merge both */ VelocityContext context = new VelocityContext(); template1.merge(context, writer1); writer1.flush(); writer1.close(); template2.merge(context, writer2); writer2.flush(); writer2.close(); template3.merge(context, writer3); writer3.flush(); writer3.close(); if (!isMatch(RESULTS_DIR,COMPARE_DIR,"path1",RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Output incorrect for FileResourceLoader test."); } if (!isMatch(RESULTS_DIR,COMPARE_DIR,"test2",RESULT_FILE_EXT,CMP_FILE_EXT) ) { fail("Output incorrect for ClasspathResourceLoader test."); } if( !isMatch(RESULTS_DIR,COMPARE_DIR,"test3",RESULT_FILE_EXT,CMP_FILE_EXT)) { fail("Output incorrect for JarResourceLoader test."); } } } velocity-1.7/src/test/org/apache/velocity/test/StrictMathTestCase.java0000755000175000017500000000444111322700447026061 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.exception.MathException; import org.apache.velocity.runtime.RuntimeConstants; /** * This class tests support for strict math mode. */ public class StrictMathTestCase extends BaseTestCase { public StrictMathTestCase(String name) { super(name); } public void setUp() throws Exception { super.setUp(); engine.setProperty(RuntimeConstants.STRICT_MATH, Boolean.TRUE); context.put("num", new Integer(5)); context.put("zero", new Integer(0)); } protected void assertNullMathEx(String operation) { String leftnull = "#set( $foo = $null "+operation+" $num )"; assertEvalException(leftnull, MathException.class); String rightnull = "#set( $foo = $num "+operation+" $null )"; assertEvalException(rightnull, MathException.class); } protected void assertImaginaryMathEx(String operation) { String infinity = "#set( $foo = $num "+operation+" $zero )"; assertEvalException(infinity, MathException.class); } public void testAdd() { assertNullMathEx("+"); } public void testSub() { assertNullMathEx("-"); } public void testMul() { assertNullMathEx("*"); } public void testMod() { assertNullMathEx("%"); assertImaginaryMathEx("%"); } public void testDiv() { assertNullMathEx("/"); assertImaginaryMathEx("/"); } } velocity-1.7/src/test/org/apache/velocity/test/BreakDirectiveTestCase.java0000644000175000017500000001024211206073012026643 0ustar moellermoellerpackage org.apache.velocity.test; /* * 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. */ import org.apache.velocity.app.VelocityEngine; /** * This class tests the break directive. */ public class BreakDirectiveTestCase extends BaseTestCase { public BreakDirectiveTestCase(String name) { super(name); } protected void setUpEngine(VelocityEngine engine) { engine.setProperty("a.provide.scope.control", "true"); engine.setProperty("define.provide.scope.control", "true"); engine.setProperty("evaluate.provide.scope.control", "true"); engine.setProperty("macro.provide.scope.control", "true"); engine.setProperty("template.provide.scope.control", "true"); } public void testBadArgs() { context.put("foo","foo"); assertEvalException("#break($null)"); assertEvalException("#break($foo)"); assertEvalException("#break(true)"); assertEvalException("#break(1.2)"); assertEvalException("#break([0..1])"); assertEvalException("#break( $too $many )"); } public void testStopForeach() { String template = "#foreach($i in [1..5])$i#if($i>2)#break($foreach)#end#end test"; assertEvalEquals("123 test", template); // only inner should be stopped, not outer String t2 = "#foreach($j in [1..2])"+template+"#end"; assertEvalEquals("123 test123 test", t2); // stop outer using #break($foreach.parent) String t3 = "#foreach($i in [1..2])#foreach($j in [2..3])$i$j#if($i+$j==5)#break($foreach.parent)#end#end test#end"; assertEvalEquals("1213 test2223", t3); // without specifying scope... assertEvalEquals("1, 2, 3, 4, 5", "#foreach($i in [1..10])$i#if($i > 4)#break#end, #end"); assertEvalEquals("1", "#foreach($i in [1..5])$i#break #end"); assertEvalEquals("~~~, ~~, ~, ", "#foreach($i in [1..3])#foreach($j in [2..4])#if($i*$j >= 8)#break#end~#end, #end"); } public void testStopTemplate() { addTemplate("a", "a#break($template)b"); assertTmplEquals("a", "a"); assertEvalEquals("ac", "#parse('a')c"); addTemplate("b", "b#{break}a"); assertTmplEquals("b", "b"); } public void testStopEvaluate() { assertEvalEquals("a", "a#break($evaluate)b"); assertEvalEquals("a", "#evaluate('a#break($evaluate)b')"); assertEvalEquals("a", "a#evaluate('#break($evaluate.topmost)')b"); assertEvalEquals("a", "a#{break}b"); } public void testStopDefineBlock() { assertEvalEquals("a", "#define($a)a#break($define)b#end$a"); assertEvalEquals("aa", "#define($a)a#break($define.parent)b#end#define($b)a${a}b#end$b"); assertEvalEquals("a", "#define($a)a#{break}b#end$a"); } public void testStopMacro() { assertEvalEquals("a ", "#macro(a)a #break($macro) b#end#a"); assertEvalEquals("b c ", "#macro(c)c #break($macro.parent) d#end"+ "#macro(b)b #c c#end"+ "#b"); assertEvalEquals("d", "#macro(d)d#{break}e#end#d"); } public void testStopMacroBodyBlock() { assertEvalEquals(" a ", "#macro(a) $bodyContent #end"+ "#@a()a#break($a)b#end"); assertEvalEquals(" b ", "#macro(b) $bodyContent #end"+ "#@b()b#{break}c#end"); } } velocity-1.7/src/test/org/apache/velocity/io/0000755000175000017500000000000011675166247021141 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/io/UnicodeInputStreamTestCase.java0000644000175000017500000001467110557734552027231 0ustar moellermoellerpackage org.apache.velocity.io; /* * 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. */ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.InputStreamReader; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.lang.ArrayUtils; /** * Test the UnicodeInputStream. * * @author $author$ * @version $Revision: 501574 $, $Date: 2007-01-30 22:32:26 +0100 (Tue, 30 Jan 2007) $ */ public class UnicodeInputStreamTestCase extends TestCase { public UnicodeInputStreamTestCase(final String name) { super(name); } public static Test suite() { return new TestSuite(UnicodeInputStreamTestCase.class); } public void testSimpleStream() throws Exception { testRun(null, "Ich bin zwei Oeltanks", "US-ASCII", true); testRun(null, "Ich bin zwei Oeltanks", "US-ASCII", false); } public void testSimpleUTF8() throws Exception { testRun(null, "Ich bin zwei Oeltanks", "UTF-8", true); testRun(null, "Ich bin zwei Oeltanks", "UTF-8", false); } public void testRealUTF8() throws Exception { testRun(null, "Ich bin zwei \u00d6ltanks", "UTF-8", true); testRun(null, "Ich bin zwei \u00d6ltanks", "UTF-8", false); } public void testRealUTF8WithBOM() throws Exception { testRun(UnicodeInputStream.UTF8_BOM, "Ich bin ein Test", "UTF-8", true); testRun(UnicodeInputStream.UTF8_BOM, "Ich bin ein Test", "UTF-8", false); } public void testRealUTF16BEWithBOM() throws Exception { testRun(UnicodeInputStream.UTF16BE_BOM, "Ich bin ein Test", "UTF-16BE", true); testRun(UnicodeInputStream.UTF16BE_BOM, "Ich bin ein Test", "UTF-16BE", false); } public void testRealUTF16LEWithBOM() throws Exception { testRun(UnicodeInputStream.UTF16LE_BOM, "Ich bin ein Test", "UTF-16LE", true); testRun(UnicodeInputStream.UTF16LE_BOM, "Ich bin ein Test", "UTF-16LE", false); } public void testRealUTF32BEWithBOM() throws Exception { testRun(UnicodeInputStream.UTF32BE_BOM, null, "UTF-32BE", true); testRun(UnicodeInputStream.UTF32BE_BOM, null, "UTF-32BE", false); } public void testRealUTF32LEWithBOM() throws Exception { testRun(UnicodeInputStream.UTF32LE_BOM, null, "UTF-32LE", true); testRun(UnicodeInputStream.UTF32LE_BOM, null, "UTF-32LE", false); } protected void testRun(final UnicodeInputStream.UnicodeBOM bom, final String str, final String testEncoding, final boolean skipBOM) throws Exception { byte [] testString = buildTestString(bom, str, testEncoding, skipBOM); InputStream is = null; UnicodeInputStream uis = null; try { is = createInputStream(bom, str, testEncoding); uis = new UnicodeInputStream(is, skipBOM); assertEquals("BOM Skipping problem", skipBOM, uis.isSkipBOM()); if (bom != null) { assertEquals("Wrong Encoding detected", testEncoding, uis.getEncodingFromStream()); } byte [] result = readAllBytes(uis, testEncoding); assertNotNull(testString); assertNotNull(result); assertEquals("Wrong result length", testString.length, result.length); for (int i = 0; i < result.length; i++) { assertEquals("Wrong Byte at " + i, testString[i], result[i]); } } finally { if (uis != null) { uis.close(); } if (is != null) { is.close(); } } } protected InputStream createInputStream(final UnicodeInputStream.UnicodeBOM bom, final String str, final String enc) throws Exception { if (bom == null) { if (str != null) { return new ByteArrayInputStream(str.getBytes(enc)); } else { return new ByteArrayInputStream(new byte[0]); } } else { if (str != null) { return new ByteArrayInputStream(ArrayUtils.addAll(bom.getBytes(), str.getBytes(enc))); } else { return new ByteArrayInputStream(ArrayUtils.addAll(bom.getBytes(), new byte[0])); } } } protected byte [] buildTestString(final UnicodeInputStream.UnicodeBOM bom, final String str, final String enc, final boolean skipBOM) throws Exception { byte [] strBytes = (str != null) ? str.getBytes(enc) : new byte[0]; if ((bom == null) || skipBOM) { return strBytes; } else { return ArrayUtils.addAll(bom.getBytes(), strBytes); } } protected byte [] readAllBytes(final InputStream inputStream, final String enc) throws Exception { InputStreamReader isr = null; byte [] res = new byte[0]; try { byte[] buf = new byte[1024]; int read = 0; while ((read = inputStream.read(buf)) >= 0) { res = ArrayUtils.addAll(res, ArrayUtils.subarray(buf, 0, read)); } } finally { if (isr != null) { isr.close(); } } return res; } } velocity-1.7/src/test/org/apache/velocity/util/0000755000175000017500000000000011675166247021507 5ustar moellermoellervelocity-1.7/src/test/org/apache/velocity/util/SimplePoolTestCase.java0000644000175000017500000000341310513464370026056 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Simpletest for the SimplePool * * @version $Id: SimplePoolTestCase.java 463298 2006-10-12 16:10:32Z henning $ */ public class SimplePoolTestCase extends TestCase { public static Test suite() { return new TestSuite(SimplePoolTestCase.class); } public SimplePoolTestCase(String testName) { super(testName); } public void testPool() throws Exception { SimplePool sp = new SimplePool(10); for (int i=0; i<10; i++) { sp.put(new Integer(i)); } for (int i=9; i>=0; i--) { Integer obj = (Integer) sp.get(); assertTrue(i == obj.intValue()); } Object[] pool = sp.getPool(); for (int i=0; i<10; i++) { assertTrue("Pool not empty", pool[i] == null); } } } velocity-1.7/src/java/0000755000175000017500000000000011675166247014626 5ustar moellermoellervelocity-1.7/src/java/org/0000755000175000017500000000000011675166247015415 5ustar moellermoellervelocity-1.7/src/java/org/apache/0000755000175000017500000000000011675166247016636 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/0000755000175000017500000000000011675166252020470 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/app/0000755000175000017500000000000011675166250021246 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/app/tools/0000755000175000017500000000000011675166247022414 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/app/tools/VelocityFormatter.java0000644000175000017500000003017310631352756026736 0ustar moellermoellerpackage org.apache.velocity.app.tools; /* * 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. */ import java.lang.reflect.Array; import java.text.DateFormat; import java.util.Date; import java.util.List; import org.apache.velocity.context.Context; /** * Formatting tool for inserting into the Velocity WebContext. Can * format dates or lists of objects. * *

    Here's an example of some uses: * *

     * $formatter.formatShortDate($object.Date)
     * $formatter.formatLongDate($db.getRecord(232).getDate())
     * $formatter.formatArray($array)
     * $formatter.limitLen(30, $object.Description)
     * 
    * * @deprecated This class has been replaced by NumberTool, DateTool, * DisplayTool, and AlternatorTool available from the Velocity-Tools sub-project. * VelocityFormatter will be removed in a future version of Velocity. * * @author Sean Legassick * @author Daniel Rall * @version $Id: VelocityFormatter.java 544641 2007-06-05 21:30:22Z nbubna $ */ public class VelocityFormatter { Context context = null; /** * Constructor needs a backpointer to the context. * * @param context A Context. */ public VelocityFormatter(Context context) { this.context = context; } /** * Formats a date in DateFormat.SHORT style. * * @param date The date to format. * @return The formatted date as text. */ public String formatShortDate(Date date) { return DateFormat.getDateInstance(DateFormat.SHORT).format(date); } /** * Formats a date in DateFormat.LONG style. * * @param date The date to format. * @return The formatted date as text. */ public String formatLongDate(Date date) { return DateFormat.getDateInstance(DateFormat.LONG).format(date); } /** * Formats a date/time in 'short' style. * * @param date The date to format. * @return The formatted date as text. */ public String formatShortDateTime(Date date) { return DateFormat .getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(date); } /** * Formats a date/time in 'long' style. * * @param date The date to format. * @return The formatted date as text. */ public String formatLongDateTime(Date date) { return DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG).format(date); } /** * Formats an array into the form "A, B and C". * * @param array An Object. * @return A String. */ public String formatArray(Object array) { return formatArray(array, ", ", " and "); } /** * Formats an array into the form * "A<delim>B<delim>C". * * @param array An Object. * @param delim A String. * @return A String. */ public String formatArray(Object array, String delim) { return formatArray(array, delim, delim); } /** * Formats an array into the form * "A<delim>B<finaldelim>C". * * @param array An Object. * @param delim A String. * @param finaldelim A String. * @return A String. */ public String formatArray(Object array, String delim, String finaldelim) { StringBuffer sb = new StringBuffer(); int arrayLen = Array.getLength(array); for (int i = 0; i < arrayLen; i++) { // Use the Array.get method as this will automatically // wrap primitive types in a suitable Object-derived // wrapper if necessary. sb.append(Array.get(array, i).toString()); if (i < arrayLen - 2) { sb.append(delim); } else if (i < arrayLen - 1) { sb.append(finaldelim); } } return sb.toString(); } /** * Formats a vector into the form "A, B and C". * * @param list The list of elements to format. * @return A String. */ public String formatVector(List list) { return formatVector(list, ", ", " and "); } /** * Formats a vector into the form "A<delim>B<delim>C". * * @param list The list of elements to format. * @param delim A String. * @return A String. */ public String formatVector(List list, String delim) { return formatVector(list, delim, delim); } /** * Formats a list into the form * "Adelim>B<finaldelim>C". * * @param list The list of elements to format. * @param delim A String. * @param finaldelim A String. * @return A String. */ public String formatVector(List list, String delim, String finaldelim) { StringBuffer sb = new StringBuffer(); int size = list.size(); for (int i = 0; i < size; i++) { sb.append(list.get(i)); if (i < size - 2) { sb.append(delim); } else if (i < size - 1) { sb.append(finaldelim); } } return sb.toString(); } /** * Limits 'string' to 'maxlen' characters. If the string gets * curtailed, "..." is appended to it. * * @param maxlen An int with the maximum length. * @param string A String. * @return A String. */ public String limitLen(int maxlen, String string) { return limitLen(maxlen, string, "..."); } /** * Limits 'string' to 'maxlen' character. If the string gets * curtailed, 'suffix' is appended to it. * * @param maxlen An int with the maximum length. * @param string A String. * @param suffix A String. * @return A String. */ public String limitLen(int maxlen, String string, String suffix) { String ret = string; if (string.length() > maxlen) { ret = string.substring(0, maxlen - suffix.length()) + suffix; } return ret; } /** * Class that returns alternating values in a template. It stores * a list of alternate Strings, whenever alternate() is called it * switches to the next in the list. The current alternate is * retrieved through toString() - i.e. just by referencing the * object in a Velocity template. For an example of usage see the * makeAlternator() method below. */ public class VelocityAlternator { /** * */ protected String[] alternates = null; /** * */ protected int current = 0; /** * Constructor takes an array of Strings. * * @param alternates A String[]. */ public VelocityAlternator(String[] alternates) { this.alternates = alternates; } /** * Alternates to the next in the list. * * @return The current alternate in the sequence. */ public String alternate() { current++; current %= alternates.length; return ""; } /** * Returns the current alternate. * * @return A String. */ public String toString() { return alternates[current]; } } /** * As VelocityAlternator, but calls alternate() * automatically on rendering in a template. */ public class VelocityAutoAlternator extends VelocityAlternator { /** * Constructor takes an array of Strings. * * @param alternates A String[]. */ public VelocityAutoAlternator(String[] alternates) { super(alternates); } /** * Returns the current alternate, and automatically alternates * to the next alternate in its sequence (trigged upon * rendering). * * @return The current alternate in the sequence. */ public final String toString() { String s = alternates[current]; alternate(); return s; } } /** * Makes an alternator object that alternates between two values. * *

    Example usage in a Velocity template: * *

         * <table>
         * $formatter.makeAlternator("rowcolor", "#c0c0c0", "#e0e0e0")
         * #foreach $item in $items
         * #begin
         * <tr><td bgcolor="$rowcolor">$item.Name</td></tr>
         * $rowcolor.alternate()
         * #end
         * </table>
         * 
    * * @param name The name for the alternator int the context. * @param alt1 The first alternate. * @param alt2 The second alternate. * @return The newly created instance. */ public String makeAlternator(String name, String alt1, String alt2) { String[] alternates = { alt1, alt2 }; context.put(name, new VelocityAlternator(alternates)); return ""; } /** * Makes an alternator object that alternates between three * values. * @param name * @param alt1 * @param alt2 * @param alt3 * @return alternated object. * * @see #makeAlternator(String name, String alt1, String alt2) */ public String makeAlternator(String name, String alt1, String alt2, String alt3) { String[] alternates = { alt1, alt2, alt3 }; context.put(name, new VelocityAlternator(alternates)); return ""; } /** * Makes an alternator object that alternates between four values. * @param name * @param alt1 * @param alt2 * @param alt3 * @param alt4 * @return Alternated object. * * @see #makeAlternator(String name, String alt1, String alt2) */ public String makeAlternator(String name, String alt1, String alt2, String alt3, String alt4) { String[] alternates = { alt1, alt2, alt3, alt4 }; context.put(name, new VelocityAlternator(alternates)); return ""; } /** * Makes an alternator object that alternates between two values * automatically. * @param name * @param alt1 * @param alt2 * @return Alternated object. * * @see #makeAlternator(String name, String alt1, String alt2) */ public String makeAutoAlternator(String name, String alt1, String alt2) { String[] alternates = { alt1, alt2 }; context.put(name, new VelocityAutoAlternator(alternates)); return ""; } /** * Returns a default value if the object passed is null. * @param o * @param dflt * @return Object or default value when object is null. */ public Object isNull(Object o, Object dflt) { if ( o == null ) { return dflt; } else { return o; } } } velocity-1.7/src/java/org/apache/velocity/app/event/0000755000175000017500000000000011675166247022375 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/app/event/EventHandler.java0000644000175000017500000000207510513464370025607 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ /** * Base interface for all event handlers * * @author Geir Magnusson Jr. * @version $Id: EventHandler.java 463298 2006-10-12 16:10:32Z henning $ */ public interface EventHandler { } velocity-1.7/src/java/org/apache/velocity/app/event/EventHandlerMethodExecutor.java0000644000175000017500000000417111050652577030473 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ /** * Strategy object used to execute event handler method. Will be called * while looping through all the chained event handler implementations. * Each EventHandler method call should have a parallel executor object * defined. * * @author Will Glass-Husain * @version $Id: EventHandlerMethodExecutor.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface EventHandlerMethodExecutor { /** * Execute the event handler method. If Object is not null, do not * iterate further through the handler chain. * If appropriate, the returned Object will be the return value. * * @param handler call the appropriate method on this handler * @exception Exception generic exception potentially thrown by event handlers */ public void execute(EventHandler handler) throws Exception; /** * Called after execute() to see if iterating should stop. Should * always return false before method execute() is run. * * @return true if no more event handlers for this method should be called. */ public boolean isDone(); /** * Get return value at end of all the iterations * * @return null if no return value is required */ public Object getReturnValue(); } velocity-1.7/src/java/org/apache/velocity/app/event/MethodExceptionEventHandler.java0000644000175000017500000000726711050652577030644 0ustar moellermoellerpackage org.apache.velocity.app.event; import org.apache.velocity.context.Context; import org.apache.velocity.util.ContextAware; /* * 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. */ /** * Event handler called when a method throws an exception. This gives the * application a chance to deal with it and either * return something nice, or throw. * * Please return what you want rendered into the output stream. * * @author Will Glass-Husain * @author Geir Magnusson Jr. * @version $Id: MethodExceptionEventHandler.java 685685 2008-08-13 21:43:27Z nbubna $ */ public interface MethodExceptionEventHandler extends EventHandler { /** * Called when a method throws an exception. * Only the first registered MethodExceptionEventHandler is called. If * none are registered a MethodInvocationException is thrown. * * @param claz the class of the object the method is being applied to * @param method the method * @param e the thrown exception * @return an object to insert in the page * @throws Exception an exception to be thrown instead inserting an object */ public Object methodException( Class claz, String method, Exception e ) throws Exception; /** * Defines the execution strategy for methodException * @since 1.5 */ static class MethodExceptionExecutor implements EventHandlerMethodExecutor { private Context context; private Class claz; private String method; private Exception e; private Object result; private boolean executed = false; MethodExceptionExecutor( Context context, Class claz, String method, Exception e) { this.context = context; this.claz = claz; this.method = method; this.e = e; } /** * Call the method methodException() * * @param handler call the appropriate method on this handler * @exception Exception generic exception thrown by methodException event handler method call */ public void execute(EventHandler handler) throws Exception { MethodExceptionEventHandler eh = (MethodExceptionEventHandler) handler; if (eh instanceof ContextAware) ((ContextAware) eh).setContext(context); executed = true; result = ((MethodExceptionEventHandler) handler).methodException(claz, method, e); } public Object getReturnValue() { return result; } /** * Only run the first MethodExceptionEventHandler * * @return true after this is executed once. */ public boolean isDone() { return executed; } } } velocity-1.7/src/java/org/apache/velocity/app/event/IncludeEventHandler.java0000644000175000017500000000762011050652577027121 0ustar moellermoellerpackage org.apache.velocity.app.event; import org.apache.velocity.context.Context; import org.apache.velocity.util.ContextAware; /* * 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. */ /** * Event handler for include type directives (e.g. #include(), #parse()) * Allows the developer to modify the path of the resource returned. * * @author Will Glass-Husain * @version $Id: IncludeEventHandler.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface IncludeEventHandler extends EventHandler { /** * Called when an include-type directive is encountered ( * #include or #parse). May modify the path * of the resource to be included or may block the include entirely. All the * registered IncludeEventHandlers are called unless null is returned. If * none are registered the template at the includeResourcePath is retrieved. * * @param includeResourcePath the path as given in the include directive. * @param currentResourcePath the path of the currently rendering template that includes the * include directive. * @param directiveName name of the directive used to include the resource. (With the * standard directives this is either "parse" or "include"). * * @return a new resource path for the directive, or null to block the * include from occurring. */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName ); /** * Defines the execution strategy for includeEvent */ static class IncludeEventExecutor implements EventHandlerMethodExecutor { private Context context; private String includeResourcePath; private String currentResourcePath; private String directiveName; private boolean executed = false; IncludeEventExecutor( Context context, String includeResourcePath, String currentResourcePath, String directiveName) { this.context = context; this.includeResourcePath = includeResourcePath; this.currentResourcePath = currentResourcePath; this.directiveName = directiveName; } /** * Call the method includeEvent() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { IncludeEventHandler eh = (IncludeEventHandler) handler; if (eh instanceof ContextAware) ((ContextAware) eh).setContext(context); executed = true; includeResourcePath = ((IncludeEventHandler) handler) .includeEvent(includeResourcePath, currentResourcePath, directiveName); } public Object getReturnValue() { return includeResourcePath; } public boolean isDone() { return executed && (includeResourcePath == null); } } } velocity-1.7/src/java/org/apache/velocity/app/event/InvalidReferenceEventHandler.java0000644000175000017500000001740611273756257030755 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ import org.apache.velocity.context.Context; import org.apache.velocity.util.introspection.Info; /** * Event handler called when an invalid reference is encountered. Allows * the application to report errors or substitute return values. May be chained * in sequence; the behavior will differ per method. * *

    This feature should be regarded as experimental. * * @author Will Glass-Husain * @version $Id: InvalidReferenceEventHandler.java 832324 2009-11-03 07:33:03Z wglass $ * @since 1.5 */ public interface InvalidReferenceEventHandler extends EventHandler { /** * Called when object is null or there is no getter for the given * property. Also called for invalid references without properties. * invalidGetMethod() will be called in sequence for * each link in the chain until the first non-null value is * returned. * * @param context the context when the reference was found invalid * @param reference string with complete invalid reference. If silent reference, will start with $! * @param object the object referred to, or null if not found * @param property the property name from the reference * @param info contains template, line, column details * @return substitute return value for missing reference, or null if no substitute */ public Object invalidGetMethod(Context context, String reference, Object object, String property, Info info); /** * Called when object is null or there is no setter for the given * property. invalidSetMethod() will be called in sequence for * each link in the chain until a true value is returned. It's * recommended that false be returned as a default to allow * for easy chaining. * * @param context the context when the reference was found invalid * @param leftreference left reference being assigned to * @param rightreference invalid reference on the right * @param info contains info on template, line, col * * @return if true then stop calling invalidSetMethod along the * chain. */ public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info); /** * Called when object is null or the given method does not exist. * invalidMethod() will be called in sequence for each link in * the chain until the first non-null value is returned. * * @param context the context when the reference was found invalid * @param reference string with complete invalid reference. If silent reference, will start with $! * @param object the object referred to, or null if not found * @param method the name of the (non-existent) method * @param info contains template, line, column details * @return substitute return value for missing reference, or null if no substitute */ public Object invalidMethod(Context context, String reference, Object object, String method, Info info); /** * Defines the execution strategy for invalidGetMethod */ static class InvalidGetMethodExecutor implements EventHandlerMethodExecutor { private Context context; private String reference; private Object object; private String property; private Info info; private Object result; InvalidGetMethodExecutor( Context context, String reference, Object object, String property, Info info) { this.context = context; this.reference = reference; this.object = object; this.property = property; this.info = info; } /** * Call the method invalidGetMethod() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { result = ((InvalidReferenceEventHandler) handler).invalidGetMethod( context, reference, object, property, info); } public Object getReturnValue() { return result; } public boolean isDone() { return (result != null); } } /** * Defines the execution strategy for invalidGetMethod */ static class InvalidSetMethodExecutor implements EventHandlerMethodExecutor { private Context context; private String leftreference; private String rightreference; private Info info; private boolean result; InvalidSetMethodExecutor( Context context, String leftreference, String rightreference, Info info) { this.context = context; this.leftreference = leftreference; this.rightreference = rightreference; this.info = info; } /** * Call the method invalidSetMethod() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { result = ((InvalidReferenceEventHandler) handler).invalidSetMethod( context, leftreference, rightreference, info); } public Object getReturnValue() { return null; } public boolean isDone() { return result; } } /** * Defines the execution strategy for invalidGetMethod */ static class InvalidMethodExecutor implements EventHandlerMethodExecutor { private Context context; private String reference; private Object object; private String method; private Info info; private Object result; private boolean executed = false; InvalidMethodExecutor( Context context, String reference, Object object, String method, Info info) { this.context = context; this.reference = reference; this.object = object; this.method = method; this.info = info; } /** * Call the method invalidMethod() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { executed = true; result = ((InvalidReferenceEventHandler) handler).invalidMethod( context, reference, object, method, info); } public Object getReturnValue() { return result; } public boolean isDone() { return executed && (result != null); } } } velocity-1.7/src/java/org/apache/velocity/app/event/EventCartridge.java0000644000175000017500000002627711050652577026155 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.velocity.context.Context; import org.apache.velocity.context.InternalEventContext; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; /** * Stores the event handlers. Event handlers can be assigned on a per * VelocityEngine instance basis by specifying the class names in the * velocity.properties file. Event handlers may also be assigned on a per-page * basis by creating a new instance of EventCartridge, adding the event * handlers, and then calling attachToContext. For clarity, it's recommended * that one approach or the other be followed, as the second method is primarily * presented for backwards compatibility. * *

    * Note that Event Handlers follow a filter pattern, with multiple event * handlers allowed for each event. When the appropriate event occurs, all the * appropriate event handlers are called in the sequence they were added to the * Event Cartridge. See the javadocs of the specific event handler interfaces * for more details. * * @author Will Glass-Husain * @author Geir Magnusson Jr. * @author Jose Alberto Fernandez * @version $Id: EventCartridge.java 685685 2008-08-13 21:43:27Z nbubna $ */ public class EventCartridge { private List referenceHandlers = new ArrayList(); private List nullSetHandlers = new ArrayList(); private List methodExceptionHandlers = new ArrayList(); private List includeHandlers = new ArrayList(); private List invalidReferenceHandlers = new ArrayList(); /** * Ensure that handlers are not initialized more than once. */ Set initializedHandlers = new HashSet(); /** * Adds an event handler(s) to the Cartridge. This method * will find all possible event handler interfaces supported * by the passed in object. * * @param ev object impementing a valid EventHandler-derived interface * @return true if a supported interface, false otherwise or if null */ public boolean addEventHandler( EventHandler ev ) { if (ev == null) { return false; } boolean found = false; if ( ev instanceof ReferenceInsertionEventHandler) { addReferenceInsertionEventHandler( (ReferenceInsertionEventHandler) ev ); found = true; } if ( ev instanceof NullSetEventHandler ) { addNullSetEventHandler( (NullSetEventHandler) ev ); found = true; } if ( ev instanceof MethodExceptionEventHandler ) { addMethodExceptionHandler( (MethodExceptionEventHandler) ev ); found = true; } if ( ev instanceof IncludeEventHandler ) { addIncludeEventHandler( (IncludeEventHandler) ev ); found = true; } if ( ev instanceof InvalidReferenceEventHandler ) { addInvalidReferenceEventHandler( (InvalidReferenceEventHandler) ev ); found = true; } return found; } /** * Add a reference insertion event handler to the Cartridge. * * @param ev ReferenceInsertionEventHandler * @since 1.5 */ public void addReferenceInsertionEventHandler( ReferenceInsertionEventHandler ev ) { referenceHandlers.add( ev ); } /** * Add a null set event handler to the Cartridge. * * @param ev NullSetEventHandler * @since 1.5 */ public void addNullSetEventHandler( NullSetEventHandler ev ) { nullSetHandlers.add( ev ); } /** * Add a method exception event handler to the Cartridge. * * @param ev MethodExceptionEventHandler * @since 1.5 */ public void addMethodExceptionHandler( MethodExceptionEventHandler ev ) { methodExceptionHandlers.add( ev ); } /** * Add an include event handler to the Cartridge. * * @param ev IncludeEventHandler * @since 1.5 */ public void addIncludeEventHandler( IncludeEventHandler ev ) { includeHandlers.add( ev ); } /** * Add an invalid reference event handler to the Cartridge. * * @param ev InvalidReferenceEventHandler * @since 1.5 */ public void addInvalidReferenceEventHandler( InvalidReferenceEventHandler ev ) { invalidReferenceHandlers.add( ev ); } /** * Removes an event handler(s) from the Cartridge. This method will find all * possible event handler interfaces supported by the passed in object and * remove them. * * @param ev object impementing a valid EventHandler-derived interface * @return true if event handler was previously registered, false if not * found */ public boolean removeEventHandler( EventHandler ev ) { if ( ev == null ) { return false; } boolean found = false; if ( ev instanceof ReferenceInsertionEventHandler ) return referenceHandlers.remove( ev ); if ( ev instanceof NullSetEventHandler ) return nullSetHandlers.remove( ev ); if ( ev instanceof MethodExceptionEventHandler ) return methodExceptionHandlers.remove(ev ); if ( ev instanceof IncludeEventHandler ) return includeHandlers.remove( ev ); if ( ev instanceof InvalidReferenceEventHandler ) return invalidReferenceHandlers.remove( ev ); return found; } /** * Iterate through all the stored ReferenceInsertionEventHandler objects * * @return iterator of handler objects, null if there are not handlers * @since 1.5 */ public Iterator getReferenceInsertionEventHandlers() { return referenceHandlers.size() == 0 ? null : referenceHandlers.iterator(); } /** * Iterate through all the stored NullSetEventHandler objects * * @return iterator of handler objects * @since 1.5 */ public Iterator getNullSetEventHandlers() { return nullSetHandlers.iterator(); } /** * Iterate through all the stored MethodExceptionEventHandler objects * * @return iterator of handler objects * @since 1.5 */ public Iterator getMethodExceptionEventHandlers() { return methodExceptionHandlers.iterator(); } /** * Iterate through all the stored IncludeEventHandlers objects * * @return iterator of handler objects */ public Iterator getIncludeEventHandlers() { return includeHandlers.iterator(); } /** * Iterate through all the stored InvalidReferenceEventHandlers objects * * @return iterator of handler objects * @since 1.5 */ public Iterator getInvalidReferenceEventHandlers() { return invalidReferenceHandlers.iterator(); } /** * Attached the EventCartridge to the context * * Final because not something one should mess with lightly :) * * @param context context to attach to * @return true if successful, false otherwise */ public final boolean attachToContext( Context context ) { if ( context instanceof InternalEventContext ) { InternalEventContext iec = (InternalEventContext) context; iec.attachEventCartridge( this ); /** * while it's tempting to call setContext on each handler from here, * this needs to be done before each method call. This is * because the specific context will change as inner contexts * are linked in through macros, foreach, or directly by the user. */ return true; } else { return false; } } /** * Initialize the handlers. For global handlers this is called when Velocity * is initialized. For local handlers this is called when the first handler * is executed. Handlers will not be initialized more than once. * * @param rs * @throws Exception * @since 1.5 */ public void initialize (RuntimeServices rs) throws Exception { for ( Iterator i = referenceHandlers.iterator(); i.hasNext(); ) { EventHandler eh = ( EventHandler ) i.next(); if ( (eh instanceof RuntimeServicesAware) && !initializedHandlers.contains(eh) ) { ((RuntimeServicesAware) eh).setRuntimeServices ( rs ); initializedHandlers.add( eh ); } } for ( Iterator i = nullSetHandlers.iterator(); i.hasNext(); ) { EventHandler eh = ( EventHandler ) i.next(); if ( (eh instanceof RuntimeServicesAware) && !initializedHandlers.contains(eh) ) { ((RuntimeServicesAware) eh).setRuntimeServices ( rs ); initializedHandlers.add( eh ); } } for ( Iterator i = methodExceptionHandlers.iterator(); i.hasNext(); ) { EventHandler eh = ( EventHandler ) i.next(); if ( (eh instanceof RuntimeServicesAware) && !initializedHandlers.contains(eh) ) { ((RuntimeServicesAware) eh).setRuntimeServices ( rs ); initializedHandlers.add( eh ); } } for ( Iterator i = includeHandlers.iterator(); i.hasNext(); ) { EventHandler eh = ( EventHandler ) i.next(); if ( (eh instanceof RuntimeServicesAware) && !initializedHandlers.contains(eh) ) { ((RuntimeServicesAware) eh).setRuntimeServices ( rs ); initializedHandlers.add( eh ); } } for ( Iterator i = invalidReferenceHandlers.iterator(); i.hasNext(); ) { EventHandler eh = ( EventHandler ) i.next(); if ( (eh instanceof RuntimeServicesAware) && !initializedHandlers.contains(eh) ) { ((RuntimeServicesAware) eh).setRuntimeServices ( rs ); initializedHandlers.add( eh ); } } } } velocity-1.7/src/java/org/apache/velocity/app/event/NullSetEventHandler.java0000644000175000017500000000653511050652577027130 0ustar moellermoellerpackage org.apache.velocity.app.event; import org.apache.velocity.context.Context; import org.apache.velocity.util.ContextAware; /* * 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. */ /** * Event handler called when the RHS of #set is null. Lets an app approve / veto * writing a log message based on the specific reference. * * @author Will Glass-Husain * @author Geir Magnusson Jr. * @version $Id: NullSetEventHandler.java 685685 2008-08-13 21:43:27Z nbubna $ */ public interface NullSetEventHandler extends EventHandler { /** * Called when the RHS of a #set() is null, which will result * in a null LHS. All NullSetEventHandlers * are called in sequence until a false is returned. If no NullSetEventHandler * is registered all nulls will be logged. * * @param lhs reference literal of left-hand-side of set statement * @param rhs reference literal of right-hand-side of set statement * @return true if log message should be written, false otherwise */ public boolean shouldLogOnNullSet( String lhs, String rhs ); /** * Defines the execution strategy for shouldLogOnNullSet * @since 1.5 */ static class ShouldLogOnNullSetExecutor implements EventHandlerMethodExecutor { private Context context; private String lhs; private String rhs; /** * when this is false, quit iterating */ private boolean result = true; private boolean executed = false; ShouldLogOnNullSetExecutor( Context context, String lhs, String rhs) { this.context = context; this.lhs = lhs; this.rhs = rhs; } /** * Call the method shouldLogOnNullSet() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { NullSetEventHandler eh = (NullSetEventHandler) handler; if (eh instanceof ContextAware) ((ContextAware) eh).setContext(context); executed = true; result = ((NullSetEventHandler) handler).shouldLogOnNullSet(lhs, rhs); } public Object getReturnValue() { // return new Boolean(result); return result ? Boolean.TRUE : Boolean.FALSE; } public boolean isDone() { return executed && !result; } } } velocity-1.7/src/java/org/apache/velocity/app/event/ReferenceInsertionEventHandler.java0000644000175000017500000000706311050652577031330 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ import org.apache.velocity.context.Context; import org.apache.velocity.util.ContextAware; /** * Reference 'Stream insertion' event handler. Called with object * that will be inserted into stream via value.toString(). * * Please return an Object that will toString() nicely :) * * @author Will Glass-Husain * @author Geir Magnusson Jr. * @version $Id: ReferenceInsertionEventHandler.java 685685 2008-08-13 21:43:27Z nbubna $ */ public interface ReferenceInsertionEventHandler extends EventHandler { /** * A call-back which is executed during Velocity merge before a reference * value is inserted into the output stream. All registered * ReferenceInsertionEventHandlers are called in sequence. If no * ReferenceInsertionEventHandlers are are registered then reference value * is inserted into the output stream as is. * * @param reference Reference from template about to be inserted. * @param value Value about to be inserted (after its toString() * method is called). * @return Object on which toString() should be called for * output. */ public Object referenceInsert( String reference, Object value ); /** * Defines the execution strategy for referenceInsert * @since 1.5 */ static class referenceInsertExecutor implements EventHandlerMethodExecutor { private Context context; private String reference; private Object value; referenceInsertExecutor( Context context, String reference, Object value) { this.context = context; this.reference = reference; this.value = value; } /** * Call the method referenceInsert() * * @param handler call the appropriate method on this handler */ public void execute(EventHandler handler) { ReferenceInsertionEventHandler eh = (ReferenceInsertionEventHandler) handler; if (eh instanceof ContextAware) ((ContextAware) eh).setContext(context); /** * Every successive call will alter the same value */ value = ((ReferenceInsertionEventHandler) handler).referenceInsert(reference, value); } public Object getReturnValue() { return value; } /** * Continue to end of event handler iteration * * @return always returns false */ public boolean isDone() { return false; } } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/0000755000175000017500000000000011675166247024367 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/app/event/implement/EscapeReference.java0000644000175000017500000001223511050652577030245 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.oro.text.perl.MalformedPerl5PatternException; import org.apache.oro.text.perl.Perl5Util; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; import org.apache.velocity.util.StringUtils; /** * Base class for escaping references. To use it, override the following methods: *

    *
    String escape(String text)
    *
    escape the provided text
    *
    String getMatchAttribute()
    *
    retrieve the configuration attribute used to match references (see below)
    *
    * *

    By default, all references are escaped. However, by setting the match attribute * in the configuration file to a regular expression, users can specify which references * to escape. For example the following configuration property tells the EscapeSqlReference * event handler to only escape references that start with "sql". * (e.g. $sql, $sql.toString(),, etc). * *

     * eventhandler.escape.sql.match = /sql.*/
     * 
     * 
    * * * Regular expressions should follow the "Perl5" format used by the ORO regular expression * library. More info is at * http://jakarta.apache.org/oro/api/org/apache/oro/text/perl/package-summary.html. * * @author Will Glass-Husain * @version $Id: EscapeReference.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public abstract class EscapeReference implements ReferenceInsertionEventHandler,RuntimeServicesAware { private Perl5Util perl = new Perl5Util(); private RuntimeServices rs; private String matchRegExp = null; /** * Escape the given text. Override this in a subclass to do the actual * escaping. * * @param text the text to escape * @return the escaped text */ protected abstract String escape(Object text); /** * Specify the configuration attribute that specifies the * regular expression. Ideally should be in a form *
    eventhandler.escape.XYZ.match
    * *

    where XYZ is the type of escaping being done. * @return configuration attribute */ protected abstract String getMatchAttribute(); /** * Escape the provided text if it matches the configured regular expression. * * @param reference * @param value * @return Escaped text. */ public Object referenceInsert(String reference, Object value) { if(value == null) { return value; } if (matchRegExp == null) { return escape(value); } else if (perl.match(matchRegExp,reference)) { return escape(value); } else { return value; } } /** * Called automatically when event cartridge is initialized. * * @param rs instance of RuntimeServices */ public void setRuntimeServices(RuntimeServices rs) { this.rs = rs; /** * Get the regular expression pattern. */ matchRegExp = StringUtils.nullTrim(rs.getConfiguration().getString(getMatchAttribute())); if ((matchRegExp != null) && (matchRegExp.length() == 0)) { matchRegExp = null; } /** * Test the regular expression for a well formed pattern */ if (matchRegExp != null) { try { perl.match(matchRegExp,""); } catch (MalformedPerl5PatternException E) { rs.getLog().error("Invalid regular expression '" + matchRegExp + "'. No escaping will be performed.", E); matchRegExp = null; } } } /** * Retrieve a reference to RuntimeServices. Use this for checking additional * configuration properties. * * @return The current runtime services object. */ protected RuntimeServices getRuntimeServices() { return rs; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/EscapeSqlReference.java0000644000175000017500000000350611050652577030726 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.commons.lang.StringEscapeUtils; /** * Escapes the characters in a String to be suitable to pass to an SQL query. * @see StringEscapeUtils * @author wglass * @since 1.5 */ public class EscapeSqlReference extends EscapeReference { /** * Escapes the characters in a String to be suitable to pass to an SQL query. * * @param text * @return An escaped string. * @see StringEscapeUtils */ protected String escape(Object text) { return StringEscapeUtils.escapeSql(text.toString()); } /** * @return attribute "eventhandler.escape.sql.match" */ protected String getMatchAttribute() { return "eventhandler.escape.sql.match"; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/EscapeXmlReference.java0000644000175000017500000000334211050652577030725 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.commons.lang.StringEscapeUtils; /** * Escape all XML entities. * @see StringEscapeUtils * @author wglass * @since 1.5 */ public class EscapeXmlReference extends EscapeReference { /** * Escape all XML entities. * * @param text * @return An escaped String. * @see StringEscapeUtils */ protected String escape(Object text) { return StringEscapeUtils.escapeXml(text.toString()); } /** * @return attribute "eventhandler.escape.xml.match" */ protected String getMatchAttribute() { return "eventhandler.escape.xml.match"; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/IncludeNotFound.java0000644000175000017500000000770311247126663030272 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.ContextAware; import org.apache.velocity.util.RuntimeServicesAware; import org.apache.velocity.util.StringUtils; /** * Simple event handler that checks to see if an included page is available. * If not, it includes a designated replacement page instead. * *

    By default, the name of the replacement page is "notfound.vm", however this * page name can be changed by setting the Velocity property * eventhandler.include.notfound, for example: * *

     * eventhandler.include.notfound = error.vm
     * 
    * *

    * The name of the missing resource is put into the Velocity context, under the * key "missingResource", so that the "notfound" template can report the missing * resource with a Velocity reference, like: * $missingResource *

    * * @author Will Glass-Husain * @version $Id: IncludeNotFound.java 809816 2009-09-01 05:14:27Z nbubna $ * @since 1.5 */ public class IncludeNotFound implements IncludeEventHandler,RuntimeServicesAware,ContextAware { private static final String DEFAULT_NOT_FOUND = "notfound.vm"; private static final String PROPERTY_NOT_FOUND = "eventhandler.include.notfound"; private RuntimeServices rs = null; String notfound; Context context; /** * Chseck to see if included file exists, and display "not found" page if it * doesn't. If "not found" page does not exist, log an error and return * null. * * @param includeResourcePath * @param currentResourcePath * @param directiveName * @return message. */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName) { /** * check to see if page exists */ boolean exists = (rs.getLoaderNameForResource(includeResourcePath) != null); if (!exists) { context.put("missingResource", includeResourcePath); if (rs.getLoaderNameForResource(notfound) != null) { return notfound; } else { /** * can't find not found, so display nothing */ rs.getLog().error("Can't find include not found page: " + notfound); return null; } } else return includeResourcePath; } /** * @see org.apache.velocity.util.RuntimeServicesAware#setRuntimeServices(org.apache.velocity.runtime.RuntimeServices) */ public void setRuntimeServices(RuntimeServices rs) { this.rs = rs; notfound = StringUtils.nullTrim(rs.getString(PROPERTY_NOT_FOUND, DEFAULT_NOT_FOUND)); } /** * @see org.apache.velocity.util.ContextAware#setContext(org.apache.velocity.context.Context) */ public void setContext(Context context) { this.context = context; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/InvalidReferenceInfo.java0000644000175000017500000000401011050652577031237 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.velocity.util.introspection.Info; /** * Convenience class to use when reporting out invalid syntax * with line, column, and template name. * * @author Will Glass-Husain * @version $Id: InvalidReferenceInfo.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class InvalidReferenceInfo extends Info { private String invalidReference; public InvalidReferenceInfo(String invalidReference, Info info) { super(info.getTemplateName(),info.getLine(),info.getColumn()); this.invalidReference = invalidReference; } /** * Get the specific invalid reference string. * @return the invalid reference string */ public String getInvalidReference() { return invalidReference; } /** * Formats a textual representation of this object as SOURCE * [line X, column Y]: invalidReference. * * @return String representing this object. */ public String toString() { return getTemplateName() + " [line " + getLine() + ", column " + getColumn() + "]: " + invalidReference; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/EscapeHtmlReference.java0000644000175000017500000000335211050652577031072 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.commons.lang.StringEscapeUtils; /** * Escape all HTML entities. * @see StringEscapeUtils * @author wglass * @since 1.5 */ public class EscapeHtmlReference extends EscapeReference { /** * Escape all HTML entities. * * @param text * @return An escaped String. * @see StringEscapeUtils */ protected String escape(Object text) { return StringEscapeUtils.escapeHtml(text.toString()); } /** * @return attribute "eventhandler.escape.html.match" */ protected String getMatchAttribute() { return "eventhandler.escape.html.match"; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/ReportInvalidReferences.java0000644000175000017500000001450611050652577032015 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import java.util.ArrayList; import java.util.List; import org.apache.velocity.app.event.InvalidReferenceEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; import org.apache.velocity.util.introspection.Info; /** * Use this event handler to flag invalid references. Since this * is intended to be used for a specific request, this should be * used as a local event handler attached to a specific context * instead of being globally defined in the Velocity properties file. * *

    * Note that InvalidReferenceHandler can be used * in two modes. If the Velocity properties file contains the following: *

     * eventhandler.invalidreference.exception = true
     * 
    * then the event handler will throw a ParseErrorRuntimeException upon * hitting the first invalid reference. This stops processing and is * passed through to the application code. The ParseErrorRuntimeException * contain information about the template name, line number, column number, * and invalid reference. * *

    * If this configuration setting is false or omitted then the page * will be processed as normal, but all invalid references will be collected * in a List of InvalidReferenceInfo objects. * *

    This feature should be regarded as experimental. * * @author Will Glass-Husain * @version $Id: ReportInvalidReferences.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class ReportInvalidReferences implements InvalidReferenceEventHandler, RuntimeServicesAware { public static final String EVENTHANDLER_INVALIDREFERENCE_EXCEPTION = "eventhandler.invalidreference.exception"; /** * List of InvalidReferenceInfo objects */ List invalidReferences = new ArrayList(); /** * If true, stop at the first invalid reference and throw an exception. */ private boolean stopOnFirstInvalidReference = false; /** * Collect the error and/or throw an exception, depending on configuration. * * @param context the context when the reference was found invalid * @param reference string with complete invalid reference * @param object the object referred to, or null if not found * @param property the property name from the reference * @param info contains template, line, column details * @return always returns null * @throws ParseErrorException */ public Object invalidGetMethod(Context context, String reference, Object object, String property, Info info) { reportInvalidReference(reference, info); return null; } /** * Collect the error and/or throw an exception, depending on configuration. * * @param context the context when the reference was found invalid * @param reference complete invalid reference * @param object the object referred to, or null if not found * @param method the property name from the reference * @param info contains template, line, column details * @return always returns null * @throws ParseErrorException */ public Object invalidMethod(Context context, String reference, Object object, String method, Info info) { if (reference == null) { reportInvalidReference(object.getClass().getName() + "." + method, info); } else { reportInvalidReference(reference, info); } return null; } /** * Collect the error and/or throw an exception, depending on configuration. * * @param context the context when the reference was found invalid * @param leftreference left reference being assigned to * @param rightreference invalid reference on the right * @param info contains info on template, line, col * @return loop to end -- always returns false */ public boolean invalidSetMethod(Context context, String leftreference, String rightreference, Info info) { reportInvalidReference(leftreference, info); return false; } /** * Check for an invalid reference and collect the error or throw an exception * (depending on configuration). * * @param reference the invalid reference * @param info line, column, template name */ private void reportInvalidReference(String reference, Info info) { InvalidReferenceInfo invalidReferenceInfo = new InvalidReferenceInfo(reference, info); invalidReferences.add(invalidReferenceInfo); if (stopOnFirstInvalidReference) { throw new ParseErrorException( "Error in page - invalid reference. ", info, invalidReferenceInfo.getInvalidReference()); } } /** * All invalid references during the processing of this page. * @return a List of InvalidReferenceInfo objects */ public List getInvalidReferences() { return invalidReferences; } /** * Called automatically when event cartridge is initialized. * @param rs RuntimeServices object assigned during initialization */ public void setRuntimeServices(RuntimeServices rs) { stopOnFirstInvalidReference = rs.getConfiguration().getBoolean( EVENTHANDLER_INVALIDREFERENCE_EXCEPTION, false); } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/EscapeJavaScriptReference.java0000644000175000017500000000355411050652577032240 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.commons.lang.StringEscapeUtils; /** * Escapes the characters in a String to be suitable for use in JavaScript. * @see StringEscapeUtils * @author wglass * @since 1.5 */ public class EscapeJavaScriptReference extends EscapeReference { /** * Escapes the characters in a String to be suitable for use in JavaScript. * * @param text * @return An escaped String. * @see StringEscapeUtils */ protected String escape(Object text) { return StringEscapeUtils.escapeJavaScript(text.toString()); } /** * @return attribute "eventhandler.escape.javascript.match" */ protected String getMatchAttribute() { return "eventhandler.escape.javascript.match"; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/IncludeRelativePath.java0000644000175000017500000000515611050652577031126 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import org.apache.velocity.app.event.IncludeEventHandler; /** *

    Event handler that looks for included files relative to the path of the * current template. The handler assumes that paths are separated by a forward * slash "/" or backwards slash "\". * * @author Will Glass-Husain * @version $Id: IncludeRelativePath.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class IncludeRelativePath implements IncludeEventHandler { /** * Return path relative to the current template's path. * * @param includeResourcePath the path as given in the include directive. * @param currentResourcePath the path of the currently rendering template that includes the * include directive. * @param directiveName name of the directive used to include the resource. (With the * standard directives this is either "parse" or "include"). * @return new path relative to the current template's path */ public String includeEvent( String includeResourcePath, String currentResourcePath, String directiveName) { // if the resource name starts with a slash, it's not a relative path if (includeResourcePath.startsWith("/") || includeResourcePath.startsWith("\\") ) { return includeResourcePath; } int lastslashpos = Math.max( currentResourcePath.lastIndexOf("/"), currentResourcePath.lastIndexOf("\\") ); // root of resource tree if (lastslashpos == -1) { return includeResourcePath; } // prepend path to the include path return currentResourcePath.substring(0,lastslashpos) + "/" + includeResourcePath; } } velocity-1.7/src/java/org/apache/velocity/app/event/implement/PrintExceptions.java0000644000175000017500000001031311050652577030357 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import java.io.PrintWriter; import java.io.StringWriter; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; /** * Simple event handler that renders method exceptions in the page * rather than throwing the exception. Useful for debugging. * *

    By default this event handler renders the exception name only. * To include both the exception name and the message, set the property * eventhandler.methodexception.message to true. To render * the stack trace, set the property eventhandler.methodexception.stacktrace * to true. * * @author Will Glass-Husain * @version $Id: PrintExceptions.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class PrintExceptions implements MethodExceptionEventHandler, RuntimeServicesAware { private static String SHOW_MESSAGE = "eventhandler.methodexception.message"; private static String SHOW_STACK_TRACE = "eventhandler.methodexception.stacktrace"; /** Reference to the runtime service */ private RuntimeServices rs = null; /** * Render the method exception, and optionally the exception message and stack trace. * * @param claz the class of the object the method is being applied to * @param method the method * @param e the thrown exception * @return an object to insert in the page * @throws Exception an exception to be thrown instead inserting an object */ public Object methodException(Class claz, String method, Exception e) throws Exception { boolean showMessage = rs.getBoolean(SHOW_MESSAGE,false); boolean showStackTrace = rs.getBoolean(SHOW_STACK_TRACE,false); StringBuffer st; if (showMessage && showStackTrace) { st = new StringBuffer(200); st.append(e.getClass().getName()).append("\n"); st.append(e.getMessage()).append("\n"); st.append(getStackTrace(e)); } else if (showMessage) { st = new StringBuffer(50); st.append(e.getClass().getName()).append("\n"); st.append(e.getMessage()).append("\n"); } else if (showStackTrace) { st = new StringBuffer(200); st.append(e.getClass().getName()).append("\n"); st.append(getStackTrace(e)); } else { st = new StringBuffer(15); st.append(e.getClass().getName()).append("\n"); } return st.toString(); } private static String getStackTrace(Throwable throwable) { PrintWriter printWriter = null; try { StringWriter stackTraceWriter = new StringWriter(); printWriter = new PrintWriter(stackTraceWriter); throwable.printStackTrace(printWriter); printWriter.flush(); return stackTraceWriter.toString(); } finally { if (printWriter != null) { printWriter.close(); } } } /** * @see org.apache.velocity.util.RuntimeServicesAware#setRuntimeServices(org.apache.velocity.runtime.RuntimeServices) */ public void setRuntimeServices(RuntimeServices rs) { this.rs = rs; } } velocity-1.7/src/java/org/apache/velocity/app/event/EventHandlerUtil.java0000644000175000017500000004227511050652577026460 0ustar moellermoellerpackage org.apache.velocity.app.event; /* * 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. */ import java.util.Iterator; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.ExceptionUtils; import org.apache.velocity.util.introspection.Info; /** * Calls on request all registered event handlers for a particular event. Each * method accepts two event cartridges (typically one from the application and * one from the context). All appropriate event handlers are executed in order * until a stopping condition is met. See the docs for the individual methods to * see what the stopping condition is for that method. * * @author Will Glass-Husain * @version $Id: EventHandlerUtil.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class EventHandlerUtil { /** * Called before a reference is inserted. All event handlers are called in * sequence. The default implementation inserts the reference as is. * * This is a major hotspot method called by ASTReference render. * * @param reference reference from template about to be inserted * @param value value about to be inserted (after toString() ) * @param rsvc current instance of RuntimeServices * @param context The internal context adapter. * @return Object on which toString() should be called for output. */ public static Object referenceInsert(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object value) { // app level cartridges have already been initialized /* * Performance modification: EventCartridge.getReferenceInsertionEventHandlers * now returns a null if there are no handlers. Thus we can avoid creating the * Iterator object. */ EventCartridge ev1 = rsvc.getApplicationEventCartridge(); Iterator applicationEventHandlerIterator = (ev1 == null) ? null: ev1.getReferenceInsertionEventHandlers(); EventCartridge ev2 = context.getEventCartridge(); initializeEventCartridge(rsvc, ev2); Iterator contextEventHandlerIterator = (ev2 == null) ? null: ev2.getReferenceInsertionEventHandlers(); try { /* * Performance modification: methodExecutor is created only if one of the * iterators is not null. */ EventHandlerMethodExecutor methodExecutor = null; if( applicationEventHandlerIterator != null ) { methodExecutor = new ReferenceInsertionEventHandler.referenceInsertExecutor(context, reference, value); iterateOverEventHandlers(applicationEventHandlerIterator, methodExecutor); } if( contextEventHandlerIterator != null ) { if( methodExecutor == null ) methodExecutor = new ReferenceInsertionEventHandler.referenceInsertExecutor(context, reference, value); iterateOverEventHandlers(contextEventHandlerIterator, methodExecutor); } return methodExecutor != null ? methodExecutor.getReturnValue() : value; } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ExceptionUtils.createRuntimeException("Exception in event handler.",e); } } /** * Called when a null is evaluated during a #set. All event handlers are * called in sequence until a false is returned. The default implementation * always returns true. * * @param lhs Left hand side of the expression. * @param rhs Right hand side of the expression. * @param rsvc current instance of RuntimeServices * @param context The internal context adapter. * @return true if to be logged, false otherwise */ public static boolean shouldLogOnNullSet(RuntimeServices rsvc, InternalContextAdapter context, String lhs, String rhs) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.getApplicationEventCartridge(); Iterator applicationEventHandlerIterator = (ev1 == null) ? null: ev1.getNullSetEventHandlers(); EventCartridge ev2 = context.getEventCartridge(); initializeEventCartridge(rsvc, ev2); Iterator contextEventHandlerIterator = (ev2 == null) ? null: ev2.getNullSetEventHandlers(); try { EventHandlerMethodExecutor methodExecutor = new NullSetEventHandler.ShouldLogOnNullSetExecutor(context, lhs, rhs); callEventHandlers( applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return ((Boolean) methodExecutor.getReturnValue()).booleanValue(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ExceptionUtils.createRuntimeException("Exception in event handler.",e); } } /** * Called when a method exception is generated during Velocity merge. Only * the first valid event handler in the sequence is called. The default * implementation simply rethrows the exception. * * @param claz * Class that is causing the exception * @param method * method called that causes the exception * @param e * Exception thrown by the method * @param rsvc current instance of RuntimeServices * @param context The internal context adapter. * @return Object to return as method result * @throws Exception * to be wrapped and propogated to app */ public static Object methodException(RuntimeServices rsvc, InternalContextAdapter context, Class claz, String method, Exception e) throws Exception { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.getApplicationEventCartridge(); Iterator applicationEventHandlerIterator = (ev1 == null) ? null: ev1.getMethodExceptionEventHandlers(); EventCartridge ev2 = context.getEventCartridge(); initializeEventCartridge(rsvc, ev2); Iterator contextEventHandlerIterator = (ev2 == null) ? null: ev2.getMethodExceptionEventHandlers(); EventHandlerMethodExecutor methodExecutor = new MethodExceptionEventHandler.MethodExceptionExecutor(context, claz, method, e); if ( ((applicationEventHandlerIterator == null) || !applicationEventHandlerIterator.hasNext()) && ((contextEventHandlerIterator == null) || !contextEventHandlerIterator.hasNext()) ) { throw e; } callEventHandlers( applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return methodExecutor.getReturnValue(); } /** * Called when an include-type directive is encountered (#include or * #parse). All the registered event handlers are called unless null is * returned. The default implementation always processes the included * resource. * * @param includeResourcePath * the path as given in the include directive. * @param currentResourcePath * the path of the currently rendering template that includes the * include directive. * @param directiveName * name of the directive used to include the resource. (With the * standard directives this is either "parse" or "include"). * @param rsvc current instance of RuntimeServices * @param context The internal context adapter. * * @return a new resource path for the directive, or null to block the * include from occurring. */ public static String includeEvent(RuntimeServices rsvc, InternalContextAdapter context, String includeResourcePath, String currentResourcePath, String directiveName) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.getApplicationEventCartridge(); Iterator applicationEventHandlerIterator = (ev1 == null) ? null: ev1.getIncludeEventHandlers(); EventCartridge ev2 = context.getEventCartridge(); initializeEventCartridge(rsvc, ev2); Iterator contextEventHandlerIterator = (ev2 == null) ? null: ev2.getIncludeEventHandlers(); try { EventHandlerMethodExecutor methodExecutor = new IncludeEventHandler.IncludeEventExecutor( context, includeResourcePath, currentResourcePath, directiveName); callEventHandlers( applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return (String) methodExecutor.getReturnValue(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ExceptionUtils.createRuntimeException("Exception in event handler.",e); } } /** * Called when an invalid get method is encountered. * * @param rsvc current instance of RuntimeServices * @param context the context when the reference was found invalid * @param reference complete invalid reference * @param object object from reference, or null if not available * @param property name of property, or null if not relevant * @param info contains info on template, line, col * @return substitute return value for missing reference, or null if no substitute */ public static Object invalidGetMethod(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object object, String property, Info info) { return invalidReferenceHandlerCall ( new InvalidReferenceEventHandler.InvalidGetMethodExecutor (context, reference, object, property, info), rsvc, context); } /** * Called when an invalid set method is encountered. * * @param rsvc current instance of RuntimeServices * @param context the context when the reference was found invalid * @param leftreference left reference being assigned to * @param rightreference invalid reference on the right * @param info contains info on template, line, col */ public static void invalidSetMethod(RuntimeServices rsvc, InternalContextAdapter context, String leftreference, String rightreference, Info info) { /** * ignore return value */ invalidReferenceHandlerCall ( new InvalidReferenceEventHandler.InvalidSetMethodExecutor (context, leftreference, rightreference, info), rsvc, context); } /** * Called when an invalid method is encountered. * * @param rsvc current instance of RuntimeServices * @param context the context when the reference was found invalid * @param reference complete invalid reference * @param object object from reference, or null if not available * @param method name of method, or null if not relevant * @param info contains info on template, line, col * @return substitute return value for missing reference, or null if no substitute */ public static Object invalidMethod(RuntimeServices rsvc, InternalContextAdapter context, String reference, Object object, String method, Info info) { return invalidReferenceHandlerCall ( new InvalidReferenceEventHandler.InvalidMethodExecutor (context, reference, object, method, info), rsvc, context); } /** * Calls event handler method with appropriate chaining across event handlers. * * @param methodExecutor * @param rsvc current instance of RuntimeServices * @param context The current context * @return return value from method, or null if no return value */ public static Object invalidReferenceHandlerCall( EventHandlerMethodExecutor methodExecutor, RuntimeServices rsvc, InternalContextAdapter context) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.getApplicationEventCartridge(); Iterator applicationEventHandlerIterator = (ev1 == null) ? null: ev1.getInvalidReferenceEventHandlers(); EventCartridge ev2 = context.getEventCartridge(); initializeEventCartridge(rsvc, ev2); Iterator contextEventHandlerIterator = (ev2 == null) ? null: ev2.getInvalidReferenceEventHandlers(); try { callEventHandlers( applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return methodExecutor.getReturnValue(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw ExceptionUtils.createRuntimeException("Exception in event handler.",e); } } /** * Initialize the event cartridge if appropriate. * * @param rsvc current instance of RuntimeServices * @param eventCartridge the event cartridge to be initialized */ private static void initializeEventCartridge(RuntimeServices rsvc, EventCartridge eventCartridge) { if (eventCartridge != null) { try { eventCartridge.initialize(rsvc); } catch (Exception e) { throw ExceptionUtils.createRuntimeException("Couldn't initialize event cartridge : ", e); } } } /** * Loop through both the application level and context-attached event handlers. * * @param applicationEventHandlerIterator Iterator that loops through all global event handlers declared at application level * @param contextEventHandlerIterator Iterator that loops through all global event handlers attached to context * @param eventExecutor Strategy object that executes event handler method * @exception Exception generic exception potentially thrown by event handlers */ private static void callEventHandlers( Iterator applicationEventHandlerIterator, Iterator contextEventHandlerIterator, EventHandlerMethodExecutor eventExecutor) throws Exception { /** * First loop through the event handlers configured at the app level * in the properties file. */ iterateOverEventHandlers(applicationEventHandlerIterator, eventExecutor); /** * Then loop through the event handlers attached to the context. */ iterateOverEventHandlers(contextEventHandlerIterator, eventExecutor); } /** * Loop through a given iterator of event handlers. * * @param handlerIterator Iterator that loops through event handlers * @param eventExecutor Strategy object that executes event handler method * @exception Exception generic exception potentially thrown by event handlers */ private static void iterateOverEventHandlers( Iterator handlerIterator, EventHandlerMethodExecutor eventExecutor) throws Exception { if (handlerIterator != null) { for (Iterator i = handlerIterator; i.hasNext();) { EventHandler eventHandler = (EventHandler) i.next(); if (!eventExecutor.isDone()) { eventExecutor.execute(eventHandler); } } } } } velocity-1.7/src/java/org/apache/velocity/app/VelocityEngine.java0000644000175000017500000004345711317167355025052 0ustar moellermoellerpackage org.apache.velocity.app; /* * 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. */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.Properties; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.Template; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.runtime.log.Log; /** *

    * 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. *

    *

    Velocity will call * the parameter-less init() at the first use of this class * if the init() wasn't explicitly called. While this will * ensure that Velocity functions, it probably won't * function in the way you intend, so it is strongly recommended that * you call an init() method yourself if you use the default constructor. *

    * * @version $Id: VelocityEngine.java 894920 2009-12-31 18:35:25Z nbubna $ */ public class VelocityEngine implements RuntimeConstants { private RuntimeInstance ri = new RuntimeInstance(); /** * Init-less CTOR */ public VelocityEngine() { // do nothing } /** * Construct a VelocityEngine with the initial properties defined in the file * propsFilename */ public VelocityEngine(String propsFilename) { ri.setProperties(propsFilename); } /** * Construct a VelocityEngine instance with the specified initial properties. */ public VelocityEngine(Properties p) { ri.setProperties(p); } /** * initialize the Velocity runtime engine, using the default * properties of the Velocity distribution */ public void init() { ri.init(); } /** * initialize the Velocity runtime engine, using default properties * plus the properties in the properties file passed in as the arg * * @param propsFilename file containing properties to use to initialize * the Velocity runtime */ public void init(String propsFilename) { ri.init(propsFilename); } /** * initialize the Velocity runtime engine, using default properties * plus the properties in the passed in java.util.Properties object * * @param p Proprties object containing initialization properties */ public void init(Properties p) { ri.init(p); } /** * Set a Velocity Runtime property. * * @param key * @param value */ public void setProperty(String key, Object value) { ri.setProperty(key,value); } /** * Add a Velocity Runtime property. * * @param key * @param value */ public void addProperty(String key, Object value) { ri.addProperty(key,value); } /** * Clear a Velocity Runtime property. * * @param key of property to clear */ public void clearProperty(String key) { ri.clearProperty(key); } /** * Set an entire configuration at once. This is * useful in cases where the parent application uses * the ExtendedProperties class and the velocity configuration * is a subset of the parent application's configuration. * * @param configuration * */ public void setExtendedProperties( ExtendedProperties configuration) { ri.setConfiguration( configuration ); } /** * Get a Velocity Runtime property. * * @param key property to retrieve * @return property value or null if the property * not currently set */ public Object getProperty( String key ) { return ri.getProperty( key ); } /** * renders the input string using the context into the output writer. * To be used when a template is dynamically constructed, or want to use * Velocity as a token replacer. * * @param context context to use in rendering input string * @param out Writer in which to render the output * @param logTag string to be used as the template name for log * messages in case of error * @param instring input string containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. */ public boolean evaluate( Context context, Writer out, String logTag, String instring ) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException { return ri.evaluate(context, out, logTag, instring); } /** * Renders the input stream using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param instream input stream containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException * @throws MethodInvocationException * @throws ResourceNotFoundException * @throws IOException * @deprecated Use * {@link #evaluate( Context context, Writer writer, * String logTag, Reader reader ) } */ public boolean evaluate( Context context, Writer writer, String logTag, InputStream instream ) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException, IOException { /* * first, parse - convert ParseException if thrown */ BufferedReader br = null; String encoding = null; try { encoding = ri.getString(INPUT_ENCODING,ENCODING_DEFAULT); br = new BufferedReader( new InputStreamReader( instream, encoding)); } catch( UnsupportedEncodingException uce ) { String msg = "Unsupported input encoding : " + encoding + " for template " + logTag; throw new ParseErrorException( msg ); } return evaluate( context, writer, logTag, br ); } /** * Renders the input reader using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param reader Reader containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity v1.1 */ public boolean evaluate(Context context, Writer writer, String logTag, Reader reader) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException { return ri.evaluate(context, writer, logTag, reader); } /** * Invokes a currently registered Velocimacro with the params provided * and places the rendered stream into the writer. *
    * Note : currently only accepts args to the VM if they are in the context. * * @param vmName name of Velocimacro to call * @param logTag string to be used for template name in case of error. if null, * the vmName will be used * @param params keys for args used to invoke Velocimacro, in java format * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar") * @param context Context object containing data/objects used for rendering. * @param writer Writer for output stream * @return true if Velocimacro exists and successfully invoked, false otherwise. */ public boolean invokeVelocimacro( String vmName, String logTag, String params[], Context context, Writer writer ) { return ri.invokeVelocimacro(vmName, logTag, params, context, writer); } /** * Merges a template and puts the rendered stream into the writer. * The default encoding that Velocity uses to read template files is defined in * the property input.encoding and defaults to ISO-8859-1. * * @param templateName name of template to be used in merge * @param context filled context to be used in merge * @param writer writer to write template into * * @return true if successful, false otherwise. Errors * logged to velocity log. * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException * @deprecated Use * {@link #mergeTemplate( String templateName, String encoding, * Context context, Writer writer )} */ public boolean mergeTemplate( String templateName, Context context, Writer writer ) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { return mergeTemplate( templateName, ri.getString(INPUT_ENCODING,ENCODING_DEFAULT), context, writer ); } /** * merges a template and puts the rendered stream into the writer * * @param templateName name of template to be used in merge * @param encoding encoding used in template * @param context filled context to be used in merge * @param writer writer to write template into * * @return true if successful, false otherwise. Errors * logged to velocity log * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException * @since Velocity v1.1 */ public boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer ) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { Template template = ri.getTemplate(templateName, encoding); if ( template == null ) { String msg = "VelocityEngine.mergeTemplate() was unable to load template '" + templateName + "'"; getLog().error(msg); throw new ResourceNotFoundException(msg); } else { template.merge(context, writer); return true; } } /** * Returns a Template from the Velocity * resource management system. * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException { return ri.getTemplate( name ); } /** * Returns a Template from the Velocity * resource management system. * * @param name The file name of the desired template. * @param encoding The character encoding to use for the template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @since Velocity v1.1 */ public Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException { return ri.getTemplate( name, encoding ); } /** * Determines if a resource is accessable via the currently * configured resource loaders. *

    * Note that the current implementation will not * change the state of the system in any real way - so this * cannot be used to pre-load the resource cache, as the * previous implementation did as a side-effect. *

    * The previous implementation exhibited extreme lazyness and * sloth, and the author has been flogged. * * @param resourceName name of the resource to search for * @return true if found, false otherwise * @since 1.5 */ public boolean resourceExists(String resourceName) { return (ri.getLoaderNameForResource(resourceName) != null); } /** * @param resourceName * @return True if the template exists. * @see #resourceExists(String) * @deprecated Use resourceExists(String) instead. */ public boolean templateExists(String resourceName) { return resourceExists(resourceName); } /** * Returns a convenient Log instance that wraps the current LogChute. * Use this to log error messages. It has the usual methods you'd expect. * @return A log object. * @since 1.5 */ public Log getLog() { return ri.getLog(); } /** * @param message * @deprecated Use getLog() and call warn() on it. */ public void warn(Object message) { getLog().warn(message); } /** * @param message * @deprecated Use getLog() and call warn() on it. */ public void info(Object message) { getLog().info(message); } /** * @param message * @deprecated Use getLog() and call warn() on it. */ public void error(Object message) { getLog().error(message); } /** * @param message * @deprecated Use getLog() and call warn() on it. */ public void debug(Object message) { getLog().debug(message); } /** *

    * Sets an application attribute (which can be any Object) that will be * accessible from any component of the system that gets a * RuntimeServices. This allows communication between the application * environment and custom pluggable components of the Velocity engine, * such as ResourceLoaders and LogChutes. *

    * *

    * Note that there is no enforcement or rules for the key * used - it is up to the application developer. However, to * help make the intermixing of components possible, using * the target Class name (e.g. com.foo.bar ) as the key * might help avoid collision. *

    * * @param key object 'name' under which the object is stored * @param value object to store under this key */ public void setApplicationAttribute( Object key, Object value ) { ri.setApplicationAttribute(key, value); } /** *

    * Return an application attribute (which can be any Object) * that was set by the application in order to be accessible from * any component of the system that gets a RuntimeServices. * This allows communication between the application * environment and custom pluggable components of the * Velocity engine, such as ResourceLoaders and LogChutes. *

    * * @param key object 'name' under which the object is stored * @return value object to store under this key * @since 1.5 */ public Object getApplicationAttribute( Object key ) { return ri.getApplicationAttribute(key); } /** * Remove a directive. * @param name name of the directive. */ public void removeDirective(String name) { ri.removeDirective(name); } /** * Instantiates and loads the directive with some basic checks. * * @param directiveClass classname of directive to load */ public void loadDirective(String directiveClass) { ri.loadDirective(directiveClass); } } velocity-1.7/src/java/org/apache/velocity/app/FieldMethodizer.java0000644000175000017500000001240111006510772025153 0ustar moellermoellerpackage org.apache.velocity.app; /* * 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. */ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import org.apache.velocity.util.ClassUtils; /** *

    * This is a small utility class allow easy access to static fields in a class, * such as string constants. Velocity will not introspect for class * fields (and won't in the future :), but writing setter/getter methods to do * this really is a pain, so use this if you really have * to access fields. * *

    * The idea it so enable access to the fields just like you would in Java. * For example, in Java, you would access a static field like *

     *  MyClass.STRING_CONSTANT
     *  
    * and that is the same thing we are trying to allow here. * *

    * So to use in your Java code, do something like this : *

     *   context.put("runtime", new FieldMethodizer( "org.apache.velocity.runtime.Runtime" ));
     *  
    * and then in your template, you can access any of your static fields in this way : *
     *   $runtime.COUNTER_NAME
     *  
    * *

    * Right now, this class only methodizes public static fields. It seems * that anything else is too dangerous. This class is for convenience accessing * 'constants'. If you have fields that aren't static it may be better * to handle them by explicitly placing them into the context. * * @author Geir Magnusson Jr. * @version $Id: FieldMethodizer.java 652755 2008-05-02 04:00:58Z nbubna $ */ public class FieldMethodizer { /** Hold the field objects by field name */ private HashMap fieldHash = new HashMap(); /** * Allow object to be initialized without any data. You would use * addObject() to add data later. */ public FieldMethodizer() { } /** * Constructor that takes as it's arg the name of the class * to methodize. * * @param s Name of class to methodize. */ public FieldMethodizer( String s ) { try { addObject(s); } catch( Exception e ) { System.err.println("Could not add " + s + " for field methodizing: " + e.getMessage()); } } /** * Constructor that takes as it's arg a living * object to methodize. Note that it will still * only methodized the public static fields of * the class. * * @param o Name of class to methodize. */ public FieldMethodizer( Object o ) { try { addObject(o); } catch( Exception e ) { System.err.println("Could not add " + o + " for field methodizing: " + e.getMessage()); } } /** * Add the Name of the class to methodize * @param s * @throws Exception */ public void addObject ( String s ) throws Exception { inspect(ClassUtils.getClass(s)); } /** * Add an Object to methodize * @param o * @throws Exception */ public void addObject ( Object o ) throws Exception { inspect(o.getClass()); } /** * Accessor method to get the fields by name. * * @param fieldName Name of static field to retrieve * * @return The value of the given field. */ public Object get( String fieldName ) { Object value = null; try { Field f = (Field) fieldHash.get( fieldName ); if (f != null) { value = f.get(null); } } catch( IllegalAccessException e ) { System.err.println("IllegalAccessException while trying to access " + fieldName + ": " + e.getMessage()); } return value; } /** * Method that retrieves all public static fields * in the class we are methodizing. */ private void inspect(Class clas) { Field[] fields = clas.getFields(); for( int i = 0; i < fields.length; i++) { /* * only if public and static */ int mod = fields[i].getModifiers(); if ( Modifier.isStatic(mod) && Modifier.isPublic(mod) ) { fieldHash.put(fields[i].getName(), fields[i]); } } } } velocity-1.7/src/java/org/apache/velocity/app/Velocity.java0000644000175000017500000004464611322703343023712 0ustar moellermoellerpackage org.apache.velocity.app; /* * 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. */ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.Properties; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.Template; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.runtime.log.Log; /** * This class provides services to the application * developer, such as : *

      *
    • Simple Velocity Runtime engine initialization methods. *
    • Functions to apply the template engine to streams and strings * to allow embedding and dynamic template generation. *
    • Methods to access Velocimacros directly. *
    * *

    * While the most common way to use Velocity is via templates, as * Velocity is a general-purpose template engine, there are other * uses that Velocity is well suited for, such as processing dynamically * created templates, or processing content streams. * *

    * The methods herein were developed to allow easy access to the Velocity * facilities without direct spelunking of the internals. If there is * something you feel is necessary to add here, please, send a patch. * * @author Geir Magnusson Jr. * @author Christoph Reck * @author Jason van Zyl * @version $Id: Velocity.java 898050 2010-01-11 20:15:31Z nbubna $ */ public class Velocity implements RuntimeConstants { /** * initialize the Velocity runtime engine, using the default * properties of the Velocity distribution */ public static void init() { RuntimeSingleton.init(); } /** * initialize the Velocity runtime engine, using default properties * plus the properties in the properties file passed in as the arg * * @param propsFilename file containing properties to use to initialize * the Velocity runtime */ public static void init( String propsFilename ) { RuntimeSingleton.init(propsFilename); } /** * initialize the Velocity runtime engine, using default properties * plus the properties in the passed in java.util.Properties object * * @param p Properties object containing initialization properties */ public static void init( Properties p ) { RuntimeSingleton.init( p ); } /** * Set a Velocity Runtime property. * * @param key The property key. * @param value The property value. */ public static void setProperty(String key, Object value) { RuntimeSingleton.setProperty(key,value); } /** * Add a Velocity Runtime property. * * @param key The property key. * @param value The property value. */ public static void addProperty(String key, Object value) { RuntimeSingleton.addProperty(key,value); } /** * Clear a Velocity Runtime property. * * @param key of property to clear */ public static void clearProperty(String key) { RuntimeSingleton.clearProperty(key); } /** * Set an entire configuration at once. This is * useful in cases where the parent application uses * the ExtendedProperties class and the velocity configuration * is a subset of the parent application's configuration. * * @param configuration A configuration object. * */ public static void setExtendedProperties( ExtendedProperties configuration) { RuntimeSingleton.setConfiguration( configuration ); } /** * Get a Velocity Runtime property. * * @param key property to retrieve * @return property value or null if the property * not currently set */ public static Object getProperty( String key ) { return RuntimeSingleton.getProperty( key ); } /** * renders the input string using the context into the output writer. * To be used when a template is dynamically constructed, or want to use * Velocity as a token replacer. * * @param context context to use in rendering input string * @param out Writer in which to render the output * @param logTag string to be used as the template name for log * messages in case of error * @param instring input string containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. */ public static boolean evaluate( Context context, Writer out, String logTag, String instring ) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException { return RuntimeSingleton.getRuntimeServices() .evaluate(context, out, logTag, instring); } /** * Renders the input stream using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param instream input stream containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @deprecated Use * {@link #evaluate( Context context, Writer writer, * String logTag, Reader reader ) } * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @throws IOException While loading a reference, an I/O problem occured. */ public static boolean evaluate( Context context, Writer writer, String logTag, InputStream instream ) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException { /* * first, parse - convert ParseException if thrown */ BufferedReader br = null; String encoding = null; try { encoding = RuntimeSingleton.getString(INPUT_ENCODING,ENCODING_DEFAULT); br = new BufferedReader( new InputStreamReader( instream, encoding)); } catch( UnsupportedEncodingException uce ) { String msg = "Unsupported input encoding : " + encoding + " for template " + logTag; throw new ParseErrorException( msg ); } return evaluate( context, writer, logTag, br ); } /** * Renders the input reader using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param reader Reader containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity v1.1 */ public static boolean evaluate( Context context, Writer writer, String logTag, Reader reader ) throws ParseErrorException, MethodInvocationException, ResourceNotFoundException { return RuntimeSingleton.getRuntimeServices().evaluate(context, writer, logTag, reader); } /** * Invokes a currently registered Velocimacro with the params provided * and places the rendered stream into the writer. *
    * Note : currently only accepts args to the VM if they are in the context. * * @param vmName name of Velocimacro to call * @param logTag string to be used for template name in case of error. if null, * the vmName will be used * @param params keys for args used to invoke Velocimacro, in java format * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar") * @param context Context object containing data/objects used for rendering. * @param writer Writer for output stream * @return true if Velocimacro exists and successfully invoked, false otherwise. */ public static boolean invokeVelocimacro( String vmName, String logTag, String params[], Context context, Writer writer ) { return RuntimeSingleton.getRuntimeServices() .invokeVelocimacro(vmName, logTag, params, context, writer); } /** * Merges a template and puts the rendered stream into the writer. * The default encoding that Velocity uses to read template files is defined in * the property input.encoding and defaults to ISO-8859-1. * * @param templateName name of template to be used in merge * @param context filled context to be used in merge * @param writer writer to write template into * * @return true if successful, false otherwise. Errors * logged to velocity log. * @deprecated Use * {@link #mergeTemplate( String templateName, String encoding, * Context context, Writer writer )} * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. */ public static boolean mergeTemplate( String templateName, Context context, Writer writer ) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { return mergeTemplate( templateName, RuntimeSingleton.getString(INPUT_ENCODING,ENCODING_DEFAULT), context, writer ); } /** * merges a template and puts the rendered stream into the writer * * @param templateName name of template to be used in merge * @param encoding encoding used in template * @param context filled context to be used in merge * @param writer writer to write template into * * @return true if successful, false otherwise. Errors * logged to velocity log * * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * * @since Velocity v1.1 */ public static boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer ) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { Template template = RuntimeSingleton.getTemplate(templateName, encoding); if ( template == null ) { String msg = "Velocity.mergeTemplate() was unable to load template '" + templateName + "'"; getLog().error(msg); throw new ResourceNotFoundException(msg); } else { template.merge(context, writer); return true; } } /** * Returns a Template from the Velocity * resource management system. * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public static Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException { return RuntimeSingleton.getTemplate( name ); } /** * Returns a Template from the Velocity * resource management system. * * @param name The file name of the desired template. * @param encoding The character encoding to use for the template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * * @since Velocity v1.1 */ public static Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException { return RuntimeSingleton.getTemplate( name, encoding ); } /** *

    Determines whether a resource is accessable via the * currently configured resource loaders. {@link * org.apache.velocity.runtime.resource.Resource} is the generic * description of templates, static content, etc.

    * *

    Note that the current implementation will not change * the state of the system in any real way - so this cannot be * used to pre-load the resource cache, as the previous * implementation did as a side-effect.

    * * @param resourceName The name of the resource to search for. * @return Whether the resource was located. */ public static boolean resourceExists(String resourceName) { return (RuntimeSingleton.getLoaderNameForResource(resourceName) != null); } /** * Returns a convenient Log instance that wraps the current LogChute. * Use this to log error messages. It has the usual methods. * * @return A convenience Log instance that wraps the current LogChute. * @since 1.5 */ public static Log getLog() { return RuntimeSingleton.getLog(); } /** * @deprecated Use getLog() and call warn() on it. * @see Log#warn(Object) * @param message The message to log. */ public static void warn(Object message) { getLog().warn( message ); } /** * @deprecated Use getLog() and call info() on it. * @see Log#info(Object) * @param message The message to log. */ public static void info(Object message) { getLog().info( message ); } /** * @deprecated Use getLog() and call error() on it. * @see Log#error(Object) * @param message The message to log. */ public static void error(Object message) { getLog().error( message ); } /** * @deprecated Use getLog() and call debug() on it. * @see Log#debug(Object) * @param message The message to log. */ public static void debug(Object message) { getLog().debug( message ); } /** *

    * Set the an ApplicationAttribue, which is an Object * set by the application which is accessable from * any component of the system that gets a RuntimeServices. * This allows communication between the application * environment and custom pluggable components of the * Velocity engine, such as loaders and loggers. *

    * *

    * Note that there is no enfocement or rules for the key * used - it is up to the application developer. However, to * help make the intermixing of components possible, using * the target Class name (e.g. com.foo.bar ) as the key * might help avoid collision. *

    * * @param key object 'name' under which the object is stored * @param value object to store under this key */ public static void setApplicationAttribute( Object key, Object value ) { RuntimeSingleton.getRuntimeInstance().setApplicationAttribute( key, value); } /** * @param resourceName Name of the Template to check. * @return True if the template exists. * @see #resourceExists(String) * @deprecated Use resourceExists(String) instead. */ public static boolean templateExists(String resourceName) { return resourceExists(resourceName); } /** * Remove a directive. * * @param name name of the directive. */ public void removeDirective(String name) { RuntimeSingleton.removeDirective(name); } /** * Instantiates and loads the directive with some basic checks. * * @param directiveClass classname of directive to load */ public void loadDirective(String directiveClass) { RuntimeSingleton.loadDirective(directiveClass); } } velocity-1.7/src/java/org/apache/velocity/convert/0000755000175000017500000000000011675166250022146 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/convert/WebMacro.java0000644000175000017500000002077311322676677024531 0ustar moellermoellerpackage org.apache.velocity.convert; /* * 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. */ import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.apache.oro.text.perl.Perl5Util; import org.apache.velocity.util.StringUtils; import org.apache.tools.ant.DirectoryScanner; /** * This is deprecated without replacement. * * @author Jason van Zyl * @author Daniel Rall * @version $Id: WebMacro.java 898028 2010-01-11 19:36:31Z nbubna $ * @deprecated Obsolete and outdated. */ public class WebMacro { /** * */ protected static final String VM_EXT = ".vm"; /** * */ protected static final String WM_EXT = ".wm"; /** * The regexes to use for line by line substition. The regexes * come in pairs. The first is the string to match, the second is * the substitution to make. */ protected static String[] perLineREs = { // Make #if directive match the Velocity directive style. "#if\\s*[(]\\s*(.*\\S)\\s*[)]\\s*(#begin|{)[ \\t]?", "#if( $1 )", // Remove the WM #end #else #begin usage. "[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?(\\w)", "$2#else#**#$4", // avoid touching followup word with embedded comment "[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?", "$2#else", "(#end|})(\\s*#else)\\s*(#begin|{)[ \\t]?", "$1\n$2", // Convert WM style #foreach to Velocity directive style. "#foreach\\s+(\\$\\w+)\\s+in\\s+(\\$[^\\s#]+)\\s*(#begin|{)[ \\t]?", "#foreach( $1 in $2 )", // Convert WM style #set to Velocity directive style. "#set\\s+(\\$[^\\s=]+)\\s*=\\s*([\\S \\t]+)", "#set( $1 = $2 )", "(##[# \\t\\w]*)\\)", // fix comments included at end of line ")$1", // Convert WM style #parse to Velocity directive style. "#parse\\s+([^\\s#]+)[ \\t]?", "#parse( $1 )", // Convert WM style #include to Velocity directive style. "#include\\s+([^\\s#]+)[ \\t]?", "#include( $1 )", // Convert WM formal reference to VTL syntax. "\\$\\(([^\\)]+)\\)", "${$1}", "\\${([^}\\(]+)\\(([^}]+)}\\)", // fix encapsulated brakets: {(}) "${$1($2)}", // Velocity currently does not permit leading underscore. "\\$_", "$l_", "\\${(_[^}]+)}", // within a formal reference "${l$1}", // Eat semi-colons in (converted) VTL #set directives. "(#set\\s*\\([^;]+);(\\s*\\))", "$1$2", // Convert explicitly terminated WM statements to VTL syntax. "(^|[^\\\\])\\$(\\w[^=\n;'\"]*);", "$1${$2}", // Change extensions when seen. "\\.wm", ".vm" }; /** * Iterate through the set of find/replace regexes * that will convert a given WM template to a VM template * @param target */ public void convert(String target) { File file = new File(target); if (!file.exists()) { throw new RuntimeException("The specified template or directory does not exist"); } if (file.isDirectory()) { String basedir = file.getAbsolutePath(); String newBasedir = basedir + VM_EXT; DirectoryScanner ds = new DirectoryScanner(); ds.setBasedir(basedir); ds.addDefaultExcludes(); ds.scan(); String[] files = ds.getIncludedFiles(); for (int i = 0; i < files.length; i++) { writeTemplate(files[i], basedir, newBasedir); } } else { writeTemplate(file.getAbsolutePath(), "", ""); } } /** * Write out the converted template to the given named file * and base directory. */ private boolean writeTemplate(String file, String basedir, String newBasedir) { if (file.indexOf(WM_EXT) < 0) { return false; } System.out.println("Converting " + file + "..."); String template = file; String newTemplate = convertName(file); if (basedir.length() > 0) { String templateDir = newBasedir + extractPath(file); File outputDirectory = new File(templateDir); template = basedir + File.separator + file; if (! outputDirectory.exists()) { outputDirectory.mkdirs(); } newTemplate = newBasedir + File.separator + convertName(file); } String convertedTemplate = convertTemplate(template); FileWriter fw = null; try { fw = new FileWriter(newTemplate); fw.write(convertedTemplate); } catch (Exception e) { e.printStackTrace(); } finally { if (fw != null) { try { fw.close(); } catch (IOException io) { // Do nothing } } } return true; } /** * Gets the path segment of the full path to a file (i.e. one * which originally included the file name). */ private final String extractPath(String file) { int lastSepPos = file.lastIndexOf(File.separator); return (lastSepPos == -1 ? "" : File.separator + file.substring(0, lastSepPos)); } /** * Simple extension conversion of .wm to .vm */ private String convertName(String name) { return (name.indexOf(WM_EXT) < 0) ? name : name.substring(0, name.indexOf(WM_EXT)) + VM_EXT; } /** * How to use this little puppy :-) */ private static final void usage() { System.err.println("Usage: convert-wm "); } /** * Apply find/replace regexes to our WM template * @param template * @return Returns the template with all regexprs applied. */ public String convertTemplate(String template) { String contents = StringUtils.fileContentsToString(template); // Overcome Velocity 0.71 limitation. // HELP: Is this still necessary? if (!contents.endsWith("\n")) { contents += "\n"; } // Convert most markup. Perl5Util perl = new Perl5Util(); for (int i = 0; i < perLineREs.length; i += 2) { contents = perl.substitute(makeSubstRE(i), contents); } // Convert closing curlies. if (perl.match("m/javascript/i", contents)) { // ASSUMPTION: JavaScript is indented, WM is not. contents = perl.substitute("s/\n}/\n#end/g", contents); } else { contents = perl.substitute("s/(\n\\s*)}/$1#end/g", contents); contents = perl.substitute("s/#end\\s*\n\\s*#else/#else/g", contents); } return contents; } /** * Makes a Perl 5 regular expression for use by ORO. */ private final String makeSubstRE(int i) { return ("s/" + perLineREs[i] + '/' + perLineREs[i + 1] + "/g"); } /** * Main hook for the conversion process. * @param args */ public static void main(String[] args) { if (args.length > 0) { for (int x=0; x < args.length; x++) { WebMacro converter = new WebMacro(); converter.convert(args[x]); } } else { usage(); } } } velocity-1.7/src/java/org/apache/velocity/VelocityContext.java0000644000175000017500000001222411322700447024464 0ustar moellermoellerpackage org.apache.velocity; /* * 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. */ import java.util.HashMap; import java.util.Map; import org.apache.velocity.context.AbstractContext; import org.apache.velocity.context.Context; /** * General purpose implemention 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. * * This context implementation cannot be shared between threads * without those threads synchronizing access between them, as * the HashMap is not synchronized, nor are some of the fundamentals * of AbstractContext. If you need to share a Context between * threads with simultaneous access for some reason, please create * your own and extend the interface Context * * @see org.apache.velocity.context.Context * * @author Geir Magnusson Jr. * @author Jason van Zyl * @author Fedor Karpelevitch * @author Daniel Rall * @version $Id: VelocityContext.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class VelocityContext extends AbstractContext implements Cloneable { /** * Version Id for serializable */ private static final long serialVersionUID = 9033846851064645037L; /** * Storage for key/value pairs. */ private Map context = null; /** * Creates a new instance (with no inner context). */ public VelocityContext() { this(null, null); } /** * Creates a new instance with the provided storage (and no inner * context). * @param context */ public VelocityContext(Map context) { this(context, null); } /** * Chaining constructor, used when you want to * wrap a context in another. The inner context * will be 'read only' - put() calls to the * wrapping context will only effect the outermost * context * * @param innerContext The Context implementation to * wrap. */ public VelocityContext( Context innerContext ) { this(null, innerContext); } /** * Initializes internal storage (never to null), and * inner context. * * @param context Internal storage, or null to * create default storage. * @param innerContext Inner context. */ public VelocityContext(Map context, Context innerContext) { super(innerContext); this.context = (context == null ? new HashMap() : context); } /** * retrieves value for key from internal * storage * * @param key name of value to get * @return value as object */ public Object internalGet( String key ) { return context.get( key ); } /** * stores the value for key to internal * storage * * @param key name of value to store * @param value value to store * @return previous value of key as Object */ public Object internalPut( String key, Object value ) { return context.put( key, value ); } /** * determines if there is a value for the * given key * * @param key name of value to check * @return true if non-null value in store */ public boolean internalContainsKey(Object key) { return context.containsKey( key ); } /** * returns array of keys * * @return keys as [] */ public Object[] internalGetKeys() { return context.keySet().toArray(); } /** * remove a key/value pair from the * internal storage * * @param key name of value to remove * @return value removed */ public Object internalRemove(Object key) { return context.remove( key ); } /** * Clones this context object. * * @return A deep copy of this Context. */ public Object clone() { VelocityContext clone = null; try { clone = (VelocityContext) super.clone(); clone.context = new HashMap(context); } catch (CloneNotSupportedException ignored) { } return clone; } } velocity-1.7/src/java/org/apache/velocity/runtime/0000755000175000017500000000000011675166252022153 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/log/0000755000175000017500000000000011675166250022732 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/log/SimpleLog4JLogSystem.java0000644000175000017500000001177611110372503027531 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.log4j.Category; import org.apache.log4j.Level; import org.apache.log4j.PatternLayout; import org.apache.log4j.RollingFileAppender; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; /** *

    This class is deprecated in favor of the new {@link Log4JLogChute}, * which makes use of Log4J's Logger rather than its deprecated * Category class.

    * * Implementation of a simple log4j system that will either * latch onto an existing category, or just do a simple * rolling file log. Derived from Jon's 'complicated' * version :) * * @author Geir Magnusson Jr. * @author Nathan Bubna. * @version $Id: NullLogChute.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ public class NullLogChute implements LogChute { /** * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices) */ public void init(RuntimeServices rs) throws Exception { } /** * logs messages to the great Garbage Collector in the sky * * @param level severity level * @param message complete error message */ public void log(int level, String message) { } /** * logs messages and their accompanying Throwables * to the great Garbage Collector in the sky * * @param level severity level * @param message complete error message * @param t the java.lang.Throwable */ public void log(int level, String message, Throwable t) { } /** * @see org.apache.velocity.runtime.log.LogChute#isLevelEnabled(int) */ public boolean isLevelEnabled(int level) { return false; } } velocity-1.7/src/java/org/apache/velocity/runtime/log/CommonsLogLogChute.java0000644000175000017500000001072011126315457027301 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogChute; /** * Redirects Velocity's LogChute messages to commons-logging. * *

    To use, first set up commons-logging, then tell Velocity to use * this class for logging by adding the following to your velocity.properties: * * * runtime.log.logsystem.class = org.apache.velocity.runtime.log.CommonsLogLogChute * *

    * *

    You may also set this property to specify what log/name Velocity's * messages should be logged to (example below is default). * * runtime.log.logsystem.commons.logging.name = org.apache.velocity * *

    * * @author Nathan Bubna * @since 1.6 * @version $Id: CommonsLogLogChute.java 71982 2004-02-18 20:11:07Z nbubna $ */ public class CommonsLogLogChute implements LogChute { /** Property key for specifying the name for the log instance */ public static final String LOGCHUTE_COMMONS_LOG_NAME = "runtime.log.logsystem.commons.logging.name"; /** Default name for the commons-logging instance */ public static final String DEFAULT_LOG_NAME = "org.apache.velocity"; /** the commons-logging Log instance */ protected Log log; /********** LogChute methods *************/ public void init(RuntimeServices rs) throws Exception { String name = (String)rs.getProperty(LOGCHUTE_COMMONS_LOG_NAME); if (name == null) { name = DEFAULT_LOG_NAME; } log = LogFactory.getLog(name); log(LogChute.DEBUG_ID, "CommonsLogLogChute name is '" + name + "'"); } /** * Send a log message from Velocity. */ public void log(int level, String message) { switch (level) { case LogChute.WARN_ID: log.warn(message); break; case LogChute.INFO_ID: log.info(message); break; case LogChute.TRACE_ID: log.trace(message); break; case LogChute.ERROR_ID: log.error(message); break; case LogChute.DEBUG_ID: default: log.debug(message); break; } } /** * Send a log message from Velocity with an error. */ public void log(int level, String message, Throwable t) { switch (level) { case LogChute.WARN_ID: log.warn(message, t); break; case LogChute.INFO_ID: log.info(message, t); break; case LogChute.TRACE_ID: log.trace(message, t); break; case LogChute.ERROR_ID: log.error(message, t); break; case LogChute.DEBUG_ID: default: log.debug(message, t); break; } } /** * Checks whether the specified log level is enabled. */ public boolean isLevelEnabled(int level) { switch (level) { case LogChute.DEBUG_ID: return log.isDebugEnabled(); case LogChute.INFO_ID: return log.isInfoEnabled(); case LogChute.TRACE_ID: return log.isTraceEnabled(); case LogChute.WARN_ID: return log.isWarnEnabled(); case LogChute.ERROR_ID: return log.isErrorEnabled(); default: return true; } } } velocity-1.7/src/java/org/apache/velocity/runtime/log/LogDisplayWrapper.java0000644000175000017500000001350011050652577027203 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ /** * This is a wrapper around a log object, that can add a prefix to log messages * and also turn logging on and off dynamically. It is mainly used to control the * logging of VelociMacro generation messages but is actually generic enough code. * * @author Henning P. Schmiedehausen * @version $Id: LogDisplayWrapper.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class LogDisplayWrapper extends Log { /** The prefix to record with every log message */ private final String prefix; /** log messages only if true */ private final boolean outputMessages; /** The Log object we wrap */ private final Log log; /** * Create a new LogDisplayWrapper * @param log The Log object to wrap. * @param prefix The prefix to record with all messages. * @param outputMessages True when messages should actually get logged. */ public LogDisplayWrapper(final Log log, final String prefix, final boolean outputMessages) { super(log.getLogChute()); this.log = log; this.prefix = prefix; this.outputMessages = outputMessages; } /** * make sure that we always use the right LogChute Object */ protected LogChute getLogChute() { return log.getLogChute(); } /** * @see Log#log(int, Object) */ protected void log(final int level, final Object message) { log(outputMessages, level, message); } protected void log(final boolean doLogging, final int level, final Object message) { if (doLogging) { getLogChute().log(level, prefix + String.valueOf(message)); } } /** * @see Log#log(int, Object, Throwable) */ protected void log(final int level, final Object message, final Throwable t) { log(outputMessages, level, message); } protected void log(final boolean doLogging, final int level, final Object message, final Throwable t) { if (doLogging) { getLogChute().log(level, prefix + String.valueOf(message), t); } } /** * Log a trace message. * @param doLogging Log only if this parameter is true. * @param message */ public void trace(final boolean doLogging, final Object message) { log(doLogging, LogChute.TRACE_ID, message); } /** * Log a trace message and accompanying Throwable. * @param doLogging Log only if this parameter is true. * @param message * @param t */ public void trace(final boolean doLogging, final Object message, final Throwable t) { log(doLogging, LogChute.TRACE_ID, message, t); } /** * Log a debug message. * @param doLogging Log only if this parameter is true. * @param message */ public void debug(final boolean doLogging, final Object message) { log(doLogging, LogChute.DEBUG_ID, message); } /** * Log a debug message and accompanying Throwable. * @param doLogging Log only if this parameter is true. * @param message * @param t */ public void debug(final boolean doLogging, final Object message, final Throwable t) { log(doLogging, LogChute.DEBUG_ID, message, t); } /** * Log an info message. * @param doLogging Log only if this parameter is true. * @param message */ public void info(final boolean doLogging, final Object message) { log(doLogging, LogChute.INFO_ID, message); } /** * Log an info message and accompanying Throwable. * @param doLogging Log only if this parameter is true. * @param message * @param t */ public void info(final boolean doLogging, final Object message, final Throwable t) { log(doLogging, LogChute.INFO_ID, message, t); } /** * Log a warning message. * @param doLogging Log only if this parameter is true. * @param message */ public void warn(final boolean doLogging, final Object message) { log(doLogging, LogChute.WARN_ID, message); } /** * Log a warning message and accompanying Throwable. * @param doLogging Log only if this parameter is true. * @param message * @param t */ public void warn(final boolean doLogging, final Object message, final Throwable t) { log(doLogging, LogChute.WARN_ID, message, t); } /** * Log an error message. * @param doLogging Log only if this parameter is true. * @param message */ public void error(final boolean doLogging, final Object message) { log(doLogging, LogChute.ERROR_ID, message); } /** * Log an error message and accompanying Throwable. * @param doLogging Log only if this parameter is true. * @param message * @param t */ public void error(final boolean doLogging, final Object message, final Throwable t) { log(doLogging, LogChute.ERROR_ID, message, t); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/PrimordialLogSystem.java0000644000175000017500000000334010513464370027540 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ /** * Pre-init logger. I believe that this was suggested by * Carsten Ziegeler and * Jeroen C. van Gelderen. If this isn't correct, let me * know as this was a good idea... * * @author Geir Magnusson Jr. * @version $Id: PrimordialLogSystem.java 463298 2006-10-12 16:10:32Z henning $ * @deprecated Use HoldingLogChute instead! */ public class PrimordialLogSystem extends HoldingLogChute implements LogSystem { /** * @param level * @param message * @deprecated Use log(level, message). */ public void logVelocityMessage(int level, String message) { log(level, message); } /** * @param newLogger * @deprecated use transferTo(LogChute newChute) */ public void dumpLogMessages( LogSystem newLogger ) { transferTo(new LogChuteSystem(newLogger)); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/Log4JLogChute.java0000644000175000017500000001775511126315457026162 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.io.IOException; import java.lang.reflect.Field; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.RollingFileAppender; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.ExceptionUtils; /** * Implementation of a simple log4j system that will either latch onto * an existing category, or just do a simple rolling file log. * * @author Daniel L. Rall * @author Log4J logging API. */ protected Logger logger = null; /** * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices) */ public void init(RuntimeServices rs) throws Exception { rsvc = rs; /* first see if there is a category specified and just use that - it allows * the application to make us use an existing logger */ String name = (String)rsvc.getProperty(RUNTIME_LOG_LOG4J_LOGGER); if (name != null) { logger = Logger.getLogger(name); log(DEBUG_ID, "Log4JLogChute using logger '" + name + '\''); } else { // create a logger with this class name to avoid conflicts logger = Logger.getLogger(this.getClass().getName()); // if we have a file property, then create a separate // rolling file log for velocity messages only String file = rsvc.getString(RuntimeConstants.RUNTIME_LOG); if (file != null && file.length() > 0) { initAppender(file); } } /* get and set specified level for this logger */ String lvl = rsvc.getString(RUNTIME_LOG_LOG4J_LOGGER_LEVEL); if (lvl != null) { Level level = Level.toLevel(lvl); logger.setLevel(level); } /* Ok, now let's see if this version of log4j supports the trace level. */ try { Field traceLevel = Level.class.getField("TRACE"); // we'll never get here in pre 1.2.12 log4j hasTrace = true; } catch (NoSuchFieldException e) { log(DEBUG_ID, "The version of log4j being used does not support the \"trace\" level."); } } // This tries to create a file appender for the specified file name. private void initAppender(String file) throws Exception { try { // to add the appender PatternLayout layout = new PatternLayout("%d - %m%n"); this.appender = new RollingFileAppender(layout, file, true); // if we successfully created the file appender, // configure it and set the logger to use only it appender.setMaxBackupIndex(1); appender.setMaximumFileSize(100000); // don't inherit appenders from higher in the logger heirarchy logger.setAdditivity(false); logger.addAppender(appender); log(DEBUG_ID, "Log4JLogChute initialized using file '"+file+'\''); } catch (IOException ioe) { rsvc.getLog().error("Could not create file appender '"+file+'\'', ioe); throw ExceptionUtils.createRuntimeException("Error configuring Log4JLogChute : ", ioe); } } /** * logs messages * * @param level severity level * @param message complete error message */ public void log(int level, String message) { switch (level) { case LogChute.WARN_ID: logger.warn(message); break; case LogChute.INFO_ID: logger.info(message); break; case LogChute.TRACE_ID: if (hasTrace) { logger.trace(message); } else { logger.debug(message); } break; case LogChute.ERROR_ID: logger.error(message); break; case LogChute.DEBUG_ID: default: logger.debug(message); break; } } /** * @see org.apache.velocity.runtime.log.LogChute#log(int, java.lang.String, java.lang.Throwable) */ public void log(int level, String message, Throwable t) { switch (level) { case LogChute.WARN_ID: logger.warn(message, t); break; case LogChute.INFO_ID: logger.info(message, t); break; case LogChute.TRACE_ID: if (hasTrace) { logger.trace(message, t); } else { logger.debug(message, t); } break; case LogChute.ERROR_ID: logger.error(message, t); break; case LogChute.DEBUG_ID: default: logger.debug(message, t); break; } } /** * @see org.apache.velocity.runtime.log.LogChute#isLevelEnabled(int) */ public boolean isLevelEnabled(int level) { switch (level) { case LogChute.DEBUG_ID: return logger.isDebugEnabled(); case LogChute.INFO_ID: return logger.isInfoEnabled(); case LogChute.TRACE_ID: if (hasTrace) { return logger.isTraceEnabled(); } else { return logger.isDebugEnabled(); } case LogChute.WARN_ID: return logger.isEnabledFor(Level.WARN); case LogChute.ERROR_ID: // can't be disabled in log4j return logger.isEnabledFor(Level.ERROR); default: return true; } } /** * Also do a shutdown if the object is destroy()'d. * @throws Throwable */ protected void finalize() throws Throwable { shutdown(); } /** Close all destinations*/ public void shutdown() { if (appender != null) { logger.removeAppender(appender); appender.close(); appender = null; } } } velocity-1.7/src/java/org/apache/velocity/runtime/log/LogChute.java0000644000175000017500000000523211126315457025305 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; /** * Base interface that logging systems need to implement. This * is the blessed descendant of the old LogSystem interface. * * @author Jon S. Stevens * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: LogChute.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ public interface LogChute { /** Prefix string for trace messages. */ String TRACE_PREFIX = " [trace] "; /** Prefix string for debug messages. */ String DEBUG_PREFIX = " [debug] "; /** Prefix string for info messages. */ String INFO_PREFIX = " [info] "; /** Prefix string for warn messages. */ String WARN_PREFIX = " [warn] "; /** Prefix string for error messages. */ String ERROR_PREFIX = " [error] "; /** ID for trace messages. */ int TRACE_ID = -1; /** ID for debug messages. */ int DEBUG_ID = 0; /** ID for info messages. */ int INFO_ID = 1; /** ID for warning messages. */ int WARN_ID = 2; /** ID for error messages. */ int ERROR_ID = 3; /** * Initializes this LogChute. * @param rs * @throws Exception */ void init(RuntimeServices rs) throws Exception; /** * Send a log message from Velocity. * @param level * @param message */ void log(int level, String message); /** * Send a log message from Velocity along with an exception or error * @param level * @param message * @param t */ void log(int level, String message, Throwable t); /** * Tell whether or not a log level is enabled. * @param level * @return True if a level is enabled. */ boolean isLevelEnabled(int level); } velocity-1.7/src/java/org/apache/velocity/runtime/log/AvalonLogChute.java0000644000175000017500000001720411126315457026450 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log.Hierarchy; import org.apache.log.LogTarget; import org.apache.log.Logger; import org.apache.log.Priority; import org.apache.log.output.io.FileTarget; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; /** * Implementation of a Avalon logger. * * @author Jon S. Stevens * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: AvalonLogChute.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ public class AvalonLogChute implements LogChute { public static final String AVALON_LOGGER = "runtime.log.logsystem.avalon.logger"; public static final String AVALON_LOGGER_FORMAT = "runtime.log.logsystem.avalon.format"; public static final String AVALON_LOGGER_LEVEL = "runtime.log.logsystem.avalon.level"; private Logger logger = null; private RuntimeServices rsvc = null; private static final Map logLevels = new HashMap(); static { logLevels.put("trace", Priority.DEBUG); logLevels.put("debug", Priority.DEBUG); logLevels.put("info", Priority.INFO); logLevels.put("warn", Priority.WARN); logLevels.put("error", Priority.ERROR); } /** * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices) */ public void init(RuntimeServices rs) throws Exception { this.rsvc = rs; // if a logger is specified, we will use this instead of the default String name = (String)rsvc.getProperty(AVALON_LOGGER); if (name != null) { this.logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name); } else { // use the toString() of RuntimeServices to make a unique logger logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString()); // if we have a file property, use it to create a FileTarget String file = (String)rsvc.getProperty(RuntimeConstants.RUNTIME_LOG); if (StringUtils.isNotEmpty(file)) { initTarget(file, rsvc); } } } // creates a file target using the specified file name private void initTarget(final String file, final RuntimeServices rsvc) throws Exception { try { String format = null; Priority level = null; if (rsvc != null) { format = rsvc.getString(AVALON_LOGGER_FORMAT, "%{time} %{message}\\n%{throwable}"); level = (Priority) logLevels.get(rsvc.getString(AVALON_LOGGER_LEVEL, "warn")); } VelocityFormatter vf = new VelocityFormatter(format); // make the target and keep the default behavior of not appending FileTarget target = new FileTarget(new File(file), false, vf); logger.setPriority(level); logger.setLogTargets(new LogTarget[] { target }); log(DEBUG_ID, "AvalonLogChute initialized using file '"+file+'\''); } catch (IOException ioe) { rsvc.getLog().error("Unable to create log file for AvalonLogChute", ioe); throw new Exception("Error configuring AvalonLogChute : " + ioe); } } /** * @param file * @throws Exception * @deprecated This method should not be used. It is here only to provide * backwards compatibility for the deprecated AvalonLogSystem * class, in case anyone used it and this method directly. */ public void init(String file) throws Exception { logger = Hierarchy.getDefaultHierarchy().getLoggerFor(rsvc.toString()); initTarget(file, null); // nag the theoretical user log(DEBUG_ID, "You shouldn't be using the init(String file) method!"); } /** * logs messages * * @param level severity level * @param message complete error message */ public void log(int level, String message) { /* * based on level, call the right logger method * and prefix with the appropos prefix */ switch (level) { case WARN_ID: logger.warn(WARN_PREFIX + message ); break; case INFO_ID: logger.info(INFO_PREFIX + message); break; case DEBUG_ID: logger.debug(DEBUG_PREFIX + message); break; case TRACE_ID: logger.debug(TRACE_PREFIX + message); break; case ERROR_ID: logger.error(ERROR_PREFIX + message); break; default: logger.info(message); break; } } /** * logs messages and error * * @param level severity level * @param message complete error message * @param t */ public void log(int level, String message, Throwable t) { switch (level) { case WARN_ID: logger.warn(WARN_PREFIX + message, t); break; case INFO_ID: logger.info(INFO_PREFIX + message, t); break; case DEBUG_ID: logger.debug(DEBUG_PREFIX + message, t); break; case TRACE_ID: logger.debug(TRACE_PREFIX + message, t); break; case ERROR_ID: logger.error(ERROR_PREFIX + message, t); break; default: logger.info(message, t); break; } } /** * Checks to see whether the specified level is enabled. * @param level * @return True if the specified level is enabled. */ public boolean isLevelEnabled(int level) { switch (level) { // For Avalon, no Trace exists. Log at debug level. case TRACE_ID: case DEBUG_ID: return logger.isDebugEnabled(); case INFO_ID: return logger.isInfoEnabled(); case WARN_ID: return logger.isWarnEnabled(); case ERROR_ID: return logger.isErrorEnabled(); default: return true; } } /** * Also do a shutdown if the object is destroy()'d. * @throws Throwable */ protected void finalize() throws Throwable { shutdown(); } /** Close all destinations*/ public void shutdown() { logger.unsetLogTargets(); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/LogManager.java0000644000175000017500000002567511437541404025622 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.util.List; import java.util.ArrayList; import java.util.Iterator; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.util.ClassUtils; /** *

    * This class is responsible for instantiating the correct LogChute *

    * *

    * The approach is : *

    *
      *
    • * First try to see if the user is passing in a living object * that is a LogChute, allowing the app to give its living * custom loggers. *
    • *
    • * Next, run through the (possible) list of classes specified * specified as loggers, taking the first one that appears to * work. This is how we support finding logkit, log4j or * jdk logging, whichever is in the classpath and found first, * as all three are listed as defaults. *
    • *
    • * Finally, we turn to the System.err stream and print log messages * to it if nothing else works. *
    • * * @author Jason van Zyl * @author Jon S. Stevens * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: LogManager.java 991708 2010-09-01 21:17:56Z nbubna $ */ public class LogManager { // Creates a new logging system or returns an existing one // specified by the application. private static LogChute createLogChute(RuntimeServices rsvc) throws Exception { Log log = rsvc.getLog(); /* If a LogChute or LogSystem instance was set as a configuration * value, use that. This is any class the user specifies. */ Object o = rsvc.getProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM); if (o != null) { // first check for a LogChute if (o instanceof LogChute) { try { ((LogChute)o).init(rsvc); return (LogChute)o; } catch (Exception e) { String msg = "Could not init runtime.log.logsystem " + o; log.error(msg, e); throw new VelocityException(msg, e); } } // then check for a LogSystem else if (o instanceof LogSystem) { // inform the user about the deprecation log.debug("LogSystem has been deprecated. Please use a LogChute implementation."); try { // wrap the LogSystem into a chute. LogChute chute = new LogChuteSystem((LogSystem)o); chute.init(rsvc); return chute; } catch (Exception e) { String msg = "Could not init runtime.log.logsystem " + o; log.error(msg, e); throw new VelocityException(msg, e); } } else { String msg = o.getClass().getName() + " object set as runtime.log.logsystem is not a valid log implementation."; log.error(msg); throw new VelocityException(msg); } } /* otherwise, see if a class was specified. You can put multiple * classes, and we use the first one we find. * * Note that the default value of this property contains the * AvalonLogChute, the Log4JLogChute, CommonsLogLogChute, * ServletLogChute, and the JdkLogChute for * convenience - so we use whichever we works first. */ List classes = new ArrayList(); Object obj = rsvc.getProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS ); /* * we might have a list, or not - so check */ if ( obj instanceof List) { classes = (List) obj; } else if ( obj instanceof String) { classes.add( obj ); } /* * now run through the list, trying each. It's ok to * fail with a class not found, as we do this to also * search out a default simple file logger */ for( Iterator ii = classes.iterator(); ii.hasNext(); ) { String claz = (String) ii.next(); if (claz != null && claz.length() > 0 ) { log.debug("Trying to use logger class " + claz ); try { o = ClassUtils.getNewInstance( claz ); if (o instanceof LogChute) { ((LogChute)o).init(rsvc); log.debug("Using logger class " + claz); return (LogChute)o; } else if (o instanceof LogSystem) { // inform the user about the deprecation log.debug("LogSystem has been deprecated. Please use a LogChute implementation."); LogChute chute = new LogChuteSystem((LogSystem)o); chute.init(rsvc); return chute; } else { String msg = "The specified logger class " + claz + " does not implement the "+LogChute.class.getName()+" interface."; log.error(msg); // be extra informative if it appears to be a classloader issue // this should match all our provided LogChutes if (isProbablyProvidedLogChute(claz)) { // if it's likely to be ours, tip them off about classloader stuff log.error("This appears to be a ClassLoader issue. Check for multiple Velocity jars in your classpath."); } throw new VelocityException(msg); } } catch(NoClassDefFoundError ncdfe) { // note these errors for anyone debugging the app if (isProbablyProvidedLogChute(claz)) { log.debug("Target log system for " + claz + " is not available (" + ncdfe.toString() + "). Falling back to next log system..."); } else { log.debug("Couldn't find class " + claz + " or necessary supporting classes in classpath.", ncdfe); } } catch(UnsupportedOperationException uoe) { // note these errors for anyone debugging the app if (isProbablyProvidedLogChute(claz)) { log.debug("Target log system for " + claz + " is not supported (" + uoe.toString() + "). Falling back to next log system..."); } else { log.debug("Couldn't find necessary resources for "+claz, uoe); } } catch(Exception e) { String msg = "Failed to initialize an instance of " + claz + " with the current runtime configuration."; // log unexpected init exception at higher priority log.error(msg, e); throw new VelocityException(msg,e); } } } /* If the above failed, that means either the user specified a * logging class that we can't find, there weren't the necessary * dependencies in the classpath for it, or there were the same * problems for the default loggers, log4j and Java1.4+. * Since we really don't know and we want to be sure the user knows * that something went wrong with the logging, let's fall back to the * surefire SystemLogChute. No panicking or failing to log!! */ LogChute slc = new SystemLogChute(); slc.init(rsvc); log.debug("Using SystemLogChute."); return slc; } /** * Simply tells whether the specified classname probably is provided * by Velocity or is implemented by someone else. Not surefire, but * it'll probably always be right. In any case, this method shouldn't * be relied upon for anything important. */ private static boolean isProbablyProvidedLogChute(String claz) { if (claz == null) { return false; } else { return (claz.startsWith("org.apache.velocity.runtime.log") && claz.endsWith("LogChute")); } } /** * Update the Log instance with the appropriate LogChute and other * settings determined by the RuntimeServices. * @param log * @param rsvc * @throws Exception * @since 1.5 */ public static void updateLog(Log log, RuntimeServices rsvc) throws Exception { // create a new LogChute using the RuntimeServices LogChute newLogChute = createLogChute(rsvc); LogChute oldLogChute = log.getLogChute(); // pass the new LogChute to the log first, // (if the old was a HoldingLogChute, we don't want it // to accrue new messages during the transfer below) log.setLogChute(newLogChute); // If the old LogChute was the pre-Init logger, // dump its messages into the new system. if (oldLogChute instanceof HoldingLogChute) { HoldingLogChute hlc = (HoldingLogChute)oldLogChute; hlc.transferTo(newLogChute); } } } velocity-1.7/src/java/org/apache/velocity/runtime/log/SystemLogChute.java0000644000175000017500000001277211126315457026521 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.io.PrintStream; import org.apache.velocity.runtime.RuntimeServices; /** * Logger used when no other is configured. By default, all messages * will be printed to the System.err output stream. * * @author Nathan Bubna * @version $Id: SystemLogChute.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ public class SystemLogChute implements LogChute { public static final String RUNTIME_LOG_LEVEL_KEY = "runtime.log.logsystem.system.level"; public static final String RUNTIME_LOG_SYSTEM_ERR_LEVEL_KEY = "runtime.log.logsystem.system.err.level"; private int enabled = WARN_ID; private int errLevel = TRACE_ID; public void init(RuntimeServices rs) throws Exception { // look for a level config property String level = (String)rs.getProperty(RUNTIME_LOG_LEVEL_KEY); if (level != null) { // and set it accordingly setEnabledLevel(toLevel(level)); } // look for an errLevel config property String errLevel = (String)rs.getProperty(RUNTIME_LOG_SYSTEM_ERR_LEVEL_KEY); if (errLevel != null) { setSystemErrLevel(toLevel(errLevel)); } } protected int toLevel(String level) { if (level.equalsIgnoreCase("debug")) { return DEBUG_ID; } else if (level.equalsIgnoreCase("info")) { return INFO_ID; } else if (level.equalsIgnoreCase("warn")) { return WARN_ID; } else if (level.equalsIgnoreCase("error")) { return ERROR_ID; } else { return TRACE_ID; } } protected String getPrefix(int level) { switch (level) { case WARN_ID: return WARN_PREFIX; case DEBUG_ID: return DEBUG_PREFIX; case TRACE_ID: return TRACE_PREFIX; case ERROR_ID: return ERROR_PREFIX; case INFO_ID: default: return INFO_PREFIX; } } /** * Logs messages to either std.out or std.err * depending on their severity. * * @param level severity level * @param message complete error message */ public void log(int level, String message) { // pass it off log(level, message, null); } /** * Logs messages to the system console so long as the specified level * is equal to or greater than the level this LogChute is enabled for. * If the level is equal to or greater than LogChute.ERROR_ID, * messages will be printed to System.err. Otherwise, they will be * printed to System.out. If a java.lang.Throwable accompanies the * message, it's stack trace will be printed to the same stream * as the message. * * @param level severity level * @param message complete error message * @param t the java.lang.Throwable */ public void log(int level, String message, Throwable t) { if (!isLevelEnabled(level)) { return; } String prefix = getPrefix(level); if (level >= this.errLevel) { write(System.err, prefix, message, t); } else { write(System.out, prefix, message, t); } } protected void write(PrintStream stream, String prefix, String message, Throwable t) { stream.print(prefix); stream.println(message); if (t != null) { stream.println(t.getMessage()); t.printStackTrace(stream); } } /** * Set the minimum level at which messages will be printed. */ public void setEnabledLevel(int level) { this.enabled = level; } /** * Returns the current minimum level at which messages will be printed. */ public int getEnabledLevel() { return this.enabled; } /** * Set the minimum level at which messages will be printed to System.err * instead of System.out. */ public void setSystemErrLevel(int level) { this.errLevel = level; } /** * Returns the current minimum level at which messages will be printed * to System.err instead of System.out. */ public int getSystemErrLevel() { return this.errLevel; } /** * This will return true if the specified level * is equal to or higher than the level this * LogChute is enabled for. */ public boolean isLevelEnabled(int level) { return (level >= this.enabled); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/ServletLogChute.java0000644000175000017500000001243511126315457026655 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.io.StringWriter; import java.io.PrintWriter; import javax.servlet.ServletContext; import org.apache.velocity.runtime.RuntimeServices; /** * Simple wrapper for the servlet log. This passes Velocity log * messages to ServletContext.log(String). You may configure the * level of output in your velocity.properties by adding the * "runtime.log.logsystem.servlet.level" property with one of the * following values: error, warn, info, debug, or trace. The default * is trace. * * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Revision: 730039 $ $Date: 2008-12-30 04:53:19 +0100 (Tue, 30 Dec 2008) $ * @since 1.6 */ public class ServletLogChute implements LogChute { public static final String RUNTIME_LOG_LEVEL_KEY = "runtime.log.logsystem.servlet.level"; private int enabled = TRACE_ID; protected ServletContext servletContext = null; public static final String PREFIX = " Velocity "; /** * Construct a simple logger for a servlet environment. *
      * NOTE: this class expects that the ServletContext has already * been placed in the runtime's application attributes * under its full class name (i.e. "javax.servlet.ServletContext"). */ public ServletLogChute() { } /** * init() * * @throws IllegalStateException if the ServletContext is not available * in the application attributes under the appropriate key. */ public void init(RuntimeServices rs) throws Exception { Object obj = rs.getApplicationAttribute(ServletContext.class.getName()); if (obj == null) { throw new UnsupportedOperationException("Could not retrieve ServletContext from application attributes"); } servletContext = (ServletContext)obj; // look for a level config property String level = (String)rs.getProperty(RUNTIME_LOG_LEVEL_KEY); if (level != null) { // and set it accordingly setEnabledLevel(toLevel(level)); } } protected int toLevel(String level) { if (level.equalsIgnoreCase("debug")) { return DEBUG_ID; } else if (level.equalsIgnoreCase("info")) { return INFO_ID; } else if (level.equalsIgnoreCase("warn")) { return WARN_ID; } else if (level.equalsIgnoreCase("error")) { return ERROR_ID; } else { return TRACE_ID; } } /** * Set the minimum level at which messages will be printed. */ public void setEnabledLevel(int level) { this.enabled = level; } /** * Returns the current minimum level at which messages will be printed. */ public int getEnabledLevel() { return this.enabled; } /** * This will return true if the specified level * is equal to or higher than the level this * LogChute is enabled for. */ public boolean isLevelEnabled(int level) { return (level >= this.enabled); } /** * Send a log message from Velocity. */ public void log(int level, String message) { if (!isLevelEnabled(level)) { return; } switch (level) { case WARN_ID: servletContext.log(PREFIX + WARN_PREFIX + message); break; case INFO_ID: servletContext.log(PREFIX + INFO_PREFIX + message); break; case DEBUG_ID: servletContext.log(PREFIX + DEBUG_PREFIX + message); break; case TRACE_ID: servletContext.log(PREFIX + TRACE_PREFIX + message); break; case ERROR_ID: servletContext.log(PREFIX + ERROR_PREFIX + message); break; default: servletContext.log(PREFIX + " : " + message); break; } } public void log(int level, String message, Throwable t) { if (!isLevelEnabled(level)) { return; } message += " - "+t.toString(); if (level >= ERROR_ID) { StringWriter sw = new StringWriter(); t.printStackTrace(new PrintWriter(sw)); message += "\n" + sw.toString(); } log(level, message); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/HoldingLogChute.java0000644000175000017500000000733611126315457026621 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.util.Vector; import java.util.Iterator; import org.apache.velocity.runtime.RuntimeServices; /** * Pre-init logger. I believe that this was suggested by * Carsten Ziegeler and * Jeroen C. van Gelderen. If this isn't correct, let me * know as this was a good idea... * * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: HoldingLogChute.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ class HoldingLogChute implements LogChute { private Vector pendingMessages = new Vector(); private volatile boolean transferring = false; /** * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices) */ public void init(RuntimeServices rs) throws Exception { } /** * Logs messages. All we do is store them until 'later'. * * @param level severity level * @param message complete error message */ public synchronized void log(int level, String message) { if (!transferring) { Object[] data = new Object[2]; data[0] = new Integer(level); data[1] = message; pendingMessages.addElement(data); } } /** * Logs messages and errors. All we do is store them until 'later'. * * @param level severity level * @param message complete error message * @param t the accompanying java.lang.Throwable */ public synchronized void log(int level, String message, Throwable t) { if (!transferring) { Object[] data = new Object[3]; data[0] = new Integer(level); data[1] = message; data[2] = t; pendingMessages.addElement(data); } } /** * @see org.apache.velocity.runtime.log.LogChute#isLevelEnabled(int) */ public boolean isLevelEnabled(int level) { return true; } /** * Dumps the log messages this chute is holding into a new chute * @param newChute */ public synchronized void transferTo(LogChute newChute) { if (!transferring && !pendingMessages.isEmpty()) { // let the other methods know what's up transferring = true; // iterate and log each individual message... for(Iterator i = pendingMessages.iterator(); i.hasNext();) { Object[] data = (Object[])i.next(); int level = ((Integer)data[0]).intValue(); String message = (String)data[1]; if (data.length == 2) { newChute.log(level, message); } else { newChute.log(level, message, (Throwable)data[2]); } } } } } velocity-1.7/src/java/org/apache/velocity/runtime/log/LogChuteSystem.java0000644000175000017500000000500611126315457026511 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.StringUtils; /** * Wrapper to make user's custom LogSystem implementations work * with the new LogChute setup. * * @author Nathan Bubna * @version $Id: LogChuteSystem.java 730039 2008-12-30 03:53:19Z byron $ * @since 1.5 */ public class LogChuteSystem implements LogChute { private LogSystem logSystem; /** * Only classes in this package should be creating this. * Users should not have to mess with this class. * @param wrapMe */ protected LogChuteSystem(LogSystem wrapMe) { this.logSystem = wrapMe; } /** * @see org.apache.velocity.runtime.log.LogChute#init(org.apache.velocity.runtime.RuntimeServices) */ public void init(RuntimeServices rs) throws Exception { logSystem.init(rs); } /** * @see org.apache.velocity.runtime.log.LogChute#log(int, java.lang.String) */ public void log(int level, String message) { logSystem.logVelocityMessage(level, message); } /** * First passes off the message at the specified level, * then passes off stack trace of the Throwable as a * 2nd message at the same level. * @param level * @param message * @param t */ public void log(int level, String message, Throwable t) { logSystem.logVelocityMessage(level, message); logSystem.logVelocityMessage(level, StringUtils.stackTrace(t)); } /** * @see org.apache.velocity.runtime.log.LogChute#isLevelEnabled(int) */ public boolean isLevelEnabled(int level) { return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/log/Log.java0000644000175000017500000001675611117533044024323 0ustar moellermoellerpackage org.apache.velocity.runtime.log; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.util.introspection.Info; /* * 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. */ /** * Convenient wrapper for LogChute functions. This implements * the RuntimeLogger methods (and then some). It is hoped that * use of this will fully replace use of the RuntimeLogger. * * @author Nathan Bubna * @version $Id: Log.java 724804 2008-12-09 18:17:08Z nbubna $ * @since 1.5 */ public class Log { private LogChute chute; /** * Creates a new Log that wraps a HoldingLogChute. */ public Log() { setLogChute(new HoldingLogChute()); } /** * Creates a new Log that wraps the specified LogChute. * @param chute */ public Log(final LogChute chute) { setLogChute(chute); } /** * Updates the LogChute wrapped by this Log instance. * @param chute The new value for the log chute. */ protected void setLogChute(final LogChute chute) { if (chute == null) { throw new NullPointerException("The LogChute cannot be set to null!"); } this.chute = chute; } /** * Returns the LogChute wrapped by this Log instance. * @return The LogChute wrapped by this Log instance. */ protected LogChute getLogChute() { return this.chute; } protected void log(int level, Object message) { getLogChute().log(level, String.valueOf(message)); } protected void log(int level, Object message, Throwable t) { getLogChute().log(level, String.valueOf(message), t); } /** * Returns true if trace level messages will be printed by the LogChute. * @return If trace level messages will be printed by the LogChute. */ public boolean isTraceEnabled() { return getLogChute().isLevelEnabled(LogChute.TRACE_ID); } /** * Log a trace message. * @param message */ public void trace(Object message) { log(LogChute.TRACE_ID, message); } /** * Log a trace message and accompanying Throwable. * @param message * @param t */ public void trace(Object message, Throwable t) { log(LogChute.TRACE_ID, message, t); } /** * Returns true if debug level messages will be printed by the LogChute. * @return True if debug level messages will be printed by the LogChute. */ public boolean isDebugEnabled() { return getLogChute().isLevelEnabled(LogChute.DEBUG_ID); } /** * Log a debug message. * @param message */ public void debug(Object message) { log(LogChute.DEBUG_ID, message); } /** * Log a debug message and accompanying Throwable. * @param message * @param t */ public void debug(Object message, Throwable t) { log(LogChute.DEBUG_ID, message, t); } /** * Returns true if info level messages will be printed by the LogChute. * @return True if info level messages will be printed by the LogChute. */ public boolean isInfoEnabled() { return getLogChute().isLevelEnabled(LogChute.INFO_ID); } /** * Log an info message. * @param message */ public void info(Object message) { log(LogChute.INFO_ID, message); } /** * Log an info message and accompanying Throwable. * @param message * @param t */ public void info(Object message, Throwable t) { log(LogChute.INFO_ID, message, t); } /** * Returns true if warn level messages will be printed by the LogChute. * @return True if warn level messages will be printed by the LogChute. */ public boolean isWarnEnabled() { return getLogChute().isLevelEnabled(LogChute.WARN_ID); } /** * Log a warning message. * @param message */ public void warn(Object message) { log(LogChute.WARN_ID, message); } /** * Log a warning message and accompanying Throwable. * @param message * @param t */ public void warn(Object message, Throwable t) { log(LogChute.WARN_ID, message, t); } /** * Returns true if error level messages will be printed by the LogChute. * @return True if error level messages will be printed by the LogChute. */ public boolean isErrorEnabled() { return getLogChute().isLevelEnabled(LogChute.ERROR_ID); } /** * Log an error message. * @param message */ public void error(Object message) { log(LogChute.ERROR_ID, message); } /** * Log an error message and accompanying Throwable. * @param message * @param t */ public void error(Object message, Throwable t) { log(LogChute.ERROR_ID, message, t); } /** * Creates a string that formats the template filename with line number * and column of the given Directive. We use this routine to provide a cosistent format for displaying * file errors. */ public static final String formatFileString(Directive directive) { return formatFileString(directive.getTemplateName(), directive.getLine(), directive.getColumn()); } /** * Creates a string that formats the template filename with line number * and column of the given Node. We use this routine to provide a cosistent format for displaying * file errors. */ public static final String formatFileString(Node node) { return formatFileString(node.getTemplateName(), node.getLine(), node.getColumn()); } /** * Simply creates a string that formats the template filename with line number * and column. We use this routine to provide a cosistent format for displaying * file errors. */ public static final String formatFileString(Info info) { return formatFileString(info.getTemplateName(), info.getLine(), info.getColumn()); } /** * Simply creates a string that formats the template filename with line number * and column. We use this routine to provide a cosistent format for displaying * file errors. * @param template File name of template, can be null * @param linenum Line number within the file * @param colnum Column number withing the file at linenum */ public static final String formatFileString(String template, int linenum, int colnum) { if (template == null || template.equals("")) { template = ""; } return template + "[line " + linenum + ", column " + colnum + "]"; } } velocity-1.7/src/java/org/apache/velocity/runtime/log/NullLogSystem.java0000644000175000017500000000250010513464370026345 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ /** * Logger used in case of failure. Does nothing. * * @author Geir Magnusson Jr. * @deprecated Use NullLogChute. * @version $Id: NullLogSystem.java 463298 2006-10-12 16:10:32Z henning $ */ public class NullLogSystem extends NullLogChute implements LogSystem { /** * @param level * @param message * @deprecated Use log(level, message). */ public void logVelocityMessage(int level, String message) { } } velocity-1.7/src/java/org/apache/velocity/runtime/log/VelocityFormatter.java0000644000175000017500000000262110513464370027252 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import java.util.Date; import org.apache.log.format.PatternFormatter; /** * */ public class VelocityFormatter extends PatternFormatter { /** * @param format */ public VelocityFormatter( String format ) { super( format ); } /** * Utility method to format time. * * @param time the time * @param format ancilliary format parameter - allowed to be null * @return the formatted string */ protected String getTime( final long time, final String format ) { return new Date().toString(); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/RuntimeLoggerLog.java0000644000175000017500000001313411050652577027023 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.velocity.runtime.RuntimeLogger; /** * A temporary RuntimeLogger wrapper to make the deprecation * of UberspectLoggable.setRuntimeLogger(RuntimeLogger) feasible. * This overrides all Log methods, either throwing * UnsupportedOperationExceptions or passing things off to the * theoretical RuntimeLogger used to create it. Oh, and all the * isEnabled() methods return true. Of course, ideally * there is no one out there who actually created their own * RuntimeLogger instance to use with UberspectLoggable.setRuntimeLogger() * and this class will therefore never be used. But it's here just in case. * * @author Nathan Bubna * @version $Id: RuntimeLoggerLog.java 685685 2008-08-13 21:43:27Z nbubna $ * @deprecated This will be removed along with the RuntimeLogger interface. * @since 1.5 */ public class RuntimeLoggerLog extends Log { private RuntimeLogger rlog; /** * Creates a new Log that wraps a PrimordialLogChute. * @param rlog */ public RuntimeLoggerLog(RuntimeLogger rlog) { if (rlog == null) { throw new NullPointerException("RuntimeLogger cannot be null!"); } this.rlog = rlog; } /** * @see org.apache.velocity.runtime.log.Log#setLogChute(org.apache.velocity.runtime.log.LogChute) */ protected void setLogChute(LogChute newLogChute) { throw new UnsupportedOperationException("RuntimeLoggerLog does not support this method."); } /** * @see org.apache.velocity.runtime.log.Log#getLogChute() */ protected LogChute getLogChute() { throw new UnsupportedOperationException("RuntimeLoggerLog does not support this method."); } /** * @param showStacks */ protected void setShowStackTraces(boolean showStacks) { throw new UnsupportedOperationException("RuntimeLoggerLog does not support this method."); } /** * @return True if Stack traces should be shown. */ public boolean getShowStackTraces() { throw new UnsupportedOperationException("RuntimeLoggerLog does not support this method."); } /** * @see org.apache.velocity.runtime.log.Log#isTraceEnabled() */ public boolean isTraceEnabled() { return true; } /** * @see org.apache.velocity.runtime.log.Log#trace(java.lang.Object) */ public void trace(Object message) { debug(message); } /** * @see org.apache.velocity.runtime.log.Log#trace(java.lang.Object, java.lang.Throwable) */ public void trace(Object message, Throwable t) { debug(message, t); } /** * @see org.apache.velocity.runtime.log.Log#isDebugEnabled() */ public boolean isDebugEnabled() { return true; } /** * @see org.apache.velocity.runtime.log.Log#debug(java.lang.Object) */ public void debug(Object message) { rlog.debug(message); } /** * @see org.apache.velocity.runtime.log.Log#debug(java.lang.Object, java.lang.Throwable) */ public void debug(Object message, Throwable t) { rlog.debug(message); rlog.debug(t); } /** * @see org.apache.velocity.runtime.log.Log#isInfoEnabled() */ public boolean isInfoEnabled() { return true; } /** * @see org.apache.velocity.runtime.log.Log#info(java.lang.Object) */ public void info(Object message) { rlog.info(message); } /** * @see org.apache.velocity.runtime.log.Log#info(java.lang.Object, java.lang.Throwable) */ public void info(Object message, Throwable t) { rlog.info(message); rlog.info(t); } /** * @see org.apache.velocity.runtime.log.Log#isWarnEnabled() */ public boolean isWarnEnabled() { return true; } /** * @see org.apache.velocity.runtime.log.Log#warn(java.lang.Object) */ public void warn(Object message) { rlog.warn(message); } /** * @see org.apache.velocity.runtime.log.Log#warn(java.lang.Object, java.lang.Throwable) */ public void warn(Object message, Throwable t) { rlog.warn(message); rlog.warn(t); } /** * @see org.apache.velocity.runtime.log.Log#isErrorEnabled() */ public boolean isErrorEnabled() { return true; } /** * @see org.apache.velocity.runtime.log.Log#error(java.lang.Object) */ public void error(Object message) { rlog.error(message); } /** * @see org.apache.velocity.runtime.log.Log#error(java.lang.Object, java.lang.Throwable) */ public void error(Object message, Throwable t) { rlog.error(message); rlog.error(t); } } velocity-1.7/src/java/org/apache/velocity/runtime/log/LogSystem.java0000644000175000017500000000400111126315457025512 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; /** * Old base interface that old logging systems needed to implement. * * @author Jon S. Stevens * @author Geir Magnusson Jr. * @deprecated Use LogChute instead! * @version $Id: LogSystem.java 730039 2008-12-30 03:53:19Z byron $ */ public interface LogSystem { /** * @deprecated This is unused and meaningless */ public final static boolean DEBUG_ON = true; /** * ID for debug messages. */ public final static int DEBUG_ID = 0; /** * ID for info messages. */ public final static int INFO_ID = 1; /** * ID for warning messages. */ public final static int WARN_ID = 2; /** * ID for error messages. */ public final static int ERROR_ID = 3; /** * Initializes this LogSystem. * @param rs * @throws Exception */ public void init( RuntimeServices rs ) throws Exception; /** * @param level * @param message * @deprecated Use log(level, message). */ public void logVelocityMessage(int level, String message); } velocity-1.7/src/java/org/apache/velocity/runtime/log/Log4JLogSystem.java0000644000175000017500000000341210513464370026355 0ustar moellermoellerpackage org.apache.velocity.runtime.log; /* * 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. */ /** * Implementation of a simple log4j system that will either latch onto * an existing category, or just do a simple rolling file log. * * Use this one rather than {@link SimpleLog4JLogSystem}; it uses the * modern Logger concept of Log4J, rather than the * deprecated Categeory concept. * * @author Daniel L. Rall * @author Jon S. Stevens * @author Geir Magnusson Jr. * @version $Id: AvalonLogSystem.java 463298 2006-10-12 16:10:32Z henning $ */ public class AvalonLogSystem extends AvalonLogChute implements LogSystem { /** * @param level * @param message * @deprecated Use log(level, message). */ public void logVelocityMessage(int level, String message) { log(level, message); } } velocity-1.7/src/java/org/apache/velocity/runtime/Renderable.java0000644000175000017500000000306011060021415025033 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import java.io.Writer; import java.io.IOException; /** * This interface caraterize objects other than ASTNodes that can be rendered * to a writer using a context. * * @author Claude Brisson * @version $Id:$ * @since 1.6 */ public interface Renderable { public boolean render( InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException; } velocity-1.7/src/java/org/apache/velocity/runtime/RuntimeSingleton.java0000644000175000017500000005355011322703343026317 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.io.Reader; import java.util.Properties; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.Template; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.resource.ContentResource; import org.apache.velocity.util.introspection.Introspector; import org.apache.velocity.util.introspection.Uberspect; /** * This is the Runtime system for Velocity. It is the * single access point for all functionality in Velocity. * It adheres to the mediator pattern and is the only * structure that developers need to be familiar with * in order to get Velocity to perform. * * The Runtime will also cooperate with external * systems like Turbine. Runtime properties can * set and then the Runtime is initialized. * * Turbine for example knows where the templates * are to be loaded from, and where the velocity * log file should be placed. * * So in the case of Velocity cooperating with Turbine * the code might look something like the following: * *
       * RuntimeSingleton.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
       * RuntimeSingleton.setProperty(RuntimeConstants.RUNTIME_LOG, pathToVelocityLog);
       * RuntimeSingleton.init();
       * 
      * *
       * -----------------------------------------------------------------------
       * N O T E S  O N  R U N T I M E  I N I T I A L I Z A T I O N
       * -----------------------------------------------------------------------
       * RuntimeSingleton.init()
       *
       * If Runtime.init() is called by itself the Runtime will
       * initialize with a set of default values.
       * -----------------------------------------------------------------------
       * RuntimeSingleton.init(String/Properties)
       *
       * In this case the default velocity properties are layed down
       * first to provide a solid base, then any properties provided
       * in the given properties object will override the corresponding
       * default property.
       * -----------------------------------------------------------------------
       * 
      * * @author Jason van Zyl * @author Jeff Bowden * @author Geir Magusson Jr. * @author Daniel Rall * * @see org.apache.velocity.runtime.RuntimeInstance * * @version $Id: RuntimeSingleton.java 898050 2010-01-11 20:15:31Z nbubna $ */ public class RuntimeSingleton implements RuntimeConstants { private static RuntimeInstance ri = new RuntimeInstance(); /** * This is the primary initialization method in the Velocity * Runtime. The systems that are setup/initialized here are * as follows: * *
        *
      • Logging System
      • *
      • ResourceManager
      • *
      • Event Handlers
      • *
      • Parser Pool
      • *
      • Global Cache
      • *
      • Static Content Include System
      • *
      • Velocimacro System
      • *
      * @see RuntimeInstance#init() */ public synchronized static void init() { ri.init(); } /** * Returns true if the RuntimeInstance has been successfully initialized. * @return True if the RuntimeInstance has been successfully initialized. * @see RuntimeInstance#isInitialized() * @since 1.5 */ public static boolean isInitialized() { return ri.isInitialized(); } /** * Returns the RuntimeServices Instance used by this wrapper. * * @return The RuntimeServices Instance used by this wrapper. */ public static RuntimeServices getRuntimeServices() { return ri; } /** * Allows an external system to set a property in * the Velocity Runtime. * * @param key property key * @param value property value * @see RuntimeInstance#setProperty(String, Object) */ public static void setProperty(String key, Object value) { ri.setProperty( key, value ); } /** * Allow an external system to set an ExtendedProperties * object to use. This is useful where the external * system also uses the ExtendedProperties class and * the velocity configuration is a subset of * parent application's configuration. This is * the case with Turbine. * * @param configuration * @see RuntimeInstance#setConfiguration(ExtendedProperties) */ public static void setConfiguration( ExtendedProperties configuration) { ri.setConfiguration( configuration ); } /** * Add a property to the configuration. If it already * exists then the value stated here will be added * to the configuration entry. For example, if * * resource.loader = file * * is already present in the configuration and you * * addProperty("resource.loader", "classpath") * * Then you will end up with a Vector like the * following: * * ["file", "classpath"] * * @param key * @param value * @see RuntimeInstance#addProperty(String, Object) */ public static void addProperty(String key, Object value) { ri.addProperty( key, value ); } /** * Clear the values pertaining to a particular * property. * * @param key of property to clear * @see RuntimeInstance#clearProperty(String) */ public static void clearProperty(String key) { ri.clearProperty( key ); } /** * Allows an external caller to get a property. The calling * routine is required to know the type, as this routine * will return an Object, as that is what properties can be. * * @param key property to return * @return Value of the property or null if it does not exist. * @see RuntimeInstance#getProperty(String) */ public static Object getProperty( String key ) { return ri.getProperty( key ); } /** * Initialize the Velocity Runtime with a Properties * object. * * @param p * @see RuntimeInstance#init(Properties) */ public static void init(Properties p) { ri.init(p); } /** * Initialize the Velocity Runtime with the name of * ExtendedProperties object. * * @param configurationFile * @see RuntimeInstance#init(String) */ public static void init(String configurationFile) { ri.init( configurationFile ); } /** * Parse the input and return the root of * AST node structure. *

      * In the event that it runs out of parsers in the * pool, it will create and let them be GC'd * dynamically, logging that it has to do that. This * is considered an exceptional condition. It is * expected that the user will set the * PARSER_POOL_SIZE property appropriately for their * application. We will revisit this. * * @param reader Reader retrieved by a resource loader * @param templateName name of the template being parsed * @return A root node representing the template as an AST tree. * @throws ParseException When the template could not be parsed. * @see RuntimeInstance#parse(Reader, String) */ public static SimpleNode parse( Reader reader, String templateName ) throws ParseException { return ri.parse( reader, templateName ); } /** * Parse the input and return the root of the AST node structure. * * @param reader Reader retrieved by a resource loader * @param templateName name of the template being parsed * @param dumpNamespace flag to dump the Velocimacro namespace for this template * @return A root node representing the template as an AST tree. * @throws ParseException When the template could not be parsed. * @see RuntimeInstance#parse(Reader, String, boolean) */ public static SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace ) throws ParseException { return ri.parse( reader, templateName, dumpNamespace ); } /** * Returns a Template from the resource manager. * This method assumes that the character encoding of the * template is set by the input.encoding * property. The default is "ISO-8859-1" * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @see RuntimeInstance#getTemplate(String) */ public static Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException { return ri.getTemplate( name ); } /** * Returns a Template from the resource manager * * @param name The name of the desired template. * @param encoding Character encoding of the template * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @see RuntimeInstance#getTemplate(String, String) */ public static Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException { return ri.getTemplate( name, encoding ); } /** * Returns a static content resource from the * resource manager. Uses the current value * if INPUT_ENCODING as the character encoding. * * @param name Name of content resource to get * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException When the template could not be parsed. * @see RuntimeInstance#getContent(String) */ public static ContentResource getContent(String name) throws ResourceNotFoundException, ParseErrorException { return ri.getContent( name ); } /** * Returns a static content resource from the * resource manager. * * @param name Name of content resource to get * @param encoding Character encoding to use * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException When the template could not be parsed. * @see RuntimeInstance#getContent(String, String) */ public static ContentResource getContent( String name, String encoding ) throws ResourceNotFoundException, ParseErrorException { return ri.getContent( name, encoding ); } /** * Determines is a template exists, and returns name of the loader that * provides it. This is a slightly less hokey way to support * the Velocity.templateExists() utility method, which was broken * when per-template encoding was introduced. We can revisit this. * * @param resourceName Name of template or content resource * @return class name of loader than can provide it * @see RuntimeInstance#getLoaderNameForResource(String) */ public static String getLoaderNameForResource( String resourceName ) { return ri.getLoaderNameForResource( resourceName ); } /** * Returns a convenient Log instance that wraps the current LogChute. * * @return A convenience Log instance that wraps the current LogChute. * @see RuntimeInstance#getLog() * @since 1.5 */ public static Log getLog() { return ri.getLog(); } /** * @deprecated Use getLog() and call warn() on it. * @see Log#warn(Object) * @param message The message to log. */ public static void warn(Object message) { getLog().warn(message); } /** * @deprecated Use getLog() and call info() on it. * @see Log#info(Object) * @param message The message to log. */ public static void info(Object message) { getLog().info(message); } /** * @deprecated Use getLog() and call error() on it. * @see Log#error(Object) * @param message The message to log. */ public static void error(Object message) { getLog().error(message); } /** * @deprecated Use getLog() and call debug() on it. * @see Log#debug(Object) * @param message The message to log. */ public static void debug(Object message) { getLog().debug(message); } /** * String property accessor method with default to hide the * configuration implementation. * * @param key property key * @param defaultValue default value to return if key not * found in resource manager. * @return value of key or default * @see RuntimeInstance#getString(String, String) */ public static String getString( String key, String defaultValue) { return ri.getString( key, defaultValue ); } /** * Returns the appropriate VelocimacroProxy object if strVMname * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName Name of the template that contains the velocimacro. * @return The requested VelocimacroProxy. * @see RuntimeInstance#getVelocimacro(String, String) */ public static Directive getVelocimacro( String vmName, String templateName ) { return ri.getVelocimacro( vmName, templateName ); } /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of a new velocimacro. * @param macro root AST node of the parsed macro * @param argArray Array of strings, containing the * #macro() arguments. the 0th argument is the name. * @param sourceTemplate The template from which the macro is requested. * @return boolean True if added, false if rejected for some * reason (either parameters or permission settings) * @see RuntimeInstance#addVelocimacro(String, Node, String[], String) * @since 1.6 */ public static boolean addVelocimacro(String name, Node macro, String argArray[], String sourceTemplate) { return ri.addVelocimacro(name, macro, argArray, sourceTemplate); } /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of velocimacro * @param macro String form of macro body * @param argArray Array of strings, containing the * #macro() arguments. the 0th is the name. * @param sourceTemplate Name of the template that contains the velocimacro. * @return True if added, false if rejected for some * reason (either parameters or permission settings) * * @deprecated Use addVelocimacro(String, Node, String[], String) instead * * @see RuntimeInstance#addVelocimacro(String, String, String[], String) */ public static boolean addVelocimacro( String name, String macro, String argArray[], String sourceTemplate ) { return ri.addVelocimacro( name, macro, argArray, sourceTemplate ); } /** * Checks to see if a VM exists * * @param vmName Name of the Velocimacro. * @param templateName Template on which to look for the Macro. * @return True if VM by that name exists, false if not * @see RuntimeInstance#isVelocimacro(String, String) */ public static boolean isVelocimacro( String vmName, String templateName ) { return ri.isVelocimacro( vmName, templateName ); } /** * tells the vmFactory to dump the specified namespace. This is to support * clearing the VM list when in inline-VM-local-scope mode * @param namespace Namespace to dump. * @return True if namespace was dumped successfully. * @see RuntimeInstance#dumpVMNamespace(String) */ public static boolean dumpVMNamespace( String namespace ) { return ri.dumpVMNamespace( namespace ); } /* -------------------------------------------------------------------- * R U N T I M E A C C E S S O R M E T H O D S * -------------------------------------------------------------------- * These are the getXXX() methods that are a simple wrapper * around the configuration object. This is an attempt * to make a the Velocity Runtime the single access point * for all things Velocity, and allow the Runtime to * adhere as closely as possible the the Mediator pattern * which is the ultimate goal. * -------------------------------------------------------------------- */ /** * String property accessor method to hide the configuration implementation * @param key property key * @return value of key or null * @see RuntimeInstance#getString(String) */ public static String getString(String key) { return ri.getString( key ); } /** * Int property accessor method to hide the configuration implementation. * * @param key Property key * @return value * @see RuntimeInstance#getInt(String) */ public static int getInt( String key ) { return ri.getInt( key ); } /** * Int property accessor method to hide the configuration implementation. * * @param key property key * @param defaultValue The default value. * @return value * @see RuntimeInstance#getInt(String, int) */ public static int getInt( String key, int defaultValue ) { return ri.getInt( key, defaultValue ); } /** * Boolean property accessor method to hide the configuration implementation. * * @param key property key * @param def The default value if property not found. * @return value of key or default value * @see RuntimeInstance#getBoolean(String, boolean) */ public static boolean getBoolean( String key, boolean def ) { return ri.getBoolean( key, def ); } /** * Return the velocity runtime configuration object. * * @return ExtendedProperties configuration object which houses * the velocity runtime properties. * @see RuntimeInstance#getConfiguration() */ public static ExtendedProperties getConfiguration() { return ri.getConfiguration(); } /** * Return the Introspector for this RuntimeInstance * * @return Introspector object for this runtime instance * @see RuntimeInstance#getIntrospector() */ public static Introspector getIntrospector() { return ri.getIntrospector(); } /** * Returns the event handlers for the application. * @return The event handlers for the application. * @see RuntimeInstance#getApplicationEventCartridge() * @since 1.5 */ public EventCartridge getEventCartridge() { return ri.getApplicationEventCartridge(); } /** * Gets the application attribute for the given key * * @see org.apache.velocity.runtime.RuntimeServices#getApplicationAttribute(Object) * @param key * @return The application attribute for the given key. * @see RuntimeInstance#getApplicationAttribute(Object) */ public static Object getApplicationAttribute(Object key) { return ri.getApplicationAttribute(key); } /** * Returns the Uberspect object for this Instance. * * @return The Uberspect object for this Instance. * @see org.apache.velocity.runtime.RuntimeServices#getUberspect() * @see RuntimeInstance#getUberspect() */ public static Uberspect getUberspect() { return ri.getUberspect(); } /** * @deprecated Use getRuntimeServices() instead. * @return The RuntimeInstance used by this Singleton. */ public static RuntimeInstance getRuntimeInstance() { return ri; } /** * Remove a directive. * * @param name name of the directive. */ public static void removeDirective(String name) { ri.removeDirective(name); } /** * Instantiates and loads the directive with some basic checks. * * @param directiveClass classname of directive to load */ public static void loadDirective(String directiveClass) { ri.loadDirective(directiveClass); } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/0000755000175000017500000000000011675166250024000 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/resource/ResourceFactory.java0000644000175000017500000000343210513464370027756 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import org.apache.velocity.Template; /** * Class responsible for instantiating Resource objects, * given name and type. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ResourceFactory.java 463298 2006-10-12 16:10:32Z henning $ */ public class ResourceFactory { /** * @param resourceName * @param resourceType * @return The resource described by name and type. */ public static Resource getResource(String resourceName, int resourceType) { Resource resource = null; switch (resourceType) { case ResourceManager.RESOURCE_TEMPLATE: resource = new Template(); break; case ResourceManager.RESOURCE_CONTENT: resource = new ContentResource(); break; } return resource; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/ContentResource.java0000644000175000017500000000617411052641200027753 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import java.io.StringWriter; import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; /** * This class represent a general text resource that may have been * retrieved from any number of possible sources. * * Also of interest is Velocity's {@link org.apache.velocity.Template} * Resource. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ContentResource.java 687177 2008-08-19 22:00:32Z nbubna $ */ public class ContentResource extends Resource { /** Default empty constructor */ public ContentResource() { super(); setType(ResourceManager.RESOURCE_CONTENT); } /** * Pull in static content and store it. * @return True if everything went ok. * * @exception ResourceNotFoundException Resource could not be * found. */ public boolean process() throws ResourceNotFoundException { BufferedReader reader = null; try { StringWriter sw = new StringWriter(); reader = new BufferedReader( new InputStreamReader(resourceLoader.getResourceStream(name), encoding)); char buf[] = new char[1024]; int len = 0; while ( ( len = reader.read( buf, 0, 1024 )) != -1) sw.write( buf, 0, len ); setData(sw.toString()); return true; } catch ( ResourceNotFoundException e ) { // Tell the ContentManager to continue to look through any // remaining configured ResourceLoaders. throw e; } catch ( Exception e ) { String msg = "Cannot process content resource"; rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } finally { if (reader != null) { try { reader.close(); } catch (Exception ignored) { } } } } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/ResourceManager.java0000644000175000017500000000607111322703343027716 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; /** * Class to manage the text resource for the Velocity * Runtime. * * @author Jason van Zyl * @author Paulo Gaspar * @author Geir Magnusson Jr. * @version $Id: ResourceManager.java 898050 2010-01-11 20:15:31Z nbubna $ */ public interface ResourceManager { /** * A template resources. */ public static final int RESOURCE_TEMPLATE = 1; /** * A static content resource. */ public static final int RESOURCE_CONTENT = 2; /** * Initialize the ResourceManager. * @param rs */ public void initialize( RuntimeServices rs ); /** * Gets the named resource. Returned class type corresponds to specified type * (i.e. Template to RESOURCE_TEMPLATE). * * @param resourceName The name of the resource to retrieve. * @param resourceType The type of resource (RESOURCE_TEMPLATE, * RESOURCE_CONTENT, etc.). * @param encoding The character encoding to use. * @return Resource with the template parsed and ready. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Resource getResource(String resourceName, int resourceType, String encoding ) throws ResourceNotFoundException, ParseErrorException; /** * Determines is a template exists, and returns name of the loader that * provides it. This is a slightly less hokey way to support * the Velocity.templateExists() utility method, which was broken * when per-template encoding was introduced. We can revisit this. * * @param resourceName Name of template or content resource * @return class name of loader than can provide it */ public String getLoaderNameForResource(String resourceName ); } velocity-1.7/src/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java0000644000175000017500000005640311147200252030540 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Vector; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.resource.loader.ResourceLoader; import org.apache.velocity.runtime.resource.loader.ResourceLoaderFactory; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.StringUtils; /** * Class to manage the text resource for the Velocity Runtime. * * @author Will Glass-Husain * @author Jason van Zyl * @author Paulo Gaspar * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: ResourceManagerImpl.java 745757 2009-02-19 06:48:10Z nbubna $ */ public class ResourceManagerImpl implements ResourceManager { /** A template resources. */ public static final int RESOURCE_TEMPLATE = 1; /** A static content resource. */ public static final int RESOURCE_CONTENT = 2; /** token used to identify the loader internally. */ private static final String RESOURCE_LOADER_IDENTIFIER = "_RESOURCE_LOADER_IDENTIFIER_"; /** Object implementing ResourceCache to be our resource manager's Resource cache. */ protected ResourceCache globalCache = null; /** The List of templateLoaders that the Runtime will use to locate the InputStream source of a template. */ protected final List resourceLoaders = new ArrayList(); /** * This is a list of the template input stream source initializers, basically properties for a particular template stream * source. The order in this list reflects numbering of the properties i.e. * *

      <loader-id>.resource.loader.<property> = <value>

      */ private final List sourceInitializerList = new ArrayList(); /** * Has this Manager been initialized? */ private boolean isInit = false; /** switch to turn off log notice when a resource is found for the first time. */ private boolean logWhenFound = true; /** The internal RuntimeServices object. */ protected RuntimeServices rsvc = null; /** Logging. */ protected Log log = null; /** * Initialize the ResourceManager. * * @param rsvc The Runtime Services object which is associated with this Resource Manager. */ public synchronized void initialize(final RuntimeServices rsvc) { if (isInit) { log.debug("Re-initialization of ResourceLoader attempted and ignored."); return; } ResourceLoader resourceLoader = null; this.rsvc = rsvc; log = rsvc.getLog(); log.trace("Default ResourceManager initializing. (" + this.getClass() + ")"); assembleResourceLoaderInitializers(); for (Iterator it = sourceInitializerList.iterator(); it.hasNext();) { /** * Resource loader can be loaded either via class name or be passed * in as an instance. */ ExtendedProperties configuration = (ExtendedProperties) it.next(); String loaderClass = StringUtils.nullTrim(configuration.getString("class")); ResourceLoader loaderInstance = (ResourceLoader) configuration.get("instance"); if (loaderInstance != null) { resourceLoader = loaderInstance; } else if (loaderClass != null) { resourceLoader = ResourceLoaderFactory.getLoader(rsvc, loaderClass); } else { String msg = "Unable to find '" + configuration.getString(RESOURCE_LOADER_IDENTIFIER) + ".resource.loader.class' specification in configuration." + " This is a critical value. Please adjust configuration."; log.error(msg); throw new VelocityException(msg); } resourceLoader.commonInit(rsvc, configuration); resourceLoader.init(configuration); resourceLoaders.add(resourceLoader); } /* * now see if this is overridden by configuration */ logWhenFound = rsvc.getBoolean(RuntimeConstants.RESOURCE_MANAGER_LOGWHENFOUND, true); /* * now, is a global cache specified? */ String cacheClassName = rsvc.getString(RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS); Object cacheObject = null; if (org.apache.commons.lang.StringUtils.isNotEmpty(cacheClassName)) { try { cacheObject = ClassUtils.getNewInstance(cacheClassName); } catch (ClassNotFoundException cnfe) { String msg = "The specified class for ResourceCache (" + cacheClassName + ") does not exist or is not accessible to the current classloader."; log.error(msg, cnfe); throw new VelocityException(msg, cnfe); } catch (IllegalAccessException ae) { throw new VelocityException("Could not access class '" + cacheClassName + "'", ae); } catch (InstantiationException ie) { throw new VelocityException("Could not instantiate class '" + cacheClassName + "'", ie); } if (!(cacheObject instanceof ResourceCache)) { String msg = "The specified resource cache class (" + cacheClassName + ") must implement " + ResourceCache.class.getName(); log.error(msg); throw new RuntimeException(msg); } } /* * if we didn't get through that, just use the default. */ if (cacheObject == null) { cacheObject = new ResourceCacheImpl(); } globalCache = (ResourceCache) cacheObject; globalCache.initialize(rsvc); log.trace("Default ResourceManager initialization complete."); } /** * This will produce a List of Hashtables, each hashtable contains the intialization info for a particular resource loader. This * Hashtable will be passed in when initializing the the template loader. */ private void assembleResourceLoaderInitializers() { Vector resourceLoaderNames = rsvc.getConfiguration().getVector(RuntimeConstants.RESOURCE_LOADER); StringUtils.trimStrings(resourceLoaderNames); for (Iterator it = resourceLoaderNames.iterator(); it.hasNext(); ) { /* * The loader id might look something like the following: * * file.resource.loader * * The loader id is the prefix used for all properties * pertaining to a particular loader. */ String loaderName = (String) it.next(); StringBuffer loaderID = new StringBuffer(loaderName); loaderID.append(".").append(RuntimeConstants.RESOURCE_LOADER); ExtendedProperties loaderConfiguration = rsvc.getConfiguration().subset(loaderID.toString()); /* * we can't really count on ExtendedProperties to give us an empty set */ if (loaderConfiguration == null) { log.debug("ResourceManager : No configuration information found "+ "for resource loader named '" + loaderName + "' (id is "+loaderID+"). Skipping it..."); continue; } /* * add the loader name token to the initializer if we need it * for reference later. We can't count on the user to fill * in the 'name' field */ loaderConfiguration.setProperty(RESOURCE_LOADER_IDENTIFIER, loaderName); /* * Add resources to the list of resource loader * initializers. */ sourceInitializerList.add(loaderConfiguration); } } /** * Gets the named resource. Returned class type corresponds to specified type (i.e. Template to * RESOURCE_TEMPLATE). * * This method is now unsynchronized which requires that ResourceCache * implementations be thread safe (as the default is). * * @param resourceName The name of the resource to retrieve. * @param resourceType The type of resource (RESOURCE_TEMPLATE, RESOURCE_CONTENT, etc.). * @param encoding The character encoding to use. * * @return Resource with the template parsed and ready. * * @throws ResourceNotFoundException if template not found from any available source. * @throws ParseErrorException if template cannot be parsed due to syntax (or other) error. */ public Resource getResource(final String resourceName, final int resourceType, final String encoding) throws ResourceNotFoundException, ParseErrorException { /* * Check to see if the resource was placed in the cache. * If it was placed in the cache then we will use * the cached version of the resource. If not we * will load it. * * Note: the type is included in the key to differentiate ContentResource * (static content from #include) with a Template. */ String resourceKey = resourceType + resourceName; Resource resource = globalCache.get(resourceKey); if (resource != null) { try { // avoids additional method call to refreshResource if (resource.requiresChecking()) { /* * both loadResource() and refreshResource() now return * a new Resource instance when they are called * (put in the cache when appropriate) in order to allow * several threads to parse the same template simultaneously. * It is redundant work and will cause more garbage collection but the * benefit is that it allows concurrent parsing and processing * without race conditions when multiple requests try to * refresh/load the same template at the same time. * * Another alternative is to limit template parsing/retrieval * so that only one thread can parse each template at a time * but that creates a scalability bottleneck. * * See VELOCITY-606, VELOCITY-595 and VELOCITY-24 */ resource = refreshResource(resource, encoding); } } catch (ResourceNotFoundException rnfe) { /* * something exceptional happened to that resource * this could be on purpose, * so clear the cache and try again */ globalCache.remove(resourceKey); return getResource(resourceName, resourceType, encoding); } catch (ParseErrorException pee) { log.error("ResourceManager.getResource() exception", pee); throw pee; } catch (RuntimeException re) { log.error("ResourceManager.getResource() exception", re); throw re; } } else { try { /* * it's not in the cache, so load it. */ resource = loadResource(resourceName, resourceType, encoding); if (resource.getResourceLoader().isCachingOn()) { globalCache.put(resourceKey, resource); } } catch (ResourceNotFoundException rnfe) { log.error("ResourceManager : unable to find resource '" + resourceName + "' in any resource loader."); throw rnfe; } catch (ParseErrorException pee) { log.error("ResourceManager.getResource() parse exception", pee); throw pee; } catch (RuntimeException re) { log.error("ResourceManager.getResource() load exception", re); throw re; } } return resource; } /** * Create a new Resource of the specified type. * * @param resourceName The name of the resource to retrieve. * @param resourceType The type of resource (RESOURCE_TEMPLATE, RESOURCE_CONTENT, etc.). * @return new instance of appropriate resource type * @since 1.6 */ protected Resource createResource(String resourceName, int resourceType) { return ResourceFactory.getResource(resourceName, resourceType); } /** * Loads a resource from the current set of resource loaders. * * @param resourceName The name of the resource to retrieve. * @param resourceType The type of resource (RESOURCE_TEMPLATE, RESOURCE_CONTENT, etc.). * @param encoding The character encoding to use. * * @return Resource with the template parsed and ready. * * @throws ResourceNotFoundException if template not found from any available source. * @throws ParseErrorException if template cannot be parsed due to syntax (or other) error. */ protected Resource loadResource(String resourceName, int resourceType, String encoding) throws ResourceNotFoundException, ParseErrorException { Resource resource = createResource(resourceName, resourceType); resource.setRuntimeServices(rsvc); resource.setName(resourceName); resource.setEncoding(encoding); /* * Now we have to try to find the appropriate * loader for this resource. We have to cycle through * the list of available resource loaders and see * which one gives us a stream that we can use to * make a resource with. */ long howOldItWas = 0; for (Iterator it = resourceLoaders.iterator(); it.hasNext();) { ResourceLoader resourceLoader = (ResourceLoader) it.next(); resource.setResourceLoader(resourceLoader); /* * catch the ResourceNotFound exception * as that is ok in our new multi-loader environment */ try { if (resource.process()) { /* * FIXME (gmj) * moved in here - technically still * a problem - but the resource needs to be * processed before the loader can figure * it out due to to the new * multi-path support - will revisit and fix */ if (logWhenFound && log.isDebugEnabled()) { log.debug("ResourceManager : found " + resourceName + " with loader " + resourceLoader.getClassName()); } howOldItWas = resourceLoader.getLastModified(resource); break; } } catch (ResourceNotFoundException rnfe) { /* * that's ok - it's possible to fail in * multi-loader environment */ } } /* * Return null if we can't find a resource. */ if (resource.getData() == null) { throw new ResourceNotFoundException("Unable to find resource '" + resourceName + "'"); } /* * some final cleanup */ resource.setLastModified(howOldItWas); resource.setModificationCheckInterval(resource.getResourceLoader().getModificationCheckInterval()); resource.touch(); return resource; } /** * Takes an existing resource, and 'refreshes' it. This generally means that the source of the resource is checked for changes * according to some cache/check algorithm and if the resource changed, then the resource data is reloaded and re-parsed. * * @param resource resource to refresh * @param encoding character encoding of the resource to refresh. * * @throws ResourceNotFoundException if template not found from current source for this Resource * @throws ParseErrorException if template cannot be parsed due to syntax (or other) error. */ protected Resource refreshResource(Resource resource, final String encoding) throws ResourceNotFoundException, ParseErrorException { /* * The resource knows whether it needs to be checked * or not, and the resource's loader can check to * see if the source has been modified. If both * these conditions are true then we must reload * the input stream and parse it to make a new * AST for the resource. */ /* * touch() the resource to reset the counters */ resource.touch(); /* check whether this can now be found in a higher priority * resource loader. if so, pass the request off to loadResource. */ ResourceLoader loader = resource.getResourceLoader(); if (resourceLoaders.size() > 0 && resourceLoaders.indexOf(loader) > 0) { String name = resource.getName(); if (loader != getLoaderForResource(name)) { return loadResource(name, resource.getType(), encoding); } } if (resource.isSourceModified()) { /* * now check encoding info. It's possible that the newly declared * encoding is different than the encoding already in the resource * this strikes me as bad... */ if (!org.apache.commons.lang.StringUtils.equals(resource.getEncoding(), encoding)) { log.warn("Declared encoding for template '" + resource.getName() + "' is different on reload. Old = '" + resource.getEncoding() + "' New = '" + encoding); resource.setEncoding(encoding); } /* * read how old the resource is _before_ * processing (=>reading) it */ long howOldItWas = loader.getLastModified(resource); String resourceKey = resource.getType() + resource.getName(); /* * we create a copy to avoid partially overwriting a * template which may be in use in another thread */ Resource newResource = ResourceFactory.getResource(resource.getName(), resource.getType()); newResource.setRuntimeServices(rsvc); newResource.setName(resource.getName()); newResource.setEncoding(resource.getEncoding()); newResource.setResourceLoader(loader); newResource.setModificationCheckInterval(loader.getModificationCheckInterval()); newResource.process(); newResource.setLastModified(howOldItWas); resource = newResource; globalCache.put(resourceKey, newResource); } return resource; } /** * Gets the named resource. Returned class type corresponds to specified type (i.e. Template to * RESOURCE_TEMPLATE). * * @param resourceName The name of the resource to retrieve. * @param resourceType The type of resource (RESOURCE_TEMPLATE, RESOURCE_CONTENT, etc.). * * @return Resource with the template parsed and ready. * * @throws ResourceNotFoundException if template not found from any available source. * @throws ParseErrorException if template cannot be parsed due to syntax (or other) error. * @throws Exception if a problem in parse * * @deprecated Use {@link #getResource(String resourceName, int resourceType, String encoding )} */ public Resource getResource(String resourceName, int resourceType) throws ResourceNotFoundException, ParseErrorException, Exception { return getResource(resourceName, resourceType, RuntimeConstants.ENCODING_DEFAULT); } /** * Determines if a template exists, and returns name of the loader that provides it. This is a slightly less hokey way to * support the Velocity.templateExists() utility method, which was broken when per-template encoding was introduced. We can * revisit this. * * @param resourceName Name of template or content resource * * @return class name of loader than can provide it */ public String getLoaderNameForResource(String resourceName) { ResourceLoader loader = getLoaderForResource(resourceName); if (loader == null) { return null; } return loader.getClass().toString(); } /** * Returns the first {@link ResourceLoader} in which the specified * resource exists. */ private ResourceLoader getLoaderForResource(String resourceName) { for (Iterator i = resourceLoaders.iterator(); i.hasNext(); ) { ResourceLoader loader = (ResourceLoader)i.next(); if (loader.resourceExists(resourceName)) { return loader; } } return null; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/0000755000175000017500000000000011675166250025246 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java0000644000175000017500000001167410523173621032672 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.InputStream; import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.lang.StringUtils; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.ExceptionUtils; /** * ClasspathResourceLoader is a simple loader that will load * templates from the classpath. *
      *
      * Will load templates from from multiple instances of * and arbitrary combinations of : *
        *
      • jar files *
      • zip files *
      • template directories (any directory containing templates) *
      * This is a configuration-free loader, in that there are no * parameters to be specified in the configuration properties, * other than specifying this as the loader to use. For example * the following is all that the loader needs to be functional : *
      *
      * resource.loader = class * class.resource.loader.class = * org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader *
      *
      * To use, put your template directories, jars * and zip files into the classpath or other mechanisms that make * resources accessable to the classloader. *
      *
      * This makes deployment trivial for web applications running in * any Servlet 2.2 compliant servlet runner, such as Tomcat 3.2 * and others. *
      *
      * For a Servlet Spec v2.2 servlet runner, * just drop the jars of template files into the WEB-INF/lib * directory of your webapp, and you won't have to worry about setting * template paths or altering them with the root of the webapp * before initializing. *
      *
      * I have also tried it with a WAR deployment, and that seemed to * work just fine. * * @author Aki Nieminen * @author Geir Magnusson Jr. * @version $Id: ClasspathResourceLoader.java 471259 2006-11-04 20:26:57Z henning $ */ public class ClasspathResourceLoader extends ResourceLoader { /** * This is abstract in the base class, so we need it * @param configuration */ public void init( ExtendedProperties configuration) { if (log.isTraceEnabled()) { log.trace("ClasspathResourceLoader : initialization complete."); } } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param name name of template to get * @return InputStream containing the template * @throws ResourceNotFoundException if template not found * in classpath. */ public InputStream getResourceStream( String name ) throws ResourceNotFoundException { InputStream result = null; if (StringUtils.isEmpty(name)) { throw new ResourceNotFoundException ("No template name provided"); } /** * look for resource in thread classloader first (e.g. WEB-INF\lib in * a servlet container) then fall back to the system classloader. */ try { result = ClassUtils.getResourceAsStream( getClass(), name ); } catch( Exception fnfe ) { throw (ResourceNotFoundException) ExceptionUtils.createWithCause(ResourceNotFoundException.class, "problem with template: " + name, fnfe ); } if (result == null) { String msg = "ClasspathResourceLoader Error: cannot find resource " + name; throw new ResourceNotFoundException( msg ); } return result; } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#isSourceModified(org.apache.velocity.runtime.resource.Resource) */ public boolean isSourceModified(Resource resource) { return false; } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#getLastModified(org.apache.velocity.runtime.resource.Resource) */ public long getLastModified(Resource resource) { return 0; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java0000644000175000017500000001710111057363623031407 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.InputStream; import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.lang.StringUtils; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.resource.Resource; /** * This is a simple URL-based loader. * * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: URLResourceLoader.java 191743 2005-06-21 23:22:20Z dlr $ * @since 1.5 */ public class URLResourceLoader extends ResourceLoader { private String[] roots = null; protected HashMap templateRoots = null; private int timeout = -1; private Method[] timeoutMethods; /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties) */ public void init(ExtendedProperties configuration) { log.trace("URLResourceLoader : initialization starting."); roots = configuration.getStringArray("root"); if (log.isDebugEnabled()) { for (int i=0; i < roots.length; i++) { log.debug("URLResourceLoader : adding root '" + roots[i] + "'"); } } timeout = configuration.getInt("timeout", -1); if (timeout > 0) { try { Class[] types = new Class[] { Integer.TYPE }; Method conn = URLConnection.class.getMethod("setConnectTimeout", types); Method read = URLConnection.class.getMethod("setReadTimeout", types); timeoutMethods = new Method[] { conn, read }; log.debug("URLResourceLoader : timeout set to "+timeout); } catch (NoSuchMethodException nsme) { log.debug("URLResourceLoader : Java 1.5+ is required to customize timeout!", nsme); timeout = -1; } } // init the template paths map templateRoots = new HashMap(); log.trace("URLResourceLoader : initialization complete."); } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param name name of template to fetch bytestream of * @return InputStream containing the template * @throws ResourceNotFoundException if template not found * in the file template path. */ public synchronized InputStream getResourceStream(String name) throws ResourceNotFoundException { if (StringUtils.isEmpty(name)) { throw new ResourceNotFoundException("URLResourceLoader : No template name provided"); } InputStream inputStream = null; Exception exception = null; for(int i=0; i < roots.length; i++) { try { URL u = new URL(roots[i] + name); URLConnection conn = u.openConnection(); tryToSetTimeout(conn); inputStream = conn.getInputStream(); if (inputStream != null) { if (log.isDebugEnabled()) log.debug("URLResourceLoader: Found '"+name+"' at '"+roots[i]+"'"); // save this root for later re-use templateRoots.put(name, roots[i]); break; } } catch(IOException ioe) { if (log.isDebugEnabled()) log.debug("URLResourceLoader: Exception when looking for '"+name+"' at '"+roots[i]+"'", ioe); // only save the first one for later throwing if (exception == null) { exception = ioe; } } } // if we never found the template if (inputStream == null) { String msg; if (exception == null) { msg = "URLResourceLoader : Resource '" + name + "' not found."; } else { msg = exception.getMessage(); } // convert to a general Velocity ResourceNotFoundException throw new ResourceNotFoundException(msg); } return inputStream; } /** * Checks to see if a resource has been deleted, moved or modified. * * @param resource Resource The resource to check for modification * @return boolean True if the resource has been modified, moved, or unreachable */ public boolean isSourceModified(Resource resource) { long fileLastModified = getLastModified(resource); // if the file is unreachable or otherwise changed if (fileLastModified == 0 || fileLastModified != resource.getLastModified()) { return true; } return false; } /** * Checks to see when a resource was last modified * * @param resource Resource the resource to check * @return long The time when the resource was last modified or 0 if the file can't be reached */ public long getLastModified(Resource resource) { // get the previously used root String name = resource.getName(); String root = (String)templateRoots.get(name); try { // get a connection to the URL URL u = new URL(root + name); URLConnection conn = u.openConnection(); tryToSetTimeout(conn); return conn.getLastModified(); } catch (IOException ioe) { // the file is not reachable at its previous address String msg = "URLResourceLoader: '"+name+"' is no longer reachable at '"+root+"'"; log.error(msg, ioe); throw new ResourceNotFoundException(msg, ioe); } } /** * Returns the current, custom timeout setting. If negative, there is no custom timeout. * @since 1.6 */ public int getTimeout() { return timeout; } private void tryToSetTimeout(URLConnection conn) { if (timeout > 0) { Object[] arg = new Object[] { new Integer(timeout) }; try { timeoutMethods[0].invoke(conn, arg); timeoutMethods[1].invoke(conn, arg); } catch (Exception e) { String msg = "Unexpected exception while setting connection timeout for "+conn; log.error(msg, e); throw new VelocityException(msg, e); } } } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java0000644000175000017500000003503511265443753032225 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.lang.StringUtils; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.runtime.resource.util.StringResource; import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl; import org.apache.velocity.util.ClassUtils; /** * Resource loader that works with Strings. Users should manually add * resources to the repository that is used by the resource loader instance. * * Below is an example configuration for this loader. * Note that 'repository.class' is not necessary; * if not provided, the factory will fall back on using * {@link StringResourceRepositoryImpl} as the default. *
       * resource.loader = string
       * string.resource.loader.description = Velocity StringResource loader
       * string.resource.loader.class = org.apache.velocity.runtime.resource.loader.StringResourceLoader
       * string.resource.loader.repository.class = org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl
       * 
      * Resources can be added to the repository like this: *
      
       *   StringResourceRepository repo = StringResourceLoader.getRepository();
       *
       *   String myTemplateName = "/some/imaginary/path/hello.vm";
       *   String myTemplate = "Hi, ${username}... this is some template!";
       *   repo.putStringResource(myTemplateName, myTemplate);
       * 
      * * After this, the templates can be retrieved as usual. *
      *

      If there will be multiple StringResourceLoaders used in an application, * you should consider specifying a 'string.resource.loader.repository.name = foo' * property in order to keep you string resources in a non-default repository. * This can help to avoid conflicts between different frameworks or components * that are using StringResourceLoader. * You can then retrieve your named repository like this: *

      
       *   StringResourceRepository repo = StringResourceLoader.getRepository("foo");
       * 
      * and add string resources to the repo just as in the previous example. *

      *

      If you have concerns about memory leaks or for whatever reason do not wish * to have your string repository stored statically as a class member, then you * should set 'string.resource.loader.repository.static = false' in your properties. * This will tell the resource loader that the string repository should be stored * in the Velocity application attributes. To retrieve the repository, do: *

      
       *   StringResourceRepository repo = velocityEngine.getApplicationAttribute("foo");
       * 
      * If you did not specify a name for the repository, then it will be stored under the * class name of the repository implementation class (for which the default is * 'org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl'). * Incidentally, this is also true for the default statically stored repository. *

      *

      Whether your repository is stored statically or in Velocity's application * attributes, you can also manually create and set it prior to Velocity * initialization. For a static repository, you can do something like this: *

      
       *   StringResourceRepository repo = new MyStringResourceRepository();
       *   repo.magicallyAddSomeStringResources();
       *   StringResourceLoader.setRepository("foo", repo);
       * 
      * Or for a non-static repository: *
      
       *   StringResourceRepository repo = new MyStringResourceRepository();
       *   repo.magicallyAddSomeStringResources();
       *   velocityEngine.setApplicationAttribute("foo", repo);
       * 
      * Then, assuming the 'string.resource.loader.repository.name' property is * set to 'some.name', the StringResourceLoader will use that already created * repository, rather than creating a new one. *

      * * @author Eelco Hillenius * @author Henning P. Schmiedehausen * @author Nathan Bubna * @version $Id: StringResourceLoader.java 825302 2009-10-14 21:51:39Z nbubna $ * @since 1.5 */ public class StringResourceLoader extends ResourceLoader { /** * Key to determine whether the repository should be set as the static one or not. * @since 1.6 */ public static final String REPOSITORY_STATIC = "repository.static"; /** * By default, repositories are stored statically (shared across the VM). * @since 1.6 */ public static final boolean REPOSITORY_STATIC_DEFAULT = true; /** Key to look up the repository implementation class. */ public static final String REPOSITORY_CLASS = "repository.class"; /** The default implementation class. */ public static final String REPOSITORY_CLASS_DEFAULT = StringResourceRepositoryImpl.class.getName(); /** * Key to look up the name for the repository to be used. * @since 1.6 */ public static final String REPOSITORY_NAME = "repository.name"; /** The default name for string resource repositories * ('org.apache.velocity.runtime.resource.util.StringResourceRepository'). * @since 1.6 */ public static final String REPOSITORY_NAME_DEFAULT = StringResourceRepository.class.getName(); /** Key to look up the repository char encoding. */ public static final String REPOSITORY_ENCODING = "repository.encoding"; /** The default repository encoding. */ public static final String REPOSITORY_ENCODING_DEFAULT = "UTF-8"; protected static final Map STATIC_REPOSITORIES = Collections.synchronizedMap(new HashMap()); /** * Returns a reference to the default static repository. */ public static StringResourceRepository getRepository() { return getRepository(REPOSITORY_NAME_DEFAULT); } /** * Returns a reference to the repository stored statically under the * specified name. * @since 1.6 */ public static StringResourceRepository getRepository(String name) { return (StringResourceRepository)STATIC_REPOSITORIES.get(name); } /** * Sets the specified {@link StringResourceRepository} in static storage * under the specified name. * @since 1.6 */ public static void setRepository(String name, StringResourceRepository repo) { STATIC_REPOSITORIES.put(name, repo); } /** * Removes the {@link StringResourceRepository} stored under the specified * name. * @since 1.6 */ public static StringResourceRepository removeRepository(String name) { return (StringResourceRepository)STATIC_REPOSITORIES.remove(name); } /** * Removes all statically stored {@link StringResourceRepository}s. * @since 1.6 */ public static void clearRepositories() { STATIC_REPOSITORIES.clear(); } // the repository used internally by this resource loader protected StringResourceRepository repository; /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties) */ public void init(final ExtendedProperties configuration) { log.trace("StringResourceLoader : initialization starting."); // get the repository configuration info String repoClass = configuration.getString(REPOSITORY_CLASS, REPOSITORY_CLASS_DEFAULT); String repoName = configuration.getString(REPOSITORY_NAME, REPOSITORY_NAME_DEFAULT); boolean isStatic = configuration.getBoolean(REPOSITORY_STATIC, REPOSITORY_STATIC_DEFAULT); String encoding = configuration.getString(REPOSITORY_ENCODING); // look for an existing repository of that name and isStatic setting if (isStatic) { this.repository = getRepository(repoName); if (repository != null && log.isDebugEnabled()) { log.debug("Loaded repository '"+repoName+"' from static repo store"); } } else { this.repository = (StringResourceRepository)rsvc.getApplicationAttribute(repoName); if (repository != null && log.isDebugEnabled()) { log.debug("Loaded repository '"+repoName+"' from application attributes"); } } if (this.repository == null) { // since there's no repository under the repo name, create a new one this.repository = createRepository(repoClass, encoding); // and store it according to the isStatic setting if (isStatic) { setRepository(repoName, this.repository); } else { rsvc.setApplicationAttribute(repoName, this.repository); } } else { // ok, we already have a repo // warn them if they are trying to change the class of the repository if (!this.repository.getClass().getName().equals(repoClass)) { log.debug("Cannot change class of string repository '"+repoName+ "' from "+this.repository.getClass().getName()+" to "+repoClass+ ". The change will be ignored."); } // allow them to change the default encoding of the repo if (encoding != null && !this.repository.getEncoding().equals(encoding)) { if (log.isDebugEnabled()) { log.debug("Changing the default encoding of string repository '"+repoName+ "' from "+this.repository.getEncoding()+" to "+encoding); } this.repository.setEncoding(encoding); } } log.trace("StringResourceLoader : initialization complete."); } /** * @since 1.6 */ public StringResourceRepository createRepository(final String className, final String encoding) { if (log.isDebugEnabled()) { log.debug("Creating string repository using class "+className+"..."); } StringResourceRepository repo; try { repo = (StringResourceRepository) ClassUtils.getNewInstance(className); } catch (ClassNotFoundException cnfe) { throw new VelocityException("Could not find '" + className + "'", cnfe); } catch (IllegalAccessException iae) { throw new VelocityException("Could not access '" + className + "'", iae); } catch (InstantiationException ie) { throw new VelocityException("Could not instantiate '" + className + "'", ie); } if (encoding != null) { repo.setEncoding(encoding); } else { repo.setEncoding(REPOSITORY_ENCODING_DEFAULT); } if (log.isDebugEnabled()) { log.debug("Default repository encoding is " + repo.getEncoding()); } return repo; } /** * Overrides superclass for better performance. * @since 1.6 */ public boolean resourceExists(final String name) { if (name == null) { return false; } return (this.repository.getStringResource(name) != null); } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param name name of template to get. * @return InputStream containing the template. * @throws ResourceNotFoundException Ff template not found * in the RepositoryFactory. */ public InputStream getResourceStream(final String name) throws ResourceNotFoundException { if (StringUtils.isEmpty(name)) { throw new ResourceNotFoundException("No template name provided"); } StringResource resource = this.repository.getStringResource(name); if(resource == null) { throw new ResourceNotFoundException("Could not locate resource '" + name + "'"); } byte [] byteArray = null; try { byteArray = resource.getBody().getBytes(resource.getEncoding()); return new ByteArrayInputStream(byteArray); } catch(UnsupportedEncodingException ue) { throw new VelocityException("Could not convert String using encoding " + resource.getEncoding(), ue); } } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#isSourceModified(org.apache.velocity.runtime.resource.Resource) */ public boolean isSourceModified(final Resource resource) { StringResource original = null; boolean result = true; original = this.repository.getStringResource(resource.getName()); if (original != null) { result = original.getLastModified() != resource.getLastModified(); } return result; } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#getLastModified(org.apache.velocity.runtime.resource.Resource) */ public long getLastModified(final Resource resource) { StringResource original = null; original = this.repository.getStringResource(resource.getName()); return (original != null) ? original.getLastModified() : 0; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/ResourceLoaderFactory.java0000644000175000017500000000437311322700447032355 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.ClassUtils; /** * Factory to grab a template loader. * * @author Jason van Zyl * @version $Id: ResourceLoaderFactory.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class ResourceLoaderFactory { /** * Gets the loader specified in the configuration file. * @param rs * @param loaderClassName * @return TemplateLoader */ public static ResourceLoader getLoader(RuntimeServices rs, String loaderClassName) { ResourceLoader loader = null; try { loader = (ResourceLoader) ClassUtils.getNewInstance( loaderClassName ); rs.getLog().debug("ResourceLoader instantiated: " + loader.getClass().getName()); return loader; } // The ugly three strike again: ClassNotFoundException,IllegalAccessException,InstantiationException catch(Exception e) { String msg = "Problem instantiating the template loader: "+loaderClassName+".\n" + "Look at your properties file and make sure the\n" + "name of the template loader is correct."; rs.getLog().error(msg, e); throw new VelocityException(msg, e); } } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java0000644000175000017500000003732711437522752033015 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.BufferedInputStream; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.util.ExceptionUtils; import org.apache.velocity.util.StringUtils; /** *

      This is a simple template file loader that loads templates * from a DataSource instead of plain files. * *

      It can be configured with a datasource name, a table name, * id column (name), content column (the template body) and a * datetime column (for last modification info). *
      *
      * Example configuration snippet for velocity.properties: *
      *
      * resource.loader = file, ds
      *
      * ds.resource.loader.public.name = DataSource
      * ds.resource.loader.description = Velocity DataSource Resource Loader
      * ds.resource.loader.class = org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader
      * ds.resource.loader.resource.datasource = java:comp/env/jdbc/Velocity
      * ds.resource.loader.resource.table = tb_velocity_template
      * ds.resource.loader.resource.keycolumn = id_template
      * ds.resource.loader.resource.templatecolumn = template_definition
      * ds.resource.loader.resource.timestampcolumn = template_timestamp
      * ds.resource.loader.cache = false
      * ds.resource.loader.modificationCheckInterval = 60
      *
      *

      Optionally, the developer can instantiate the DataSourceResourceLoader and set the DataSource via code in * a manner similar to the following: *
      *
      * DataSourceResourceLoader ds = new DataSourceResourceLoader();
      * ds.setDataSource(DATASOURCE);
      * Velocity.setProperty("ds.resource.loader.instance",ds);
      *

      The property ds.resource.loader.class should be left out, otherwise all the other * properties in velocity.properties would remain the same. *
      *
      * * Example WEB-INF/web.xml:
      *
      *
      * Velocity template DataSource
      * jdbc/Velocity
      * javax.sql.DataSource
      * Container
      *

      *
      *
      * and Tomcat 4 server.xml file:
      * [...]
      *
      * [...]
      *
      *
      * driverClassName
      * org.hsql.jdbcDriver
      *

      *
      * driverName
      * jdbc:HypersonicSQL:database
      *

      *
      * user
      * database_username
      *

      *
      * password
      * database_password
      *

      *

      * [...]
      *

      * [...]
      *
      * Example sql script:
      * CREATE TABLE tb_velocity_template (
      * id_template varchar (40) NOT NULL ,
      * template_definition text (16) NOT NULL ,
      * template_timestamp datetime NOT NULL
      * )
      * * @author Will Glass-Husain * @author Matt Raible * @author David Kinnvall * @author Paulo Gaspar * @author Sylwester Lachiewicz * @author Henning P. Schmiedehausen * @version $Id: DataSourceResourceLoader.java 991660 2010-09-01 19:13:46Z nbubna $ * @since 1.5 */ public class DataSourceResourceLoader extends ResourceLoader { private String dataSourceName; private String tableName; private String keyColumn; private String templateColumn; private String timestampColumn; private InitialContext ctx; private DataSource dataSource; /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties) */ public void init(ExtendedProperties configuration) { dataSourceName = StringUtils.nullTrim(configuration.getString("resource.datasource")); tableName = StringUtils.nullTrim(configuration.getString("resource.table")); keyColumn = StringUtils.nullTrim(configuration.getString("resource.keycolumn")); templateColumn = StringUtils.nullTrim(configuration.getString("resource.templatecolumn")); timestampColumn = StringUtils.nullTrim(configuration.getString("resource.timestampcolumn")); if (dataSource != null) { if (log.isDebugEnabled()) { log.debug("DataSourceResourceLoader: using dataSource instance with table \"" + tableName + "\""); log.debug("DataSourceResourceLoader: using columns \"" + keyColumn + "\", \"" + templateColumn + "\" and \"" + timestampColumn + "\""); } log.trace("DataSourceResourceLoader initialized."); } else if (dataSourceName != null) { if (log.isDebugEnabled()) { log.debug("DataSourceResourceLoader: using \"" + dataSourceName + "\" datasource with table \"" + tableName + "\""); log.debug("DataSourceResourceLoader: using columns \"" + keyColumn + "\", \"" + templateColumn + "\" and \"" + timestampColumn + "\""); } log.trace("DataSourceResourceLoader initialized."); } else { String msg = "DataSourceResourceLoader not properly initialized. No DataSource was identified."; log.error(msg); throw new RuntimeException(msg); } } /** * Set the DataSource used by this resource loader. Call this as an alternative to * specifying the data source name via properties. * @param dataSource The data source for this ResourceLoader. */ public void setDataSource(final DataSource dataSource) { this.dataSource = dataSource; } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#isSourceModified(org.apache.velocity.runtime.resource.Resource) */ public boolean isSourceModified(final Resource resource) { return (resource.getLastModified() != readLastModified(resource, "checking timestamp")); } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#getLastModified(org.apache.velocity.runtime.resource.Resource) */ public long getLastModified(final Resource resource) { return readLastModified(resource, "getting timestamp"); } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param name name of template * @return InputStream containing template * @throws ResourceNotFoundException */ public synchronized InputStream getResourceStream(final String name) throws ResourceNotFoundException { if (org.apache.commons.lang.StringUtils.isEmpty(name)) { throw new ResourceNotFoundException("DataSourceResourceLoader: Template name was empty or null"); } Connection conn = null; ResultSet rs = null; PreparedStatement ps = null; try { conn = openDbConnection(); ps = getStatement(conn, templateColumn, name); rs = ps.executeQuery(); if (rs.next()) { InputStream stream = rs.getBinaryStream(templateColumn); if (stream == null) { throw new ResourceNotFoundException("DataSourceResourceLoader: " + "template column for '" + name + "' is null"); } return new BufferedInputStream(stream); } else { throw new ResourceNotFoundException("DataSourceResourceLoader: " + "could not find resource '" + name + "'"); } } catch (SQLException sqle) { String msg = "DataSourceResourceLoader: database problem while getting resource '" + name + "': "; log.error(msg, sqle); throw new ResourceNotFoundException(msg); } catch (NamingException ne) { String msg = "DataSourceResourceLoader: database problem while getting resource '" + name + "': "; log.error(msg, ne); throw new ResourceNotFoundException(msg); } finally { closeResultSet(rs); closeStatement(ps); closeDbConnection(conn); } } /** * Fetches the last modification time of the resource * * @param resource Resource object we are finding timestamp of * @param operation string for logging, indicating caller's intention * * @return timestamp as long */ private long readLastModified(final Resource resource, final String operation) { long timeStamp = 0; /* get the template name from the resource */ String name = resource.getName(); if (name == null || name.length() == 0) { String msg = "DataSourceResourceLoader: Template name was empty or null"; log.error(msg); throw new NullPointerException(msg); } else { Connection conn = null; ResultSet rs = null; PreparedStatement ps = null; try { conn = openDbConnection(); ps = getStatement(conn, timestampColumn, name); rs = ps.executeQuery(); if (rs.next()) { Timestamp ts = rs.getTimestamp(timestampColumn); timeStamp = ts != null ? ts.getTime() : 0; } else { String msg = "DataSourceResourceLoader: could not find resource " + name + " while " + operation; log.error(msg); throw new ResourceNotFoundException(msg); } } catch (SQLException sqle) { String msg = "DataSourceResourceLoader: database problem while " + operation + " of '" + name + "': "; log.error(msg, sqle); throw ExceptionUtils.createRuntimeException(msg, sqle); } catch (NamingException ne) { String msg = "DataSourceResourceLoader: database problem while " + operation + " of '" + name + "': "; log.error(msg, ne); throw ExceptionUtils.createRuntimeException(msg, ne); } finally { closeResultSet(rs); closeStatement(ps); closeDbConnection(conn); } } return timeStamp; } /** * Gets connection to the datasource specified through the configuration * parameters. * * @return connection */ private Connection openDbConnection() throws NamingException, SQLException { if (dataSource != null) { return dataSource.getConnection(); } if (ctx == null) { ctx = new InitialContext(); } dataSource = (DataSource) ctx.lookup(dataSourceName); return dataSource.getConnection(); } /** * Closes connection to the datasource */ private void closeDbConnection(final Connection conn) { if (conn != null) { try { conn.close(); } catch (RuntimeException re) { throw re; } catch (Exception e) { String msg = "DataSourceResourceLoader: problem when closing connection"; log.error(msg, e); throw new VelocityException(msg, e); } } } /** * Closes the result set. */ private void closeResultSet(final ResultSet rs) { if (rs != null) { try { rs.close(); } catch (RuntimeException re) { throw re; } catch (Exception e) { String msg = "DataSourceResourceLoader: problem when closing result set"; log.error(msg, e); throw new VelocityException(msg, e); } } } /** * Closes the PreparedStatement. */ private void closeStatement(PreparedStatement ps) { if (ps != null) { try { ps.close(); } catch (RuntimeException re) { throw re; } catch (Exception e) { String msg = "DataSourceResourceLoader: problem when closing PreparedStatement "; log.error(msg, e); throw new VelocityException(msg, e); } } } /** * Creates the following PreparedStatement query : *
      * SELECT columnNames FROM tableName WHERE keyColumn * = 'templateName' *
      * where keyColumn is a class member set in init() * * @param conn connection to datasource * @param columnNames columns to fetch from datasource * @param templateName name of template to fetch * @return PreparedStatement */ private PreparedStatement getStatement(final Connection conn, final String columnNames, final String templateName) throws SQLException { PreparedStatement ps = conn.prepareStatement("SELECT " + columnNames + " FROM "+ tableName + " WHERE " + keyColumn + " = ?"); ps.setString(1, templateName); return ps; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/JarHolder.java0000644000175000017500000001064011052641200027742 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.IOException; import java.io.InputStream; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.Hashtable; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; /** * A small wrapper around a Jar * * @author Dave Bryson * @version $Id: JarHolder.java 687177 2008-08-19 22:00:32Z nbubna $ */ public class JarHolder { private String urlpath = null; private JarFile theJar = null; private JarURLConnection conn = null; private Log log = null; /** * @param rs * @param urlpath */ public JarHolder( RuntimeServices rs, String urlpath ) { this.log = rs.getLog(); this.urlpath=urlpath; init(); if (log.isDebugEnabled()) { log.debug("JarHolder: initialized JAR: " + urlpath); } } /** * */ public void init() { try { if (log.isDebugEnabled()) { log.debug("JarHolder: attempting to connect to " + urlpath); } URL url = new URL( urlpath ); conn = (JarURLConnection) url.openConnection(); conn.setAllowUserInteraction(false); conn.setDoInput(true); conn.setDoOutput(false); conn.connect(); theJar = conn.getJarFile(); } catch (IOException ioe) { String msg = "JarHolder: error establishing connection to JAR at \"" + urlpath + "\""; log.error(msg, ioe); throw new VelocityException(msg, ioe); } } /** * */ public void close() { try { theJar.close(); } catch ( Exception e ) { String msg = "JarHolder: error closing the JAR file"; log.error(msg, e); throw new VelocityException(msg, e); } theJar = null; conn = null; log.trace("JarHolder: JAR file closed"); } /** * @param theentry * @return The requested resource. * @throws ResourceNotFoundException */ public InputStream getResource( String theentry ) throws ResourceNotFoundException { InputStream data = null; try { JarEntry entry = theJar.getJarEntry( theentry ); if ( entry != null ) { data = theJar.getInputStream( entry ); } } catch(Exception fnfe) { log.error("JarHolder: getResource() error", fnfe); throw new ResourceNotFoundException(fnfe); } return data; } /** * @return The entries of the jar as a hashtable. */ public Hashtable getEntries() { Hashtable allEntries = new Hashtable(559); Enumeration all = theJar.entries(); while ( all.hasMoreElements() ) { JarEntry je = (JarEntry)all.nextElement(); // We don't map plain directory entries if ( !je.isDirectory() ) { allEntries.put( je.getName(), this.urlpath ); } } return allEntries; } /** * @return The URL path of this jar holder. */ public String getUrlPath() { return urlpath; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java0000644000175000017500000001777311057702133031471 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.InputStream; import java.util.Hashtable; import java.util.Vector; import java.util.Map; import java.util.HashMap; import org.apache.velocity.util.StringUtils; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.commons.collections.ExtendedProperties; /** *

      * ResourceLoader to load templates from multiple Jar files. *

      *

      * The configuration of the JarResourceLoader is straightforward - * You simply add the JarResourceLoader to the configuration via *

      *

       *    resource.loader = jar
       *    jar.resource.loader.class = org.apache.velocity.runtime.resource.loader.JarResourceLoader
       *    jar.resource.loader.path = list of JAR <URL>s
       * 

      * *

      So for example, if you had a jar file on your local filesystem, you could simply do *

       *    jar.resource.loader.path = jar:file:/opt/myfiles/jar1.jar
       *    
      *

      *

      Note that jar specification for the .path configuration property * conforms to the same rules for the java.net.JarUrlConnection class. *

      * *

      For a working example, see the unit test case, * org.apache.velocity.test.MultiLoaderTestCase class *

      * * @author Aki Nieminen * @author Dave Bryson * @version $Id: JarResourceLoader.java 691884 2008-09-04 06:46:51Z nbubna $ */ public class JarResourceLoader extends ResourceLoader { /** * Maps entries to the parent JAR File * Key = the entry *excluding* plain directories * Value = the JAR URL */ private Map entryDirectory = new HashMap(559); /** * Maps JAR URLs to the actual JAR * Key = the JAR URL * Value = the JAR */ private Map jarfiles = new HashMap(89); /** * Called by Velocity to initialize the loader * @param configuration */ public void init( ExtendedProperties configuration) { log.trace("JarResourceLoader : initialization starting."); // rest of Velocity engine still use legacy Vector // and Hashtable classes. Classes are implicitly // synchronized even if we don't need it. Vector paths = configuration.getVector("path"); StringUtils.trimStrings(paths); /* * support the old version but deprecate with a log message */ if( paths == null || paths.size() == 0) { paths = configuration.getVector("resource.path"); StringUtils.trimStrings(paths); if (paths != null && paths.size() > 0) { log.debug("JarResourceLoader : you are using a deprecated configuration" + " property for the JarResourceLoader -> '.resource.loader.resource.path'." + " Please change to the conventional '.resource.loader.path'."); } } if (paths != null) { log.debug("JarResourceLoader # of paths : " + paths.size() ); for ( int i=0; iWill Glass-Husain * @author Aki Nieminen * @author Jason van Zyl * @version $Id: FileResourceLoader.java 743616 2009-02-12 04:38:53Z nbubna $ */ public class FileResourceLoader extends ResourceLoader { /** * The paths to search for templates. */ private List paths = new ArrayList(); /** * Used to map the path that a template was found on * so that we can properly check the modification * times of the files. This is synchronizedMap * instance. */ private Map templatePaths = Collections.synchronizedMap(new HashMap()); /** Shall we inspect unicode files to see what encoding they contain?. */ private boolean unicode = false; /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties) */ public void init( ExtendedProperties configuration) { if (log.isTraceEnabled()) { log.trace("FileResourceLoader : initialization starting."); } paths.addAll( configuration.getVector("path") ); // unicode files may have a BOM marker at the start, but Java // has problems recognizing the UTF-8 bom. Enabling unicode will // recognize all unicode boms. unicode = configuration.getBoolean("unicode", false); if (log.isDebugEnabled()) { log.debug("Do unicode file recognition: " + unicode); } if (log.isDebugEnabled()) { // trim spaces from all paths StringUtils.trimStrings(paths); // this section lets tell people what paths we will be using int sz = paths.size(); for( int i=0; i < sz; i++) { log.debug("FileResourceLoader : adding path '" + (String) paths.get(i) + "'"); } log.trace("FileResourceLoader : initialization complete."); } } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param templateName name of template to get * @return InputStream containing the template * @throws ResourceNotFoundException if template not found * in the file template path. */ public InputStream getResourceStream(String templateName) throws ResourceNotFoundException { /* * Make sure we have a valid templateName. */ if (org.apache.commons.lang.StringUtils.isEmpty(templateName)) { /* * If we don't get a properly formed templateName then * there's not much we can do. So we'll forget about * trying to search any more paths for the template. */ throw new ResourceNotFoundException( "Need to specify a file name or file path!"); } String template = StringUtils.normalizePath(templateName); if ( template == null || template.length() == 0 ) { String msg = "File resource error : argument " + template + " contains .. and may be trying to access " + "content outside of template root. Rejected."; log.error("FileResourceLoader : " + msg); throw new ResourceNotFoundException ( msg ); } int size = paths.size(); for (int i = 0; i < size; i++) { String path = (String) paths.get(i); InputStream inputStream = null; try { inputStream = findTemplate(path, template); } catch (IOException ioe) { String msg = "Exception while loading Template " + template; log.error(msg, ioe); throw new VelocityException(msg, ioe); } if (inputStream != null) { /* * Store the path that this template came * from so that we can check its modification * time. */ templatePaths.put(templateName, path); return inputStream; } } /* * We have now searched all the paths for * templates and we didn't find anything so * throw an exception. */ throw new ResourceNotFoundException("FileResourceLoader : cannot find " + template); } /** * Overrides superclass for better performance. * @since 1.6 */ public boolean resourceExists(String name) { if (name == null) { return false; } name = StringUtils.normalizePath(name); if (name == null || name.length() == 0) { return false; } int size = paths.size(); for (int i = 0; i < size; i++) { String path = (String)paths.get(i); try { File file = getFile(path, name); if (file.canRead()) { return true; } } catch (Exception ioe) { String msg = "Exception while checking for template " + name; log.debug(msg, ioe); } } return false; } /** * Try to find a template given a normalized path. * * @param path a normalized path * @param template name of template to find * @return InputStream input stream that will be parsed * */ private InputStream findTemplate(final String path, final String template) throws IOException { try { File file = getFile(path,template); if (file.canRead()) { FileInputStream fis = null; try { fis = new FileInputStream(file.getAbsolutePath()); if (unicode) { UnicodeInputStream uis = null; try { uis = new UnicodeInputStream(fis, true); if (log.isDebugEnabled()) { log.debug("File Encoding for " + file + " is: " + uis.getEncodingFromStream()); } return new BufferedInputStream(uis); } catch(IOException e) { closeQuiet(uis); throw e; } } else { return new BufferedInputStream(fis); } } catch (IOException e) { closeQuiet(fis); throw e; } } else { return null; } } catch(FileNotFoundException fnfe) { /* * log and convert to a general Velocity ResourceNotFoundException */ return null; } } private void closeQuiet(final InputStream is) { if (is != null) { try { is.close(); } catch(IOException ioe) { // Ignore } } } /** * How to keep track of all the modified times * across the paths. Note that a file might have * appeared in a directory which is earlier in the * path; so we should search the path and see if * the file we find that way is the same as the one * that we have cached. * @param resource * @return True if the source has been modified. */ public boolean isSourceModified(Resource resource) { /* * we assume that the file needs to be reloaded; * if we find the original file and it's unchanged, * then we'll flip this. */ boolean modified = true; String fileName = resource.getName(); String path = (String) templatePaths.get(fileName); File currentFile = null; for (int i = 0; currentFile == null && i < paths.size(); i++) { String testPath = (String) paths.get(i); File testFile = getFile(testPath, fileName); if (testFile.canRead()) { currentFile = testFile; } } File file = getFile(path, fileName); if (currentFile == null || !file.exists()) { /* * noop: if the file is missing now (either the cached * file is gone, or the file can no longer be found) * then we leave modified alone (it's set to true); a * reload attempt will be done, which will either use * a new template or fail with an appropriate message * about how the file couldn't be found. */ } else if (currentFile.equals(file) && file.canRead()) { /* * if only if currentFile is the same as file and * file.lastModified() is the same as * resource.getLastModified(), then we should use the * cached version. */ modified = (file.lastModified() != resource.getLastModified()); } /* * rsvc.debug("isSourceModified for " + fileName + ": " + modified); */ return modified; } /** * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#getLastModified(org.apache.velocity.runtime.resource.Resource) */ public long getLastModified(Resource resource) { String path = (String) templatePaths.get(resource.getName()); File file = getFile(path, resource.getName()); if (file.canRead()) { return file.lastModified(); } else { return 0; } } /** * Create a File based on either a relative path if given, or absolute path otherwise */ private File getFile(String path, String template) { File file = null; if("".equals(path)) { file = new File( template ); } else { /* * if a / leads off, then just nip that :) */ if (template.startsWith("/")) { template = template.substring(1); } file = new File ( path, template ); } return file; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java0000644000175000017500000001755111273714733031037 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.loader; /* * 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. */ import java.io.InputStream; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.runtime.resource.ResourceCacheImpl; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; import org.apache.commons.collections.ExtendedProperties; /** * This is abstract class the all text resource loaders should * extend. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ResourceLoader.java 832280 2009-11-03 02:47:55Z wglass $ */ public abstract class ResourceLoader { /** * Does this loader want templates produced with it * cached in the Runtime. */ protected boolean isCachingOn = false; /** * This property will be passed on to the templates * that are created with this loader. */ protected long modificationCheckInterval = 2; /** * Class name for this loader, for logging/debuggin * purposes. */ protected String className = null; protected RuntimeServices rsvc = null; protected Log log = null; /** * This initialization is used by all resource * loaders and must be called to set up common * properties shared by all resource loaders * @param rs * @param configuration */ public void commonInit( RuntimeServices rs, ExtendedProperties configuration) { this.rsvc = rs; this.log = rsvc.getLog(); /* * these two properties are not required for all loaders. * For example, for ClasspathLoader, what would cache mean? * so adding default values which I think are the safest * * don't cache, and modCheckInterval irrelevant... */ try { isCachingOn = configuration.getBoolean("cache", false); } catch (Exception e) { isCachingOn = false; String msg = "Exception parsing cache setting: "+configuration.getString("cache"); log.error(msg, e); throw new VelocityException(msg, e); } try { modificationCheckInterval = configuration.getLong("modificationCheckInterval", 0); } catch (Exception e) { modificationCheckInterval = 0; String msg = "Exception parsing modificationCheckInterval setting: "+configuration.getString("modificationCheckInterval"); log.error(msg, e); throw new VelocityException(msg, e); } /* * this is a must! */ className = ResourceCacheImpl.class.getName(); try { className = configuration.getString("class", className); } catch (Exception e) { String msg = "Exception retrieving resource cache class name"; log.error(msg, e); throw new VelocityException(msg, e); } } /** * Initialize the template loader with a * a resources class. * @param configuration */ public abstract void init( ExtendedProperties configuration); /** * Get the InputStream that the Runtime will parse * to create a template. * @param source * @return The input stream for the requested resource. * @throws ResourceNotFoundException */ public abstract InputStream getResourceStream( String source ) throws ResourceNotFoundException; /** * Given a template, check to see if the source of InputStream * has been modified. * @param resource * @return True if the resource has been modified. */ public abstract boolean isSourceModified(Resource resource); /** * Get the last modified time of the InputStream source * that was used to create the template. We need the template * here because we have to extract the name of the template * in order to locate the InputStream source. * @param resource * @return Time in millis when the resource has been modified. */ public abstract long getLastModified(Resource resource); /** * Return the class name of this resource Loader * @return Class name of the resource loader. */ public String getClassName() { return className; } /** * Set the caching state. If true, then this loader * would like the Runtime to cache templates that * have been created with InputStreams provided * by this loader. * @param value */ public void setCachingOn(boolean value) { isCachingOn = value; } /** * The Runtime uses this to find out whether this * template loader wants the Runtime to cache * templates created with InputStreams provided * by this loader. * @return True if this resource loader caches. */ public boolean isCachingOn() { return isCachingOn; } /** * Set the interval at which the InputStream source * should be checked for modifications. * @param modificationCheckInterval */ public void setModificationCheckInterval(long modificationCheckInterval) { this.modificationCheckInterval = modificationCheckInterval; } /** * Get the interval at which the InputStream source * should be checked for modifications. * @return The modification check interval. */ public long getModificationCheckInterval() { return modificationCheckInterval; } /** * Check whether any given resource exists. This is not really * a very efficient test and it can and should be overridden in the * subclasses extending ResourceLoader. * * @param resourceName The name of a resource. * @return true if a resource exists and can be accessed. * @since 1.6 */ public boolean resourceExists(final String resourceName) { InputStream is = null; try { is = getResourceStream(resourceName); } catch (ResourceNotFoundException e) { if (log.isDebugEnabled()) { log.debug("Could not load resource '" + resourceName + "' from ResourceLoader " + this.getClass().getName() + ": " + e.getMessage()); } } finally { try { if (is != null) { is.close(); } } catch (Exception e) { if (log.isErrorEnabled()) { String msg = "While closing InputStream for resource '" + resourceName + "' from ResourceLoader "+this.getClass().getName(); log.error(msg, e); throw new VelocityException(msg, e); } } } return (is != null); } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/Resource.java0000644000175000017500000001632211126111461026417 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.ResourceLoader; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; /** * This class represent a general text resource that * may have been retrieved from any number of possible * sources. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: Resource.java 729843 2008-12-29 09:06:57Z byron $ */ public abstract class Resource { protected RuntimeServices rsvc = null; /** * The template loader that initially loaded the input * stream for this template, and knows how to check the * source of the input stream for modification. */ protected ResourceLoader resourceLoader; /** * The number of milliseconds in a minute, used to calculate the * check interval. */ protected static final long MILLIS_PER_SECOND = 1000; /** * How often the file modification time is checked (in seconds). */ protected long modificationCheckInterval = 0; /** * The file modification time (in milliseconds) for the cached template. */ protected long lastModified = 0; /** * The next time the file modification time will be checked (in * milliseconds). */ protected long nextCheck = 0; /** * Name of the resource */ protected String name; /** * Character encoding of this resource */ protected String encoding = RuntimeConstants.ENCODING_DEFAULT; /** * Resource might require ancillary storage of some kind */ protected Object data = null; /** * Resource type (RESOURCE_TEMPLATE or RESOURCE_CONTENT) */ protected int type; /** * Default constructor */ public Resource() { } /** * @param rs */ public void setRuntimeServices( RuntimeServices rs ) { rsvc = rs; } /** * Perform any subsequent processing that might need * to be done by a resource. In the case of a template * the actual parsing of the input stream needs to be * performed. * * @return Whether the resource could be processed successfully. * For a {@link org.apache.velocity.Template} or {@link * org.apache.velocity.runtime.resource.ContentResource}, this * indicates whether the resource could be read. * @exception ResourceNotFoundException Similar in semantics as * returning false. * @throws ParseErrorException */ public abstract boolean process() throws ResourceNotFoundException, ParseErrorException; /** * @return True if source has been modified. */ public boolean isSourceModified() { return resourceLoader.isSourceModified(this); } /** * Set the modification check interval. * @param modificationCheckInterval The interval (in seconds). */ public void setModificationCheckInterval(long modificationCheckInterval) { this.modificationCheckInterval = modificationCheckInterval; } /** * Is it time to check to see if the resource * source has been updated? * @return True if resource must be checked. */ public boolean requiresChecking() { /* * short circuit this if modificationCheckInterval == 0 * as this means "don't check" */ if (modificationCheckInterval <= 0 ) { return false; } /* * see if we need to check now */ return ( System.currentTimeMillis() >= nextCheck ); } /** * 'Touch' this template and thereby resetting * the nextCheck field. */ public void touch() { nextCheck = System.currentTimeMillis() + ( MILLIS_PER_SECOND * modificationCheckInterval); } /** * Set the name of this resource, for example * test.vm. * @param name */ public void setName(String name) { this.name = name; } /** * Get the name of this template. * @return The name of this template. */ public String getName() { return name; } /** * set the encoding of this resource * for example, "ISO-8859-1" * @param encoding */ public void setEncoding( String encoding ) { this.encoding = encoding; } /** * get the encoding of this resource * for example, "ISO-8859-1" * @return The encoding of this resource. */ public String getEncoding() { return encoding; } /** * Return the lastModifed time of this * resource. * @return The lastModifed time of this resource. */ public long getLastModified() { return lastModified; } /** * Set the last modified time for this * resource. * @param lastModified */ public void setLastModified(long lastModified) { this.lastModified = lastModified; } /** * Return the template loader that pulled * in the template stream * @return The resource loader for this resource. */ public ResourceLoader getResourceLoader() { return resourceLoader; } /** * Set the template loader for this template. Set * when the Runtime determines where this template * came from the list of possible sources. * @param resourceLoader */ public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } /** * Set arbitrary data object that might be used * by the resource. * @param data */ public void setData(Object data) { this.data = data; } /** * Get arbitrary data object that might be used * by the resource. * @return The data object for this resource. */ public Object getData() { return data; } /** * Sets the type of this Resource (RESOURCE_TEMPLATE or RESOURCE_CONTENT) * @since 1.6 */ public void setType(int type) { this.type = type; } /** * @return type code of the Resource * @since 1.6 */ public int getType() { return type; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/ResourceCache.java0000644000175000017500000000446110513464370027355 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import java.util.Iterator; import org.apache.velocity.runtime.RuntimeServices; /** * Interface that defines the shape of a pluggable resource cache * for the included ResourceManager * * @author Geir Magnusson Jr. * @version $Id: ResourceCache.java 463298 2006-10-12 16:10:32Z henning $ */ public interface ResourceCache { /** * initializes the ResourceCache. Will be * called before any utilization * * @param rs RuntimeServices to use for logging, etc */ public void initialize( RuntimeServices rs ); /** * retrieves a Resource from the * cache * * @param resourceKey key for Resource to be retrieved * @return Resource specified or null if not found */ public Resource get( Object resourceKey ); /** * stores a Resource in the cache * * @param resourceKey key to associate with the Resource * @param resource Resource to be stored * @return existing Resource stored under this key, or null if none */ public Resource put( Object resourceKey, Resource resource ); /** * removes a Resource from the cache * * @param resourceKey resource to be removed * @return stored under key */ public Resource remove( Object resourceKey ); /** * returns an Iterator of Keys in the cache. * @return An Iterator of Keys in the cache. */ public Iterator enumerateKeys(); } velocity-1.7/src/java/org/apache/velocity/runtime/resource/ResourceCacheImpl.java0000644000175000017500000000735311322700447030177 0ustar moellermoellerpackage org.apache.velocity.runtime.resource; /* * 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. */ import java.util.Collections; import java.util.Iterator; import java.util.Map; import org.apache.commons.collections.map.LRUMap; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.MapFactory; /** * Default implementation of the resource cache for the default * ResourceManager. The cache uses a least recently used (LRU) * algorithm, with a maximum size specified via the * resource.manager.cache.size property (idenfied by the * {@link * org.apache.velocity.runtime.RuntimeConstants#RESOURCE_MANAGER_DEFAULTCACHE_SIZE} * constant). This property get be set to 0 or less for * a greedy, unbounded cache (the behavior from pre-v1.5). * * @author Geir Magnusson Jr. * @author Daniel Rall * @version $Id: ResourceCacheImpl.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class ResourceCacheImpl implements ResourceCache { /** * Cache storage, assumed to be thread-safe. */ protected Map cache = MapFactory.create(512, 0.5f, 30, false); /** * Runtime services, generally initialized by the * initialize() method. */ protected RuntimeServices rsvc = null; /** * @see org.apache.velocity.runtime.resource.ResourceCache#initialize(org.apache.velocity.runtime.RuntimeServices) */ public void initialize( RuntimeServices rs ) { rsvc = rs; int maxSize = rsvc.getInt(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE, 89); if (maxSize > 0) { // Create a whole new Map here to avoid hanging on to a // handle to the unsynch'd LRUMap for our lifetime. Map lruCache = Collections.synchronizedMap(new LRUMap(maxSize)); lruCache.putAll(cache); cache = lruCache; } rsvc.getLog().debug("ResourceCache: initialized ("+this.getClass()+") with "+ cache.getClass()+" cache map."); } /** * @see org.apache.velocity.runtime.resource.ResourceCache#get(java.lang.Object) */ public Resource get( Object key ) { return (Resource) cache.get( key ); } /** * @see org.apache.velocity.runtime.resource.ResourceCache#put(java.lang.Object, org.apache.velocity.runtime.resource.Resource) */ public Resource put( Object key, Resource value ) { return (Resource) cache.put( key, value ); } /** * @see org.apache.velocity.runtime.resource.ResourceCache#remove(java.lang.Object) */ public Resource remove( Object key ) { return (Resource) cache.remove( key ); } /** * @see org.apache.velocity.runtime.resource.ResourceCache#enumerateKeys() */ public Iterator enumerateKeys() { return cache.keySet().iterator(); } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/util/0000755000175000017500000000000011675166250024755 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/resource/util/StringResourceRepositoryImpl.java0000644000175000017500000000600211050665114033504 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.util; /* * 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. */ import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; /** * Default implementation of StringResourceRepository. * Uses a HashMap for storage * * @author Eelco Hillenius * @author Henning P. Schmiedehausen * @version $Id: StringResourceRepositoryImpl.java 685724 2008-08-13 23:12:12Z nbubna $ * @since 1.5 */ public class StringResourceRepositoryImpl implements StringResourceRepository { /** * mem store */ protected Map resources = Collections.synchronizedMap(new HashMap()); /** * Current Repository encoding. */ private String encoding = StringResourceLoader.REPOSITORY_ENCODING_DEFAULT; /** * @see StringResourceRepository#getStringResource(java.lang.String) */ public StringResource getStringResource(final String name) { return (StringResource)resources.get(name); } /** * @see StringResourceRepository#putStringResource(java.lang.String, java.lang.String) */ public void putStringResource(final String name, final String body) { resources.put(name, new StringResource(body, getEncoding())); } /** * @see StringResourceRepository#putStringResource(java.lang.String, java.lang.String, java.lang.String) * @since 1.6 */ public void putStringResource(final String name, final String body, final String encoding) { resources.put(name, new StringResource(body, encoding)); } /** * @see StringResourceRepository#removeStringResource(java.lang.String) */ public void removeStringResource(final String name) { resources.remove(name); } /** * @see org.apache.velocity.runtime.resource.util.StringResourceRepository#getEncoding() */ public String getEncoding() { return encoding; } /** * @see org.apache.velocity.runtime.resource.util.StringResourceRepository#setEncoding(java.lang.String) */ public void setEncoding(final String encoding) { this.encoding = encoding; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/util/StringResource.java0000644000175000017500000000555411050652577030606 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.util; /* * 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. */ /** * Wrapper for Strings containing templates, allowing to add additional meta * data like timestamps. * * @author Eelco Hillenius * @author Henning P. Schmiedehausen * @version $Id: StringResource.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public final class StringResource { /** template body */ private String body; /** encoding */ private String encoding; /** last modified ts */ private long lastModified; /** * convenience constructor; sets body to 'body' and sets lastModified to now * @param body */ public StringResource(final String body, final String encoding) { setBody(body); setEncoding(encoding); } /** * Sets the template body. * @return String containing the template body. */ public String getBody() { return body; } /** * Returns the modification date of the template. * @return Modification date in milliseconds. */ public long getLastModified() { return lastModified; } /** * Sets a new value for the template body. * @param body New body value */ public void setBody(final String body) { this.body = body; this.lastModified = System.currentTimeMillis(); } /** * Changes the last modified parameter. * @param lastModified The modification time in millis. */ public void setLastModified(final long lastModified) { this.lastModified = lastModified; } /** * Returns the encoding of this String resource. * * @return The encoding of this String resource. */ public String getEncoding() { return this.encoding; } /** * Sets the encoding of this string resource. * * @param encoding The new encoding of this resource. */ public void setEncoding(final String encoding) { this.encoding = encoding; } } velocity-1.7/src/java/org/apache/velocity/runtime/resource/util/StringResourceRepository.java0000644000175000017500000000520711050665114032670 0ustar moellermoellerpackage org.apache.velocity.runtime.resource.util; /* * 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. */ /** * A StringResourceRepository functions as a central repository for Velocity templates * stored in Strings. * * @author Eelco Hillenius * @author Henning P. Schmiedehausen * @version $Id: StringResourceRepository.java 685724 2008-08-13 23:12:12Z nbubna $ * @since 1.5 */ public interface StringResourceRepository { /** * get the string resource that is stored with given key * @param name String name to retrieve from the repository. * @return A StringResource containing the template. */ StringResource getStringResource(String name); /** * add a string resource with given key. * @param name The String name to store the template under. * @param body A String containing a template. */ void putStringResource(String name, String body); /** * add a string resource with given key. * @param name The String name to store the template under. * @param body A String containing a template. * @param encoding The encoding of this string template * @since 1.6 */ void putStringResource(String name, String body, String encoding); /** * delete a string resource with given key. * @param name The string name to remove from the repository. */ void removeStringResource(String name); /** * Sets the default encoding of the repository. Encodings can also be stored per * template string. The default implementation does this correctly. * * @param encoding The encoding to use. */ void setEncoding(String encoding); /** * Returns the current encoding of this repository. * * @return The current encoding of this repository. */ String getEncoding(); } velocity-1.7/src/java/org/apache/velocity/runtime/ParserPoolImpl.java0000644000175000017500000000455211066265225025726 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.SimplePool; import org.apache.velocity.runtime.parser.CharStream; /** * This wraps the original parser SimplePool class. It also handles * instantiating ad-hoc parsers if none are available. * * @author Serge Knystautas * @version $Id: RuntimeInstance.java 384374 2006-03-08 23:19:30Z nbubna $ * @since 1.5 */ public class ParserPoolImpl implements ParserPool { SimplePool pool = null; int max = RuntimeConstants.NUMBER_OF_PARSERS; /** * Create the underlying "pool". * @param rsvc */ public void initialize(RuntimeServices rsvc) { max = rsvc.getInt(RuntimeConstants.PARSER_POOL_SIZE, RuntimeConstants.NUMBER_OF_PARSERS); pool = new SimplePool(max); for (int i = 0; i < max; i++) { pool.put(rsvc.createNewParser()); } if (rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug("Created '" + max + "' parsers."); } } /** * Call the wrapped pool. If none are available, it will create a new * temporary one. * @return A parser Object. */ public Parser get() { return (Parser) pool.get(); } /** * Call the wrapped pool. * @param parser */ public void put(Parser parser) { parser.ReInit((CharStream) null); pool.put(parser); } } velocity-1.7/src/java/org/apache/velocity/runtime/RuntimeInstance.java0000644000175000017500000016743211322703343026126 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.io.Writer; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Properties; import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.Template; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.app.event.EventHandler; import org.apache.velocity.app.event.IncludeEventHandler; import org.apache.velocity.app.event.InvalidReferenceEventHandler; import org.apache.velocity.app.event.MethodExceptionEventHandler; import org.apache.velocity.app.event.NullSetEventHandler; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; import org.apache.velocity.context.Context; import org.apache.velocity.context.InternalContextAdapterImpl; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.Scope; import org.apache.velocity.runtime.directive.StopCommand; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.LogManager; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.resource.ContentResource; import org.apache.velocity.runtime.resource.ResourceManager; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.RuntimeServicesAware; import org.apache.velocity.util.StringUtils; import org.apache.velocity.util.introspection.ChainableUberspector; import org.apache.velocity.util.introspection.Introspector; import org.apache.velocity.util.introspection.LinkingUberspector; import org.apache.velocity.util.introspection.Uberspect; import org.apache.velocity.util.introspection.UberspectLoggable; /** * This is the Runtime system for Velocity. It is the * single access point for all functionality in Velocity. * It adheres to the mediator pattern and is the only * structure that developers need to be familiar with * in order to get Velocity to perform. * * The Runtime will also cooperate with external * systems like Turbine. Runtime properties can * set and then the Runtime is initialized. * * Turbine, for example, knows where the templates * are to be loaded from, and where the Velocity * log file should be placed. * * So in the case of Velocity cooperating with Turbine * the code might look something like the following: * *
       * ri.setProperty(Runtime.FILE_RESOURCE_LOADER_PATH, templatePath);
       * ri.setProperty(Runtime.RUNTIME_LOG, pathToVelocityLog);
       * ri.init();
       * 
      * *
       * -----------------------------------------------------------------------
       * N O T E S  O N  R U N T I M E  I N I T I A L I Z A T I O N
       * -----------------------------------------------------------------------
       * init()
       *
       * If init() is called by itself the RuntimeInstance will initialize
       * with a set of default values.
       * -----------------------------------------------------------------------
       * init(String/Properties)
       *
       * In this case the default velocity properties are layed down
       * first to provide a solid base, then any properties provided
       * in the given properties object will override the corresponding
       * default property.
       * -----------------------------------------------------------------------
       * 
      * * @author Jason van Zyl * @author Jeff Bowden * @author Geir Magusson Jr. * @version $Id: RuntimeInstance.java 898050 2010-01-11 20:15:31Z nbubna $ */ public class RuntimeInstance implements RuntimeConstants, RuntimeServices { /** * VelocimacroFactory object to manage VMs */ private VelocimacroFactory vmFactory = null; /** * The Runtime logger. We start with an instance of * a 'primordial logger', which just collects log messages * then, when the log system is initialized, all the * messages get dumpted out of the primordial one into the real one. */ private Log log = new Log(); /** * The Runtime parser pool */ private ParserPool parserPool; /** * Indicate whether the Runtime is in the midst of initialization. */ private boolean initializing = false; /** * Indicate whether the Runtime has been fully initialized. */ private volatile boolean initialized = false; /** * These are the properties that are laid down over top * of the default properties when requested. */ private ExtendedProperties overridingProperties = null; /** * This is a hashtable of initialized directives. * The directives that populate this hashtable are * taken from the RUNTIME_DEFAULT_DIRECTIVES * property file. */ private Map runtimeDirectives = new Hashtable(); /** * Copy of the actual runtimeDirectives that is shared between * parsers. Whenever directives are updated, the synchronized * runtimeDirectives is first updated and then an unsynchronized * copy of it is passed to parsers. */ private Map runtimeDirectivesShared; /** * Object that houses the configuration options for * the velocity runtime. The ExtendedProperties object allows * the convenient retrieval of a subset of properties. * For example all the properties for a resource loader * can be retrieved from the main ExtendedProperties object * using something like the following: * * ExtendedProperties loaderConfiguration = * configuration.subset(loaderID); * * And a configuration is a lot more convenient to deal * with then conventional properties objects, or Maps. */ private ExtendedProperties configuration = new ExtendedProperties(); private ResourceManager resourceManager = null; /** * This stores the engine-wide set of event handlers. Event handlers for * each specific merge are stored in the context. */ private EventCartridge eventCartridge = null; /* * Each runtime instance has it's own introspector * to ensure that each instance is completely separate. */ private Introspector introspector = null; /* * Settings for provision of root scope for evaluate(...) calls. */ private String evaluateScopeName = "evaluate"; private boolean provideEvaluateScope = false; /* * Opaque reference to something specificed by the * application for use in application supplied/specified * pluggable components */ private Map applicationAttributes = null; private Uberspect uberSpect; private String encoding; /** * Creates a new RuntimeInstance object. */ public RuntimeInstance() { /* * create a VM factory, introspector, and application attributes */ vmFactory = new VelocimacroFactory( this ); /* * make a new introspector and initialize it */ introspector = new Introspector(getLog()); /* * and a store for the application attributes */ applicationAttributes = new HashMap(); } /** * This is the primary initialization method in the Velocity * Runtime. The systems that are setup/initialized here are * as follows: * *
        *
      • Logging System
      • *
      • ResourceManager
      • *
      • EventHandler
      • *
      • Parser Pool
      • *
      • Global Cache
      • *
      • Static Content Include System
      • *
      • Velocimacro System
      • *
      */ public synchronized void init() { if (!initialized && !initializing) { log.debug("Initializing Velocity, Calling init()..."); initializing = true; log.trace("*******************************************************************"); log.debug("Starting Apache Velocity v@build.version@ (compiled: @build.time@)"); log.trace("RuntimeInstance initializing."); initializeProperties(); initializeLog(); initializeResourceManager(); initializeDirectives(); initializeEventHandlers(); initializeParserPool(); initializeIntrospection(); initializeEvaluateScopeSettings(); /* * initialize the VM Factory. It will use the properties * accessable from Runtime, so keep this here at the end. */ vmFactory.initVelocimacro(); log.trace("RuntimeInstance successfully initialized."); initialized = true; initializing = false; } } /** * Returns true if the RuntimeInstance has been successfully initialized. * @return True if the RuntimeInstance has been successfully initialized. * @since 1.5 */ public boolean isInitialized() { return initialized; } /** * Init or die! (with some log help, of course) */ private void requireInitialization() { if (!initialized) { try { init(); } catch (Exception e) { getLog().error("Could not auto-initialize Velocity", e); throw new RuntimeException("Velocity could not be initialized!", e); } } } /** * Gets the classname for the Uberspect introspection package and * instantiates an instance. */ private void initializeIntrospection() { String[] uberspectors = configuration.getStringArray(RuntimeConstants.UBERSPECT_CLASSNAME); for (int i=0; i 0) { /* * if something was specified, then make one. * if that isn't a ResourceManager, consider * this a huge error and throw */ Object o = null; try { o = ClassUtils.getNewInstance( rm ); } catch (ClassNotFoundException cnfe ) { String err = "The specified class for ResourceManager (" + rm + ") does not exist or is not accessible to the current classloader."; log.error(err); throw new VelocityException(err, cnfe); } catch (InstantiationException ie) { throw new VelocityException("Could not instantiate class '" + rm + "'", ie); } catch (IllegalAccessException ae) { throw new VelocityException("Cannot access class '" + rm + "'", ae); } if (!(o instanceof ResourceManager)) { String err = "The specified class for ResourceManager (" + rm + ") does not implement " + ResourceManager.class.getName() + "; Velocity is not initialized correctly."; log.error(err); throw new VelocityException(err); } resourceManager = (ResourceManager) o; resourceManager.initialize(this); } else { /* * someone screwed up. Lets not fool around... */ String err = "It appears that no class was specified as the" + " ResourceManager. Please ensure that all configuration" + " information is correct."; log.error(err); throw new VelocityException( err ); } } private void initializeEventHandlers() { eventCartridge = new EventCartridge(); /** * For each type of event handler, get the class name, instantiate it, and store it. */ String[] referenceinsertion = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION); if ( referenceinsertion != null ) { for ( int i=0; i < referenceinsertion.length; i++ ) { EventHandler ev = initializeSpecificEventHandler(referenceinsertion[i],RuntimeConstants.EVENTHANDLER_REFERENCEINSERTION,ReferenceInsertionEventHandler.class); if (ev != null) eventCartridge.addReferenceInsertionEventHandler((ReferenceInsertionEventHandler) ev); } } String[] nullset = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_NULLSET); if ( nullset != null ) { for ( int i=0; i < nullset.length; i++ ) { EventHandler ev = initializeSpecificEventHandler(nullset[i],RuntimeConstants.EVENTHANDLER_NULLSET,NullSetEventHandler.class); if (ev != null) eventCartridge.addNullSetEventHandler((NullSetEventHandler) ev); } } String[] methodexception = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_METHODEXCEPTION); if ( methodexception != null ) { for ( int i=0; i < methodexception.length; i++ ) { EventHandler ev = initializeSpecificEventHandler(methodexception[i],RuntimeConstants.EVENTHANDLER_METHODEXCEPTION,MethodExceptionEventHandler.class); if (ev != null) eventCartridge.addMethodExceptionHandler((MethodExceptionEventHandler) ev); } } String[] includeHandler = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_INCLUDE); if ( includeHandler != null ) { for ( int i=0; i < includeHandler.length; i++ ) { EventHandler ev = initializeSpecificEventHandler(includeHandler[i],RuntimeConstants.EVENTHANDLER_INCLUDE,IncludeEventHandler.class); if (ev != null) eventCartridge.addIncludeEventHandler((IncludeEventHandler) ev); } } String[] invalidReferenceSet = configuration.getStringArray(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES); if ( invalidReferenceSet != null ) { for ( int i=0; i < invalidReferenceSet.length; i++ ) { EventHandler ev = initializeSpecificEventHandler(invalidReferenceSet[i],RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES,InvalidReferenceEventHandler.class); if (ev != null) { eventCartridge.addInvalidReferenceEventHandler((InvalidReferenceEventHandler) ev); } } } } private EventHandler initializeSpecificEventHandler(String classname, String paramName, Class EventHandlerInterface) { if ( classname != null && classname.length() > 0) { Object o = null; try { o = ClassUtils.getNewInstance(classname); } catch (ClassNotFoundException cnfe ) { String err = "The specified class for " + paramName + " (" + classname + ") does not exist or is not accessible to the current classloader."; log.error(err); throw new VelocityException(err, cnfe); } catch (InstantiationException ie) { throw new VelocityException("Could not instantiate class '" + classname + "'", ie); } catch (IllegalAccessException ae) { throw new VelocityException("Cannot access class '" + classname + "'", ae); } if (!EventHandlerInterface.isAssignableFrom(EventHandlerInterface)) { String err = "The specified class for " + paramName + " (" + classname + ") does not implement " + EventHandlerInterface.getName() + "; Velocity is not initialized correctly."; log.error(err); throw new VelocityException(err); } EventHandler ev = (EventHandler) o; if ( ev instanceof RuntimeServicesAware ) ((RuntimeServicesAware) ev).setRuntimeServices(this); return ev; } else return null; } /** * Initialize the Velocity logging system. */ private void initializeLog() { // since the Log we started with was just placeholding, // let's update it with the real LogChute settings. try { LogManager.updateLog(this.log, this); } catch (Exception e) { throw new VelocityException("Error initializing log: " + e.getMessage(), e); } } /** * This methods initializes all the directives * that are used by the Velocity Runtime. The * directives to be initialized are listed in * the RUNTIME_DEFAULT_DIRECTIVES properties * file. */ private void initializeDirectives() { Properties directiveProperties = new Properties(); /* * Grab the properties file with the list of directives * that we should initialize. */ InputStream inputStream = null; try { inputStream = getClass().getResourceAsStream('/' + DEFAULT_RUNTIME_DIRECTIVES); if (inputStream == null) { throw new VelocityException("Error loading directive.properties! " + "Something is very wrong if these properties " + "aren't being located. Either your Velocity " + "distribution is incomplete or your Velocity " + "jar file is corrupted!"); } directiveProperties.load(inputStream); } catch (IOException ioe) { String msg = "Error while loading directive properties!"; log.error(msg, ioe); throw new RuntimeException(msg, ioe); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException ioe) { String msg = "Cannot close directive properties!"; log.error(msg, ioe); throw new RuntimeException(msg, ioe); } } /* * Grab all the values of the properties. These * are all class names for example: * * org.apache.velocity.runtime.directive.Foreach */ Enumeration directiveClasses = directiveProperties.elements(); while (directiveClasses.hasMoreElements()) { String directiveClass = (String) directiveClasses.nextElement(); loadDirective(directiveClass); log.debug("Loaded System Directive: " + directiveClass); } /* * now the user's directives */ String[] userdirective = configuration.getStringArray("userdirective"); for( int i = 0; i < userdirective.length; i++) { loadDirective(userdirective[i]); if (log.isDebugEnabled()) { log.debug("Loaded User Directive: " + userdirective[i]); } } } /** * Programatically add a directive. * @param directive */ public synchronized void addDirective(Directive directive) { runtimeDirectives.put(directive.getName(), directive); updateSharedDirectivesMap(); } /** * Retrieve a previously instantiated directive. * @param name name of the directive * @return the {@link Directive} for that name */ public Directive getDirective(String name) { return (Directive) runtimeDirectivesShared.get(name); } /** * Remove a directive. * @param name name of the directive. */ public synchronized void removeDirective(String name) { runtimeDirectives.remove(name); updateSharedDirectivesMap(); } /** * Makes an unsynchronized copy of the directives map * that is used for Directive lookups by all parsers. * * This follows Copy-on-Write pattern. The cost of creating * a new map is acceptable since directives are typically * set and modified only during Velocity setup phase. */ private void updateSharedDirectivesMap() { Map tmp = new HashMap(runtimeDirectives); runtimeDirectivesShared = tmp; } /** * instantiates and loads the directive with some basic checks * * @param directiveClass classname of directive to load */ public void loadDirective(String directiveClass) { try { Object o = ClassUtils.getNewInstance( directiveClass ); if (o instanceof Directive) { Directive directive = (Directive) o; addDirective(directive); } else { String msg = directiveClass + " does not implement " + Directive.class.getName() + "; it cannot be loaded."; log.error(msg); throw new VelocityException(msg); } } // The ugly threesome: ClassNotFoundException, // IllegalAccessException, InstantiationException. // Ignore Findbugs complaint for now. catch (Exception e) { String msg = "Failed to load Directive: " + directiveClass; log.error(msg, e); throw new VelocityException(msg, e); } } /** * Initializes the Velocity parser pool. */ private void initializeParserPool() { /* * Which parser pool? */ String pp = getString(RuntimeConstants.PARSER_POOL_CLASS); if (pp != null && pp.length() > 0) { /* * if something was specified, then make one. * if that isn't a ParserPool, consider * this a huge error and throw */ Object o = null; try { o = ClassUtils.getNewInstance( pp ); } catch (ClassNotFoundException cnfe ) { String err = "The specified class for ParserPool (" + pp + ") does not exist (or is not accessible to the current classloader."; log.error(err); throw new VelocityException(err, cnfe); } catch (InstantiationException ie) { throw new VelocityException("Could not instantiate class '" + pp + "'", ie); } catch (IllegalAccessException ae) { throw new VelocityException("Cannot access class '" + pp + "'", ae); } if (!(o instanceof ParserPool)) { String err = "The specified class for ParserPool (" + pp + ") does not implement " + ParserPool.class + " Velocity not initialized correctly."; log.error(err); throw new VelocityException(err); } parserPool = (ParserPool) o; parserPool.initialize(this); } else { /* * someone screwed up. Lets not fool around... */ String err = "It appears that no class was specified as the" + " ParserPool. Please ensure that all configuration" + " information is correct."; log.error(err); throw new VelocityException( err ); } } /** * Returns a JavaCC generated Parser. * * @return Parser javacc generated parser */ public Parser createNewParser() { requireInitialization(); Parser parser = new Parser(this); return parser; } /** * Parse the input and return the root of * AST node structure. *

      * In the event that it runs out of parsers in the * pool, it will create and let them be GC'd * dynamically, logging that it has to do that. This * is considered an exceptional condition. It is * expected that the user will set the * PARSER_POOL_SIZE property appropriately for their * application. We will revisit this. * * @param string String to be parsed * @param templateName name of the template being parsed * @return A root node representing the template as an AST tree. * @throws ParseException When the string could not be parsed as a template. * @since 1.6 */ public SimpleNode parse(String string, String templateName) throws ParseException { return parse(new StringReader(string), templateName); } /** * Parse the input and return the root of * AST node structure. *

      * In the event that it runs out of parsers in the * pool, it will create and let them be GC'd * dynamically, logging that it has to do that. This * is considered an exceptional condition. It is * expected that the user will set the * PARSER_POOL_SIZE property appropriately for their * application. We will revisit this. * * @param reader Reader retrieved by a resource loader * @param templateName name of the template being parsed * @return A root node representing the template as an AST tree. * @throws ParseException When the template could not be parsed. */ public SimpleNode parse(Reader reader, String templateName) throws ParseException { /* * do it and dump the VM namespace for this template */ return parse(reader, templateName, true); } /** * Parse the input and return the root of the AST node structure. * * @param reader Reader retrieved by a resource loader * @param templateName name of the template being parsed * @param dumpNamespace flag to dump the Velocimacro namespace for this template * @return A root node representing the template as an AST tree. * @throws ParseException When the template could not be parsed. */ public SimpleNode parse(Reader reader, String templateName, boolean dumpNamespace) throws ParseException { requireInitialization(); Parser parser = (Parser) parserPool.get(); boolean keepParser = true; if (parser == null) { /* * if we couldn't get a parser from the pool make one and log it. */ if (log.isInfoEnabled()) { log.info("Runtime : ran out of parsers. Creating a new one. " + " Please increment the parser.pool.size property." + " The current value is too small."); } parser = createNewParser(); keepParser = false; } try { /* * dump namespace if we are told to. Generally, you want to * do this - you don't in special circumstances, such as * when a VM is getting init()-ed & parsed */ if (dumpNamespace) { dumpVMNamespace(templateName); } return parser.parse(reader, templateName); } finally { if (keepParser) { parserPool.put(parser); } } } private void initializeEvaluateScopeSettings() { String property = evaluateScopeName+'.'+PROVIDE_SCOPE_CONTROL; provideEvaluateScope = getBoolean(property, provideEvaluateScope); } /** * Renders the input string using the context into the output writer. * To be used when a template is dynamically constructed, or want to use * Velocity as a token replacer. * * @param context context to use in rendering input string * @param out Writer in which to render the output * @param logTag string to be used as the template name for log * messages in case of error * @param instring input string containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity 1.6 */ public boolean evaluate(Context context, Writer out, String logTag, String instring) { return evaluate(context, out, logTag, new StringReader(instring)); } /** * Renders the input reader using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param reader Reader containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity 1.6 */ public boolean evaluate(Context context, Writer writer, String logTag, Reader reader) { if (logTag == null) { throw new NullPointerException("logTag (i.e. template name) cannot be null, you must provide an identifier for the content being evaluated"); } SimpleNode nodeTree = null; try { nodeTree = parse(reader, logTag); } catch (ParseException pex) { throw new ParseErrorException(pex, null); } catch (TemplateInitException pex) { throw new ParseErrorException(pex, null); } if (nodeTree == null) { return false; } else { return render(context, writer, logTag, nodeTree); } } /** * Initializes and renders the AST {@link SimpleNode} using the context * into the output writer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param nodeTree SimpleNode which is the root of the AST to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log for errors * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity 1.6 */ public boolean render(Context context, Writer writer, String logTag, SimpleNode nodeTree) { /* * we want to init then render */ InternalContextAdapterImpl ica = new InternalContextAdapterImpl(context); ica.pushCurrentTemplateName(logTag); try { try { nodeTree.init(ica, this); } catch (TemplateInitException pex) { throw new ParseErrorException(pex, null); } /** * pass through application level runtime exceptions */ catch(RuntimeException e) { throw e; } catch(Exception e) { String msg = "RuntimeInstance.render(): init exception for tag = "+logTag; getLog().error(msg, e); throw new VelocityException(msg, e); } try { if (provideEvaluateScope) { Object previous = ica.get(evaluateScopeName); context.put(evaluateScopeName, new Scope(this, previous)); } nodeTree.render(ica, writer); } catch (StopCommand stop) { if (!stop.isFor(this)) { throw stop; } else if (getLog().isDebugEnabled()) { getLog().debug(stop.getMessage()); } } catch (IOException e) { throw new VelocityException("IO Error in writer: " + e.getMessage(), e); } } finally { ica.popCurrentTemplateName(); if (provideEvaluateScope) { Object obj = ica.get(evaluateScopeName); if (obj instanceof Scope) { Scope scope = (Scope)obj; if (scope.getParent() != null) { ica.put(evaluateScopeName, scope.getParent()); } else if (scope.getReplaced() != null) { ica.put(evaluateScopeName, scope.getReplaced()); } else { ica.remove(evaluateScopeName); } } } } return true; } /** * Invokes a currently registered Velocimacro with the params provided * and places the rendered stream into the writer. *
      * Note : currently only accepts args to the VM if they are in the context. * * @param vmName name of Velocimacro to call * @param logTag string to be used for template name in case of error. if null, * the vmName will be used * @param params keys for args used to invoke Velocimacro, in java format * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar") * @param context Context object containing data/objects used for rendering. * @param writer Writer for output stream * @return true if Velocimacro exists and successfully invoked, false otherwise. * @since 1.6 */ public boolean invokeVelocimacro(final String vmName, String logTag, String[] params, final Context context, final Writer writer) { /* check necessary parameters */ if (vmName == null || context == null || writer == null) { String msg = "RuntimeInstance.invokeVelocimacro() : invalid call : vmName, context, and writer must not be null"; getLog().error(msg); throw new NullPointerException(msg); } /* handle easily corrected parameters */ if (logTag == null) { logTag = vmName; } if (params == null) { params = new String[0]; } /* does the VM exist? */ if (!isVelocimacro(vmName, logTag)) { String msg = "RuntimeInstance.invokeVelocimacro() : VM '" + vmName + "' is not registered."; getLog().error(msg); throw new VelocityException(msg); } /* now just create the VM call, and use evaluate */ StrBuilder template = new StrBuilder("#"); template.append(vmName); template.append("("); for( int i = 0; i < params.length; i++) { template.append(" $"); template.append(params[i]); } template.append(" )"); return evaluate(context, writer, logTag, template.toString()); } /** * Retrieves and caches the configured default encoding * for better performance. (VELOCITY-606) */ private String getDefaultEncoding() { if (encoding == null) { encoding = getString(INPUT_ENCODING, ENCODING_DEFAULT); } return encoding; } /** * Returns a Template from the resource manager. * This method assumes that the character encoding of the * template is set by the input.encoding * property. The default is "ISO-8859-1" * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException { return getTemplate(name, getDefaultEncoding()); } /** * Returns a Template from the resource manager * * @param name The name of the desired template. * @param encoding Character encoding of the template * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException { requireInitialization(); return (Template) resourceManager.getResource(name, ResourceManager.RESOURCE_TEMPLATE, encoding); } /** * Returns a static content resource from the * resource manager. Uses the current value * if INPUT_ENCODING as the character encoding. * * @param name Name of content resource to get * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException When the template could not be parsed. */ public ContentResource getContent(String name) throws ResourceNotFoundException, ParseErrorException { /* * the encoding is irrelvant as we don't do any converstion * the bytestream should be dumped to the output stream */ return getContent(name, getDefaultEncoding()); } /** * Returns a static content resource from the * resource manager. * * @param name Name of content resource to get * @param encoding Character encoding to use * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException When the template could not be parsed. */ public ContentResource getContent(String name, String encoding) throws ResourceNotFoundException, ParseErrorException { requireInitialization(); return (ContentResource) resourceManager.getResource(name, ResourceManager.RESOURCE_CONTENT, encoding); } /** * Determines if a template exists and returns name of the loader that * provides it. This is a slightly less hokey way to support * the Velocity.resourceExists() utility method, which was broken * when per-template encoding was introduced. We can revisit this. * * @param resourceName Name of template or content resource * @return class name of loader than can provide it */ public String getLoaderNameForResource(String resourceName) { requireInitialization(); return resourceManager.getLoaderNameForResource(resourceName); } /** * Returns a convenient Log instance that wraps the current LogChute. * Use this to log error messages. It has the usual methods. * * @return A convenience Log instance that wraps the current LogChute. * @since 1.5 */ public Log getLog() { return log; } /** * @deprecated Use getLog() and call warn() on it. * @see Log#warn(Object) * @param message The message to log. */ public void warn(Object message) { getLog().warn(message); } /** * @deprecated Use getLog() and call info() on it. * @see Log#info(Object) * @param message The message to log. */ public void info(Object message) { getLog().info(message); } /** * @deprecated Use getLog() and call error() on it. * @see Log#error(Object) * @param message The message to log. */ public void error(Object message) { getLog().error(message); } /** * @deprecated Use getLog() and call debug() on it. * @see Log#debug(Object) * @param message The message to log. */ public void debug(Object message) { getLog().debug(message); } /** * String property accessor method with default to hide the * configuration implementation. * * @param key property key * @param defaultValue default value to return if key not * found in resource manager. * @return value of key or default */ public String getString( String key, String defaultValue) { return configuration.getString(key, defaultValue); } /** * Returns the appropriate VelocimacroProxy object if vmName * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName Name of the template that contains the velocimacro. * @return The requested VelocimacroProxy. * @since 1.6 */ public Directive getVelocimacro(String vmName, String templateName) { return vmFactory.getVelocimacro( vmName, templateName ); } /** * Returns the appropriate VelocimacroProxy object if vmName * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName Name of the namespace. * @param renderingTemplate Name of the template we are currently rendering. This * information is needed when VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL setting is true * and template contains a macro with the same name as the global macro library. * * @since Velocity 1.6 * * @return VelocimacroProxy */ public Directive getVelocimacro(String vmName, String templateName, String renderingTemplate) { return vmFactory.getVelocimacro( vmName, templateName, renderingTemplate ); } /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of velocimacro * @param macro String form of macro body * @param argArray Array of strings, containing the * #macro() arguments. the 0th is the name. * @param sourceTemplate Name of the template that contains the velocimacro. * * @deprecated Use addVelocimacro(String, Node, String[], String) instead * * @return True if added, false if rejected for some * reason (either parameters or permission settings) */ public boolean addVelocimacro( String name, String macro, String argArray[], String sourceTemplate ) { return vmFactory.addVelocimacro(name.intern(), macro, argArray, sourceTemplate); } /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * Called by org.apache.velocity.runtime.directive.processAndRegister * * @param name Name of velocimacro * @param macro root AST node of the parsed macro * @param argArray Array of strings, containing the * #macro() arguments. the 0th is the name. * @param sourceTemplate * * @since Velocity 1.6 * * @return boolean True if added, false if rejected for some * reason (either parameters or permission settings) */ public boolean addVelocimacro( String name, Node macro, String argArray[], String sourceTemplate ) { return vmFactory.addVelocimacro(name.intern(), macro, argArray, sourceTemplate); } /** * Checks to see if a VM exists * * @param vmName Name of the Velocimacro. * @param templateName Template on which to look for the Macro. * @return True if VM by that name exists, false if not */ public boolean isVelocimacro( String vmName, String templateName ) { return vmFactory.isVelocimacro(vmName.intern(), templateName); } /** * tells the vmFactory to dump the specified namespace. This is to support * clearing the VM list when in inline-VM-local-scope mode * @param namespace Namespace to dump. * @return True if namespace was dumped successfully. */ public boolean dumpVMNamespace(String namespace) { return vmFactory.dumpVMNamespace( namespace ); } /* -------------------------------------------------------------------- * R U N T I M E A C C E S S O R M E T H O D S * -------------------------------------------------------------------- * These are the getXXX() methods that are a simple wrapper * around the configuration object. This is an attempt * to make a the Velocity Runtime the single access point * for all things Velocity, and allow the Runtime to * adhere as closely as possible the the Mediator pattern * which is the ultimate goal. * -------------------------------------------------------------------- */ /** * String property accessor method to hide the configuration implementation * @param key property key * @return value of key or null */ public String getString(String key) { return StringUtils.nullTrim(configuration.getString(key)); } /** * Int property accessor method to hide the configuration implementation. * * @param key Property key * @return value */ public int getInt(String key) { return configuration.getInt(key); } /** * Int property accessor method to hide the configuration implementation. * * @param key property key * @param defaultValue The default value. * @return value */ public int getInt(String key, int defaultValue) { return configuration.getInt(key, defaultValue); } /** * Boolean property accessor method to hide the configuration implementation. * * @param key property key * @param def The default value if property not found. * @return value of key or default value */ public boolean getBoolean(String key, boolean def) { return configuration.getBoolean(key, def); } /** * Return the velocity runtime configuration object. * * @return Configuration object which houses the Velocity runtime * properties. */ public ExtendedProperties getConfiguration() { return configuration; } /** * Return the Introspector for this instance * @return The Introspector for this instance */ public Introspector getIntrospector() { return introspector; } /** * Returns the event handlers for the application. * @return The event handlers for the application. * @since 1.5 */ public EventCartridge getApplicationEventCartridge() { return eventCartridge; } /** * Gets the application attribute for the given key * * @param key * @return The application attribute for the given key. */ public Object getApplicationAttribute(Object key) { return applicationAttributes.get(key); } /** * Sets the application attribute for the given key * * @param key * @param o The new application attribute. * @return The old value of this attribute or null if it hasn't been set before. */ public Object setApplicationAttribute(Object key, Object o) { return applicationAttributes.put(key, o); } /** * Returns the Uberspect object for this Instance. * * @return The Uberspect object for this Instance. */ public Uberspect getUberspect() { return uberSpect; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/0000755000175000017500000000000011675166251023446 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/parser/Token.java0000644000175000017500000000517110330726455025370 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ package org.apache.velocity.runtime.parser; /** * Describes the input token stream. */ public class Token { /** * An integer that describes the kind of this token. This numbering * system is determined by JavaCCParser, and a table of these numbers is * stored in the file ...Constants.java. */ public int kind; /** * beginLine and beginColumn describe the position of the first character * of this token; endLine and endColumn describe the position of the * last character of this token. */ public int beginLine, beginColumn, endLine, endColumn; /** * The string image of the token. */ public String image; /** * A reference to the next regular (non-special) token from the input * stream. If this is the last token from the input stream, or if the * token manager has not read tokens beyond this one, this field is * set to null. This is true only if this token is also a regular * token. Otherwise, see below for a description of the contents of * this field. */ public Token next; /** * This field is used to access special tokens that occur prior to this * token, but after the immediately preceding regular (non-special) token. * If there are no such special tokens, this field is set to null. * When there are more than one such special token, this field refers * to the last of these special tokens, which in turn refers to the next * previous special token through its specialToken field, and so on * until the first special token (whose specialToken field is null). * The next fields of special tokens refer to other special tokens that * immediately follow it (without an intervening regular token). If there * is no such token, this field is null. */ public Token specialToken; /** * Returns the image. */ public String toString() { return image; } /** * Returns a new Token object, by default. However, if you want, you * can create and return subclass objects based on the value of ofKind. * Simply add the cases to the switch for all those special cases. * For example, if you have a subclass of Token called IDToken that * you want to create if ofKind is ID, simlpy add something like : * * case MyParserConstants.ID : return new IDToken(); * * to the following switch statement. Then you can cast matchedToken * variable to the appropriate type and use it in your lexical actions. */ public static final Token newToken(int ofKind) { switch(ofKind) { default : return new Token(); } } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/TokenMgrError.java0000644000175000017500000001017710504055136027044 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ package org.apache.velocity.runtime.parser; public class TokenMgrError extends Error { /* * Ordinals for various reasons why an Error of this type can be thrown. */ /** * Lexical error occured. */ static final int LEXICAL_ERROR = 0; /** * An attempt wass made to create a second instance of a static token manager. */ static final int STATIC_LEXER_ERROR = 1; /** * Tried to change to an invalid lexical state. */ static final int INVALID_LEXICAL_STATE = 2; /** * Detected (and bailed out of) an infinite loop in the token manager. */ static final int LOOP_DETECTED = 3; /** * Indicates the reason why the exception is thrown. It will have * one of the above 4 values. */ int errorCode; /** * Replaces unprintable characters by their espaced (or unicode escaped) * equivalents in the given string */ protected static final String addEscapes(String str) { StringBuffer retval = new StringBuffer(); char ch; for (int i = 0; i < str.length(); i++) { switch (str.charAt(i)) { case 0 : continue; case '\b': retval.append("\\b"); continue; case '\t': retval.append("\\t"); continue; case '\n': retval.append("\\n"); continue; case '\f': retval.append("\\f"); continue; case '\r': retval.append("\\r"); continue; case '\"': retval.append("\\\""); continue; case '\'': retval.append("\\\'"); continue; case '\\': retval.append("\\\\"); continue; default: if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { String s = "0000" + Integer.toString(ch, 16); retval.append("\\u" + s.substring(s.length() - 4, s.length())); } else { retval.append(ch); } continue; } } return retval.toString(); } /** * Returns a detailed message for the Error when it is thrown by the * token manager to indicate a lexical error. * Parameters : * EOFSeen : indicates if EOF caused the lexicl error * curLexState : lexical state in which this error occured * errorLine : line number when the error occured * errorColumn : column number when the error occured * errorAfter : prefix that was seen before this error occured * curchar : the offending character * Note: You can customize the lexical error message by modifying this method. */ protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { return("Lexical error at line " + errorLine + ", column " + errorColumn + ". Encountered: " + (EOFSeen ? " " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + "after : \"" + addEscapes(errorAfter) + "\""); } /** * You can also modify the body of this method to customize your error messages. * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not * of end-users concern, so you can return something like : * * "Internal Error : Please file a bug report .... " * * from this method for such cases in the release version of your parser. */ public String getMessage() { return super.getMessage(); } /* * Constructors of various flavors follow. */ public TokenMgrError() { } public TokenMgrError(String message, int reason) { super(message); errorCode = reason; } public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/JJTParserState.java0000644000175000017500000000653211066507011027107 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. JJTParserState.java Version 4.1 */ package org.apache.velocity.runtime.parser; import org.apache.velocity.runtime.parser.node.Node; public class JJTParserState { private java.util.List nodes; private java.util.List marks; private int sp; // number of nodes on stack private int mk; // current mark private boolean node_created; public JJTParserState() { nodes = new java.util.ArrayList(); marks = new java.util.ArrayList(); sp = 0; mk = 0; } /* Determines whether the current node was actually closed and pushed. This should only be called in the final user action of a node scope. */ public boolean nodeCreated() { return node_created; } /* Call this to reinitialize the node stack. It is called automatically by the parser's ReInit() method. */ public void reset() { nodes.clear(); marks.clear(); sp = 0; mk = 0; } /* Returns the root node of the AST. It only makes sense to call this after a successful parse. */ public Node rootNode() { return (Node)nodes.get(0); } /* Pushes a node on to the stack. */ public void pushNode(Node n) { nodes.add(n); ++sp; } /* Returns the node on the top of the stack, and remove it from the stack. */ public Node popNode() { if (--sp < mk) { mk = ((Integer)marks.remove(marks.size()-1)).intValue(); } return (Node)nodes.remove(nodes.size()-1); } /* Returns the node currently on the top of the stack. */ public Node peekNode() { return (Node)nodes.get(nodes.size()-1); } /* Returns the number of children on the stack in the current node scope. */ public int nodeArity() { return sp - mk; } public void clearNodeScope(Node n) { while (sp > mk) { popNode(); } mk = ((Integer)marks.remove(marks.size()-1)).intValue(); } public void openNodeScope(Node n) { marks.add(new Integer(mk)); mk = sp; n.jjtOpen(); } /* A definite node is constructed from a specified number of children. That number of nodes are popped from the stack and made the children of the definite node. Then the definite node is pushed on to the stack. */ public void closeNodeScope(Node n, int num) { mk = ((Integer)marks.remove(marks.size()-1)).intValue(); while (num-- > 0) { Node c = popNode(); c.jjtSetParent(n); n.jjtAddChild(c, num); } n.jjtClose(); pushNode(n); node_created = true; } /* A conditional node is constructed if its condition is true. All the nodes that have been pushed since the node was opened are made children of the conditional node, which is then pushed on to the stack. If the condition is false the node is not constructed and they are left on the stack. */ public void closeNodeScope(Node n, boolean condition) { if (condition) { int a = nodeArity(); mk = ((Integer)marks.remove(marks.size()-1)).intValue(); while (a-- > 0) { Node c = popNode(); c.jjtSetParent(n); n.jjtAddChild(c, a); } n.jjtClose(); pushNode(n); node_created = true; } else { mk = ((Integer)marks.remove(marks.size()-1)).intValue(); node_created = false; } } } /* JavaCC - OriginalChecksum=8480fe4a1d30863ae6ba57f195d12191 (do not edit this line) */ velocity-1.7/src/java/org/apache/velocity/runtime/parser/TemplateParseException.java0000644000175000017500000001671711073715731030745 0ustar moellermoellerpackage org.apache.velocity.runtime.parser; /* * 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. */ import org.apache.velocity.exception.ExtendedParseException; import org.apache.velocity.runtime.log.Log; /** * This is an extension of the ParseException, which also takes a * template name. * * @see org.apache.velocity.runtime.parser.ParseException * * @author Henning P. Schmiedehausen * @version $Id: TemplateParseException.java 703544 2008-10-10 18:15:53Z nbubna $ * @since 1.5 */ public class TemplateParseException extends ParseException implements ExtendedParseException { private static final long serialVersionUID = -3146323135623083918L; /** * This is the name of the template which contains the parsing error, or * null if not defined. */ private final String templateName; /** * This constructor is used to add a template name * to info cribbed from a ParseException generated in the parser. * @param currentTokenVal * @param expectedTokenSequencesVal * @param tokenImageVal * @param templateNameVal */ public TemplateParseException(Token currentTokenVal, int [][] expectedTokenSequencesVal, String [] tokenImageVal, String templateNameVal) { super(currentTokenVal, expectedTokenSequencesVal, tokenImageVal); this.templateName = templateNameVal; } /** * This constructor is used by the method "generateParseException" * in the generated parser. Calling this constructor generates * a new object of this type with the fields "currentToken", * "expectedTokenSequences", and "tokenImage" set. The boolean * flag "specialConstructor" is also set to true to indicate that * this constructor was used to create this object. * This constructor calls its super class with the empty string * to force the "toString" method of parent class "Throwable" to * print the error message in the form: * ParseException: * @param currentTokenVal * @param expectedTokenSequencesVal * @param tokenImageVal */ public TemplateParseException(Token currentTokenVal, int [][] expectedTokenSequencesVal, String [] tokenImageVal) { super(currentTokenVal, expectedTokenSequencesVal, tokenImageVal); templateName = "*unset*"; } /** * The following constructors are for use by you for whatever * purpose you can think of. Constructing the exception in this * manner makes the exception behave in the normal way - i.e., as * documented in the class "Throwable". The fields "errorToken", * "expectedTokenSequences", and "tokenImage" do not contain * relevant information. The JavaCC generated code does not use * these constructors. */ public TemplateParseException() { super(); templateName = "*unset*"; } /** * Creates a new TemplateParseException object. * * @param message TODO: DOCUMENT ME! */ public TemplateParseException(String message) { super(message); templateName = "*unset*"; } /** * returns the Template name where this exception occured. * @return The Template name where this exception occured. */ public String getTemplateName() { return templateName; } /** * returns the line number where this exception occured. * @return The line number where this exception occured. */ public int getLineNumber() { if ((currentToken != null) && (currentToken.next != null)) { return currentToken.next.beginLine; } else { return -1; } } /** * returns the column number where this exception occured. * @return The column number where this exception occured. */ public int getColumnNumber() { if ((currentToken != null) && (currentToken.next != null)) { return currentToken.next.beginColumn; } else { return -1; } } /** * This method has the standard behavior when this object has been * created using the standard constructors. Otherwise, it uses * "currentToken" and "expectedTokenSequences" to generate a parse * error message and returns it. If this object has been created * due to a parse error, and you do not catch it (it gets thrown * from the parser), then this method is called during the printing * of the final stack trace, and hence the correct error message * gets displayed. * @return The error message. */ public String getMessage() { if (!specialConstructor) { StringBuffer sb = new StringBuffer(super.getMessage()); appendTemplateInfo(sb); return sb.toString(); } int maxSize = 0; StringBuffer expected = new StringBuffer(); for (int i = 0; i < expectedTokenSequences.length; i++) { if (maxSize < expectedTokenSequences[i].length) { maxSize = expectedTokenSequences[i].length; } for (int j = 0; j < expectedTokenSequences[i].length; j++) { expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" "); } if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { expected.append("..."); } expected.append(eol).append(" "); } StringBuffer retval = new StringBuffer("Encountered \""); Token tok = currentToken.next; for (int i = 0; i < maxSize; i++) { if (i != 0) { retval.append(" "); } if (tok.kind == 0) { retval.append(tokenImage[0]); break; } retval.append(add_escapes(tok.image)); tok = tok.next; } retval.append("\" at "); appendTemplateInfo(retval); if (expectedTokenSequences.length == 1) { retval.append("Was expecting:").append(eol).append(" "); } else { retval.append("Was expecting one of:").append(eol).append(" "); } // avoid JDK 1.3 StringBuffer.append(Object o) vs 1.4 StringBuffer.append(StringBuffer sb) gotcha. retval.append(expected.toString()); return retval.toString(); } /** * @param sb */ protected void appendTemplateInfo(final StringBuffer sb) { sb.append(Log.formatFileString(getTemplateName(), getLineNumber(), getColumnNumber())); sb.append(eol); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/0000755000175000017500000000000011675166251024373 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIndex.java0000644000175000017500000001452011322700447026645 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.introspection.VelMethod; /* * 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. */ /** * This node is responsible for the bracket notation at the end of * a reference, e.g., $foo[1] */ public class ASTIndex extends SimpleNode { private final String methodName = "get"; /** * Indicates if we are running in strict reference mode. */ protected boolean strictRef = false; public ASTIndex(int i) { super(i); } public ASTIndex(Parser p, int i) { super(p, i); } public Object init(InternalContextAdapter context, Object data) throws TemplateInitException { super.init(context, data); strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); return data; } private final static Object[] noParams = {}; private final static Class[] noTypes = {}; /** * If argument is an Integer and negative, then return (o.size() - argument). * Otherwise return the original argument. We use this to calculate the true * index of a negative index e.g., $foo[-1]. If no size() method is found on the * 'o' object, then we throw an VelocityException. * @param context Used to access the method cache. * @param node ASTNode used for error reporting. */ public static Object adjMinusIndexArg(Object argument, Object o, InternalContextAdapter context, SimpleNode node) { if (argument instanceof Integer && ((Integer)argument).intValue() < 0) { // The index value is a negative number, $foo[-1], so we want to actually // Index [size - value], so try and call the size method. VelMethod method = ClassUtils.getMethod("size", noParams, noTypes, o, context, node, false); if (method == null) { // The object doesn't have a size method, so there is no notion of "at the end" throw new VelocityException( "A 'size()' method required for negative value " + ((Integer)argument).intValue() + " does not exist for class '" + o.getClass().getName() + "' at " + Log.formatFileString(node)); } Object size = null; try { size = method.invoke(o, noParams); } catch (Exception e) { throw new VelocityException("Error trying to calls the 'size()' method on '" + o.getClass().getName() + "' at " + Log.formatFileString(node), e); } int sizeint = 0; try { sizeint = ((Integer)size).intValue(); } catch (ClassCastException e) { // If size() doesn't return an Integer we want to report a pretty error throw new VelocityException("Method 'size()' on class '" + o.getClass().getName() + "' returned '" + size.getClass().getName() + "' when Integer was expected at " + Log.formatFileString(node)); } argument = new Integer(sizeint + ((Integer)argument).intValue()); } // Nothing to do, return the original argument return argument; } public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { Object argument = jjtGetChild(0).value(context); // If negative, turn -1 into size - 1 argument = adjMinusIndexArg(argument, o, context, this); Object [] params = {argument}; Class[] paramClasses = {argument == null ? null : argument.getClass()}; VelMethod method = ClassUtils.getMethod(methodName, params, paramClasses, o, context, this, strictRef); if (method == null) return null; try { /* * get the returned object. It may be null, and that is * valid for something declared with a void return type. * Since the caller is expecting something to be returned, * as long as things are peachy, we can return an empty * String so ASTReference() correctly figures out that * all is well. */ Object obj = method.invoke(o, params); if (obj == null) { if( method.getReturnType() == Void.TYPE) { return ""; } } return obj; } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch( Exception e ) { String msg = "Error invoking method 'get(" + (argument == null ? "null" : argument.getClass().getName()) + ")' in " + o.getClass().getName() + " at " + Log.formatFileString(this); log.error(msg, e); throw new VelocityException(msg, e); } } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/SimpleNode.java0000644000175000017500000002547611127425322027300 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; /** * */ public class SimpleNode implements Node { /** */ protected RuntimeServices rsvc = null; /** */ protected Log log = null; /** */ protected Node parent; /** */ protected Node[] children; /** */ protected int id; /** */ // TODO - It seems that this field is only valid when parsing, and should not be kept around. protected Parser parser; /** */ protected int info; // added /** */ public boolean state; /** */ protected boolean invalid = false; /** */ protected Token first; /** */ protected Token last; protected String templateName; public RuntimeServices getRuntimeServices() { return rsvc; } /** * @param i */ public SimpleNode(int i) { id = i; } /** * @param p * @param i */ public SimpleNode(Parser p, int i) { this(i); parser = p; templateName = parser.currentTemplateName; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtOpen() */ public void jjtOpen() { first = parser.getToken(1); // added } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtClose() */ public void jjtClose() { last = parser.getToken(0); // added } /** * @param t */ public void setFirstToken(Token t) { this.first = t; } /** * @see org.apache.velocity.runtime.parser.node.Node#getFirstToken() */ public Token getFirstToken() { return first; } /** * @see org.apache.velocity.runtime.parser.node.Node#getLastToken() */ public Token getLastToken() { return last; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtSetParent(org.apache.velocity.runtime.parser.node.Node) */ public void jjtSetParent(Node n) { parent = n; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtGetParent() */ public Node jjtGetParent() { return parent; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtAddChild(org.apache.velocity.runtime.parser.node.Node, int) */ public void jjtAddChild(Node n, int i) { if (children == null) { children = new Node[i + 1]; } else if (i >= children.length) { Node c[] = new Node[i + 1]; System.arraycopy(children, 0, c, 0, children.length); children = c; } children[i] = n; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtGetChild(int) */ public Node jjtGetChild(int i) { return children[i]; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtGetNumChildren() */ public int jjtGetNumChildren() { return (children == null) ? 0 : children.length; } /** * @see org.apache.velocity.runtime.parser.node.Node#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.Node#childrenAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object childrenAccept(ParserVisitor visitor, Object data) { if (children != null) { for (int i = 0; i < children.length; ++i) { children[i].jjtAccept(visitor, data); } } return data; } /* You can override these two methods in subclasses of SimpleNode to customize the way the node appears when the tree is dumped. If your output uses more than one line you should override toString(String), otherwise overriding toString() is probably all you need to do. */ // public String toString() // { // return ParserTreeConstants.jjtNodeName[id]; // } /** * @param prefix * @return String representation of this node. */ public String toString(String prefix) { return prefix + toString(); } /** * Override this method if you want to customize how the node dumps * out its children. * * @param prefix */ public void dump(String prefix) { System.out.println(toString(prefix)); if (children != null) { for (int i = 0; i < children.length; ++i) { SimpleNode n = (SimpleNode) children[i]; if (n != null) { n.dump(prefix + " "); } } } } /** * Return a string that tells the current location of this node. */ protected String getLocation(InternalContextAdapter context) { return Log.formatFileString(this); } // All additional methods /** * @see org.apache.velocity.runtime.parser.node.Node#literal() */ public String literal() { // if we have only one string, just return it and avoid // buffer allocation. VELOCITY-606 if (first == last) { return NodeUtils.tokenLiteral(first); } Token t = first; StrBuilder sb = new StrBuilder(NodeUtils.tokenLiteral(t)); while (t != last) { t = t.next; sb.append(NodeUtils.tokenLiteral(t)); } return sb.toString(); } /** * @throws TemplateInitException * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { /* * hold onto the RuntimeServices */ rsvc = (RuntimeServices) data; log = rsvc.getLog(); int i, k = jjtGetNumChildren(); for (i = 0; i < k; i++) { jjtGetChild(i).init( context, data); } return data; } /** * @see org.apache.velocity.runtime.parser.node.Node#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { return false; } /** * @see org.apache.velocity.runtime.parser.node.Node#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) throws MethodInvocationException { return null; } /** * @see org.apache.velocity.runtime.parser.node.Node#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException { int i, k = jjtGetNumChildren(); for (i = 0; i < k; i++) jjtGetChild(i).render(context, writer); return true; } /** * @see org.apache.velocity.runtime.parser.node.Node#execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter) */ public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { return null; } /** * @see org.apache.velocity.runtime.parser.node.Node#getType() */ public int getType() { return id; } /** * @see org.apache.velocity.runtime.parser.node.Node#setInfo(int) */ public void setInfo(int info) { this.info = info; } /** * @see org.apache.velocity.runtime.parser.node.Node#getInfo() */ public int getInfo() { return info; } /** * @see org.apache.velocity.runtime.parser.node.Node#setInvalid() */ public void setInvalid() { invalid = true; } /** * @see org.apache.velocity.runtime.parser.node.Node#isInvalid() */ public boolean isInvalid() { return invalid; } /** * @see org.apache.velocity.runtime.parser.node.Node#getLine() */ public int getLine() { return first.beginLine; } /** * @see org.apache.velocity.runtime.parser.node.Node#getColumn() */ public int getColumn() { return first.beginColumn; } /** * @since 1.5 */ public String toString() { StrBuilder tokens = new StrBuilder(); for (Token t = getFirstToken(); t != null; ) { tokens.append("[").append(t.image).append("]"); if (t.next != null) { if (t.equals(getLastToken())) { break; } else { tokens.append(", "); } } t = t.next; } return new ToStringBuilder(this) .append("id", getType()) .append("info", getInfo()) .append("invalid", isInvalid()) .append("children", jjtGetNumChildren()) .append("tokens", tokens) .toString(); } public String getTemplateName() { return templateName; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTMulNode.java0000644000175000017500000000352211057047743027151 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * Handles multiplication

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTMulNode.java 691048 2008-09-01 20:26:11Z nbubna $ */ public class ASTMulNode extends ASTMathNode { /** * @param id */ public ASTMulNode(int id) { super(id); } /** * @param p * @param id */ public ASTMulNode(Parser p, int id) { super(p, id); } public Number perform(Number left, Number right, InternalContextAdapter context) { return MathUtils.multiply(left, right); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTDivNode.java0000644000175000017500000000456511057047743027146 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MathException; import org.apache.velocity.runtime.parser.Parser; /** * Handles number division of nodes

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTDivNode.java 691048 2008-09-01 20:26:11Z nbubna $ */ public class ASTDivNode extends ASTMathNode { /** * @param id */ public ASTDivNode(int id) { super(id); } /** * @param p * @param id */ public ASTDivNode(Parser p, int id) { super(p, id); } public Number perform(Number left, Number right, InternalContextAdapter context) { /* * check for divide by 0 */ if (MathUtils.isZero(right)) { String msg = "Right side of division operation is zero. Must be non-zero. " + getLocation(context); if (strictMode) { log.error(msg); throw new MathException(msg); } else { log.debug(msg); return null; } } return MathUtils.divide(left, right); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTEscapedDirective.java0000644000175000017500000000432611130150630030772 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * This class is responsible for handling EscapedDirectives * in VTL. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Geir Magnusson Jr. * @version $Id: ASTEscapedDirective.java 731266 2009-01-04 15:11:20Z byron $ */ public class ASTEscapedDirective extends SimpleNode { /** * @param id */ public ASTEscapedDirective(int id) { super(id); } /** * @param p * @param id */ public ASTEscapedDirective(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render(InternalContextAdapter context, Writer writer) throws IOException { writer.write(getFirstToken().image); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTBlock.java0000644000175000017500000000432610575440066026642 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTBlock extends SimpleNode { /** * @param id */ public ASTBlock(int id) { super(id); } /** * @param p * @param id */ public ASTBlock(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException, ResourceNotFoundException, ParseErrorException { int i, k = jjtGetNumChildren(); for (i = 0; i < k; i++) jjtGetChild(i).render(context, writer); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTObjectArray.java0000644000175000017500000000427011050422307027776 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.util.ArrayList; import java.util.List; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTObjectArray extends SimpleNode { /** * @param id */ public ASTObjectArray(int id) { super(id); } /** * @param p * @param id */ public ASTObjectArray(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) throws MethodInvocationException { int size = jjtGetNumChildren(); // since we know the amount of elements, initialize arraylist with proper size List objectArray = new ArrayList(size); for (int i = 0; i < size; i++) { objectArray.add(jjtGetChild(i).value(context)); } return objectArray; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/BooleanPropertyExecutor.java0000644000175000017500000000754211053123230032065 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.RuntimeLoggerLog; import org.apache.velocity.util.introspection.Introspector; /** * Handles discovery and valuation of a * boolean object property, of the * form public boolean is when executed. * * We do this separately as to preserve the current * quasi-broken semantics of get * get< flip 1st char> get("property") and now followed * by is * * @author Geir Magnusson Jr. * @version $Id: BooleanPropertyExecutor.java 687502 2008-08-20 23:19:52Z nbubna $ */ public class BooleanPropertyExecutor extends PropertyExecutor { /** * @param log * @param introspector * @param clazz * @param property * @since 1.5 */ public BooleanPropertyExecutor(final Log log, final Introspector introspector, final Class clazz, final String property) { super(log, introspector, clazz, property); } /** * @param rlog * @param introspector * @param clazz * @param property * @deprecated RuntimeLogger is deprecated. Use the other constructor. */ public BooleanPropertyExecutor(final RuntimeLogger rlog, final Introspector introspector, final Class clazz, final String property) { super(new RuntimeLoggerLog(rlog), introspector, clazz, property); } protected void discover(final Class clazz, final String property) { try { Object [] params = {}; StringBuffer sb = new StringBuffer("is"); sb.append(property); setMethod(getIntrospector().getMethod(clazz, sb.toString(), params)); if (!isAlive()) { /* * now the convenience, flip the 1st character */ char c = sb.charAt(2); if (Character.isLowerCase(c)) { sb.setCharAt(2, Character.toUpperCase(c)); } else { sb.setCharAt(2, Character.toLowerCase(c)); } setMethod(getIntrospector().getMethod(clazz, sb.toString(), params)); } if (isAlive()) { if( getMethod().getReturnType() != Boolean.TYPE && getMethod().getReturnType() != Boolean.class ) { setMethod(null); } } } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for boolean property getter for '" + property; log.error(msg, e); throw new VelocityException(msg, e); } } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ParserVisitor.java0000644000175000017500000001602411150574032030041 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ /** * Interface used in implementation of visitor pattern. Based on * code autogenerated by JavaCC. Formerly found in package * org.apache.velocity.runtime.parser. * * @version $Id: ParserVisitor.java 747106 2009-02-23 19:25:14Z nbubna $ * @since 1.5 */ public interface ParserVisitor { /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(SimpleNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTprocess node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTEscapedDirective node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTEscape node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTComment node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTFloatingPointLiteral node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTIntegerLiteral node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTStringLiteral node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTIdentifier node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTWord node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTDirective node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTBlock node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTMap node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTObjectArray node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTIntegerRange node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTMethod node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTReference node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTTrue node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTFalse node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTText node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTIfStatement node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTElseStatement node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTElseIfStatement node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTSetDirective node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTExpression node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTAssignment node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTOrNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTAndNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTEQNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTNENode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTLTNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTGTNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTLENode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTGENode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTAddNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTSubtractNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTMulNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTDivNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTModNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ public Object visit(ASTNotNode node, Object data); /** * @param node * @param data * @return The object rendered by this node. */ } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/PropertyExecutor.java0000644000175000017500000001027211052641200030560 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.commons.lang.StringUtils; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.RuntimeLoggerLog; import org.apache.velocity.util.introspection.Introspector; /** * Returned the value of object property when executed. */ public class PropertyExecutor extends AbstractExecutor { private final Introspector introspector; /** * @param log * @param introspector * @param clazz * @param property * @since 1.5 */ public PropertyExecutor(final Log log, final Introspector introspector, final Class clazz, final String property) { this.log = log; this.introspector = introspector; // Don't allow passing in the empty string or null because // it will either fail with a StringIndexOutOfBounds error // or the introspector will get confused. if (StringUtils.isNotEmpty(property)) { discover(clazz, property); } } /** * @param r * @param introspector * @param clazz * @param property * @deprecated RuntimeLogger is deprecated. Use the other constructor. */ public PropertyExecutor(final RuntimeLogger r, final Introspector introspector, final Class clazz, final String property) { this(new RuntimeLoggerLog(r), introspector, clazz, property); } /** * @return The current introspector. * @since 1.5 */ protected Introspector getIntrospector() { return this.introspector; } /** * @param clazz * @param property */ protected void discover(final Class clazz, final String property) { /* * this is gross and linear, but it keeps it straightforward. */ try { Object [] params = {}; StringBuffer sb = new StringBuffer("get"); sb.append(property); setMethod(introspector.getMethod(clazz, sb.toString(), params)); if (!isAlive()) { /* * now the convenience, flip the 1st character */ char c = sb.charAt(3); if (Character.isLowerCase(c)) { sb.setCharAt(3, Character.toUpperCase(c)); } else { sb.setCharAt(3, Character.toLowerCase(c)); } setMethod(introspector.getMethod(clazz, sb.toString(), params)); } } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for property getter for '" + property; log.error(msg, e); throw new VelocityException(msg, e); } } /** * @see org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object) */ public Object execute(Object o) throws IllegalAccessException, InvocationTargetException { return isAlive() ? getMethod().invoke(o, ((Object []) null)) : null; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTAddNode.java0000644000175000017500000000462211106150606027072 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * Handles number addition of nodes.

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTAddNode.java 712887 2008-11-11 00:27:50Z nbubna $ */ public class ASTAddNode extends ASTMathNode { /** * @param id */ public ASTAddNode(int id) { super(id); } /** * @param p * @param id */ public ASTAddNode(Parser p, int id) { super(p, id); } //@Override protected Object handleSpecial(Object left, Object right, InternalContextAdapter context) { /* * shall we try for strings? */ if (left instanceof String || right instanceof String) { if (left == null) { left = jjtGetChild(0).literal(); } else if (right == null) { right = jjtGetChild(1).literal(); } return left.toString().concat(right.toString()); } return null; } public Number perform(Number left, Number right, InternalContextAdapter context) { return MathUtils.add(left, right); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIntegerLiteral.java0000644000175000017500000000606011050652577030520 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.math.BigInteger; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; /** * Handles integer numbers. The value will be either an Integer, a Long, or a BigInteger. * * @author Will Glass-Husain * @since 1.5 */ public class ASTIntegerLiteral extends SimpleNode { // This may be of type Integer, Long or BigInteger private Number value = null; /** * @param id */ public ASTIntegerLiteral(int id) { super(id); } /** * @param p * @param id */ public ASTIntegerLiteral(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { /* * init the tree correctly */ super.init( context, data ); /** * Determine the size of the item and make it an Integer, Long, or BigInteger as appropriate. */ String str = getFirstToken().image; try { value = new Integer( str ); } catch ( NumberFormatException E1 ) { try { value = new Long( str ); } catch ( NumberFormatException E2 ) { // if there's still an Exception it will propogate out value = new BigInteger( str ); } } return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) { return value; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTReference.java0000644000175000017500000010316711273740157027511 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.Context; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.directive.Block.Reference; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.VelMethod; import org.apache.velocity.util.introspection.VelPropertySet; /** * This class is responsible for handling the references in * VTL ($foo). * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Christoph Reck * @author to render as $abc */ public boolean strictEscape = false; /** * Indicates if toString() should be called during condition evaluation just * to ensure it does not return null. Check is unnecessary if all toString() * implementations are known to have non-null return values. Disabling the * check will give a performance improval since toString() may be a complex * operation on large objects. */ public boolean toStringNullCheck = true; private int numChildren = 0; protected Info uberInfo; /** * @param id */ public ASTReference(int id) { super(id); } /** * @param p * @param id */ public ASTReference(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init(InternalContextAdapter context, Object data) throws TemplateInitException { super.init(context, data); strictEscape = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false); strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); toStringNullCheck = rsvc.getBoolean(RuntimeConstants.DIRECTIVE_IF_TOSTRING_NULLCHECK, true); /* * the only thing we can do in init() is getRoot() * as that is template based, not context based, * so it's thread- and context-safe */ rootString = getRoot().intern(); numChildren = jjtGetNumChildren(); // This is an expensive call, so get it now. literal = literal(); /* * and if appropriate... */ if (numChildren > 0 ) { Node lastNode = jjtGetChild(numChildren-1); if (lastNode instanceof ASTIndex) astIndex = (ASTIndex)lastNode; else identifier = lastNode.getFirstToken().image; } /* * make an uberinfo - saves new's later on */ uberInfo = new Info(getTemplateName(), getLine(),getColumn()); /* * track whether we log invalid references */ logOnNull = rsvc.getBoolean(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID, true); /** * In the case we are referencing a variable with #if($foo) or * #if( ! $foo) then we allow variables to be undefined and we * set strictRef to false so that if the variable is undefined * an exception is not thrown. */ if (strictRef && numChildren == 0) { logOnNull = false; // Strict mode allows nulls Node node = this.jjtGetParent(); if (node instanceof ASTNotNode // #if( ! $foo) || node instanceof ASTExpression // #if( $foo ) || node instanceof ASTOrNode // #if( $foo || ... || node instanceof ASTAndNode) // #if( $foo && ... { // Now scan up tree to see if we are in an If statement while (node != null) { if (node instanceof ASTIfStatement) { strictRef = false; break; } node = node.jjtGetParent(); } } } return data; } /** * Returns the 'root string', the reference key * @return the root string. */ public String getRootString() { return rootString; } /** * gets an Object that 'is' the value of the reference * * @param o unused Object parameter * @param context context used to generate value * @return The execution result. * @throws MethodInvocationException */ public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { if (referenceType == RUNT) return null; /* * get the root object from the context */ Object result = getVariableValue(context, rootString); if (result == null && !strictRef) { return EventHandlerUtil.invalidGetMethod(rsvc, context, getDollarBang() + rootString, null, null, uberInfo); } /* * Iteratively work 'down' (it's flat...) the reference * to get the value, but check to make sure that * every result along the path is valid. For example: * * $hashtable.Customer.Name * * The $hashtable may be valid, but there is no key * 'Customer' in the hashtable so we want to stop * when we find a null value and return the null * so the error gets logged. */ try { Object previousResult = result; int failedChild = -1; for (int i = 0; i < numChildren; i++) { if (strictRef && result == null) { /** * At this point we know that an attempt is about to be made * to call a method or property on a null value. */ String name = jjtGetChild(i).getFirstToken().image; throw new VelocityException("Attempted to access '" + name + "' on a null value at " + Log.formatFileString(uberInfo.getTemplateName(), + jjtGetChild(i).getLine(), jjtGetChild(i).getColumn())); } previousResult = result; result = jjtGetChild(i).execute(result,context); if (result == null && !strictRef) // If strict and null then well catch this // next time through the loop { failedChild = i; break; } } if (result == null) { if (failedChild == -1) { result = EventHandlerUtil.invalidGetMethod(rsvc, context, getDollarBang() + rootString, previousResult, null, uberInfo); } else { StringBuffer name = new StringBuffer(getDollarBang()).append(rootString); for (int i = 0; i <= failedChild; i++) { Node node = jjtGetChild(i); if (node instanceof ASTMethod) { name.append(".").append(((ASTMethod) node).getMethodName()).append("()"); } else { name.append(".").append(node.getFirstToken().image); } } if (jjtGetChild(failedChild) instanceof ASTMethod) { String methodName = ((ASTMethod) jjtGetChild(failedChild)).getMethodName(); result = EventHandlerUtil.invalidMethod(rsvc, context, name.toString(), previousResult, methodName, uberInfo); } else { String property = jjtGetChild(failedChild).getFirstToken().image; result = EventHandlerUtil.invalidGetMethod(rsvc, context, name.toString(), previousResult, property, uberInfo); } } } return result; } catch(MethodInvocationException mie) { mie.setReferenceName(rootString); throw mie; } } /** * gets the value of the reference and outputs it to the * writer. * * @param context context of data to use in getting value * @param writer writer to render to * @return True if rendering was successful. * @throws IOException * @throws MethodInvocationException */ public boolean render(InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException { if (referenceType == RUNT) { writer.write(rootString); return true; } Object value = null; if (escaped && strictEscape) { /** * If we are in strict mode and the variable is escaped, then don't bother to * retreive the value since we won't use it. And if the var is not defined * it will throw an exception. Set value to TRUE to fall through below with * simply printing $foo, and not \$foo */ value = Boolean.TRUE; } else { value = execute(null, context); } String localNullString = null; /* * if this reference is escaped (\$foo) then we want to do one of two things : 1) if this is * a reference in the context, then we want to print $foo 2) if not, then \$foo (its * considered schmoo, not VTL) */ if (escaped) { localNullString = getNullString(context); if (value == null) { writer.write(escPrefix); writer.write("\\"); writer.write(localNullString); } else { writer.write(escPrefix); writer.write(localNullString); } return true; } /* * the normal processing * * if we have an event cartridge, get a new value object */ value = EventHandlerUtil.referenceInsert(rsvc, context, literal, value); String toString = null; if (value != null) { if (value instanceof Renderable) { Renderable renderable = (Renderable)value; try { if (renderable.render(context,writer)) return true; } catch(RuntimeException e) { // We commonly get here when an error occurs within a block reference. // We want to log where the reference is at so that a developer can easily // know where the offending call is located. This can be seen // as another element of the error stack we report to log. log.error("Exception rendering " + ((renderable instanceof Reference)? "block ":"Renderable ") + rootString + " at " + Log.formatFileString(this)); throw e; } } toString = value.toString(); } if (value == null || toString == null) { if (strictRef) { if (referenceType != QUIET_REFERENCE) { log.error("Prepend the reference with '$!' e.g., $!" + literal().substring(1) + " if you want Velocity to ignore the reference when it evaluates to null"); if (value == null) { throw new VelocityException("Reference " + literal() + " evaluated to null when attempting to render at " + Log.formatFileString(this)); } else // toString == null { // This will probably rarely happen, but when it does we want to // inform the user that toString == null so they don't pull there // hair out wondering why Velocity thinks the value is null. throw new VelocityException("Reference " + literal() + " evaluated to object " + value.getClass().getName() + " whose toString() method returned null at " + Log.formatFileString(this)); } } return true; } /* * write prefix twice, because it's schmoo, so the \ don't escape each * other... */ localNullString = getNullString(context); if (!strictEscape) { // If in strict escape mode then we only print escape once. // Yea, I know.. brittle stuff writer.write(escPrefix); } writer.write(escPrefix); writer.write(morePrefix); writer.write(localNullString); if (logOnNull && referenceType != QUIET_REFERENCE && log.isDebugEnabled()) { log.debug("Null reference [template '" + getTemplateName() + "', line " + this.getLine() + ", column " + this.getColumn() + "] : " + this.literal() + " cannot be resolved."); } return true; } else { /* * non-null processing */ writer.write(escPrefix); writer.write(morePrefix); writer.write(toString); return true; } } /** * This method helps to implement the "render literal if null" functionality. * * VelocimacroProxy saves references to macro arguments (AST nodes) so that if we have a macro * #foobar($a $b) then there is key "$a.literal" which points to the literal presentation of the * argument provided to variable $a. If the value of $a is null, we render the string that was * provided as the argument. * * @param context * @return */ private String getNullString(InternalContextAdapter context) { Object callingArgument = context.get(".literal." + nullString); if (callingArgument != null) return ((Node) callingArgument).literal(); else return nullString; } /** * Computes boolean value of this reference * Returns the actual value of reference return type * boolean, and 'true' if value is not null * * @param context context to compute value with * @return True if evaluation was ok. * @throws MethodInvocationException */ public boolean evaluate(InternalContextAdapter context) throws MethodInvocationException { Object value = execute(null, context); if (value == null) { return false; } else if (value instanceof Boolean) { if (((Boolean) value).booleanValue()) return true; else return false; } else if (toStringNullCheck) { try { return value.toString() != null; } catch(Exception e) { throw new VelocityException("Reference evaluation threw an exception at " + Log.formatFileString(this), e); } } else { return true; } } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { return (computableReference ? execute(null, context) : null); } /** * Utility class to handle nulls when printing a class type */ public static String printClass(Class clazz) { return clazz == null ? "null" : clazz.getName(); } /** * Sets the value of a complex reference (something like $foo.bar) * Currently used by ASTSetReference() * * @see ASTSetDirective * * @param context context object containing this reference * @param value Object to set as value * @return true if successful, false otherwise * @throws MethodInvocationException */ public boolean setValue( InternalContextAdapter context, Object value) throws MethodInvocationException { if (jjtGetNumChildren() == 0) { context.put(rootString, value); return true; } /* * The rootOfIntrospection is the object we will * retrieve from the Context. This is the base * object we will apply reflection to. */ Object result = getVariableValue(context, rootString); if (result == null) { String msg = "reference set is not a valid reference at " + Log.formatFileString(uberInfo); log.error(msg); return false; } /* * How many child nodes do we have? */ for (int i = 0; i < numChildren - 1; i++) { result = jjtGetChild(i).execute(result, context); if (result == null) { if (strictRef) { String name = jjtGetChild(i+1).getFirstToken().image; throw new MethodInvocationException("Attempted to access '" + name + "' on a null value", null, name, uberInfo.getTemplateName(), jjtGetChild(i+1).getLine(), jjtGetChild(i+1).getColumn()); } String msg = "reference set is not a valid reference at " + Log.formatFileString(uberInfo); log.error(msg); return false; } } if (astIndex != null) { // If astIndex is not null then we are actually setting an index reference, // something of the form $foo[1] =, or in general any reference that ends with // the brackets. This means that we need to call a more general method // of the form set(Integer, ), or put(Object, not escaped, odd -> escaped */ int i = 0; int len = t.image.length(); i = t.image.indexOf('$'); if (i == -1) { /* yikes! */ log.error("ASTReference.getRoot() : internal error : " + "no $ found for slashbang."); computableReference = false; nullString = t.image; return nullString; } while (i < len && t.image.charAt(i) != '\\') { i++; } /* ok, i is the first \ char */ int start = i; int count = 0; while (i < len && t.image.charAt(i++) == '\\') { count++; } /* * now construct the output string. We really don't care about * leading slashes as this is not a reference. It's quasi-schmoo */ nullString = t.image.substring(0,start); // prefix up to the first nullString += t.image.substring(start, start + count-1 ); // get the slashes nullString += t.image.substring(start+count); // and the rest, including the /* * this isn't a valid reference, so lets short circuit the value * and set calcs */ computableReference = false; return nullString; } /* * we need to see if this reference is escaped. if so * we will clean off the leading \'s and let the * regular behavior determine if we should output this * as \$foo or $foo later on in render(). Lazyness.. */ escaped = false; if (t.image.startsWith("\\")) { /* * count the escapes : even # -> not escaped, odd -> escaped */ int i = 0; int len = t.image.length(); while (i < len && t.image.charAt(i) == '\\') { i++; } if ((i % 2) != 0) escaped = true; if (i > 0) escPrefix = t.image.substring(0, i / 2 ); t.image = t.image.substring(i); } /* * Look for preceeding stuff like '#' and '$' * and snip it off, except for the * last $ */ int loc1 = t.image.lastIndexOf('$'); /* * if we have extra stuff, loc > 0 * ex. '#$foo' so attach that to * the prefix. */ if (loc1 > 0) { morePrefix = morePrefix + t.image.substring(0, loc1); t.image = t.image.substring(loc1); } /* * Now it should be clean. Get the literal in case this reference * isn't backed by the context at runtime, and then figure out what * we are working with. */ // FIXME: this is the key to render nulls as literals, we need to look at context(refname+".literal") nullString = literal(); if (t.image.startsWith("$!")) { referenceType = QUIET_REFERENCE; /* * only if we aren't escaped do we want to null the output */ if (!escaped) nullString = ""; if (t.image.startsWith("$!{")) { /* * ex : $!{provider.Title} */ return t.next.image; } else { /* * ex : $!provider.Title */ return t.image.substring(2); } } else if (t.image.equals("${")) { /* * ex : ${provider.Title} */ referenceType = FORMAL_REFERENCE; return t.next.image; } else if (t.image.startsWith("$")) { /* * just nip off the '$' so we have * the root */ referenceType = NORMAL_REFERENCE; return t.image.substring(1); } else { /* * this is a 'RUNT', which can happen in certain circumstances where * the parser is fooled into believeing that an IDENTIFIER is a real * reference. Another 'dreaded' MORE hack :). */ referenceType = RUNT; return t.image; } } /** * @param context * @param variable * @return The evaluated value of the variable. * @throws MethodInvocationException */ public Object getVariableValue(Context context, String variable) throws MethodInvocationException { Object obj = null; try { obj = context.get(variable); } catch(RuntimeException e) { log.error("Exception calling reference $" + variable + " at " + Log.formatFileString(uberInfo)); throw e; } if (strictRef && obj == null) { if (!context.containsKey(variable)) { log.error("Variable $" + variable + " has not been set at " + Log.formatFileString(uberInfo)); throw new MethodInvocationException("Variable $" + variable + " has not been set", null, identifier, uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn()); } } return obj; } public String getDollarBang() { return (referenceType == QUIET_REFERENCE) ? "$!" : "$"; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIntegerRange.java0000644000175000017500000001015311112556471030151 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.util.ArrayList; import java.util.List; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; /** * handles the range 'operator' [ n .. m ] * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Geir Magnusson Jr. */ public class ASTIntegerRange extends SimpleNode { /** * @param id */ public ASTIntegerRange(int id) { super(id); } /** * @param p * @param id */ public ASTIntegerRange(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * does the real work. Creates an Vector of Integers with the * right value range * * @param context app context used if Left or Right of .. is a ref * @return Object array of Integers * @throws MethodInvocationException */ public Object value( InternalContextAdapter context) throws MethodInvocationException { /* * get the two range ends */ Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * if either is null, lets log and bail */ if (left == null || right == null) { log.error((left == null ? "Left" : "Right") + " side of range operator [n..m] has null value." + " Operation not possible. " + Log.formatFileString(this)); return null; } /* * if not a Number, not much we can do either */ if ( !( left instanceof Number ) || !( right instanceof Number )) { log.error((!(left instanceof Number) ? "Left" : "Right") + " side of range operator is not a valid type. " + "Currently only integers (1,2,3...) and the Number type are supported. " + Log.formatFileString(this)); return null; } /* * get the two integer values of the ends of the range */ int l = ((Number) left).intValue() ; int r = ((Number) right).intValue(); /* * find out how many there are */ int nbrElements = Math.abs( l - r ); nbrElements += 1; /* * Determine whether the increment is positive or negative. */ int delta = ( l >= r ) ? -1 : 1; /* * Fill the range with the appropriate values. */ List elements = new ArrayList(nbrElements); int value = l; for (int i = 0; i < nbrElements; i++) { // TODO: JDK 1.4+ -> valueOf() elements.add(new Integer(value)); value += delta; } return elements; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/NodeUtils.java0000644000175000017500000001542511053046343027140 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.ParserConstants; import org.apache.velocity.runtime.parser.Token; /** * Utilities for dealing with the AST node structure. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: NodeUtils.java 687386 2008-08-20 16:57:07Z nbubna $ */ public class NodeUtils { /** * @deprecated use getSpecialText(Token t) */ public static String specialText(Token t) { if (t.specialToken == null || t.specialToken.image.startsWith("##") ) { return ""; } return getSpecialText(t).toString(); } /** * Collect all the s that * are carried along with a token. Special * tokens do not participate in parsing but * can still trigger certain lexical actions. * In some cases you may want to retrieve these * special tokens, this is simply a way to * extract them. * @param t the Token * @return StrBuilder with the special tokens. */ public static StrBuilder getSpecialText(Token t) { StrBuilder sb = new StrBuilder(); Token tmp_t = t.specialToken; while (tmp_t.specialToken != null) { tmp_t = tmp_t.specialToken; } while (tmp_t != null) { String st = tmp_t.image; for(int i = 0, is = st.length(); i < is; i++) { char c = st.charAt(i); if ( c == '#' || c == '$' ) { sb.append( c ); } /* * more dreaded MORE hack :) * * looking for ("\\")*"$" sequences */ if ( c == '\\') { boolean ok = true; boolean term = false; int j = i; for( ok = true; ok && j < is; j++) { char cc = st.charAt( j ); if (cc == '\\') { /* * if we see a \, keep going */ continue; } else if( cc == '$' ) { /* * a $ ends it correctly */ term = true; ok = false; } else { /* * nah... */ ok = false; } } if (term) { String foo = st.substring( i, j ); sb.append( foo ); i = j; } } } tmp_t = tmp_t.next; } return sb; } /** * complete node literal * @param t * @return A node literal. */ public static String tokenLiteral( Token t ) { // Look at kind of token and return "" when it's a multiline comment if (t.kind == ParserConstants.MULTI_LINE_COMMENT) { return ""; } else if (t.specialToken == null || t.specialToken.image.startsWith("##")) { return t.image; } else { StrBuilder special = getSpecialText(t); if (special.length() > 0) { return special.append(t.image).toString(); } return t.image; } } /** * Utility method to interpolate context variables * into string literals. So that the following will * work: * * #set $name = "candy" * $image.getURI("${name}.jpg") * * And the string literal argument will * be transformed into "candy.jpg" before * the method is executed. * * @deprecated this method isn't called by any class * * @param argStr * @param vars * @return Interpoliation result. * @throws MethodInvocationException */ public static String interpolate(String argStr, Context vars) throws MethodInvocationException { // if there's nothing to replace, skip this (saves buffer allocation) if( argStr.indexOf('$') == -1 ) return argStr; StrBuilder argBuf = new StrBuilder(); for (int cIdx = 0, is = argStr.length(); cIdx < is;) { char ch = argStr.charAt(cIdx); if( ch == '$' ) { StrBuilder nameBuf = new StrBuilder(); for (++cIdx ; cIdx < is; ++cIdx) { ch = argStr.charAt(cIdx); if (ch == '_' || ch == '-' || Character.isLetterOrDigit(ch)) nameBuf.append(ch); else if (ch == '{' || ch == '}') continue; else break; } if (nameBuf.length() > 0) { Object value = vars.get(nameBuf.toString()); if (value == null) argBuf.append("$").append(nameBuf.toString()); else argBuf.append(value.toString()); } } else { argBuf.append(ch); ++cIdx; } } return argBuf.toString(); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTprocess.java0000644000175000017500000000267710575440066027275 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTprocess extends SimpleNode { /** * @param id */ public ASTprocess(int id) { super(id); } /** * @param p * @param id */ public ASTprocess(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTMathNode.java0000755000175000017500000001134311057047743027310 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MathException; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Helps handle math

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: ASTMathNode.java 517553 2007-03-13 06:09:58Z wglass $ */ public abstract class ASTMathNode extends SimpleNode { protected boolean strictMode = false; public ASTMathNode(int id) { super(id); } public ASTMathNode(Parser p, int id) { super(p, id); } /** * {@inheritDoc} */ public Object init(InternalContextAdapter context, Object data) throws TemplateInitException { super.init(context, data); strictMode = rsvc.getBoolean(RuntimeConstants.STRICT_MATH, false); return data; } /** * {@inheritDoc} */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * gets the two args and performs the operation on them * * @param context * @return result or null * @throws MethodInvocationException */ public Object value(InternalContextAdapter context) throws MethodInvocationException { Object left = jjtGetChild(0).value(context); Object right = jjtGetChild(1).value(context); /* * should we do anything special here? */ Object special = handleSpecial(left, right, context); if (special != null) { return special; } /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ((TemplateNumber)left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ((TemplateNumber)right).getAsNumber(); } /* * if not a Number, not much we can do */ if (!(left instanceof Number) || !(right instanceof Number)) { boolean wrongright = (left instanceof Number); boolean wrongtype = wrongright ? right != null : left != null; String msg = (wrongright ? "Right" : "Left") + " side of math operation (" + jjtGetChild(wrongright ? 1 : 0).literal() + ") " + (wrongtype ? "is not a Number. " : "has a null value. ") + getLocation(context); if (strictMode) { log.error(msg); throw new MathException(msg); } else { log.debug(msg); return null; } } return perform((Number)left, (Number)right, context); } /** * Extension hook to allow special behavior by subclasses * If this method returns a non-null value, that is returned, * rather than the result of the math operation. * @see ASTAddNode#handleSpecial */ protected Object handleSpecial(Object left, Object right, InternalContextAdapter context) { // do nothing, this is an extension hook return null; } /** * Performs the math operation represented by this node. */ public abstract Number perform(Number left, Number right, InternalContextAdapter context); } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTExpression.java0000644000175000017500000000423110575440066027742 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTExpression extends SimpleNode { /** * @param id */ public ASTExpression(int id) { super(id); } /** * @param p * @param id */ public ASTExpression(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { return jjtGetChild(0).evaluate(context); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) throws MethodInvocationException { return jjtGetChild(0).value(context); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java0000644000175000017500000000563011130520621027526 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; /** * This node holds the "Textblock" data which should not be interpreted by Velocity. * * Textblocks are marked in Velocity with #[[content here]]# notation. Velocity * will output everything between the markers and does not attempt to parse it in any way. */ public class ASTTextblock extends SimpleNode { public static final String START = "#[["; public static final String END = "]]#"; private char[] ctext; /** * @param id */ public ASTTextblock(int id) { super(id); } /** * @param p * @param id */ public ASTTextblock(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { Token t = getFirstToken(); String text = t.image; // t.image is in format: #% %# // we must strip away the hash tags text = text.substring(START.length(), text.length() - END.length()); ctext = text.toCharArray(); return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException { writer.write(ctext); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTEscape.java0000644000175000017500000000501011130150630026756 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * This class is responsible for handling Escapes * in VTL. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Geir Magnusson Jr. * @version $Id: ASTEscape.java 731266 2009-01-04 15:11:20Z byron $ */ public class ASTEscape extends SimpleNode { /** Used by the parser */ public String val; private char[] ctext; /** * @param id */ public ASTEscape(int id) { super(id); } /** * @param p * @param id */ public ASTEscape(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init( InternalContextAdapter context, Object data) { ctext = val.toCharArray(); return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException { writer.write(ctext); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/MapSetExecutor.java0000644000175000017500000000454011234415123030133 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.util.Map; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.log.Log; /** * SetExecutor that is smart about Maps. If it detects one, it does not * use Reflection but a cast to access the setter. * * @author Henning P. Schmiedehausen * @version $Id: MapSetExecutor.java 799457 2009-07-30 22:10:27Z nbubna $ * @since 1.5 */ public class MapSetExecutor extends SetExecutor { private final String property; public MapSetExecutor(final Log log, final Class clazz, final String property) { this.log = log; this.property = property; discover(clazz); } protected void discover (final Class clazz) { if (property != null && Map.class.isAssignableFrom(clazz)) { try { setMethod(Map.class.getMethod("put", new Class [] { Object.class, Object.class })); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for put('" + property + "') method"; log.error(msg, e); throw new VelocityException(msg, e); } } } public Object execute(final Object o, final Object arg) { return ((Map) o).put(property, arg); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTGENode.java0000644000175000017500000001063111124067071026675 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 >= arg2

      * * Only subclasses of Number can be compared.

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski */ public class ASTGENode extends SimpleNode { /** * @param id */ public ASTGENode(int id) { super(id); } /** * @param p * @param id */ public ASTGENode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { /* * get the two args */ Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * if either is null, lets log and bail */ if (left == null || right == null) { String msg = (left == null ? "Left" : "Right") + " side (" + jjtGetChild( (left == null? 0 : 1) ).literal() + ") of '>=' operation has null value at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * Only compare Numbers */ if ( !( left instanceof Number ) || !( right instanceof Number )) { String msg = (!(left instanceof Number) ? "Left" : "Right") + " side of '>=' operation is not a Number at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } return MathUtils.compare ( (Number)left,(Number)right) >= 0; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { boolean val = evaluate(context); return val ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTComment.java0000644000175000017500000000575011130150630027173 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; /** * Represents all comments... * * @author Geir Magnusson Jr. * @version $Id: ASTComment.java 731266 2009-01-04 15:11:20Z byron $ */ public class ASTComment extends SimpleNode { private static final char[] ZILCH = "".toCharArray(); private char[] carr; /** * @param id */ public ASTComment(int id) { super(id); } /** * @param p * @param id */ public ASTComment(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * We need to make sure we catch any of the dreaded MORE tokens. * @param context * @param data * @return The data object. */ public Object init(InternalContextAdapter context, Object data) { Token t = getFirstToken(); int loc1 = t.image.indexOf("##"); int loc2 = t.image.indexOf("#*"); if (loc1 == -1 && loc2 == -1) { carr = ZILCH; } else { carr = t.image.substring(0, (loc1 == -1) ? loc2 : loc1).toCharArray(); } return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException { writer.write(carr); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/SetExecutor.java0000644000175000017500000000507311050652577027513 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.velocity.runtime.log.Log; /** * Abstract class that is used to execute an arbitrary * method that is in introspected. This is the superclass * for the PutExecutor and SetPropertyExecutor. * * There really should be a superclass for this and AbstractExecutor (which should * be refactored to GetExecutor) because they differ only in the execute() method. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: SetExecutor.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public abstract class SetExecutor { /** Class logger */ protected Log log = null; /** * Method to be executed. */ private Method method = null; /** * Execute method against context. * @param o * @param value * @return The result of the invocation. * @throws IllegalAccessException * @throws InvocationTargetException */ public abstract Object execute(Object o, Object value) throws IllegalAccessException, InvocationTargetException; /** * Tell whether the executor is alive by looking * at the value of the method. * @return True if the executor is alive. */ public boolean isAlive() { return (method != null); } /** * @return The method to invoke. */ public Method getMethod() { return method; } /** * @param method */ protected void setMethod(final Method method) { this.method = method; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTParameters.java0000644000175000017500000000271110575440066027707 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTParameters extends SimpleNode { /** * @param id */ public ASTParameters(int id) { super(id); } /** * @param p * @param id */ public ASTParameters(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTLENode.java0000644000175000017500000001064211124067071026704 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 <= arg2

      * * Only subclasses of Number can be compared.

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski */ public class ASTLENode extends SimpleNode { /** * @param id */ public ASTLENode(int id) { super(id); } /** * @param p * @param id */ public ASTLENode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { /* * get the two args */ Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * if either is null, lets log and bail */ if (left == null || right == null) { String msg = (left == null ? "Left" : "Right") + " side (" + jjtGetChild( (left == null? 0 : 1) ).literal() + ") of '<=' operation has null value at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * Only compare Numbers */ if ( !( left instanceof Number ) || !( right instanceof Number )) { String msg = (!(left instanceof Number) ? "Left" : "Right") + " side of '>=' operation is not a Number at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } return MathUtils.compare ( (Number)left,(Number)right) <= 0; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { boolean val = evaluate(context); return val ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTNotNode.java0000644000175000017500000000436510575440066027161 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTNotNode extends SimpleNode { /** * @param id */ public ASTNotNode(int id) { super(id); } /** * @param p * @param id */ public ASTNotNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { if (jjtGetChild(0).evaluate(context)) return false; else return true; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) throws MethodInvocationException { return (jjtGetChild(0).evaluate( context ) ? Boolean.FALSE : Boolean.TRUE) ; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/SetPropertyExecutor.java0000644000175000017500000001015311052641200031232 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.util.introspection.Introspector; /** * Executor for looking up property names in the passed in class * This will try to find a set<foo>(key, value) method * * @author Henning P. Schmiedehausen * @version $Id: SetPropertyExecutor.java 687177 2008-08-19 22:00:32Z nbubna $ * @since 1.5 */ public class SetPropertyExecutor extends SetExecutor { private final Introspector introspector; /** * @param log * @param introspector * @param clazz * @param property * @param arg */ public SetPropertyExecutor(final Log log, final Introspector introspector, final Class clazz, final String property, final Object arg) { this.log = log; this.introspector = introspector; // Don't allow passing in the empty string or null because // it will either fail with a StringIndexOutOfBounds error // or the introspector will get confused. if (StringUtils.isNotEmpty(property)) { discover(clazz, property, arg); } } /** * @return The current introspector. */ protected Introspector getIntrospector() { return this.introspector; } /** * @param clazz * @param property * @param arg */ protected void discover(final Class clazz, final String property, final Object arg) { Object [] params = new Object [] { arg }; try { StrBuilder sb = new StrBuilder("set"); sb.append(property); setMethod(introspector.getMethod(clazz, sb.toString(), params)); if (!isAlive()) { /* * now the convenience, flip the 1st character */ char c = sb.charAt(3); if (Character.isLowerCase(c)) { sb.setCharAt(3, Character.toUpperCase(c)); } else { sb.setCharAt(3, Character.toLowerCase(c)); } setMethod(introspector.getMethod(clazz, sb.toString(), params)); } } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for property setter for '" + property; log.error(msg, e); throw new VelocityException(msg, e); } } /** * Execute method against context. * @param o * @param value * @return The value of the invocation. * @throws IllegalAccessException * @throws InvocationTargetException */ public Object execute(final Object o, final Object value) throws IllegalAccessException, InvocationTargetException { Object [] params = new Object [] { value }; return isAlive() ? getMethod().invoke(o, params) : null; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTAssignment.java0000644000175000017500000000271010575440066027713 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTAssignment extends SimpleNode { /** * @param id */ public ASTAssignment(int id) { super(id); } /** * @param p * @param id */ public ASTAssignment(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTAndNode.java0000644000175000017500000000632511052643107027111 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTAndNode.java 687184 2008-08-19 22:16:39Z nbubna $ */ public class ASTAndNode extends SimpleNode { /** * @param id */ public ASTAndNode(int id) { super(id); } /** * @param p * @param id */ public ASTAndNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Returns the value of the expression. * Since the value of the expression is simply the boolean * result of evaluate(), lets return that. * @param context * @return The value of the expression. * @throws MethodInvocationException */ public Object value(InternalContextAdapter context) throws MethodInvocationException { // TODO: JDK 1.4+ -> valueOf() // return new Boolean(evaluate(context)); return evaluate(context) ? Boolean.TRUE : Boolean.FALSE; } /** * logical and : * null && right = false * left && null = false * null && null = false * @param context * @return True if both sides are true. * @throws MethodInvocationException */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { Node left = jjtGetChild(0); Node right = jjtGetChild(1); /* * null == false */ if (left == null || right == null) { return false; } /* * short circuit the test. Don't eval the RHS if the LHS is false */ if( left.evaluate( context ) ) { if ( right.evaluate( context ) ) { return true; } } return false; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIncludeStatement.java0000644000175000017500000000273310575440066031060 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTIncludeStatement extends SimpleNode { /** * @param id */ public ASTIncludeStatement(int id) { super(id); } /** * @param p * @param id */ public ASTIncludeStatement(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTNENode.java0000644000175000017500000001151111057047743026713 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 != arg2 * * This operator requires that the LHS and RHS are both of the * same Class OR both are subclasses of java.lang.Number * * @author Will Glass-Husain * @author Peter Romianowski */ public class ASTNENode extends SimpleNode { /** * @param id */ public ASTNENode(int id) { super(id); } /** * @param p * @param id */ public ASTNENode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * If comparing Numbers we do not care about the Class. */ if (left instanceof Number && right instanceof Number) { return MathUtils.compare ( (Number)left,(Number)right) != 0; } /** * if both are not null, then assume that if one class * is a subclass of the other that we should use the equals operator */ if (left != null && right != null && (left.getClass().isAssignableFrom(right.getClass()) || right.getClass().isAssignableFrom(left.getClass()))) { return !left.equals( right ); } /* * Ok, time to compare string values */ left = (left == null) ? null : left.toString(); right = (right == null) ? null: right.toString(); if (left == null && right == null) { if (log.isDebugEnabled()) { log.debug("Both right (" + getLiteral(false) + " and left " + getLiteral(true) + " sides of '!=' operation returned null." + "If references, they may not be in the context." + getLocation(context)); } return false; } else if (left == null || right == null) { if (log.isDebugEnabled()) { log.debug((left == null ? "Left" : "Right") + " side (" + getLiteral(left == null) + ") of '!=' operation has null value. If it is a " + "reference, it may not be in the context or its " + "toString() returned null. " + getLocation(context)); } return true; } else { return !left.equals(right); } } private String getLiteral(boolean left) { return jjtGetChild(left ? 0 : 1).literal(); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { boolean val = evaluate(context); return val ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/AbstractExecutor.java0000644000175000017500000000443311050652577030522 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.velocity.runtime.log.Log; /** * Abstract class that is used to execute an arbitrary * method that is in introspected. This is the superclass * for the GetExecutor and PropertyExecutor. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: AbstractExecutor.java 685685 2008-08-13 21:43:27Z nbubna $ */ public abstract class AbstractExecutor { /** */ protected Log log = null; /** * Method to be executed. */ private Method method = null; /** * Execute method against context. * @param o * @return The resulting object. * @throws IllegalAccessException * @throws InvocationTargetException */ public abstract Object execute(Object o) throws IllegalAccessException, InvocationTargetException; /** * Tell whether the executor is alive by looking * at the value of the method. * * @return True if executor is alive. */ public boolean isAlive() { return (method != null); } /** * @return The current method. */ public Method getMethod() { return method; } /** * @param method * @since 1.5 */ protected void setMethod(final Method method) { this.method = method; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTWord.java0000644000175000017500000000266610575440066026530 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTWord extends SimpleNode { /** * @param id */ public ASTWord(int id) { super(id); } /** * @param p * @param id */ public ASTWord(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTEQNode.java0000644000175000017500000001256711057047743026732 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 == arg2 * * This operator requires that the LHS and RHS are both of the * same Class OR both are subclasses of java.lang.Number * * @author Will Glass-Husain * @author Peter Romianowski * @version $Id: ASTEQNode.java 691048 2008-09-01 20:26:11Z nbubna $ */ public class ASTEQNode extends SimpleNode { /** * @param id */ public ASTEQNode(int id) { super(id); } /** * @param p * @param id */ public ASTEQNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Calculates the value of the logical expression * * arg1 == arg2 * * All class types are supported. Uses equals() to * determine equivalence. This should work as we represent * with the types we already support, and anything else that * implements equals() to mean more than identical references. * * * @param context internal context used to evaluate the LHS and RHS * @return true if equivalent, false if not equivalent, * false if not compatible arguments, or false * if either LHS or RHS is null * @throws MethodInvocationException */ public boolean evaluate(InternalContextAdapter context) throws MethodInvocationException { Object left = jjtGetChild(0).value(context); Object right = jjtGetChild(1).value(context); /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * If comparing Numbers we do not care about the Class. */ if (left instanceof Number && right instanceof Number) { return MathUtils.compare( (Number)left, (Number)right) == 0; } /** * if both are not null, then assume that if one class * is a subclass of the other that we should use the equals operator */ if (left != null && right != null && (left.getClass().isAssignableFrom(right.getClass()) || right.getClass().isAssignableFrom(left.getClass()))) { return left.equals( right ); } /* * Ok, time to compare string values */ left = (left == null) ? null : left.toString(); right = (right == null) ? null: right.toString(); if (left == null && right == null) { if (log.isDebugEnabled()) { log.debug("Both right (" + getLiteral(false) + " and left " + getLiteral(true) + " sides of '==' operation returned null." + "If references, they may not be in the context." + getLocation(context)); } return true; } else if (left == null || right == null) { if (log.isDebugEnabled()) { log.debug((left == null ? "Left" : "Right") + " side (" + getLiteral(left == null) + ") of '==' operation has null value. If it is a " + "reference, it may not be in the context or its " + "toString() returned null. " + getLocation(context)); } return false; } else { return left.equals(right); } } private String getLiteral(boolean left) { return jjtGetChild(left ? 0 : 1).literal(); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { return evaluate(context) ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/Node.java0000644000175000017500000001275711137120115026115 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.parser.Token; /** * This file describes the interface between the Velocity code * and the JavaCC generated code. * * @author Henning P. Schmiedehausen * @version $Id: Node.java 737539 2009-01-25 17:24:29Z nbubna $ */ public interface Node extends Renderable { /** This method is called after the node has been made the current * node. It indicates that child nodes can now be added to it. */ public void jjtOpen(); /** This method is called after all the child nodes have been added. */ public void jjtClose(); /** * This pair of methods are used to inform the node of its * parent. * @param n * */ public void jjtSetParent(Node n); /** * @return The node parent. */ public Node jjtGetParent(); /** * This method tells the node to add its argument to the node's * list of children. * @param n * @param i */ public void jjtAddChild(Node n, int i); /** * This method returns a child node. The children are numbered * from zero, left to right. * @param i * @return A child node. */ public Node jjtGetChild(int i); /** * Return the number of children the node has. * @return The number of children of this node. */ public int jjtGetNumChildren(); /** * @param visitor * @param data * @return The Node execution result object. */ public Object jjtAccept(ParserVisitor visitor, Object data); /* * ======================================================================== * * The following methods are not generated automatically be the Parser but * added manually to be used by Velocity. * * ======================================================================== */ /** * @see #jjtAccept(ParserVisitor, Object) * @param visitor * @param data * @return The node execution result. */ public Object childrenAccept(ParserVisitor visitor, Object data); /** * @return The first token. */ public Token getFirstToken(); /** * @return The last token. */ public Token getLastToken(); /** * @return The NodeType. */ public int getType(); /** * @param context * @param data * @return The init result. * @throws TemplateInitException */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException; /** * @param context * @return The evaluation result. * @throws MethodInvocationException */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException; /** * @param context * @return The node value. * @throws MethodInvocationException */ public Object value( InternalContextAdapter context) throws MethodInvocationException; /** * @param context * @param writer * @return True if the node rendered successfully. * @throws IOException * @throws MethodInvocationException * @throws ParseErrorException * @throws ResourceNotFoundException */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException,MethodInvocationException, ParseErrorException, ResourceNotFoundException; /** * @param o * @param context * @return The execution result. * @throws MethodInvocationException */ public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException; /** * @param info */ public void setInfo(int info); /** * @return The current node info. */ public int getInfo(); /** * @return A literal. */ public String literal(); /** * Mark the node as invalid. */ public void setInvalid(); /** * @return True if the node is invalid. */ public boolean isInvalid(); /** * @return The current line position. */ public int getLine(); /** * @return The current column position. */ public int getColumn(); /** * @return the file name of the template */ public String getTemplateName(); } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTElseStatement.java0000644000175000017500000000421610575440066030363 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * This class is responsible for handling the Else VTL control statement. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTElseStatement.java 517553 2007-03-13 06:09:58Z wglass $ */ public class ASTElseStatement extends SimpleNode { /** * @param id */ public ASTElseStatement(int id) { super(id); } /** * @param p * @param id */ public ASTElseStatement(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * An ASTElseStatement always evaluates to * true. Basically behaves like an #if(true). * @param context * @return Always true. */ public boolean evaluate( InternalContextAdapter context) { return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTMap.java0000644000175000017500000000501311353722777026326 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.util.LinkedHashMap; import java.util.Map; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * AST Node for creating a map / dictionary. * * This class was originally generated from Parset.jjt. * * @version $Id: ASTMap.java 928475 2010-03-28 18:54:55Z nbubna $ * @since 1.5 */ public class ASTMap extends SimpleNode { /** * @param id */ public ASTMap(int id) { super(id); } /** * @param p * @param id */ public ASTMap(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { int size = jjtGetNumChildren(); Map objectMap = new LinkedHashMap(); for (int i = 0; i < size; i += 2) { SimpleNode keyNode = (SimpleNode) jjtGetChild(i); SimpleNode valueNode = (SimpleNode) jjtGetChild(i+1); Object key = (keyNode == null ? null : keyNode.value(context)); Object value = (valueNode == null ? null : valueNode.value(context)); objectMap.put(key, value); } return objectMap; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java0000644000175000017500000002006611136111426027512 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.RuntimeMacro; import org.apache.velocity.runtime.directive.BlockMacro; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.ExceptionUtils; /** * This class is responsible for handling the pluggable * directives in VTL. * * For example : #foreach() * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Kasper Nielsen * @version $Id: ASTDirective.java 736677 2009-01-22 15:39:02Z nbubna $ */ public class ASTDirective extends SimpleNode { private Directive directive = null; private String directiveName = ""; private boolean isDirective; private boolean isInitialized; /** * @param id */ public ASTDirective(int id) { super(id); } /** * @param p * @param id */ public ASTDirective(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public synchronized Object init( InternalContextAdapter context, Object data) throws TemplateInitException { /** method is synchronized to avoid concurrent directive initialization **/ if (!isInitialized) { super.init( context, data ); /* * only do things that are not context dependent */ if (parser.isDirective( directiveName )) { isDirective = true; try { directive = (Directive) parser.getDirective( directiveName ) .getClass().newInstance(); } catch (InstantiationException e) { throw ExceptionUtils.createRuntimeException("Couldn't initialize " + "directive of class " + parser.getDirective(directiveName).getClass().getName(), e); } catch (IllegalAccessException e) { throw ExceptionUtils.createRuntimeException("Couldn't initialize " + "directive of class " + parser.getDirective(directiveName).getClass().getName(), e); } directive.setLocation(getLine(), getColumn(), getTemplateName()); directive.init(rsvc, context,this); } else if( directiveName.startsWith("@") ) { if( this.jjtGetNumChildren() > 0 ) { // block macro call (normal macro call but has AST body) directiveName = directiveName.substring(1); directive = new BlockMacro(directiveName); directive.setLocation(getLine(), getColumn(), getTemplateName()); try { directive.init( rsvc, context, this ); } catch (TemplateInitException die) { throw new TemplateInitException(die.getMessage(), (ParseException) die.getWrappedThrowable(), die.getTemplateName(), die.getColumnNumber() + getColumn(), die.getLineNumber() + getLine()); } isDirective = true; } else { // this is a fake block macro call without a body. e.g. #@foo // just render as it is isDirective = false; } } else { /** * Create a new RuntimeMacro */ directive = new RuntimeMacro(directiveName); directive.setLocation(getLine(), getColumn(), getTemplateName()); /** * Initialize it */ try { directive.init( rsvc, context, this ); } /** * correct the line/column number if an exception is caught */ catch (TemplateInitException die) { throw new TemplateInitException(die.getMessage(), (ParseException) die.getWrappedThrowable(), die.getTemplateName(), die.getColumnNumber() + getColumn(), die.getLineNumber() + getLine()); } isDirective = true; } isInitialized = true; } return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException,MethodInvocationException, ResourceNotFoundException, ParseErrorException { /* * normal processing */ if (isDirective) { directive.render(context, writer, this); } else { writer.write( "#"); writer.write( directiveName ); } return true; } /** * Sets the directive name. Used by the parser. This keeps us from having to * dig it out of the token stream and gives the parse the change to override. * @param str */ public void setDirectiveName( String str ) { directiveName = str; } /** * Gets the name of this directive. * @return The name of this directive. */ public String getDirectiveName() { return directiveName; } /** * @since 1.5 */ public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) .append("directiveName", getDirectiveName()) .toString(); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTTrue.java0000644000175000017500000000376110575440066026531 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTTrue extends SimpleNode { private static Boolean value = Boolean.TRUE; /** * @param id */ public ASTTrue(int id) { super(id); } /** * @param p * @param id */ public ASTTrue(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate(InternalContextAdapter context) { return true; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) { return value; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTMethod.java0000644000175000017500000002611311322700447027017 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.directive.StopCommand; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.ClassUtils; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.VelMethod; /** * ASTMethod.java * * Method support for references : $foo.method() * * NOTE : * * introspection is now done at render time. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTMethod.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class ASTMethod extends SimpleNode { private String methodName = ""; private int paramCount = 0; protected Info uberInfo; /** * Indicates if we are running in strict reference mode. */ protected boolean strictRef = false; /** * @param id */ public ASTMethod(int id) { super(id); } /** * @param p * @param id */ public ASTMethod(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * simple init - init our subtree and get what we can from * the AST * @param context * @param data * @return The init result * @throws TemplateInitException */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { super.init( context, data ); /* * make an uberinfo - saves new's later on */ uberInfo = new Info(getTemplateName(), getLine(),getColumn()); /* * this is about all we can do */ methodName = getFirstToken().image; paramCount = jjtGetNumChildren() - 1; strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); return data; } /** * invokes the method. Returns null if a problem, the * actual return if the method returns something, or * an empty string "" if the method returns void * @param o * @param context * @return Result or null. * @throws MethodInvocationException */ public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { /* * new strategy (strategery!) for introspection. Since we want * to be thread- as well as context-safe, we *must* do it now, * at execution time. There can be no in-node caching, * but if we are careful, we can do it in the context. */ Object [] params = new Object[paramCount]; /* * sadly, we do need recalc the values of the args, as this can * change from visit to visit */ final Class[] paramClasses = paramCount > 0 ? new Class[paramCount] : ArrayUtils.EMPTY_CLASS_ARRAY; for (int j = 0; j < paramCount; j++) { params[j] = jjtGetChild(j + 1).value(context); if (params[j] != null) { paramClasses[j] = params[j].getClass(); } } VelMethod method = ClassUtils.getMethod(methodName, params, paramClasses, o, context, this, strictRef); if (method == null) return null; try { /* * get the returned object. It may be null, and that is * valid for something declared with a void return type. * Since the caller is expecting something to be returned, * as long as things are peachy, we can return an empty * String so ASTReference() correctly figures out that * all is well. */ Object obj = method.invoke(o, params); if (obj == null) { if( method.getReturnType() == Void.TYPE) { return ""; } } return obj; } catch( InvocationTargetException ite ) { return handleInvocationException(o, context, ite.getTargetException()); } /** Can also be thrown by method invocation **/ catch( IllegalArgumentException t ) { return handleInvocationException(o, context, t); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch( Exception e ) { String msg = "ASTMethod.execute() : exception invoking method '" + methodName + "' in " + o.getClass(); log.error(msg, e); throw new VelocityException(msg, e); } } private Object handleInvocationException(Object o, InternalContextAdapter context, Throwable t) { /* * We let StopCommands go up to the directive they are for/from */ if (t instanceof StopCommand) { throw (StopCommand)t; } /* * In the event that the invocation of the method * itself throws an exception, we want to catch that * wrap it, and throw. We don't log here as we want to figure * out which reference threw the exception, so do that * above */ else if (t instanceof Exception) { try { return EventHandlerUtil.methodException( rsvc, context, o.getClass(), methodName, (Exception) t ); } /** * If the event handler throws an exception, then wrap it * in a MethodInvocationException. Don't pass through RuntimeExceptions like other * similar catchall code blocks. */ catch( Exception e ) { throw new MethodInvocationException( "Invocation of method '" + methodName + "' in " + o.getClass() + " threw exception " + e.toString(), e, methodName, getTemplateName(), this.getLine(), this.getColumn()); } } /* * let non-Exception Throwables go... */ else { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException( "Invocation of method '" + methodName + "' in " + o.getClass() + " threw exception " + t.toString(), t, methodName, getTemplateName(), this.getLine(), this.getColumn()); } } /** * Internal class used as key for method cache. Combines * ASTMethod fields with array of parameter classes. Has * public access (and complete constructor) for unit test * purposes. * @since 1.5 */ public static class MethodCacheKey { private final String methodName; private final Class[] params; public MethodCacheKey(String methodName, Class[] params) { /** * Should never be initialized with nulls, but to be safe we refuse * to accept them. */ this.methodName = (methodName != null) ? methodName : StringUtils.EMPTY; this.params = (params != null) ? params : ArrayUtils.EMPTY_CLASS_ARRAY; } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object o) { /** * note we skip the null test for methodName and params * due to the earlier test in the constructor */ if (o instanceof MethodCacheKey) { final MethodCacheKey other = (MethodCacheKey) o; if (params.length == other.params.length && methodName.equals(other.methodName)) { for (int i = 0; i < params.length; ++i) { if (params[i] == null) { if (params[i] != other.params[i]) { return false; } } else if (!params[i].equals(other.params[i])) { return false; } } return true; } } return false; } /** * @see java.lang.Object#hashCode() */ public int hashCode() { int result = 17; /** * note we skip the null test for methodName and params * due to the earlier test in the constructor */ for (int i = 0; i < params.length; ++i) { final Class param = params[i]; if (param != null) { result = result * 37 + param.hashCode(); } } result = result * 37 + methodName.hashCode(); return result; } } /** * @return Returns the methodName. * @since 1.5 */ public String getMethodName() { return methodName; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIdentifier.java0000644000175000017500000002062511131055646027665 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.IntrospectionCacheData; import org.apache.velocity.util.introspection.VelPropertyGet; /** * ASTIdentifier.java * * Method support for identifiers : $foo * * mainly used by ASTRefrence * * Introspection is now moved to 'just in time' or at render / execution * time. There are many reasons why this has to be done, but the * primary two are thread safety, to remove any context-derived * information from class member variables. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTIdentifier.java 732250 2009-01-07 07:37:10Z byron $ */ public class ASTIdentifier extends SimpleNode { private String identifier = ""; /** * This is really immutable after the init, so keep one for this node */ protected Info uberInfo; /** * Indicates if we are running in strict reference mode. */ protected boolean strictRef = false; /** * @param id */ public ASTIdentifier(int id) { super(id); } /** * @param p * @param id */ public ASTIdentifier(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * simple init - don't do anything that is context specific. * just get what we need from the AST, which is static. * @param context * @param data * @return The data object. * @throws TemplateInitException */ public Object init(InternalContextAdapter context, Object data) throws TemplateInitException { super.init(context, data); identifier = getFirstToken().image.intern(); uberInfo = new Info(getTemplateName(), getLine(), getColumn()); strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter) */ public Object execute(Object o, InternalContextAdapter context) throws MethodInvocationException { VelPropertyGet vg = null; try { /* * first, see if we have this information cached. */ IntrospectionCacheData icd = context.icacheGet(this); /* * if we have the cache data and the class of the object we are * invoked with is the same as that in the cache, then we must * be allright. The last 'variable' is the method name, and * that is fixed in the template :) */ if ( icd != null && (o != null) && (icd.contextData == o.getClass()) ) { vg = (VelPropertyGet) icd.thingy; } else { /* * otherwise, do the introspection, and cache it. Use the * uberspector */ vg = rsvc.getUberspect().getPropertyGet(o,identifier, uberInfo); if (vg != null && vg.isCacheable() && (o != null)) { icd = new IntrospectionCacheData(); icd.contextData = o.getClass(); icd.thingy = vg; context.icachePut(this,icd); } } } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "ASTIdentifier.execute() : identifier = "+identifier; log.error(msg, e); throw new VelocityException(msg, e); } /* * we have no getter... punt... */ if (vg == null) { if (strictRef) { throw new MethodInvocationException("Object '" + o.getClass().getName() + "' does not contain property '" + identifier + "'", null, identifier, uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn()); } else { return null; } } /* * now try and execute. If we get a MIE, throw that * as the app wants to get these. If not, log and punt. */ try { return vg.invoke(o); } catch(InvocationTargetException ite) { /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ Throwable t = ite.getTargetException(); if (t instanceof Exception) { try { return EventHandlerUtil.methodException(rsvc, context, o.getClass(), vg.getMethodName(), (Exception) t); } /** * If the event handler throws an exception, then wrap it * in a MethodInvocationException. Don't pass through RuntimeExceptions like other * similar catchall code blocks. */ catch( Exception e ) { throw new MethodInvocationException( "Invocation of method '" + vg.getMethodName() + "'" + " in " + o.getClass() + " threw exception " + ite.getTargetException().toString(), ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); } } else { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException( "Invocation of method '" + vg.getMethodName() + "'" + " in " + o.getClass() + " threw exception " + ite.getTargetException().toString(), ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn()); } } catch(IllegalArgumentException iae) { return null; } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "ASTIdentifier() : exception invoking method " + "for identifier '" + identifier + "' in " + o.getClass(); log.error(msg, e); throw new VelocityException(msg, e); } } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java0000644000175000017500000000732010575440066030030 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ /** * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTIfStatement.java 517553 2007-03-13 06:09:58Z wglass $ */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTIfStatement extends SimpleNode { /** * @param id */ public ASTIfStatement(int id) { super(id); } /** * @param p * @param id */ public ASTIfStatement(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException,MethodInvocationException, ResourceNotFoundException, ParseErrorException { /* * Check if the #if(expression) construct evaluates to true: * if so render and leave immediately because there * is nothing left to do! */ if (jjtGetChild(0).evaluate(context)) { jjtGetChild(1).render(context, writer); return true; } int totalNodes = jjtGetNumChildren(); /* * Now check the remaining nodes left in the * if construct. The nodes are either elseif * nodes or else nodes. Each of these node * types knows how to evaluate themselves. If * a node evaluates to true then the node will * render itself and this method will return * as there is nothing left to do. */ for (int i = 2; i < totalNodes; i++) { if (jjtGetChild(i).evaluate(context)) { jjtGetChild(i).render(context, writer); return true; } } /* * This is reached when an ASTIfStatement * consists of an if/elseif sequence where * none of the nodes evaluate to true. */ return true; } /** * @param context * @param visitor */ public void process( InternalContextAdapter context, ParserVisitor visitor) { } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTText.java0000644000175000017500000000462111130460676026527 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; /** * */ public class ASTText extends SimpleNode { private char[] ctext; /** * @param id */ public ASTText(int id) { super(id); } /** * @param p * @param id */ public ASTText(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object) */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { Token t = getFirstToken(); String text = NodeUtils.tokenLiteral( t ); ctext = text.toCharArray(); return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException { writer.write(ctext); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTModNode.java0000644000175000017500000000446311057047743027140 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MathException; import org.apache.velocity.runtime.parser.Parser; /** * Handles modulus division

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Geir Magnusson Jr. * @version $Id: ASTModNode.java 691048 2008-09-01 20:26:11Z nbubna $ */ public class ASTModNode extends ASTMathNode { /** * @param id */ public ASTModNode(int id) { super(id); } /** * @param p * @param id */ public ASTModNode(Parser p, int id) { super(p, id); } public Number perform(Number left, Number right, InternalContextAdapter context) { /* * check for divide / modulo by 0 */ if (MathUtils.isZero(right)) { String msg = "Right side of modulus operation is zero. Must be non-zero. " + getLocation(context); if (strictMode) { log.error(msg); throw new MathException(msg); } else { log.debug(msg); return null; } } return MathUtils.modulo(left, right); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTVariable.java0000644000175000017500000000270310575440066027332 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTVariable extends SimpleNode { /** * @param id */ public ASTVariable(int id) { super(id); } /** * @param p * @param id */ public ASTVariable(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTOrNode.java0000644000175000017500000000626011050417203026757 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.runtime.parser.Parser; /** * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTOrNode.java 685370 2008-08-12 23:36:35Z nbubna $ */ public class ASTOrNode extends SimpleNode { /** * @param id */ public ASTOrNode(int id) { super(id); } /** * @param p * @param id */ public ASTOrNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Returns the value of the expression. * Since the value of the expression is simply the boolean * result of evaluate(), lets return that. * @param context * @return The Expression value. * @throws MethodInvocationException */ public Object value(InternalContextAdapter context ) throws MethodInvocationException { // TODO: JDK 1.4+ -> valueOf() // return new Boolean(evaluate(context)); return evaluate(context) ? Boolean.TRUE : Boolean.FALSE; } /** * the logical or : * the rule : * left || null -> left * null || right -> right * null || null -> false * left || right -> left || right * @param context * @return The evaluation result. * @throws MethodInvocationException */ public boolean evaluate( InternalContextAdapter context) throws MethodInvocationException { Node left = jjtGetChild(0); Node right = jjtGetChild(1); /* * if the left is not null and true, then true */ if (left != null && left.evaluate( context ) ) return true; /* * same for right */ if ( right != null && right.evaluate( context ) ) return true; return false; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTFalse.java0000644000175000017500000000377010575440066026644 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * */ public class ASTFalse extends SimpleNode { private static Boolean value = Boolean.FALSE; /** * @param id */ public ASTFalse(int id) { super(id); } /** * @param p * @param id */ public ASTFalse(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate( InternalContextAdapter context) { return false; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) { return value; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTFloatingPointLiteral.java0000644000175000017500000000572611050652577031710 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.math.BigDecimal; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.parser.Parser; /** * Handles floating point numbers. The value will be either a Double * or a BigDecimal. * * @author Will Glass-Husain * @since 1.5 */ public class ASTFloatingPointLiteral extends SimpleNode { // This may be of type Double or BigDecimal private Number value = null; /** * @param id */ public ASTFloatingPointLiteral(int id) { super(id); } /** * @param p * @param id */ public ASTFloatingPointLiteral(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Initialization method - doesn't do much but do the object * creation. We only need to do it once. * @param context * @param data * @return The data object. * @throws TemplateInitException */ public Object init( InternalContextAdapter context, Object data) throws TemplateInitException { /* * init the tree correctly */ super.init( context, data ); /** * Determine the size of the item and make it a Double or BigDecimal as appropriate. */ String str = getFirstToken().image; try { value = new Double( str ); } catch ( NumberFormatException E1 ) { // if there's still an Exception it will propogate out value = new BigDecimal( str ); } return data; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value( InternalContextAdapter context) { return value; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java0000644000175000017500000001646011112556471030200 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.introspection.Info; /** * Node for the #set directive * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTSetDirective.java 720228 2008-11-24 16:58:33Z nbubna $ */ public class ASTSetDirective extends SimpleNode { private String leftReference = ""; private Node right = null; private ASTReference left = null; boolean logOnNull = false; private boolean allowNull = false; private boolean isInitialized; /** * This is really immutable after the init, so keep one for this node */ protected Info uberInfo; /** * Indicates if we are running in strict reference mode. */ protected boolean strictRef = false; /** * @param id */ public ASTSetDirective(int id) { super(id); } /** * @param p * @param id */ public ASTSetDirective(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * simple init. We can get the RHS and LHS as the the tree structure is static * @param context * @param data * @return Init result. * @throws TemplateInitException */ public synchronized Object init(InternalContextAdapter context, Object data) throws TemplateInitException { /** This method is synchronized to prevent double initialization or initialization while rendering **/ if (!isInitialized) { /* * init the tree correctly */ super.init( context, data ); uberInfo = new Info(getTemplateName(), getLine(), getColumn()); right = getRightHandSide(); left = getLeftHandSide(); logOnNull = rsvc.getBoolean(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID, true); allowNull = rsvc.getBoolean(RuntimeConstants.SET_NULL_ALLOWED, false); strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); if (strictRef) allowNull = true; // strictRef implies allowNull /* * grab this now. No need to redo each time */ leftReference = left.getFirstToken().image.substring(1); isInitialized = true; } return data; } /** * puts the value of the RHS into the context under the key of the LHS * @param context * @param writer * @return True if rendering was sucessful. * @throws IOException * @throws MethodInvocationException */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException, MethodInvocationException { /* * get the RHS node, and its value */ Object value = right.value(context); /* * it's an error if we don't have a value of some sort AND * it is not allowed by configuration */ if( !allowNull ) { if ( value == null ) { /* * first, are we supposed to say anything anyway? */ if(logOnNull) { boolean doit = EventHandlerUtil.shouldLogOnNullSet( rsvc, context, left.literal(), right.literal() ); if (doit && rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug("RHS of #set statement is null. Context will not be modified. " + Log.formatFileString(this)); } } String rightReference = null; if (right instanceof ASTExpression) { rightReference = ((ASTExpression) right).getLastToken().image; } EventHandlerUtil.invalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo); return false; } } if ( value == null && !strictRef) { String rightReference = null; if (right instanceof ASTExpression) { rightReference = ((ASTExpression) right).getLastToken().image; } EventHandlerUtil.invalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo); /* * if RHS is null, remove simple LHS from context * or call setValue() with a null value for complex LHS */ if (left.jjtGetNumChildren() == 0) { context.remove( leftReference ); } else { left.setValue(context, null); } return false; } else { /* * if the LHS is simple, just punch the value into the context * otherwise, use the setValue() method do to it. * Maybe we should always use setValue() */ if (left.jjtGetNumChildren() == 0) { context.put( leftReference, value); } else { left.setValue(context, value); } } return true; } /** * returns the ASTReference that is the LHS of the set statememt * * @return left hand side of #set statement */ private ASTReference getLeftHandSide() { return (ASTReference) jjtGetChild(0); } /** * returns the RHS Node of the set statement * * @return right hand side of #set statement */ private Node getRightHandSide() { return jjtGetChild(1); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTElseIfStatement.java0000644000175000017500000000612610575440066030644 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.parser.Parser; /** * This class is responsible for handling the ElseIf VTL control statement. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTElseIfStatement.java 517553 2007-03-13 06:09:58Z wglass $ */ public class ASTElseIfStatement extends SimpleNode { /** * @param id */ public ASTElseIfStatement(int id) { super(id); } /** * @param p * @param id */ public ASTElseIfStatement(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * An ASTElseStatement is true if the expression * it contains evaluates to true. Expressions know * how to evaluate themselves, so we do that * here and return the value back to ASTIfStatement * where this node was originally asked to evaluate * itself. * @param context * @return True if all childs are true. * @throws MethodInvocationException */ public boolean evaluate ( InternalContextAdapter context) throws MethodInvocationException { return jjtGetChild(0).evaluate(context); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer) */ public boolean render( InternalContextAdapter context, Writer writer) throws IOException,MethodInvocationException, ResourceNotFoundException, ParseErrorException { return jjtGetChild(1).render( context, writer ); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTSubtractNode.java0000644000175000017500000000357011057047743030206 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.Parser; /** * Handles subtraction of nodes (in #set() )

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ASTSubtractNode.java 691048 2008-09-01 20:26:11Z nbubna $ */ public class ASTSubtractNode extends ASTMathNode { /** * @param id */ public ASTSubtractNode(int id) { super(id); } /** * @param p * @param id */ public ASTSubtractNode(Parser p, int id) { super(p, id); } public Number perform(Number left, Number right, InternalContextAdapter context) { return MathUtils.subtract(left, right); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/MathUtils.java0000644000175000017500000003727611050652577027165 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.math.BigDecimal; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; import java.util.List; import java.util.ArrayList; /** * Utility-class for all arithmetic-operations.

      * * All operations (+ - / *) return a Number which type is the type of the bigger argument.
      * Example:
      * add ( new Integer(10), new Integer(1)) will return an Integer-Object with the value 11
      * add ( new Long(10), new Integer(1)) will return an Long-Object with the value 11
      * add ( new Integer(10), new Float(1)) will return an Float-Object with the value 11

      * * Overflow checking:
      * For integral values (byte, short, int) there is an implicit overflow correction (the next "bigger" * type will be returned). For example, if you call add (new Integer (Integer.MAX_VALUE), 1) a * Long-object will be returned with the correct value of Integer.MAX_VALUE+1.
      * In addition to that the methods multiply,add and substract implement overflow * checks for long-values. That means that if an overflow occurs while working with long values a BigInteger * will be returned.
      * For all other operations and types (such as Float and Double) there is no overflow checking. * * @author Peter Romianowski * @since 1.5 */ public abstract class MathUtils { /** * A BigDecimal representing the number 0 */ protected static final BigDecimal DECIMAL_ZERO = new BigDecimal ( BigInteger.ZERO ); /** * The constants are used to determine in which context we have to calculate. */ protected static final int BASE_LONG = 0; protected static final int BASE_FLOAT = 1; protected static final int BASE_DOUBLE = 2; protected static final int BASE_BIGINTEGER = 3; protected static final int BASE_BIGDECIMAL = 4; /** * The Class-object is key, the maximum-value is the value */ protected static final Map ints = new HashMap(); static { ints.put (Byte.class, BigDecimal.valueOf (Byte.MAX_VALUE)); ints.put (Short.class, BigDecimal.valueOf (Short.MAX_VALUE)); ints.put (Integer.class, BigDecimal.valueOf (Integer.MAX_VALUE)); ints.put (Long.class, BigDecimal.valueOf (Long.MAX_VALUE)); ints.put (BigInteger.class, BigDecimal.valueOf (-1)); } /** * The "size" of the number-types - ascending. */ protected static final List typesBySize = new ArrayList(); static { typesBySize.add (Byte.class); typesBySize.add (Short.class); typesBySize.add (Integer.class); typesBySize.add (Long.class); typesBySize.add (Float.class); typesBySize.add (Double.class); } /** * Convert the given Number to a BigDecimal * @param n * @return The number as BigDecimal */ public static BigDecimal toBigDecimal (Number n) { if (n instanceof BigDecimal) { return (BigDecimal)n; } if (n instanceof BigInteger) { return new BigDecimal ( (BigInteger)n ); } return new BigDecimal (n.doubleValue()); } /** * Convert the given Number to a BigInteger * @param n * @return The number as BigInteger */ public static BigInteger toBigInteger (Number n) { if (n instanceof BigInteger) { return (BigInteger)n; } return BigInteger.valueOf (n.longValue()); } /** * Compare the given Number to 0. * @param n * @return True if number is 0. */ public static boolean isZero (Number n) { if (isInteger( n ) ) { if (n instanceof BigInteger) { return ((BigInteger)n).compareTo (BigInteger.ZERO) == 0; } return n.doubleValue() == 0; } if (n instanceof Float) { return n.floatValue() == 0f; } if (n instanceof Double) { return n.doubleValue() == 0d; } return toBigDecimal( n ).compareTo( DECIMAL_ZERO) == 0; } /** * Test, whether the given object is an integer value * (Byte, Short, Integer, Long, BigInteger) * @param n * @return True if n is an integer. */ public static boolean isInteger (Number n) { return ints.containsKey (n.getClass()); } /** * Wrap the given primitive into the given class if the value is in the * range of the destination type. If not the next bigger type will be chosen. * @param value * @param type * @return Number object representing the primitive. */ public static Number wrapPrimitive (long value, Class type) { if (type == Byte.class) { if (value > Byte.MAX_VALUE || value < Byte.MIN_VALUE) { type = Short.class; } else { // TODO: JDK 1.4+ -> valueOf() return new Byte ((byte)value); } } if (type == Short.class) { if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) { type = Integer.class; } else { // TODO: JDK 1.4+ -> valueOf() return new Short((short)value); } } if (type == Integer.class) { if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) { type = Long.class; } else { // TODO: JDK 1.4+ -> valueOf() return new Integer ((int)value); } } if (type == Long.class) { // TODO: JDK 1.4+ -> valueOf() return new Long (value); } return BigInteger.valueOf( value); } /** * Wrap the result in the object of the bigger type. * * @param value result of operation (as a long) - used to check size * @param op1 first operand of binary operation * @param op2 second operand of binary operation * @return Number object of appropriate size to fit the value and operators */ private static Number wrapPrimitive (long value, Number op1, Number op2) { if ( typesBySize.indexOf( op1.getClass()) > typesBySize.indexOf( op2.getClass())) { return wrapPrimitive( value, op1.getClass()); } return wrapPrimitive( value, op2.getClass()); } /** * Find the common Number-type to be used in calculations. * * @param op1 first operand of binary operation * @param op2 second operand of binary operation * @return constant indicating type of Number to use in calculations */ private static int findCalculationBase (Number op1, Number op2) { boolean op1Int = isInteger(op1); boolean op2Int = isInteger(op2); if ( (op1 instanceof BigDecimal || op2 instanceof BigDecimal) || ( (!op1Int || !op2Int) && (op1 instanceof BigInteger || op2 instanceof BigInteger)) ) { return BASE_BIGDECIMAL; } if (op1Int && op2Int) { if (op1 instanceof BigInteger || op2 instanceof BigInteger) { return BASE_BIGINTEGER; } return BASE_LONG; } if ((op1 instanceof Double) || (op2 instanceof Double)) { return BASE_DOUBLE; } return BASE_FLOAT; } /** * Add two numbers and return the correct value / type. * Overflow detection is done for integer values (byte, short, int, long) only! * @param op1 * @param op2 * @return Addition result. */ public static Number add (Number op1, Number op2) { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: return toBigInteger( op1 ).add( toBigInteger( op2 )); case BASE_LONG: long l1 = op1.longValue(); long l2 = op2.longValue(); long result = l1+l2; // Overflow check if ((result ^ l1) < 0 && (result ^ l2) < 0) { return toBigInteger( op1).add( toBigInteger( op2)); } return wrapPrimitive( result, op1, op2); case BASE_FLOAT: return new Float (op1.floatValue()+op2.floatValue()); case BASE_DOUBLE: return new Double (op1.doubleValue()+op2.doubleValue()); // Default is BigDecimal operation default: return toBigDecimal( op1 ).add( toBigDecimal( op2 )); } } /** * Subtract two numbers and return the correct value / type. * Overflow detection is done for integer values (byte, short, int, long) only! * @param op1 * @param op2 * @return Subtraction result. */ public static Number subtract (Number op1, Number op2) { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: return toBigInteger( op1 ).subtract( toBigInteger( op2 )); case BASE_LONG: long l1 = op1.longValue(); long l2 = op2.longValue(); long result = l1-l2; // Overflow check if ((result ^ l1) < 0 && (result ^ ~l2) < 0) { return toBigInteger( op1).subtract( toBigInteger( op2)); } return wrapPrimitive( result, op1, op2); case BASE_FLOAT: return new Float (op1.floatValue()-op2.floatValue()); case BASE_DOUBLE: return new Double (op1.doubleValue()-op2.doubleValue()); // Default is BigDecimal operation default: return toBigDecimal( op1 ).subtract( toBigDecimal( op2 )); } } /** * Multiply two numbers and return the correct value / type. * Overflow detection is done for integer values (byte, short, int, long) only! * @param op1 * @param op2 * @return Multiplication result. */ public static Number multiply (Number op1, Number op2) { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: return toBigInteger( op1 ).multiply( toBigInteger( op2 )); case BASE_LONG: long l1 = op1.longValue(); long l2 = op2.longValue(); long result = l1*l2; // Overflow detection if ((l2 != 0) && (result / l2 != l1)) { return toBigInteger( op1).multiply( toBigInteger( op2)); } return wrapPrimitive( result, op1, op2); case BASE_FLOAT: return new Float (op1.floatValue()*op2.floatValue()); case BASE_DOUBLE: return new Double (op1.doubleValue()*op2.doubleValue()); // Default is BigDecimal operation default: return toBigDecimal( op1 ).multiply( toBigDecimal( op2 )); } } /** * Divide two numbers. The result will be returned as Integer-type if and only if * both sides of the division operator are Integer-types. Otherwise a Float, Double, * or BigDecimal will be returned. * @param op1 * @param op2 * @return Division result. */ public static Number divide (Number op1, Number op2) { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: BigInteger b1 = toBigInteger( op1 ); BigInteger b2 = toBigInteger( op2 ); return b1.divide( b2); case BASE_LONG: long l1 = op1.longValue(); long l2 = op2.longValue(); return wrapPrimitive( l1 / l2, op1, op2); case BASE_FLOAT: return new Float (op1.floatValue()/op2.floatValue()); case BASE_DOUBLE: return new Double (op1.doubleValue()/op2.doubleValue()); // Default is BigDecimal operation default: return toBigDecimal( op1 ).divide( toBigDecimal( op2 ), BigDecimal.ROUND_HALF_DOWN); } } /** * Modulo two numbers. * @param op1 * @param op2 * @return Modulo result. * * @throws ArithmeticException If at least one parameter is a BigDecimal */ public static Number modulo (Number op1, Number op2) throws ArithmeticException { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: return toBigInteger( op1 ).mod( toBigInteger( op2 )); case BASE_LONG: return wrapPrimitive( op1.longValue() % op2.longValue(), op1, op2); case BASE_FLOAT: return new Float (op1.floatValue() % op2.floatValue()); case BASE_DOUBLE: return new Double (op1.doubleValue() % op2.doubleValue()); // Default is BigDecimal operation default: throw new ArithmeticException( "Cannot calculate the modulo of BigDecimals."); } } /** * Compare two numbers. * @param op1 * @param op2 * @return 1 if n1 > n2, -1 if n1 < n2 and 0 if equal. */ public static int compare (Number op1, Number op2) { int calcBase = findCalculationBase( op1, op2); switch (calcBase) { case BASE_BIGINTEGER: return toBigInteger( op1 ).compareTo( toBigInteger( op2 )); case BASE_LONG: long l1 = op1.longValue(); long l2 = op2.longValue(); if (l1 < l2) { return -1; } if (l1 > l2) { return 1; } return 0; case BASE_FLOAT: float f1 = op1.floatValue(); float f2 = op2.floatValue(); if (f1 < f2) { return -1; } if (f1 > f2) { return 1; } return 0; case BASE_DOUBLE: double d1 = op1.doubleValue(); double d2 = op2.doubleValue(); if (d1 < d2) { return -1; } if (d1 > d2) { return 1; } return 0; // Default is BigDecimal operation default: return toBigDecimal( op1 ).compareTo( toBigDecimal ( op2 )); } } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/PutExecutor.java0000644000175000017500000000766411052641200027517 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.util.introspection.Introspector; /** * Executor that simply tries to execute a put(key, value) * operation. This will try to find a put(key) method * for any type of object, not just objects that * implement the Map interface as was previously * the case. * * @author Jason van Zyl * @author Henning P. Schmiedehausen * @version $Id: PutExecutor.java 687177 2008-08-19 22:00:32Z nbubna $ * @since 1.5 */ public class PutExecutor extends SetExecutor { private final Introspector introspector; private final String property; /** * @param log * @param introspector * @param clazz * @param arg * @param property */ public PutExecutor(final Log log, final Introspector introspector, final Class clazz, final Object arg, final String property) { this.log = log; this.introspector = introspector; this.property = property; discover(clazz, arg); } /** * @param clazz * @param arg */ protected void discover(final Class clazz, final Object arg) { Object [] params; // If you passed in null as property, we don't use the value // for parameter lookup. Instead we just look for put(Object) without // any parameters. // // In any other case, the following condition will set up an array // for looking up put(String, Object) on the class. if (property == null) { // The passed in arg object is used by the Cache to look up the method. params = new Object[] { arg }; } else { params = new Object[] { property, arg }; } try { setMethod(introspector.getMethod(clazz, "put", params)); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for put('" + params[0] + "') method"; log.error(msg, e); throw new VelocityException(msg, e); } } /** * @see org.apache.velocity.runtime.parser.node.SetExecutor#execute(java.lang.Object, java.lang.Object) */ public Object execute(final Object o, final Object value) throws IllegalAccessException, InvocationTargetException { Object [] params; if (isAlive()) { // If property != null, pass in the name for put(key, value). Else just put(value). if (property == null) { params = new Object [] { value }; } else { params = new Object [] { property, value }; } return getMethod().invoke(o, params); } return null; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTGTNode.java0000644000175000017500000001062611124067071026720 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 > arg2

      * * Only subclasses of Number can be compared.

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski */ public class ASTGTNode extends SimpleNode { /** * @param id */ public ASTGTNode(int id) { super(id); } /** * @param p * @param id */ public ASTGTNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate(InternalContextAdapter context) throws MethodInvocationException { /* * get the two args */ Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * if either is null, lets log and bail */ if (left == null || right == null) { String msg = (left == null ? "Left" : "Right") + " side (" + jjtGetChild( (left == null? 0 : 1) ).literal() + ") of '>' operation has null value at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * Only compare Numbers */ if ( !( left instanceof Number ) || !( right instanceof Number )) { String msg = (!(left instanceof Number) ? "Left" : "Right") + " side of '>=' operation is not a Number at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } return MathUtils.compare ( (Number)left,(Number)right) == 1; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { boolean val = evaluate(context); return val ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java0000644000175000017500000002714511465334133030373 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.Token; /** * ASTStringLiteral support. Will interpolate! * * @author Geir Magnusson Jr. * @author Jason van Zyl * @version $Id: ASTStringLiteral.java 1032134 2010-11-06 20:19:39Z cbrisson $ */ public class ASTStringLiteral extends SimpleNode { /* cache the value of the interpolation switch */ private boolean interpolate = true; private SimpleNode nodeTree = null; private String image = ""; private String interpolateimage = ""; /** true if the string contains a line comment (##) */ private boolean containsLineComment; /** * @param id */ public ASTStringLiteral(int id) { super(id); } /** * @param p * @param id */ public ASTStringLiteral(Parser p, int id) { super(p, id); } /** * init : we don't have to do much. Init the tree (there shouldn't be one) * and then see if interpolation is turned on. * * @param context * @param data * @return Init result. * @throws TemplateInitException */ public Object init(InternalContextAdapter context, Object data) throws TemplateInitException { /* * simple habit... we prollie don't have an AST beneath us */ super.init(context, data); /* * the stringlit is set at template parse time, so we can do this here * for now. if things change and we can somehow create stringlits at * runtime, this must move to the runtime execution path * * so, only if interpolation is turned on AND it starts with a " AND it * has a directive or reference, then we can interpolate. Otherwise, * don't bother. */ interpolate = rsvc.getBoolean( RuntimeConstants.INTERPOLATE_STRINGLITERALS, true) && getFirstToken().image.startsWith("\"") && ((getFirstToken().image.indexOf('$') != -1) || (getFirstToken().image .indexOf('#') != -1)); /* * get the contents of the string, minus the '/" at each end */ String img = getFirstToken().image; image = img.substring(1, img.length() - 1); if (img.startsWith("\"")) { image = unescape(image); } if (img.charAt(0) == '"' || img.charAt(0) == '\'' ) { // replace double-double quotes like "" with a single double quote " // replace double single quotes '' with a single quote ' image = replaceQuotes(image, img.charAt(0)); } /** * note. A kludge on a kludge. The first part, Geir calls this the * dreaded kludge. Basically, the use of the token eats * the last character of an interpolated string. EXCEPT when a line * comment (##) is in the string this isn't an issue. * * So, to solve this we look for a line comment. If it isn't found we * add a space here and remove it later. */ /** * Note - this should really use a regexp to look for [^\]## but * apparently escaping of line comments isn't working right now anyway. */ containsLineComment = (image.indexOf("##") != -1); /* * if appropriate, tack a space on the end (dreaded kludge) */ if (!containsLineComment) { interpolateimage = image + " "; } else { interpolateimage = image; } if (interpolate) { /* * now parse and init the nodeTree */ StringReader br = new StringReader(interpolateimage); /* * it's possible to not have an initialization context - or we don't * want to trust the caller - so have a fallback value if so * * Also, do *not* dump the VM namespace for this template */ String templateName = (context != null) ? context.getCurrentTemplateName() : "StringLiteral"; try { nodeTree = rsvc.parse(br, templateName, false); } catch (ParseException e) { String msg = "Failed to parse String literal at "+ Log.formatFileString(templateName, getLine(), getColumn()); throw new TemplateInitException(msg, e, templateName, getColumn(), getLine()); } adjTokenLineNums(nodeTree); /* * init with context. It won't modify anything */ nodeTree.init(context, rsvc); } return data; } /** * Adjust all the line and column numbers that comprise a node so that they * are corrected for the string literals position within the template file. * This is neccessary if an exception is thrown while processing the node so * that the line and column position reported reflects the error position * within the template and not just relative to the error position within * the string literal. */ public void adjTokenLineNums(Node node) { Token tok = node.getFirstToken(); // Test against null is probably not neccessary, but just being safe while(tok != null && tok != node.getLastToken()) { // If tok is on the first line, then the actual column is // offset by the template column. if (tok.beginLine == 1) tok.beginColumn += getColumn(); if (tok.endLine == 1) tok.endColumn += getColumn(); tok.beginLine += getLine()- 1; tok.endLine += getLine() - 1; tok = tok.next; } } /** * Replaces double double-quotes with a single double quote ("" to "). * Replaces double single quotes with a single quote ('' to '). * * @param s StringLiteral without the surrounding quotes * @param literalQuoteChar char that starts the StringLiteral (" or ') */ private String replaceQuotes(String s, char literalQuoteChar) { if( (literalQuoteChar == '"' && s.indexOf("\"") == -1) || (literalQuoteChar == '\'' && s.indexOf("'") == -1) ) { return s; } StrBuilder result = new StrBuilder(s.length()); char prev = ' '; for(int i = 0, is = s.length(); i < is; i++) { char c = s.charAt(i); result.append(c); if( i + 1 < is ) { char next = s.charAt(i + 1); // '""' -> "", "''" -> '' // thus it is not necessary to double quotes if the "surrounding" quotes // of the StringLiteral are different. See VELOCITY-785 if( (literalQuoteChar == '"' && (next == '"' && c == '"')) || (literalQuoteChar == '\'' && (next == '\'' && c == '\'')) ) { i++; } } } return result.toString(); } /** * @since 1.6 */ public static String unescape(final String string) { int u = string.indexOf("\\u"); if (u < 0) return string; StrBuilder result = new StrBuilder(); int lastCopied = 0; for (;;) { result.append(string.substring(lastCopied, u)); /* we don't worry about an exception here, * because the lexer checked that string is correct */ char c = (char) Integer.parseInt(string.substring(u + 2, u + 6), 16); result.append(c); lastCopied = u + 6; u = string.indexOf("\\u", lastCopied); if (u < 0) { result.append(string.substring(lastCopied)); return result.toString(); } } } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, * java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Check to see if this is an interpolated string. * @return true if this is constant (not an interpolated string) * @since 1.6 */ public boolean isConstant() { return !interpolate; } /** * renders the value of the string literal If the properties allow, and the * string literal contains a $ or a # the literal is rendered against the * context Otherwise, the stringlit is returned. * * @param context * @return result of the rendering. */ public Object value(InternalContextAdapter context) { if (interpolate) { try { /* * now render against the real context */ StringWriter writer = new StringWriter(); nodeTree.render(context, writer); /* * and return the result as a String */ String ret = writer.toString(); /* * if appropriate, remove the space from the end (dreaded * kludge part deux) */ if (!containsLineComment && ret.length() > 0) { return ret.substring(0, ret.length() - 1); } else { return ret; } } /** * pass through application level runtime exceptions */ catch (RuntimeException e) { throw e; } catch (IOException e) { String msg = "Error in interpolating string literal"; log.error(msg, e); throw new VelocityException(msg, e); } } /* * ok, either not allowed to interpolate, there wasn't a ref or * directive, or we failed, so just output the literal */ return image; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/MapGetExecutor.java0000644000175000017500000000450011234415123030113 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.util.Map; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.log.Log; /** * GetExecutor that is smart about Maps. If it detects one, it does not * use Reflection but a cast to access the getter. * * @author Henning P. Schmiedehausen * @version $Id: MapGetExecutor.java 799457 2009-07-30 22:10:27Z nbubna $ * @since 1.5 */ public class MapGetExecutor extends AbstractExecutor { private final String property; public MapGetExecutor(final Log log, final Class clazz, final String property) { this.log = log; this.property = property; discover(clazz); } protected void discover (final Class clazz) { if (property != null && Map.class.isAssignableFrom(clazz)) { try { setMethod(Map.class.getMethod("get", new Class [] { Object.class })); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for get('" + property + "') method"; log.error(msg, e); throw new VelocityException(msg, e); } } } public Object execute(final Object o) { return ((Map) o).get(property); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/ASTLTNode.java0000644000175000017500000001066511124067071026730 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.util.TemplateNumber; /** * Handles arg1 < arg2

      * * Only subclasses of Number can be compared.

      * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Will Glass-Husain * @author Peter Romianowski */ public class ASTLTNode extends SimpleNode { /** * @param id */ public ASTLTNode(int id) { super(id); } /** * @param p * @param id */ public ASTLTNode(Parser p, int id) { super(p, id); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object) */ public Object jjtAccept(ParserVisitor visitor, Object data) { return visitor.visit(this, data); } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#evaluate(org.apache.velocity.context.InternalContextAdapter) */ public boolean evaluate(InternalContextAdapter context) throws MethodInvocationException { /* * get the two args */ Object left = jjtGetChild(0).value( context ); Object right = jjtGetChild(1).value( context ); /* * if either is null, lets log and bail */ if (left == null || right == null) { String msg = (left == null ? "Left" : "Right") + " side (" + jjtGetChild( (left == null? 0 : 1) ).literal() + ") of '<' operation has null value at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } /* * convert to Number if applicable */ if (left instanceof TemplateNumber) { left = ( (TemplateNumber) left).getAsNumber(); } if (right instanceof TemplateNumber) { right = ( (TemplateNumber) right).getAsNumber(); } /* * Only compare Numbers */ if ( !( left instanceof Number ) || !( right instanceof Number )) { String msg = (!(left instanceof Number) ? "Left" : "Right") + " side of '>=' operation is not a valid Number at " + Log.formatFileString(this); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { throw new VelocityException(msg); } log.error(msg); return false; } return MathUtils.compare ( (Number)left,(Number)right) == -1; } /** * @see org.apache.velocity.runtime.parser.node.SimpleNode#value(org.apache.velocity.context.InternalContextAdapter) */ public Object value(InternalContextAdapter context) throws MethodInvocationException { boolean val = evaluate(context); return val ? Boolean.TRUE : Boolean.FALSE; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/node/GetExecutor.java0000644000175000017500000000733211052641200027456 0ustar moellermoellerpackage org.apache.velocity.runtime.parser.node; /* * 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. */ import java.lang.reflect.InvocationTargetException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.RuntimeLoggerLog; import org.apache.velocity.util.introspection.Introspector; /** * Executor that simply tries to execute a get(key) * operation. This will try to find a get(key) method * for any type of object, not just objects that * implement the Map interface as was previously * the case. * * @author Jason van Zyl * @version $Id: GetExecutor.java 687177 2008-08-19 22:00:32Z nbubna $ */ public class GetExecutor extends AbstractExecutor { private final Introspector introspector; // This is still threadsafe because this object is only read except in the C'tor. private Object [] params = {}; /** * @param log * @param introspector * @param clazz * @param property * @since 1.5 */ public GetExecutor(final Log log, final Introspector introspector, final Class clazz, final String property) { this.log = log; this.introspector = introspector; // If you passed in null as property, we don't use the value // for parameter lookup. Instead we just look for get() without // any parameters. // // In any other case, the following condition will set up an array // for looking up get(String) on the class. if (property != null) { this.params = new Object[] { property }; } discover(clazz); } /** * @param rlog * @param introspector * @param clazz * @param property * @deprecated RuntimeLogger is deprecated. Use the other constructor. */ public GetExecutor(final RuntimeLogger rlog, final Introspector introspector, final Class clazz, final String property) { this(new RuntimeLoggerLog(rlog), introspector, clazz, property); } /** * @since 1.5 */ protected void discover(final Class clazz) { try { setMethod(introspector.getMethod(clazz, "get", params)); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { String msg = "Exception while looking for get('" + params[0] + "') method"; log.error(msg, e); throw new VelocityException(msg, e); } } /** * @see org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object) */ public Object execute(final Object o) throws IllegalAccessException, InvocationTargetException { return isAlive() ? getMethod().invoke(o, params) : null; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/ParserTokenManager.java0000644000175000017500000052565411353715726030062 0ustar moellermoeller/* Generated By:JJTree&JavaCC: Do not edit this line. ParserTokenManager.java */ package org.apache.velocity.runtime.parser; import java.io.*; import java.util.*; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.*; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.Macro; import org.apache.velocity.runtime.directive.MacroParseException; import org.apache.velocity.util.StringUtils; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.runtime.RuntimeConstants; /** Token Manager. */ public class ParserTokenManager implements ParserConstants { private int fileDepth = 0; private int lparen = 0; private int rparen = 0; List stateStack = new ArrayList(50); public boolean debugPrint = false; private boolean inReference; public boolean inDirective; private boolean inComment; public boolean inSet; /** * pushes the current state onto the 'state stack', * and maintains the parens counts * public because we need it in PD & VM handling * * @return boolean : success. It can fail if the state machine * gets messed up (do don't mess it up :) */ public boolean stateStackPop() { ParserState s; try { s = (ParserState) stateStack.remove(stateStack.size() - 1); // stack.pop } catch(IndexOutOfBoundsException e) { // empty stack lparen=0; SwitchTo(DEFAULT); return false; } if( debugPrint ) System.out.println( " stack pop (" + stateStack.size() + ") : lparen=" + s.lparen + " newstate=" + s.lexstate ); lparen = s.lparen; rparen = s.rparen; SwitchTo(s.lexstate); return true; } /** * pops a state off the stack, and restores paren counts * * @return boolean : success of operation */ public boolean stateStackPush() { if( debugPrint ) System.out.println(" (" + stateStack.size() + ") pushing cur state : " + curLexState ); ParserState s = new ParserState(); s.lparen = lparen; s.rparen = rparen; s.lexstate = curLexState; lparen = 0; stateStack.add(s); // stack.push return true; } /** * Clears all state variables, resets to * start values, clears stateStack. Call * before parsing. */ public void clearStateVars() { stateStack.clear(); lparen = 0; rparen = 0; inReference = false; inDirective = false; inComment = false; inSet = false; return; } /** * Holds the state of the parsing process. */ private static class ParserState { int lparen; int rparen; int lexstate; } /** * handles the dropdown logic when encountering a RPAREN */ private void RPARENHandler() { /* * Ultimately, we want to drop down to the state below * the one that has an open (if we hit bottom (DEFAULT), * that's fine. It's just text schmoo. */ boolean closed = false; if (inComment) closed = true; while( !closed ) { /* * look at current state. If we haven't seen a lparen * in this state then we drop a state, because this * lparen clearly closes our state */ if( lparen > 0) { /* * if rparen + 1 == lparen, then this state is closed. * Otherwise, increment and keep parsing */ if( lparen == rparen + 1) { stateStackPop(); } else { rparen++; } closed = true; } else { /* * now, drop a state */ if(!stateStackPop()) break; } } } /** Debug output. */ public java.io.PrintStream debugStream = System.out; /** Set debug output. */ public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } private final int jjStopStringLiteralDfa_3(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1000000000L) != 0L) return 105; if ((active0 & 0x100L) != 0L) return 69; if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 61; return 67; } if ((active0 & 0x40L) != 0L) return 62; if ((active0 & 0x4000000000000L) != 0L) return 54; if ((active0 & 0x3a0000L) != 0L) return 7; return -1; case 1: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 61; jjmatchedPos = 1; return 67; } if ((active0 & 0x80000L) != 0L) return 5; return -1; case 2: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 61; jjmatchedPos = 2; return 67; } return -1; case 3: if ((active0 & 0x200000000L) != 0L) return 67; if ((active0 & 0x400000000L) != 0L) { jjmatchedKind = 61; jjmatchedPos = 3; return 67; } return -1; default : return -1; } } private final int jjStartNfa_3(int pos, long active0) { return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); } private int jjStopAtPos(int pos, int kind) { jjmatchedKind = kind; jjmatchedPos = pos; return pos + 1; } private int jjMoveStringLiteralDfa0_3() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_3(0x2a0000L); case 37: return jjStopAtPos(0, 40); case 40: return jjStopAtPos(0, 10); case 42: return jjStopAtPos(0, 38); case 43: return jjStopAtPos(0, 37); case 44: return jjStopAtPos(0, 5); case 45: return jjStartNfaWithStates_3(0, 36, 105); case 46: return jjMoveStringLiteralDfa1_3(0x40L); case 47: return jjStopAtPos(0, 39); case 58: return jjStopAtPos(0, 7); case 61: return jjStartNfaWithStates_3(0, 50, 54); case 91: return jjStopAtPos(0, 3); case 93: return jjStopAtPos(0, 4); case 102: return jjMoveStringLiteralDfa1_3(0x400000000L); case 116: return jjMoveStringLiteralDfa1_3(0x200000000L); case 123: return jjStartNfaWithStates_3(0, 8, 69); case 125: return jjStopAtPos(0, 9); default : return jjMoveNfa_3(0, 0); } } private int jjMoveStringLiteralDfa1_3(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_3(0, active0); return 1; } switch(curChar) { case 35: if ((active0 & 0x200000L) != 0L) return jjStopAtPos(1, 21); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_3(1, 19, 5); break; case 46: if ((active0 & 0x40L) != 0L) return jjStopAtPos(1, 6); break; case 91: return jjMoveStringLiteralDfa2_3(active0, 0x20000L); case 97: return jjMoveStringLiteralDfa2_3(active0, 0x400000000L); case 114: return jjMoveStringLiteralDfa2_3(active0, 0x200000000L); default : break; } return jjStartNfa_3(0, active0); } private int jjMoveStringLiteralDfa2_3(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_3(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_3(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; case 108: return jjMoveStringLiteralDfa3_3(active0, 0x400000000L); case 117: return jjMoveStringLiteralDfa3_3(active0, 0x200000000L); default : break; } return jjStartNfa_3(1, active0); } private int jjMoveStringLiteralDfa3_3(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_3(1, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_3(2, active0); return 3; } switch(curChar) { case 101: if ((active0 & 0x200000000L) != 0L) return jjStartNfaWithStates_3(3, 33, 67); break; case 115: return jjMoveStringLiteralDfa4_3(active0, 0x400000000L); default : break; } return jjStartNfa_3(2, active0); } private int jjMoveStringLiteralDfa4_3(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_3(2, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_3(3, active0); return 4; } switch(curChar) { case 101: if ((active0 & 0x400000000L) != 0L) return jjStartNfaWithStates_3(4, 34, 67); break; default : break; } return jjStartNfa_3(3, active0); } private int jjStartNfaWithStates_3(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_3(state, pos + 1); } static final long[] jjbitVec0 = { 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL }; static final long[] jjbitVec2 = { 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL }; private int jjMoveNfa_3(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 105; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 105: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(100, 101); else if (curChar == 46) jjCheckNAdd(62); if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(94, 95); if ((0x3ff000000000000L & l) != 0L) { if (kind > 56) kind = 56; jjCheckNAddTwoStates(91, 93); } break; case 0: if ((0x3ff000000000000L & l) != 0L) { if (kind > 56) kind = 56; jjCheckNAddStates(0, 5); } else if ((0x100002600L & l) != 0L) { if (kind > 31) kind = 31; jjCheckNAdd(9); } else if (curChar == 45) jjCheckNAddStates(6, 9); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(77, 78); } else if (curChar == 46) jjCheckNAdd(62); else if (curChar == 33) { if (kind > 49) kind = 49; } else if (curChar == 61) jjstateSet[jjnewStateCnt++] = 54; else if (curChar == 62) jjstateSet[jjnewStateCnt++] = 52; else if (curChar == 60) jjstateSet[jjnewStateCnt++] = 49; else if (curChar == 38) jjstateSet[jjnewStateCnt++] = 39; else if (curChar == 39) jjCheckNAddStates(10, 13); else if (curChar == 34) jjCheckNAddStates(14, 17); else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 7; else if (curChar == 41) { if (kind > 11) kind = 11; jjCheckNAddStates(18, 20); } if ((0x2400L & l) != 0L) { if (kind > 35) kind = 35; } else if (curChar == 33) jjstateSet[jjnewStateCnt++] = 58; else if (curChar == 62) { if (kind > 45) kind = 45; } else if (curChar == 60) { if (kind > 43) kind = 43; } if (curChar == 13) jjstateSet[jjnewStateCnt++] = 37; break; case 1: if ((0x100000200L & l) != 0L) jjCheckNAddStates(18, 20); break; case 2: if ((0x2400L & l) != 0L && kind > 11) kind = 11; break; case 3: if (curChar == 10 && kind > 11) kind = 11; break; case 4: if (curChar == 13) jjstateSet[jjnewStateCnt++] = 3; break; case 5: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 6; break; case 6: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 7: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 5; break; case 8: if (curChar == 35) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if ((0x100002600L & l) == 0L) break; if (kind > 31) kind = 31; jjCheckNAdd(9); break; case 10: case 12: if (curChar == 34) jjCheckNAddStates(14, 17); break; case 11: if ((0xfffffffbffffffffL & l) != 0L) jjCheckNAddStates(14, 17); break; case 13: if (curChar == 34) jjstateSet[jjnewStateCnt++] = 12; break; case 14: if (curChar == 34 && kind > 32) kind = 32; break; case 17: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(21, 25); break; case 18: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(14, 17); break; case 19: if ((0xf000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 20; break; case 20: if ((0xff000000000000L & l) != 0L) jjCheckNAdd(18); break; case 22: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 23; break; case 23: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 24; break; case 24: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 25; break; case 25: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddStates(14, 17); break; case 26: if (curChar == 32) jjAddStates(26, 27); break; case 27: if (curChar == 10) jjCheckNAddStates(14, 17); break; case 28: case 30: if (curChar == 39) jjCheckNAddStates(10, 13); break; case 29: if ((0xffffff7fffffffffL & l) != 0L) jjCheckNAddStates(10, 13); break; case 31: if (curChar == 39) jjstateSet[jjnewStateCnt++] = 30; break; case 33: if (curChar == 32) jjAddStates(28, 29); break; case 34: if (curChar == 10) jjCheckNAddStates(10, 13); break; case 35: if (curChar == 39 && kind > 32) kind = 32; break; case 36: if ((0x2400L & l) != 0L && kind > 35) kind = 35; break; case 37: if (curChar == 10 && kind > 35) kind = 35; break; case 38: if (curChar == 13) jjstateSet[jjnewStateCnt++] = 37; break; case 39: if (curChar == 38 && kind > 41) kind = 41; break; case 40: if (curChar == 38) jjstateSet[jjnewStateCnt++] = 39; break; case 48: if (curChar == 60 && kind > 43) kind = 43; break; case 49: if (curChar == 61 && kind > 44) kind = 44; break; case 50: if (curChar == 60) jjstateSet[jjnewStateCnt++] = 49; break; case 51: if (curChar == 62 && kind > 45) kind = 45; break; case 52: if (curChar == 61 && kind > 46) kind = 46; break; case 53: if (curChar == 62) jjstateSet[jjnewStateCnt++] = 52; break; case 54: if (curChar == 61 && kind > 47) kind = 47; break; case 55: if (curChar == 61) jjstateSet[jjnewStateCnt++] = 54; break; case 58: if (curChar == 61 && kind > 48) kind = 48; break; case 59: if (curChar == 33) jjstateSet[jjnewStateCnt++] = 58; break; case 60: if (curChar == 33 && kind > 49) kind = 49; break; case 61: if (curChar == 46) jjCheckNAdd(62); break; case 62: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(62, 63); break; case 64: if ((0x280000000000L & l) != 0L) jjCheckNAdd(65); break; case 65: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(65); break; case 67: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 61) kind = 61; jjstateSet[jjnewStateCnt++] = 67; break; case 70: if ((0x3ff000000000000L & l) != 0L) jjAddStates(30, 31); break; case 74: if (curChar == 36 && kind > 15) kind = 15; break; case 76: if (curChar == 36) jjCheckNAddTwoStates(77, 78); break; case 78: if (curChar == 33 && kind > 16) kind = 16; break; case 79: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(77, 78); break; case 90: if (curChar == 45) jjCheckNAddStates(6, 9); break; case 91: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddTwoStates(91, 93); break; case 92: if (curChar == 46 && kind > 56) kind = 56; break; case 93: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 92; break; case 94: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(94, 95); break; case 95: if (curChar != 46) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(96, 97); break; case 96: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(96, 97); break; case 98: if ((0x280000000000L & l) != 0L) jjCheckNAdd(99); break; case 99: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(99); break; case 100: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(100, 101); break; case 102: if ((0x280000000000L & l) != 0L) jjCheckNAdd(103); break; case 103: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(103); break; case 104: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddStates(0, 5); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 0: if ((0x7fffffe87ffffffL & l) != 0L) { if (kind > 61) kind = 61; jjCheckNAdd(67); } else if (curChar == 92) jjCheckNAddStates(32, 35); else if (curChar == 123) jjstateSet[jjnewStateCnt++] = 69; else if (curChar == 124) jjstateSet[jjnewStateCnt++] = 44; if (curChar == 110) jjAddStates(36, 37); else if (curChar == 103) jjAddStates(38, 39); else if (curChar == 108) jjAddStates(40, 41); else if (curChar == 101) jjstateSet[jjnewStateCnt++] = 56; else if (curChar == 111) jjstateSet[jjnewStateCnt++] = 46; else if (curChar == 97) jjstateSet[jjnewStateCnt++] = 42; break; case 6: if (kind > 18) kind = 18; break; case 11: jjCheckNAddStates(14, 17); break; case 15: if (curChar == 92) jjAddStates(42, 47); break; case 16: if ((0x14404400000000L & l) != 0L) jjCheckNAddStates(14, 17); break; case 21: if (curChar == 117) jjstateSet[jjnewStateCnt++] = 22; break; case 22: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 23; break; case 23: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 24; break; case 24: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 25; break; case 25: if ((0x7e0000007eL & l) != 0L) jjCheckNAddStates(14, 17); break; case 29: jjAddStates(10, 13); break; case 32: if (curChar == 92) jjAddStates(28, 29); break; case 41: if (curChar == 100 && kind > 41) kind = 41; break; case 42: if (curChar == 110) jjstateSet[jjnewStateCnt++] = 41; break; case 43: if (curChar == 97) jjstateSet[jjnewStateCnt++] = 42; break; case 44: if (curChar == 124 && kind > 42) kind = 42; break; case 45: if (curChar == 124) jjstateSet[jjnewStateCnt++] = 44; break; case 46: if (curChar == 114 && kind > 42) kind = 42; break; case 47: if (curChar == 111) jjstateSet[jjnewStateCnt++] = 46; break; case 56: if (curChar == 113 && kind > 47) kind = 47; break; case 57: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 56; break; case 63: if ((0x2000000020L & l) != 0L) jjAddStates(48, 49); break; case 66: case 67: if ((0x7fffffe87ffffffL & l) == 0L) break; if (kind > 61) kind = 61; jjCheckNAdd(67); break; case 68: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 69; break; case 69: if ((0x7fffffe87fffffeL & l) != 0L) jjCheckNAddTwoStates(70, 71); break; case 70: if ((0x7fffffe87ffffffL & l) != 0L) jjCheckNAddTwoStates(70, 71); break; case 71: if (curChar == 125 && kind > 62) kind = 62; break; case 72: if (curChar == 92) jjCheckNAddStates(32, 35); break; case 73: if (curChar == 92) jjCheckNAddTwoStates(73, 74); break; case 75: if (curChar == 92) jjCheckNAddTwoStates(75, 76); break; case 77: if (curChar == 92) jjAddStates(50, 51); break; case 80: if (curChar == 108) jjAddStates(40, 41); break; case 81: if (curChar == 116 && kind > 43) kind = 43; break; case 82: if (curChar == 101 && kind > 44) kind = 44; break; case 83: if (curChar == 103) jjAddStates(38, 39); break; case 84: if (curChar == 116 && kind > 45) kind = 45; break; case 85: if (curChar == 101 && kind > 46) kind = 46; break; case 86: if (curChar == 110) jjAddStates(36, 37); break; case 87: if (curChar == 101 && kind > 48) kind = 48; break; case 88: if (curChar == 116 && kind > 49) kind = 49; break; case 89: if (curChar == 111) jjstateSet[jjnewStateCnt++] = 88; break; case 97: if ((0x2000000020L & l) != 0L) jjAddStates(52, 53); break; case 101: if ((0x2000000020L & l) != 0L) jjAddStates(54, 55); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 6: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; case 11: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(14, 17); break; case 29: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(10, 13); break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 105 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_11(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x3a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_11(int pos, long active0) { return jjMoveNfa_11(jjStopStringLiteralDfa_11(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_11() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_11(0x2a0000L); default : return jjMoveNfa_11(3, 0); } } private int jjMoveStringLiteralDfa1_11(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_11(0, active0); return 1; } switch(curChar) { case 35: if ((active0 & 0x200000L) != 0L) return jjStopAtPos(1, 21); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_11(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_11(active0, 0x20000L); default : break; } return jjStartNfa_11(0, active0); } private int jjMoveStringLiteralDfa2_11(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_11(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_11(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_11(1, active0); } private int jjStartNfaWithStates_11(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_11(state, pos + 1); } private int jjMoveNfa_11(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 83; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if ((0x3ff000000000000L & l) != 0L) { if (kind > 56) kind = 56; jjCheckNAddStates(56, 61); } else if (curChar == 45) jjCheckNAddStates(62, 65); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(22, 23); } else if (curChar == 46) jjCheckNAdd(7); else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 6: if (curChar == 46) jjCheckNAdd(7); break; case 7: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(7, 8); break; case 9: if ((0x280000000000L & l) != 0L) jjCheckNAdd(10); break; case 10: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(10); break; case 12: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 61) kind = 61; jjstateSet[jjnewStateCnt++] = 12; break; case 15: if ((0x3ff000000000000L & l) != 0L) jjAddStates(66, 67); break; case 19: if (curChar == 36 && kind > 15) kind = 15; break; case 21: if (curChar == 36) jjCheckNAddTwoStates(22, 23); break; case 23: if (curChar == 33 && kind > 16) kind = 16; break; case 24: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(22, 23); break; case 27: if ((0x100000200L & l) != 0L) jjCheckNAddStates(68, 70); break; case 28: if ((0x2400L & l) != 0L && kind > 51) kind = 51; break; case 29: if (curChar == 10 && kind > 51) kind = 51; break; case 30: case 47: if (curChar == 13) jjCheckNAdd(29); break; case 38: if ((0x100000200L & l) != 0L) jjCheckNAddStates(71, 73); break; case 39: if ((0x2400L & l) != 0L && kind > 54) kind = 54; break; case 40: if (curChar == 10 && kind > 54) kind = 54; break; case 41: case 63: if (curChar == 13) jjCheckNAdd(40); break; case 46: if ((0x100000200L & l) != 0L) jjCheckNAddStates(74, 76); break; case 62: if ((0x100000200L & l) != 0L) jjCheckNAddStates(77, 79); break; case 68: if (curChar == 45) jjCheckNAddStates(62, 65); break; case 69: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddTwoStates(69, 71); break; case 70: if (curChar == 46 && kind > 56) kind = 56; break; case 71: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 70; break; case 72: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(72, 73); break; case 73: if (curChar != 46) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(74, 75); break; case 74: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(74, 75); break; case 76: if ((0x280000000000L & l) != 0L) jjCheckNAdd(77); break; case 77: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(77); break; case 78: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(78, 79); break; case 80: if ((0x280000000000L & l) != 0L) jjCheckNAdd(81); break; case 81: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(81); break; case 82: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddStates(56, 61); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if ((0x7fffffe87ffffffL & l) != 0L) { if (kind > 61) kind = 61; jjCheckNAdd(12); } else if (curChar == 123) jjAddStates(80, 83); else if (curChar == 92) jjCheckNAddStates(84, 87); if (curChar == 101) jjAddStates(88, 90); else if (curChar == 123) jjstateSet[jjnewStateCnt++] = 14; else if (curChar == 105) jjstateSet[jjnewStateCnt++] = 4; break; case 1: if (kind > 18) kind = 18; break; case 4: if (curChar == 102 && kind > 52) kind = 52; break; case 5: if (curChar == 105) jjstateSet[jjnewStateCnt++] = 4; break; case 8: if ((0x2000000020L & l) != 0L) jjAddStates(91, 92); break; case 11: case 12: if ((0x7fffffe87ffffffL & l) == 0L) break; if (kind > 61) kind = 61; jjCheckNAdd(12); break; case 13: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 14; break; case 14: if ((0x7fffffe87fffffeL & l) != 0L) jjCheckNAddTwoStates(15, 16); break; case 15: if ((0x7fffffe87ffffffL & l) != 0L) jjCheckNAddTwoStates(15, 16); break; case 16: if (curChar == 125 && kind > 62) kind = 62; break; case 17: if (curChar == 92) jjCheckNAddStates(84, 87); break; case 18: if (curChar == 92) jjCheckNAddTwoStates(18, 19); break; case 20: if (curChar == 92) jjCheckNAddTwoStates(20, 21); break; case 22: if (curChar == 92) jjAddStates(93, 94); break; case 25: if (curChar == 101) jjAddStates(88, 90); break; case 26: if (curChar != 100) break; if (kind > 51) kind = 51; jjCheckNAddStates(68, 70); break; case 31: if (curChar == 110) jjstateSet[jjnewStateCnt++] = 26; break; case 32: if (curChar == 102 && kind > 53) kind = 53; break; case 33: if (curChar == 105) jjstateSet[jjnewStateCnt++] = 32; break; case 34: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 33; break; case 35: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 34; break; case 36: if (curChar == 108) jjstateSet[jjnewStateCnt++] = 35; break; case 37: if (curChar != 101) break; if (kind > 54) kind = 54; jjCheckNAddStates(71, 73); break; case 42: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 37; break; case 43: if (curChar == 108) jjstateSet[jjnewStateCnt++] = 42; break; case 44: if (curChar == 123) jjAddStates(80, 83); break; case 45: if (curChar != 125) break; if (kind > 51) kind = 51; jjCheckNAddStates(74, 76); break; case 48: if (curChar == 100) jjstateSet[jjnewStateCnt++] = 45; break; case 49: if (curChar == 110) jjstateSet[jjnewStateCnt++] = 48; break; case 50: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 49; break; case 51: if (curChar == 125 && kind > 52) kind = 52; break; case 52: if (curChar == 102) jjstateSet[jjnewStateCnt++] = 51; break; case 53: if (curChar == 105) jjstateSet[jjnewStateCnt++] = 52; break; case 54: if (curChar == 125 && kind > 53) kind = 53; break; case 55: if (curChar == 102) jjstateSet[jjnewStateCnt++] = 54; break; case 56: if (curChar == 105) jjstateSet[jjnewStateCnt++] = 55; break; case 57: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 56; break; case 58: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 57; break; case 59: if (curChar == 108) jjstateSet[jjnewStateCnt++] = 58; break; case 60: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 59; break; case 61: if (curChar != 125) break; if (kind > 54) kind = 54; jjCheckNAddStates(77, 79); break; case 64: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 61; break; case 65: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 64; break; case 66: if (curChar == 108) jjstateSet[jjnewStateCnt++] = 65; break; case 67: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 66; break; case 75: if ((0x2000000020L & l) != 0L) jjAddStates(95, 96); break; case 79: if ((0x2000000020L & l) != 0L) jjAddStates(97, 98); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 83 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_8(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_8(int pos, long active0) { return jjMoveNfa_8(jjStopStringLiteralDfa_8(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_8() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_8(0xa0000L); case 42: return jjMoveStringLiteralDfa1_8(0x8000000L); default : return jjMoveNfa_8(3, 0); } } private int jjMoveStringLiteralDfa1_8(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_8(0, active0); return 1; } switch(curChar) { case 35: if ((active0 & 0x8000000L) != 0L) return jjStopAtPos(1, 27); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_8(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_8(active0, 0x20000L); default : break; } return jjStartNfa_8(0, active0); } private int jjMoveStringLiteralDfa2_8(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_8(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_8(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_8(1, active0); } private int jjStartNfaWithStates_8(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_8(state, pos + 1); } private int jjMoveNfa_8(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 12; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); } else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 6: if (curChar == 36 && kind > 15) kind = 15; break; case 8: if (curChar == 36) jjCheckNAddTwoStates(9, 10); break; case 10: if (curChar == 33 && kind > 16) kind = 16; break; case 11: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(99, 102); break; case 1: if (kind > 18) kind = 18; break; case 5: if (curChar == 92) jjCheckNAddTwoStates(5, 6); break; case 7: if (curChar == 92) jjCheckNAddTwoStates(7, 8); break; case 9: if (curChar == 92) jjAddStates(91, 92); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 12 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_6(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_6(int pos, long active0) { return jjMoveNfa_6(jjStopStringLiteralDfa_6(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_6() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_6(0xa0000L); default : return jjMoveNfa_6(3, 0); } } private int jjMoveStringLiteralDfa1_6(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_6(0, active0); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_6(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_6(active0, 0x20000L); default : break; } return jjStartNfa_6(0, active0); } private int jjMoveStringLiteralDfa2_6(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_6(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_6(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_6(1, active0); } private int jjStartNfaWithStates_6(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_6(state, pos + 1); } private int jjMoveNfa_6(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 12; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); } else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 6: if (curChar == 36 && kind > 15) kind = 15; break; case 8: if (curChar == 36) jjCheckNAddTwoStates(9, 10); break; case 10: if (curChar == 33 && kind > 16) kind = 16; break; case 11: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(99, 102); break; case 1: if (kind > 18) kind = 18; break; case 5: if (curChar == 92) jjCheckNAddTwoStates(5, 6); break; case 7: if (curChar == 92) jjCheckNAddTwoStates(7, 8); break; case 9: if (curChar == 92) jjAddStates(91, 92); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 12 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_5(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0xc00000L) != 0L) return 20; if ((active0 & 0x3a0000L) != 0L) return 39; return -1; case 1: if ((active0 & 0x400000L) != 0L) return 40; if ((active0 & 0x80000L) != 0L) return 37; return -1; default : return -1; } } private final int jjStartNfa_5(int pos, long active0) { return jjMoveNfa_5(jjStopStringLiteralDfa_5(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_5() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_5(0x2a0000L); case 92: jjmatchedKind = 23; return jjMoveStringLiteralDfa1_5(0x400000L); default : return jjMoveNfa_5(13, 0); } } private int jjMoveStringLiteralDfa1_5(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_5(0, active0); return 1; } switch(curChar) { case 35: if ((active0 & 0x200000L) != 0L) return jjStopAtPos(1, 21); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_5(1, 19, 37); break; case 91: return jjMoveStringLiteralDfa2_5(active0, 0x20000L); case 92: if ((active0 & 0x400000L) != 0L) return jjStartNfaWithStates_5(1, 22, 40); break; default : break; } return jjStartNfa_5(0, active0); } private int jjMoveStringLiteralDfa2_5(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_5(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_5(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_5(1, active0); } private int jjStartNfaWithStates_5(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_5(state, pos + 1); } private int jjMoveNfa_5(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 40; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 39: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 37; break; case 40: if (curChar == 36) jjCheckNAddTwoStates(33, 34); if (curChar == 36) { if (kind > 15) kind = 15; } break; case 13: if ((0xffffffe7ffffffffL & l) != 0L) { if (kind > 24) kind = 24; jjCheckNAdd(12); } else if (curChar == 35) jjCheckNAddStates(103, 105); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(33, 34); } if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); else if (curChar == 36) jjCheckNAddStates(106, 109); break; case 20: if (curChar == 36) jjCheckNAddTwoStates(33, 34); else if (curChar == 35) jjAddStates(110, 111); if (curChar == 36) { if (kind > 15) kind = 15; } break; case 0: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); break; case 1: if (curChar == 35) jjCheckNAddTwoStates(6, 11); break; case 3: if (curChar == 32) jjAddStates(112, 113); break; case 4: if (curChar == 40 && kind > 14) kind = 14; break; case 12: if ((0xffffffe7ffffffffL & l) == 0L) break; if (kind > 24) kind = 24; jjCheckNAdd(12); break; case 15: case 16: if (curChar == 33) jjCheckNAdd(14); break; case 18: if (curChar == 46 && kind > 72) kind = 72; break; case 21: if (curChar == 35) jjAddStates(110, 111); break; case 23: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 13) kind = 13; jjstateSet[jjnewStateCnt++] = 23; break; case 26: if ((0x3ff000000000000L & l) != 0L) jjAddStates(26, 27); break; case 30: if (curChar == 36 && kind > 15) kind = 15; break; case 32: if (curChar == 36) jjCheckNAddTwoStates(33, 34); break; case 34: if (curChar == 33 && kind > 16) kind = 16; break; case 35: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(33, 34); break; case 36: if (curChar == 35) jjCheckNAddStates(103, 105); break; case 37: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 38; break; case 38: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 39: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; else if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 40: if (curChar == 92) jjAddStates(114, 115); if (curChar == 92) jjCheckNAddTwoStates(31, 32); if (curChar == 92) jjCheckNAddTwoStates(29, 30); break; case 13: if ((0xffffffffefffffffL & l) != 0L) { if (kind > 24) kind = 24; jjCheckNAdd(12); } else if (curChar == 92) jjCheckNAddStates(116, 119); if (curChar == 92) jjAddStates(114, 115); break; case 20: if (curChar == 92) jjCheckNAddTwoStates(31, 32); if (curChar == 92) jjCheckNAddTwoStates(29, 30); if (curChar == 92) jjstateSet[jjnewStateCnt++] = 19; break; case 2: if (curChar == 116) jjCheckNAddTwoStates(3, 4); break; case 5: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 2; break; case 6: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 7: if (curChar == 125) jjCheckNAddTwoStates(3, 4); break; case 8: if (curChar == 116) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 8; break; case 10: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 9; break; case 11: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; break; case 12: if ((0xffffffffefffffffL & l) == 0L) break; if (kind > 24) kind = 24; jjCheckNAdd(12); break; case 14: if (curChar == 91 && kind > 72) kind = 72; break; case 17: if (curChar == 92) jjstateSet[jjnewStateCnt++] = 16; break; case 19: if (curChar == 92) jjAddStates(114, 115); break; case 22: case 23: if ((0x7fffffe87ffffffL & l) == 0L) break; if (kind > 13) kind = 13; jjCheckNAdd(23); break; case 24: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 25; break; case 25: if ((0x7fffffe87fffffeL & l) != 0L) jjCheckNAddTwoStates(26, 27); break; case 26: if ((0x7fffffe87ffffffL & l) != 0L) jjCheckNAddTwoStates(26, 27); break; case 27: if (curChar == 125 && kind > 13) kind = 13; break; case 28: if (curChar == 92) jjCheckNAddStates(116, 119); break; case 29: if (curChar == 92) jjCheckNAddTwoStates(29, 30); break; case 31: if (curChar == 92) jjCheckNAddTwoStates(31, 32); break; case 33: if (curChar == 92) jjAddStates(28, 29); break; case 38: if (kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 13: case 12: if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) break; if (kind > 24) kind = 24; jjCheckNAdd(12); break; case 38: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 40 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_9(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_9(int pos, long active0) { return jjMoveNfa_9(jjStopStringLiteralDfa_9(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_9() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_9(0xa0000L); case 42: return jjMoveStringLiteralDfa1_9(0x4000000L); default : return jjMoveNfa_9(3, 0); } } private int jjMoveStringLiteralDfa1_9(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_9(0, active0); return 1; } switch(curChar) { case 35: if ((active0 & 0x4000000L) != 0L) return jjStopAtPos(1, 26); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_9(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_9(active0, 0x20000L); default : break; } return jjStartNfa_9(0, active0); } private int jjMoveStringLiteralDfa2_9(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_9(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_9(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_9(1, active0); } private int jjStartNfaWithStates_9(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_9(state, pos + 1); } private int jjMoveNfa_9(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 12; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); } else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 6: if (curChar == 36 && kind > 15) kind = 15; break; case 8: if (curChar == 36) jjCheckNAddTwoStates(9, 10); break; case 10: if (curChar == 33 && kind > 16) kind = 16; break; case 11: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(99, 102); break; case 1: if (kind > 18) kind = 18; break; case 5: if (curChar == 92) jjCheckNAddTwoStates(5, 6); break; case 7: if (curChar == 92) jjCheckNAddTwoStates(7, 8); break; case 9: if (curChar == 92) jjAddStates(91, 92); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 12 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_2(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_2(int pos, long active0) { return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_2() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_2(0xa0000L); case 93: return jjStopAtPos(0, 2); case 102: return jjMoveStringLiteralDfa1_2(0x400000000L); case 116: return jjMoveStringLiteralDfa1_2(0x200000000L); default : return jjMoveNfa_2(3, 0); } } private int jjMoveStringLiteralDfa1_2(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_2(0, active0); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_2(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_2(active0, 0x20000L); case 97: return jjMoveStringLiteralDfa2_2(active0, 0x400000000L); case 114: return jjMoveStringLiteralDfa2_2(active0, 0x200000000L); default : break; } return jjStartNfa_2(0, active0); } private int jjMoveStringLiteralDfa2_2(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_2(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_2(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; case 108: return jjMoveStringLiteralDfa3_2(active0, 0x400000000L); case 117: return jjMoveStringLiteralDfa3_2(active0, 0x200000000L); default : break; } return jjStartNfa_2(1, active0); } private int jjMoveStringLiteralDfa3_2(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_2(1, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_2(2, active0); return 3; } switch(curChar) { case 101: if ((active0 & 0x200000000L) != 0L) return jjStopAtPos(3, 33); break; case 115: return jjMoveStringLiteralDfa4_2(active0, 0x400000000L); default : break; } return jjStartNfa_2(2, active0); } private int jjMoveStringLiteralDfa4_2(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_2(2, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_2(3, active0); return 4; } switch(curChar) { case 101: if ((active0 & 0x400000000L) != 0L) return jjStopAtPos(4, 34); break; default : break; } return jjStartNfa_2(3, active0); } private int jjStartNfaWithStates_2(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_2(state, pos + 1); } private int jjMoveNfa_2(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 59; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if ((0x3ff000000000000L & l) != 0L) { if (kind > 56) kind = 56; jjCheckNAddStates(120, 125); } else if ((0x100002600L & l) != 0L) { if (kind > 31) kind = 31; jjCheckNAdd(4); } else if (curChar == 45) jjCheckNAddStates(126, 129); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(41, 42); } else if (curChar == 46) jjCheckNAdd(32); else if (curChar == 39) jjCheckNAddStates(130, 133); else if (curChar == 34) jjCheckNAddStates(134, 137); else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 4: if ((0x100002600L & l) == 0L) break; if (kind > 31) kind = 31; jjCheckNAdd(4); break; case 5: case 7: if (curChar == 34) jjCheckNAddStates(134, 137); break; case 6: if ((0xfffffffbffffffffL & l) != 0L) jjCheckNAddStates(134, 137); break; case 8: if (curChar == 34) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if (curChar == 34 && kind > 32) kind = 32; break; case 12: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(138, 142); break; case 13: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(134, 137); break; case 14: if ((0xf000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 15; break; case 15: if ((0xff000000000000L & l) != 0L) jjCheckNAdd(13); break; case 17: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 18; break; case 18: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 19; break; case 19: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 20; break; case 20: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddStates(134, 137); break; case 21: if (curChar == 32) jjAddStates(143, 144); break; case 22: if (curChar == 10) jjCheckNAddStates(134, 137); break; case 23: case 25: if (curChar == 39) jjCheckNAddStates(130, 133); break; case 24: if ((0xffffff7fffffffffL & l) != 0L) jjCheckNAddStates(130, 133); break; case 26: if (curChar == 39) jjstateSet[jjnewStateCnt++] = 25; break; case 28: if (curChar == 32) jjAddStates(145, 146); break; case 29: if (curChar == 10) jjCheckNAddStates(130, 133); break; case 30: if (curChar == 39 && kind > 32) kind = 32; break; case 31: if (curChar == 46) jjCheckNAdd(32); break; case 32: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(32, 33); break; case 34: if ((0x280000000000L & l) != 0L) jjCheckNAdd(35); break; case 35: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(35); break; case 38: if (curChar == 36 && kind > 15) kind = 15; break; case 40: if (curChar == 36) jjCheckNAddTwoStates(41, 42); break; case 42: if (curChar == 33 && kind > 16) kind = 16; break; case 43: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(41, 42); break; case 44: if (curChar == 45) jjCheckNAddStates(126, 129); break; case 45: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddTwoStates(45, 47); break; case 46: if (curChar == 46 && kind > 56) kind = 56; break; case 47: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 46; break; case 48: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(48, 49); break; case 49: if (curChar != 46) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(50, 51); break; case 50: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(50, 51); break; case 52: if ((0x280000000000L & l) != 0L) jjCheckNAdd(53); break; case 53: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(53); break; case 54: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(54, 55); break; case 56: if ((0x280000000000L & l) != 0L) jjCheckNAdd(57); break; case 57: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(57); break; case 58: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddStates(120, 125); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(147, 150); break; case 1: if (kind > 18) kind = 18; break; case 6: jjCheckNAddStates(134, 137); break; case 10: if (curChar == 92) jjAddStates(151, 156); break; case 11: if ((0x14404400000000L & l) != 0L) jjCheckNAddStates(134, 137); break; case 16: if (curChar == 117) jjstateSet[jjnewStateCnt++] = 17; break; case 17: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 18; break; case 18: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 19; break; case 19: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 20; break; case 20: if ((0x7e0000007eL & l) != 0L) jjCheckNAddStates(134, 137); break; case 24: jjAddStates(130, 133); break; case 27: if (curChar == 92) jjAddStates(145, 146); break; case 33: if ((0x2000000020L & l) != 0L) jjAddStates(157, 158); break; case 37: if (curChar == 92) jjCheckNAddTwoStates(37, 38); break; case 39: if (curChar == 92) jjCheckNAddTwoStates(39, 40); break; case 41: if (curChar == 92) jjAddStates(159, 160); break; case 51: if ((0x2000000020L & l) != 0L) jjAddStates(161, 162); break; case 55: if ((0x2000000020L & l) != 0L) jjAddStates(163, 164); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; case 6: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(134, 137); break; case 24: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(130, 133); break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 59 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_10(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_10(int pos, long active0) { return jjMoveNfa_10(jjStopStringLiteralDfa_10(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_10() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_10(0xa0000L); default : return jjMoveNfa_10(3, 0); } } private int jjMoveStringLiteralDfa1_10(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_10(0, active0); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_10(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_10(active0, 0x20000L); default : break; } return jjStartNfa_10(0, active0); } private int jjMoveStringLiteralDfa2_10(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_10(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_10(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_10(1, active0); } private int jjStartNfaWithStates_10(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_10(state, pos + 1); } private int jjMoveNfa_10(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 15; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if ((0x2400L & l) != 0L) { if (kind > 25) kind = 25; } else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(12, 13); } else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; if (curChar == 13) jjstateSet[jjnewStateCnt++] = 5; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 4: if ((0x2400L & l) != 0L && kind > 25) kind = 25; break; case 5: if (curChar == 10 && kind > 25) kind = 25; break; case 6: if (curChar == 13) jjstateSet[jjnewStateCnt++] = 5; break; case 9: if (curChar == 36 && kind > 15) kind = 15; break; case 11: if (curChar == 36) jjCheckNAddTwoStates(12, 13); break; case 13: if (curChar == 33 && kind > 16) kind = 16; break; case 14: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(12, 13); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(165, 168); break; case 1: if (kind > 18) kind = 18; break; case 8: if (curChar == 92) jjCheckNAddTwoStates(8, 9); break; case 10: if (curChar == 92) jjCheckNAddTwoStates(10, 11); break; case 12: if (curChar == 92) jjAddStates(169, 170); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 15 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1) { switch (pos) { case 0: if ((active0 & 0x3a0000L) != 0L) return 33; if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; return 13; } return -1; case 1: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 1; return 13; } if ((active0 & 0x80000L) != 0L) return 31; return -1; case 2: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 2; return 13; } return -1; case 3: if ((active0 & 0x200000000L) != 0L) return 13; if ((active0 & 0x400000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 3; return 13; } return -1; default : return -1; } } private final int jjStartNfa_0(int pos, long active0, long active1) { return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); } private int jjMoveStringLiteralDfa0_0() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_0(0x2a0000L); case 91: return jjStopAtPos(0, 1); case 102: return jjMoveStringLiteralDfa1_0(0x400000000L); case 116: return jjMoveStringLiteralDfa1_0(0x200000000L); case 123: return jjStopAtPos(0, 68); case 125: return jjStopAtPos(0, 69); default : return jjMoveNfa_0(12, 0); } } private int jjMoveStringLiteralDfa1_0(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_0(0, active0, 0L); return 1; } switch(curChar) { case 35: if ((active0 & 0x200000L) != 0L) return jjStopAtPos(1, 21); break; case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_0(1, 19, 31); break; case 91: return jjMoveStringLiteralDfa2_0(active0, 0x20000L); case 97: return jjMoveStringLiteralDfa2_0(active0, 0x400000000L); case 114: return jjMoveStringLiteralDfa2_0(active0, 0x200000000L); default : break; } return jjStartNfa_0(0, active0, 0L); } private int jjMoveStringLiteralDfa2_0(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_0(0, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_0(1, active0, 0L); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; case 108: return jjMoveStringLiteralDfa3_0(active0, 0x400000000L); case 117: return jjMoveStringLiteralDfa3_0(active0, 0x200000000L); default : break; } return jjStartNfa_0(1, active0, 0L); } private int jjMoveStringLiteralDfa3_0(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_0(1, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_0(2, active0, 0L); return 3; } switch(curChar) { case 101: if ((active0 & 0x200000000L) != 0L) return jjStartNfaWithStates_0(3, 33, 13); break; case 115: return jjMoveStringLiteralDfa4_0(active0, 0x400000000L); default : break; } return jjStartNfa_0(2, active0, 0L); } private int jjMoveStringLiteralDfa4_0(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_0(2, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_0(3, active0, 0L); return 4; } switch(curChar) { case 101: if ((active0 & 0x400000000L) != 0L) return jjStartNfaWithStates_0(4, 34, 13); break; default : break; } return jjStartNfa_0(3, active0, 0L); } private int jjStartNfaWithStates_0(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_0(state, pos + 1); } private int jjMoveNfa_0(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 34; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 12: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); else if (curChar == 35) jjCheckNAddStates(171, 173); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(27, 28); } else if (curChar == 46) jjstateSet[jjnewStateCnt++] = 15; if (curChar == 36) jjCheckNAddStates(174, 177); break; case 33: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 31; break; case 0: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); break; case 1: if (curChar == 35) jjCheckNAddTwoStates(6, 11); break; case 3: if (curChar == 32) jjAddStates(112, 113); break; case 4: if (curChar == 40 && kind > 14) kind = 14; break; case 13: if ((0x3ff200000000000L & l) == 0L) break; if (kind > 66) kind = 66; jjstateSet[jjnewStateCnt++] = 13; break; case 14: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 15; break; case 16: if (curChar == 36) jjCheckNAddStates(174, 177); break; case 18: case 19: if (curChar == 33) jjCheckNAdd(17); break; case 21: if (curChar == 46 && kind > 72) kind = 72; break; case 24: if (curChar == 36 && kind > 15) kind = 15; break; case 26: if (curChar == 36) jjCheckNAddTwoStates(27, 28); break; case 28: if (curChar == 33 && kind > 16) kind = 16; break; case 29: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(27, 28); break; case 30: if (curChar == 35) jjCheckNAddStates(171, 173); break; case 31: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 32; break; case 32: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 12: if ((0x7fffffe87fffffeL & l) != 0L) { if (kind > 66) kind = 66; jjCheckNAdd(13); } else if (curChar == 92) jjCheckNAddStates(178, 181); break; case 33: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; else if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 2: if (curChar == 116) jjCheckNAddTwoStates(3, 4); break; case 5: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 2; break; case 6: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 7: if (curChar == 125) jjCheckNAddTwoStates(3, 4); break; case 8: if (curChar == 116) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 8; break; case 10: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 9; break; case 11: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; break; case 13: if ((0x7fffffe87fffffeL & l) == 0L) break; if (kind > 66) kind = 66; jjCheckNAdd(13); break; case 15: if ((0x7fffffe07fffffeL & l) != 0L && kind > 67) kind = 67; break; case 17: if (curChar == 91 && kind > 72) kind = 72; break; case 20: if (curChar == 92) jjstateSet[jjnewStateCnt++] = 19; break; case 22: if (curChar == 92) jjCheckNAddStates(178, 181); break; case 23: if (curChar == 92) jjCheckNAddTwoStates(23, 24); break; case 25: if (curChar == 92) jjCheckNAddTwoStates(25, 26); break; case 27: if (curChar == 92) jjAddStates(182, 183); break; case 32: if (kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 32: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 34 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_4(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 52; if ((active0 & 0x40L) != 0L) return 74; if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; return 40; } return -1; case 1: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 1; return 40; } if ((active0 & 0x80000L) != 0L) return 50; return -1; case 2: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 2; return 40; } return -1; case 3: if ((active0 & 0x200000000L) != 0L) return 40; if ((active0 & 0x400000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 3; return 40; } return -1; default : return -1; } } private final int jjStartNfa_4(int pos, long active0) { return jjMoveNfa_4(jjStopStringLiteralDfa_4(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_4() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_4(0xa0000L); case 41: return jjStopAtPos(0, 12); case 44: return jjStopAtPos(0, 5); case 46: return jjMoveStringLiteralDfa1_4(0x40L); case 58: return jjStopAtPos(0, 7); case 91: return jjStopAtPos(0, 3); case 93: return jjStopAtPos(0, 4); case 102: return jjMoveStringLiteralDfa1_4(0x400000000L); case 116: return jjMoveStringLiteralDfa1_4(0x200000000L); case 123: return jjStopAtPos(0, 8); case 125: return jjStopAtPos(0, 9); default : return jjMoveNfa_4(13, 0); } } private int jjMoveStringLiteralDfa1_4(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_4(0, active0); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_4(1, 19, 50); break; case 46: if ((active0 & 0x40L) != 0L) return jjStopAtPos(1, 6); break; case 91: return jjMoveStringLiteralDfa2_4(active0, 0x20000L); case 97: return jjMoveStringLiteralDfa2_4(active0, 0x400000000L); case 114: return jjMoveStringLiteralDfa2_4(active0, 0x200000000L); default : break; } return jjStartNfa_4(0, active0); } private int jjMoveStringLiteralDfa2_4(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_4(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_4(1, active0); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; case 108: return jjMoveStringLiteralDfa3_4(active0, 0x400000000L); case 117: return jjMoveStringLiteralDfa3_4(active0, 0x200000000L); default : break; } return jjStartNfa_4(1, active0); } private int jjMoveStringLiteralDfa3_4(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_4(1, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_4(2, active0); return 3; } switch(curChar) { case 101: if ((active0 & 0x200000000L) != 0L) return jjStartNfaWithStates_4(3, 33, 40); break; case 115: return jjMoveStringLiteralDfa4_4(active0, 0x400000000L); default : break; } return jjStartNfa_4(2, active0); } private int jjMoveStringLiteralDfa4_4(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_4(2, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_4(3, active0); return 4; } switch(curChar) { case 101: if ((active0 & 0x400000000L) != 0L) return jjStartNfaWithStates_4(4, 34, 40); break; default : break; } return jjStartNfa_4(3, active0); } private int jjStartNfaWithStates_4(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_4(state, pos + 1); } private int jjMoveNfa_4(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 75; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 52: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 50; break; case 74: case 64: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(64, 65); break; case 13: if ((0x3ff000000000000L & l) != 0L) { if (kind > 56) kind = 56; jjCheckNAddStates(184, 189); } else if ((0x100002600L & l) != 0L) { if (kind > 31) kind = 31; jjCheckNAdd(12); } else if (curChar == 46) jjCheckNAddTwoStates(64, 74); else if (curChar == 45) jjCheckNAddStates(190, 193); else if (curChar == 35) jjCheckNAddStates(194, 196); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(46, 47); } else if (curChar == 39) jjCheckNAddStates(197, 200); else if (curChar == 34) jjCheckNAddStates(201, 204); if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); break; case 0: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); break; case 1: if (curChar == 35) jjCheckNAddTwoStates(6, 11); break; case 3: if (curChar == 32) jjAddStates(112, 113); break; case 4: if (curChar == 40 && kind > 14) kind = 14; break; case 12: if ((0x100002600L & l) == 0L) break; if (kind > 31) kind = 31; jjCheckNAdd(12); break; case 14: if ((0xfffffffbffffffffL & l) != 0L) jjCheckNAddStates(201, 204); break; case 15: if (curChar == 34) jjCheckNAddStates(201, 204); break; case 16: if (curChar == 34) jjstateSet[jjnewStateCnt++] = 15; break; case 17: if (curChar == 34 && kind > 32) kind = 32; break; case 20: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(205, 209); break; case 21: if ((0xff000000000000L & l) != 0L) jjCheckNAddStates(201, 204); break; case 22: if ((0xf000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 23; break; case 23: if ((0xff000000000000L & l) != 0L) jjCheckNAdd(21); break; case 25: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 26; break; case 26: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 27; break; case 27: if ((0x3ff000000000000L & l) != 0L) jjstateSet[jjnewStateCnt++] = 28; break; case 28: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddStates(201, 204); break; case 29: if (curChar == 32) jjAddStates(210, 211); break; case 30: if (curChar == 10) jjCheckNAddStates(201, 204); break; case 31: case 33: if (curChar == 39) jjCheckNAddStates(197, 200); break; case 32: if ((0xffffff7fffffffffL & l) != 0L) jjCheckNAddStates(197, 200); break; case 34: if (curChar == 39) jjstateSet[jjnewStateCnt++] = 33; break; case 36: if (curChar == 32) jjAddStates(212, 213); break; case 37: if (curChar == 10) jjCheckNAddStates(197, 200); break; case 38: if (curChar == 39 && kind > 32) kind = 32; break; case 40: if ((0x3ff200000000000L & l) == 0L) break; if (kind > 66) kind = 66; jjstateSet[jjnewStateCnt++] = 40; break; case 43: if (curChar == 36 && kind > 15) kind = 15; break; case 45: if (curChar == 36) jjCheckNAddTwoStates(46, 47); break; case 47: if (curChar == 33 && kind > 16) kind = 16; break; case 48: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(46, 47); break; case 49: if (curChar == 35) jjCheckNAddStates(194, 196); break; case 50: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 51; break; case 51: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 53: if (curChar == 45) jjCheckNAddStates(190, 193); break; case 54: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddTwoStates(54, 56); break; case 55: if (curChar == 46 && kind > 56) kind = 56; break; case 56: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 55; break; case 57: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(57, 58); break; case 58: if (curChar != 46) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(59, 60); break; case 59: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAddTwoStates(59, 60); break; case 61: if ((0x280000000000L & l) != 0L) jjCheckNAdd(62); break; case 62: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(62); break; case 63: if (curChar == 46) jjCheckNAdd(64); break; case 66: if ((0x280000000000L & l) != 0L) jjCheckNAdd(67); break; case 67: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(67); break; case 68: if ((0x3ff000000000000L & l) != 0L) jjCheckNAddTwoStates(68, 69); break; case 70: if ((0x280000000000L & l) != 0L) jjCheckNAdd(71); break; case 71: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 57) kind = 57; jjCheckNAdd(71); break; case 72: if ((0x3ff000000000000L & l) == 0L) break; if (kind > 56) kind = 56; jjCheckNAddStates(184, 189); break; case 73: if (curChar == 46) jjCheckNAddTwoStates(64, 74); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 52: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; else if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 74: if ((0x7fffffe07fffffeL & l) != 0L && kind > 67) kind = 67; break; case 13: if ((0x7fffffe87fffffeL & l) != 0L) { if (kind > 66) kind = 66; jjCheckNAdd(40); } else if (curChar == 92) jjCheckNAddStates(214, 217); break; case 2: if (curChar == 116) jjCheckNAddTwoStates(3, 4); break; case 5: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 2; break; case 6: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 7: if (curChar == 125) jjCheckNAddTwoStates(3, 4); break; case 8: if (curChar == 116) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 8; break; case 10: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 9; break; case 11: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; break; case 14: jjCheckNAddStates(201, 204); break; case 18: if (curChar == 92) jjAddStates(218, 223); break; case 19: if ((0x14404400000000L & l) != 0L) jjCheckNAddStates(201, 204); break; case 24: if (curChar == 117) jjstateSet[jjnewStateCnt++] = 25; break; case 25: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 26; break; case 26: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 27; break; case 27: if ((0x7e0000007eL & l) != 0L) jjstateSet[jjnewStateCnt++] = 28; break; case 28: if ((0x7e0000007eL & l) != 0L) jjCheckNAddStates(201, 204); break; case 32: jjAddStates(197, 200); break; case 35: if (curChar == 92) jjAddStates(212, 213); break; case 39: case 40: if ((0x7fffffe87fffffeL & l) == 0L) break; if (kind > 66) kind = 66; jjCheckNAdd(40); break; case 41: if (curChar == 92) jjCheckNAddStates(214, 217); break; case 42: if (curChar == 92) jjCheckNAddTwoStates(42, 43); break; case 44: if (curChar == 92) jjCheckNAddTwoStates(44, 45); break; case 46: if (curChar == 92) jjAddStates(224, 225); break; case 51: if (kind > 18) kind = 18; break; case 60: if ((0x2000000020L & l) != 0L) jjAddStates(226, 227); break; case 65: if ((0x2000000020L & l) != 0L) jjAddStates(228, 229); break; case 69: if ((0x2000000020L & l) != 0L) jjAddStates(30, 31); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 14: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(201, 204); break; case 32: if (jjCanMove_0(hiByte, i1, i2, l1, l2)) jjAddStates(197, 200); break; case 51: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 75 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_1(int pos, long active0, long active1) { switch (pos) { case 0: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; return 13; } if ((active0 & 0x1a0000L) != 0L) return 27; return -1; case 1: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 1; return 13; } if ((active0 & 0x80000L) != 0L) return 25; return -1; case 2: if ((active0 & 0x600000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 2; return 13; } return -1; case 3: if ((active0 & 0x200000000L) != 0L) return 13; if ((active0 & 0x400000000L) != 0L) { jjmatchedKind = 66; jjmatchedPos = 3; return 13; } return -1; default : return -1; } } private final int jjStartNfa_1(int pos, long active0, long active1) { return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0, active1), pos + 1); } private int jjMoveStringLiteralDfa0_1() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_1(0xa0000L); case 40: return jjStopAtPos(0, 10); case 91: return jjStopAtPos(0, 1); case 102: return jjMoveStringLiteralDfa1_1(0x400000000L); case 116: return jjMoveStringLiteralDfa1_1(0x200000000L); case 123: return jjStopAtPos(0, 68); case 125: return jjStopAtPos(0, 69); default : return jjMoveNfa_1(12, 0); } } private int jjMoveStringLiteralDfa1_1(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_1(0, active0, 0L); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_1(1, 19, 25); break; case 91: return jjMoveStringLiteralDfa2_1(active0, 0x20000L); case 97: return jjMoveStringLiteralDfa2_1(active0, 0x400000000L); case 114: return jjMoveStringLiteralDfa2_1(active0, 0x200000000L); default : break; } return jjStartNfa_1(0, active0, 0L); } private int jjMoveStringLiteralDfa2_1(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_1(0, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_1(1, active0, 0L); return 2; } switch(curChar) { case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; case 108: return jjMoveStringLiteralDfa3_1(active0, 0x400000000L); case 117: return jjMoveStringLiteralDfa3_1(active0, 0x200000000L); default : break; } return jjStartNfa_1(1, active0, 0L); } private int jjMoveStringLiteralDfa3_1(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_1(1, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_1(2, active0, 0L); return 3; } switch(curChar) { case 101: if ((active0 & 0x200000000L) != 0L) return jjStartNfaWithStates_1(3, 33, 13); break; case 115: return jjMoveStringLiteralDfa4_1(active0, 0x400000000L); default : break; } return jjStartNfa_1(2, active0, 0L); } private int jjMoveStringLiteralDfa4_1(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_1(2, old0, 0L); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_1(3, active0, 0L); return 4; } switch(curChar) { case 101: if ((active0 & 0x400000000L) != 0L) return jjStartNfaWithStates_1(4, 34, 13); break; default : break; } return jjStartNfa_1(3, active0, 0L); } private int jjStartNfaWithStates_1(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_1(state, pos + 1); } private int jjMoveNfa_1(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 28; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 12: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); else if (curChar == 35) jjCheckNAddStates(230, 232); else if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(21, 22); } else if (curChar == 46) jjstateSet[jjnewStateCnt++] = 15; break; case 27: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 25; break; case 0: if ((0x100000200L & l) != 0L) jjCheckNAddTwoStates(0, 1); break; case 1: if (curChar == 35) jjCheckNAddTwoStates(6, 11); break; case 3: if (curChar == 32) jjAddStates(112, 113); break; case 4: if (curChar == 40 && kind > 14) kind = 14; break; case 13: if ((0x3ff200000000000L & l) == 0L) break; if (kind > 66) kind = 66; jjstateSet[jjnewStateCnt++] = 13; break; case 14: if (curChar == 46) jjstateSet[jjnewStateCnt++] = 15; break; case 18: if (curChar == 36 && kind > 15) kind = 15; break; case 20: if (curChar == 36) jjCheckNAddTwoStates(21, 22); break; case 22: if (curChar == 33 && kind > 16) kind = 16; break; case 23: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(21, 22); break; case 24: if (curChar == 35) jjCheckNAddStates(230, 232); break; case 25: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 26; break; case 26: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 12: if ((0x7fffffe87fffffeL & l) != 0L) { if (kind > 66) kind = 66; jjCheckNAdd(13); } else if (curChar == 92) jjCheckNAddStates(233, 236); break; case 27: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; else if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 2: if (curChar == 116) jjCheckNAddTwoStates(3, 4); break; case 5: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 2; break; case 6: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 5; break; case 7: if (curChar == 125) jjCheckNAddTwoStates(3, 4); break; case 8: if (curChar == 116) jjstateSet[jjnewStateCnt++] = 7; break; case 9: if (curChar == 101) jjstateSet[jjnewStateCnt++] = 8; break; case 10: if (curChar == 115) jjstateSet[jjnewStateCnt++] = 9; break; case 11: if (curChar == 123) jjstateSet[jjnewStateCnt++] = 10; break; case 13: if ((0x7fffffe87fffffeL & l) == 0L) break; if (kind > 66) kind = 66; jjCheckNAdd(13); break; case 15: if ((0x7fffffe07fffffeL & l) != 0L && kind > 67) kind = 67; break; case 16: if (curChar == 92) jjCheckNAddStates(233, 236); break; case 17: if (curChar == 92) jjCheckNAddTwoStates(17, 18); break; case 19: if (curChar == 92) jjCheckNAddTwoStates(19, 20); break; case 21: if (curChar == 92) jjAddStates(143, 144); break; case 26: if (kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 26: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 28 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } private final int jjStopStringLiteralDfa_7(int pos, long active0) { switch (pos) { case 0: if ((active0 & 0x1a0000L) != 0L) return 2; return -1; case 1: if ((active0 & 0x80000L) != 0L) return 0; return -1; default : return -1; } } private final int jjStartNfa_7(int pos, long active0) { return jjMoveNfa_7(jjStopStringLiteralDfa_7(pos, active0), pos + 1); } private int jjMoveStringLiteralDfa0_7() { switch(curChar) { case 35: jjmatchedKind = 20; return jjMoveStringLiteralDfa1_7(0xa0000L); case 93: return jjMoveStringLiteralDfa1_7(0x10000000L); default : return jjMoveNfa_7(3, 0); } } private int jjMoveStringLiteralDfa1_7(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_7(0, active0); return 1; } switch(curChar) { case 42: if ((active0 & 0x80000L) != 0L) return jjStartNfaWithStates_7(1, 19, 0); break; case 91: return jjMoveStringLiteralDfa2_7(active0, 0x20000L); case 93: return jjMoveStringLiteralDfa2_7(active0, 0x10000000L); default : break; } return jjStartNfa_7(0, active0); } private int jjMoveStringLiteralDfa2_7(long old0, long active0) { if (((active0 &= old0)) == 0L) return jjStartNfa_7(0, old0); try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { jjStopStringLiteralDfa_7(1, active0); return 2; } switch(curChar) { case 35: if ((active0 & 0x10000000L) != 0L) return jjStopAtPos(2, 28); break; case 91: if ((active0 & 0x20000L) != 0L) return jjStopAtPos(2, 17); break; default : break; } return jjStartNfa_7(1, active0); } private int jjStartNfaWithStates_7(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } return jjMoveNfa_7(state, pos + 1); } private int jjMoveNfa_7(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 12; int i = 1; jjstateSet[0] = startState; int kind = 0x7fffffff; for (;;) { if (++jjround == 0x7fffffff) ReInitRounds(); if (curChar < 64) { long l = 1L << curChar; do { switch(jjstateSet[--i]) { case 3: if (curChar == 36) { if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); } else if (curChar == 35) jjstateSet[jjnewStateCnt++] = 2; break; case 0: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 1; break; case 1: if ((0xfffffff7ffffffffL & l) != 0L && kind > 18) kind = 18; break; case 2: if (curChar == 42) jjstateSet[jjnewStateCnt++] = 0; break; case 6: if (curChar == 36 && kind > 15) kind = 15; break; case 8: if (curChar == 36) jjCheckNAddTwoStates(9, 10); break; case 10: if (curChar == 33 && kind > 16) kind = 16; break; case 11: if (curChar != 36) break; if (kind > 15) kind = 15; jjCheckNAddTwoStates(9, 10); break; default : break; } } while(i != startsAt); } else if (curChar < 128) { long l = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 3: if (curChar == 92) jjCheckNAddStates(99, 102); break; case 1: if (kind > 18) kind = 18; break; case 5: if (curChar == 92) jjCheckNAddTwoStates(5, 6); break; case 7: if (curChar == 92) jjCheckNAddTwoStates(7, 8); break; case 9: if (curChar == 92) jjAddStates(91, 92); break; default : break; } } while(i != startsAt); } else { int hiByte = (int)(curChar >> 8); int i1 = hiByte >> 6; long l1 = 1L << (hiByte & 077); int i2 = (curChar & 0xff) >> 6; long l2 = 1L << (curChar & 077); do { switch(jjstateSet[--i]) { case 1: if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 18) kind = 18; break; default : break; } } while(i != startsAt); } if (kind != 0x7fffffff) { jjmatchedKind = kind; jjmatchedPos = curPos; kind = 0x7fffffff; } ++curPos; if ((i = jjnewStateCnt) == (startsAt = 12 - (jjnewStateCnt = startsAt))) return curPos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return curPos; } } } static final int[] jjnextStates = { 91, 93, 94, 95, 100, 101, 91, 94, 61, 100, 29, 31, 32, 35, 11, 13, 14, 15, 1, 2, 4, 11, 18, 13, 14, 15, 26, 27, 33, 34, 70, 71, 73, 74, 75, 76, 87, 89, 84, 85, 81, 82, 16, 17, 19, 21, 26, 27, 64, 65, 77, 78, 98, 99, 102, 103, 69, 71, 72, 73, 78, 79, 69, 72, 6, 78, 15, 16, 27, 28, 30, 38, 39, 41, 46, 28, 47, 62, 39, 63, 50, 53, 60, 67, 18, 19, 20, 21, 31, 36, 43, 9, 10, 22, 23, 76, 77, 80, 81, 5, 6, 7, 8, 6, 11, 39, 14, 15, 17, 18, 22, 24, 3, 4, 20, 21, 29, 30, 31, 32, 45, 47, 48, 49, 54, 55, 45, 48, 31, 54, 24, 26, 27, 30, 6, 8, 9, 10, 6, 13, 8, 9, 10, 21, 22, 28, 29, 37, 38, 39, 40, 11, 12, 14, 16, 21, 22, 34, 35, 41, 42, 52, 53, 56, 57, 8, 9, 10, 11, 12, 13, 6, 11, 33, 17, 18, 20, 21, 23, 24, 25, 26, 27, 28, 54, 56, 57, 58, 68, 69, 54, 57, 63, 68, 6, 11, 52, 32, 34, 35, 38, 14, 16, 17, 18, 14, 21, 16, 17, 18, 29, 30, 36, 37, 42, 43, 44, 45, 19, 20, 22, 24, 29, 30, 46, 47, 61, 62, 66, 67, 6, 11, 27, 17, 18, 19, 20, }; private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) { switch(hiByte) { case 0: return ((jjbitVec2[i2] & l2) != 0L); default : if ((jjbitVec0[i1] & l1) != 0L) return true; return false; } } /** Token literal values. */ public static final String[] jjstrLiteralImages = { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }; /** Lexer state names. */ public static final String[] lexStateNames = { "REFERENCE", "REFMODIFIER", "REFINDEX", "DIRECTIVE", "REFMOD2", "DEFAULT", "REFMOD", "IN_TEXTBLOCK", "IN_MULTI_LINE_COMMENT", "IN_FORMAL_COMMENT", "IN_SINGLE_LINE_COMMENT", "PRE_DIRECTIVE", }; /** Lex State array. */ public static final int[] jjnewLexState = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; static final long[] jjtoToken = { 0x637fffff9fe07fffL, 0x13cL, }; static final long[] jjtoSkip = { 0x20000000L, 0xc0L, }; static final long[] jjtoSpecial = { 0x0L, 0xc0L, }; static final long[] jjtoMore = { 0x401f8000L, 0x0L, }; protected CharStream input_stream; private final int[] jjrounds = new int[105]; private final int[] jjstateSet = new int[210]; private final StrBuilder jjimage = new StrBuilder(); private StrBuilder image = jjimage; private int jjimageLen; private int lengthOfMatch; protected char curChar; /** Constructor. */ public ParserTokenManager(CharStream stream){ input_stream = stream; } /** Constructor. */ public ParserTokenManager(CharStream stream, int lexState){ this(stream); SwitchTo(lexState); } /** Reinitialise parser. */ public void ReInit(CharStream stream) { jjmatchedPos = jjnewStateCnt = 0; curLexState = defaultLexState; input_stream = stream; ReInitRounds(); } private void ReInitRounds() { int i; jjround = 0x80000001; for (i = 105; i-- > 0;) jjrounds[i] = 0x80000000; } /** Reinitialise parser. */ public void ReInit(CharStream stream, int lexState) { ReInit(stream); SwitchTo(lexState); } /** Switch to specified lex state. */ public void SwitchTo(int lexState) { if (lexState >= 12 || lexState < 0) throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); else curLexState = lexState; } protected Token jjFillToken() { final Token t; final String curTokenImage; final int beginLine; final int endLine; final int beginColumn; final int endColumn; String im = jjstrLiteralImages[jjmatchedKind]; curTokenImage = (im == null) ? input_stream.GetImage() : im; beginLine = input_stream.getBeginLine(); beginColumn = input_stream.getBeginColumn(); endLine = input_stream.getEndLine(); endColumn = input_stream.getEndColumn(); t = Token.newToken(jjmatchedKind); t.kind = jjmatchedKind; t.image = curTokenImage; t.beginLine = beginLine; t.endLine = endLine; t.beginColumn = beginColumn; t.endColumn = endColumn; return t; } int curLexState = 5; int defaultLexState = 5; int jjnewStateCnt; int jjround; int jjmatchedPos; int jjmatchedKind; /** Get the next Token. */ public Token getNextToken() { Token specialToken = null; Token matchedToken; int curPos = 0; EOFLoop : for (;;) { try { curChar = input_stream.BeginToken(); } catch(java.io.IOException e) { jjmatchedKind = 0; matchedToken = jjFillToken(); matchedToken.specialToken = specialToken; return matchedToken; } image = jjimage; image.setLength(0); jjimageLen = 0; for (;;) { switch(curLexState) { case 0: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_0(); if (jjmatchedPos == 0 && jjmatchedKind > 70) { jjmatchedKind = 70; } break; case 1: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_1(); if (jjmatchedPos == 0 && jjmatchedKind > 70) { jjmatchedKind = 70; } break; case 2: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_2(); break; case 3: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_3(); break; case 4: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_4(); break; case 5: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_5(); break; case 6: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_6(); if (jjmatchedPos == 0 && jjmatchedKind > 70) { jjmatchedKind = 70; } break; case 7: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_7(); if (jjmatchedPos == 0 && jjmatchedKind > 30) { jjmatchedKind = 30; } break; case 8: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_8(); if (jjmatchedPos == 0 && jjmatchedKind > 29) { jjmatchedKind = 29; } break; case 9: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_9(); if (jjmatchedPos == 0 && jjmatchedKind > 29) { jjmatchedKind = 29; } break; case 10: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_10(); if (jjmatchedPos == 0 && jjmatchedKind > 29) { jjmatchedKind = 29; } break; case 11: jjmatchedKind = 0x7fffffff; jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_11(); if (jjmatchedPos == 0 && jjmatchedKind > 71) { jjmatchedKind = 71; } break; } if (jjmatchedKind != 0x7fffffff) { if (jjmatchedPos + 1 < curPos) input_stream.backup(curPos - jjmatchedPos - 1); if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { matchedToken = jjFillToken(); matchedToken.specialToken = specialToken; TokenLexicalActions(matchedToken); if (jjnewLexState[jjmatchedKind] != -1) curLexState = jjnewLexState[jjmatchedKind]; return matchedToken; } else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { matchedToken = jjFillToken(); if (specialToken == null) specialToken = matchedToken; else { matchedToken.specialToken = specialToken; specialToken = (specialToken.next = matchedToken); } SkipLexicalActions(matchedToken); } else SkipLexicalActions(null); if (jjnewLexState[jjmatchedKind] != -1) curLexState = jjnewLexState[jjmatchedKind]; continue EOFLoop; } MoreLexicalActions(); if (jjnewLexState[jjmatchedKind] != -1) curLexState = jjnewLexState[jjmatchedKind]; curPos = 0; jjmatchedKind = 0x7fffffff; try { curChar = input_stream.readChar(); continue; } catch (java.io.IOException e1) { } } int error_line = input_stream.getEndLine(); int error_column = input_stream.getEndColumn(); String error_after = null; boolean EOFSeen = false; try { input_stream.readChar(); input_stream.backup(1); } catch (java.io.IOException e1) { EOFSeen = true; error_after = curPos <= 1 ? "" : input_stream.GetImage(); if (curChar == '\n' || curChar == '\r') { error_line++; error_column = 0; } else error_column++; } if (!EOFSeen) { input_stream.backup(1); error_after = curPos <= 1 ? "" : input_stream.GetImage(); } throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); } } } void SkipLexicalActions(Token matchedToken) { switch(jjmatchedKind) { case 70 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * push every terminator character back into the stream */ input_stream.backup(1); inReference = false; if ( debugPrint ) System.out.print("REF_TERM :"); stateStackPop(); break; case 71 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); if ( debugPrint ) System.out.print("DIRECTIVE_TERM :"); input_stream.backup(1); inDirective = false; stateStackPop(); break; default : break; } } void MoreLexicalActions() { jjimageLen += (lengthOfMatch = jjmatchedPos + 1); switch(jjmatchedKind) { case 15 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (! inComment) { /* * if we find ourselves in REFERENCE, we need to pop down * to end the previous ref */ if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inReference = true; if ( debugPrint ) System.out.print( "$ : going to " + REFERENCE ); stateStackPush(); SwitchTo(REFERENCE); } break; case 16 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (! inComment) { /* * if we find ourselves in REFERENCE, we need to pop down * to end the previous ref */ if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inReference = true; if ( debugPrint ) System.out.print( "$! : going to " + REFERENCE ); stateStackPush(); SwitchTo(REFERENCE); } break; case 17 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (!inComment) { inComment = true; stateStackPush(); SwitchTo( IN_TEXTBLOCK ); } break; case 18 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (!inComment) { input_stream.backup(1); inComment = true; stateStackPush(); SwitchTo( IN_FORMAL_COMMENT); } break; case 19 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (!inComment) { inComment=true; stateStackPush(); SwitchTo( IN_MULTI_LINE_COMMENT ); } break; case 20 : image.append(input_stream.GetSuffix(jjimageLen)); jjimageLen = 0; if (! inComment) { /* * We can have the situation where #if($foo)$foo#end. * We need to transition out of REFERENCE before going to DIRECTIVE. * I don't really like this, but I can't think of a legal way * you are going into DIRECTIVE while in REFERENCE. -gmj */ if (curLexState == REFERENCE || curLexState == REFMODIFIER ) { inReference = false; stateStackPop(); } inDirective = true; if ( debugPrint ) System.out.print("# : going to " + DIRECTIVE ); stateStackPush(); SwitchTo(PRE_DIRECTIVE); } break; default : break; } } void TokenLexicalActions(Token matchedToken) { switch(jjmatchedKind) { case 1 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); stateStackPush(); SwitchTo(REFINDEX); break; case 2 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); stateStackPop(); break; case 10 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); if (!inComment) lparen++; /* * If in REFERENCE and we have seen the dot, then move * to REFMOD2 -> Modifier() */ if (curLexState == REFMODIFIER ) SwitchTo( REFMOD2 ); break; case 11 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); RPARENHandler(); break; case 12 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * need to simply switch back to REFERENCE, not drop down the stack * because we can (infinitely) chain, ala * $foo.bar().blargh().woogie().doogie() */ SwitchTo( REFERENCE ); break; case 14 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); if (! inComment) { inDirective = true; if ( debugPrint ) System.out.print("#set : going to " + DIRECTIVE ); stateStackPush(); inSet = true; SwitchTo(DIRECTIVE); } /* * need the LPAREN action */ if (!inComment) { lparen++; /* * If in REFERENCE and we have seen the dot, then move * to REFMOD2 -> Modifier() */ if (curLexState == REFMODIFIER ) SwitchTo( REFMOD2 ); } break; case 21 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); if (!inComment) { if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inComment = true; stateStackPush(); SwitchTo(IN_SINGLE_LINE_COMMENT); } break; case 25 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inComment = false; stateStackPop(); break; case 26 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inComment = false; stateStackPop(); break; case 27 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inComment = false; stateStackPop(); break; case 28 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inComment = false; stateStackPop(); break; case 32 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. * don't forget to account for the beloved yet wierd #set * - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok! */ if( curLexState == DIRECTIVE && !inSet && lparen == 0) stateStackPop(); break; case 35 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); if ( debugPrint ) System.out.println(" NEWLINE :"); stateStackPop(); if (inSet) inSet = false; if (inDirective) inDirective = false; break; case 51 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inDirective = false; stateStackPop(); break; case 52 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); SwitchTo(DIRECTIVE); break; case 53 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); SwitchTo(DIRECTIVE); break; case 54 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); inDirective = false; stateStackPop(); break; case 56 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * Remove the double period if it is there */ if (matchedToken.image.endsWith("..")) { input_stream.backup(2); matchedToken.image = matchedToken.image.substring(0,matchedToken.image.length()-2); } /* * check to see if we are in set * ex. #set $foo = $foo + 3 * because we want to handle the \n after */ if ( lparen == 0 && !inSet && curLexState != REFMOD2 && curLexState != REFINDEX) { stateStackPop(); } break; case 57 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * check to see if we are in set * ex. #set $foo = $foo + 3 * because we want to handle the \n after */ if ( lparen == 0 && !inSet && curLexState != REFMOD2) { stateStackPop(); } break; case 67 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); /* * push the alpha char back into the stream so the following identifier * is complete */ input_stream.backup(1); /* * and munge the so we just get a . when we have normal text that * looks like a ref.ident */ matchedToken.image = "."; if ( debugPrint ) System.out.print("DOT : switching to " + REFMODIFIER); SwitchTo(REFMODIFIER); break; case 69 : image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))); stateStackPop(); break; default : break; } } private void jjCheckNAdd(int state) { if (jjrounds[state] != jjround) { jjstateSet[jjnewStateCnt++] = state; jjrounds[state] = jjround; } } private void jjAddStates(int start, int end) { do { jjstateSet[jjnewStateCnt++] = jjnextStates[start]; } while (start++ != end); } private void jjCheckNAddTwoStates(int state1, int state2) { jjCheckNAdd(state1); jjCheckNAdd(state2); } private void jjCheckNAddStates(int start, int end) { do { jjCheckNAdd(jjnextStates[start]); } while (start++ != end); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/VelocityCharStream.java0000644000175000017500000003304311051347261030052 0ustar moellermoellerpackage org.apache.velocity.runtime.parser; /* * 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. */ /** * NOTE : This class was originally an ASCII_CharStream autogenerated * by Javacc. It was then modified via changing class name with appropriate * fixes for CTORS, and mods to readChar(). * * This is safe because we *always* use Reader with this class, and never a * InputStream. This guarantees that we have a correct stream of 16-bit * chars - all encoding transformations have been done elsewhere, so we * believe that there is no risk in doing this. Time will tell :) */ /** * An implementation of interface CharStream, where the stream is assumed to * contain only ASCII characters (without unicode processing). */ public final class VelocityCharStream implements CharStream { public static final boolean staticFlag = false; int bufsize; private int nextBufExpand; int available; int tokenBegin; public int bufpos = -1; private int bufline[]; private int bufcolumn[]; private int column = 0; private int line = 1; private boolean prevCharIsCR = false; private boolean prevCharIsLF = false; private java.io.Reader inputStream; private char[] buffer; private int maxNextCharInd = 0; private int inBuf = 0; private final void ExpandBuff(boolean wrapAround) { char[] newbuffer = new char[bufsize + nextBufExpand]; int newbufline[] = new int[bufsize + nextBufExpand]; int newbufcolumn[] = new int[bufsize + nextBufExpand]; try { if (wrapAround) { System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos); buffer = newbuffer; System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); bufline = newbufline; System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); bufcolumn = newbufcolumn; maxNextCharInd = (bufpos += (bufsize - tokenBegin)); } else { System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); buffer = newbuffer; System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); bufline = newbufline; System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); bufcolumn = newbufcolumn; maxNextCharInd = (bufpos -= tokenBegin); } } catch (Throwable t) { throw new Error(t.getMessage()); } bufsize += nextBufExpand; nextBufExpand = bufsize; available = bufsize; tokenBegin = 0; } private final void FillBuff() throws java.io.IOException { if (maxNextCharInd == available) { if (available == bufsize) { if (tokenBegin > nextBufExpand) { bufpos = maxNextCharInd = 0; available = tokenBegin; } else if (tokenBegin < 0) { bufpos = maxNextCharInd = 0; } else { ExpandBuff(false); } } else if (available > tokenBegin) { available = bufsize; } else if ((tokenBegin - available) < nextBufExpand) { ExpandBuff(true); } else { available = tokenBegin; } } int i; try { if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) { inputStream.close(); throw new java.io.IOException(); } else { maxNextCharInd += i; } return; } catch(java.io.IOException e) { --bufpos; backup(0); if (tokenBegin == -1) { tokenBegin = bufpos; } throw e; } } /** * @see org.apache.velocity.runtime.parser.CharStream#BeginToken() */ public final char BeginToken() throws java.io.IOException { tokenBegin = -1; char c = readChar(); tokenBegin = bufpos; return c; } private final void UpdateLineColumn(char c) { column++; if (prevCharIsLF) { prevCharIsLF = false; line += (column = 1); } else if (prevCharIsCR) { prevCharIsCR = false; if (c == '\n') { prevCharIsLF = true; } else { line += (column = 1); } } switch (c) { case '\r' : prevCharIsCR = true; break; case '\n' : prevCharIsLF = true; break; case '\t' : column--; column += (8 - (column & 07)); break; default : break; } bufline[bufpos] = line; bufcolumn[bufpos] = column; } /** * @see org.apache.velocity.runtime.parser.CharStream#readChar() */ public final char readChar() throws java.io.IOException { if (inBuf > 0) { --inBuf; /* * was : return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]); */ return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]; } if (++bufpos >= maxNextCharInd) { FillBuff(); } /* * was : char c = (char)((char)0xff & buffer[bufpos]); */ char c = buffer[bufpos]; UpdateLineColumn(c); return (c); } /** * @see org.apache.velocity.runtime.parser.CharStream#getColumn() * @deprecated */ public final int getColumn() { return bufcolumn[bufpos]; } /** * @see org.apache.velocity.runtime.parser.CharStream#getLine() * @deprecated */ public final int getLine() { return bufline[bufpos]; } /** * @see org.apache.velocity.runtime.parser.CharStream#getEndColumn() */ public final int getEndColumn() { return bufcolumn[bufpos]; } /** * @see org.apache.velocity.runtime.parser.CharStream#getEndLine() */ public final int getEndLine() { return bufline[bufpos]; } /** * @see org.apache.velocity.runtime.parser.CharStream#getBeginColumn() */ public final int getBeginColumn() { return bufcolumn[tokenBegin]; } /** * @see org.apache.velocity.runtime.parser.CharStream#getBeginLine() */ public final int getBeginLine() { return bufline[tokenBegin]; } /** * @see org.apache.velocity.runtime.parser.CharStream#backup(int) */ public final void backup(int amount) { inBuf += amount; if ((bufpos -= amount) < 0) bufpos += bufsize; } /** * @param dstream * @param startline * @param startcolumn * @param buffersize */ public VelocityCharStream(java.io.Reader dstream, int startline, int startcolumn, int buffersize) { inputStream = dstream; line = startline; column = startcolumn - 1; available = bufsize = nextBufExpand = buffersize; buffer = new char[buffersize]; bufline = new int[buffersize]; bufcolumn = new int[buffersize]; } /** * @param dstream * @param startline * @param startcolumn */ public VelocityCharStream(java.io.Reader dstream, int startline, int startcolumn) { this(dstream, startline, startcolumn, 4096); } /** * @param dstream * @param startline * @param startcolumn * @param buffersize */ public void ReInit(java.io.Reader dstream, int startline, int startcolumn, int buffersize) { inputStream = dstream; line = startline; column = startcolumn - 1; if (buffer == null || buffersize != buffer.length) { available = bufsize = nextBufExpand = buffersize; buffer = new char[buffersize]; bufline = new int[buffersize]; bufcolumn = new int[buffersize]; } prevCharIsLF = prevCharIsCR = false; tokenBegin = inBuf = maxNextCharInd = 0; bufpos = -1; } /** * @param dstream * @param startline * @param startcolumn */ public void ReInit(java.io.Reader dstream, int startline, int startcolumn) { ReInit(dstream, startline, startcolumn, 4096); } /** * @param dstream * @param startline * @param startcolumn * @param buffersize */ public VelocityCharStream(java.io.InputStream dstream, int startline, int startcolumn, int buffersize) { this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); } /** * @param dstream * @param startline * @param startcolumn */ public VelocityCharStream(java.io.InputStream dstream, int startline, int startcolumn) { this(dstream, startline, startcolumn, 4096); } /** * @param dstream * @param startline * @param startcolumn * @param buffersize */ public void ReInit(java.io.InputStream dstream, int startline, int startcolumn, int buffersize) { ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); } /** * @param dstream * @param startline * @param startcolumn */ public void ReInit(java.io.InputStream dstream, int startline, int startcolumn) { ReInit(dstream, startline, startcolumn, 4096); } /** * @see org.apache.velocity.runtime.parser.CharStream#GetImage() */ public final String GetImage() { if (bufpos >= tokenBegin) { return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); } else { return new String(buffer, tokenBegin, bufsize - tokenBegin) + new String(buffer, 0, bufpos + 1); } } /** * @see org.apache.velocity.runtime.parser.CharStream#GetSuffix(int) */ public final char[] GetSuffix(int len) { char[] ret = new char[len]; if ((bufpos + 1) >= len) { System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); } else { System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, len - bufpos - 1); System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); } return ret; } /** * @see org.apache.velocity.runtime.parser.CharStream#Done() */ public void Done() { buffer = null; bufline = null; bufcolumn = null; } /** * Method to adjust line and column numbers for the start of a token.
      * @param newLine * @param newCol */ public void adjustBeginLineColumn(int newLine, int newCol) { int start = tokenBegin; int len; if (bufpos >= tokenBegin) { len = bufpos - tokenBegin + inBuf + 1; } else { len = bufsize - tokenBegin + bufpos + 1 + inBuf; } int i = 0, j = 0, k = 0; int nextColDiff = 0, columnDiff = 0; while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) { bufline[j] = newLine; nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; bufcolumn[j] = newCol + columnDiff; columnDiff = nextColDiff; i++; } if (i < len) { bufline[j] = newLine++; bufcolumn[j] = newCol + columnDiff; while (i++ < len) { if (bufline[j = start % bufsize] != bufline[++start % bufsize]) bufline[j] = newLine++; else bufline[j] = newLine; } } line = bufline[j]; column = bufcolumn[j]; } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/build.sh0000755000175000017500000000201710513464370025075 0ustar moellermoeller# !/bin/sh # 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. echo "Running JJTree ..." jjtree Parser.jjt echo "Running JavaCC ..." javacc Parser.jj # Remove the generated nodes as they are now # in a package of their own. rm -f AST* rm -f Node.java rm -f SimpleNode.java rm -f ParserVisitor.java velocity-1.7/src/java/org/apache/velocity/runtime/parser/CharStream.java0000644000175000017500000000715510315733667026353 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. CharStream.java Version 2.1 */ package org.apache.velocity.runtime.parser; /** * This interface describes a character stream that maintains line and * column number positions of the characters. It also has the capability * to backup the stream to some extent. An implementation of this * interface is used in the TokenManager implementation generated by * JavaCCParser. * * All the methods except backup can be implemented in any fashion. backup * needs to be implemented correctly for the correct operation of the lexer. * Rest of the methods are all used to get information like line number, * column number and the String that constitutes a token and are not used * by the lexer. Hence their implementation won't affect the generated lexer's * operation. */ public interface CharStream { /** * Returns the next character from the selected input. The method * of selecting the input is the responsibility of the class * implementing this interface. Can throw any java.io.IOException. */ char readChar() throws java.io.IOException; /** * Returns the column position of the character last read. * @deprecated * @see #getEndColumn */ int getColumn(); /** * Returns the line number of the character last read. * @deprecated * @see #getEndLine */ int getLine(); /** * Returns the column number of the last character for current token (being * matched after the last call to BeginTOken). */ int getEndColumn(); /** * Returns the line number of the last character for current token (being * matched after the last call to BeginTOken). */ int getEndLine(); /** * Returns the column number of the first character for current token (being * matched after the last call to BeginTOken). */ int getBeginColumn(); /** * Returns the line number of the first character for current token (being * matched after the last call to BeginTOken). */ int getBeginLine(); /** * Backs up the input stream by amount steps. Lexer calls this method if it * had already read some characters, but could not use them to match a * (longer) token. So, they will be used again as the prefix of the next * token and it is the implemetation's responsibility to do this right. */ void backup(int amount); /** * Returns the next character that marks the beginning of the next token. * All characters must remain in the buffer between two successive calls * to this method to implement backup correctly. */ char BeginToken() throws java.io.IOException; /** * Returns a string made up of characters from the marked token beginning * to the current buffer position. Implementations have the choice of returning * anything that they want to. For example, for efficiency, one might decide * to just return null, which is a valid implementation. */ String GetImage(); /** * Returns an array of characters that make up the suffix of length 'len' for * the currently matched token. This is used to build up the matched string * for use in actions in the case of MORE. A simple and inefficient * implementation of this is as follows : * * { * String t = GetImage(); * return t.substring(t.length() - len, t.length()).toCharArray(); * } */ char[] GetSuffix(int len); /** * The lexer calls this function to indicate that it is done with the stream * and hence implementations can free any resources held by this class. * Again, the body of this function can be just empty and it will not * affect the lexer's operation. */ void Done(); } velocity-1.7/src/java/org/apache/velocity/runtime/parser/ParseException.java0000644000175000017500000001462311110402715027226 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */ package org.apache.velocity.runtime.parser; /** * This exception is thrown when parse errors are encountered. * It is intended to be caught and typically will be rethrown * as a ParseErrorException. * *

      You can explicitly create objects of this exception type by * calling the method generateParseException in the generated * parser. * * You can modify this class to customize your error reporting * mechanisms so long as you retain the public fields. */ public class ParseException extends Exception { private static final long serialVersionUID = -309603325673449381L; /** * This constructor is used by the method "generateParseException" * in the generated parser. Calling this constructor generates * a new object of this type with the fields "currentToken", * "expectedTokenSequences", and "tokenImage" set. The boolean * flag "specialConstructor" is also set to true to indicate that * this constructor was used to create this object. * This constructor calls its super class with the empty string * to force the "toString" method of parent class "Throwable" to * print the error message in the form: * ParseException: */ public ParseException(Token currentTokenVal, int[][] expectedTokenSequencesVal, String[] tokenImageVal ) { super(""); specialConstructor = true; currentToken = currentTokenVal; expectedTokenSequences = expectedTokenSequencesVal; tokenImage = tokenImageVal; } /** * The following constructors are for use by you for whatever * purpose you can think of. Constructing the exception in this * manner makes the exception behave in the normal way - i.e., as * documented in the class "Throwable". The fields "errorToken", * "expectedTokenSequences", and "tokenImage" do not contain * relevant information. The JavaCC generated code does not use * these constructors. */ public ParseException() { super(); specialConstructor = false; } public ParseException(String message) { super(message); specialConstructor = false; } /** * This variable determines which constructor was used to create * this object and thereby affects the semantics of the * "getMessage" method (see below). */ protected boolean specialConstructor; /** * This is the last token that has been consumed successfully. If * this object has been created due to a parse error, the token * followng this token will (therefore) be the first error token. */ public Token currentToken; /** * Each entry in this array is an array of integers. Each array * of integers represents a sequence of tokens (by their ordinal * values) that is expected at this point of the parse. */ public int[][] expectedTokenSequences; /** * This is a reference to the "tokenImage" array of the generated * parser within which the parse error occurred. This array is * defined in the generated ...Constants interface. */ public String[] tokenImage; /** * This method has the standard behavior when this object has been * created using the standard constructors. Otherwise, it uses * "currentToken" and "expectedTokenSequences" to generate a parse * error message and returns it. If this object has been created * due to a parse error, and you do not catch it (it gets thrown * from the parser), then this method is called during the printing * of the final stack trace, and hence the correct error message * gets displayed. */ public String getMessage() { if (!specialConstructor) { return super.getMessage(); } String expected = ""; int maxSize = 0; for (int i = 0; i < expectedTokenSequences.length; i++) { if (maxSize < expectedTokenSequences[i].length) { maxSize = expectedTokenSequences[i].length; } for (int j = 0; j < expectedTokenSequences[i].length; j++) { expected += tokenImage[expectedTokenSequences[i][j]] + " "; } if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { expected += "..."; } expected += eol + " "; } String retval = "Encountered \""; Token tok = currentToken.next; for (int i = 0; i < maxSize; i++) { if (i != 0) retval += " "; if (tok.kind == 0) { retval += tokenImage[0]; break; } retval += add_escapes(tok.image); tok = tok.next; } retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; retval += "." + eol; if (expectedTokenSequences.length == 1) { retval += "Was expecting:" + eol + " "; } else { retval += "Was expecting one of:" + eol + " "; } retval += expected; return retval; } /** * The end of line string for this machine. */ protected String eol = System.getProperty("line.separator", "\n"); /** * Used to convert raw characters to their escaped version * when these raw version cannot be used as part of an ASCII * string literal. */ protected String add_escapes(String str) { StringBuffer retval = new StringBuffer(); char ch; for (int i = 0; i < str.length(); i++) { switch (str.charAt(i)) { case 0 : continue; case '\b': retval.append("\\b"); continue; case '\t': retval.append("\\t"); continue; case '\n': retval.append("\\n"); continue; case '\f': retval.append("\\f"); continue; case '\r': retval.append("\\r"); continue; case '\"': retval.append("\\\""); continue; case '\'': retval.append("\\\'"); continue; case '\\': retval.append("\\\\"); continue; default: if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { String s = "0000" + Integer.toString(ch, 16); retval.append("\\u" + s.substring(s.length() - 4, s.length())); } else { retval.append(ch); } continue; } } return retval.toString(); } } velocity-1.7/src/java/org/apache/velocity/runtime/parser/ParserConstants.java0000644000175000017500000001343711150574032027436 0ustar moellermoeller/* Generated By:JJTree&JavaCC: Do not edit this line. ParserConstants.java */ package org.apache.velocity.runtime.parser; /** * Token literal values and constants. * Generated by org.javacc.parser.OtherFilesGen#start() */ public interface ParserConstants { /** End of File. */ int EOF = 0; /** RegularExpression Id. */ int INDEX_LBRACKET = 1; /** RegularExpression Id. */ int INDEX_RBRACKET = 2; /** RegularExpression Id. */ int LBRACKET = 3; /** RegularExpression Id. */ int RBRACKET = 4; /** RegularExpression Id. */ int COMMA = 5; /** RegularExpression Id. */ int DOUBLEDOT = 6; /** RegularExpression Id. */ int COLON = 7; /** RegularExpression Id. */ int LEFT_CURLEY = 8; /** RegularExpression Id. */ int RIGHT_CURLEY = 9; /** RegularExpression Id. */ int LPAREN = 10; /** RegularExpression Id. */ int RPAREN = 11; /** RegularExpression Id. */ int REFMOD2_RPAREN = 12; /** RegularExpression Id. */ int ESCAPE_DIRECTIVE = 13; /** RegularExpression Id. */ int SET_DIRECTIVE = 14; /** RegularExpression Id. */ int DOLLAR = 15; /** RegularExpression Id. */ int DOLLARBANG = 16; /** RegularExpression Id. */ int HASH = 20; /** RegularExpression Id. */ int SINGLE_LINE_COMMENT_START = 21; /** RegularExpression Id. */ int DOUBLE_ESCAPE = 22; /** RegularExpression Id. */ int ESCAPE = 23; /** RegularExpression Id. */ int TEXT = 24; /** RegularExpression Id. */ int SINGLE_LINE_COMMENT = 25; /** RegularExpression Id. */ int FORMAL_COMMENT = 26; /** RegularExpression Id. */ int MULTI_LINE_COMMENT = 27; /** RegularExpression Id. */ int TEXTBLOCK = 28; /** RegularExpression Id. */ int WHITESPACE = 31; /** RegularExpression Id. */ int STRING_LITERAL = 32; /** RegularExpression Id. */ int TRUE = 33; /** RegularExpression Id. */ int FALSE = 34; /** RegularExpression Id. */ int NEWLINE = 35; /** RegularExpression Id. */ int MINUS = 36; /** RegularExpression Id. */ int PLUS = 37; /** RegularExpression Id. */ int MULTIPLY = 38; /** RegularExpression Id. */ int DIVIDE = 39; /** RegularExpression Id. */ int MODULUS = 40; /** RegularExpression Id. */ int LOGICAL_AND = 41; /** RegularExpression Id. */ int LOGICAL_OR = 42; /** RegularExpression Id. */ int LOGICAL_LT = 43; /** RegularExpression Id. */ int LOGICAL_LE = 44; /** RegularExpression Id. */ int LOGICAL_GT = 45; /** RegularExpression Id. */ int LOGICAL_GE = 46; /** RegularExpression Id. */ int LOGICAL_EQUALS = 47; /** RegularExpression Id. */ int LOGICAL_NOT_EQUALS = 48; /** RegularExpression Id. */ int LOGICAL_NOT = 49; /** RegularExpression Id. */ int EQUALS = 50; /** RegularExpression Id. */ int END = 51; /** RegularExpression Id. */ int IF_DIRECTIVE = 52; /** RegularExpression Id. */ int ELSEIF_DIRECTIVE = 53; /** RegularExpression Id. */ int ELSE_DIRECTIVE = 54; /** RegularExpression Id. */ int DIGIT = 55; /** RegularExpression Id. */ int INTEGER_LITERAL = 56; /** RegularExpression Id. */ int FLOATING_POINT_LITERAL = 57; /** RegularExpression Id. */ int EXPONENT = 58; /** RegularExpression Id. */ int LETTER = 59; /** RegularExpression Id. */ int DIRECTIVE_CHAR = 60; /** RegularExpression Id. */ int WORD = 61; /** RegularExpression Id. */ int BRACKETED_WORD = 62; /** RegularExpression Id. */ int ALPHA_CHAR = 63; /** RegularExpression Id. */ int ALPHANUM_CHAR = 64; /** RegularExpression Id. */ int IDENTIFIER_CHAR = 65; /** RegularExpression Id. */ int IDENTIFIER = 66; /** RegularExpression Id. */ int DOT = 67; /** RegularExpression Id. */ int LCURLY = 68; /** RegularExpression Id. */ int RCURLY = 69; /** RegularExpression Id. */ int REFERENCE_TERMINATOR = 70; /** RegularExpression Id. */ int DIRECTIVE_TERMINATOR = 71; /** RegularExpression Id. */ int EMPTY_INDEX = 72; /** Lexical state. */ int REFERENCE = 0; /** Lexical state. */ int REFMODIFIER = 1; /** Lexical state. */ int REFINDEX = 2; /** Lexical state. */ int DIRECTIVE = 3; /** Lexical state. */ int REFMOD2 = 4; /** Lexical state. */ int DEFAULT = 5; /** Lexical state. */ int REFMOD = 6; /** Lexical state. */ int IN_TEXTBLOCK = 7; /** Lexical state. */ int IN_MULTI_LINE_COMMENT = 8; /** Lexical state. */ int IN_FORMAL_COMMENT = 9; /** Lexical state. */ int IN_SINGLE_LINE_COMMENT = 10; /** Lexical state. */ int PRE_DIRECTIVE = 11; /** Literal token values. */ String[] tokenImage = { "", "\"[\"", "\"]\"", "\"[\"", "\"]\"", "\",\"", "\"..\"", "\":\"", "\"{\"", "\"}\"", "\"(\"", "", "\")\"", "", "", "", "", "\"#[[\"", "", "\"#*\"", "\"#\"", "\"##\"", "\"\\\\\\\\\"", "\"\\\\\"", "", "", "\"*#\"", "\"*#\"", "\"]]#\"", "", "", "", "", "\"true\"", "\"false\"", "", "\"-\"", "\"+\"", "\"*\"", "\"/\"", "\"%\"", "", "", "", "", "", "", "", "", "", "\"=\"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\"{\"", "\"}\"", "", "", "", }; } velocity-1.7/src/java/org/apache/velocity/runtime/parser/ParserTreeConstants.java0000644000175000017500000000436711150574032030260 0ustar moellermoeller/* Generated By:JavaCC: Do not edit this line. ParserTreeConstants.java Version 4.1 */ package org.apache.velocity.runtime.parser; public interface ParserTreeConstants { public int JJTPROCESS = 0; public int JJTVOID = 1; public int JJTESCAPEDDIRECTIVE = 2; public int JJTESCAPE = 3; public int JJTCOMMENT = 4; public int JJTTEXTBLOCK = 5; public int JJTFLOATINGPOINTLITERAL = 6; public int JJTINTEGERLITERAL = 7; public int JJTSTRINGLITERAL = 8; public int JJTIDENTIFIER = 9; public int JJTWORD = 10; public int JJTDIRECTIVE = 11; public int JJTBLOCK = 12; public int JJTMAP = 13; public int JJTOBJECTARRAY = 14; public int JJTINTEGERRANGE = 15; public int JJTMETHOD = 16; public int JJTINDEX = 17; public int JJTREFERENCE = 18; public int JJTTRUE = 19; public int JJTFALSE = 20; public int JJTTEXT = 21; public int JJTIFSTATEMENT = 22; public int JJTELSESTATEMENT = 23; public int JJTELSEIFSTATEMENT = 24; public int JJTSETDIRECTIVE = 25; public int JJTEXPRESSION = 26; public int JJTASSIGNMENT = 27; public int JJTORNODE = 28; public int JJTANDNODE = 29; public int JJTEQNODE = 30; public int JJTNENODE = 31; public int JJTLTNODE = 32; public int JJTGTNODE = 33; public int JJTLENODE = 34; public int JJTGENODE = 35; public int JJTADDNODE = 36; public int JJTSUBTRACTNODE = 37; public int JJTMULNODE = 38; public int JJTDIVNODE = 39; public int JJTMODNODE = 40; public int JJTNOTNODE = 41; public String[] jjtNodeName = { "process", "void", "EscapedDirective", "Escape", "Comment", "Textblock", "FloatingPointLiteral", "IntegerLiteral", "StringLiteral", "Identifier", "Word", "Directive", "Block", "Map", "ObjectArray", "IntegerRange", "Method", "Index", "Reference", "True", "False", "Text", "IfStatement", "ElseStatement", "ElseIfStatement", "SetDirective", "Expression", "Assignment", "OrNode", "AndNode", "EQNode", "NENode", "LTNode", "GTNode", "LENode", "GENode", "AddNode", "SubtractNode", "MulNode", "DivNode", "ModNode", "NotNode", }; } /* JavaCC - OriginalChecksum=711f18baf1c477a8c95d1c28eaa4b636 (do not edit this line) */ velocity-1.7/src/java/org/apache/velocity/runtime/parser/BUILD_README.txt0000644000175000017500000000227610315733667026073 0ustar moellermoellerQuick Note: ----------- The parser is a 'special' piece of the build tree - currently it doesn't behave as everything else due to javacc and the package layout. 1) The build script in this directory will take care of the simple case when the parser is modified via Parser.jjt. It runs 'jjtree' on Parser.jjt to make the AST nodes (which are then deleted later - more on this in a bit) and creates Parser.jj for javacc. 2) Javacc is then run on Parser.jj to make Parser.java, which will be compiled like any other piece of java source via build-velocity.sh (or whatever follows.) 3) In the event that something 'serious' changes, such as an AST node is created or altered, it must be *manually* moved to the node subdirectory, and have it's package declaration fixed. This should be an extremely rare event at this point and will change with javacc 2.0. 4) When committing changes, to aid readability to those watching the cvs commit messages, please commit Parser.jjt separately from the .jj and .java files generated from .jjt. -gmj 5) Finally, note that in order to create code that will compile with JDK 1.5, you will need to use JavaCC 3.2 or later (replaces variable "enumeration" with "e". (WGH) velocity-1.7/src/java/org/apache/velocity/runtime/parser/Parser.java0000644000175000017500000031132511353715726025552 0ustar moellermoeller/* Generated By:JJTree&JavaCC: Do not edit this line. Parser.java */ package org.apache.velocity.runtime.parser; import java.io.*; import java.util.*; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.*; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.Macro; import org.apache.velocity.runtime.directive.MacroParseException; import org.apache.velocity.util.StringUtils; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.runtime.RuntimeConstants; /** * This class is responsible for parsing a Velocity * template. This class was generated by JavaCC using * the JJTree extension to produce an Abstract * Syntax Tree (AST) of the template. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: Parser.java 928463 2010-03-28 18:11:34Z nbubna $ */ public class Parser/*@bgen(jjtree)*/implements ParserTreeConstants, ParserConstants {/*@bgen(jjtree)*/ protected JJTParserState jjtree = new JJTParserState();/** * Keep track of defined macros, used for escape processing */ private Map macroNames = new HashMap(); /** * Name of current template we are parsing. Passed to us in parse() */ public String currentTemplateName = ""; /** * Set to true if the property * RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE is set to true */ public boolean strictEscape = false; VelocityCharStream velcharstream = null; private RuntimeServices rsvc = null; /** * This constructor was added to allow the re-use of parsers. * The normal constructor takes a single argument which * an InputStream. This simply creates a re-usable parser * object, we satisfy the requirement of an InputStream * by using a newline character as an input stream. */ public Parser( RuntimeServices rs) { /* * need to call the CTOR first thing. */ this( new VelocityCharStream( new ByteArrayInputStream("\n".getBytes()), 1, 1 )); /* * now setup a VCS for later use */ velcharstream = new VelocityCharStream( new ByteArrayInputStream("\n".getBytes()), 1, 1 ); strictEscape = rs.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false); /* * and save the RuntimeServices */ rsvc = rs; } /** * This was also added to allow parsers to be * re-usable. Normal JavaCC use entails passing an * input stream to the constructor and the parsing * process is carried out once. We want to be able * to re-use parsers: we do this by adding this * method and re-initializing the lexer with * the new stream that we want parsed. */ public SimpleNode parse( Reader reader, String templateName ) throws ParseException { SimpleNode sn = null; currentTemplateName = templateName; try { token_source.clearStateVars(); /* * reinitialize the VelocityCharStream * with the new reader */ velcharstream.ReInit( reader, 1, 1 ); /* * now reinit the Parser with this CharStream */ ReInit( velcharstream ); /* * do that voodoo... */ sn = process(); } catch (MacroParseException mee) { /* * thrown by the Macro class when something is amiss in the * Macro specification */ rsvc.getLog().error("Parser Error: " + templateName, mee); throw mee; } catch (ParseException pe) { rsvc.getLog().error("Parser Exception: " + templateName, pe); throw new TemplateParseException (pe.currentToken, pe.expectedTokenSequences, pe.tokenImage, currentTemplateName); } catch (TokenMgrError tme) { throw new ParseException("Lexical error: " + tme.toString()); } catch (Exception e) { String msg = "Parser Error: " + templateName; rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } currentTemplateName = ""; return sn; } /** * This method gets a Directive from the directives Hashtable */ public Directive getDirective(String directive) { return (Directive) rsvc.getDirective(directive); } /** * This method finds out of the directive exists in the directives Map. */ public boolean isDirective(String directive) { return rsvc.getDirective(directive) != null; } /** * Produces a processed output for an escaped control or * pluggable directive */ private String escapedDirective( String strImage ) { int iLast = strImage.lastIndexOf("\\"); String strDirective = strImage.substring(iLast + 1); boolean bRecognizedDirective = false; // we don't have to call substring method all the time in this method String dirTag = strDirective.substring(1); if (dirTag.charAt(0) == '{') { dirTag = dirTag.substring(1, dirTag.length() - 1); } /* * If this is a predefined derective or if we detect * a macro definition (this is aproximate at best) then * we absorb the forward slash. If in strict reference * mode then we always absord the forward slash regardless * if the derective is defined or not. */ if (strictEscape || isDirective(dirTag) || macroNames.containsKey(dirTag) || rsvc.isVelocimacro(dirTag, currentTemplateName)) { bRecognizedDirective = true; } else { /* order for speed? */ if ( dirTag.equals("if") || dirTag.equals("end") || dirTag.equals("set") || dirTag.equals("else") || dirTag.equals("elseif") ) { bRecognizedDirective = true; } } /* * if so, make the proper prefix string (let the escapes do their thing..) * otherwise, just return what it is.. */ if (bRecognizedDirective) return ( strImage.substring(0,iLast/2) + strDirective); else return ( strImage ); } /** * Check whether there is a left parenthesis with leading optional * whitespaces. This method is used in the semantic look ahead of * Directive method. This is done in code instead of as a production * for simplicity and efficiency. */ private boolean isLeftParenthesis() { char c; int no = 0; try { while(true) { /** * Read a character */ c = velcharstream.readChar(); no++; if (c == '(') { return true; } /** * if not a white space return */ else if (c != ' ' && c != '\n' && c != '\r' && c != '\t') { return false; } } } catch (IOException e) { } finally { /** * Backup the stream to the initial state */ velcharstream.backup(no); } return false; } /** * This method is what starts the whole parsing * process. After the parsing is complete and * the template has been turned into an AST, * this method returns the root of AST which * can subsequently be traversed by a visitor * which implements the ParserVisitor interface * which is generated automatically by JavaCC */ final public SimpleNode process() throws ParseException { /*@bgen(jjtree) process */ ASTprocess jjtn000 = new ASTprocess(this, JJTPROCESS); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { label_1: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: case RPAREN: case ESCAPE_DIRECTIVE: case SET_DIRECTIVE: case SINGLE_LINE_COMMENT_START: case DOUBLE_ESCAPE: case ESCAPE: case TEXT: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: case TEXTBLOCK: case STRING_LITERAL: case IF_DIRECTIVE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case WORD: case BRACKETED_WORD: case IDENTIFIER: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: ; break; default: jj_la1[0] = jj_gen; break label_1; } Statement(); } jj_consume_token(0); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; {if (true) return jjtn000;} } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } throw new Error("Missing return statement in function"); } /** * These are the types of statements that * are acceptable in Velocity templates. */ final public void Statement() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IF_DIRECTIVE: IfStatement(); break; default: jj_la1[1] = jj_gen; if (jj_2_1(2)) { Reference(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SINGLE_LINE_COMMENT_START: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: Comment(); break; case TEXTBLOCK: Textblock(); break; case SET_DIRECTIVE: SetDirective(); break; case ESCAPE_DIRECTIVE: EscapedDirective(); break; case DOUBLE_ESCAPE: Escape(); break; case WORD: case BRACKETED_WORD: Directive(); break; case LPAREN: case RPAREN: case ESCAPE: case TEXT: case STRING_LITERAL: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: Text(); break; default: jj_la1[2] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } } /** * used to separate the notion of a valid directive that has been * escaped, versus something that looks like a directive and * is just schmoo. This is important to do as a separate production * that creates a node, because we want this, in either case, to stop * the further parsing of the Directive() tree. */ final public void EscapedDirective() throws ParseException { /*@bgen(jjtree) EscapedDirective */ ASTEscapedDirective jjtn000 = new ASTEscapedDirective(this, JJTESCAPEDDIRECTIVE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { Token t = null; t = jj_consume_token(ESCAPE_DIRECTIVE); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; /* * churn and burn.. */ t.image = escapedDirective( t.image ); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * Used to catch and process escape sequences in grammatical constructs * as escapes outside of VTL are just characters. Right now we have both * this and the EscapeDirective() construction because in the EscapeDirective() * case, we want to suck in the # and here we don't. We just want * the escapes to render correctly */ final public void Escape() throws ParseException { /*@bgen(jjtree) Escape */ ASTEscape jjtn000 = new ASTEscape(this, JJTESCAPE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { Token t = null; int count = 0; boolean control = false; label_2: while (true) { t = jj_consume_token(DOUBLE_ESCAPE); count++; if (jj_2_2(2)) { ; } else { break label_2; } } jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; /* * first, check to see if we have a control directive */ switch(t.next.kind ) { case IF_DIRECTIVE : case ELSE_DIRECTIVE : case ELSEIF_DIRECTIVE : case END : control = true; break; } /* * if that failed, lets lookahead to see if we matched a PD or a VM */ String nTag = t.next.image.substring(1); if (strictEscape || isDirective(nTag) || macroNames.containsKey(nTag) || rsvc.isVelocimacro(nTag, currentTemplateName)) { control = true; } jjtn000.val = ""; for( int i = 0; i < count; i++) jjtn000.val += ( control ? "\\" : "\\\\"); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Comment() throws ParseException { /*@bgen(jjtree) Comment */ ASTComment jjtn000 = new ASTComment(this, JJTCOMMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SINGLE_LINE_COMMENT_START: jj_consume_token(SINGLE_LINE_COMMENT_START); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SINGLE_LINE_COMMENT: jj_consume_token(SINGLE_LINE_COMMENT); break; default: jj_la1[3] = jj_gen; ; } break; case MULTI_LINE_COMMENT: jj_consume_token(MULTI_LINE_COMMENT); break; case FORMAL_COMMENT: jj_consume_token(FORMAL_COMMENT); break; default: jj_la1[4] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Textblock() throws ParseException { /*@bgen(jjtree) Textblock */ ASTTextblock jjtn000 = new ASTTextblock(this, JJTTEXTBLOCK); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(TEXTBLOCK); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void FloatingPointLiteral() throws ParseException { /*@bgen(jjtree) FloatingPointLiteral */ ASTFloatingPointLiteral jjtn000 = new ASTFloatingPointLiteral(this, JJTFLOATINGPOINTLITERAL); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(FLOATING_POINT_LITERAL); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void IntegerLiteral() throws ParseException { /*@bgen(jjtree) IntegerLiteral */ ASTIntegerLiteral jjtn000 = new ASTIntegerLiteral(this, JJTINTEGERLITERAL); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(INTEGER_LITERAL); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void StringLiteral() throws ParseException { /*@bgen(jjtree) StringLiteral */ ASTStringLiteral jjtn000 = new ASTStringLiteral(this, JJTSTRINGLITERAL); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(STRING_LITERAL); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * This method corresponds to variable * references in Velocity templates. * The following are examples of variable * references that may be found in a * template: * * $foo * $bar * */ final public void Identifier() throws ParseException { /*@bgen(jjtree) Identifier */ ASTIdentifier jjtn000 = new ASTIdentifier(this, JJTIDENTIFIER); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(IDENTIFIER); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Word() throws ParseException { /*@bgen(jjtree) Word */ ASTWord jjtn000 = new ASTWord(this, JJTWORD); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(WORD); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * Supports the arguments for the Pluggable Directives */ final public int DirectiveArg() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: case LCURLY: Reference(); {if (true) return ParserTreeConstants.JJTREFERENCE;} break; case WORD: Word(); {if (true) return ParserTreeConstants.JJTWORD;} break; case STRING_LITERAL: StringLiteral(); {if (true) return ParserTreeConstants.JJTSTRINGLITERAL;} break; case INTEGER_LITERAL: IntegerLiteral(); {if (true) return ParserTreeConstants.JJTINTEGERLITERAL;} break; default: jj_la1[5] = jj_gen; if (jj_2_3(2147483647)) { IntegerRange(); {if (true) return ParserTreeConstants.JJTINTEGERRANGE;} } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case FLOATING_POINT_LITERAL: FloatingPointLiteral(); {if (true) return ParserTreeConstants.JJTFLOATINGPOINTLITERAL;} break; case LEFT_CURLEY: Map(); {if (true) return ParserTreeConstants.JJTMAP;} break; case LBRACKET: ObjectArray(); {if (true) return ParserTreeConstants.JJTOBJECTARRAY;} break; case TRUE: True(); {if (true) return ParserTreeConstants.JJTTRUE;} break; case FALSE: False(); {if (true) return ParserTreeConstants.JJTFALSE;} break; default: jj_la1[6] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } throw new Error("Missing return statement in function"); } /** * Supports the Pluggable Directives * #foo( arg+ ) */ final public SimpleNode Directive() throws ParseException { /*@bgen(jjtree) Directive */ ASTDirective jjtn000 = new ASTDirective(this, JJTDIRECTIVE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);Token t = null; int argType; int argPos = 0; Directive d; int directiveType; boolean isVM = false; boolean doItNow = false; try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WORD: t = jj_consume_token(WORD); break; case BRACKETED_WORD: t = jj_consume_token(BRACKETED_WORD); break; default: jj_la1[7] = jj_gen; jj_consume_token(-1); throw new ParseException(); } String directiveName; if (t.kind == ParserConstants.BRACKETED_WORD) { directiveName = t.image.substring(2, t.image.length() - 1); } else { directiveName = t.image.substring(1); } d = getDirective(directiveName); /* * Velocimacro support : if the directive is macro directive * then set the flag so after the block parsing, we add the VM * right then. (So available if used w/in the current template ) */ if (directiveName.equals("macro")) { doItNow = true; } /* * set the directive name from here. No reason for the thing to know * about parser tokens */ jjtn000.setDirectiveName(directiveName); if ( d == null) { if( directiveName.startsWith("@") ) { // block macro call of type: #@foobar($arg1 $arg2) astBody #end directiveType = Directive.BLOCK; } else { /* * if null, then not a real directive, but maybe a Velocimacro */ isVM = rsvc.isVelocimacro(directiveName, currentTemplateName); /* * Currently, all VMs are LINE directives */ directiveType = Directive.LINE; } } else { directiveType = d.getType(); } /* * now, switch us out of PRE_DIRECTIVE */ token_source.SwitchTo(DIRECTIVE); argPos = 0; if (isLeftParenthesis()) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[8] = jj_gen; ; } jj_consume_token(LPAREN); label_3: while (true) { if (jj_2_4(2)) { ; } else { break label_3; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[9] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[10] = jj_gen; ; } break; default: jj_la1[11] = jj_gen; ; } argType = DirectiveArg(); if (argType == ParserTreeConstants.JJTWORD) { if (doItNow && argPos == 0) { /* if #macro and it's the 0th arg, ok */ } else if (isVM) { {if (true) throw new MacroParseException("Invalid arg #" + argPos + " in VM " + t.image, currentTemplateName, t);} } /* if #foreach and it's the 2nd arg, ok */ else if (d != null && (!directiveName.equals("foreach") || argPos != 1)) { {if (true) throw new MacroParseException("Invalid arg #" + argPos + " in directive " + t.image, currentTemplateName, t);} } else { /* either schmoo or a late-defined macro, * VelocimacroProxy will have to check for latter. */ } } else { if (doItNow && argPos == 0) { /* if a VM and it's the 0th arg, not ok */ {if (true) throw new MacroParseException("Invalid first arg" + " in #macro() directive - must be a" + " word token (no \' or \" surrounding)", currentTemplateName, t);} } } argPos++; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[12] = jj_gen; ; } jj_consume_token(RPAREN); if (directiveType == Directive.LINE) { {if (true) return jjtn000;} } } else { if (doItNow) // doItNow is true if the directive is "macro" { // VELOCITY-667 We get here if we have a "#macro" construct // without parenthesis which is a parse error {if (true) throw new MacroParseException("A macro declaration requires at least a name argument" , currentTemplateName, t);} } /** * Not a directive */ token_source.stateStackPop(); token_source.inDirective = false; {if (true) return jjtn000;} } ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { label_4: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: case RPAREN: case ESCAPE_DIRECTIVE: case SET_DIRECTIVE: case SINGLE_LINE_COMMENT_START: case DOUBLE_ESCAPE: case ESCAPE: case TEXT: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: case TEXTBLOCK: case STRING_LITERAL: case IF_DIRECTIVE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case WORD: case BRACKETED_WORD: case IDENTIFIER: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: ; break; default: jj_la1[13] = jj_gen; break label_4; } Statement(); } } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } jj_consume_token(END); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; /* * VM : if we are processing a #macro directive, we need to * process the block. In truth, I can just register the name * and do the work later when init-ing. That would work * as long as things were always defined before use. This way * we don't have to worry about forward references and such... */ if (doItNow) { // Further checking of macro arguments Macro.checkArgs(rsvc, t, jjtn000, currentTemplateName); // Add the macro name so that we can peform escape processing // on defined macros String macroName = jjtn000.jjtGetChild(0).getFirstToken().image; macroNames.put(macroName, macroName); } /* * VM : end */ {if (true) return jjtn000;} } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } throw new Error("Missing return statement in function"); } /** * for creating a map in a #set * * #set($foo = {$foo : $bar, $blargh : $thingy}) */ final public void Map() throws ParseException { /*@bgen(jjtree) Map */ ASTMap jjtn000 = new ASTMap(this, JJTMAP); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(LEFT_CURLEY); if (jj_2_5(2)) { Parameter(); jj_consume_token(COLON); Parameter(); label_5: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: jj_la1[14] = jj_gen; break label_5; } jj_consume_token(COMMA); Parameter(); jj_consume_token(COLON); Parameter(); } } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[15] = jj_gen; ; } } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case RIGHT_CURLEY: jj_consume_token(RIGHT_CURLEY); break; case RCURLY: jj_consume_token(RCURLY); break; default: jj_la1[16] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ObjectArray() throws ParseException { /*@bgen(jjtree) ObjectArray */ ASTObjectArray jjtn000 = new ASTObjectArray(this, JJTOBJECTARRAY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(LBRACKET); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LBRACKET: case LEFT_CURLEY: case WHITESPACE: case STRING_LITERAL: case TRUE: case FALSE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case IDENTIFIER: case LCURLY: Parameter(); label_6: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: jj_la1[17] = jj_gen; break label_6; } jj_consume_token(COMMA); Parameter(); } break; default: jj_la1[18] = jj_gen; ; } jj_consume_token(RBRACKET); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * supports the [n..m] vector generator for use in * the #foreach() to generate measured ranges w/o * needing explicit support from the app/servlet */ final public void IntegerRange() throws ParseException { /*@bgen(jjtree) IntegerRange */ ASTIntegerRange jjtn000 = new ASTIntegerRange(this, JJTINTEGERRANGE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(LBRACKET); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[19] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: case LCURLY: Reference(); break; case INTEGER_LITERAL: IntegerLiteral(); break; default: jj_la1[20] = jj_gen; jj_consume_token(-1); throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[21] = jj_gen; ; } jj_consume_token(DOUBLEDOT); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[22] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: case LCURLY: Reference(); break; case INTEGER_LITERAL: IntegerLiteral(); break; default: jj_la1[23] = jj_gen; jj_consume_token(-1); throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[24] = jj_gen; ; } jj_consume_token(RBRACKET); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * A Simplified parameter more suitable for an index position: $foo[$index] */ final public void IndexParameter() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[25] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case STRING_LITERAL: StringLiteral(); break; case INTEGER_LITERAL: IntegerLiteral(); break; case TRUE: True(); break; case FALSE: False(); break; case IDENTIFIER: case LCURLY: Reference(); break; default: jj_la1[26] = jj_gen; jj_consume_token(-1); throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[27] = jj_gen; ; } } /** * This method has yet to be fully implemented * but will allow arbitrarily nested method * calls */ final public void Parameter() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[28] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case STRING_LITERAL: StringLiteral(); break; case INTEGER_LITERAL: IntegerLiteral(); break; default: jj_la1[29] = jj_gen; if (jj_2_6(2147483647)) { IntegerRange(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LEFT_CURLEY: Map(); break; case LBRACKET: ObjectArray(); break; case TRUE: True(); break; case FALSE: False(); break; case IDENTIFIER: case LCURLY: Reference(); break; case FLOATING_POINT_LITERAL: FloatingPointLiteral(); break; default: jj_la1[30] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[31] = jj_gen; ; } } /** * This method has yet to be fully implemented * but will allow arbitrarily nested method * calls */ final public void Method() throws ParseException { /*@bgen(jjtree) Method */ ASTMethod jjtn000 = new ASTMethod(this, JJTMETHOD); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { Identifier(); jj_consume_token(LPAREN); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LBRACKET: case LEFT_CURLEY: case WHITESPACE: case STRING_LITERAL: case TRUE: case FALSE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case IDENTIFIER: case LCURLY: Parameter(); label_7: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: jj_la1[32] = jj_gen; break label_7; } jj_consume_token(COMMA); Parameter(); } break; default: jj_la1[33] = jj_gen; ; } jj_consume_token(REFMOD2_RPAREN); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Index() throws ParseException { /*@bgen(jjtree) Index */ ASTIndex jjtn000 = new ASTIndex(this, JJTINDEX); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(INDEX_LBRACKET); IndexParameter(); jj_consume_token(INDEX_RBRACKET); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Reference() throws ParseException { /*@bgen(jjtree) Reference */ ASTReference jjtn000 = new ASTReference(this, JJTREFERENCE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: jj_consume_token(IDENTIFIER); label_8: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INDEX_LBRACKET: ; break; default: jj_la1[34] = jj_gen; break label_8; } Index(); } label_9: while (true) { if (jj_2_7(2)) { ; } else { break label_9; } jj_consume_token(DOT); if (jj_2_8(3)) { Method(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: Identifier(); break; default: jj_la1[35] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } label_10: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INDEX_LBRACKET: ; break; default: jj_la1[36] = jj_gen; break label_10; } Index(); } } break; case LCURLY: jj_consume_token(LCURLY); jj_consume_token(IDENTIFIER); label_11: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INDEX_LBRACKET: ; break; default: jj_la1[37] = jj_gen; break label_11; } Index(); } label_12: while (true) { if (jj_2_9(2)) { ; } else { break label_12; } jj_consume_token(DOT); if (jj_2_10(3)) { Method(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENTIFIER: Identifier(); break; default: jj_la1[38] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } label_13: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INDEX_LBRACKET: ; break; default: jj_la1[39] = jj_gen; break label_13; } Index(); } } jj_consume_token(RCURLY); break; default: jj_la1[40] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void True() throws ParseException { /*@bgen(jjtree) True */ ASTTrue jjtn000 = new ASTTrue(this, JJTTRUE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(TRUE); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void False() throws ParseException { /*@bgen(jjtree) False */ ASTFalse jjtn000 = new ASTFalse(this, JJTFALSE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(FALSE); } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * This method is responsible for allowing * all non-grammar text to pass through * unscathed. */ final public void Text() throws ParseException { /*@bgen(jjtree) Text */ ASTText jjtn000 = new ASTText(this, JJTTEXT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case TEXT: jj_consume_token(TEXT); break; case DOT: jj_consume_token(DOT); break; case RPAREN: jj_consume_token(RPAREN); break; case LPAREN: jj_consume_token(LPAREN); break; case INTEGER_LITERAL: jj_consume_token(INTEGER_LITERAL); break; case FLOATING_POINT_LITERAL: jj_consume_token(FLOATING_POINT_LITERAL); break; case STRING_LITERAL: jj_consume_token(STRING_LITERAL); break; case ESCAPE: jj_consume_token(ESCAPE); break; case LCURLY: jj_consume_token(LCURLY); break; case RCURLY: jj_consume_token(RCURLY); break; case EMPTY_INDEX: jj_consume_token(EMPTY_INDEX); break; default: jj_la1[41] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /* ----------------------------------------------------------------------- * * Defined Directive Syntax * * ----------------------------------------------------------------------*/ final public void IfStatement() throws ParseException { /*@bgen(jjtree) IfStatement */ ASTIfStatement jjtn000 = new ASTIfStatement(this, JJTIFSTATEMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(IF_DIRECTIVE); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[42] = jj_gen; ; } jj_consume_token(LPAREN); Expression(); jj_consume_token(RPAREN); ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { label_14: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: case RPAREN: case ESCAPE_DIRECTIVE: case SET_DIRECTIVE: case SINGLE_LINE_COMMENT_START: case DOUBLE_ESCAPE: case ESCAPE: case TEXT: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: case TEXTBLOCK: case STRING_LITERAL: case IF_DIRECTIVE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case WORD: case BRACKETED_WORD: case IDENTIFIER: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: ; break; default: jj_la1[43] = jj_gen; break label_14; } Statement(); } } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ELSEIF_DIRECTIVE: label_15: while (true) { ElseIfStatement(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ELSEIF_DIRECTIVE: ; break; default: jj_la1[44] = jj_gen; break label_15; } } break; default: jj_la1[45] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ELSE_DIRECTIVE: ElseStatement(); break; default: jj_la1[46] = jj_gen; ; } jj_consume_token(END); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ElseStatement() throws ParseException { /*@bgen(jjtree) ElseStatement */ ASTElseStatement jjtn000 = new ASTElseStatement(this, JJTELSESTATEMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(ELSE_DIRECTIVE); ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { label_16: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: case RPAREN: case ESCAPE_DIRECTIVE: case SET_DIRECTIVE: case SINGLE_LINE_COMMENT_START: case DOUBLE_ESCAPE: case ESCAPE: case TEXT: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: case TEXTBLOCK: case STRING_LITERAL: case IF_DIRECTIVE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case WORD: case BRACKETED_WORD: case IDENTIFIER: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: ; break; default: jj_la1[47] = jj_gen; break label_16; } Statement(); } } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void ElseIfStatement() throws ParseException { /*@bgen(jjtree) ElseIfStatement */ ASTElseIfStatement jjtn000 = new ASTElseIfStatement(this, JJTELSEIFSTATEMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(ELSEIF_DIRECTIVE); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[48] = jj_gen; ; } jj_consume_token(LPAREN); Expression(); jj_consume_token(RPAREN); ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { label_17: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LPAREN: case RPAREN: case ESCAPE_DIRECTIVE: case SET_DIRECTIVE: case SINGLE_LINE_COMMENT_START: case DOUBLE_ESCAPE: case ESCAPE: case TEXT: case FORMAL_COMMENT: case MULTI_LINE_COMMENT: case TEXTBLOCK: case STRING_LITERAL: case IF_DIRECTIVE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case WORD: case BRACKETED_WORD: case IDENTIFIER: case DOT: case LCURLY: case RCURLY: case EMPTY_INDEX: ; break; default: jj_la1[49] = jj_gen; break label_17; } Statement(); } } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, true); } } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /** * Currently support both types of set : * #set( expr ) * #set expr */ final public void SetDirective() throws ParseException { /*@bgen(jjtree) SetDirective */ ASTSetDirective jjtn000 = new ASTSetDirective(this, JJTSETDIRECTIVE); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { jj_consume_token(SET_DIRECTIVE); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[50] = jj_gen; ; } Reference(); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[51] = jj_gen; ; } jj_consume_token(EQUALS); Expression(); jj_consume_token(RPAREN); /* * ensure that inSet is false. Leads to some amusing bugs... */ token_source.inSet = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case NEWLINE: jj_consume_token(NEWLINE); break; default: jj_la1[52] = jj_gen; ; } } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } /* ----------------------------------------------------------------------- * * Expression Syntax * * ----------------------------------------------------------------------*/ final public void Expression() throws ParseException { /*@bgen(jjtree) Expression */ ASTExpression jjtn000 = new ASTExpression(this, JJTEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { ConditionalOrExpression(); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } } final public void Assignment() throws ParseException { /*@bgen(jjtree) #Assignment( 2) */ ASTAssignment jjtn000 = new ASTAssignment(this, JJTASSIGNMENT); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000); try { PrimaryExpression(); jj_consume_token(EQUALS); Expression(); } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte000;} } if (jjte000 instanceof ParseException) { {if (true) throw (ParseException)jjte000;} } {if (true) throw (Error)jjte000;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, 2); } } } final public void ConditionalOrExpression() throws ParseException { ConditionalAndExpression(); label_18: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_OR: ; break; default: jj_la1[53] = jj_gen; break label_18; } jj_consume_token(LOGICAL_OR); ASTOrNode jjtn001 = new ASTOrNode(this, JJTORNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { ConditionalAndExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } } } final public void ConditionalAndExpression() throws ParseException { EqualityExpression(); label_19: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_AND: ; break; default: jj_la1[54] = jj_gen; break label_19; } jj_consume_token(LOGICAL_AND); ASTAndNode jjtn001 = new ASTAndNode(this, JJTANDNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { EqualityExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } } } final public void EqualityExpression() throws ParseException { RelationalExpression(); label_20: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_EQUALS: case LOGICAL_NOT_EQUALS: ; break; default: jj_la1[55] = jj_gen; break label_20; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_EQUALS: jj_consume_token(LOGICAL_EQUALS); ASTEQNode jjtn001 = new ASTEQNode(this, JJTEQNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { RelationalExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } break; case LOGICAL_NOT_EQUALS: jj_consume_token(LOGICAL_NOT_EQUALS); ASTNENode jjtn002 = new ASTNENode(this, JJTNENODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); try { RelationalExpression(); } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte002;} } if (jjte002 instanceof ParseException) { {if (true) throw (ParseException)jjte002;} } {if (true) throw (Error)jjte002;} } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, 2); } } break; default: jj_la1[56] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } final public void RelationalExpression() throws ParseException { AdditiveExpression(); label_21: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_LT: case LOGICAL_LE: case LOGICAL_GT: case LOGICAL_GE: ; break; default: jj_la1[57] = jj_gen; break label_21; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LOGICAL_LT: jj_consume_token(LOGICAL_LT); ASTLTNode jjtn001 = new ASTLTNode(this, JJTLTNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { AdditiveExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } break; case LOGICAL_GT: jj_consume_token(LOGICAL_GT); ASTGTNode jjtn002 = new ASTGTNode(this, JJTGTNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); try { AdditiveExpression(); } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte002;} } if (jjte002 instanceof ParseException) { {if (true) throw (ParseException)jjte002;} } {if (true) throw (Error)jjte002;} } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, 2); } } break; case LOGICAL_LE: jj_consume_token(LOGICAL_LE); ASTLENode jjtn003 = new ASTLENode(this, JJTLENODE); boolean jjtc003 = true; jjtree.openNodeScope(jjtn003); try { AdditiveExpression(); } catch (Throwable jjte003) { if (jjtc003) { jjtree.clearNodeScope(jjtn003); jjtc003 = false; } else { jjtree.popNode(); } if (jjte003 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte003;} } if (jjte003 instanceof ParseException) { {if (true) throw (ParseException)jjte003;} } {if (true) throw (Error)jjte003;} } finally { if (jjtc003) { jjtree.closeNodeScope(jjtn003, 2); } } break; case LOGICAL_GE: jj_consume_token(LOGICAL_GE); ASTGENode jjtn004 = new ASTGENode(this, JJTGENODE); boolean jjtc004 = true; jjtree.openNodeScope(jjtn004); try { AdditiveExpression(); } catch (Throwable jjte004) { if (jjtc004) { jjtree.clearNodeScope(jjtn004); jjtc004 = false; } else { jjtree.popNode(); } if (jjte004 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte004;} } if (jjte004 instanceof ParseException) { {if (true) throw (ParseException)jjte004;} } {if (true) throw (Error)jjte004;} } finally { if (jjtc004) { jjtree.closeNodeScope(jjtn004, 2); } } break; default: jj_la1[58] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } final public void AdditiveExpression() throws ParseException { MultiplicativeExpression(); label_22: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case MINUS: case PLUS: ; break; default: jj_la1[59] = jj_gen; break label_22; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: jj_consume_token(PLUS); ASTAddNode jjtn001 = new ASTAddNode(this, JJTADDNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { MultiplicativeExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } break; case MINUS: jj_consume_token(MINUS); ASTSubtractNode jjtn002 = new ASTSubtractNode(this, JJTSUBTRACTNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); try { MultiplicativeExpression(); } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte002;} } if (jjte002 instanceof ParseException) { {if (true) throw (ParseException)jjte002;} } {if (true) throw (Error)jjte002;} } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, 2); } } break; default: jj_la1[60] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } final public void MultiplicativeExpression() throws ParseException { UnaryExpression(); label_23: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case MULTIPLY: case DIVIDE: case MODULUS: ; break; default: jj_la1[61] = jj_gen; break label_23; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case MULTIPLY: jj_consume_token(MULTIPLY); ASTMulNode jjtn001 = new ASTMulNode(this, JJTMULNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { UnaryExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 2); } } break; case DIVIDE: jj_consume_token(DIVIDE); ASTDivNode jjtn002 = new ASTDivNode(this, JJTDIVNODE); boolean jjtc002 = true; jjtree.openNodeScope(jjtn002); try { UnaryExpression(); } catch (Throwable jjte002) { if (jjtc002) { jjtree.clearNodeScope(jjtn002); jjtc002 = false; } else { jjtree.popNode(); } if (jjte002 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte002;} } if (jjte002 instanceof ParseException) { {if (true) throw (ParseException)jjte002;} } {if (true) throw (Error)jjte002;} } finally { if (jjtc002) { jjtree.closeNodeScope(jjtn002, 2); } } break; case MODULUS: jj_consume_token(MODULUS); ASTModNode jjtn003 = new ASTModNode(this, JJTMODNODE); boolean jjtc003 = true; jjtree.openNodeScope(jjtn003); try { UnaryExpression(); } catch (Throwable jjte003) { if (jjtc003) { jjtree.clearNodeScope(jjtn003); jjtc003 = false; } else { jjtree.popNode(); } if (jjte003 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte003;} } if (jjte003 instanceof ParseException) { {if (true) throw (ParseException)jjte003;} } {if (true) throw (Error)jjte003;} } finally { if (jjtc003) { jjtree.closeNodeScope(jjtn003, 2); } } break; default: jj_la1[62] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } final public void UnaryExpression() throws ParseException { if (jj_2_11(2)) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[63] = jj_gen; ; } jj_consume_token(LOGICAL_NOT); ASTNotNode jjtn001 = new ASTNotNode(this, JJTNOTNODE); boolean jjtc001 = true; jjtree.openNodeScope(jjtn001); try { UnaryExpression(); } catch (Throwable jjte001) { if (jjtc001) { jjtree.clearNodeScope(jjtn001); jjtc001 = false; } else { jjtree.popNode(); } if (jjte001 instanceof RuntimeException) { {if (true) throw (RuntimeException)jjte001;} } if (jjte001 instanceof ParseException) { {if (true) throw (ParseException)jjte001;} } {if (true) throw (Error)jjte001;} } finally { if (jjtc001) { jjtree.closeNodeScope(jjtn001, 1); } } } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LBRACKET: case LEFT_CURLEY: case LPAREN: case WHITESPACE: case STRING_LITERAL: case TRUE: case FALSE: case INTEGER_LITERAL: case FLOATING_POINT_LITERAL: case IDENTIFIER: case LCURLY: PrimaryExpression(); break; default: jj_la1[64] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } final public void PrimaryExpression() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[65] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case STRING_LITERAL: StringLiteral(); break; case IDENTIFIER: case LCURLY: Reference(); break; case INTEGER_LITERAL: IntegerLiteral(); break; default: jj_la1[66] = jj_gen; if (jj_2_12(2147483647)) { IntegerRange(); } else { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case FLOATING_POINT_LITERAL: FloatingPointLiteral(); break; case LEFT_CURLEY: Map(); break; case LBRACKET: ObjectArray(); break; case TRUE: True(); break; case FALSE: False(); break; case LPAREN: jj_consume_token(LPAREN); Expression(); jj_consume_token(RPAREN); break; default: jj_la1[67] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case WHITESPACE: jj_consume_token(WHITESPACE); break; default: jj_la1[68] = jj_gen; ; } } private boolean jj_2_1(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_1(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(0, xla); } } private boolean jj_2_2(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_2(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(1, xla); } } private boolean jj_2_3(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_3(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(2, xla); } } private boolean jj_2_4(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_4(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(3, xla); } } private boolean jj_2_5(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_5(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(4, xla); } } private boolean jj_2_6(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_6(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(5, xla); } } private boolean jj_2_7(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_7(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(6, xla); } } private boolean jj_2_8(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_8(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(7, xla); } } private boolean jj_2_9(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_9(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(8, xla); } } private boolean jj_2_10(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_10(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(9, xla); } } private boolean jj_2_11(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_11(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(10, xla); } } private boolean jj_2_12(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_12(); } catch(LookaheadSuccess ls) { return true; } finally { jj_save(11, xla); } } private boolean jj_3_7() { if (jj_scan_token(DOT)) return true; Token xsp; xsp = jj_scanpos; if (jj_3_8()) { jj_scanpos = xsp; if (jj_3R_32()) return true; } while (true) { xsp = jj_scanpos; if (jj_3R_89()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3R_61() { if (jj_3R_29()) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_3R_97()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3R_39() { if (jj_scan_token(LCURLY)) return true; if (jj_scan_token(IDENTIFIER)) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_3R_74()) { jj_scanpos = xsp; break; } } while (true) { xsp = jj_scanpos; if (jj_3_9()) { jj_scanpos = xsp; break; } } if (jj_scan_token(RCURLY)) return true; return false; } private boolean jj_3R_40() { if (jj_scan_token(INTEGER_LITERAL)) return true; return false; } private boolean jj_3R_88() { if (jj_scan_token(LPAREN)) return true; return false; } private boolean jj_3R_87() { if (jj_3R_71()) return true; return false; } private boolean jj_3R_86() { if (jj_3R_70()) return true; return false; } private boolean jj_3R_38() { if (jj_scan_token(IDENTIFIER)) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_3R_63()) { jj_scanpos = xsp; break; } } while (true) { xsp = jj_scanpos; if (jj_3_7()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3R_85() { if (jj_3R_69()) return true; return false; } private boolean jj_3R_84() { if (jj_3R_68()) return true; return false; } private boolean jj_3R_83() { if (jj_3R_67()) return true; return false; } private boolean jj_3R_67() { if (jj_scan_token(FLOATING_POINT_LITERAL)) return true; return false; } private boolean jj_3R_24() { Token xsp; xsp = jj_scanpos; if (jj_3R_38()) { jj_scanpos = xsp; if (jj_3R_39()) return true; } return false; } private boolean jj_3R_82() { if (jj_3R_66()) return true; return false; } private boolean jj_3R_81() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_80() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_79() { if (jj_3R_65()) return true; return false; } private boolean jj_3R_72() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_79()) { jj_scanpos = xsp; if (jj_3R_80()) { jj_scanpos = xsp; if (jj_3R_81()) { jj_scanpos = xsp; if (jj_3R_82()) { jj_scanpos = xsp; if (jj_3R_83()) { jj_scanpos = xsp; if (jj_3R_84()) { jj_scanpos = xsp; if (jj_3R_85()) { jj_scanpos = xsp; if (jj_3R_86()) { jj_scanpos = xsp; if (jj_3R_87()) { jj_scanpos = xsp; if (jj_3R_88()) return true; } } } } } } } } } return false; } private boolean jj_3R_73() { if (jj_scan_token(INDEX_LBRACKET)) return true; if (jj_3R_91()) return true; if (jj_scan_token(INDEX_RBRACKET)) return true; return false; } private boolean jj_3R_35() { Token xsp; xsp = jj_scanpos; if (jj_3_11()) { jj_scanpos = xsp; if (jj_3R_62()) return true; } return false; } private boolean jj_3_11() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(LOGICAL_NOT)) return true; if (jj_3R_35()) return true; return false; } private boolean jj_3R_62() { if (jj_3R_72()) return true; return false; } private boolean jj_3_6() { if (jj_scan_token(LBRACKET)) return true; Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_30()) { jj_scanpos = xsp; if (jj_3R_31()) return true; } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(DOUBLEDOT)) return true; return false; } private boolean jj_3R_33() { if (jj_3R_60()) return true; if (jj_scan_token(LPAREN)) return true; Token xsp; xsp = jj_scanpos; if (jj_3R_61()) jj_scanpos = xsp; if (jj_scan_token(REFMOD2_RPAREN)) return true; return false; } private boolean jj_3R_59() { if (jj_3R_67()) return true; return false; } private boolean jj_3R_58() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_57() { if (jj_3R_71()) return true; return false; } private boolean jj_3R_56() { if (jj_3R_70()) return true; return false; } private boolean jj_3R_55() { if (jj_3R_69()) return true; return false; } private boolean jj_3R_54() { if (jj_3R_68()) return true; return false; } private boolean jj_3R_53() { if (jj_3R_66()) return true; return false; } private boolean jj_3R_52() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_51() { if (jj_3R_65()) return true; return false; } private boolean jj_3R_29() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_51()) { jj_scanpos = xsp; if (jj_3R_52()) { jj_scanpos = xsp; if (jj_3R_53()) { jj_scanpos = xsp; if (jj_3R_54()) { jj_scanpos = xsp; if (jj_3R_55()) { jj_scanpos = xsp; if (jj_3R_56()) { jj_scanpos = xsp; if (jj_3R_57()) { jj_scanpos = xsp; if (jj_3R_58()) { jj_scanpos = xsp; if (jj_3R_59()) return true; } } } } } } } } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; return false; } private boolean jj_3R_100() { if (jj_scan_token(COMMA)) return true; if (jj_3R_29()) return true; if (jj_scan_token(COLON)) return true; if (jj_3R_29()) return true; return false; } private boolean jj_3R_96() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_95() { if (jj_3R_71()) return true; return false; } private boolean jj_3R_94() { if (jj_3R_70()) return true; return false; } private boolean jj_3R_93() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_92() { if (jj_3R_65()) return true; return false; } private boolean jj_3R_99() { if (jj_3R_40()) return true; return false; } private boolean jj_3_2() { if (jj_scan_token(DOUBLE_ESCAPE)) return true; return false; } private boolean jj_3R_76() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_101() { if (jj_scan_token(COMMA)) return true; if (jj_3R_29()) return true; return false; } private boolean jj_3R_91() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_92()) { jj_scanpos = xsp; if (jj_3R_93()) { jj_scanpos = xsp; if (jj_3R_94()) { jj_scanpos = xsp; if (jj_3R_95()) { jj_scanpos = xsp; if (jj_3R_96()) return true; } } } } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; return false; } private boolean jj_3R_98() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_75() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_78() { if (jj_3R_29()) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_3R_101()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3R_66() { if (jj_scan_token(LBRACKET)) return true; Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_75()) { jj_scanpos = xsp; if (jj_3R_76()) return true; } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(DOUBLEDOT)) return true; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_98()) { jj_scanpos = xsp; if (jj_3R_99()) return true; } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(RBRACKET)) return true; return false; } private boolean jj_3R_26() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_69() { if (jj_scan_token(LBRACKET)) return true; Token xsp; xsp = jj_scanpos; if (jj_3R_78()) jj_scanpos = xsp; if (jj_scan_token(RBRACKET)) return true; return false; } private boolean jj_3R_77() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; return false; } private boolean jj_3_5() { if (jj_3R_29()) return true; if (jj_scan_token(COLON)) return true; if (jj_3R_29()) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_3R_100()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3R_25() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_68() { if (jj_scan_token(LEFT_CURLEY)) return true; Token xsp; xsp = jj_scanpos; if (jj_3_5()) { jj_scanpos = xsp; if (jj_3R_77()) return true; } xsp = jj_scanpos; if (jj_scan_token(9)) { jj_scanpos = xsp; if (jj_scan_token(69)) return true; } return false; } private boolean jj_3_1() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_50() { if (jj_3R_71()) return true; return false; } private boolean jj_3R_90() { if (jj_3R_73()) return true; return false; } private boolean jj_3R_49() { if (jj_3R_70()) return true; return false; } private boolean jj_3_3() { if (jj_scan_token(LBRACKET)) return true; Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_25()) { jj_scanpos = xsp; if (jj_3R_26()) return true; } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(DOUBLEDOT)) return true; return false; } private boolean jj_3R_48() { if (jj_3R_69()) return true; return false; } private boolean jj_3R_89() { if (jj_3R_73()) return true; return false; } private boolean jj_3R_47() { if (jj_3R_68()) return true; return false; } private boolean jj_3R_46() { if (jj_3R_67()) return true; return false; } private boolean jj_3R_45() { if (jj_3R_66()) return true; return false; } private boolean jj_3R_34() { if (jj_3R_60()) return true; return false; } private boolean jj_3R_37() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_32() { if (jj_3R_60()) return true; return false; } private boolean jj_3R_44() { if (jj_3R_40()) return true; return false; } private boolean jj_3R_27() { if (jj_scan_token(COMMA)) return true; Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; return false; } private boolean jj_3R_43() { if (jj_3R_65()) return true; return false; } private boolean jj_3R_42() { if (jj_3R_64()) return true; return false; } private boolean jj_3R_36() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_41() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_28() { Token xsp; xsp = jj_scanpos; if (jj_3R_41()) { jj_scanpos = xsp; if (jj_3R_42()) { jj_scanpos = xsp; if (jj_3R_43()) { jj_scanpos = xsp; if (jj_3R_44()) { jj_scanpos = xsp; if (jj_3R_45()) { jj_scanpos = xsp; if (jj_3R_46()) { jj_scanpos = xsp; if (jj_3R_47()) { jj_scanpos = xsp; if (jj_3R_48()) { jj_scanpos = xsp; if (jj_3R_49()) { jj_scanpos = xsp; if (jj_3R_50()) return true; } } } } } } } } } return false; } private boolean jj_3_10() { if (jj_3R_33()) return true; return false; } private boolean jj_3R_64() { if (jj_scan_token(WORD)) return true; return false; } private boolean jj_3R_31() { if (jj_3R_40()) return true; return false; } private boolean jj_3_8() { if (jj_3R_33()) return true; return false; } private boolean jj_3R_74() { if (jj_3R_73()) return true; return false; } private boolean jj_3R_60() { if (jj_scan_token(IDENTIFIER)) return true; return false; } private boolean jj_3R_97() { if (jj_scan_token(COMMA)) return true; if (jj_3R_29()) return true; return false; } private boolean jj_3R_71() { if (jj_scan_token(FALSE)) return true; return false; } private boolean jj_3_4() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_27()) jj_scanpos = xsp; if (jj_3R_28()) return true; return false; } private boolean jj_3R_63() { if (jj_3R_73()) return true; return false; } private boolean jj_3R_30() { if (jj_3R_24()) return true; return false; } private boolean jj_3R_70() { if (jj_scan_token(TRUE)) return true; return false; } private boolean jj_3_9() { if (jj_scan_token(DOT)) return true; Token xsp; xsp = jj_scanpos; if (jj_3_10()) { jj_scanpos = xsp; if (jj_3R_34()) return true; } while (true) { xsp = jj_scanpos; if (jj_3R_90()) { jj_scanpos = xsp; break; } } return false; } private boolean jj_3_12() { if (jj_scan_token(LBRACKET)) return true; Token xsp; xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; xsp = jj_scanpos; if (jj_3R_36()) { jj_scanpos = xsp; if (jj_3R_37()) return true; } xsp = jj_scanpos; if (jj_scan_token(31)) jj_scanpos = xsp; if (jj_scan_token(DOUBLEDOT)) return true; return false; } private boolean jj_3R_65() { if (jj_scan_token(STRING_LITERAL)) return true; return false; } /** Generated Token Manager. */ public ParserTokenManager token_source; /** Current token. */ public Token token; /** Next token. */ public Token jj_nt; private int jj_ntk; private Token jj_scanpos, jj_lastpos; private int jj_la; private int jj_gen; final private int[] jj_la1 = new int[69]; static private int[] jj_la1_0; static private int[] jj_la1_1; static private int[] jj_la1_2; static { jj_la1_init_0(); jj_la1_init_1(); jj_la1_init_2(); } private static void jj_la1_init_0() { jj_la1_0 = new int[] {0x1de06c00,0x0,0x1de06c00,0x2000000,0xc200000,0x0,0x108,0x0,0x80000000,0x80000000,0x80000000,0x20,0x80000000,0x1de06c00,0x20,0x80000000,0x200,0x20,0x80000108,0x80000000,0x0,0x80000000,0x80000000,0x0,0x80000000,0x80000000,0x0,0x80000000,0x80000000,0x0,0x108,0x80000000,0x20,0x80000108,0x2,0x0,0x2,0x2,0x0,0x2,0x0,0x1800c00,0x80000000,0x1de06c00,0x0,0x0,0x0,0x1de06c00,0x80000000,0x1de06c00,0x80000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x80000508,0x80000000,0x0,0x508,0x80000000,}; } private static void jj_la1_init_1() { jj_la1_1 = new int[] {0x63100001,0x100000,0x63000001,0x0,0x0,0x21000001,0x2000006,0x60000000,0x0,0x0,0x0,0x0,0x0,0x63100001,0x0,0x0,0x0,0x0,0x3000007,0x0,0x1000000,0x0,0x0,0x1000000,0x0,0x0,0x1000007,0x0,0x0,0x1000001,0x2000006,0x0,0x0,0x3000007,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3000001,0x0,0x63100001,0x200000,0x200000,0x400000,0x63100001,0x0,0x63100001,0x0,0x0,0x8,0x400,0x200,0x18000,0x18000,0x7800,0x7800,0x30,0x30,0x1c0,0x1c0,0x0,0x3000007,0x0,0x1000001,0x2000006,0x0,}; } private static void jj_la1_init_2() { jj_la1_2 = new int[] {0x13c,0x0,0x138,0x0,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x13c,0x0,0x0,0x20,0x0,0x14,0x0,0x14,0x0,0x0,0x14,0x0,0x0,0x14,0x0,0x0,0x0,0x14,0x0,0x0,0x14,0x0,0x4,0x0,0x0,0x4,0x0,0x14,0x138,0x0,0x13c,0x0,0x0,0x0,0x13c,0x0,0x13c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x14,0x0,0x14,0x0,0x0,}; } final private JJCalls[] jj_2_rtns = new JJCalls[12]; private boolean jj_rescan = false; private int jj_gc = 0; /** Constructor with user supplied CharStream. */ public Parser(CharStream stream) { token_source = new ParserTokenManager(stream); token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 69; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } /** Reinitialise. */ public void ReInit(CharStream stream) { token_source.ReInit(stream); token = new Token(); jj_ntk = -1; jjtree.reset(); jj_gen = 0; for (int i = 0; i < 69; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } /** Constructor with generated Token Manager. */ public Parser(ParserTokenManager tm) { token_source = tm; token = new Token(); jj_ntk = -1; jj_gen = 0; for (int i = 0; i < 69; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } /** Reinitialise. */ public void ReInit(ParserTokenManager tm) { token_source = tm; token = new Token(); jj_ntk = -1; jjtree.reset(); jj_gen = 0; for (int i = 0; i < 69; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } private Token jj_consume_token(int kind) throws ParseException { Token oldToken; if ((oldToken = token).next != null) token = token.next; else token = token.next = token_source.getNextToken(); jj_ntk = -1; if (token.kind == kind) { jj_gen++; if (++jj_gc > 100) { jj_gc = 0; for (int i = 0; i < jj_2_rtns.length; i++) { JJCalls c = jj_2_rtns[i]; while (c != null) { if (c.gen < jj_gen) c.first = null; c = c.next; } } } return token; } token = oldToken; jj_kind = kind; throw generateParseException(); } static private final class LookaheadSuccess extends java.lang.Error { } final private LookaheadSuccess jj_ls = new LookaheadSuccess(); private boolean jj_scan_token(int kind) { if (jj_scanpos == jj_lastpos) { jj_la--; if (jj_scanpos.next == null) { jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); } else { jj_lastpos = jj_scanpos = jj_scanpos.next; } } else { jj_scanpos = jj_scanpos.next; } if (jj_rescan) { int i = 0; Token tok = token; while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; } if (tok != null) jj_add_error_token(kind, i); } if (jj_scanpos.kind != kind) return true; if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; return false; } /** Get the next Token. */ final public Token getNextToken() { if (token.next != null) token = token.next; else token = token.next = token_source.getNextToken(); jj_ntk = -1; jj_gen++; return token; } /** Get the specific Token. */ final public Token getToken(int index) { Token t = token; for (int i = 0; i < index; i++) { if (t.next != null) t = t.next; else t = t.next = token_source.getNextToken(); } return t; } private int jj_ntk() { if ((jj_nt=token.next) == null) return (jj_ntk = (token.next=token_source.getNextToken()).kind); else return (jj_ntk = jj_nt.kind); } private java.util.List jj_expentries = new java.util.ArrayList(); private int[] jj_expentry; private int jj_kind = -1; private int[] jj_lasttokens = new int[100]; private int jj_endpos; private void jj_add_error_token(int kind, int pos) { if (pos >= 100) return; if (pos == jj_endpos + 1) { jj_lasttokens[jj_endpos++] = kind; } else if (jj_endpos != 0) { jj_expentry = new int[jj_endpos]; for (int i = 0; i < jj_endpos; i++) { jj_expentry[i] = jj_lasttokens[i]; } jj_entries_loop: for (java.util.Iterator it = jj_expentries.iterator(); it.hasNext();) { int[] oldentry = (int[])(it.next()); if (oldentry.length == jj_expentry.length) { for (int i = 0; i < jj_expentry.length; i++) { if (oldentry[i] != jj_expentry[i]) { continue jj_entries_loop; } } jj_expentries.add(jj_expentry); break jj_entries_loop; } } if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; } } /** Generate ParseException. */ public ParseException generateParseException() { jj_expentries.clear(); boolean[] la1tokens = new boolean[73]; if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; } for (int i = 0; i < 69; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1< jj_gen) { jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; switch (i) { case 0: jj_3_1(); break; case 1: jj_3_2(); break; case 2: jj_3_3(); break; case 3: jj_3_4(); break; case 4: jj_3_5(); break; case 5: jj_3_6(); break; case 6: jj_3_7(); break; case 7: jj_3_8(); break; case 8: jj_3_9(); break; case 9: jj_3_10(); break; case 10: jj_3_11(); break; case 11: jj_3_12(); break; } } p = p.next; } while (p != null); } catch(LookaheadSuccess ls) { } } jj_rescan = false; } private void jj_save(int index, int xla) { JJCalls p = jj_2_rtns[index]; while (p.gen > jj_gen) { if (p.next == null) { p = p.next = new JJCalls(); break; } p = p.next; } p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; } static final class JJCalls { int gen; Token first; int arg; JJCalls next; } } velocity-1.7/src/java/org/apache/velocity/runtime/exception/0000755000175000017500000000000011675166251024150 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/visitor/0000755000175000017500000000000011675166251023651 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/visitor/NodeViewMode.java0000644000175000017500000003514111150574032027031 0ustar moellermoellerpackage org.apache.velocity.runtime.visitor; /* * 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. */ import org.apache.velocity.runtime.parser.Token; import org.apache.velocity.runtime.parser.node.ASTAddNode; import org.apache.velocity.runtime.parser.node.ASTAndNode; import org.apache.velocity.runtime.parser.node.ASTAssignment; import org.apache.velocity.runtime.parser.node.ASTBlock; import org.apache.velocity.runtime.parser.node.ASTDirective; import org.apache.velocity.runtime.parser.node.ASTDivNode; import org.apache.velocity.runtime.parser.node.ASTEQNode; import org.apache.velocity.runtime.parser.node.ASTElseIfStatement; import org.apache.velocity.runtime.parser.node.ASTElseStatement; import org.apache.velocity.runtime.parser.node.ASTEscape; import org.apache.velocity.runtime.parser.node.ASTEscapedDirective; import org.apache.velocity.runtime.parser.node.ASTExpression; import org.apache.velocity.runtime.parser.node.ASTFalse; import org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral; import org.apache.velocity.runtime.parser.node.ASTGENode; import org.apache.velocity.runtime.parser.node.ASTGTNode; import org.apache.velocity.runtime.parser.node.ASTIdentifier; import org.apache.velocity.runtime.parser.node.ASTIfStatement; import org.apache.velocity.runtime.parser.node.ASTIntegerLiteral; import org.apache.velocity.runtime.parser.node.ASTIntegerRange; import org.apache.velocity.runtime.parser.node.ASTLENode; import org.apache.velocity.runtime.parser.node.ASTLTNode; import org.apache.velocity.runtime.parser.node.ASTMap; import org.apache.velocity.runtime.parser.node.ASTMethod; import org.apache.velocity.runtime.parser.node.ASTModNode; import org.apache.velocity.runtime.parser.node.ASTMulNode; import org.apache.velocity.runtime.parser.node.ASTNENode; import org.apache.velocity.runtime.parser.node.ASTNotNode; import org.apache.velocity.runtime.parser.node.ASTObjectArray; import org.apache.velocity.runtime.parser.node.ASTOrNode; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.parser.node.ASTSetDirective; import org.apache.velocity.runtime.parser.node.ASTStringLiteral; import org.apache.velocity.runtime.parser.node.ASTSubtractNode; import org.apache.velocity.runtime.parser.node.ASTText; import org.apache.velocity.runtime.parser.node.ASTTrue; import org.apache.velocity.runtime.parser.node.ASTWord; import org.apache.velocity.runtime.parser.node.ASTprocess; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; /** * This class is simply a visitor implementation * that traverses the AST, produced by the Velocity * parsing process, and creates a visual structure * of the AST. This is primarily used for * debugging, but it useful for documentation * as well. * * @author Jason van Zyl * @version $Id: NodeViewMode.java 747106 2009-02-23 19:25:14Z nbubna $ */ public class NodeViewMode extends BaseVisitor { private int indent = 0; private boolean showTokens = true; /** Indent child nodes to help visually identify * the structure of the AST. */ private String indentString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < indent; ++i) { sb.append(" "); } return sb.toString(); } /** * Display the type of nodes and optionally the * first token. */ private Object showNode(Node node, Object data) { String tokens = ""; String special = ""; Token t; if (showTokens) { t = node.getFirstToken(); if (t.specialToken != null && ! t.specialToken.image.startsWith("##")) special = t.specialToken.image; tokens = " -> " + special + t.image; } System.out.println(indentString() + node + tokens); ++indent; data = node.childrenAccept(this, data); --indent; return data; } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.SimpleNode, java.lang.Object) */ public Object visit(SimpleNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTprocess, java.lang.Object) */ public Object visit(ASTprocess node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTExpression, java.lang.Object) */ public Object visit(ASTExpression node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAssignment, java.lang.Object) */ public Object visit(ASTAssignment node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTOrNode, java.lang.Object) */ public Object visit(ASTOrNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAndNode, java.lang.Object) */ public Object visit(ASTAndNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEQNode, java.lang.Object) */ public Object visit(ASTEQNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTNENode, java.lang.Object) */ public Object visit(ASTNENode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTLTNode, java.lang.Object) */ public Object visit(ASTLTNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTGTNode, java.lang.Object) */ public Object visit(ASTGTNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTLENode, java.lang.Object) */ public Object visit(ASTLENode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTGENode, java.lang.Object) */ public Object visit(ASTGENode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAddNode, java.lang.Object) */ public Object visit(ASTAddNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTSubtractNode, java.lang.Object) */ public Object visit(ASTSubtractNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMulNode, java.lang.Object) */ public Object visit(ASTMulNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTDivNode, java.lang.Object) */ public Object visit(ASTDivNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTModNode, java.lang.Object) */ public Object visit(ASTModNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTNotNode, java.lang.Object) */ public Object visit(ASTNotNode node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral, java.lang.Object) */ public Object visit(ASTFloatingPointLiteral node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIntegerLiteral, java.lang.Object) * @since 1.5 */ public Object visit(ASTIntegerLiteral node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTStringLiteral, java.lang.Object) */ public Object visit(ASTStringLiteral node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIdentifier, java.lang.Object) */ public Object visit(ASTIdentifier node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMethod, java.lang.Object) */ public Object visit(ASTMethod node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTReference, java.lang.Object) */ public Object visit(ASTReference node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTTrue, java.lang.Object) */ public Object visit(ASTTrue node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTFalse, java.lang.Object) */ public Object visit(ASTFalse node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTBlock, java.lang.Object) */ public Object visit(ASTBlock node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTText, java.lang.Object) */ public Object visit(ASTText node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIfStatement, java.lang.Object) */ public Object visit(ASTIfStatement node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTElseStatement, java.lang.Object) */ public Object visit(ASTElseStatement node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTElseIfStatement, java.lang.Object) */ public Object visit(ASTElseIfStatement node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTObjectArray, java.lang.Object) */ public Object visit(ASTObjectArray node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTDirective, java.lang.Object) */ public Object visit(ASTDirective node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTWord, java.lang.Object) */ public Object visit(ASTWord node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTSetDirective, java.lang.Object) */ public Object visit(ASTSetDirective node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEscapedDirective, java.lang.Object) * @since 1.5 */ public Object visit(ASTEscapedDirective node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEscape, java.lang.Object) * @since 1.5 */ public Object visit(ASTEscape node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMap, java.lang.Object) * @since 1.5 */ public Object visit(ASTMap node, Object data) { return showNode(node,data); } /** * @see org.apache.velocity.runtime.visitor.BaseVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIntegerRange, java.lang.Object) */ public Object visit(ASTIntegerRange node, Object data) { return showNode(node,data); } } velocity-1.7/src/java/org/apache/velocity/runtime/visitor/BaseVisitor.java0000644000175000017500000003754211150574032026745 0ustar moellermoellerpackage org.apache.velocity.runtime.visitor; /* * 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. */ import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.node.ASTAddNode; import org.apache.velocity.runtime.parser.node.ASTAndNode; import org.apache.velocity.runtime.parser.node.ASTAssignment; import org.apache.velocity.runtime.parser.node.ASTBlock; import org.apache.velocity.runtime.parser.node.ASTComment; import org.apache.velocity.runtime.parser.node.ASTDirective; import org.apache.velocity.runtime.parser.node.ASTDivNode; import org.apache.velocity.runtime.parser.node.ASTEQNode; import org.apache.velocity.runtime.parser.node.ASTElseIfStatement; import org.apache.velocity.runtime.parser.node.ASTElseStatement; import org.apache.velocity.runtime.parser.node.ASTEscape; import org.apache.velocity.runtime.parser.node.ASTEscapedDirective; import org.apache.velocity.runtime.parser.node.ASTExpression; import org.apache.velocity.runtime.parser.node.ASTFalse; import org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral; import org.apache.velocity.runtime.parser.node.ASTGENode; import org.apache.velocity.runtime.parser.node.ASTGTNode; import org.apache.velocity.runtime.parser.node.ASTIdentifier; import org.apache.velocity.runtime.parser.node.ASTIfStatement; import org.apache.velocity.runtime.parser.node.ASTIntegerLiteral; import org.apache.velocity.runtime.parser.node.ASTIntegerRange; import org.apache.velocity.runtime.parser.node.ASTLENode; import org.apache.velocity.runtime.parser.node.ASTLTNode; import org.apache.velocity.runtime.parser.node.ASTMap; import org.apache.velocity.runtime.parser.node.ASTMethod; import org.apache.velocity.runtime.parser.node.ASTModNode; import org.apache.velocity.runtime.parser.node.ASTMulNode; import org.apache.velocity.runtime.parser.node.ASTNENode; import org.apache.velocity.runtime.parser.node.ASTNotNode; import org.apache.velocity.runtime.parser.node.ASTObjectArray; import org.apache.velocity.runtime.parser.node.ASTOrNode; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.parser.node.ASTSetDirective; import org.apache.velocity.runtime.parser.node.ASTStringLiteral; import org.apache.velocity.runtime.parser.node.ASTSubtractNode; import org.apache.velocity.runtime.parser.node.ASTText; import org.apache.velocity.runtime.parser.node.ASTTrue; import org.apache.velocity.runtime.parser.node.ASTWord; import org.apache.velocity.runtime.parser.node.ASTprocess; import org.apache.velocity.runtime.parser.node.ParserVisitor; import org.apache.velocity.runtime.parser.node.SimpleNode; /** * This is the base class for all visitors. * For each AST node, this class will provide * a bare-bones method for traversal. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: BaseVisitor.java 747106 2009-02-23 19:25:14Z nbubna $ */ public abstract class BaseVisitor implements ParserVisitor { /** Context used during traversal */ protected InternalContextAdapter context; /** Writer used as the output sink */ protected Writer writer; /** * @param writer */ public void setWriter( Writer writer ) { this.writer = writer; } /** * @param context */ public void setContext( InternalContextAdapter context) { this.context = context; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.SimpleNode, java.lang.Object) */ public Object visit(SimpleNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTprocess, java.lang.Object) */ public Object visit(ASTprocess node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTExpression, java.lang.Object) */ public Object visit(ASTExpression node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAssignment, java.lang.Object) */ public Object visit(ASTAssignment node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTOrNode, java.lang.Object) */ public Object visit(ASTOrNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAndNode, java.lang.Object) */ public Object visit(ASTAndNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEQNode, java.lang.Object) */ public Object visit(ASTEQNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTNENode, java.lang.Object) */ public Object visit(ASTNENode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTLTNode, java.lang.Object) */ public Object visit(ASTLTNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTGTNode, java.lang.Object) */ public Object visit(ASTGTNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTLENode, java.lang.Object) */ public Object visit(ASTLENode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTGENode, java.lang.Object) */ public Object visit(ASTGENode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTAddNode, java.lang.Object) */ public Object visit(ASTAddNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTSubtractNode, java.lang.Object) */ public Object visit(ASTSubtractNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMulNode, java.lang.Object) */ public Object visit(ASTMulNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTDivNode, java.lang.Object) */ public Object visit(ASTDivNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTModNode, java.lang.Object) */ public Object visit(ASTModNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTNotNode, java.lang.Object) */ public Object visit(ASTNotNode node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIntegerLiteral, java.lang.Object) */ public Object visit(ASTIntegerLiteral node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTFloatingPointLiteral, java.lang.Object) * @since 1.5 */ public Object visit(ASTFloatingPointLiteral node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTStringLiteral, java.lang.Object) */ public Object visit(ASTStringLiteral node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIdentifier, java.lang.Object) */ public Object visit(ASTIdentifier node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMethod, java.lang.Object) */ public Object visit(ASTMethod node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTReference, java.lang.Object) */ public Object visit(ASTReference node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTTrue, java.lang.Object) */ public Object visit(ASTTrue node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTFalse, java.lang.Object) */ public Object visit(ASTFalse node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTBlock, java.lang.Object) */ public Object visit(ASTBlock node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTText, java.lang.Object) */ public Object visit(ASTText node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIfStatement, java.lang.Object) */ public Object visit(ASTIfStatement node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTElseStatement, java.lang.Object) */ public Object visit(ASTElseStatement node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTElseIfStatement, java.lang.Object) */ public Object visit(ASTElseIfStatement node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTComment, java.lang.Object) */ public Object visit(ASTComment node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTObjectArray, java.lang.Object) */ public Object visit(ASTObjectArray node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTWord, java.lang.Object) */ public Object visit(ASTWord node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTSetDirective, java.lang.Object) */ public Object visit(ASTSetDirective node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTDirective, java.lang.Object) */ public Object visit(ASTDirective node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEscapedDirective, java.lang.Object) * @since 1.5 */ public Object visit(ASTEscapedDirective node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTEscape, java.lang.Object) * @since 1.5 */ public Object visit(ASTEscape node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTMap, java.lang.Object) * @since 1.5 */ public Object visit(ASTMap node, Object data) { data = node.childrenAccept(this, data); return data; } /** * @see org.apache.velocity.runtime.parser.node.ParserVisitor#visit(org.apache.velocity.runtime.parser.node.ASTIntegerRange, java.lang.Object) * @since 1.5 */ public Object visit(ASTIntegerRange node, Object data) { data = node.childrenAccept(this, data); return data; } } velocity-1.7/src/java/org/apache/velocity/runtime/RuntimeConstants.java0000644000175000017500000003402711243536636026342 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ /** * This class defines the keys that are used in the velocity.properties file so that they can be referenced as a constant within * Java code. * * @author Jon S. Stevens * @author Geir Magnusson Jr. * @author Jason van Zyl * @version $Id: RuntimeConstants.java 806601 2009-08-21 15:30:38Z nbubna $ */ public interface RuntimeConstants { /* * ---------------------------------------------------------------------- * These are public constants that are used as handles for the * properties that can be specified in your typical * velocity.properties file. * ---------------------------------------------------------------------- */ /* * ---------------------------------------------------------------------- * L O G G I N G C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** Location of the velocity log file. */ String RUNTIME_LOG = "runtime.log"; /** externally provided logger. */ String RUNTIME_LOG_LOGSYSTEM = "runtime.log.logsystem"; /** class of log system to use. */ String RUNTIME_LOG_LOGSYSTEM_CLASS = "runtime.log.logsystem.class"; /** * Properties referenced in the template are required to exist the object */ String RUNTIME_REFERENCES_STRICT = "runtime.references.strict"; /** * Indicates we are going to use modifed escape behavior in strict mode */ String RUNTIME_REFERENCES_STRICT_ESCAPE = "runtime.references.strict.escape"; /** * @deprecated This appears to have always been meaningless. */ String RUNTIME_LOG_ERROR_STACKTRACE = "runtime.log.error.stacktrace"; /** * @deprecated The functionality this controlled is confusing and no longer necessary. */ String RUNTIME_LOG_WARN_STACKTRACE = "runtime.log.warn.stacktrace"; /** * @deprecated This appears to have always been meaningless. */ String RUNTIME_LOG_INFO_STACKTRACE = "runtime.log.info.stacktrace"; /** Logging of invalid references. */ String RUNTIME_LOG_REFERENCE_LOG_INVALID = "runtime.log.invalid.references"; /** * @deprecated Use LogChute.TRACE_PREFIX instead */ String TRACE_PREFIX = " [trace] "; /** * @deprecated Use LogChute.DEBUG_PREFIX instead */ String DEBUG_PREFIX = " [debug] "; /** * @deprecated Use LogChute.INFO_PREFIX instead */ String INFO_PREFIX = " [info] "; /** * @deprecated Use LogChute.WARN_PREFIX instead */ String WARN_PREFIX = " [warn] "; /** * @deprecated Use LogChute.ERROR_PREFIX instead */ String ERROR_PREFIX = " [error] "; /** * @deprecated This will be removed in a future version */ String UNKNOWN_PREFIX = " [unknown] "; /* * ---------------------------------------------------------------------- * D I R E C T I V E C O N F I G U R A T I O N * ---------------------------------------------------------------------- * Directive properties are of the form: * * directive.. * ---------------------------------------------------------------------- */ /** Counter reference name in #foreach directives. */ String COUNTER_NAME = "directive.foreach.counter.name"; /** * Iterator.hasNext() reference name in #foreach directives. * @since 1.6 */ String HAS_NEXT_NAME = "directive.foreach.iterator.name"; /** Initial counter value in #foreach directives. */ String COUNTER_INITIAL_VALUE = "directive.foreach.counter.initial.value"; /** Maximum allowed number of loops. */ String MAX_NUMBER_LOOPS = "directive.foreach.maxloops"; /** * Whether to throw an exception or just skip bad iterables. Default is true. * @since 1.6 */ String SKIP_INVALID_ITERATOR = "directive.foreach.skip.invalid"; /** if set to true then allows #set to accept null values in the right hand side. */ String SET_NULL_ALLOWED = "directive.set.null.allowed"; /** * Indicates if toString() should be called during #if condition evaluation * just to ensure it does not return null. Check is unnecessary if all * toString() implementations are known to have non-null return values. * Disabling the check (like Velocity 1.5 did) will can boost performance * since toString() may be a complex operation on large objects. * @since 1.6 */ String DIRECTIVE_IF_TOSTRING_NULLCHECK = "directive.if.tostring.nullcheck"; /** * Starting tag for error messages triggered by passing a parameter not allowed in the #include directive. Only string literals, * and references are allowed. */ String ERRORMSG_START = "directive.include.output.errormsg.start"; /** * Ending tag for error messages triggered by passing a parameter not allowed in the #include directive. Only string literals, * and references are allowed. */ String ERRORMSG_END = "directive.include.output.errormsg.end"; /** Maximum recursion depth allowed for the #parse directive. */ String PARSE_DIRECTIVE_MAXDEPTH = "directive.parse.max.depth"; /** Maximum recursion depth allowed for the #define directive. */ String DEFINE_DIRECTIVE_MAXDEPTH = "directive.define.max.depth"; /** * class to use for local context with #evaluate() * @since 1.6 */ String EVALUATE_CONTEXT_CLASS = "directive.evaluate.context.class"; /** * Used to suppress various scope control objects. * @since 1.7 */ String PROVIDE_SCOPE_CONTROL = "provide.scope.control"; /* * ---------------------------------------------------------------------- * R E S O U R C E M A N A G E R C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** */ String RESOURCE_MANAGER_CLASS = "resource.manager.class"; /** * The resource.manager.cache.class property specifies the name of the * {@link org.apache.velocity.runtime.resource.ResourceCache} implementation to use. */ String RESOURCE_MANAGER_CACHE_CLASS = "resource.manager.cache.class"; /** The resource.manager.cache.size property specifies the cache upper bound (if relevant). */ String RESOURCE_MANAGER_DEFAULTCACHE_SIZE = "resource.manager.defaultcache.size"; /* * ---------------------------------------------------------------------- * R E S O U R C E L O A D E R C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** controls if the finding of a resource is logged. */ String RESOURCE_MANAGER_LOGWHENFOUND = "resource.manager.logwhenfound"; /** * Key used to retrieve the names of the resource loaders to be used. In a properties file they may appear as the following: * *

      resource.loader = file,classpath

      */ String RESOURCE_LOADER = "resource.loader"; /** The public handle for setting a path in the FileResourceLoader. */ String FILE_RESOURCE_LOADER_PATH = "file.resource.loader.path"; /** The public handle for turning the caching on in the FileResourceLoader. */ String FILE_RESOURCE_LOADER_CACHE = "file.resource.loader.cache"; /* * ---------------------------------------------------------------------- * E V E N T H A N D L E R C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** * The eventhandler.referenceinsertion.class property specifies a list of the * {@link org.apache.velocity.app.event.ReferenceInsertionEventHandler} implementations to use. */ String EVENTHANDLER_REFERENCEINSERTION = "eventhandler.referenceinsertion.class"; /** * The eventhandler.nullset.class property specifies a list of the * {@link org.apache.velocity.app.event.NullSetEventHandler} implementations to use. */ String EVENTHANDLER_NULLSET = "eventhandler.nullset.class"; /** * The eventhandler.methodexception.class property specifies a list of the * {@link org.apache.velocity.app.event.MethodExceptionEventHandler} implementations to use. */ String EVENTHANDLER_METHODEXCEPTION = "eventhandler.methodexception.class"; /** * The eventhandler.include.class property specifies a list of the * {@link org.apache.velocity.app.event.IncludeEventHandler} implementations to use. */ String EVENTHANDLER_INCLUDE = "eventhandler.include.class"; /** * The eventhandler.invalidreferences.class property specifies a list of the * {@link org.apache.velocity.app.event.InvalidReferenceEventHandler} implementations to use. */ String EVENTHANDLER_INVALIDREFERENCES = "eventhandler.invalidreferences.class"; /* * ---------------------------------------------------------------------- * V E L O C I M A C R O C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** Name of local Velocimacro library template. */ String VM_LIBRARY = "velocimacro.library"; /** Default Velocimacro library template. */ String VM_LIBRARY_DEFAULT = "VM_global_library.vm"; /** switch for autoloading library-sourced VMs (for development). */ String VM_LIBRARY_AUTORELOAD = "velocimacro.library.autoreload"; /** boolean (true/false) default true : allow inline (in-template) macro definitions. */ String VM_PERM_ALLOW_INLINE = "velocimacro.permissions.allow.inline"; /** boolean (true/false) default false : allow inline (in-template) macro definitions to replace existing. */ String VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL = "velocimacro.permissions.allow.inline.to.replace.global"; /** Switch for forcing inline macros to be local : default false. */ String VM_PERM_INLINE_LOCAL = "velocimacro.permissions.allow.inline.local.scope"; /** Switch for VM blather : default true. */ String VM_MESSAGES_ON = "velocimacro.messages.on"; /** switch for local context in VM : default false. */ String VM_CONTEXT_LOCALSCOPE = "velocimacro.context.localscope"; /** if true, throw an exception for wrong number of arguments **/ String VM_ARGUMENTS_STRICT = "velocimacro.arguments.strict"; /** * Specify the maximum depth for macro calls * @since 1.6 */ String VM_MAX_DEPTH = "velocimacro.max.depth"; /** * Defines name of the reference that can be used to get the AST block passed to block macro calls. * @since 1.7 */ String VM_BODY_REFERENCE = "velocimacro.body.reference"; /* * ---------------------------------------------------------------------- * G E N E R A L R U N T I M E C O N F I G U R A T I O N * ---------------------------------------------------------------------- */ /** Switch for the interpolation facility for string literals. */ String INTERPOLATE_STRINGLITERALS = "runtime.interpolate.string.literals"; /** The character encoding for the templates. Used by the parser in processing the input streams. */ String INPUT_ENCODING = "input.encoding"; /** Encoding for the output stream. Currently used by Anakia and VelocityServlet */ String OUTPUT_ENCODING = "output.encoding"; /** Default Encoding is ISO-8859-1. */ String ENCODING_DEFAULT = "ISO-8859-1"; /** key name for uberspector. Multiple classnames can be specified,in which case uberspectors will be chained. */ String UBERSPECT_CLASSNAME = "runtime.introspector.uberspect"; /** A comma separated list of packages to restrict access to in the SecureIntrospector. */ String INTROSPECTOR_RESTRICT_PACKAGES = "introspector.restrict.packages"; /** A comma separated list of classes to restrict access to in the SecureIntrospector. */ String INTROSPECTOR_RESTRICT_CLASSES = "introspector.restrict.classes"; /** Switch for ignoring nulls in math equations vs throwing exceptions. */ String STRICT_MATH = "runtime.strict.math"; /** * The parser.pool.class property specifies the name of the {@link org.apache.velocity.util.SimplePool} * implementation to use. */ String PARSER_POOL_CLASS = "parser.pool.class"; /** * @see #NUMBER_OF_PARSERS */ String PARSER_POOL_SIZE = "parser.pool.size"; /* * ---------------------------------------------------------------------- * These constants are used internally by the Velocity runtime i.e. * the constants listed below are strictly used in the Runtime * class itself. * ---------------------------------------------------------------------- */ /** Default Runtime properties. */ String DEFAULT_RUNTIME_PROPERTIES = "org/apache/velocity/runtime/defaults/velocity.properties"; /** Default Runtime properties. */ String DEFAULT_RUNTIME_DIRECTIVES = "org/apache/velocity/runtime/defaults/directive.properties"; /** * The default number of parser instances to create. Configurable via the parameter named by the {@link #PARSER_POOL_SIZE} * constant. */ int NUMBER_OF_PARSERS = 20; } velocity-1.7/src/java/org/apache/velocity/runtime/Runtime.java0000644000175000017500000004304511050422673024434 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.io.Reader; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.resource.ContentResource; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import org.apache.commons.collections.ExtendedProperties; /** * This is the Runtime system for Velocity. It is the * single access point for all functionality in Velocity. * It adheres to the mediator pattern and is the only * structure that developers need to be familiar with * in order to get Velocity to perform. * * The Runtime will also cooperate with external * systems like Turbine. Runtime properties can * set and then the Runtime is initialized. * * Turbine for example knows where the templates * are to be loaded from, and where the velocity * log file should be placed. * * So in the case of Velocity cooperating with Turbine * the code might look something like the following: * *
       * Runtime.setProperty(Runtime.FILE_RESOURCE_LOADER_PATH, templatePath);
       * Runtime.setProperty(Runtime.RUNTIME_LOG, pathToVelocityLog);
       * Runtime.init();
       * 
      * *
       * -----------------------------------------------------------------------
       * N O T E S  O N  R U N T I M E  I N I T I A L I Z A T I O N
       * -----------------------------------------------------------------------
       * Runtime.init()
       *
       * If Runtime.init() is called by itself the Runtime will
       * initialize with a set of default values.
       * -----------------------------------------------------------------------
       * Runtime.init(String/Properties)
       *
       * In this case the default velocity properties are layed down
       * first to provide a solid base, then any properties provided
       * in the given properties object will override the corresponding
       * default property.
       * -----------------------------------------------------------------------
       * 
      * * @author Jason van Zyl * @author Jeff Bowden * @author Geir Magusson Jr. * * @see org.apache.velocity.runtime.RuntimeInstance * @see org.apache.velocity.runtime.RuntimeSingleton * @deprecated Use RuntimeInstance or RuntimeSingleton instead. * * @version $Id: Runtime.java 685390 2008-08-13 00:07:23Z nbubna $ */ public class Runtime implements RuntimeConstants { /** * This is the primary initialization method in the Velocity * Runtime. The systems that are setup/initialized here are * as follows: * *
        *
      • Logging System
      • *
      • ResourceManager
      • *
      • Parser Pool
      • *
      • Global Cache
      • *
      • Static Content Include System
      • *
      • Velocimacro System
      • *
      * * @throws Exception When init fails for any reason. */ public synchronized static void init() throws Exception { RuntimeSingleton.init(); } /** * Allows an external system to set a property in * the Velocity Runtime. * * @param key The property key. * @param value The property value. */ public static void setProperty(String key, Object value) { RuntimeSingleton.setProperty( key, value ); } /** * Allow an external system to set an ExtendedProperties * object to use. This is useful where the external * system also uses the ExtendedProperties class and * the velocity configuration is a subset of * parent application's configuration. This is * the case with Turbine. * * @param configuration A configuration object. */ public static void setConfiguration( ExtendedProperties configuration) { RuntimeSingleton.setConfiguration( configuration ); } /** * Add a property to the configuration. If it already * exists then the value stated here will be added * to the configuration entry. For example, if * * resource.loader = file * * is already present in the configuration and you * * addProperty("resource.loader", "classpath") * * Then you will end up with a Vector like the * following: * * ["file", "classpath"] * * @param key A property key. * @param value The property value. */ public static void addProperty(String key, Object value) { RuntimeSingleton.addProperty( key, value ); } /** * Clear the values pertaining to a particular * property. * * @param key Name of the property to clear. */ public static void clearProperty(String key) { RuntimeSingleton.clearProperty( key ); } /** * Allows an external caller to get a property. The calling * routine is required to know the type, as this routine * will return an Object, as that is what properties can be. * * @param key property to return * @return The property value or null. */ public static Object getProperty( String key ) { return RuntimeSingleton.getProperty( key ); } /** * Initialize the Velocity Runtime with a Properties * object. * * @param p The properties used for initializiation. * @throws Exception When a problem occurs during init. */ public static void init(Properties p) throws Exception { RuntimeSingleton.init(p); } /** * Initialize the Velocity Runtime with the name of * ExtendedProperties object. * * @param configurationFile The name of a properties file. * @throws Exception When a problem occurs during init. */ public static void init(String configurationFile) throws Exception { RuntimeSingleton.init( configurationFile ); } /** * Parse the input and return the root of * AST node structure. *

      * In the event that it runs out of parsers in the * pool, it will create and let them be GC'd * dynamically, logging that it has to do that. This * is considered an exceptional condition. It is * expected that the user will set the * PARSER_POOL_SIZE property appropriately for their * application. We will revisit this. * * @param reader A reader returning the template input stream. * @param templateName name of the template being parsed * @return The root node of an AST structure for the template input stream. * @throws ParseException When the input stream is not parsable. */ public static SimpleNode parse( Reader reader, String templateName ) throws ParseException { return RuntimeSingleton.parse( reader, templateName ); } /** * Parse the input and return the root of the AST node structure. * * @see #parse(Reader, String) * * @param reader A reader returning the template input stream. * @param templateName name of the template being parsed * @param dumpNamespace flag to dump the Velocimacro namespace for this template. * @return The root node of an AST structure for the template input stream. * @throws ParseException When the input stream is not parsable. */ public static SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace ) throws ParseException { return RuntimeSingleton.parse( reader, templateName, dumpNamespace ); } /** * Returns a Template from the resource manager. * This method assumes that the character encoding of the * template is set by the input.encoding * property. The default is "ISO-8859-1" * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization. */ public static Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getTemplate( name ); } /** * Returns a Template from the resource manager * * @param name The name of the desired template. * @param encoding Character encoding of the template * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization */ public static Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getTemplate( name, encoding ); } /** * Returns a static content resource from the * resource manager. Uses the current value * if INPUT_ENCODING as the character encoding. * * @param name Name of content resource to get * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization */ public static ContentResource getContent(String name) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getContent( name ); } /** * Returns a static content resource from the * resource manager. * * @param name Name of content resource to get * @param encoding Character encoding to use * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization */ public static ContentResource getContent( String name, String encoding ) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getContent( name, encoding ); } /** * Determines is a template exists, and returns name of the loader that * provides it. This is a slightly less hokey way to support * the Velocity.templateExists() utility method, which was broken * when per-template encoding was introduced. We can revisit this. * * @param resourceName Name of template or content resource * @return class name of loader than can provide it */ public static String getLoaderNameForResource( String resourceName ) { return RuntimeSingleton.getLoaderNameForResource( resourceName ); } /** * Log a warning message. * * @param message message to log */ public static void warn(Object message) { RuntimeSingleton.warn( message ); } /** * Log an info message. * * @param message message to log */ public static void info(Object message) { RuntimeSingleton.info( message ); } /** * Log an error message. * * @param message message to log */ public static void error(Object message) { RuntimeSingleton.error( message ); } /** * Log a debug message. * * @param message message to log */ public static void debug(Object message) { RuntimeSingleton.debug( message ); } /** * String property accessor method with default to hide the * configuration implementation. * * @param key A property key. * @param defaultValue default value to return if key not * found in resource manager. * @return The property value of of key or default. */ public static String getString( String key, String defaultValue) { return RuntimeSingleton.getString( key, defaultValue ); } /** * Returns the appropriate VelocimacroProxy object if strVMname * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName The template from which the macro is requested. * @return A VelocimacroProxy object for the macro. */ public static Directive getVelocimacro( String vmName, String templateName ) { return RuntimeSingleton.getVelocimacro( vmName, templateName ); } /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of a new velocimacro. * @param macro String form of the macro body. * @param argArray Array of strings, containing the * #macro() arguments. the 0th argument is the name. * @param sourceTemplate The template from which the macro is requested. * @return boolean True if added, false if rejected for some * reason (either parameters or permission settings) * @deprecated Just like the whole class.... */ public static boolean addVelocimacro( String name, String macro, String argArray[], String sourceTemplate ) { return RuntimeSingleton.addVelocimacro( name, macro, argArray, sourceTemplate ); } /** * Checks to see if a VM exists * * @param vmName The name of velocimacro. * @param templateName The template from which the macro is requested. * @return boolean True if VM by that name exists, false if not */ public static boolean isVelocimacro( String vmName, String templateName ) { return RuntimeSingleton.isVelocimacro( vmName, templateName ); } /** * tells the vmFactory to dump the specified namespace. This is to support * clearing the VM list when in inline-VM-local-scope mode * * @param namespace The namespace to dump. * @return True if the namespace has been dumped. */ public static boolean dumpVMNamespace( String namespace ) { return RuntimeSingleton.dumpVMNamespace( namespace ); } /* -------------------------------------------------------------------- * R U N T I M E A C C E S S O R M E T H O D S * -------------------------------------------------------------------- * These are the getXXX() methods that are a simple wrapper * around the configuration object. This is an attempt * to make a the Velocity Runtime the single access point * for all things Velocity, and allow the Runtime to * adhere as closely as possible the the Mediator pattern * which is the ultimate goal. * -------------------------------------------------------------------- */ /** * String property accessor method to hide the configuration implementation * @param key property key * @return value of key or null */ public static String getString(String key) { return RuntimeSingleton.getString( key ); } /** * Int property accessor method to hide the configuration implementation. * * @param key A property key. * @return Integer value for this key. */ public static int getInt( String key ) { return RuntimeSingleton.getInt( key ); } /** * Int property accessor method to hide the configuration implementation. * * @param key property key * @param defaultValue default value * @return The integer value. */ public static int getInt( String key, int defaultValue ) { return RuntimeSingleton.getInt( key, defaultValue ); } /** * Boolean property accessor method to hide the configuration implementation. * * @param key property key * @param def default default value if property not found * @return boolean value of key or default value */ public static boolean getBoolean( String key, boolean def ) { return RuntimeSingleton.getBoolean( key, def ); } /** * Return the velocity runtime configuration object. * * @return ExtendedProperties configuration object which houses * the velocity runtime properties. */ public static ExtendedProperties getConfiguration() { return RuntimeSingleton.getConfiguration(); } } velocity-1.7/src/java/org/apache/velocity/runtime/RuntimeLogger.java0000644000175000017500000000376310513464370025602 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ /** * Interface for internal runtime logging services. This will hopefully * be dissolved into the Log class at some point soon. * * @author Geir Magusson Jr. * @version $Id: RuntimeLogger.java 463298 2006-10-12 16:10:32Z henning $ * @deprecated This functionality has been taken over by the Log class */ public interface RuntimeLogger { /** * @deprecated Use Log.warn(Object). * @see org.apache.velocity.runtime.log.Log#warn(Object) * @param message The message to log. */ public void warn(Object message); /** * @deprecated Use Log.info(Object) * @see org.apache.velocity.runtime.log.Log#info(Object) * @param message The message to log. */ public void info(Object message); /** * @deprecated Use Log.error(Object) * @see org.apache.velocity.runtime.log.Log#error(Object) * @param message The message to log. */ public void error(Object message); /** * @deprecated Use Log.debug(Object) * @see org.apache.velocity.runtime.log.Log#debug(Object) * @param message The message to log. */ public void debug(Object message); } velocity-1.7/src/java/org/apache/velocity/runtime/ParserPool.java0000644000175000017500000000325711050652577025110 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import org.apache.velocity.runtime.parser.Parser; /** * Provides instances of parsers as needed. get() will return a new parser if * available. If a parser is acquired from the pool, put() should be called * with that parser to make it available again for reuse. * * @author Serge Knystautas * @version $Id: RuntimeInstance.java 384374 2006-03-08 23:19:30Z nbubna $ * @since 1.5 */ public interface ParserPool { /** * Initialize the pool so that it can begin serving parser instances. * @param svc */ void initialize(RuntimeServices svc); /** * Retrieve an instance of a parser pool. * @return A parser object. */ Parser get(); /** * Return the parser to the pool so that it may be reused. * @param parser */ void put(Parser parser); } velocity-1.7/src/java/org/apache/velocity/runtime/RuntimeServices.java0000644000175000017500000004501511322703343026135 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.io.Reader; import java.io.Writer; import java.util.Properties; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.Template; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.Parser; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.resource.ContentResource; import org.apache.velocity.util.introspection.Introspector; import org.apache.velocity.util.introspection.Uberspect; /** * Interface for internal runtime services that are needed by the * various components w/in Velocity. This was taken from the old * Runtime singleton, and anything not necessary was removed. * * Currently implemented by RuntimeInstance. * * @author Geir Magusson Jr. * @version $Id: RuntimeServices.java 898050 2010-01-11 20:15:31Z nbubna $ */ public interface RuntimeServices extends RuntimeLogger { /** * This is the primary initialization method in the Velocity * Runtime. The systems that are setup/initialized here are * as follows: * *
        *
      • Logging System
      • *
      • ResourceManager
      • *
      • Parser Pool
      • *
      • Global Cache
      • *
      • Static Content Include System
      • *
      • Velocimacro System
      • *
      */ public void init(); /** * Allows an external system to set a property in * the Velocity Runtime. * * @param key property key * @param value property value */ public void setProperty(String key, Object value); /** * Allow an external system to set an ExtendedProperties * object to use. This is useful where the external * system also uses the ExtendedProperties class and * the velocity configuration is a subset of * parent application's configuration. This is * the case with Turbine. * * @param configuration */ public void setConfiguration( ExtendedProperties configuration); /** * Add a property to the configuration. If it already * exists then the value stated here will be added * to the configuration entry. For example, if * * resource.loader = file * * is already present in the configuration and you * * addProperty("resource.loader", "classpath") * * Then you will end up with a Vector like the * following: * * ["file", "classpath"] * * @param key * @param value */ public void addProperty(String key, Object value); /** * Clear the values pertaining to a particular * property. * * @param key of property to clear */ public void clearProperty(String key); /** * Allows an external caller to get a property. The calling * routine is required to know the type, as this routine * will return an Object, as that is what properties can be. * * @param key property to return * @return The value. */ public Object getProperty( String key ); /** * Initialize the Velocity Runtime with a Properties * object. * * @param p */ public void init(Properties p); /** * Initialize the Velocity Runtime with the name of * ExtendedProperties object. * * @param configurationFile */ public void init(String configurationFile); /** * Wraps the String in a StringReader and passes it off to * {@link #parse(Reader,String)}. * @since 1.6 */ public SimpleNode parse(String string, String templateName) throws ParseException; /** * Parse the input and return the root of * AST node structure. *

      * In the event that it runs out of parsers in the * pool, it will create and let them be GC'd * dynamically, logging that it has to do that. This * is considered an exceptional condition. It is * expected that the user will set the * PARSER_POOL_SIZE property appropriately for their * application. We will revisit this. * * @param reader inputstream retrieved by a resource loader * @param templateName name of the template being parsed * @return The AST representing the template. * @throws ParseException */ public SimpleNode parse( Reader reader, String templateName ) throws ParseException; /** * Parse the input and return the root of the AST node structure. * * @param reader inputstream retrieved by a resource loader * @param templateName name of the template being parsed * @param dumpNamespace flag to dump the Velocimacro namespace for this template * @return The AST representing the template. * @throws ParseException */ public SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace ) throws ParseException; /** * Renders the input string using the context into the output writer. * To be used when a template is dynamically constructed, or want to use * Velocity as a token replacer. * * @param context context to use in rendering input string * @param out Writer in which to render the output * @param logTag string to be used as the template name for log * messages in case of error * @param instring input string containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @throws IOException While rendering to the writer, an I/O problem occured. * @since Velocity 1.6 */ public boolean evaluate(Context context, Writer out, String logTag, String instring); /** * Renders the input reader using the context into the output writer. * To be used when a template is dynamically constructed, or want to * use Velocity as a token replacer. * * @param context context to use in rendering input string * @param writer Writer in which to render the output * @param logTag string to be used as the template name for log messages * in case of error * @param reader Reader containing the VTL to be rendered * * @return true if successful, false otherwise. If false, see * Velocity runtime log * @throws ParseErrorException The template could not be parsed. * @throws MethodInvocationException A method on a context object could not be invoked. * @throws ResourceNotFoundException A referenced resource could not be loaded. * @since Velocity 1.6 */ public boolean evaluate(Context context, Writer writer, String logTag, Reader reader); /** * Invokes a currently registered Velocimacro with the params provided * and places the rendered stream into the writer. *
      * Note : currently only accepts args to the VM if they are in the context. * * @param vmName name of Velocimacro to call * @param logTag string to be used for template name in case of error. if null, * the vmName will be used * @param params keys for args used to invoke Velocimacro, in java format * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar") * @param context Context object containing data/objects used for rendering. * @param writer Writer for output stream * @return true if Velocimacro exists and successfully invoked, false otherwise. * @since 1.6 */ public boolean invokeVelocimacro(final String vmName, String logTag, String[] params, final Context context, final Writer writer); /** * Returns a Template from the resource manager. * This method assumes that the character encoding of the * template is set by the input.encoding * property. The default is "ISO-8859-1" * * @param name The file name of the desired template. * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name) throws ResourceNotFoundException, ParseErrorException; /** * Returns a Template from the resource manager * * @param name The name of the desired template. * @param encoding Character encoding of the template * @return The template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name, String encoding) throws ResourceNotFoundException, ParseErrorException; /** * Returns a static content resource from the * resource manager. Uses the current value * if INPUT_ENCODING as the character encoding. * * @param name Name of content resource to get * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException */ public ContentResource getContent(String name) throws ResourceNotFoundException, ParseErrorException; /** * Returns a static content resource from the * resource manager. * * @param name Name of content resource to get * @param encoding Character encoding to use * @return parsed ContentResource object ready for use * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException */ public ContentResource getContent( String name, String encoding ) throws ResourceNotFoundException, ParseErrorException; /** * Determines is a template exists, and returns name of the loader that * provides it. This is a slightly less hokey way to support * the Velocity.templateExists() utility method, which was broken * when per-template encoding was introduced. We can revisit this. * * @param resourceName Name of template or content resource * @return class name of loader than can provide it */ public String getLoaderNameForResource( String resourceName ); /** * String property accessor method with default to hide the * configuration implementation. * * @param key property key * @param defaultValue default value to return if key not * found in resource manager. * @return String value of key or default */ public String getString( String key, String defaultValue); /** * Returns the appropriate VelocimacroProxy object if strVMname * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName Name of the namespace. * @return VelocimacroProxy */ public Directive getVelocimacro( String vmName, String templateName ); /** * Returns the appropriate VelocimacroProxy object if strVMname * is a valid current Velocimacro. * * @param vmName Name of velocimacro requested * @param templateName Name of the namespace. * @param renderingTemplate Name of the template we are currently rendering. This * information is needed when VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL setting is true * and template contains a macro with the same name as the global macro library. * * @since Velocity 1.6 * * @return VelocimacroProxy */ public Directive getVelocimacro( String vmName, String templateName, String renderingTemplate ); /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of velocimacro * @param macro String form of macro body * @param argArray Array of strings, containing the * #macro() arguments. the 0th is the name. * @param sourceTemplate * * @deprecated Use addVelocimacro(String, Node, String[], String) instead * * @return boolean True if added, false if rejected for some * reason (either parameters or permission settings) */ public boolean addVelocimacro( String name, String macro, String argArray[], String sourceTemplate ); /** * Adds a new Velocimacro. Usually called by Macro only while parsing. * * @param name Name of velocimacro * @param macro root AST node of the parsed macro * @param argArray Array of strings, containing the * #macro() arguments. the 0th is the name. * @param sourceTemplate * * @since Velocity 1.6 * * @return boolean True if added, false if rejected for some * reason (either parameters or permission settings) */ public boolean addVelocimacro( String name, Node macro, String argArray[], String sourceTemplate ); /** * Checks to see if a VM exists * * @param vmName Name of velocimacro * @param templateName * @return boolean True if VM by that name exists, false if not */ public boolean isVelocimacro( String vmName, String templateName ); /** * tells the vmFactory to dump the specified namespace. This is to support * clearing the VM list when in inline-VM-local-scope mode * @param namespace * @return True if the Namespace was dumped. */ public boolean dumpVMNamespace( String namespace ); /** * String property accessor method to hide the configuration implementation * @param key property key * @return value of key or null */ public String getString(String key); /** * Int property accessor method to hide the configuration implementation. * * @param key property key * @return int value */ public int getInt( String key ); /** * Int property accessor method to hide the configuration implementation. * * @param key property key * @param defaultValue default value * @return int value */ public int getInt( String key, int defaultValue ); /** * Boolean property accessor method to hide the configuration implementation. * * @param key property key * @param def default default value if property not found * @return boolean value of key or default value */ public boolean getBoolean( String key, boolean def ); /** * Return the velocity runtime configuration object. * * @return ExtendedProperties configuration object which houses * the velocity runtime properties. */ public ExtendedProperties getConfiguration(); /** * Return the specified application attribute. * * @param key The name of the attribute to retrieve. * @return The value of the attribute. */ public Object getApplicationAttribute( Object key ); /** * Set the specified application attribute. * * @param key The name of the attribute to set. * @param value The attribute value to set. * @return the displaced attribute value */ public Object setApplicationAttribute( Object key, Object value ); /** * Returns the configured class introspection/reflection * implementation. * @return The current Uberspect object. */ public Uberspect getUberspect(); /** * Returns a convenient Log instance that wraps the current LogChute. * @return A log object. */ public Log getLog(); /** * Returns the event handlers for the application. * @return The event handlers for the application. */ public EventCartridge getApplicationEventCartridge(); /** * Returns the configured method introspection/reflection * implementation. * @return The configured method introspection/reflection * implementation. */ public Introspector getIntrospector(); /** * Returns true if the RuntimeInstance has been successfully initialized. * @return True if the RuntimeInstance has been successfully initialized. */ public boolean isInitialized(); /** * Create a new parser instance. * @return A new parser instance. */ public Parser createNewParser(); /** * Retrieve a previously instantiated directive. * @param name name of the directive * @return the directive with that name, if any * @since 1.6 */ public Directive getDirective(String name); } velocity-1.7/src/java/org/apache/velocity/runtime/defaults/0000755000175000017500000000000011675166251023761 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/defaults/directive.properties0000644000175000017500000000242611150574032030045 0ustar moellermoeller# 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. directive.1=org.apache.velocity.runtime.directive.Foreach directive.2=org.apache.velocity.runtime.directive.Include directive.3=org.apache.velocity.runtime.directive.Parse directive.4=org.apache.velocity.runtime.directive.Macro directive.5=org.apache.velocity.runtime.directive.Literal directive.6=org.apache.velocity.runtime.directive.Evaluate directive.7=org.apache.velocity.runtime.directive.Break directive.8=org.apache.velocity.runtime.directive.Define directive.9=org.apache.velocity.runtime.directive.Stop velocity-1.7/src/java/org/apache/velocity/runtime/defaults/velocity.properties0000644000175000017500000003103511243536636027736 0ustar moellermoeller# 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. # ---------------------------------------------------------------------------- # R U N T I M E L O G # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # default LogChute to use: default: AvalonLogChute, Log4JLogChute, CommonsLogLogChute, ServletLogChute, JdkLogChute # ---------------------------------------------------------------------------- runtime.log.logsystem.class = org.apache.velocity.runtime.log.AvalonLogChute,org.apache.velocity.runtime.log.Log4JLogChute,org.apache.velocity.runtime.log.CommonsLogLogChute,org.apache.velocity.runtime.log.ServletLogChute,org.apache.velocity.runtime.log.JdkLogChute # --------------------------------------------------------------------------- # This is the location of the Velocity Runtime log. # ---------------------------------------------------------------------------- runtime.log = velocity.log # ---------------------------------------------------------------------------- # This controls whether invalid references are logged. # ---------------------------------------------------------------------------- runtime.log.invalid.references = true # ---------------------------------------------------------------------------- # T E M P L A T E E N C O D I N G # ---------------------------------------------------------------------------- input.encoding=ISO-8859-1 output.encoding=ISO-8859-1 # ---------------------------------------------------------------------------- # F O R E A C H P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control how the counter is accessed in the #foreach # directive. By default the reference $velocityCount and $velocityHasNext # will be available in the body of the #foreach directive. # The default starting value for $velocityCount is 1. # ---------------------------------------------------------------------------- directive.foreach.counter.name = velocityCount directive.foreach.counter.initial.value = 1 directive.foreach.maxloops = -1 directive.foreach.iterator.name = velocityHasNext # ---------------------------------------------------------------------------- # S E T P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control the behavior of #set. # For compatibility, the default behavior is to disallow setting a reference # to null. This default may be changed in a future version. # ---------------------------------------------------------------------------- directive.set.null.allowed = false # ---------------------------------------------------------------------------- # I F P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control the behavior of #if # Default behavior is to check return value of toString() and treat an object # with toString() that returns null as null. If all objects have toString() # methods that never return null, this check is unnecessary and can be disabled # to gain performance. In Velocity 1.5, no such null check was performed. directive.if.tostring.nullcheck = true # ---------------------------------------------------------------------------- # I N C L U D E P R O P E R T I E S # ---------------------------------------------------------------------------- # These are the properties that governed the way #include'd content # is governed. # ---------------------------------------------------------------------------- directive.include.output.errormsg.start = # ---------------------------------------------------------------------------- # P A R S E P R O P E R T I E S # ---------------------------------------------------------------------------- directive.parse.max.depth = 10 # ---------------------------------------------------------------------------- # S C O P E P R O P E R T I E S # ---------------------------------------------------------------------------- # These are the properties that govern whether or not a Scope object # is automatically provided for each of the given scopes to serve as a # scope-safe reference namespace and "label" for #break calls. The default # for most of these is false. Note that should be replaced by # name of macros that take bodies for which you want to suppress the scope. # ---------------------------------------------------------------------------- # template.provide.scope.control = false # evaluate.provide.scope.control = false foreach.provide.scope.control = true # macro.provide.scope.control = false # define.provide.scope.control = false # .provide.scope.control = false # ---------------------------------------------------------------------------- # T E M P L A T E L O A D E R S # ---------------------------------------------------------------------------- # # # ---------------------------------------------------------------------------- resource.loader = file file.resource.loader.description = Velocity File Resource Loader file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader file.resource.loader.path = . file.resource.loader.cache = false file.resource.loader.modificationCheckInterval = 2 string.resource.loader.description = Velocity String Resource Loader string.resource.loader.class = org.apache.velocity.runtime.resource.loader.StringResourceLoader # ---------------------------------------------------------------------------- # VELOCIMACRO PROPERTIES # ---------------------------------------------------------------------------- # global : name of default global library. It is expected to be in the regular # template path. You may remove it (either the file or this property) if # you wish with no harm. # ---------------------------------------------------------------------------- # velocimacro.library = VM_global_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false velocimacro.max.depth = 20 # ---------------------------------------------------------------------------- # VELOCIMACRO STRICT MODE # ---------------------------------------------------------------------------- # if true, will throw an exception for incorrect number # of arguments. false by default (for backwards compatibility) # but this option will eventually be removed and will always # act as if true # ---------------------------------------------------------------------------- velocimacro.arguments.strict = false # ---------------------------------------------------------------------------- # VELOCIMACRO BODY REFERENCE # ---------------------------------------------------------------------------- # Defines name of the reference that can be used to render the AST block passed to # block macro call as an argument inside a macro. # ---------------------------------------------------------------------------- velocimacro.body.reference=bodyContent # ---------------------------------------------------------------------------- # STRICT REFERENCE MODE # ---------------------------------------------------------------------------- # if true, will throw a MethodInvocationException for references # that are not defined in the context, or have not been defined # with a #set directive. This setting will also throw an exception # if an attempt is made to call a non-existing property on an object # or if the object is null. When this property is true then property # 'directive.set.null.allowed' is also set to true. # ---------------------------------------------------------------------------- runtime.references.strict = false # ---------------------------------------------------------------------------- # INTERPOLATION # ---------------------------------------------------------------------------- # turn off and on interpolation of references and directives in string # literals. ON by default :) # ---------------------------------------------------------------------------- runtime.interpolate.string.literals = true # ---------------------------------------------------------------------------- # RESOURCE MANAGEMENT # ---------------------------------------------------------------------------- # Allows alternative ResourceManager and ResourceCache implementations # to be plugged in. # ---------------------------------------------------------------------------- resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl # ---------------------------------------------------------------------------- # PARSER POOL # ---------------------------------------------------------------------------- # Selects a custom factory class for the parser pool. Must implement # ParserPool. parser.pool.size is used by the default implementation # ParserPoolImpl # ---------------------------------------------------------------------------- parser.pool.class = org.apache.velocity.runtime.ParserPoolImpl parser.pool.size = 20 # ---------------------------------------------------------------------------- # EVENT HANDLER # ---------------------------------------------------------------------------- # Allows alternative event handlers to be plugged in. Note that each # class property is actually a comma-separated list of classes (which will # be called in order). # ---------------------------------------------------------------------------- # eventhandler.referenceinsertion.class = # eventhandler.nullset.class = # eventhandler.methodexception.class = # eventhandler.include.class = # ---------------------------------------------------------------------------- # EVALUATE # ---------------------------------------------------------------------------- # Evaluate VTL dynamically in template. Select a class for the Context, if # you want all #set calls within it to be locally scoped. This feature is # deprecated; please use $evaluate to hold local references instead. # ---------------------------------------------------------------------------- #directive.evaluate.context.class = org.apache.velocity.VelocityContext # ---------------------------------------------------------------------------- # PLUGGABLE INTROSPECTOR # ---------------------------------------------------------------------------- # Allows alternative introspection and all that can of worms brings. # ---------------------------------------------------------------------------- runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl # ---------------------------------------------------------------------------- # SECURE INTROSPECTOR # ---------------------------------------------------------------------------- # If selected, prohibits methods in certain classes and packages from being # accessed. # ---------------------------------------------------------------------------- introspector.restrict.packages = java.lang.reflect # The two most dangerous classes introspector.restrict.classes = java.lang.Class introspector.restrict.classes = java.lang.ClassLoader # Restrict these for extra safety introspector.restrict.classes = java.lang.Compiler introspector.restrict.classes = java.lang.InheritableThreadLocal introspector.restrict.classes = java.lang.Package introspector.restrict.classes = java.lang.Process introspector.restrict.classes = java.lang.Runtime introspector.restrict.classes = java.lang.RuntimePermission introspector.restrict.classes = java.lang.SecurityManager introspector.restrict.classes = java.lang.System introspector.restrict.classes = java.lang.Thread introspector.restrict.classes = java.lang.ThreadGroup introspector.restrict.classes = java.lang.ThreadLocal velocity-1.7/src/java/org/apache/velocity/runtime/VelocimacroFactory.java0000644000175000017500000005675311317225063026616 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.io.StringReader; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.ArrayList; import org.apache.commons.lang.StringUtils; import org.apache.velocity.Template; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.Macro; import org.apache.velocity.runtime.directive.VelocimacroProxy; import org.apache.velocity.runtime.log.LogDisplayWrapper; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.node.Node; /** * VelocimacroFactory.java * * manages the set of VMs in a running Velocity engine. * * @author Geir Magnusson Jr. * @version $Id: VelocimacroFactory.java 894953 2009-12-31 22:48:19Z nbubna $ */ public class VelocimacroFactory { /** * runtime services for this instance */ private final RuntimeServices rsvc; /** * the log for this instance */ private final LogDisplayWrapper log; /** * VMManager : deal with namespace management * and actually keeps all the VM definitions */ private VelocimacroManager vmManager = null; /** * determines if replacement of global VMs are allowed * controlled by VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL */ private boolean replaceAllowed = false; /** * controls if new VMs can be added. Set by * VM_PERM_ALLOW_INLINE Note the assumption that only * through inline defs can this happen. * additions through autoloaded VMs is allowed */ private boolean addNewAllowed = true; /** * sets if template-local namespace in used */ private boolean templateLocal = false; /** * determines if the libraries are auto-loaded * when they change */ private boolean autoReloadLibrary = false; /** * vector of the library names */ private List macroLibVec = null; /** * map of the library Template objects * used for reload determination */ private Map libModMap; /** * C'tor for the VelociMacro factory. * * @param rsvc Reference to a runtime services object. */ public VelocimacroFactory(final RuntimeServices rsvc) { this.rsvc = rsvc; this.log = new LogDisplayWrapper(rsvc.getLog(), "Velocimacro : ", rsvc.getBoolean(RuntimeConstants.VM_MESSAGES_ON, true)); /* * we always access in a synchronized(), so we * can use an unsynchronized hashmap */ libModMap = new HashMap(); vmManager = new VelocimacroManager(rsvc); } /** * initialize the factory - setup all permissions * load all global libraries. */ public void initVelocimacro() { /* * maybe I'm just paranoid... */ synchronized(this) { log.trace("initialization starting."); /* * allow replacements while we add the libraries, if exist */ setReplacementPermission(true); /* * add all library macros to the global namespace */ vmManager.setNamespaceUsage(false); /* * now, if there is a global or local libraries specified, use them. * All we have to do is get the template. The template will be parsed; * VM's are added during the parse phase */ Object libfiles = rsvc.getProperty(RuntimeConstants.VM_LIBRARY); if (libfiles == null) { log.debug("\"" + RuntimeConstants.VM_LIBRARY + "\" is not set. Trying default library: " + RuntimeConstants.VM_LIBRARY_DEFAULT); // try the default library. if (rsvc.getLoaderNameForResource(RuntimeConstants.VM_LIBRARY_DEFAULT) != null) { libfiles = RuntimeConstants.VM_LIBRARY_DEFAULT; } else { log.debug("Default library not found."); } } if(libfiles != null) { macroLibVec = new ArrayList(); if (libfiles instanceof Vector) { macroLibVec.addAll((Vector)libfiles); } else if (libfiles instanceof String) { macroLibVec.add(libfiles); } for(int i = 0, is = macroLibVec.size(); i < is; i++) { String lib = (String) macroLibVec.get(i); /* * only if it's a non-empty string do we bother */ if (StringUtils.isNotEmpty(lib)) { /* * let the VMManager know that the following is coming * from libraries - need to know for auto-load */ vmManager.setRegisterFromLib(true); log.debug("adding VMs from VM library : " + lib); try { Template template = rsvc.getTemplate(lib); /* * save the template. This depends on the assumption * that the Template object won't change - currently * this is how the Resource manager works */ Twonk twonk = new Twonk(); twonk.template = template; twonk.modificationTime = template.getLastModified(); libModMap.put(lib, twonk); } catch (Exception e) { String msg = "Velocimacro : Error using VM library : " + lib; log.error(true, msg, e); throw new VelocityException(msg, e); } log.trace("VM library registration complete."); vmManager.setRegisterFromLib(false); } } } /* * now, the permissions */ /* * allowinline : anything after this will be an inline macro, I think * there is the question if a #include is an inline, and I think so * * default = true */ setAddMacroPermission(true); if (!rsvc.getBoolean( RuntimeConstants.VM_PERM_ALLOW_INLINE, true)) { setAddMacroPermission(false); log.debug("allowInline = false : VMs can NOT be defined inline in templates"); } else { log.debug("allowInline = true : VMs can be defined inline in templates"); } /* * allowInlineToReplaceGlobal : allows an inline VM , if allowed at all, * to replace an existing global VM * * default = false */ setReplacementPermission(false); if (rsvc.getBoolean( RuntimeConstants.VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL, false)) { setReplacementPermission(true); log.debug("allowInlineToOverride = true : VMs " + "defined inline may replace previous VM definitions"); } else { log.debug("allowInlineToOverride = false : VMs " + "defined inline may NOT replace previous VM definitions"); } /* * now turn on namespace handling as far as permissions allow in the * manager, and also set it here for gating purposes */ vmManager.setNamespaceUsage(true); /* * template-local inline VM mode : default is off */ setTemplateLocalInline(rsvc.getBoolean( RuntimeConstants.VM_PERM_INLINE_LOCAL, false)); if (getTemplateLocalInline()) { log.debug("allowInlineLocal = true : VMs " + "defined inline will be local to their defining template only."); } else { log.debug("allowInlineLocal = false : VMs " + "defined inline will be global in scope if allowed."); } vmManager.setTemplateLocalInlineVM(getTemplateLocalInline()); /* * autoload VM libraries */ setAutoload(rsvc.getBoolean(RuntimeConstants.VM_LIBRARY_AUTORELOAD, false)); if (getAutoload()) { log.debug("autoload on : VM system " + "will automatically reload global library macros"); } else { log.debug("autoload off : VM system " + "will not automatically reload global library macros"); } log.trace("Velocimacro : initialization complete."); } } /** * Adds a macro to the factory. * * addVelocimacro(String, Node, String[] argArray, String) should be used internally * instead of this. * * @param name Name of the Macro to add. * @param macroBody String representation of the macro. * @param argArray Macro arguments. First element is the macro name. * @param sourceTemplate Source template from which the macro gets registered. * * @return true if Macro was registered successfully. */ public boolean addVelocimacro(String name, String macroBody, String argArray[], String sourceTemplate) { /* * maybe we should throw an exception, maybe just tell * the caller like this... * * I hate this : maybe exceptions are in order here... * They definitely would be if this was only called by directly * by users, but Velocity calls this internally. */ if (name == null || macroBody == null || argArray == null || sourceTemplate == null) { String msg = "VM '"+name+"' addition rejected : "; if (name == null) { msg += "name"; } else if (macroBody == null) { msg += "macroBody"; } else if (argArray == null) { msg += "argArray"; } else { msg += "sourceTemplate"; } msg += " argument was null"; log.error(msg); throw new NullPointerException(msg); } /* * see if the current ruleset allows this addition */ if (!canAddVelocimacro(name, sourceTemplate)) { return false; } synchronized (this) { try { Node macroRootNode = rsvc.parse(new StringReader(macroBody), sourceTemplate); vmManager.addVM(name, macroRootNode, argArray, sourceTemplate, replaceAllowed); } catch (ParseException ex) { // to keep things 1.3 compatible call toString() here throw new RuntimeException(ex.toString()); } } if (log.isDebugEnabled()) { StringBuffer msg = new StringBuffer("added "); Macro.macroToString(msg, argArray); msg.append(" : source = ").append(sourceTemplate); log.debug(msg.toString()); } return true; } /** * Adds a macro to the factory. * * @param name Name of the Macro to add. * @param macroBody root node of the parsed macro AST * @param argArray Name of the macro arguments. First element is the macro name. * @param sourceTemplate Source template from which the macro gets registered. * @return true if Macro was registered successfully. * @since 1.6 */ public boolean addVelocimacro(String name, Node macroBody, String argArray[], String sourceTemplate) { // Called by RuntimeInstance.addVelocimacro /* * maybe we should throw an exception, maybe just tell * the caller like this... * * I hate this : maybe exceptions are in order here... * They definitely would be if this was only called by directly * by users, but Velocity calls this internally. */ if (name == null || macroBody == null || argArray == null || sourceTemplate == null) { String msg = "VM '"+name+"' addition rejected : "; if (name == null) { msg += "name"; } else if (macroBody == null) { msg += "macroBody"; } else if (argArray == null) { msg += "argArray"; } else { msg += "sourceTemplate"; } msg += " argument was null"; log.error(msg); throw new NullPointerException(msg); } /* * see if the current ruleset allows this addition */ if (!canAddVelocimacro(name, sourceTemplate)) { return false; } synchronized(this) { vmManager.addVM(name, macroBody, argArray, sourceTemplate, replaceAllowed); } if (log.isDebugEnabled()) { log.debug("added VM "+name+": source="+sourceTemplate); } return true; } /** * determines if a given macro/namespace (name, source) combo is allowed * to be added * * @param name Name of VM to add * @param sourceTemplate Source template that contains the defintion of the VM * @return true if it is allowed to be added, false otherwise */ private synchronized boolean canAddVelocimacro(String name, String sourceTemplate) { /* * short circuit and do it if autoloader is on, and the * template is one of the library templates */ if (autoReloadLibrary && (macroLibVec != null)) { if( macroLibVec.contains(sourceTemplate) ) return true; } /* * maybe the rules should be in manager? I dunno. It's to manage * the namespace issues first, are we allowed to add VMs at all? * This trumps all. */ if (!addNewAllowed) { log.warn("VM addition rejected : "+name+" : inline VMs not allowed."); return false; } /* * are they local in scope? Then it is ok to add. */ if (!templateLocal) { /* * otherwise, if we have it already in global namespace, and they can't replace * since local templates are not allowed, the global namespace is implied. * remember, we don't know anything about namespace managment here, so lets * note do anything fancy like trying to give it the global namespace here * * so if we have it, and we aren't allowed to replace, bail */ if (!replaceAllowed && isVelocimacro(name, sourceTemplate)) { /* * Concurrency fix: the log entry was changed to debug scope because it * causes false alarms when several concurrent threads simultaneously (re)parse * some macro */ if (log.isDebugEnabled()) log.debug("VM addition rejected : "+name+" : inline not allowed to replace existing VM"); return false; } } return true; } /** * Tells the world if a given directive string is a Velocimacro * @param vm Name of the Macro. * @param sourceTemplate Source template from which the macro should be loaded. * @return True if the given name is a macro. */ public boolean isVelocimacro(String vm, String sourceTemplate) { // synchronization removed return(vmManager.get(vm, sourceTemplate) != null); } /** * actual factory : creates a Directive that will * behave correctly wrt getting the framework to * dig out the correct # of args * @param vmName Name of the Macro. * @param sourceTemplate Source template from which the macro should be loaded. * @return A directive representing the Macro. */ public Directive getVelocimacro(String vmName, String sourceTemplate) { return(getVelocimacro(vmName, sourceTemplate, null)); } /** * @since 1.6 */ public Directive getVelocimacro(String vmName, String sourceTemplate, String renderingTemplate) { VelocimacroProxy vp = null; vp = vmManager.get(vmName, sourceTemplate, renderingTemplate); /* * if this exists, and autoload is on, we need to check where this VM came from */ if (vp != null && autoReloadLibrary ) { synchronized (this) { /* * see if this VM came from a library. Need to pass sourceTemplate in the event * namespaces are set, as it could be masked by local */ String lib = vmManager.getLibraryName(vmName, sourceTemplate); if (lib != null) { try { /* * get the template from our map */ Twonk tw = (Twonk) libModMap.get(lib); if (tw != null) { Template template = tw.template; /* * now, compare the last modified time of the resource with the last * modified time of the template if the file has changed, then reload. * Otherwise, we should be ok. */ long tt = tw.modificationTime; long ft = template.getResourceLoader().getLastModified(template); if (ft > tt) { log.debug("auto-reloading VMs from VM library : " + lib); /* * when there are VMs in a library that invoke each other, there are * calls into getVelocimacro() from the init() process of the VM * directive. To stop the infinite loop we save the current time * reported by the resource loader and then be honest when the * reload is complete */ tw.modificationTime = ft; template = rsvc.getTemplate(lib); /* * and now we be honest */ tw.template = template; tw.modificationTime = template.getLastModified(); /* * note that we don't need to put this twonk * back into the map, as we can just use the * same reference and this block is synchronized */ } } } catch (Exception e) { String msg = "Velocimacro : Error using VM library : " + lib; log.error(true, msg, e); throw new VelocityException(msg, e); } vp = vmManager.get(vmName, sourceTemplate, renderingTemplate); } } } return vp; } /** * tells the vmManager to dump the specified namespace * * @param namespace Namespace to dump. * @return True if namespace has been dumped successfully. */ public boolean dumpVMNamespace(String namespace) { return vmManager.dumpNamespace(namespace); } /** * sets permission to have VMs local in scope to their declaring template note that this is * really taken care of in the VMManager class, but we need it here for gating purposes in addVM * eventually, I will slide this all into the manager, maybe. */ private void setTemplateLocalInline(boolean b) { templateLocal = b; } private boolean getTemplateLocalInline() { return templateLocal; } /** * sets the permission to add new macros */ private boolean setAddMacroPermission(final boolean addNewAllowed) { boolean b = this.addNewAllowed; this.addNewAllowed = addNewAllowed; return b; } /** * sets the permission for allowing addMacro() calls to replace existing VM's */ private boolean setReplacementPermission(boolean arg) { boolean b = replaceAllowed; replaceAllowed = arg; vmManager.setInlineReplacesGlobal(arg); return b; } /** * set the switch for automatic reloading of * global library-based VMs */ private void setAutoload(boolean b) { autoReloadLibrary = b; } /** * get the switch for automatic reloading of * global library-based VMs */ private boolean getAutoload() { return autoReloadLibrary; } /** * small container class to hold the tuple * of a template and modification time. * We keep the modification time so we can * 'override' it on a reload to prevent * recursive reload due to inter-calling * VMs in a library */ private static class Twonk { /** Template kept in this container. */ public Template template; /** modification time of the template. */ public long modificationTime; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/0000755000175000017500000000000011675166252024131 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/runtime/directive/ForeachScope.java0000755000175000017500000000347611374606332027344 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ /** * This represents scoping and metadata for #foreach, * adding index, count, hasNext, isFirst and isLast info. * * @author Nathan Bubna * @version $Id$ */ public class ForeachScope extends Scope { protected int index = -1; protected boolean hasNext = false; public ForeachScope(Object owner, Object replaces) { super(owner, replaces); } public int getIndex() { return index; } public int getCount() { return index + 1; } public boolean hasNext() { return getHasNext(); } public boolean getHasNext() { return hasNext; } public boolean isFirst() { return index < 1; } public boolean getFirst() { return isFirst(); } public boolean isLast() { return !hasNext; } public boolean getLast() { return isLast(); } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Macro.java0000644000175000017500000001750311147712004026025 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.runtime.parser.Token; import org.apache.velocity.runtime.parser.node.Node; /** * Macro implements the macro definition directive of VTL. * * example : * * #macro( isnull $i ) * #if( $i ) * $i * #end * #end * * This object is used at parse time to mainly process and register the * macro. It is used inline in the parser when processing a directive. * * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: Macro.java 746438 2009-02-21 05:41:24Z nbubna $ */ public class Macro extends Directive { private static boolean debugMode = false; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "macro"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return BLOCK; } /** * Since this class does no processing of content, * there is never a need for an internal scope. */ public boolean isScopeProvided() { return false; } /** * render() doesn't do anything in the final output rendering. * There is no output from a #macro() directive. * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException { /* * do nothing : We never render. The VelocimacroProxy object does that */ return true; } /** * @see org.apache.velocity.runtime.directive.Directive#init(org.apache.velocity.runtime.RuntimeServices, org.apache.velocity.context.InternalContextAdapter, org.apache.velocity.runtime.parser.node.Node) */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); // Add this macro to the VelocimacroManager now that it has been initialized. String argArray[] = getArgArray(node, rs); int numArgs = node.jjtGetNumChildren(); rs.addVelocimacro(argArray[0], node.jjtGetChild(numArgs - 1), argArray, node.getTemplateName()); } /** * Used by Parser.java to do further parameter checking for macro arguments. */ public static void checkArgs(RuntimeServices rs, Token t, Node node, String sourceTemplate) throws IOException, ParseException { /* * There must be at least one arg to #macro, * the name of the VM. Note that 0 following * args is ok for naming blocks of HTML */ int numArgs = node.jjtGetNumChildren(); /* * this number is the # of args + 1. The + 1 * is for the block tree */ if (numArgs < 2) { /* * error - they didn't name the macro or * define a block */ rs.getLog().error("#macro error : Velocimacro must have name as 1st " + "argument to #macro(). #args = " + numArgs); throw new MacroParseException("First argument to #macro() must be " + " macro name", sourceTemplate, t); } /* * lets make sure that the first arg is an ASTWord */ int firstType = node.jjtGetChild(0).getType(); if(firstType != ParserTreeConstants.JJTWORD) { throw new MacroParseException("First argument to #macro() must be a" + " token without surrounding \' or \", which specifies" + " the macro name. Currently it is a " + ParserTreeConstants.jjtNodeName[firstType], sourceTemplate, t); } } /** * Creates an array containing the literal text from the macro * arguement(s) (including the macro's name as the first arg). * * @param node The parse node from which to grok the argument * list. It's expected to include the block node tree (for the * macro body). * @param rsvc For debugging purposes only. * @return array of arguments */ private static String[] getArgArray(Node node, RuntimeServices rsvc) { /* * Get the number of arguments for the macro, excluding the * last child node which is the block tree containing the * macro body. */ int numArgs = node.jjtGetNumChildren(); numArgs--; // avoid the block tree... String argArray[] = new String[numArgs]; int i = 0; /* * eat the args */ while (i < numArgs) { argArray[i] = node.jjtGetChild(i).getFirstToken().image; /* * trim off the leading $ for the args after the macro name. * saves everyone else from having to do it */ if (i > 0) { if (argArray[i].startsWith("$")) { argArray[i] = argArray[i] .substring(1, argArray[i].length()); } } argArray[i] = argArray[i].intern(); i++; } if (debugMode) { StringBuffer msg = new StringBuffer("Macro.getArgArray() : nbrArgs="); msg.append(numArgs).append(" : "); macroToString(msg, argArray); rsvc.getLog().debug(msg); } return argArray; } /** * For debugging purposes. Formats the arguments from * argArray and appends them to buf. * * @param buf A StringBuffer. If null, a new StringBuffer is allocated. * @param argArray The Macro arguments to format * * @return A StringBuffer containing the formatted arguments. If a StringBuffer * has passed in as buf, this method returns it. * @since 1.5 */ public static final StringBuffer macroToString(final StringBuffer buf, final String[] argArray) { StringBuffer ret = (buf == null) ? new StringBuffer() : buf; ret.append('#').append(argArray[0]).append("( "); for (int i = 1; i < argArray.length; i++) { ret.append(' ').append(argArray[i]); } ret.append(" )"); return ret; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/VelocimacroProxy.java0000644000175000017500000002536111322700447030275 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.context.ProxyVMContext; import org.apache.velocity.exception.MacroOverflowException; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; /** * VelocimacroProxy.java * * a proxy Directive-derived object to fit with the current directive system * * @author Geir Magnusson Jr. * @version $Id: VelocimacroProxy.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class VelocimacroProxy extends Directive { private String macroName; private String[] argArray = null; private String[] literalArgArray = null; private SimpleNode nodeTree = null; private int numMacroArgs = 0; private boolean strictArguments; private boolean localContextScope = false; private int maxCallDepth; private String bodyReference; /** * Return name of this Velocimacro. * @return The name of this Velocimacro. */ public String getName() { return macroName; } /** * Velocimacros are always LINE type directives. * @return The type of this directive. */ public int getType() { return LINE; } /** * sets the directive name of this VM * * @param name */ public void setName(String name) { macroName = name; } /** * sets the array of arguments specified in the macro definition * * @param arr */ public void setArgArray(String[] arr) { argArray = arr; // for performance reasons we precache these strings - they are needed in // "render literal if null" functionality literalArgArray = new String[arr.length]; for(int i = 0; i < arr.length; i++) { literalArgArray[i] = ".literal.$" + argArray[i]; } /* * get the arg count from the arg array. remember that the arg array has the macro name as * it's 0th element */ numMacroArgs = argArray.length - 1; } /** * @param tree */ public void setNodeTree(SimpleNode tree) { nodeTree = tree; } /** * returns the number of ars needed for this VM * * @return The number of ars needed for this VM */ public int getNumArgs() { return numMacroArgs; } public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, MethodInvocationException, MacroOverflowException { return render(context, writer, node, null); } /** * Renders the macro using the context. * * @param context Current rendering context * @param writer Writer for output * @param node AST that calls the macro * @return True if the directive rendered successfully. * @throws IOException * @throws MethodInvocationException * @throws MacroOverflowException */ public boolean render(InternalContextAdapter context, Writer writer, Node node, Renderable body) throws IOException, MethodInvocationException, MacroOverflowException { // wrap the current context and add the macro arguments // the creation of this context is a major bottleneck (incl 2x HashMap) final ProxyVMContext vmc = new ProxyVMContext(context, rsvc, localContextScope); int callArguments = node.jjtGetNumChildren(); if (callArguments > 0) { // the 0th element is the macro name for (int i = 1; i < argArray.length && i <= callArguments; i++) { /* * literalArgArray[i] is needed for "render literal if null" functionality. * The value is used in ASTReference render-method. * * The idea is to avoid generating the literal until absolutely necessary. * * This makes VMReferenceMungeVisitor obsolete and it would not work anyway * when the macro AST is shared */ vmc.addVMProxyArg(context, argArray[i], literalArgArray[i], node.jjtGetChild(i - 1)); } } // if this macro was invoked by a call directive, we might have a body AST here. Put it into context. if( body != null ) { vmc.addVMProxyArg(context, bodyReference, "", body); } /* * check that we aren't already at the max call depth */ if (maxCallDepth > 0 && maxCallDepth == vmc.getCurrentMacroCallDepth()) { Object[] stack = vmc.getMacroNameStack(); StringBuffer out = new StringBuffer(100) .append("Max calling depth of ").append(maxCallDepth) .append(" was exceeded in macro '").append(macroName) .append("' with Call Stack:"); for (int i = 0; i < stack.length; i++) { if (i != 0) { out.append("->"); } out.append(stack[i]); } out.append(" at " + Log.formatFileString(this)); rsvc.getLog().error(out.toString()); // clean out the macro stack, since we just broke it while (vmc.getCurrentMacroCallDepth() > 0) { vmc.popCurrentMacroName(); } throw new MacroOverflowException(out.toString()); } try { // render the velocity macro vmc.pushCurrentMacroName(macroName); nodeTree.render(vmc, writer); vmc.popCurrentMacroName(); return true; } catch (RuntimeException e) { throw e; } catch (Exception e) { String msg = "VelocimacroProxy.render() : exception VM = #" + macroName + "()"; rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } } /** * Initialize members of VelocimacroProxy. called from MacroEntry */ public void init(RuntimeServices rs) { rsvc = rs; // this is a very expensive call (ExtendedProperties is very slow) strictArguments = rs.getConfiguration().getBoolean( RuntimeConstants.VM_ARGUMENTS_STRICT, false); // support for local context scope feature, where all references are local // we do not have to check this at every invocation of ProxyVMContext localContextScope = rsvc.getBoolean(RuntimeConstants.VM_CONTEXT_LOCALSCOPE, false); if (localContextScope && rsvc.getLog().isWarnEnabled()) { // only warn once per runtime, so this isn't obnoxious String key = "velocimacro.context.localscope.warning"; Boolean alreadyWarned = (Boolean)rsvc.getApplicationAttribute(key); if (alreadyWarned == null) { rsvc.setApplicationAttribute(key, Boolean.TRUE); rsvc.getLog() .warn("The "+RuntimeConstants.VM_CONTEXT_LOCALSCOPE+ " feature is deprecated and will be removed in Velocity 2.0."+ " Instead, please use the $macro scope to store references"+ " that must be local to your macros (e.g. "+ "#set( $macro.foo = 'bar' ) and $macro.foo). This $macro"+ " namespace is automatically created and destroyed for you at"+ " the beginning and end of the macro rendering."); } } // get the macro call depth limit maxCallDepth = rsvc.getInt(RuntimeConstants.VM_MAX_DEPTH); // get name of the reference that refers to AST block passed to block macro call bodyReference = rsvc.getString(RuntimeConstants.VM_BODY_REFERENCE, "bodyContent"); } /** * Build an error message for not providing the correct number of arguments */ private String buildErrorMsg(Node node, int numArgsProvided) { String msg = "VM #" + macroName + ": too " + ((getNumArgs() > numArgsProvided) ? "few" : "many") + " arguments to macro. Wanted " + getNumArgs() + " got " + numArgsProvided; return msg; } /** * check if we are calling this macro with the right number of arguments. If * we are not, and strictArguments is active, then throw TemplateInitException. * This method is called during macro render, so it must be thread safe. */ public void checkArgs(InternalContextAdapter context, Node node, boolean hasBody) { // check how many arguments we have int i = node.jjtGetNumChildren(); // if macro call has a body (BlockMacro) then don't count the body as an argument if( hasBody ) i--; // Throw exception for invalid number of arguments? if (getNumArgs() != i) { if (strictArguments) { /** * indicate col/line assuming it starts at 0 - this will be corrected one call up */ throw new TemplateInitException(buildErrorMsg(node, i), context.getCurrentTemplateName(), 0, 0); } else if (rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug(buildErrorMsg(node, i)); return; } } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java0000644000175000017500000002724511147712004027375 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import java.util.List; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.runtime.parser.Token; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.util.introspection.Info; /** * This class acts as a proxy for potential macros. When the AST is built * this class is inserted as a placeholder for the macro (whether or not * the macro is actually defined). At render time we check whether there is * a implementation for the macro call. If an implementation cannot be * found the literal text is rendered. * @since 1.6 */ public class RuntimeMacro extends Directive { /** * Name of the macro */ private String macroName; /** * Literal text of the macro */ private String literal = null; /** * Node of the macro call */ private Node node = null; /** * Indicates if we are running in strict reference mode. */ protected boolean strictRef = false; /** * badArgsErrorMsg will be non null if the arguments to this macro * are deamed bad at init time, see the init method. If his is non null, then this macro * cannot be rendered, and if there is an attempt to render we throw an exception * with this as the message. */ private String badArgsErrorMsg = null; /** * Create a RuntimeMacro instance. Macro name and source * template stored for later use. * * @param macroName name of the macro */ public RuntimeMacro(String macroName) { if (macroName == null) { throw new IllegalArgumentException("Null arguments"); } this.macroName = macroName.intern(); } /** * Return name of this Velocimacro. * * @return The name of this Velocimacro. */ public String getName() { return macroName; } /** * Override to always return "macro". We don't want to use * the macro name here, since when writing VTL that uses the * scope, we are within a #macro call. The macro name will instead * be used as the scope name when defining the body of a BlockMacro. */ public String getScopeName() { return "macro"; } /** * Velocimacros are always LINE * type directives. * * @return The type of this directive. */ public int getType() { return LINE; } /** * Intialize the Runtime macro. At the init time no implementation so we * just save the values to use at the render time. * * @param rs runtime services * @param context InternalContextAdapter * @param node node containing the macro call */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) { super.init(rs, context, node); rsvc = rs; this.node = node; /** * Apply strictRef setting only if this really looks like a macro, * so strict mode doesn't balk at things like #E0E0E0 in a template. * compare with ")" is a simple #foo() style macro, comparing to * "#end" is a block style macro. We use starts with because the token * may end with '\n' */ Token t = node.getLastToken(); if (t.image.startsWith(")") || t.image.startsWith("#end")) { strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false); } // Validate that none of the arguments are plain words, (VELOCITY-614) // they should be string literals, references, inline maps, or inline lists for (int n=0; n < node.jjtGetNumChildren(); n++) { Node child = node.jjtGetChild(n); if (child.getType() == ParserTreeConstants.JJTWORD) { badArgsErrorMsg = "Invalid arg '" + child.getFirstToken().image + "' in macro #" + macroName + " at " + Log.formatFileString(child); if (strictRef) // If strict, throw now { /* indicate col/line assuming it starts at 0 * this will be corrected one call up */ throw new TemplateInitException(badArgsErrorMsg, context.getCurrentTemplateName(), 0, 0); } } } } /** * It is probably quite rare that we need to render the macro literal * so do it only on-demand and then cache the value. This tactic helps to * reduce memory usage a bit. */ private String getLiteral() { if (literal == null) { StrBuilder buffer = new StrBuilder(); Token t = node.getFirstToken(); while (t != null && t != node.getLastToken()) { buffer.append(t.image); t = t.next; } if (t != null) { buffer.append(t.image); } literal = buffer.toString(); } return literal; } /** * Velocimacro implementation is not known at the init time. So look for * a implementation in the macro libaries and if finds one renders it. The * actual rendering is delegated to the VelocimacroProxy object. When * looking for a macro we first loot at the template with has the * macro call then we look at the macro lbraries in the order they appear * in the list. If a macro has many definitions above look up will * determine the precedence. * * @param context * @param writer * @param node * @return true if the rendering is successful * @throws IOException * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { return render(context, writer, node, null); } /** * This method is used with BlockMacro when we want to render a macro with a body AST. * * @param context * @param writer * @param node * @param body AST block that was enclosed in the macro body. * @return true if the rendering is successful * @throws IOException * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException */ public boolean render(InternalContextAdapter context, Writer writer, Node node, Renderable body) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { VelocimacroProxy vmProxy = null; String renderingTemplate = context.getCurrentTemplateName(); /** * first look in the source template */ Object o = rsvc.getVelocimacro(macroName, getTemplateName(), renderingTemplate); if( o != null ) { // getVelocimacro can only return a VelocimacroProxy so we don't need the // costly instanceof check vmProxy = (VelocimacroProxy)o; } /** * if not found, look in the macro libraries. */ if (vmProxy == null) { List macroLibraries = context.getMacroLibraries(); if (macroLibraries != null) { for (int i = macroLibraries.size() - 1; i >= 0; i--) { o = rsvc.getVelocimacro(macroName, (String)macroLibraries.get(i), renderingTemplate); // get the first matching macro if (o != null) { vmProxy = (VelocimacroProxy) o; break; } } } } if (vmProxy != null) { try { // mainly check the number of arguments vmProxy.checkArgs(context, node, body != null); } catch (TemplateInitException die) { throw new ParseErrorException(die.getMessage() + " at " + Log.formatFileString(node), new Info(node)); } if (badArgsErrorMsg != null) { throw new TemplateInitException(badArgsErrorMsg, context.getCurrentTemplateName(), node.getColumn(), node.getLine()); } try { preRender(context); return vmProxy.render(context, writer, node, body); } catch (StopCommand stop) { if (!stop.isFor(this)) { throw stop; } return true; } catch (RuntimeException e) { /** * We catch, the exception here so that we can record in * the logs the template and line number of the macro call * which generate the exception. This information is * especially important for multiple macro call levels. * this is also true for the following catch blocks. */ rsvc.getLog().error("Exception in macro #" + macroName + " called at " + Log.formatFileString(node)); throw e; } catch (IOException e) { rsvc.getLog().error("Exception in macro #" + macroName + " called at " + Log.formatFileString(node)); throw e; } finally { postRender(context); } } else if (strictRef) { throw new VelocityException("Macro '#" + macroName + "' is not defined at " + Log.formatFileString(node)); } /** * If we cannot find an implementation write the literal text */ writer.write(getLiteral()); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Evaluate.java0000644000175000017500000001701311322700447026531 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.StringReader; import java.io.Writer; import org.apache.velocity.context.EvaluateContext; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.util.introspection.Info; /** * Evaluates the directive argument as a VTL string, using the existing * context. * * @author Will Glass-Husain * @version $Id: Evaluate.java 898032 2010-01-11 19:51:03Z nbubna $ * @since 1.6 */ public class Evaluate extends Directive { /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "evaluate"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return LINE; } /** * Initialize and check arguments. * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init( rs, context, node ); /** * Check that there is exactly one argument and it is a string or reference. */ int argCount = node.jjtGetNumChildren(); if (argCount == 0) { throw new TemplateInitException( "#" + getName() + "() requires exactly one argument", context.getCurrentTemplateName(), node.getColumn(), node.getLine()); } if (argCount > 1) { /* * use line/col of second argument */ throw new TemplateInitException( "#" + getName() + "() requires exactly one argument", context.getCurrentTemplateName(), node.jjtGetChild(1).getColumn(), node.jjtGetChild(1).getLine()); } Node childNode = node.jjtGetChild(0); if ( childNode.getType() != ParserTreeConstants.JJTSTRINGLITERAL && childNode.getType() != ParserTreeConstants.JJTREFERENCE ) { throw new TemplateInitException( "#" + getName() + "() argument must be a string literal or reference", context.getCurrentTemplateName(), childNode.getColumn(), childNode.getLine()); } } /** * Evaluate the argument, convert to a String, and evaluate again * (with the same context). * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { /* * Evaluate the string with the current context. We know there is * exactly one argument and it is a string or reference. */ Object value = node.jjtGetChild(0).value( context ); String sourceText; if ( value != null ) { sourceText = value.toString(); } else { sourceText = ""; } /* * The new string needs to be parsed since the text has been dynamically generated. */ String templateName = context.getCurrentTemplateName(); SimpleNode nodeTree = null; try { nodeTree = rsvc.parse(new StringReader(sourceText), templateName, false); } catch (ParseException pex) { // use the line/column from the template Info info = new Info( templateName, node.getLine(), node.getColumn() ); throw new ParseErrorException( pex.getMessage(), info ); } catch (TemplateInitException pex) { Info info = new Info( templateName, node.getLine(), node.getColumn() ); throw new ParseErrorException( pex.getMessage(), info ); } /* * now we want to init and render. Chain the context * to prevent any changes to the current context. */ if (nodeTree != null) { InternalContextAdapter ica = new EvaluateContext(context, rsvc); ica.pushCurrentTemplateName( templateName ); try { try { nodeTree.init( ica, rsvc ); } catch (TemplateInitException pex) { Info info = new Info( templateName, node.getLine(), node.getColumn() ); throw new ParseErrorException( pex.getMessage(), info ); } try { preRender(ica); /* * now render, and let any exceptions fly */ nodeTree.render( ica, writer ); } catch (StopCommand stop) { if (!stop.isFor(this)) { throw stop; } else if (rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug(stop.getMessage()); } } catch (ParseErrorException pex) { // convert any parsing errors to the correct line/col Info info = new Info( templateName, node.getLine(), node.getColumn() ); throw new ParseErrorException( pex.getMessage(), info ); } } finally { ica.popCurrentTemplateName(); postRender(ica); } return true; } return false; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Foreach.java0000644000175000017500000003727311374611365026353 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import java.util.Iterator; import org.apache.velocity.context.ChainedInternalContextAdapter; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.util.introspection.Info; /** * Foreach directive used for moving through arrays, * or objects that provide an Iterator. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Daniel Rall * @version $Id: Foreach.java 945927 2010-05-18 22:21:41Z nbubna $ */ public class Foreach extends Directive { /** * A special context to use when the foreach iterator returns a null. This * is required since the standard context may not support nulls. * All puts and gets are passed through, except for the foreach iterator key. * @since 1.5 */ protected static class NullHolderContext extends ChainedInternalContextAdapter { private String loopVariableKey = ""; private boolean active = true; /** * Create the context as a wrapper to be used within the foreach * @param key the reference used in the foreach * @param context the parent context */ private NullHolderContext( String key, InternalContextAdapter context ) { super(context); if( key != null ) loopVariableKey = key; } /** * Get an object from the context, or null if the key is equal to the loop variable * @see org.apache.velocity.context.InternalContextAdapter#get(java.lang.String) * @exception MethodInvocationException passes on potential exception from reference method call */ public Object get( String key ) throws MethodInvocationException { return ( active && loopVariableKey.equals(key) ) ? null : super.get(key); } /** * @see org.apache.velocity.context.InternalContextAdapter#put(java.lang.String key, java.lang.Object value) */ public Object put( String key, Object value ) { if( loopVariableKey.equals(key) && (value == null) ) { active = true; } return super.put( key, value ); } /** * Allows callers to explicitly put objects in the local context. * Objects added to the context through this method always end up * in the top-level context of possible wrapped contexts. * * @param key name of item to set. * @param value object to set to key. * @see org.apache.velocity.context.InternalWrapperContext#localPut(String, Object) */ public Object localPut(final String key, final Object value) { return put(key, value); } /** * Remove an object from the context * @see org.apache.velocity.context.InternalContextAdapter#remove(java.lang.Object key) */ public Object remove(Object key) { if( loopVariableKey.equals(key) ) { active = false; } return super.remove(key); } } /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "foreach"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return BLOCK; } /** * The name of the variable to use when placing * the counter value into the context. Right * now the default is $velocityCount. */ private String counterName; /** * The name of the variable to use when placing * iterator hasNext() value into the context.Right * now the defailt is $velocityHasNext */ private String hasNextName; /** * What value to start the loop counter at. */ private int counterInitialValue; /** * The maximum number of times we're allowed to loop. */ private int maxNbrLoops; /** * Whether or not to throw an Exception if the iterator is null. */ private boolean skipInvalidIterator; /** * The reference name used to access each * of the elements in the list object. It * is the $item in the following: * * #foreach ($item in $list) * * This can be used class wide because * it is immutable. */ private String elementKey; // track if we've done the deprecation warning thing already private boolean warned = false; /** * immutable, so create in init */ protected Info uberInfo; /** * simple init - init the tree and get the elementKey from * the AST * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); // handle deprecated config settings counterName = rsvc.getString(RuntimeConstants.COUNTER_NAME); hasNextName = rsvc.getString(RuntimeConstants.HAS_NEXT_NAME); counterInitialValue = rsvc.getInt(RuntimeConstants.COUNTER_INITIAL_VALUE); // only warn once per instance... if (!warned && rsvc.getLog().isWarnEnabled()) { warned = true; // ...and only if they customize these settings if (!"velocityCount".equals(counterName)) { rsvc.getLog().warn("The "+RuntimeConstants.COUNTER_NAME+ " property has been deprecated. It will be removed"+ " (along with $velocityCount itself) in Velocity 2.0. "+ " Instead, please use $foreach.count to access"+ " the loop counter."); } if (!"velocityHasNext".equals(hasNextName)) { rsvc.getLog().warn("The "+RuntimeConstants.HAS_NEXT_NAME+ " property has been deprecated. It will be removed"+ " (along with $velocityHasNext itself ) in Velocity 2.0. "+ " Instead, please use $foreach.hasNext to access"+ " this value from now on."); } if (counterInitialValue != 1) { rsvc.getLog().warn("The "+RuntimeConstants.COUNTER_INITIAL_VALUE+ " property has been deprecated. It will be removed"+ " (along with $velocityCount itself) in Velocity 2.0. "+ " Instead, please use $foreach.index to access"+ " the 0-based loop index and $foreach.count"+ " to access the 1-based loop counter."); } } maxNbrLoops = rsvc.getInt(RuntimeConstants.MAX_NUMBER_LOOPS, Integer.MAX_VALUE); if (maxNbrLoops < 1) { maxNbrLoops = Integer.MAX_VALUE; } skipInvalidIterator = rsvc.getBoolean(RuntimeConstants.SKIP_INVALID_ITERATOR, true); if (rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false)) { // If we are in strict mode then the default for skipInvalidItarator // is true. However, if the property is explicitly set, then honor the setting. skipInvalidIterator = rsvc.getBoolean(RuntimeConstants.SKIP_INVALID_ITERATOR, false); } /* * this is really the only thing we can do here as everything * else is context sensitive */ SimpleNode sn = (SimpleNode) node.jjtGetChild(0); if (sn instanceof ASTReference) { elementKey = ((ASTReference) sn).getRootString(); } else { /* * the default, error-prone way which we'll remove * TODO : remove if all goes well */ elementKey = sn.getFirstToken().image.substring(1); } /* * make an uberinfo - saves new's later on */ uberInfo = new Info(this.getTemplateName(), getLine(),getColumn()); } /** * Extension hook to allow subclasses to control whether loop vars * are set locally or not. So, those in favor of VELOCITY-285, can * make that happen easily by overriding this and having it use * context.localPut(k,v). See VELOCITY-630 for more on this. */ protected void put(InternalContextAdapter context, String key, Object value) { context.put(key, value); } /** * renders the #foreach() block * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException * @throws MethodInvocationException * @throws ResourceNotFoundException * @throws ParseErrorException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, MethodInvocationException, ResourceNotFoundException, ParseErrorException { /* * do our introspection to see what our collection is */ Object listObject = node.jjtGetChild(2).value(context); if (listObject == null) return false; Iterator i = null; try { i = rsvc.getUberspect().getIterator(listObject, uberInfo); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception ee) { String msg = "Error getting iterator for #foreach at "+uberInfo; rsvc.getLog().error(msg, ee); throw new VelocityException(msg, ee); } if (i == null) { if (skipInvalidIterator) { return false; } else { Node pnode = node.jjtGetChild(2); String msg = "#foreach parameter " + pnode.literal() + " at " + Log.formatFileString(pnode) + " is of type " + listObject.getClass().getName() + " and is either of wrong type or cannot be iterated."; rsvc.getLog().error(msg); throw new VelocityException(msg); } } int counter = counterInitialValue; boolean maxNbrLoopsExceeded = false; /* * save the element key if there is one, and the loop counter */ Object o = context.get(elementKey); Object savedCounter = context.get(counterName); Object nextFlag = context.get(hasNextName); /* * roll our own scope class instead of using preRender(ctx)'s */ ForeachScope foreach = null; if (isScopeProvided()) { String name = getScopeName(); foreach = new ForeachScope(this, context.get(name)); context.put(name, foreach); } /* * Instantiate the null holder context if a null value * is returned by the foreach iterator. Only one instance is * created - it's reused for every null value. */ NullHolderContext nullHolderContext = null; while (!maxNbrLoopsExceeded && i.hasNext()) { // TODO: JDK 1.5+ -> Integer.valueOf() put(context, counterName , new Integer(counter)); Object value = i.next(); put(context, hasNextName, Boolean.valueOf(i.hasNext())); put(context, elementKey, value); if (isScopeProvided()) { // update the scope control foreach.index++; foreach.hasNext = i.hasNext(); } try { /* * If the value is null, use the special null holder context */ if (value == null) { if (nullHolderContext == null) { // lazy instantiation nullHolderContext = new NullHolderContext(elementKey, context); } node.jjtGetChild(3).render(nullHolderContext, writer); } else { node.jjtGetChild(3).render(context, writer); } } catch (StopCommand stop) { if (stop.isFor(this)) { break; } else { // clean up first clean(context, o, savedCounter, nextFlag); throw stop; } } counter++; // Determine whether we're allowed to continue looping. // ASSUMPTION: counterInitialValue is not negative! maxNbrLoopsExceeded = (counter - counterInitialValue) >= maxNbrLoops; } clean(context, o, savedCounter, nextFlag); return true; } protected void clean(InternalContextAdapter context, Object o, Object savedCounter, Object nextFlag) { /* * restores element key if exists * otherwise just removes */ if (o != null) { context.put(elementKey, o); } else { context.remove(elementKey); } /* * restores the loop counter (if we were nested) * if we have one, else just removes */ if (savedCounter != null) { context.put(counterName, savedCounter); } else { context.remove(counterName); } /* * restores the "hasNext" boolean flag if it exists */ if (nextFlag != null) { context.put(hasNextName, nextFlag); } else { context.remove(hasNextName); } // clean up after the ForeachScope postRender(context); } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Scope.java0000755000175000017500000001622111440022314026026 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.util.AbstractMap; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.velocity.Template; /** * This handles context scoping and metadata for directives. * * @author Nathan Bubna * @version $Id$ */ public class Scope extends AbstractMap { private Map storage; private Object replaced; private Scope parent; private Info info; protected final Object owner; public Scope(Object owner, Object previous) { this.owner = owner; if (previous != null) { try { this.parent = (Scope)previous; } catch (ClassCastException cce) { this.replaced = previous; } } } private Map getStorage() { if (storage == null) { storage = new HashMap(); } return storage; } public Set entrySet() { return getStorage().entrySet(); } public Object get(Object key) { Object o = super.get(key); if (o == null && parent != null && !containsKey(key)) { return parent.get(key); } return o; } public Object put(Object key, Object value) { return getStorage().put(key, value); } /** * Allows #stop to easily trigger the proper StopCommand for this scope. */ protected void stop() { throw new StopCommand(owner); } /** * Returns the number of control arguments of this type * that are stacked up. This is the distance between this * instance and the topmost instance, plus one. This value * will never be negative or zero. */ protected int getDepth() { if (parent == null) { return 1; } return parent.getDepth() + 1; } /** * Returns the topmost parent control reference, retrieved * by simple recursion on {@link #getParent}. */ public Scope getTopmost() { if (parent == null) { return this; } return parent.getTopmost(); } /** * Returns the parent control reference overridden by the placement * of this instance in the context. */ public Scope getParent() { return parent; } /** * Returns the user's context reference overridden by the placement * of this instance in the context. If there was none (as is hoped), * then this will return null. This never returns parent controls; * those are returned by {@link #getParent}. */ public Object getReplaced() { if (replaced == null && parent != null) { return parent.getReplaced(); } return replaced; } /** * Returns info about the current scope for debugging purposes. */ public Info getInfo() { if (info == null) { info = new Info(this, owner); } return info; } /** * Class to encapsulate and provide access to info about * the current scope for debugging. */ public static class Info { private Scope scope; private Directive directive; private Template template; public Info(Scope scope, Object owner) { if (owner instanceof Directive) { directive = (Directive)owner; } if (owner instanceof Template) { template = (Template)owner; } this.scope = scope; } public String getName() { if (directive != null) { return directive.getName(); } if (template != null) { return template.getName(); } return null; } public String getType() { if (directive != null) { switch (directive.getType()) { case Directive.BLOCK: return "block"; case Directive.LINE: return "line"; } } if (template != null) { return template.getEncoding(); } return null; } public int getDepth() { return scope.getDepth(); } public String getTemplate() { if (directive != null) { return directive.getTemplateName(); } if (template != null) { return template.getName(); } return null; } public int getLine() { if (directive != null) { return directive.getLine(); } return 0; } public int getColumn() { if (directive != null) { return directive.getColumn(); } return 0; } public String toString() { StringBuffer sb = new StringBuffer(); if (directive != null) { sb.append('#'); } sb.append(getName()); sb.append("[type:").append(getType()); int depth = getDepth(); if (depth > 1) { sb.append(" depth:").append(depth); } if (template == null) { String vtl = getTemplate(); sb.append(" template:"); if (vtl.indexOf(" ") < 0) { sb.append(vtl); } else { sb.append('"').append(vtl).append('"'); } sb.append(" line:").append(getLine()); sb.append(" column:").append(getColumn()); } sb.append(']'); return sb.toString(); } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Parse.java0000644000175000017500000002251111353457330026040 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import java.util.List; import java.util.ArrayList; import org.apache.velocity.Template; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; /** * Pluggable directive that handles the #parse() * statement in VTL. * *
       * Notes:
       * -----
       *  1) The parsed source material can only come from somewhere in
       *    the TemplateRoot tree for security reasons. There is no way
       *    around this.  If you want to include content from elsewhere on
       *    your disk, use a link from somwhere under Template Root to that
       *    content.
       *
       *  2) There is a limited parse depth.  It is set as a property
       *    "directive.parse.max.depth = 10" by default.  This 10 deep
       *    limit is a safety feature to prevent infinite loops.
       * 
      * * @author Geir Magnusson Jr. * @author Jason van Zyl * @author Christoph Reck * @version $Id: Parse.java 928253 2010-03-27 19:39:04Z nbubna $ */ public class Parse extends InputBase { private int maxDepth; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "parse"; } /** * Overrides the default to use "template", so that all templates * can use the same scope reference, whether rendered via #parse * or direct merge. */ public String getScopeName() { return "template"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return LINE; } /** * Init's the #parse directive. * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); this.maxDepth = rsvc.getInt(RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 10); } /** * iterates through the argument list and renders every * argument that is appropriate. Any non appropriate * arguments are logged, but render() continues. * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException */ public boolean render( InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { /* * did we get an argument? */ if ( node.jjtGetNumChildren() == 0 ) { throw new VelocityException("#parse(): argument missing at " + Log.formatFileString(this)); } /* * does it have a value? If you have a null reference, then no. */ Object value = node.jjtGetChild(0).value( context ); if (value == null && rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug("#parse(): null argument at " + Log.formatFileString(this)); } /* * get the path */ String sourcearg = value == null ? null : value.toString(); /* * check to see if the argument will be changed by the event cartridge */ String arg = EventHandlerUtil.includeEvent( rsvc, context, sourcearg, context.getCurrentTemplateName(), getName()); /* * a null return value from the event cartridge indicates we should not * input a resource. */ if (arg == null) { // abort early, but still consider it a successful rendering return true; } if (maxDepth > 0) { /* * see if we have exceeded the configured depth. */ Object[] templateStack = context.getTemplateNameStack(); if (templateStack.length >= maxDepth) { StringBuffer path = new StringBuffer(); for( int i = 0; i < templateStack.length; ++i) { path.append( " > " + templateStack[i] ); } rsvc.getLog().error("Max recursion depth reached (" + templateStack.length + ')' + " File stack:" + path); return false; } } /* * now use the Runtime resource loader to get the template */ Template t = null; try { t = rsvc.getTemplate( arg, getInputEncoding(context) ); } catch ( ResourceNotFoundException rnfe ) { /* * the arg wasn't found. Note it and throw */ rsvc.getLog().error("#parse(): cannot find template '" + arg + "', called at " + Log.formatFileString(this)); throw rnfe; } catch ( ParseErrorException pee ) { /* * the arg was found, but didn't parse - syntax error * note it and throw */ rsvc.getLog().error("#parse(): syntax error in #parse()-ed template '" + arg + "', called at " + Log.formatFileString(this)); throw pee; } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { rsvc.getLog().error("Exception rendering #parse(" + arg + ") at " + Log.formatFileString(this)); throw e; } catch ( Exception e) { String msg = "Exception rendering #parse(" + arg + ") at " + Log.formatFileString(this); rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } /** * Add the template name to the macro libraries list */ List macroLibraries = context.getMacroLibraries(); /** * if macroLibraries are not set create a new one */ if (macroLibraries == null) { macroLibraries = new ArrayList(); } context.setMacroLibraries(macroLibraries); macroLibraries.add(arg); /* * and render it */ try { preRender(context); context.pushCurrentTemplateName(arg); ((SimpleNode) t.getData()).render(context, writer); } catch( StopCommand stop ) { if (!stop.isFor(this)) { throw stop; } } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { /** * Log #parse errors so the user can track which file called which. */ rsvc.getLog().error("Exception rendering #parse(" + arg + ") at " + Log.formatFileString(this)); throw e; } catch ( Exception e ) { String msg = "Exception rendering #parse(" + arg + ") at " + Log.formatFileString(this); rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } finally { context.popCurrentTemplateName(); postRender(context); } /* * note - a blocked input is still a successful operation as this is * expected behavior. */ return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/DirectiveConstants.java0000644000175000017500000000236310513464370030603 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ /** * Base class for all directives used in Velocity. * * @author Geir Magnusson Jr. * @version $Id: DirectiveConstants.java 463298 2006-10-12 16:10:32Z henning $ */ public interface DirectiveConstants { /** Block directive indicator */ public static final int BLOCK = 1; /** Line directive indicator */ public static final int LINE = 2; } velocity-1.7/src/java/org/apache/velocity/runtime/directive/MacroParseException.java0000644000175000017500000001355511135107153030702 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import org.apache.velocity.exception.ExtendedParseException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.Token; /** * Exception to indicate problem happened while constructing #macro() * * For internal use in parser - not to be passed to app level * * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: MacroParseException.java 735709 2009-01-19 14:30:03Z byron $ */ public class MacroParseException extends ParseException implements ExtendedParseException { private final String templateName; /** * Version Id for serializable */ private static final long serialVersionUID = -4985224672336070689L; /** * @param msg * @param templateName * @param currentToken */ public MacroParseException(final String msg, final String templateName, final Token currentToken) { super(msg + " at "); this.currentToken = currentToken; this.templateName = templateName; } /** * returns the Template name where this exception occured. * @return The Template name where this exception occured. * @since 1.5 */ public String getTemplateName() { return templateName; } /** * returns the line number where this exception occured. * @return The line number where this exception occured. * @since 1.5 */ public int getLineNumber() { if ((currentToken != null) && (currentToken.next != null)) { return currentToken.next.beginLine; } else if (currentToken != null) { return currentToken.beginLine; } else { return -1; } } /** * returns the column number where this exception occured. * @return The column number where this exception occured. * @since 1.5 */ public int getColumnNumber() { if ((currentToken != null) && (currentToken.next != null)) { return currentToken.next.beginColumn; } else if (currentToken != null) { return currentToken.beginColumn; } else { return -1; } } /** * This method has the standard behavior when this object has been * created using the standard constructors. Otherwise, it uses * "currentToken" and "expectedTokenSequences" to generate a parse * error message and returns it. If this object has been created * due to a parse error, and you do not catch it (it gets thrown * from the parser), then this method is called during the printing * of the final stack trace, and hence the correct error message * gets displayed. * @return the current message. * @since 1.5 */ public String getMessage() { if (!specialConstructor) { StringBuffer sb = new StringBuffer(super.getMessage()); appendTemplateInfo(sb); return sb.toString(); } int maxSize = 0; StringBuffer expected = new StringBuffer(); for (int i = 0; i < expectedTokenSequences.length; i++) { if (maxSize < expectedTokenSequences[i].length) { maxSize = expectedTokenSequences[i].length; } for (int j = 0; j < expectedTokenSequences[i].length; j++) { expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" "); } if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { expected.append("..."); } expected.append(eol).append(" "); } StringBuffer retval = new StringBuffer("Encountered \""); Token tok = currentToken.next; for (int i = 0; i < maxSize; i++) { if (i != 0) { retval.append(" "); } if (tok.kind == 0) { retval.append(tokenImage[0]); break; } retval.append(add_escapes(tok.image)); tok = tok.next; } retval.append("\""); appendTemplateInfo(retval); if (expectedTokenSequences.length == 1) { retval.append("Was expecting:").append(eol).append(" "); } else { retval.append("Was expecting one of:").append(eol).append(" "); } // avoid JDK 1.3 StringBuffer.append(Object o) vs 1.4 StringBuffer.append(StringBuffer sb) gotcha. retval.append(expected.toString()); return retval.toString(); } /** * @param sb * @since 1.5 */ protected void appendTemplateInfo(final StringBuffer sb) { sb.append(Log.formatFileString(getTemplateName(), getLineNumber(), getColumnNumber())); sb.append(eol); } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/BlockMacro.java0000644000175000017500000000716311322700447027004 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.Node; /** * BlockMacro directive is used to invoke Velocity macros with normal parameters and a macro body. *

      * The macro can then refer to the passed body AST. This directive can be used as a * "decorator". Body AST can contain any valid Velocity syntax. * * An example: *

       * #set($foobar = "yeah!")
       * 
       * #macro(strong $txt)
       * <strong>$bodyContent</strong> $txt
       * #end
       *
       * #@strong($foobar)
       * <u>This text is underlined and bold</u>
       * #end
       * 
      * Will print: *
       * <strong><u>This text is underlined and bold<u></strong> yeah!
       * 
      * * bodyContent reference name is configurable (see velocity.properties). * * @author Jarkko Viinamaki * @since 1.7 * @version $Id$ */ public class BlockMacro extends Block { private String name; private RuntimeMacro macro; public BlockMacro(String name) { this.name = name; } public String getName() { return key; } /** * Override to use the macro name, since it is within an * #@myMacro() ... #end block that the scope in question * would be used. */ public String getScopeName() { return name; } /** * Initializes the directive. * * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); // get name of the reference that refers to AST block passed to block macro call key = rsvc.getString(RuntimeConstants.VM_BODY_REFERENCE, "bodyContent"); // use the macro max depth for bodyContent max depth as well maxDepth = rs.getInt(RuntimeConstants.VM_MAX_DEPTH); macro = new RuntimeMacro(name); macro.setLocation(getLine(), getColumn(), getTemplateName()); macro.init(rs, context, node); } /** * Renders content using the selected macro and the passed AST body. * * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException { return macro.render(context, writer, node, new Reference(context, this)); } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Directive.java0000644000175000017500000001454411206073012026677 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.Writer; import java.io.IOException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; /** * Base class for all directives used in Velocity. * * @author Jason van Zyl * @author Nathan Bubna * @version $Id: Directive.java 778045 2009-05-23 22:17:46Z nbubna $ */ public abstract class Directive implements DirectiveConstants, Cloneable { private int line = 0; private int column = 0; private boolean provideScope = false; private String templateName; /** * */ protected RuntimeServices rsvc = null; /** * Return the name of this directive. * @return The name of this directive. */ public abstract String getName(); /** * Get the directive type BLOCK/LINE. * @return The directive type BLOCK/LINE. */ public abstract int getType(); /** * Allows the template location to be set. * @param line * @param column */ public void setLocation( int line, int column ) { this.line = line; this.column = column; } /** * Allows the template location to be set. * @param line * @param column */ public void setLocation(int line, int column, String templateName) { setLocation(line, column); this.templateName = templateName; } /** * for log msg purposes * @return The current line for log msg purposes. */ public int getLine() { return line; } /** * for log msg purposes * @return The current column for log msg purposes. */ public int getColumn() { return column; } /** * @return The template file name this directive was defined in, or null if not * defined in a file. */ public String getTemplateName() { return templateName; } /** * @returns the name to be used when a scope control is provided for this * directive. */ public String getScopeName() { return getName(); } /** * @return true if there will be a scope control injected into the context * when rendering this directive. */ public boolean isScopeProvided() { return provideScope; } /** * How this directive is to be initialized. * @param rs * @param context * @param node * @throws TemplateInitException */ public void init( RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { rsvc = rs; String property = getScopeName()+'.'+RuntimeConstants.PROVIDE_SCOPE_CONTROL; this.provideScope = rsvc.getBoolean(property, provideScope); } /** * How this directive is to be rendered * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException */ public abstract boolean render( InternalContextAdapter context, Writer writer, Node node ) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException; /** * This creates and places the scope control for this directive * into the context (if scope provision is turned on). */ protected void preRender(InternalContextAdapter context) { if (isScopeProvided()) { String name = getScopeName(); Object previous = context.get(name); context.put(name, makeScope(previous)); } } protected Scope makeScope(Object prev) { return new Scope(this, prev); } /** * This cleans up any scope control for this directive after rendering, * assuming the scope control was turned on. */ protected void postRender(InternalContextAdapter context) { if (isScopeProvided()) { String name = getScopeName(); Object obj = context.get(name); try { Scope scope = (Scope)obj; if (scope.getParent() != null) { context.put(name, scope.getParent()); } else if (scope.getReplaced() != null) { context.put(name, scope.getReplaced()); } else { context.remove(name); } } catch (ClassCastException cce) { // the user can override the scope with a #set, // since that means they don't care about a replaced value // and obviously aren't too keen on their scope control, // and especially since #set is meant to be handled globally, // we'll assume they know what they're doing and not worry // about replacing anything superseded by this directive's scope } } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Include.java0000644000175000017500000002313711147712004026347 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.app.event.EventHandlerUtil; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.resource.Resource; /** *

      Pluggable directive that handles the #include() statement in VTL. * This #include() can take multiple arguments of either * StringLiteral or Reference.

      * *

      Notes:

      *
        *
      1. For security reasons, the included source material can only come * from somewhere within the template root tree. If you want to include * content from elsewhere on your disk, add extra template roots, or use * a link from somwhere under template root to that content.
      2. * *
      3. By default, there is no output to the render stream in the event of * a problem. You can override this behavior with two property values : * include.output.errormsg.start * include.output.errormsg.end * If both are defined in velocity.properties, they will be used to * in the render output to bracket the arg string that caused the * problem. * Ex. : if you are working in html then * include.output.errormsg.start=<!-- #include error : * include.output.errormsg.end= --> * might be an excellent way to start...
      4. * *
      5. As noted above, #include() can take multiple arguments. * Ex : #include('foo.vm' 'bar.vm' $foo) * will include all three if valid to output without any * special separator.
      6. *
      * * @author Geir Magnusson Jr. * @author Jason van Zyl * @author Kasper Nielsen * @version $Id: Include.java 746438 2009-02-21 05:41:24Z nbubna $ */ public class Include extends InputBase { private String outputMsgStart = ""; private String outputMsgEnd = ""; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "include"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return LINE; } /** * Since there is no processing of content, * there is never a need for an internal scope. */ public boolean isScopeProvided() { return false; } /** * simple init - init the tree and get the elementKey from * the AST * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init( rs, context, node ); /* * get the msg, and add the space so we don't have to * do it each time */ outputMsgStart = rsvc.getString(RuntimeConstants.ERRORMSG_START); outputMsgStart = outputMsgStart + " "; outputMsgEnd = rsvc.getString(RuntimeConstants.ERRORMSG_END ); outputMsgEnd = " " + outputMsgEnd; } /** * iterates through the argument list and renders every * argument that is appropriate. Any non appropriate * arguments are logged, but render() continues. * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException * @throws MethodInvocationException * @throws ResourceNotFoundException */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, MethodInvocationException, ResourceNotFoundException { /* * get our arguments and check them */ int argCount = node.jjtGetNumChildren(); for( int i = 0; i < argCount; i++) { /* * we only handle StringLiterals and References right now */ Node n = node.jjtGetChild(i); if ( n.getType() == ParserTreeConstants.JJTSTRINGLITERAL || n.getType() == ParserTreeConstants.JJTREFERENCE ) { if (!renderOutput( n, context, writer )) outputErrorToStream( writer, "error with arg " + i + " please see log."); } else { String msg = "invalid #include() argument '" + n.toString() + "' at " + Log.formatFileString(this); rsvc.getLog().error(msg); outputErrorToStream( writer, "error with arg " + i + " please see log."); throw new VelocityException(msg); } } return true; } /** * does the actual rendering of the included file * * @param node AST argument of type StringLiteral or Reference * @param context valid context so we can render References * @param writer output Writer * @return boolean success or failure. failures are logged * @exception IOException * @exception MethodInvocationException * @exception ResourceNotFoundException */ private boolean renderOutput( Node node, InternalContextAdapter context, Writer writer ) throws IOException, MethodInvocationException, ResourceNotFoundException { if ( node == null ) { rsvc.getLog().error("#include() null argument"); return false; } /* * does it have a value? If you have a null reference, then no. */ Object value = node.value( context ); if ( value == null) { rsvc.getLog().error("#include() null argument"); return false; } /* * get the path */ String sourcearg = value.toString(); /* * check to see if the argument will be changed by the event handler */ String arg = EventHandlerUtil.includeEvent( rsvc, context, sourcearg, context.getCurrentTemplateName(), getName() ); /* * a null return value from the event cartridge indicates we should not * input a resource. */ boolean blockinput = false; if (arg == null) blockinput = true; Resource resource = null; try { if (!blockinput) resource = rsvc.getContent(arg, getInputEncoding(context)); } catch ( ResourceNotFoundException rnfe ) { /* * the arg wasn't found. Note it and throw */ rsvc.getLog().error("#include(): cannot find resource '" + arg + "', called at " + Log.formatFileString(this)); throw rnfe; } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { rsvc.getLog().error("#include(): arg = '" + arg + "', called at " + Log.formatFileString(this)); throw e; } catch (Exception e) { String msg = "#include(): arg = '" + arg + "', called at " + Log.formatFileString(this); rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } /* * note - a blocked input is still a successful operation as this is * expected behavior. */ if ( blockinput ) return true; else if ( resource == null ) return false; writer.write((String)resource.getData()); return true; } /** * Puts a message to the render output stream if ERRORMSG_START / END * are valid property strings. Mainly used for end-user template * debugging. * @param writer * @param msg * @throws IOException */ private void outputErrorToStream( Writer writer, String msg ) throws IOException { if ( outputMsgStart != null && outputMsgEnd != null) { writer.write(outputMsgStart); writer.write(msg); writer.write(outputMsgEnd); } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/StopCommand.java0000755000175000017500000000520211322700447027207 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import org.apache.velocity.Template; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.runtime.directive.Evaluate; /** * Stop command for directive Control objects. In an ideal JDK, * this would be able to extend a RuntimeThrowable class, but we * don't have that. So to avoid the interface changes needed by * extending Throwable and the potential errant catches were we * to extend RuntimeException, we'll have to extend Error, * despite the fact that this is never an error. * * @author Nathan Bubna * @version $Id$ */ public class StopCommand extends Error { private static final long serialVersionUID = 2577683435802825964L; private Object stopMe; private boolean nearest = false; public StopCommand() { this.nearest = true; } public StopCommand(String message) { super(message); } public StopCommand(Object stopMe) { this.stopMe = stopMe; } public String getMessage() { if (stopMe != null) { // only create a useful message if requested (which is unlikely) return "StopCommand: "+stopMe; } else { return "StopCommand: "+super.getMessage(); } } public boolean isFor(Object that) { if (nearest) // if we're stopping at the first chance { // save that for message stopMe = that; return true; } else if (stopMe != null) // if we have a specified stopping point { return (that == stopMe); } else // only stop for the top :) { return (that instanceof Template || that instanceof RuntimeInstance || that instanceof Evaluate); } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Break.java0000644000175000017500000000663311153274742026023 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; /** * Break directive used for interrupting scopes. * * @author Jarkko Viinamaki * @author Nathan Bubna * @version $Id$ */ public class Break extends Directive { private boolean scoped = false; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "break"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return LINE; } /** * Since there is no processing of content, * there is never a need for an internal scope. */ public boolean isScopeProvided() { return false; } /** * simple init - init the tree and get the elementKey from * the AST * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) { super.init(rs, context, node); int kids = node.jjtGetNumChildren(); if (kids > 1) { throw new VelocityException("The #stop directive only accepts a single scope object at " + Log.formatFileString(this)); } else { this.scoped = (kids == 1); } } /** * Break directive does not actually do any rendering. * * This directive throws a StopCommand which signals either * the nearest Scope or the specified scope to stop rendering * its content. * * @param context * @param writer * @param node * @return never, always throws a StopCommand */ public boolean render(InternalContextAdapter context, Writer writer, Node node) { if (!scoped) { throw new StopCommand(); } Object argument = node.jjtGetChild(0).value(context); if (argument instanceof Scope) { ((Scope)argument).stop(); } else { throw new VelocityException(node.jjtGetChild(0).literal()+ " is not a valid " + Scope.class.getName() + " instance at " + Log.formatFileString(this)); } return false; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Stop.java0000755000175000017500000000544011322700447025714 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; /** * This class implements the #stop directive which allows * a user to stop the merging and rendering process. The #stop directive * will accept a single message argument with info about the reason for * stopping. */ public class Stop extends Directive { private static final StopCommand STOP_ALL = new StopCommand("StopCommand to exit merging"); private boolean hasMessage = false; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "stop"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return LINE; } /** * Since there is no processing of content, * there is never a need for an internal scope. */ public boolean isScopeProvided() { return false; } public void init(RuntimeServices rs, InternalContextAdapter context, Node node) { super.init(rs, context, node); int kids = node.jjtGetNumChildren(); if (kids > 1) { throw new VelocityException("The #stop directive only accepts a single message parameter at " + Log.formatFileString(this)); } else { hasMessage = (kids == 1); } } public boolean render(InternalContextAdapter context, Writer writer, Node node) { if (!hasMessage) { throw STOP_ALL; } Object argument = node.jjtGetChild(0).value(context); // stop all and use specified message throw new StopCommand(String.valueOf(argument)); } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/InputBase.java0000644000175000017500000000404010513464370026654 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.Resource; /** * Base class for directives which do input operations * (e.g. #include(), #parse(), etc.). * * @author Daniel Rall * @since 1.4 */ public abstract class InputBase extends Directive { /** * Decides the encoding used during input processing of this * directive. * * Get the resource, and assume that we use the encoding of the * current template the 'current resource' can be * null if we are processing a stream.... * * @param context The context to derive the default input encoding * from. * @return The encoding to use when processing this directive. */ protected String getInputEncoding(InternalContextAdapter context) { Resource current = context.getCurrentResource(); if (current != null) { return current.getEncoding(); } else { return (String) rsvc.getProperty(RuntimeConstants.INPUT_ENCODING); } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Define.java0000755000175000017500000000620411317163206026160 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.Node; /** * Directive that puts an unrendered AST block in the context * under the specified key, postponing rendering until the * reference is used and rendered. * * @author Andrew Tetlaw * @author Nathan Bubna * @version $Id: Define.java 686842 2008-08-18 18:29:31Z nbubna $ */ public class Define extends Block { /** * Return name of this directive. */ public String getName() { return "define"; } /** * simple init - get the key */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); // the first child is the block name (key), the second child is the block AST body if ( node.jjtGetNumChildren() != 2 ) { throw new VelocityException("parameter missing: block name at " + Log.formatFileString(this)); } /* * first token is the name of the block. We don't even check the format, * just assume it looks like this: $block_name. Should we check if it has * a '$' or not? */ key = node.jjtGetChild(0).getFirstToken().image.substring(1); /* * default max depth of two is used because intentional recursion is * unlikely and discouraged, so make unintentional ones end fast */ maxDepth = rs.getInt(RuntimeConstants.DEFINE_DIRECTIVE_MAXDEPTH, 2); } /** * directive.render() simply makes an instance of the Block inner class * and places it into the context as indicated. */ public boolean render(InternalContextAdapter context, Writer writer, Node node) { /* put a Block.Reference instance into the context, * using the user-defined key, for later inline rendering. */ context.put(key, new Reference(context, this)); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Block.java0000755000175000017500000001250611322700447026022 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; /** * Directive that puts an unrendered AST block in the context * under the specified key, postponing rendering until the * reference is used and rendered. * * @author Andrew Tetlaw * @author Nathan Bubna * @author Jarkko Viinamaki * @since 1.7 * @version $Id: Block.java 686842 2008-08-18 18:29:31Z nbubna $ */ public abstract class Block extends Directive { protected Node block; protected Log log; protected int maxDepth; protected String key; /** * Return type of this directive. */ public int getType() { return BLOCK; } /** * simple init - get the key */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init(rs, context, node); log = rs.getLog(); /** * No checking is done. We just grab the last child node and assume * that it's the block! */ block = node.jjtGetChild(node.jjtGetNumChildren() - 1); } public boolean render(InternalContextAdapter context, Writer writer) { preRender(context); try { return block.render(context, writer); } catch (IOException e) { String msg = "Failed to render " + id(context) + " to writer " + " at " + Log.formatFileString(this); log.error(msg, e); throw new RuntimeException(msg, e); } catch (StopCommand stop) { if (!stop.isFor(this)) { throw stop; } return true; } finally { postRender(context); } } /** * Creates a string identifying the source and location of the block * definition, and the current template being rendered if that is * different. */ protected String id(InternalContextAdapter context) { StrBuilder str = new StrBuilder(100) .append("block $").append(key); if (!context.getCurrentTemplateName().equals(getTemplateName())) { str.append(" used in ").append(context.getCurrentTemplateName()); } return str.toString(); } /** * actual class placed in the context, holds the context * being used for the render, as well as the parent (which already holds * everything else we need). */ public static class Reference implements Renderable { private InternalContextAdapter context; private Block parent; private int depth; public Reference(InternalContextAdapter context, Block parent) { this.context = context; this.parent = parent; } /** * Render the AST of this block into the writer using the context. */ public boolean render(InternalContextAdapter context, Writer writer) { depth++; if (depth > parent.maxDepth) { /* this is only a debug message, as recursion can * happen in quasi-innocent situations and is relatively * harmless due to how we handle it here. * this is more to help anyone nuts enough to intentionally * use recursive block definitions and having problems * pulling it off properly. */ parent.log.debug("Max recursion depth reached for " + parent.id(context) + " at " + Log.formatFileString(parent)); depth--; return false; } else { parent.render(context, writer); depth--; return true; } } public String toString() { Writer writer = new StringWriter(); if (render(context, writer)) { return writer.toString(); } return null; } } } velocity-1.7/src/java/org/apache/velocity/runtime/directive/Literal.java0000644000175000017500000000610611147712004026355 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.IOException; import java.io.Writer; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.Node; /** * A very simple directive that leverages the Node.literal() * to grab the literal rendition of a node. We basically * grab the literal value on init(), then repeatedly use * that during render(). This is deprecated and will be * removed in Velocity 2.0; please use #[[unparsed content]]# * instead. * * @author Jason van Zyl * @version $Id: Literal.java 746438 2009-02-21 05:41:24Z nbubna $ * @deprecated Use the #[[unparsed content]]# syntax instead. */ public class Literal extends Directive { String literalText; /** * Return name of this directive. * @return The name of this directive. */ public String getName() { return "literal"; } /** * Return type of this directive. * @return The type of this directive. */ public int getType() { return BLOCK; } /** * Since there is no processing of content, * there is never a need for an internal scope. */ public boolean isScopeProvided() { return false; } /** * Store the literal rendition of a node using * the Node.literal(). * @param rs * @param context * @param node * @throws TemplateInitException */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws TemplateInitException { super.init( rs, context, node ); literalText = node.jjtGetChild(0).literal(); } /** * Throw the literal rendition of the block between * #literal()/#end into the writer. * @param context * @param writer * @param node * @return True if the directive rendered successfully. * @throws IOException */ public boolean render( InternalContextAdapter context, Writer writer, Node node) throws IOException { writer.write(literalText); return true; } } velocity-1.7/src/java/org/apache/velocity/runtime/VelocimacroManager.java0000644000175000017500000003643111440010132026532 0ustar moellermoellerpackage org.apache.velocity.runtime; /* * 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. */ import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.directive.VelocimacroProxy; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.util.MapFactory; /** * Manages VMs in namespaces. Currently, two namespace modes are * supported: * *
        *
      • flat - all allowable VMs are in the global namespace
      • *
      • local - inline VMs are added to it's own template namespace
      • *
      * * Thanks to Jose Alberto Fernandez * for some ideas incorporated here. * * @author Geir Magnusson Jr. * @author Jose Alberto Fernandez * @version $Id: VelocimacroManager.java 992115 2010-09-02 21:00:10Z nbubna $ */ public class VelocimacroManager { private static String GLOBAL_NAMESPACE = ""; private boolean registerFromLib = false; /** Hash of namespace hashes. */ private final Map namespaceHash = MapFactory.create(17, 0.5f, 20, false); /** reference to global namespace hash */ private final Map globalNamespace; /** set of names of library tempates/namespaces */ private final Set libraries = Collections.synchronizedSet(new HashSet()); private RuntimeServices rsvc = null; /* * big switch for namespaces. If true, then properties control * usage. If false, no. */ private boolean namespacesOn = true; private boolean inlineLocalMode = false; private boolean inlineReplacesGlobal = false; /** * Adds the global namespace to the hash. */ VelocimacroManager(RuntimeServices rsvc) { /* * add the global namespace to the namespace hash. We always have that. */ globalNamespace = addNamespace(GLOBAL_NAMESPACE); this.rsvc = rsvc; } /** * Adds a VM definition to the cache. * * Called by VelocimacroFactory.addVelociMacro (after parsing and discovery in Macro directive) * * @param vmName Name of the new VelociMacro. * @param macroBody String representation of the macro body. * @param argArray Array of macro parameters, first parameter is the macro name. * @param namespace The namespace/template from which this macro has been loaded. * @return Whether everything went okay. */ public boolean addVM(final String vmName, final Node macroBody, final String argArray[], final String namespace, boolean canReplaceGlobalMacro) { if (macroBody == null) { // happens only if someone uses this class without the Macro directive // and provides a null value as an argument throw new VelocityException("Null AST for "+vmName+" in "+namespace); } MacroEntry me = new MacroEntry(vmName, macroBody, argArray, namespace, rsvc); me.setFromLibrary(registerFromLib); /* * the client (VMFactory) will signal to us via * registerFromLib that we are in startup mode registering * new VMs from libraries. Therefore, we want to * addto the library map for subsequent auto reloads */ boolean isLib = true; MacroEntry exist = (MacroEntry) globalNamespace.get(vmName); if (registerFromLib) { libraries.add(namespace); } else { /* * now, we first want to check to see if this namespace (template) * is actually a library - if so, we need to use the global namespace * we don't have to do this when registering, as namespaces should * be shut off. If not, the default value is true, so we still go * global */ isLib = libraries.contains(namespace); } if ( !isLib && usingNamespaces(namespace) ) { /* * first, do we have a namespace hash already for this namespace? * if not, add it to the namespaces, and add the VM */ Map local = getNamespace(namespace, true); local.put(vmName, me); return true; } else { /* * otherwise, add to global template. First, check if we * already have it to preserve some of the autoload information */ if (exist != null) { me.setFromLibrary(exist.getFromLibrary()); } /* * now add it */ globalNamespace.put(vmName, me); return true; } } /** * Gets a VelocimacroProxy object by the name / source template duple. * * @param vmName Name of the VelocityMacro to look up. * @param namespace Namespace in which to look up the macro. * @return A proxy representing the Macro. */ public VelocimacroProxy get(final String vmName, final String namespace) { return(get(vmName, namespace, null)); } /** * Gets a VelocimacroProxy object by the name / source template duple. * * @param vmName Name of the VelocityMacro to look up. * @param namespace Namespace in which to look up the macro. * @param renderingTemplate Name of the template we are currently rendering. * @return A proxy representing the Macro. * @since 1.6 */ public VelocimacroProxy get(final String vmName, final String namespace, final String renderingTemplate) { if( inlineReplacesGlobal && renderingTemplate != null ) { /* * if VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL is true (local macros can * override global macros) and we know which template we are rendering at the * moment, check if local namespace contains a macro we are looking for * if so, return it instead of the global one */ Map local = getNamespace(renderingTemplate, false); if (local != null) { MacroEntry me = (MacroEntry) local.get(vmName); if (me != null) { return me.getProxy(namespace); } } } if (usingNamespaces(namespace)) { Map local = getNamespace(namespace, false); /* * if we have macros defined for this template */ if (local != null) { MacroEntry me = (MacroEntry) local.get(vmName); if (me != null) { return me.getProxy(namespace); } } } /* * if we didn't return from there, we need to simply see * if it's in the global namespace */ MacroEntry me = (MacroEntry) globalNamespace.get(vmName); if (me != null) { return me.getProxy(namespace); } return null; } /** * Removes the VMs and the namespace from the manager. * Used when a template is reloaded to avoid * losing memory. * * @param namespace namespace to dump * @return boolean representing success */ public boolean dumpNamespace(final String namespace) { if (usingNamespaces(namespace)) { synchronized(this) { Map h = (Map) namespaceHash.remove(namespace); if (h == null) { return false; } h.clear(); return true; } } return false; } /** * public switch to let external user of manager to control namespace * usage indep of properties. That way, for example, at startup the * library files are loaded into global namespace * * @param namespaceOn True if namespaces should be used. */ public void setNamespaceUsage(final boolean namespaceOn) { this.namespacesOn = namespaceOn; } /** * Should macros registered from Libraries be marked special? * @param registerFromLib True if macros from Libs should be marked. */ public void setRegisterFromLib(final boolean registerFromLib) { this.registerFromLib = registerFromLib; } /** * Should macros from the same template be inlined? * * @param inlineLocalMode True if macros should be inlined on the same template. */ public void setTemplateLocalInlineVM(final boolean inlineLocalMode) { this.inlineLocalMode = inlineLocalMode; } /** * returns the hash for the specified namespace, and if it doesn't exist * will create a new one and add it to the namespaces * * @param namespace name of the namespace :) * @param addIfNew flag to add a new namespace if it doesn't exist * @return namespace Map of VMs or null if doesn't exist */ private Map getNamespace(final String namespace, final boolean addIfNew) { Map h = (Map) namespaceHash.get(namespace); if (h == null && addIfNew) { h = addNamespace(namespace); } return h; } /** * adds a namespace to the namespaces * * @param namespace name of namespace to add * @return Hash added to namespaces, ready for use */ private Map addNamespace(final String namespace) { Map h = MapFactory.create(17, 0.5f, 20, false); Object oh; if ((oh = namespaceHash.put(namespace, h)) != null) { /* * There was already an entry on the table, restore it! * This condition should never occur, given the code * and the fact that this method is private. * But just in case, this way of testing for it is much * more efficient than testing before hand using get(). */ namespaceHash.put(namespace, oh); /* * Should't we be returning the old entry (oh)? * The previous code was just returning null in this case. */ return null; } return h; } /** * determines if currently using namespaces. * * @param namespace currently ignored * @return true if using namespaces, false if not */ private boolean usingNamespaces(final String namespace) { /* * if the big switch turns of namespaces, then ignore the rules */ if (!namespacesOn) { return false; } /* * currently, we only support the local template namespace idea */ if (inlineLocalMode) { return true; } return false; } /** * Return the library name for a given macro. * @param vmName Name of the Macro to look up. * @param namespace Namespace to look the macro up. * @return The name of the library which registered this macro in a namespace. */ public String getLibraryName(final String vmName, final String namespace) { if (usingNamespaces(namespace)) { Map local = getNamespace(namespace, false); /* * if we have this macro defined in this namespace, then * it is masking the global, library-based one, so * just return null */ if ( local != null) { MacroEntry me = (MacroEntry) local.get(vmName); if (me != null) { return null; } } } /* * if we didn't return from there, we need to simply see * if it's in the global namespace */ MacroEntry me = (MacroEntry) globalNamespace.get(vmName); if (me != null) { return me.getSourceTemplate(); } return null; } /** * @since 1.6 */ public void setInlineReplacesGlobal(boolean is) { inlineReplacesGlobal = is; } /** * wrapper class for holding VM information */ private static class MacroEntry { private final String vmName; private final String[] argArray; private final String sourceTemplate; private SimpleNode nodeTree = null; private boolean fromLibrary = false; private VelocimacroProxy vp; private MacroEntry(final String vmName, final Node macro, final String argArray[], final String sourceTemplate, RuntimeServices rsvc) { this.vmName = vmName; this.argArray = argArray; this.nodeTree = (SimpleNode)macro; this.sourceTemplate = sourceTemplate; vp = new VelocimacroProxy(); vp.setName(this.vmName); vp.setArgArray(this.argArray); vp.setNodeTree(this.nodeTree); vp.setLocation(macro.getLine(), macro.getColumn(), macro.getTemplateName()); vp.init(rsvc); } /** * Has the macro been registered from a library. * @param fromLibrary True if the macro was registered from a Library. */ public void setFromLibrary(final boolean fromLibrary) { this.fromLibrary = fromLibrary; } /** * Returns true if the macro was registered from a library. * @return True if the macro was registered from a library. */ public boolean getFromLibrary() { return fromLibrary; } /** * Returns the node tree for this macro. * @return The node tree for this macro. */ public SimpleNode getNodeTree() { return nodeTree; } /** * Returns the source template name for this macro. * @return The source template name for this macro. */ public String getSourceTemplate() { return sourceTemplate; } VelocimacroProxy getProxy(final String namespace) { /* * FIXME: namespace data is omitted, this probably * breaks some error reporting? */ return vp; } } } velocity-1.7/src/java/org/apache/velocity/texen/0000755000175000017500000000000011675166252021613 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/texen/ant/0000755000175000017500000000000011675166252022375 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/texen/ant/TexenTask.java0000644000175000017500000005042310513464370025142 0ustar moellermoellerpackage org.apache.velocity.texen.ant; /* * 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. */ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Writer; import java.util.Date; import java.util.Iterator; import java.util.StringTokenizer; import org.apache.commons.collections.ExtendedProperties; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.texen.Generator; import org.apache.velocity.util.StringUtils; /** * An ant task for generating output by using Velocity * * @author Jason van Zyl * @author Robert Burrell Donkin * @version $Id: TexenTask.java 463298 2006-10-12 16:10:32Z henning $ */ public class TexenTask extends Task { /** * This message fragment (telling users to consult the log or * invoke ant with the -debug flag) is appended to rethrown * exception messages. */ private final static String ERR_MSG_FRAGMENT = ". For more information consult the velocity log, or invoke ant " + "with the -debug flag."; /** * This is the control template that governs the output. * It may or may not invoke the services of worker * templates. */ protected String controlTemplate; /** * This is where Velocity will look for templates * using the file template loader. */ protected String templatePath; /** * This is where texen will place all the output * that is a product of the generation process. */ protected String outputDirectory; /** * This is the file where the generated text * will be placed. */ protected String outputFile; /** * This is the encoding for the output file(s). */ protected String outputEncoding; /** * This is the encoding for the input file(s) * (templates). */ protected String inputEncoding; /** *

      * These are properties that are fed into the * initial context from a properties file. This * is simply a convenient way to set some values * that you wish to make available in the context. *

      *

      * These values are not critical, like the template path * or output path, but allow a convenient way to * set a value that may be specific to a particular * generation task. *

      *

      * For example, if you are generating scripts to allow * user to automatically create a database, then * you might want the $databaseName * to be placed * in the initial context so that it is available * in a script that might look something like the * following: *

           * #!bin/sh
           *
           * echo y | mysqladmin create $databaseName
           * 
      * The value of $databaseName isn't critical to * output, and you obviously don't want to change * the ant task to simply take a database name. * So initial context values can be set with * properties file. */ protected ExtendedProperties contextProperties; /** * Property which controls whether the classpath * will be used when trying to locate templates. */ protected boolean useClasspath; /** * The LogFile (incl. path) to log to. */ protected String logFile; /** * Property which controls whether the resource * loader will be told to cache. Default false */ protected String useResourceLoaderCache = "false"; /** * */ protected String resourceLoaderModificationCheckInterval = "2"; /** * [REQUIRED] Set the control template for the * generating process. * @param controlTemplate */ public void setControlTemplate (String controlTemplate) { this.controlTemplate = controlTemplate; } /** * Get the control template for the * generating process. * @return The current control template. */ public String getControlTemplate() { return controlTemplate; } /** * [REQUIRED] Set the path where Velocity will look * for templates using the file template * loader. * @param templatePath * @throws Exception */ public void setTemplatePath(String templatePath) throws Exception { StringBuffer resolvedPath = new StringBuffer(); StringTokenizer st = new StringTokenizer(templatePath, ","); while ( st.hasMoreTokens() ) { // resolve relative path from basedir and leave // absolute path untouched. File fullPath = project.resolveFile(st.nextToken()); resolvedPath.append(fullPath.getCanonicalPath()); if ( st.hasMoreTokens() ) { resolvedPath.append(","); } } this.templatePath = resolvedPath.toString(); System.out.println(templatePath); } /** * Get the path where Velocity will look * for templates using the file template * loader. * @return The template path. */ public String getTemplatePath() { return templatePath; } /** * [REQUIRED] Set the output directory. It will be * created if it doesn't exist. * @param outputDirectory */ public void setOutputDirectory(File outputDirectory) { try { this.outputDirectory = outputDirectory.getCanonicalPath(); } catch (java.io.IOException ioe) { throw new BuildException(ioe); } } /** * Get the output directory. * @return The output directory. */ public String getOutputDirectory() { return outputDirectory; } /** * [REQUIRED] Set the output file for the * generation process. * @param outputFile */ public void setOutputFile(String outputFile) { this.outputFile = outputFile; } /** * Set the output encoding. * @param outputEncoding */ public void setOutputEncoding(String outputEncoding) { this.outputEncoding = outputEncoding; } /** * Set the input (template) encoding. * @param inputEncoding */ public void setInputEncoding(String inputEncoding) { this.inputEncoding = inputEncoding; } /** * Get the output file for the * generation process. * @return The output file. */ public String getOutputFile() { return outputFile; } /** * Sets the log file. * @param log */ public void setLogFile(String log) { this.logFile = log; } /** * Gets the log file. * @return The log file. */ public String getLogFile() { return this.logFile; } /** * Set the context properties that will be * fed into the initial context be the * generating process starts. * @param file */ public void setContextProperties( String file ) { String[] sources = StringUtils.split(file,","); contextProperties = new ExtendedProperties(); // Always try to get the context properties resource // from a file first. Templates may be taken from a JAR // file but the context properties resource may be a // resource in the filesystem. If this fails than attempt // to get the context properties resource from the // classpath. for (int i = 0; i < sources.length; i++) { ExtendedProperties source = new ExtendedProperties(); try { // resolve relative path from basedir and leave // absolute path untouched. File fullPath = project.resolveFile(sources[i]); log("Using contextProperties file: " + fullPath); source.load(new FileInputStream(fullPath)); } catch (IOException e) { ClassLoader classLoader = this.getClass().getClassLoader(); try { InputStream inputStream = classLoader.getResourceAsStream(sources[i]); if (inputStream == null) { throw new BuildException("Context properties file " + sources[i] + " could not be found in the file system or on the classpath!"); } else { source.load(inputStream); } } catch (IOException ioe) { source = null; } } if (source != null) { for (Iterator j = source.getKeys(); j.hasNext(); ) { String name = (String) j.next(); String value = StringUtils.nullTrim(source.getString(name)); contextProperties.setProperty(name,value); } } } } /** * Get the context properties that will be * fed into the initial context be the * generating process starts. * @return The current context properties. */ public ExtendedProperties getContextProperties() { return contextProperties; } /** * Set the use of the classpath in locating templates * * @param useClasspath true means the classpath will be used. */ public void setUseClasspath(boolean useClasspath) { this.useClasspath = useClasspath; } /** * @param useResourceLoaderCache */ public void setUseResourceLoaderCache(String useResourceLoaderCache) { this.useResourceLoaderCache = useResourceLoaderCache; } /** * @param resourceLoaderModificationCheckInterval */ public void setResourceLoaderModificationCheckInterval(String resourceLoaderModificationCheckInterval) { this.resourceLoaderModificationCheckInterval = resourceLoaderModificationCheckInterval; } /** * Creates a VelocityContext. * * @return new Context * @throws Exception the execute method will catch * and rethrow as a BuildException */ public Context initControlContext() throws Exception { return new VelocityContext(); } /** * Execute the input script with Velocity * * @throws BuildException * BuildExceptions are thrown when required attributes are missing. * Exceptions thrown by Velocity are rethrown as BuildExceptions. */ public void execute () throws BuildException { // Make sure the template path is set. if (templatePath == null && useClasspath == false) { throw new BuildException( "The template path needs to be defined if you are not using " + "the classpath for locating templates!"); } // Make sure the control template is set. if (controlTemplate == null) { throw new BuildException("The control template needs to be defined!"); } // Make sure the output directory is set. if (outputDirectory == null) { throw new BuildException("The output directory needs to be defined!"); } // Make sure there is an output file. if (outputFile == null) { throw new BuildException("The output file needs to be defined!"); } VelocityEngine ve = new VelocityEngine(); try { // Setup the Velocity Runtime. if (templatePath != null) { log("Using templatePath: " + templatePath, Project.MSG_VERBOSE); ve.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath); } if (useClasspath) { log("Using classpath"); ve.addProperty( VelocityEngine.RESOURCE_LOADER, "classpath"); ve.setProperty( "classpath." + VelocityEngine.RESOURCE_LOADER + ".class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); ve.setProperty( "classpath." + VelocityEngine.RESOURCE_LOADER + ".cache", useResourceLoaderCache); ve.setProperty( "classpath." + VelocityEngine.RESOURCE_LOADER + ".modificationCheckInterval", resourceLoaderModificationCheckInterval); } if (this.logFile != null) { ve.setProperty(RuntimeConstants.RUNTIME_LOG, this.logFile); } ve.init(); // Create the text generator. Generator generator = Generator.getInstance(); generator.setVelocityEngine(ve); generator.setOutputPath(outputDirectory); generator.setInputEncoding(inputEncoding); generator.setOutputEncoding(outputEncoding); if (templatePath != null) { generator.setTemplatePath(templatePath); } // Make sure the output directory exists, if it doesn't // then create it. File file = new File(outputDirectory); if (! file.exists()) { file.mkdirs(); } String path = outputDirectory + File.separator + outputFile; log("Generating to file " + path, Project.MSG_INFO); Writer writer = generator.getWriter(path, outputEncoding); // The generator and the output path should // be placed in the init context here and // not in the generator class itself. Context c = initControlContext(); // Everything in the generator class should be // pulled out and placed in here. What the generator // class does can probably be added to the Velocity // class and the generator class can probably // be removed all together. populateInitialContext(c); // Feed all the options into the initial // control context so they are available // in the control/worker templates. if (contextProperties != null) { Iterator i = contextProperties.getKeys(); while (i.hasNext()) { String property = (String) i.next(); String value = StringUtils.nullTrim(contextProperties.getString(property)); // Now lets quickly check to see if what // we have is numeric and try to put it // into the context as an Integer. try { c.put(property, new Integer(value)); } catch (NumberFormatException nfe) { // Now we will try to place the value into // the context as a boolean value if it // maps to a valid boolean value. String booleanString = contextProperties.testBoolean(value); if (booleanString != null) { c.put(property, Boolean.valueOf(booleanString)); } else { // We are going to do something special // for properties that have a "file.contents" // suffix: for these properties will pull // in the contents of the file and make // them available in the context. So for // a line like the following in a properties file: // // license.file.contents = license.txt // // We will pull in the contents of license.txt // and make it available in the context as // $license. This should make texen a little // more flexible. if (property.endsWith("file.contents")) { // We need to turn the license file from relative to // absolute, and let Ant help :) value = StringUtils.fileContentsToString( project.resolveFile(value).getCanonicalPath()); property = property.substring( 0, property.indexOf("file.contents") - 1); } c.put(property, value); } } } } writer.write(generator.parse(controlTemplate, c)); writer.flush(); writer.close(); generator.shutdown(); cleanup(); } catch( BuildException e) { throw e; } catch( MethodInvocationException e ) { throw new BuildException( "Exception thrown by '" + e.getReferenceName() + "." + e.getMethodName() +"'" + ERR_MSG_FRAGMENT, e.getWrappedThrowable()); } catch( ParseErrorException e ) { throw new BuildException("Velocity syntax error" + ERR_MSG_FRAGMENT ,e); } catch( ResourceNotFoundException e ) { throw new BuildException("Resource not found" + ERR_MSG_FRAGMENT,e); } catch( Exception e ) { throw new BuildException("Generation failed" + ERR_MSG_FRAGMENT ,e); } } /** *

      Place useful objects into the initial context.

      * *

      TexenTask places Date().toString() into the * context as $now. Subclasses who want to vary the * objects in the context should override this method.

      * *

      $generator is not put into the context in this * method.

      * * @param context The context to populate, as retrieved from * {@link #initControlContext()}. * * @throws Exception Error while populating context. The {@link * #execute()} method will catch and rethrow as a * BuildException. */ protected void populateInitialContext(Context context) throws Exception { context.put("now", new Date().toString()); } /** * A hook method called at the end of {@link #execute()} which can * be overridden to perform any necessary cleanup activities (such * as the release of database connections, etc.). By default, * does nothing. * * @exception Exception Problem cleaning up. */ protected void cleanup() throws Exception { } } velocity-1.7/src/java/org/apache/velocity/texen/Generator.java0000644000175000017500000003773710513464370024415 0ustar moellermoellerpackage org.apache.velocity.texen; /* * 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. */ import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.Writer; import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.io.OutputStreamWriter; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.context.Context; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.util.ClassUtils; /** * A text/code generator class * * @author Leon Messerschmidt * @author Jason van Zyl * @version $Id: Generator.java 463298 2006-10-12 16:10:32Z henning $ */ public class Generator { /** * Where the texen output will placed. */ public static final String OUTPUT_PATH = "output.path"; /** * Where the velocity templates live. */ public static final String TEMPLATE_PATH = "template.path"; /** * Default properties file used for controlling the * tools placed in the context. */ private static final String DEFAULT_TEXEN_PROPERTIES = "org/apache/velocity/texen/defaults/texen.properties"; /** * Default properties used by texen. */ private Properties props = new Properties(); /** * Context used for generating the texen output. */ private Context controlContext; /** * Keep track of the file writers used for outputting * to files. If we come across a file writer more * then once then the additional output will be * appended to the file instead of overwritting * the contents. */ private Hashtable writers = new Hashtable(); /** * The generator tools used for creating additional * output withing the control template. This could * use some cleaning up. */ private static Generator instance = new Generator(); /** * This is the encoding for the output file(s). */ protected String outputEncoding; /** * This is the encoding for the input file(s) * (templates). */ protected String inputEncoding; /** * Velocity engine. */ protected VelocityEngine ve; /** * Default constructor. */ private Generator() { setDefaultProps(); } /** * Create a new generator object with default properties. * * @return Generator generator used in the control context. */ public static Generator getInstance() { return instance; } /** * Set the velocity engine. * @param ve */ public void setVelocityEngine(VelocityEngine ve) { this.ve = ve; } /** * Create a new generator object with properties loaded from * a file. If the file does not exist or any other exception * occurs during the reading operation the default properties * are used. * * @param propFile properties used to help populate the control context. */ public Generator (String propFile) { try { BufferedInputStream bi = null; try { bi = new BufferedInputStream (new FileInputStream (propFile)); props.load (bi); } finally { if (bi != null) { bi.close(); } } } catch (IOException e) { System.err.println("Could not load " + propFile + ", falling back to defaults. (" + e.getMessage() + ")"); /* * If something goes wrong we use default properties */ setDefaultProps(); } } /** * Create a new Generator object with a given property * set. The property set will be duplicated. * * @param props properties object to help populate the control context. */ public Generator (Properties props) { this.props = (Properties)props.clone(); } /** * Set default properties. */ protected void setDefaultProps() { ClassLoader classLoader = VelocityEngine.class.getClassLoader(); try { InputStream inputStream = null; try { inputStream = classLoader.getResourceAsStream( DEFAULT_TEXEN_PROPERTIES); props.load( inputStream ); } finally { if (inputStream != null) { inputStream.close(); } } } catch (IOException ioe) { System.err.println("Cannot get default properties: " + ioe.getMessage()); } } /** * Set the template path, where Texen will look * for Velocity templates. * * @param templatePath template path for velocity templates. */ public void setTemplatePath(String templatePath) { props.put(TEMPLATE_PATH, templatePath); } /** * Get the template path. * * @return String template path for velocity templates. */ public String getTemplatePath() { return props.getProperty(TEMPLATE_PATH); } /** * Set the output path for the generated * output. * @param outputPath */ public void setOutputPath(String outputPath) { props.put(OUTPUT_PATH, outputPath); } /** * Get the output path for the generated * output. * * @return String output path for texen output. */ public String getOutputPath() { return props.getProperty(OUTPUT_PATH); } /** * Set the output encoding. * @param outputEncoding */ public void setOutputEncoding(String outputEncoding) { this.outputEncoding = outputEncoding; } /** * Set the input (template) encoding. * @param inputEncoding */ public void setInputEncoding(String inputEncoding) { this.inputEncoding = inputEncoding; } /** * Returns a writer, based on encoding and path. * * @param path path to the output file * @param encoding output encoding * @return A Writer for this generator. * @throws Exception */ public Writer getWriter(String path, String encoding) throws Exception { Writer writer; if (encoding == null || encoding.length() == 0 || encoding.equals("8859-1") || encoding.equals("8859_1")) { writer = new FileWriter(path); } else { writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), encoding)); } return writer; } /** * Returns a template, based on encoding and path. * * @param templateName name of the template * @param encoding template encoding * @return A Template. * @throws Exception */ public Template getTemplate(String templateName, String encoding) throws Exception { Template template; if (encoding == null || encoding.length() == 0 || encoding.equals("8859-1") || encoding.equals("8859_1")) { template = ve.getTemplate(templateName); } else { template = ve.getTemplate(templateName, encoding); } return template; } /** * Parse an input and write the output to an output file. If the * output file parameter is null or an empty string the result is * returned as a string object. Otherwise an empty string is returned. * * @param inputTemplate input template * @param outputFile output file * @return The parsed file. * @throws Exception */ public String parse (String inputTemplate, String outputFile) throws Exception { return parse(inputTemplate, outputFile, null, null); } /** * Parse an input and write the output to an output file. If the * output file parameter is null or an empty string the result is * returned as a string object. Otherwise an empty string is returned. * You can add objects to the context with the objs Hashtable. * * @param inputTemplate input template * @param outputFile output file * @param objectID id for object to be placed in the control context * @param object object to be placed in the context * @return String generated output from velocity * @throws Exception */ public String parse (String inputTemplate, String outputFile, String objectID, Object object) throws Exception { return parse(inputTemplate, null, outputFile, null, objectID, object); } /** * Parse an input and write the output to an output file. If the * output file parameter is null or an empty string the result is * returned as a string object. Otherwise an empty string is returned. * You can add objects to the context with the objs Hashtable. * * @param inputTemplate input template * @param inputEncoding template encoding * @param outputFile output file * @param outputEncoding outputEncoding encoding of output file * @param objectID id for object to be placed in the control context * @param object object to be placed in the context * @return String generated output from velocity * @throws Exception */ public String parse (String inputTemplate, String inputEncoding, String outputFile, String outputEncoding, String objectID, Object object) throws Exception { if (objectID != null && object != null) { controlContext.put(objectID, object); } Template template = getTemplate(inputTemplate, inputEncoding != null ? inputEncoding : this.inputEncoding); if (outputFile == null || outputFile.equals("")) { StringWriter sw = new StringWriter(); template.merge (controlContext,sw); return sw.toString(); } else { Writer writer = null; if (writers.get(outputFile) == null) { /* * We have never seen this file before so create * a new file writer for it. */ writer = getWriter( getOutputPath() + File.separator + outputFile, outputEncoding != null ? outputEncoding : this.outputEncoding ); /* * Place the file writer in our collection * of file writers. */ writers.put(outputFile, writer); } else { writer = (Writer) writers.get(outputFile); } VelocityContext vc = new VelocityContext( controlContext ); template.merge (vc,writer); // commented because it is closed in shutdown(); //fw.close(); return ""; } } /** * Parse the control template and merge it with the control * context. This is the starting point in texen. * * @param controlTemplate control template * @param controlContext control context * @return String generated output * @throws Exception */ public String parse (String controlTemplate, Context controlContext) throws Exception { this.controlContext = controlContext; fillContextDefaults(this.controlContext); fillContextProperties(this.controlContext); Template template = getTemplate(controlTemplate, inputEncoding); StringWriter sw = new StringWriter(); template.merge (controlContext,sw); return sw.toString(); } /** * Create a new context and fill it with the elements of the * objs Hashtable. Default objects and objects that comes from * the properties of this Generator object is also added. * * @param objs objects to place in the control context * @return Context context filled with objects */ protected Context getContext (Hashtable objs) { fillContextHash (controlContext,objs); return controlContext; } /** * Add all the contents of a Hashtable to the context. * * @param context context to fill with objects * @param objs source of objects */ protected void fillContextHash (Context context, Hashtable objs) { Enumeration enumeration = objs.keys(); while (enumeration.hasMoreElements()) { String key = enumeration.nextElement().toString(); context.put (key, objs.get(key)); } } /** * Add properties that will aways be in the context by default * * @param context control context to fill with default values. */ protected void fillContextDefaults (Context context) { context.put ("generator", instance); context.put ("outputDirectory", getOutputPath()); } /** * Add objects to the context from the current properties. * * @param context control context to fill with objects * that are specified in the default.properties * file */ protected void fillContextProperties (Context context) { Enumeration enumeration = props.propertyNames(); while (enumeration.hasMoreElements()) { String nm = (String) enumeration.nextElement(); if (nm.startsWith ("context.objects.")) { String contextObj = props.getProperty (nm); int colon = nm.lastIndexOf ('.'); String contextName = nm.substring (colon+1); try { Object o = ClassUtils.getNewInstance(contextObj); context.put (contextName,o); } catch (Exception e) { e.printStackTrace(); //TO DO: Log Something Here } } } } /** * Properly shut down the generator, right now * this is simply flushing and closing the file * writers that we have been holding on to. */ public void shutdown() { Iterator iterator = writers.values().iterator(); while(iterator.hasNext()) { Writer writer = (Writer) iterator.next(); try { writer.flush(); } catch (IOException e) { /* do nothing */ } try { writer.close(); } catch (IOException e) { /* do nothing */ } } // clear the file writers cache writers.clear(); } } velocity-1.7/src/java/org/apache/velocity/texen/defaults/0000755000175000017500000000000011675166252023422 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/texen/defaults/texen.properties0000644000175000017500000000175410513464370026662 0ustar moellermoeller# 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. path.output=output context.objects.strings=org.apache.velocity.util.StringUtils context.objects.files=org.apache.velocity.texen.util.FileUtil context.objects.properties=org.apache.velocity.texen.util.PropertiesUtil velocity-1.7/src/java/org/apache/velocity/texen/util/0000755000175000017500000000000011675166252022570 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/texen/util/PropertiesUtil.java0000644000175000017500000001541110567365017026426 0ustar moellermoellerpackage org.apache.velocity.texen.util; /* * 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. */ import java.io.FileInputStream; import java.io.InputStream; import java.util.Properties; import java.util.StringTokenizer; import org.apache.velocity.texen.Generator; /** * A property utility class for the texen text/code generator * Usually this class is only used from a Velocity context. * * @author Leon Messerschmidt * @author Stephane Bailliez * @version $Id: PropertiesUtil.java 510628 2007-02-22 19:07:59Z nbubna $ */ public class PropertiesUtil { /** * Load properties from either a file in the templatePath if there * is one or the classPath. * * @param propertiesFile the properties file to load through * either the templatePath or the classpath. * @return a properties instance filled with the properties found * in the file or an empty instance if no file was found. */ public Properties load(final String propertiesFile) { Properties properties = null; String templatePath = Generator.getInstance().getTemplatePath(); try { if (templatePath != null) { properties = loadFromTemplatePath(propertiesFile); } else { properties = loadFromClassPath(propertiesFile); } } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException("Could not load properties: " + e.getMessage()); } return properties; } /** * Load a properties file from the templatePath defined in the * generator. As the templatePath can contains multiple paths, * it will cycle through them to find the file. The first file * that can be successfully loaded is considered. (kind of * like the java classpath), it is done to clone the Velocity * process of loading templates. * * @param propertiesFile the properties file to load. It must be * a relative pathname. * @return a properties instance loaded with the properties from * the file. If no file can be found it returns an empty instance. * @throws Exception */ protected Properties loadFromTemplatePath(final String propertiesFile) throws Exception { Properties properties = new Properties(); String templatePath = Generator.getInstance().getTemplatePath(); // We might have something like the following: // // #set ($dbprops = $properties.load("$generator.templatePath/path/props") // // as we have in Torque but we want people to start using // // #set ($dbprops = $properties.load("path/props") // // so that everything works from the filesystem or from // a JAR. So the actual Generator.getTemplatePath() // is not deprecated but it's use in templates // should be. StringTokenizer st = new StringTokenizer(templatePath, ","); while (st.hasMoreTokens()) { String templateDir = st.nextToken(); InputStream stream = null; try { // If the properties file is being pulled from the // file system and someone is using the method whereby // the properties file is assumed to be in the template // path and they are simply using: // // #set ($dbprops = $properties.load("props") (1) // // than we have to tack on the templatePath in order // for the properties file to be found. We want (1) // to work whether the generation is being run from // the file system or from a JAR file. String fullPath = propertiesFile; // FIXME probably not that clever since there could be // a mix of file separators and the test will fail :-( if (!fullPath.startsWith(templateDir)) { fullPath = templateDir + "/" + propertiesFile; } stream = new FileInputStream(fullPath); properties.load(stream); // first pick wins, we don't need to go further since // we found a valid file. break; } finally { if (stream != null) { stream.close(); } } } return properties; } /** * Load a properties file from the classpath * * @param propertiesName the properties file to load. * @return a properties instance loaded with the properties from * the file. If no file can be found it returns an empty instance. * @throws Exception */ protected Properties loadFromClassPath(final String propertiesName) throws Exception { Properties properties = new Properties(); ClassLoader classLoader = this.getClass().getClassLoader(); InputStream inputStream = null; try { // This is a hack for now to make sure that properties // files referenced in the filesystem work in // a JAR file. We have to deprecate the use // of $generator.templatePath in templates first // and this hack will allow those same templates // that use $generator.templatePath to work in // JAR files. String propertiesFile = propertiesName.startsWith("$generator") ? propertiesName.substring("$generator.templatePath/".length()) : propertiesName; inputStream = classLoader.getResourceAsStream(propertiesFile); properties.load(inputStream); } finally { if (inputStream != null) { inputStream.close(); } } return properties; } } velocity-1.7/src/java/org/apache/velocity/texen/util/FileUtil.java0000644000175000017500000000424410513464370025144 0ustar moellermoellerpackage org.apache.velocity.texen.util; /* * 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. */ import java.io.File; /** * A general file utility for use in the context * * @author Leon Messerschmidt * @author Jason van Zyl * @version $Id: FileUtil.java 463298 2006-10-12 16:10:32Z henning $ */ public class FileUtil { /** * Creates the directory s (and any parent directories needed). * * @param s path/directory to create. * @return report of path/directory creation. */ static public String mkdir (String s) { try { if ((new File(s)).mkdirs()) return "Created dir: "+s; else return "Failed to create dir or dir already exists: "+s; } catch (Exception e) { return e.toString(); } } /** * A method to get a File object. * * @param s path to file object to create. * @return File created file object. */ public static File file(String s) { File f = new File(s); return f; } /** * A method to get a File object. * * @param base base path * @param s file name * @return File created file object. */ public static File file(String base, String s) { File f = new File(base, s); return f; } } velocity-1.7/src/java/org/apache/velocity/anakia/0000755000175000017500000000000011675166252021714 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/anakia/Escape.java0000644000175000017500000000544210513464370023754 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ /** * This class is for escaping CDATA sections. The code was * "borrowed" from the JDOM code. Also included is escaping * the " -> &quot; character and the conversion of newlines * to the platform line separator. * * @author Will Glass-Husain * @author Jon S. Stevens * @version $Id: Escape.java 463298 2006-10-12 16:10:32Z henning $ */ public class Escape { /** * */ public static final String LINE_SEPARATOR = System.getProperty("line.separator"); /** * Empty constructor */ public Escape() { // left blank on purpose } /** * Do the escaping. * @param st * @return The escaped text. */ public static final String getText(String st) { StringBuffer buff = new StringBuffer(); char[] block = st.toCharArray(); String stEntity = null; int i, last; for (i=0, last=0; i < block.length; i++) { switch(block[i]) { case '<' : stEntity = "<"; break; case '>' : stEntity = ">"; break; case '&' : stEntity = "&"; break; case '"' : stEntity = """; break; case '\n' : stEntity = LINE_SEPARATOR; break; default : /* no-op */ break; } if (stEntity != null) { buff.append(block, last, i - last); buff.append(stEntity); stEntity = null; last = i + 1; } } if(last < block.length) { buff.append(block, last, i - last); } return buff.toString(); } } velocity-1.7/src/java/org/apache/velocity/anakia/NodeList.java0000644000175000017500000003420610513464370024275 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.jdom.Attribute; import org.jdom.CDATA; import org.jdom.Comment; import org.jdom.DocType; import org.jdom.Document; import org.jdom.Element; import org.jdom.EntityRef; import org.jdom.ProcessingInstruction; import org.jdom.Text; import org.jdom.output.XMLOutputter; /** * Provides a class for wrapping a list of JDOM objects primarily for use in template * engines and other kinds of text transformation tools. * It has a {@link #toString()} method that will output the XML serialized form of the * nodes it contains - again focusing on template engine usage, as well as the * {@link #selectNodes(String)} method that helps selecting a different set of nodes * starting from the nodes in this list. The class also implements the {@link java.util.List} * interface by simply delegating calls to the contained list (the {@link #subList(int, int)} * method is implemented by delegating to the contained list and wrapping the returned * sublist into a NodeList). * * @author Attila Szegedi * @version $Id: NodeList.java 463298 2006-10-12 16:10:32Z henning $ */ public class NodeList implements List, Cloneable { private static final AttributeXMLOutputter DEFAULT_OUTPUTTER = new AttributeXMLOutputter(); /** The contained nodes */ private List nodes; /** * Creates an empty node list. */ public NodeList() { nodes = new ArrayList(); } /** * Creates a node list that holds a single {@link Document} node. * @param document */ public NodeList(Document document) { this((Object)document); } /** * Creates a node list that holds a single {@link Element} node. * @param element */ public NodeList(Element element) { this((Object)element); } private NodeList(Object object) { if(object == null) { throw new IllegalArgumentException( "Cannot construct NodeList with null."); } nodes = new ArrayList(1); nodes.add(object); } /** * Creates a node list that holds a list of nodes. * @param nodes the list of nodes this template should hold. The created * template will copy the passed nodes list, so changes to the passed list * will not affect the model. */ public NodeList(List nodes) { this(nodes, true); } /** * Creates a node list that holds a list of nodes. * @param nodes the list of nodes this template should hold. * @param copy if true, the created template will copy the passed nodes * list, so changes to the passed list will not affect the model. If false, * the model will reference the passed list and will sense changes in it, * altough no operations on the list will be synchronized. */ public NodeList(List nodes, boolean copy) { if(nodes == null) { throw new IllegalArgumentException( "Cannot initialize NodeList with null list"); } this.nodes = copy ? new ArrayList(nodes) : nodes; } /** * Retrieves the underlying list used to store the nodes. Note however, that * you can fully use the underlying list through the List interface * of this class itself. You would probably access the underlying list only for * synchronization purposes. * @return The internal node List. */ public List getList() { return nodes; } /** * This method returns the string resulting from concatenation of string * representations of its nodes. Each node is rendered using its XML * serialization format. This greatly simplifies creating XML-transformation * templates, as to output a node contained in variable x as XML fragment, * you simply write ${x} in the template (or whatever your template engine * uses as its expression syntax). * @return The Nodelist as printable object. */ public String toString() { if(nodes.isEmpty()) { return ""; } StringWriter sw = new StringWriter(nodes.size() * 128); try { for(Iterator i = nodes.iterator(); i.hasNext();) { Object node = i.next(); if(node instanceof Element) { DEFAULT_OUTPUTTER.output((Element)node, sw); } else if(node instanceof Attribute) { DEFAULT_OUTPUTTER.output((Attribute)node, sw); } else if(node instanceof Text) { DEFAULT_OUTPUTTER.output((Text)node, sw); } else if(node instanceof Document) { DEFAULT_OUTPUTTER.output((Document)node, sw); } else if(node instanceof ProcessingInstruction) { DEFAULT_OUTPUTTER.output((ProcessingInstruction)node, sw); } else if(node instanceof Comment) { DEFAULT_OUTPUTTER.output((Comment)node, sw); } else if(node instanceof CDATA) { DEFAULT_OUTPUTTER.output((CDATA)node, sw); } else if(node instanceof DocType) { DEFAULT_OUTPUTTER.output((DocType)node, sw); } else if(node instanceof EntityRef) { DEFAULT_OUTPUTTER.output((EntityRef)node, sw); } else { throw new IllegalArgumentException( "Cannot process a " + (node == null ? "null node" : "node of class " + node.getClass().getName())); } } } catch(IOException e) { // Cannot happen as we work with a StringWriter in memory throw new Error(); } return sw.toString(); } /** * Returns a NodeList that contains the same nodes as this node list. * @return A clone of this list. * @throws CloneNotSupportedException if the contained list's class does * not have an accessible no-arg constructor. */ public Object clone() throws CloneNotSupportedException { NodeList clonedList = (NodeList)super.clone(); clonedList.cloneNodes(); return clonedList; } private void cloneNodes() throws CloneNotSupportedException { Class listClass = nodes.getClass(); try { List clonedNodes = (List)listClass.newInstance(); clonedNodes.addAll(nodes); nodes = clonedNodes; } catch(IllegalAccessException e) { throw new CloneNotSupportedException("Cannot clone NodeList since" + " there is no accessible no-arg constructor on class " + listClass.getName()); } catch(InstantiationException e) { // Cannot happen as listClass represents a concrete, non-primitive, // non-array, non-void class - there's an instance of it in "nodes" // which proves these assumptions. throw new Error(); } } /** * Returns the hash code of the contained list. * @return The hashcode of the list. */ public int hashCode() { return nodes.hashCode(); } /** * Tests for equality with another object. * @param o the object to test for equality * @return true if the other object is also a NodeList and their contained * {@link List} objects evaluate as equals. */ public boolean equals(Object o) { return o instanceof NodeList ? ((NodeList)o).nodes.equals(nodes) : false; } /** * Applies an XPath expression to the node list and returns the resulting * node list. In order for this method to work, your application must have * access to werken.xpath library * classes. The implementation does cache the parsed format of XPath * expressions in a weak hash map, keyed by the string representation of * the XPath expression. As the string object passed as the argument is * usually kept in the parsed template, this ensures that each XPath * expression is parsed only once during the lifetime of the template that * first invoked it. * @param xpathString the XPath expression you wish to apply * @return a NodeList representing the nodes that are the result of * application of the XPath to the current node list. It can be empty. */ public NodeList selectNodes(String xpathString) { return new NodeList(XPathCache.getXPath(xpathString).applyTo(nodes), false); } // List methods implemented hereafter /** * @see java.util.List#add(java.lang.Object) */ public boolean add(Object o) { return nodes.add(o); } /** * @see java.util.List#add(int, java.lang.Object) */ public void add(int index, Object o) { nodes.add(index, o); } /** * @see java.util.List#addAll(java.util.Collection) */ public boolean addAll(Collection c) { return nodes.addAll(c); } /** * @see java.util.List#addAll(int, java.util.Collection) */ public boolean addAll(int index, Collection c) { return nodes.addAll(index, c); } /** * @see java.util.List#clear() */ public void clear() { nodes.clear(); } /** * @see java.util.List#contains(java.lang.Object) */ public boolean contains(Object o) { return nodes.contains(o); } /** * @see java.util.List#containsAll(java.util.Collection) */ public boolean containsAll(Collection c) { return nodes.containsAll(c); } /** * @see java.util.List#get(int) */ public Object get(int index) { return nodes.get(index); } /** * @see java.util.List#indexOf(java.lang.Object) */ public int indexOf(Object o) { return nodes.indexOf(o); } /** * @see java.util.List#isEmpty() */ public boolean isEmpty() { return nodes.isEmpty(); } /** * @see java.util.List#iterator() */ public Iterator iterator() { return nodes.iterator(); } /** * @see java.util.List#lastIndexOf(java.lang.Object) */ public int lastIndexOf(Object o) { return nodes.lastIndexOf(o); } /** * @see java.util.List#listIterator() */ public ListIterator listIterator() { return nodes.listIterator(); } /** * @see java.util.List#listIterator(int) */ public ListIterator listIterator(int index) { return nodes.listIterator(index); } /** * @see java.util.List#remove(int) */ public Object remove(int index) { return nodes.remove(index); } /** * @see java.util.List#remove(java.lang.Object) */ public boolean remove(Object o) { return nodes.remove(o); } /** * @see java.util.List#removeAll(java.util.Collection) */ public boolean removeAll(Collection c) { return nodes.removeAll(c); } /** * @see java.util.List#retainAll(java.util.Collection) */ public boolean retainAll(Collection c) { return nodes.retainAll(c); } /** * @see java.util.List#set(int, java.lang.Object) */ public Object set(int index, Object o) { return nodes.set(index, o); } /** * @see java.util.List#size() */ public int size() { return nodes.size(); } /** * @see java.util.List#subList(int, int) */ public List subList(int fromIndex, int toIndex) { return new NodeList(nodes.subList(fromIndex, toIndex)); } /** * @see java.util.List#toArray() */ public Object[] toArray() { return nodes.toArray(); } /** * @see java.util.List#toArray(java.lang.Object[]) */ public Object[] toArray(Object[] a) { return nodes.toArray(a); } /** * A special subclass of XMLOutputter that will be used to output * Attribute nodes. As a subclass of XMLOutputter it can use its protected * method escapeAttributeEntities() to serialize the attribute * appropriately. */ private static final class AttributeXMLOutputter extends XMLOutputter { /** * @param attribute * @param out * @throws IOException */ public void output(Attribute attribute, Writer out) throws IOException { out.write(" "); out.write(attribute.getQualifiedName()); out.write("="); out.write("\""); out.write(escapeAttributeEntities(attribute.getValue())); out.write("\""); } } } velocity-1.7/src/java/org/apache/velocity/anakia/OutputWrapper.java0000644000175000017500000000435710513464370025421 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import java.io.IOException; import java.io.StringWriter; import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.jdom.output.Format; /** * This class extends XMLOutputter in order to provide * a way to walk an Element tree into a String. * * @author Jon S. Stevens * @author Sam Ruby * @version $Id: OutputWrapper.java 463298 2006-10-12 16:10:32Z henning $ */ public class OutputWrapper extends XMLOutputter { /** * Empty constructor */ public OutputWrapper() { } /** * @param f */ public OutputWrapper(Format f) { super(f); } /** * This method walks an Element tree into a String. The cool * thing about it is that it will strip off the first Element. * For example, if you have: *

      * <td> foo <strong>bar</strong> ack </td> *

      * It will output *

      * foo <strong>bar</strong> ack </td> *

      * @param element * @param strip * @return The output string. */ public String outputString(Element element, boolean strip) { StringWriter buff = new StringWriter(); try { outputElementContent(element, buff); } catch (IOException e) { } return buff.toString(); } } velocity-1.7/src/java/org/apache/velocity/anakia/XPathTool.java0000644000175000017500000000773610513464370024446 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import java.util.List; import org.jdom.Document; import org.jdom.Element; /** * This class adds an entrypoint into XPath functionality, * for Anakia. *

      * All methods take a string XPath specification, along with * a context, and produces a resulting java.util.List. *

      * The W3C XPath Specification (http://www.w3.org/TR/xpath) refers * to NodeSets repeatedly, but this implementation simply uses * java.util.List to hold all Nodes. A 'Node' is any object in * a JDOM object tree, such as an org.jdom.Element, org.jdom.Document, * or org.jdom.Attribute. *

      * To use it in Velocity, do this: *

      *

       * #set $authors = $xpath.applyTo("document/author", $root)
       * #foreach ($author in $authors)
       *   $author.getValue()
       * #end
       * #set $chapterTitles = $xpath.applyTo("document/chapter/@title", $root)
       * #foreach ($title in $chapterTitles)
       *   $title.getValue()
       * #end
       * 
      *

      * In newer Anakia builds, this class is obsoleted in favor of calling * selectNodes() on the element directly: *

       * #set $authors = $root.selectNodes("document/author")
       * #foreach ($author in $authors)
       *   $author.getValue()
       * #end
       * #set $chapterTitles = $root.selectNodes("document/chapter/@title")
       * #foreach ($title in $chapterTitles)
       *   $title.getValue()
       * #end
       * 
      *

      * * @author bob mcwhirter * @author Jon S. Stevens * @author Attila Szegedi * @version $Id: XPathTool.java 463298 2006-10-12 16:10:32Z henning $ */ public class XPathTool { /** * Constructor does nothing, as this is mostly * just objectified static methods */ public XPathTool() { // RuntimeSingleton.info("XPathTool::XPathTool()"); // intentionally left blank } /** * Apply an XPath to a JDOM Document * * @param xpathSpec The XPath to apply * @param doc The Document context * * @return A list of selected nodes */ public NodeList applyTo(String xpathSpec, Document doc) { //RuntimeSingleton.info("XPathTool::applyTo(String, Document)"); return new NodeList(XPathCache.getXPath(xpathSpec).applyTo( doc ), false); } /** * Apply an XPath to a JDOM Element * * @param xpathSpec The XPath to apply * @param elem The Element context * * @return A list of selected nodes */ public NodeList applyTo(String xpathSpec, Element elem) { //RuntimeSingleton.info("XPathTool::applyTo(String, Element)"); return new NodeList(XPathCache.getXPath(xpathSpec).applyTo( elem ), false); } /** * Apply an XPath to a nodeset * * @param xpathSpec The XPath to apply * @param nodeSet The nodeset context * * @return A list of selected nodes */ public NodeList applyTo(String xpathSpec, List nodeSet) { //RuntimeSingleton.info("XPathTool::applyTo(String, List)"); return new NodeList(XPathCache.getXPath(xpathSpec).applyTo( nodeSet ), false); } } velocity-1.7/src/java/org/apache/velocity/anakia/TreeWalker.java0000644000175000017500000000472410513464370024623 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.jdom.Element; /** * This class allows you to walk a tree of JDOM Element objects. * It first walks the tree itself starting at the Element passed * into allElements() and stores each node of the tree * in a Vector which allElements() returns as a result of its * execution. You can then use a #foreach in Velocity to walk * over the Vector and visit each Element node. However, you can * achieve the same effect by calling element.selectNodes("//*"). * * @author Jon S. Stevens * @author Attila Szegedi * @version $Id: TreeWalker.java 463298 2006-10-12 16:10:32Z henning $ */ public class TreeWalker { /** * Empty constructor */ public TreeWalker() { // Left blank } /** * Creates a new Vector and walks the Element tree. * * @param e the starting Element node * @return Vector a vector of Element nodes */ public NodeList allElements(Element e) { ArrayList theElements = new ArrayList(); treeWalk (e, theElements); return new NodeList(theElements, false); } /** * A recursive method to walk the Element tree. * @param Element the current Element */ private final void treeWalk(Element e, Collection theElements ) { for (Iterator i=e.getChildren().iterator(); i.hasNext(); ) { Element child = (Element)i.next(); theElements.add(child); treeWalk(child, theElements); } } } velocity-1.7/src/java/org/apache/velocity/anakia/AnakiaJDOMFactory.java0000644000175000017500000000426310513464370025742 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import org.jdom.Element; import org.jdom.Namespace; import org.jdom.DefaultJDOMFactory; /** * A customized JDOMFactory for Anakia that produces {@link AnakiaElement} * instances instead of ordinary JDOM {@link Element} instances. * * @author Attila Szegedi * @version $Id: AnakiaJDOMFactory.java 463298 2006-10-12 16:10:32Z henning $ */ public class AnakiaJDOMFactory extends DefaultJDOMFactory { /** * */ public AnakiaJDOMFactory() { } /** * @see org.jdom.DefaultJDOMFactory#element(java.lang.String, org.jdom.Namespace) */ public Element element(String name, Namespace namespace) { return new AnakiaElement(name, namespace); } /** * @see org.jdom.DefaultJDOMFactory#element(java.lang.String) */ public Element element(String name) { return new AnakiaElement(name); } /** * @see org.jdom.DefaultJDOMFactory#element(java.lang.String, java.lang.String) */ public Element element(String name, String uri) { return new AnakiaElement(name, uri); } /** * @see org.jdom.DefaultJDOMFactory#element(java.lang.String, java.lang.String, java.lang.String) */ public Element element(String name, String prefix, String uri) { return new AnakiaElement(name, prefix, uri); } } velocity-1.7/src/java/org/apache/velocity/anakia/AnakiaTask.java0000644000175000017500000004606710557734552024605 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import org.apache.commons.collections.ExtendedProperties; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; 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.util.StringUtils; import org.jdom.Document; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.xml.sax.SAXParseException; /** * The purpose of this Ant Task is to allow you to use * Velocity as an XML transformation tool like XSLT is. * So, instead of using XSLT, you will be able to use this * class instead to do your transformations. It works very * similar in concept to Ant's <style> task. *

      * You can find more documentation about this class on the * Velocity * Website. * * @author Jon S. Stevens * @author Attila Szegedi * @version $Id: AnakiaTask.java 501574 2007-01-30 21:32:26Z henning $ */ public class AnakiaTask extends MatchingTask { /** {@link SAXBuilder} instance to use */ SAXBuilder builder; /** the destination directory */ private File destDir = null; /** the base directory */ File baseDir = null; /** the style= attribute */ private String style = null; /** last modified of the style sheet */ private long styleSheetLastModified = 0; /** the projectFile= attribute */ private String projectAttribute = null; /** the File for the project.xml file */ private File projectFile = null; /** last modified of the project file if it exists */ private long projectFileLastModified = 0; /** check the last modified date on files. defaults to true */ private boolean lastModifiedCheck = true; /** the default output extension is .html */ private String extension = ".html"; /** the template path */ private String templatePath = null; /** the file to get the velocity properties file */ private File velocityPropertiesFile = null; /** the VelocityEngine instance to use */ private VelocityEngine ve = new VelocityEngine(); /** the Velocity subcontexts */ private List contexts = new LinkedList(); /** * Constructor creates the SAXBuilder. */ public AnakiaTask() { builder = new SAXBuilder(); builder.setFactory(new AnakiaJDOMFactory()); } /** * Set the base directory. * @param dir */ public void setBasedir(File dir) { baseDir = dir; } /** * Set the destination directory into which the VSL result * files should be copied to * @param dir the name of the destination directory */ public void setDestdir(File dir) { destDir = dir; } /** * Allow people to set the default output file extension * @param extension */ public void setExtension(String extension) { this.extension = extension; } /** * Allow people to set the path to the .vsl file * @param style */ public void setStyle(String style) { this.style = style; } /** * Allow people to set the path to the project.xml file * @param projectAttribute */ public void setProjectFile(String projectAttribute) { this.projectAttribute = projectAttribute; } /** * Set the path to the templates. * The way it works is this: * If you have a Velocity.properties file defined, this method * will override whatever is set in the * Velocity.properties file. This allows one to not have to define * a Velocity.properties file, therefore using Velocity's defaults * only. * @param templatePath */ public void setTemplatePath(File templatePath) { try { this.templatePath = templatePath.getCanonicalPath(); } catch (java.io.IOException ioe) { throw new BuildException(ioe); } } /** * Allow people to set the path to the velocity.properties file * This file is found relative to the path where the JVM was run. * For example, if build.sh was executed in the ./build directory, * then the path would be relative to this directory. * This is optional based on the setting of setTemplatePath(). * @param velocityPropertiesFile */ public void setVelocityPropertiesFile(File velocityPropertiesFile) { this.velocityPropertiesFile = velocityPropertiesFile; } /** * Turn on/off last modified checking. by default, it is on. * @param lastmod */ public void setLastModifiedCheck(String lastmod) { if (lastmod.equalsIgnoreCase("false") || lastmod.equalsIgnoreCase("no") || lastmod.equalsIgnoreCase("off")) { this.lastModifiedCheck = false; } } /** * Main body of the application * @throws BuildException */ public void execute () throws BuildException { DirectoryScanner scanner; String[] list; if (baseDir == null) { baseDir = project.resolveFile("."); } if (destDir == null ) { String msg = "destdir attribute must be set!"; throw new BuildException(msg); } if (style == null) { throw new BuildException("style attribute must be set!"); } if (velocityPropertiesFile == null) { velocityPropertiesFile = new File("velocity.properties"); } /* * If the props file doesn't exist AND a templatePath hasn't * been defined, then throw the exception. */ if ( !velocityPropertiesFile.exists() && templatePath == null ) { throw new BuildException ("No template path and could not " + "locate velocity.properties file: " + velocityPropertiesFile.getAbsolutePath()); } log("Transforming into: " + destDir.getAbsolutePath(), Project.MSG_INFO); // projectFile relative to baseDir if (projectAttribute != null && projectAttribute.length() > 0) { projectFile = new File(baseDir, projectAttribute); if (projectFile.exists()) { projectFileLastModified = projectFile.lastModified(); } else { log ("Project file is defined, but could not be located: " + projectFile.getAbsolutePath(), Project.MSG_INFO ); projectFile = null; } } Document projectDocument = null; try { if ( velocityPropertiesFile.exists() ) { String file = velocityPropertiesFile.getAbsolutePath(); ExtendedProperties config = new ExtendedProperties(file); ve.setExtendedProperties(config); } // override the templatePath if it exists if (templatePath != null && templatePath.length() > 0) { ve.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath); } ve.init(); // get the last modification of the VSL stylesheet styleSheetLastModified = ve.getTemplate( style ).getLastModified(); // Build the Project file document if (projectFile != null) { projectDocument = builder.build(projectFile); } } catch (Exception e) { log("Error: " + e.toString(), Project.MSG_INFO); throw new BuildException(e); } // find the files/directories scanner = getDirectoryScanner(baseDir); // get a list of files to work on list = scanner.getIncludedFiles(); for (int i = 0;i < list.length; ++i) { process(list[i], projectDocument ); } } /** * Process an XML file using Velocity */ private void process(String xmlFile, Document projectDocument) throws BuildException { File outFile=null; File inFile=null; Writer writer = null; try { // the current input file relative to the baseDir inFile = new File(baseDir,xmlFile); // the output file relative to basedir outFile = new File(destDir, xmlFile.substring(0, xmlFile.lastIndexOf('.')) + extension); // only process files that have changed if (lastModifiedCheck == false || (inFile.lastModified() > outFile.lastModified() || styleSheetLastModified > outFile.lastModified() || projectFileLastModified > outFile.lastModified() || userContextsModifed(outFile.lastModified()))) { ensureDirectoryFor( outFile ); //-- command line status log("Input: " + xmlFile, Project.MSG_INFO ); // Build the JDOM Document Document root = builder.build(inFile); // Shove things into the Context VelocityContext context = new VelocityContext(); /* * get the property TEMPLATE_ENCODING * we know it's a string... */ String encoding = (String) ve.getProperty( RuntimeConstants.OUTPUT_ENCODING ); if (encoding == null || encoding.length() == 0 || encoding.equals("8859-1") || encoding.equals("8859_1")) { encoding = "ISO-8859-1"; } Format f = Format.getRawFormat(); f.setEncoding(encoding); OutputWrapper ow = new OutputWrapper(f); context.put ("root", root.getRootElement()); context.put ("xmlout", ow ); context.put ("relativePath", getRelativePath(xmlFile)); context.put ("treeWalk", new TreeWalker()); context.put ("xpath", new XPathTool() ); context.put ("escape", new Escape() ); context.put ("date", new java.util.Date() ); /** * only put this into the context if it exists. */ if (projectDocument != null) { context.put ("project", projectDocument.getRootElement()); } /** * Add the user subcontexts to the to context */ for (Iterator iter = contexts.iterator(); iter.hasNext();) { Context subContext = (Context) iter.next(); if (subContext == null) { throw new BuildException("Found an undefined SubContext!"); } if (subContext.getContextDocument() == null) { throw new BuildException("Could not build a subContext for " + subContext.getName()); } context.put(subContext.getName(), subContext .getContextDocument().getRootElement()); } /** * Process the VSL template with the context and write out * the result as the outFile. */ writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(outFile), encoding)); /** * get the template to process */ Template template = ve.getTemplate(style); template.merge(context, writer); log("Output: " + outFile, Project.MSG_INFO ); } } catch (JDOMException e) { outFile.delete(); if (e.getCause() != null) { Throwable rootCause = e.getCause(); if (rootCause instanceof SAXParseException) { System.out.println(""); System.out.println("Error: " + rootCause.getMessage()); System.out.println( " Line: " + ((SAXParseException)rootCause).getLineNumber() + " Column: " + ((SAXParseException)rootCause).getColumnNumber()); System.out.println(""); } else { rootCause.printStackTrace(); } } else { e.printStackTrace(); } } catch (Throwable e) { if (outFile != null) { outFile.delete(); } e.printStackTrace(); } finally { if (writer != null) { try { writer.flush(); } catch (IOException e) { // Do nothing } try { writer.close(); } catch (IOException e) { // Do nothing } } } } /** * Hacky method to figure out the relative path * that we are currently in. This is good for getting * the relative path for images and anchor's. */ private String getRelativePath(String file) { if (file == null || file.length()==0) return ""; StringTokenizer st = new StringTokenizer(file, "/\\"); // needs to be -1 cause ST returns 1 even if there are no matches. huh? int slashCount = st.countTokens() - 1; StringBuffer sb = new StringBuffer(); for (int i=0;i 0) { return StringUtils.chop(sb.toString(), 1); } return "."; } /** * create directories as needed */ private void ensureDirectoryFor( File targetFile ) throws BuildException { File directory = new File( targetFile.getParent() ); if (!directory.exists()) { if (!directory.mkdirs()) { throw new BuildException("Unable to create directory: " + directory.getAbsolutePath() ); } } } /** * Check to see if user context is modified. */ private boolean userContextsModifed(long lastModified) { for (Iterator iter = contexts.iterator(); iter.hasNext();) { AnakiaTask.Context ctx = (AnakiaTask.Context) iter.next(); if(ctx.getLastModified() > lastModified) { return true; } } return false; } /** * Create a new context. * @return A new context. */ public Context createContext() { Context context = new Context(); contexts.add(context); return context; } /** * A context implementation that loads all values from an XML file. */ public class Context { private String name; private Document contextDoc = null; private String file; /** * Public constructor. */ public Context() { } /** * Get the name of the context. * @return The name of the context. */ public String getName() { return name; } /** * Set the name of the context. * @param name * * @throws IllegalArgumentException if a reserved word is used as a * name, specifically any of "relativePath", "treeWalk", "xpath", * "escape", "date", or "project" */ public void setName(String name) { if (name.equals("relativePath") || name.equals("treeWalk") || name.equals("xpath") || name.equals("escape") || name.equals("date") || name.equals("project")) { throw new IllegalArgumentException("Context name '" + name + "' is reserved by Anakia"); } this.name = name; } /** * Build the context based on a file path. * @param file */ public void setFile(String file) { this.file = file; } /** * Retrieve the time the source file was last modified. * @return The time the source file was last modified. */ public long getLastModified() { return new File(baseDir, file).lastModified(); } /** * Retrieve the context document object. * @return The context document object. */ public Document getContextDocument() { if (contextDoc == null) { File contextFile = new File(baseDir, file); try { contextDoc = builder.build(contextFile); } catch (Exception e) { throw new BuildException(e); } } return contextDoc; } } } velocity-1.7/src/java/org/apache/velocity/anakia/XPathCache.java0000644000175000017500000000422610513464370024523 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import com.werken.xpath.XPath; import java.util.Map; import java.util.WeakHashMap; /** * Provides a cache for XPath expressions. Used by {@link NodeList} and * {@link AnakiaElement} to minimize XPath parsing in their * selectNodes() methods. * * @author Attila Szegedi * @version $Id: XPathCache.java 463298 2006-10-12 16:10:32Z henning $ */ class XPathCache { // Cache of already parsed XPath expressions, keyed by String representations // of the expression as passed to getXPath(). private static final Map XPATH_CACHE = new WeakHashMap(); private XPathCache() { } /** * Returns an XPath object representing the requested XPath expression. * A cached object is returned if it already exists for the requested expression. * @param xpathString the XPath expression to parse * @return the XPath object that represents the parsed XPath expression. */ static XPath getXPath(String xpathString) { XPath xpath = null; synchronized(XPATH_CACHE) { xpath = (XPath)XPATH_CACHE.get(xpathString); if(xpath == null) { xpath = new XPath(xpathString); XPATH_CACHE.put(xpathString, xpath); } } return xpath; } } velocity-1.7/src/java/org/apache/velocity/anakia/AnakiaElement.java0000644000175000017500000002233310513464370025250 0ustar moellermoellerpackage org.apache.velocity.anakia; /* * 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. */ import org.jdom.Element; import org.jdom.Namespace; import org.jdom.output.XMLOutputter; import java.util.List; /** * A JDOM {@link Element} that is tailored for Anakia needs. It has * {@link #selectNodes(String)} method as well as a {@link #toString()} that * outputs the XML serialized form of the element. This way it acts in much the * same way as a single-element {@link NodeList} would. * * @author Attila Szegedi * @version $Id: AnakiaElement.java 463298 2006-10-12 16:10:32Z henning $ */ public class AnakiaElement extends Element { /** * Version Id for serializable */ private static final long serialVersionUID = 8429597252274491314L; private static final XMLOutputter DEFAULT_OUTPUTTER = new XMLOutputter(); static { DEFAULT_OUTPUTTER.getFormat().setLineSeparator(System.getProperty("line.separator")); } /** *

      * This will create a new AnakiaElement * with the supplied (local) name, and define * the {@link Namespace} to be used. * If the provided namespace is null, the element will have * no namespace. *

      * * @param name String name of element. * @param namespace Namespace to put element in. */ public AnakiaElement(String name, Namespace namespace) { super(name, namespace); } /** *

      * This will create an AnakiaElement in no * {@link Namespace}. *

      * * @param name String name of element. */ public AnakiaElement(String name) { super(name); } /** *

      * This will create a new AnakiaElement with * the supplied (local) name, and specifies the URI * of the {@link Namespace} the Element * should be in, resulting it being unprefixed (in the default * namespace). *

      * * @param name String name of element. * @param uri String URI for Namespace element * should be in. */ public AnakiaElement(String name, String uri) { super(name, uri); } /** *

      * This will create a new AnakiaElement with * the supplied (local) name, and specifies the prefix and URI * of the {@link Namespace} the Element * should be in. *

      * * @param name String name of element. * @param prefix The prefix of the element. * @param uri String URI for Namespace element * should be in. */ public AnakiaElement(String name, String prefix, String uri) { super(name, prefix, uri); } /** * Applies an XPath expression to this element and returns the resulting * node list. In order for this method to work, your application must have * access to werken.xpath library * classes. The implementation does cache the parsed format of XPath * expressions in a weak hash map, keyed by the string representation of * the XPath expression. As the string object passed as the argument is * usually kept in the parsed template, this ensures that each XPath * expression is parsed only once during the lifetime of the template that * first invoked it. * @param xpathExpression the XPath expression you wish to apply * @return a NodeList representing the nodes that are the result of * application of the XPath to the current element. It can be empty. */ public NodeList selectNodes(String xpathExpression) { return new NodeList(XPathCache.getXPath(xpathExpression).applyTo(this), false); } /** * Returns the XML serialized form of this element, as produced by the default * {@link XMLOutputter}. * @return The XML serialized form of this element, as produced by the default * {@link XMLOutputter}. */ public String toString() { return DEFAULT_OUTPUTTER.outputString(this); } /** *

      * This returns the full content of the element as a NodeList which * may contain objects of type String, Element, * Comment, ProcessingInstruction, * CDATA, and EntityRef. * The List returned is "live" in document order and modifications * to it affect the element's actual contents. Whitespace content is * returned in its entirety. *

      * * @return a List containing the mixed content of the * element: may contain String, * {@link Element}, {@link org.jdom.Comment}, * {@link org.jdom.ProcessingInstruction}, * {@link org.jdom.CDATA}, and * {@link org.jdom.EntityRef} objects. */ public List getContent() { return new NodeList(super.getContent(), false); } /** *

      * This returns a NodeList of all the child elements * nested directly (one level deep) within this element, as * Element objects. If this target element has no nested * elements, an empty List is returned. The returned list is "live" * in document order and changes to it affect the element's actual * contents. *

      *

      * This performs no recursion, so elements nested two levels * deep would have to be obtained with: *

           * 
           *   Iterator itr = currentElement.getChildren().iterator();
           *   while (itr.hasNext()) {
           *     Element oneLevelDeep = (Element)nestedElements.next();
           *     List twoLevelsDeep = oneLevelDeep.getChildren();
           *     // Do something with these children
           *   }
           * 
           * 
      *

      * * @return list of child Element objects for this element */ public List getChildren() { return new NodeList(super.getChildren(), false); } /** *

      * This returns a NodeList of all the child elements * nested directly (one level deep) within this element with the given * local name and belonging to no namespace, returned as * Element objects. If this target element has no nested * elements with the given name outside a namespace, an empty List * is returned. The returned list is "live" in document order * and changes to it affect the element's actual contents. *

      *

      * Please see the notes for {@link #getChildren()} * for a code example. *

      * * @param name local name for the children to match * @return all matching child elements */ public List getChildren(String name) { return new NodeList(super.getChildren(name)); } /** *

      * This returns a NodeList of all the child elements * nested directly (one level deep) within this element with the given * local name and belonging to the given Namespace, returned as * Element objects. If this target element has no nested * elements with the given name in the given Namespace, an empty List * is returned. The returned list is "live" in document order * and changes to it affect the element's actual contents. *

      *

      * Please see the notes for {@link #getChildren()} * for a code example. *

      * * @param name local name for the children to match * @param ns Namespace to search within * @return all matching child elements */ public List getChildren(String name, Namespace ns) { return new NodeList(super.getChildren(name, ns)); } /** *

      * This returns the complete set of attributes for this element, as a * NodeList of Attribute objects in no particular * order, or an empty list if there are none. * The returned list is "live" and changes to it affect the * element's actual attributes. *

      * * @return attributes for the element */ public List getAttributes() { return new NodeList(super.getAttributes()); } } velocity-1.7/src/java/org/apache/velocity/context/0000755000175000017500000000000011675166252022154 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/context/InternalContextAdapter.java0000644000175000017500000000251310513464370027432 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ /** * interface to bring all necessary internal and user contexts together. * this is what the AST expects to deal with. If anything new comes * along, add it here. * * I will rename soon :) * * @author Geir Magnusson Jr. * @version $Id: InternalContextAdapter.java 463298 2006-10-12 16:10:32Z henning $ */ public interface InternalContextAdapter extends InternalHousekeepingContext, Context, InternalWrapperContext, InternalEventContext { } velocity-1.7/src/java/org/apache/velocity/context/InternalWrapperContext.java0000644000175000017500000000342510523734640027476 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ /** * interface for internal context wrapping functionality * * @author Geir Magnusson Jr. * @version $Id: InternalWrapperContext.java 471908 2006-11-06 22:39:28Z henning $ */ public interface InternalWrapperContext { /** * Returns the wrapped user context. * @return The wrapped user context. */ Context getInternalUserContext(); /** * Returns the base full context impl. * @return The base full context impl. * */ InternalContextAdapter getBaseContext(); /** * Allows callers to explicitly put objects in the local context. * Objects added to the context through this method always end up * in the top-level context of possible wrapped contexts. * * @param key name of item to set. * @param value object to set to key. * @return old stored object */ Object localPut(final String key, final Object value); } velocity-1.7/src/java/org/apache/velocity/context/InternalEventContext.java0000644000175000017500000000276710513464370027146 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import org.apache.velocity.app.event.EventCartridge; /** * Interface for event support. Note that this is a public internal * interface, as it is something that will be accessed from outside * of the .context package. * * @author Geir Magnusson Jr. * @version $Id: InternalEventContext.java 463298 2006-10-12 16:10:32Z henning $ */ public interface InternalEventContext { /** * @param ec * @return The old EventCartridge. */ public EventCartridge attachEventCartridge( EventCartridge ec); /** * @return The current EventCartridge. */ public EventCartridge getEventCartridge(); } velocity-1.7/src/java/org/apache/velocity/context/Context.java0000644000175000017500000000520010513464370024430 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ /** * Interface describing the application data context. This set of * routines is used by the application to set and remove 'named' data * object to pass them to the template engine to use when rendering * a template. * * This is the same set of methods supported by the original Context * class * * @see org.apache.velocity.context.AbstractContext * @see org.apache.velocity.VelocityContext * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: Context.java 463298 2006-10-12 16:10:32Z henning $ */ public interface Context { /** * Adds a name/value pair to the context. * * @param key The name to key the provided value with. * @param value The corresponding value. * @return The old object or null if there was no old object. */ Object put(String key, Object value); /** * Gets the value corresponding to the provided key from the context. * * @param key The name of the desired value. * @return The value corresponding to the provided key. */ Object get(String key); /** * Indicates whether the specified key is in the context. * * @param key The key to look for. * @return Whether the key is in the context. */ boolean containsKey(Object key); /** * Get all the keys for the values in the context. * @return All the keys for the values in the context. */ Object[] getKeys(); /** * Removes the value associated with the specified key from the context. * * @param key The name of the value to remove. * @return The value that the key was mapped to, or null * if unmapped. */ Object remove(Object key); } velocity-1.7/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java0000644000175000017500000002350411130150630030242 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.util.introspection.IntrospectionCacheData; import java.util.List; /** * This adapter class is the container for all context types for internal * use. The AST now uses this class rather than the app-level Context * interface to allow flexibility in the future. * * Currently, we have two context interfaces which must be supported : *
        *
      • Context : used for application/template data access *
      • InternalHousekeepingContext : used for internal housekeeping and caching *
      • InternalWrapperContext : used for getting root cache context and other * such. *
      • InternalEventContext : for event handling. *
      * * This class implements the two interfaces to ensure that all methods are * supported. When adding to the interfaces, or adding more context * functionality, the interface is the primary definition, so alter that first * and then all classes as necessary. As of this writing, this would be * the only class affected by changes to InternalContext * * This class ensures that an InternalContextBase is available for internal * use. If an application constructs their own Context-implementing * object w/o subclassing AbstractContext, it may be that support for * InternalContext is not available. Therefore, InternalContextAdapter will * create an InternalContextBase if necessary for this support. Note that * if this is necessary, internal information such as node-cache data will be * lost from use to use of the context. This may or may not be important, * depending upon application. * * * @author Geir Magnusson Jr. * @version $Id: InternalContextAdapterImpl.java 731266 2009-01-04 15:11:20Z byron $ */ public final class InternalContextAdapterImpl implements InternalContextAdapter { /** * the user data Context that we are wrapping */ Context context = null; /** * the ICB we are wrapping. We may need to make one * if the user data context implementation doesn't * support one. The default AbstractContext-derived * VelocityContext does, and it's recommended that * people derive new contexts from AbstractContext * rather than piecing things together */ InternalHousekeepingContext icb = null; /** * The InternalEventContext that we are wrapping. If * the context passed to us doesn't support it, no * biggie. We don't make it for them - since its a * user context thing, nothing gained by making one * for them now */ InternalEventContext iec = null; /** * CTOR takes a Context and wraps it, delegating all 'data' calls * to it. * * For support of internal contexts, it will create an InternalContextBase * if need be. * @param c */ public InternalContextAdapterImpl( Context c ) { context = c; if ( !( c instanceof InternalHousekeepingContext )) { icb = new InternalContextBase(); } else { icb = (InternalHousekeepingContext) context; } if ( c instanceof InternalEventContext) { iec = ( InternalEventContext) context; } } /* --- InternalHousekeepingContext interface methods --- */ /** * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentTemplateName(java.lang.String) */ public void pushCurrentTemplateName( String s ) { icb.pushCurrentTemplateName( s ); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentTemplateName() */ public void popCurrentTemplateName() { icb.popCurrentTemplateName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentTemplateName() */ public String getCurrentTemplateName() { return icb.getCurrentTemplateName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getTemplateNameStack() */ public Object[] getTemplateNameStack() { return icb.getTemplateNameStack(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String) * @since 1.6 */ public void pushCurrentMacroName( String s ) { icb.pushCurrentMacroName( s ); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName() * @since 1.6 */ public void popCurrentMacroName() { icb.popCurrentMacroName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName() * @since 1.6 */ public String getCurrentMacroName() { return icb.getCurrentMacroName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth() * @since 1.6 */ public int getCurrentMacroCallDepth() { return icb.getCurrentMacroCallDepth(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack() * @since 1.6 */ public Object[] getMacroNameStack() { return icb.getMacroNameStack(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#icacheGet(java.lang.Object) */ public IntrospectionCacheData icacheGet( Object key ) { return icb.icacheGet( key ); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#icachePut(java.lang.Object, org.apache.velocity.util.introspection.IntrospectionCacheData) */ public void icachePut( Object key, IntrospectionCacheData o ) { icb.icachePut( key, o ); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setCurrentResource(org.apache.velocity.runtime.resource.Resource) */ public void setCurrentResource( Resource r ) { icb.setCurrentResource(r); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentResource() */ public Resource getCurrentResource() { return icb.getCurrentResource(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setMacroLibraries(List) * @since 1.6 */ public void setMacroLibraries(List macroLibraries) { icb.setMacroLibraries(macroLibraries); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroLibraries() * @since 1.6 */ public List getMacroLibraries() { return icb.getMacroLibraries(); } /* --- Context interface methods --- */ /** * @see org.apache.velocity.context.Context#put(java.lang.String, java.lang.Object) */ public Object put(String key, Object value) { return context.put( key , value ); } /** * @see InternalWrapperContext#localPut(String, Object) * @since 1.5 */ public Object localPut(final String key, final Object value) { return put(key, value); } /** * @see org.apache.velocity.context.Context#get(java.lang.String) */ public Object get(String key) { return context.get( key ); } /** * @see org.apache.velocity.context.Context#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { return context.containsKey( key ); } /** * @see org.apache.velocity.context.Context#getKeys() */ public Object[] getKeys() { return context.getKeys(); } /** * @see org.apache.velocity.context.Context#remove(java.lang.Object) */ public Object remove(Object key) { return context.remove( key ); } /* ---- InternalWrapperContext --- */ /** * returns the user data context that * we are wrapping * @return The internal user data context. */ public Context getInternalUserContext() { return context; } /** * Returns the base context that we are * wrapping. Here, its this, but for other thing * like VM related context contortions, it can * be something else * @return The base context. */ public InternalContextAdapter getBaseContext() { return this; } /* ----- InternalEventContext ---- */ /** * @see org.apache.velocity.context.InternalEventContext#attachEventCartridge(org.apache.velocity.app.event.EventCartridge) */ public EventCartridge attachEventCartridge( EventCartridge ec ) { if (iec != null) { return iec.attachEventCartridge( ec ); } return null; } /** * @see org.apache.velocity.context.InternalEventContext#getEventCartridge() */ public EventCartridge getEventCartridge() { if ( iec != null) { return iec.getEventCartridge( ); } return null; } } velocity-1.7/src/java/org/apache/velocity/context/AbstractContext.java0000644000175000017500000001661411131055646026126 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ /** * This class is the abstract base class for all conventional * Velocity Context implementations. Simply extend this class * and implement the abstract routines that access your preferred * storage method. * * Takes care of context chaining. * * Also handles / enforces policy on null keys and values : * *
        *
      • Null keys and values are accepted and basically dropped. *
      • If you place an object into the context with a null key, it * will be ignored and logged. *
      • If you try to place a null into the context with any key, it * will be dropped and logged. *
      * * The default implementation of this for application use is * org.apache.velocity.VelocityContext. * * All thanks to Fedor for the chaining idea. * * @author Geir Magnusson Jr. * @author Fedor Karpelevitch * @author Jason van Zyl * @version $Id: AbstractContext.java 732250 2009-01-07 07:37:10Z byron $ */ public abstract class AbstractContext extends InternalContextBase implements Context { /** * the chained Context if any */ private Context innerContext = null; /** * Implement to return a value from the context storage. *

      * The implementation of this method is required for proper * operation of a Context implementation in general * Velocity use. * * @param key key whose associated value is to be returned * @return object stored in the context */ public abstract Object internalGet( String key ); /** * Implement to put a value into the context storage. *

      * The implementation of this method is required for * proper operation of a Context implementation in * general Velocity use. * * @param key key with which to associate the value * @param value value to be associated with the key * @return previously stored value if exists, or null */ public abstract Object internalPut( String key, Object value ); /** * Implement to determine if a key is in the storage. *

      * Currently, this method is not used internally by * the Velocity engine. * * @param key key to test for existance * @return true if found, false if not */ public abstract boolean internalContainsKey(Object key); /** * Implement to return an object array of key * strings from your storage. *

      * Currently, this method is not used internally by * the Velocity engine. * * @return array of keys */ public abstract Object[] internalGetKeys(); /** * I mplement to remove an item from your storage. *

      * Currently, this method is not used internally by * the Velocity engine. * * @param key key to remove * @return object removed if exists, else null */ public abstract Object internalRemove(Object key); /** * default CTOR */ public AbstractContext() { } /** * Chaining constructor accepts a Context argument. * It will relay get() operations into this Context * in the even the 'local' get() returns null. * * @param inner context to be chained */ public AbstractContext( Context inner ) { innerContext = inner; /* * now, do a 'forward pull' of event cartridge so * it's accessable, bringing to the top level. */ if (innerContext instanceof InternalEventContext ) { attachEventCartridge( ( (InternalEventContext) innerContext).getEventCartridge() ); } } /** * Adds a name/value pair to the context. * * @param key The name to key the provided value with. * @param value The corresponding value. * @return Object that was replaced in the the Context if * applicable or null if not. */ public Object put(String key, Object value) { /* * don't even continue if key is null */ if (key == null) { return null; } return internalPut(key.intern(), value); } /** * Gets the value corresponding to the provided key from the context. * * Supports the chaining context mechanism. If the 'local' context * doesn't have the value, we try to get it from the chained context. * * @param key The name of the desired value. * @return The value corresponding to the provided key or null if * the key param is null. */ public Object get(String key) { /* * punt if key is null */ if (key == null) { return null; } /* * get the object for this key. If null, and we are chaining another Context * call the get() on it. */ Object o = internalGet( key ); if (o == null && innerContext != null) { o = innerContext.get( key ); } return o; } /** * Indicates whether the specified key is in the context. Provided for * debugging purposes. * * @param key The key to look for. * @return true if the key is in the context, false if not. */ public boolean containsKey(Object key) { if (key == null) { return false; } boolean exists = internalContainsKey(key); if (!exists && innerContext != null) { exists = innerContext.containsKey(key); } return exists; } /** * Get all the keys for the values in the context * @return Object[] of keys in the Context. Does not return * keys in chained context. */ public Object[] getKeys() { return internalGetKeys(); } /** * Removes the value associated with the specified key from the context. * * @param key The name of the value to remove. * @return The value that the key was mapped to, or null * if unmapped. */ public Object remove(Object key) { if (key == null) { return null; } return internalRemove(key); } /** * returns innerContext if one is chained * * @return Context if chained, null if not */ public Context getChainedContext() { return innerContext; } } velocity-1.7/src/java/org/apache/velocity/context/InternalHousekeepingContext.java0000644000175000017500000001005511130150630030463 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import org.apache.velocity.util.introspection.IntrospectionCacheData; import org.apache.velocity.runtime.resource.Resource; import java.util.List; /** * interface to encapsulate the 'stuff' for internal operation of velocity. * We use the context as a thread-safe storage : we take advantage of the * fact that it's a visitor of sorts to all nodes (that matter) of the * AST during init() and render(). * * Currently, it carries the template name for namespace * support, as well as node-local context data introspection caching. * * @author Geir Magnusson Jr. * @author Christoph Reck * @version $Id: InternalHousekeepingContext.java 731266 2009-01-04 15:11:20Z byron $ */ interface InternalHousekeepingContext { /** * set the current template name on top of stack * * @param s current template name */ void pushCurrentTemplateName( String s ); /** * remove the current template name from stack */ void popCurrentTemplateName(); /** * get the current template name * * @return String current template name */ String getCurrentTemplateName(); /** * Returns the template name stack in form of an array. * * @return Object[] with the template name stack contents. */ Object[] getTemplateNameStack(); /** * set the current macro name on top of stack * * @param s current macro name */ void pushCurrentMacroName( String s ); /** * remove the current macro name from stack */ void popCurrentMacroName(); /** * get the current macro name * * @return String current macro name */ String getCurrentMacroName(); /** * get the current macro call depth * * @return int current macro call depth */ int getCurrentMacroCallDepth(); /** * Returns the macro name stack in form of an array. * * @return Object[] with the macro name stack contents. */ Object[] getMacroNameStack(); /** * returns an IntrospectionCache Data (@see IntrospectionCacheData) * object if exists for the key * * @param key key to find in cache * @return cache object */ IntrospectionCacheData icacheGet( Object key ); /** * places an IntrospectionCache Data (@see IntrospectionCacheData) * element in the cache for specified key * * @param key key * @param o IntrospectionCacheData object to place in cache */ void icachePut( Object key, IntrospectionCacheData o ); /** * temporary fix to enable #include() to figure out * current encoding. * * @return The current resource. */ Resource getCurrentResource(); /** * @param r */ void setCurrentResource( Resource r ); /** * Set the macro library list for the current template. * * @param macroLibraries list of macro libraries to set */ void setMacroLibraries(List macroLibraries); /** * Get the macro library list for the current template. * * @return List of macro library names */ List getMacroLibraries(); } velocity-1.7/src/java/org/apache/velocity/context/ProxyVMContext.java0000755000175000017500000002433711322700447025751 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import java.io.StringWriter; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.Renderable; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.parser.node.Node; /** * Context for Velocity macro arguments. * * This special context combines ideas of earlier VMContext and VMProxyArgs * by implementing routing functionality internally. This significantly * reduces memory allocation upon macro invocations. * Since the macro AST is now shared and RuntimeMacro directive is used, * the earlier implementation of precalculating VMProxyArgs would not work. * * See Issue 607 * for more info on this class. * @author Jarkko Viinamaki * @version $Id$ * @since 1.6 */ public class ProxyVMContext extends ChainedInternalContextAdapter { /** container for our macro AST node arguments. Size must be power of 2. */ Map vmproxyhash = new HashMap(8, 0.8f); /** container for any local or constant macro arguments. Size must be power of 2. */ Map localcontext = new HashMap(8, 0.8f); /** support for local context scope feature, where all references are local */ private boolean localContextScope; /** needed for writing log entries. */ private RuntimeServices rsvc; /** * @param inner Velocity context for processing * @param rsvc RuntimeServices provides logging reference * @param localContextScope if true, all references are set to be local */ public ProxyVMContext(InternalContextAdapter inner, RuntimeServices rsvc, boolean localContextScope) { super(inner); this.localContextScope = localContextScope; this.rsvc = rsvc; } /** * Used to put Velocity macro arguments into this context. * * @param context rendering context * @param macroArgumentName name of the macro argument that we received * @param literalMacroArgumentName ".literal.$"+macroArgumentName * @param argumentValue actual value of the macro argument * * @throws MethodInvocationException */ public void addVMProxyArg(InternalContextAdapter context, String macroArgumentName, String literalMacroArgumentName, Node argumentValue) throws MethodInvocationException { if (isConstant(argumentValue)) { localcontext.put(macroArgumentName, argumentValue.value(context)); } else { vmproxyhash.put(macroArgumentName, argumentValue); localcontext.put(literalMacroArgumentName, argumentValue); } } /** * Used to put Velocity macro bodyContext arguments into this context. * * @param context rendering context * @param macroArgumentName name of the macro argument that we received * @param literalMacroArgumentName ".literal.$"+macroArgumentName * @param argumentValue actual value of the macro body * * @throws MethodInvocationException */ public void addVMProxyArg(InternalContextAdapter context, String macroArgumentName, String literalMacroArgumentName, Renderable argumentValue) throws MethodInvocationException { localcontext.put(macroArgumentName, argumentValue); } /** * AST nodes that are considered constants can be directly * saved into the context. Dynamic values are stored in * another argument hashmap. * * @param node macro argument as AST node * @return true if the node is a constant value */ private boolean isConstant(Node node) { switch (node.getType()) { case ParserTreeConstants.JJTINTEGERRANGE: case ParserTreeConstants.JJTREFERENCE: case ParserTreeConstants.JJTOBJECTARRAY: case ParserTreeConstants.JJTMAP: case ParserTreeConstants.JJTSTRINGLITERAL: case ParserTreeConstants.JJTTEXT: return (false); default: return (true); } } /** * Impl of the Context.put() method. * * @param key name of item to set * @param value object to set to key * @return old stored object */ public Object put(final String key, final Object value) { return put(key, value, localContextScope); } /** * Allows callers to explicitly put objects in the local context, no matter what the * velocimacro.context.local setting says. Needed e.g. for loop variables in foreach. * * @param key name of item to set. * @param value object to set to key. * @return old stored object */ public Object localPut(final String key, final Object value) { return put(key, value, true); } /** * Internal put method to select between local and global scope. * * @param key name of item to set * @param value object to set to key * @param forceLocal True forces the object into the local scope. * @return old stored object */ protected Object put(final String key, final Object value, final boolean forceLocal) { Object old = localcontext.put(key, value); if (!forceLocal) { old = super.put(key, value); } return old; } /** * Implementation of the Context.get() method. First checks * localcontext, then arguments, then global context. * * @param key name of item to get * @return stored object or null */ public Object get(String key) { Object o = localcontext.get(key); if (o != null) { return o; } Node astNode = (Node) vmproxyhash.get(key); if (astNode != null) { int type = astNode.getType(); // if the macro argument (astNode) is a reference, we need to evaluate it // in case it is a multilevel node if (type == ParserTreeConstants.JJTREFERENCE) { ASTReference ref = (ASTReference) astNode; if (ref.jjtGetNumChildren() > 0) { return ref.execute(null, innerContext); } else { Object obj = innerContext.get(ref.getRootString()); if (obj == null && ref.strictRef) { if (!innerContext.containsKey(ref.getRootString())) { throw new MethodInvocationException("Parameter '" + ref.getRootString() + "' not defined", null, key, ref.getTemplateName(), ref.getLine(), ref.getColumn()); } } return obj; } } else if (type == ParserTreeConstants.JJTTEXT) { // this really shouldn't happen. text is just a throwaway arg for #foreach() try { StringWriter writer = new StringWriter(); astNode.render(innerContext, writer); return writer.toString(); } catch (RuntimeException e) { throw e; } catch (Exception e) { String msg = "ProxyVMContext.get() : error rendering reference"; rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } } else { // use value method to render other dynamic nodes return astNode.value(innerContext); } } return super.get(key); } /** * @see org.apache.velocity.context.Context#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { return vmproxyhash.containsKey(key) || localcontext.containsKey(key) || super.containsKey(key); } /** * @see org.apache.velocity.context.Context#getKeys() */ public Object[] getKeys() { if (localcontext.isEmpty()) { return vmproxyhash.keySet().toArray(); } else if (vmproxyhash.isEmpty()) { return localcontext.keySet().toArray(); } HashSet keys = new HashSet(localcontext.keySet()); keys.addAll(vmproxyhash.keySet()); return keys.toArray(); } /** * @see org.apache.velocity.context.Context#remove(java.lang.Object) */ public Object remove(Object key) { Object loc = localcontext.remove(key); Object glo = null; vmproxyhash.remove(key); if (!localContextScope) { glo = super.remove(key); } if (loc != null) { return loc; } return glo; } } velocity-1.7/src/java/org/apache/velocity/context/EvaluateContext.java0000644000175000017500000001631511322700447026125 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import java.util.HashSet; import java.util.Set; import org.apache.velocity.VelocityContext; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.ClassUtils; /** * This is a special, internal-use-only context implementation to be * used for the #evaluate directive. * * We use this context to chain the existing context, preventing any changes * from impacting the parent context. By separating this context into a * separate class it also allows for the future possibility of changing * the context behavior for the #evaluate directive. * * Note that the context used to store values local to #evaluate() * is user defined but defaults to {@link VelocityContext}. * * @author Will Glass-Husain * @version $Id: EvaluateContext.java 898032 2010-01-11 19:51:03Z nbubna $ * @since 1.6 * @deprecated Will be removed in 2.0 */ public class EvaluateContext extends ChainedInternalContextAdapter { /** container for any local items */ Context localContext; /** * CTOR, wraps an ICA * @param inner context for parent template * @param rsvc */ public EvaluateContext( InternalContextAdapter inner, RuntimeServices rsvc ) { super(inner); initContext(rsvc); } /** * Initialize the context based on user-configured class * @param rsvc */ private void initContext( RuntimeServices rsvc ) { String contextClass = rsvc.getString(RuntimeConstants.EVALUATE_CONTEXT_CLASS); if (contextClass != null && contextClass.length() > 0) { rsvc.getLog().warn("The "+RuntimeConstants.EVALUATE_CONTEXT_CLASS+ " property has been deprecated. It will be removed in Velocity 2.0. "+ " Instead, please use the automatically provided $evaluate"+ " namespace to get and set local references"+ " (e.g. #set($evaluate.foo = 'bar') and $evaluate.foo)."); Object o = null; try { o = ClassUtils.getNewInstance( contextClass ); } catch (ClassNotFoundException cnfe) { String err = "The specified class for #evaluate() context (" + contextClass + ") does not exist or is not accessible to the current classloader."; rsvc.getLog().error(err); throw new RuntimeException(err,cnfe); } catch (Exception e) { String err = "The specified class for #evaluate() context (" + contextClass + ") can not be loaded."; rsvc.getLog().error(err,e); throw new RuntimeException(err); } if (!(o instanceof Context)) { String err = "The specified class for #evaluate() context (" + contextClass + ") does not implement " + Context.class.getName() + "."; rsvc.getLog().error(err); throw new RuntimeException(err); } localContext = (Context) o; } else { if (rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug("No class specified for #evaluate() context, "+ "so #set calls will now alter the global context and no longer be local. "+ "This is a change from earlier versions due to VELOCITY-704. "+ "If you need references within #evaluate to stay local, "+ "please use the automatically provided $evaluate namespace instead "+ "(e.g. #set($evaluate.foo = 'bar') and $evaluate.foo)."); } } } /** * Put method also stores values in local scope * * @param key name of item to set * @param value object to set to key * @return old stored object */ public Object put(String key, Object value) { if (localContext != null) { return localContext.put(key, value); } return super.put(key, value); } /** * Retrieves from local or global context. * * @param key name of item to get * @return stored object or null */ public Object get( String key ) { /* * always try the local context then innerContext */ Object o = null; if (localContext != null) { o = localContext.get(key); } if (o == null) { o = super.get( key ); } return o; } /** * @see org.apache.velocity.context.Context#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { return (localContext != null && localContext.containsKey(key)) || super.containsKey(key); } /** * @see org.apache.velocity.context.Context#getKeys() */ public Object[] getKeys() { if (localContext != null) { Set keys = new HashSet(); Object[] localKeys = localContext.getKeys(); for (int i=0; i < localKeys.length; i++) { keys.add(localKeys[i]); } Object[] innerKeys = super.getKeys(); for (int i=0; i < innerKeys.length; i++) { keys.add(innerKeys[i]); } return keys.toArray(); } return super.getKeys(); } /** * @see org.apache.velocity.context.Context#remove(java.lang.Object) */ public Object remove(Object key) { if (localContext != null) { return localContext.remove(key); } return super.remove(key); } /** * Allows callers to explicitly put objects in the local context. * Objects added to the context through this method always end up * in the top-level context of possible wrapped contexts. * * @param key name of item to set. * @param value object to set to key. * @return old stored object */ public Object localPut(final String key, final Object value) { if (localContext != null) { return localContext.put(key, value); } return super.localPut(key, value); } } velocity-1.7/src/java/org/apache/velocity/context/InternalContextBase.java0000644000175000017500000001551711130150630026717 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import java.util.HashMap; import java.util.Stack; import java.util.List; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.util.introspection.IntrospectionCacheData; /** * class to encapsulate the 'stuff' for internal operation of velocity. * We use the context as a thread-safe storage : we take advantage of the * fact that it's a visitor of sorts to all nodes (that matter) of the * AST during init() and render(). * Currently, it carries the template name for namespace * support, as well as node-local context data introspection caching. * * Note that this is not a public class. It is for package access only to * keep application code from accessing the internals, as AbstractContext * is derived from this. * * @author Geir Magnusson Jr. * @version $Id: InternalContextBase.java 731266 2009-01-04 15:11:20Z byron $ */ class InternalContextBase implements InternalHousekeepingContext, InternalEventContext { /** * Version Id for serializable */ private static final long serialVersionUID = -245905472770843470L; /** * cache for node/context specific introspection information */ private HashMap introspectionCache = new HashMap(33); /** * Template name stack. The stack top contains the current template name. */ private Stack templateNameStack = new Stack(); /** * Velocimacro name stack. The stack top contains the current macro name. */ private Stack macroNameStack = new Stack(); /** * EventCartridge we are to carry. Set by application */ private EventCartridge eventCartridge = null; /** * Current resource - used for carrying encoding and other * information down into the rendering process */ private Resource currentResource = null; /** * List for holding the macro libraries. Contains the macro library * template name as strings. */ private List macroLibraries = null; /** * set the current template name on top of stack * * @param s current template name */ public void pushCurrentTemplateName( String s ) { templateNameStack.push(s); } /** * remove the current template name from stack */ public void popCurrentTemplateName() { templateNameStack.pop(); } /** * get the current template name * * @return String current template name */ public String getCurrentTemplateName() { if ( templateNameStack.empty() ) return ""; else return (String) templateNameStack.peek(); } /** * get the current template name stack * * @return Object[] with the template name stack contents. */ public Object[] getTemplateNameStack() { return templateNameStack.toArray(); } /** * set the current macro name on top of stack * * @param s current macro name */ public void pushCurrentMacroName( String s ) { macroNameStack.push(s); } /** * remove the current macro name from stack */ public void popCurrentMacroName() { macroNameStack.pop(); } /** * get the current macro name * * @return String current macro name */ public String getCurrentMacroName() { if (macroNameStack.empty()) { return ""; } else { return (String) macroNameStack.peek(); } } /** * get the current macro call depth * * @return int current macro call depth */ public int getCurrentMacroCallDepth() { return macroNameStack.size(); } /** * get the current macro name stack * * @return Object[] with the macro name stack contents. */ public Object[] getMacroNameStack() { return macroNameStack.toArray(); } /** * returns an IntrospectionCache Data (@see IntrospectionCacheData) * object if exists for the key * * @param key key to find in cache * @return cache object */ public IntrospectionCacheData icacheGet( Object key ) { return ( IntrospectionCacheData ) introspectionCache.get( key ); } /** * places an IntrospectionCache Data (@see IntrospectionCacheData) * element in the cache for specified key * * @param key key * @param o IntrospectionCacheData object to place in cache */ public void icachePut( Object key, IntrospectionCacheData o ) { introspectionCache.put( key, o ); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setCurrentResource(org.apache.velocity.runtime.resource.Resource) */ public void setCurrentResource( Resource r ) { currentResource = r; } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentResource() */ public Resource getCurrentResource() { return currentResource; } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setMacroLibraries(List) */ public void setMacroLibraries(List macroLibraries) { this.macroLibraries = macroLibraries; } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroLibraries() */ public List getMacroLibraries() { return macroLibraries; } /** * @see org.apache.velocity.context.InternalEventContext#attachEventCartridge(org.apache.velocity.app.event.EventCartridge) */ public EventCartridge attachEventCartridge( EventCartridge ec ) { EventCartridge temp = eventCartridge; eventCartridge = ec; return temp; } /** * @see org.apache.velocity.context.InternalEventContext#getEventCartridge() */ public EventCartridge getEventCartridge() { return eventCartridge; } } velocity-1.7/src/java/org/apache/velocity/context/ChainedInternalContextAdapter.java0000755000175000017500000001667411322700447030723 0ustar moellermoellerpackage org.apache.velocity.context; /* * 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. */ import java.util.List; import org.apache.velocity.app.event.EventCartridge; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.util.introspection.IntrospectionCacheData; /** * This is an abstract internal-use-only context implementation to be * used as a subclass for other internal-use-only contexts that wrap * other internal-use-only contexts. * * We use this context to make it easier to chain an existing context * as part of a new context implementation. It just delegates everything * to the inner/parent context. Subclasses then only need to override * the methods relevant to them. * * @author Nathan Bubna * @version $Id: ChainedInternalContextAdapter.java 685724 2008-08-13 23:12:12Z nbubna $ * @since 1.6 */ public abstract class ChainedInternalContextAdapter implements InternalContextAdapter { /** the parent context */ protected InternalContextAdapter innerContext = null; /** * CTOR, wraps an ICA * @param inner context */ public ChainedInternalContextAdapter(InternalContextAdapter inner) { innerContext = inner; } /** * Return the inner / user context. * @return The inner / user context. */ public Context getInternalUserContext() { return innerContext.getInternalUserContext(); } /** * @see org.apache.velocity.context.InternalWrapperContext#getBaseContext() */ public InternalContextAdapter getBaseContext() { return innerContext.getBaseContext(); } /** * Retrieves from parent context. * * @param key name of item to get * @return stored object or null */ public Object get(String key) { return innerContext.get(key); } /** * Put method also stores values in parent context * * @param key name of item to set * @param value object to set to key * @return old stored object */ public Object put(String key, Object value) { /* * just put in the local context */ return innerContext.put(key, value); } /** * @see org.apache.velocity.context.Context#containsKey(java.lang.Object) */ public boolean containsKey(Object key) { return innerContext.containsKey(key); } /** * @see org.apache.velocity.context.Context#getKeys() */ public Object[] getKeys() { return innerContext.getKeys(); } /** * @see org.apache.velocity.context.Context#remove(java.lang.Object) */ public Object remove(Object key) { return innerContext.remove(key); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentTemplateName(java.lang.String) */ public void pushCurrentTemplateName(String s) { innerContext.pushCurrentTemplateName(s); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentTemplateName() */ public void popCurrentTemplateName() { innerContext.popCurrentTemplateName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentTemplateName() */ public String getCurrentTemplateName() { return innerContext.getCurrentTemplateName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getTemplateNameStack() */ public Object[] getTemplateNameStack() { return innerContext.getTemplateNameStack(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#pushCurrentMacroName(java.lang.String) */ public void pushCurrentMacroName(String s) { innerContext.pushCurrentMacroName(s); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#popCurrentMacroName() */ public void popCurrentMacroName() { innerContext.popCurrentMacroName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroName() */ public String getCurrentMacroName() { return innerContext.getCurrentMacroName(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentMacroCallDepth() */ public int getCurrentMacroCallDepth() { return innerContext.getCurrentMacroCallDepth(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroNameStack() */ public Object[] getMacroNameStack() { return innerContext.getMacroNameStack(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#icacheGet(java.lang.Object) */ public IntrospectionCacheData icacheGet(Object key) { return innerContext.icacheGet(key); } /** * @see org.apache.velocity.context.InternalWrapperContext#localPut(java.lang.String,java.lang.Object) */ public Object localPut(final String key, final Object value) { return innerContext.put(key, value); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#icachePut(java.lang.Object, org.apache.velocity.util.introspection.IntrospectionCacheData) */ public void icachePut(Object key, IntrospectionCacheData o) { innerContext.icachePut(key, o); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setMacroLibraries(List) */ public void setMacroLibraries(List macroLibraries) { innerContext.setMacroLibraries(macroLibraries); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroLibraries() */ public List getMacroLibraries() { return innerContext.getMacroLibraries(); } /** * @see org.apache.velocity.context.InternalEventContext#attachEventCartridge(org.apache.velocity.app.event.EventCartridge) */ public EventCartridge attachEventCartridge(EventCartridge ec) { return innerContext.attachEventCartridge(ec); } /** * @see org.apache.velocity.context.InternalEventContext#getEventCartridge() */ public EventCartridge getEventCartridge() { return innerContext.getEventCartridge(); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#setCurrentResource(org.apache.velocity.runtime.resource.Resource) */ public void setCurrentResource(Resource r) { innerContext.setCurrentResource(r); } /** * @see org.apache.velocity.context.InternalHousekeepingContext#getCurrentResource() */ public Resource getCurrentResource() { return innerContext.getCurrentResource(); } } velocity-1.7/src/java/org/apache/velocity/servlet/0000755000175000017500000000000011675166252022154 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/servlet/VelocityServlet.java0000644000175000017500000006132010513464370026154 0ustar moellermoellerpackage org.apache.velocity.servlet; /* * 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. */ import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.Properties; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.io.VelocityWriter; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeSingleton; import org.apache.velocity.util.SimplePool; /** * Base class which simplifies the use of Velocity with Servlets. * Extend this class, implement the handleRequest() method, * and add your data to the context. Then call * getTemplate("myTemplate.wm"). * * This class puts some things into the context object that you should * be aware of: *
       * "req" - The HttpServletRequest object
       * "res" - The HttpServletResponse object
       * 
      * * There are other methods you can override to access, alter or control * any part of the request processing chain. Please see the javadocs for * more information on : *
        *
      • loadConfiguration() : for setting up the Velocity runtime *
      • createContext() : for creating and loading the Context *
      • setContentType() : for changing the content type on a request * by request basis *
      • handleRequest() : you must implement this *
      • mergeTemplate() : the template rendering process *
      • requestCleanup() : post rendering resource or other cleanup *
      • error() : error handling *
      *
      * If you put a String with key "contentType" object into the context within either your * servlet or within your template, then that will be used to override * the default content type specified in the properties file. * * @deprecated This servlet has been replaced by VelocityViewServlet, * available from the Velocity-Tools sub-project. VelocityViewServlet * provides support for quick, clean MVC web development. * VelocityServlet will be removed in a future version of Velocity. * * @author Dave Bryson * @author Jon S. Stevens * @author Geir Magnusson Jr. * @author Kent Johnson * @author Daniel Rall * $Id: VelocityServlet.java 463298 2006-10-12 16:10:32Z henning $ */ public abstract class VelocityServlet extends HttpServlet { /** * The context key for the HTTP request object. */ public static final String REQUEST = "req"; /** * The context key for the HTTP response object. */ public static final String RESPONSE = "res"; /** * The HTTP content type context key. */ public static final String CONTENT_TYPE = "default.contentType"; /** * The default content type for the response */ public static final String DEFAULT_CONTENT_TYPE = "text/html"; /** * Encoding for the output stream */ public static final String DEFAULT_OUTPUT_ENCODING = "ISO-8859-1"; /** * The default content type, itself defaulting to {@link * #DEFAULT_CONTENT_TYPE} if not configured. */ private static String defaultContentType; /** * This is the string that is looked for when getInitParameter is * called (org.apache.velocity.properties). */ protected static final String INIT_PROPS_KEY = "org.apache.velocity.properties"; /** * Use of this properties key has been deprecated, and will be * removed in Velocity version 1.5. */ private static final String OLD_INIT_PROPS_KEY = "properties"; /** * Cache of writers */ private static SimplePool writerPool = new SimplePool(40); /** * Performs initialization of this servlet. Called by the servlet * container on loading. * * @param config The servlet configuration to apply. * * @exception ServletException */ public void init( ServletConfig config ) throws ServletException { super.init( config ); /* * do whatever we have to do to init Velocity */ initVelocity( config ); /* * Now that Velocity is initialized, cache some config. */ VelocityServlet.defaultContentType = RuntimeSingleton.getString(CONTENT_TYPE, DEFAULT_CONTENT_TYPE); } /** * Initializes the Velocity runtime, first calling * loadConfiguration(ServletConvig) to get a * java.util.Properties of configuration information * and then calling Velocity.init(). Override this * to do anything to the environment before the * initialization of the singelton takes place, or to * initialize the singleton in other ways. * @param config * @throws ServletException */ protected void initVelocity( ServletConfig config ) throws ServletException { try { /* * call the overridable method to allow the * derived classes a shot at altering the configuration * before initializing Runtime */ Properties props = loadConfiguration( config ); Velocity.init( props ); } catch( Exception e ) { throw new ServletException("Error initializing Velocity: " + e, e); } } /** * Loads the configuration information and returns that * information as a Properties, which will be used to * initialize the Velocity runtime. *

      * Currently, this method gets the initialization parameter * VelocityServlet.INIT_PROPS_KEY, which should be a file containing * the configuration information. *

      * To configure your Servlet Spec 2.2 compliant servlet runner to pass * this to you, put the following in your WEB-INF/web.xml file *
      *
           *    <servlet>
           *      <servlet-name> YourServlet </servlet-name>
           *      <servlet-class> your.package.YourServlet </servlet-class>
           *      <init-param>
           *         <param-name> org.apache.velocity.properties </param-name>
           *         <param-value> velocity.properties </param-value>
           *      </init-param>
           *    </servlet>
           *   
      * * Alternately, if you wish to configure an entire context in this * fashion, you may use the following: *
      *
           *    <context-param>
           *       <param-name> org.apache.velocity.properties </param-name>
           *       <param-value> velocity.properties </param-value>
           *       <description> Path to Velocity configuration </description>
           *    </context-param>
           *   
      * * Derived classes may do the same, or take advantage of this code to do the loading for them via : *
           *      Properties p = super.loadConfiguration( config );
           *   
      * and then add or modify the configuration values from the file. *
      * * @param config ServletConfig passed to the servlets init() function * Can be used to access the real path via ServletContext (hint) * @return java.util.Properties loaded with configuration values to be used * to initialize the Velocity runtime. * @throws FileNotFoundException if a specified file is not found. * @throws IOException I/O problem accessing the specified file, if specified. * @deprecated Use VelocityViewServlet from the Velocity Tools * library instead. */ protected Properties loadConfiguration(ServletConfig config) throws IOException, FileNotFoundException { // This is a little overly complex because of legacy support // for the initialization properties key "properties". // References to OLD_INIT_PROPS_KEY should be removed at // Velocity version 1.5. String propsFile = config.getInitParameter(INIT_PROPS_KEY); if (propsFile == null || propsFile.length() == 0) { ServletContext sc = config.getServletContext(); propsFile = config.getInitParameter(OLD_INIT_PROPS_KEY); if (propsFile == null || propsFile.length() == 0) { propsFile = sc.getInitParameter(INIT_PROPS_KEY); if (propsFile == null || propsFile.length() == 0) { propsFile = sc.getInitParameter(OLD_INIT_PROPS_KEY); if (propsFile != null && propsFile.length() > 0) { sc.log("Use of the properties initialization " + "parameter '" + OLD_INIT_PROPS_KEY + "' has " + "been deprecated by '" + INIT_PROPS_KEY + '\''); } } } else { sc.log("Use of the properties initialization parameter '" + OLD_INIT_PROPS_KEY + "' has been deprecated by '" + INIT_PROPS_KEY + '\''); } } /* * This will attempt to find the location of the properties * file from the relative path to the WAR archive (ie: * docroot). Since JServ returns null for getRealPath() * because it was never implemented correctly, then we know we * will not have an issue with using it this way. I don't know * if this will break other servlet engines, but it probably * shouldn't since WAR files are the future anyways. */ Properties p = new Properties(); if ( propsFile != null ) { p.load(getServletContext().getResourceAsStream(propsFile)); } return p; } /** * Handles HTTP GET requests by calling {@link * #doRequest(HttpServletRequest, HttpServletResponse)}. * @param request * @param response * @throws ServletException * @throws IOException */ public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { doRequest(request, response); } /** * Handles HTTP POST requests by calling {@link * #doRequest(HttpServletRequest, HttpServletResponse)}. * @param request * @param response * @throws ServletException * @throws IOException */ public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { doRequest(request, response); } /** * Handles all requests (by default). * * @param request HttpServletRequest object containing client request * @param response HttpServletResponse object for the response * @throws ServletException * @throws IOException */ protected void doRequest(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { Context context = null; try { /* * first, get a context */ context = createContext( request, response ); /* * set the content type */ setContentType( request, response ); /* * let someone handle the request */ Template template = handleRequest( request, response, context ); /* * bail if we can't find the template */ if ( template == null ) { return; } /* * now merge it */ mergeTemplate( template, context, response ); } catch (Exception e) { /* * call the error handler to let the derived class * do something useful with this failure. */ error( request, response, e); } finally { /* * call cleanup routine to let a derived class do some cleanup */ requestCleanup( request, response, context ); } } /** * A cleanup routine which is called at the end of the {@link * #doRequest(HttpServletRequest, HttpServletResponse)} * processing sequence, allowing a derived class to do resource * cleanup or other end of process cycle tasks. * * @param request servlet request from client * @param response servlet reponse * @param context context created by the createContext() method */ protected void requestCleanup( HttpServletRequest request, HttpServletResponse response, Context context ) { } /** * merges the template with the context. Only override this if you really, really * really need to. (And don't call us with questions if it breaks :) * * @param template template object returned by the handleRequest() method * @param context context created by the createContext() method * @param response servlet reponse (use this to get the output stream or Writer * @throws ResourceNotFoundException * @throws ParseErrorException * @throws MethodInvocationException * @throws IOException * @throws UnsupportedEncodingException * @throws Exception */ protected void mergeTemplate( Template template, Context context, HttpServletResponse response ) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, IOException, UnsupportedEncodingException, Exception { ServletOutputStream output = response.getOutputStream(); VelocityWriter vw = null; // ASSUMPTION: response.setContentType() has been called. String encoding = response.getCharacterEncoding(); try { vw = (VelocityWriter) writerPool.get(); if (vw == null) { vw = new VelocityWriter(new OutputStreamWriter(output, encoding), 4 * 1024, true); } else { vw.recycle(new OutputStreamWriter(output, encoding)); } template.merge(context, vw); } finally { if (vw != null) { try { /* * flush and put back into the pool * don't close to allow us to play * nicely with others. */ vw.flush(); } catch (IOException e) { // do nothing } /* * Clear the VelocityWriter's reference to its * internal OutputStreamWriter to allow the latter * to be GC'd while vw is pooled. */ vw.recycle(null); writerPool.put(vw); } } } /** * Sets the content type of the response, defaulting to {@link * #defaultContentType} if not overriden. Delegates to {@link * #chooseCharacterEncoding(HttpServletRequest)} to select the * appropriate character encoding. * * @param request The servlet request from the client. * @param response The servlet reponse to the client. */ protected void setContentType(HttpServletRequest request, HttpServletResponse response) { String contentType = VelocityServlet.defaultContentType; int index = contentType.lastIndexOf(';') + 1; if (index <= 0 || (index < contentType.length() && contentType.indexOf("charset", index) == -1)) { // Append the character encoding which we'd like to use. String encoding = chooseCharacterEncoding(request); //RuntimeSingleton.debug("Chose output encoding of '" + // encoding + '\''); if (!DEFAULT_OUTPUT_ENCODING.equalsIgnoreCase(encoding)) { contentType += "; charset=" + encoding; } } response.setContentType(contentType); //RuntimeSingleton.debug("Response Content-Type set to '" + // contentType + '\''); } /** * Chooses the output character encoding to be used as the value * for the "charset=" portion of the HTTP Content-Type header (and * thus returned by response.getCharacterEncoding()). * Called by {@link #setContentType(HttpServletRequest, * HttpServletResponse)} if an encoding isn't already specified by * Content-Type. By default, chooses the value of * RuntimeSingleton's output.encoding property. * * @param request The servlet request from the client. * @return The chosen character encoding. */ protected String chooseCharacterEncoding(HttpServletRequest request) { return RuntimeSingleton.getString(RuntimeConstants.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING); } /** * Returns a context suitable to pass to the handleRequest() method *

      * Default implementation will create a VelocityContext object, * put the HttpServletRequest and HttpServletResponse * into the context accessable via the keys VelocityServlet.REQUEST and * VelocityServlet.RESPONSE, respectively. * * @param request servlet request from client * @param response servlet reponse to client * * @return context */ protected Context createContext(HttpServletRequest request, HttpServletResponse response ) { /* * create a new context */ VelocityContext context = new VelocityContext(); /* * put the request/response objects into the context * wrap the HttpServletRequest to solve the introspection * problems */ context.put( REQUEST, request ); context.put( RESPONSE, response ); return context; } /** * Retrieves the requested template. * * @param name The file name of the template to retrieve relative to the * template root. * @return The requested template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization */ public Template getTemplate( String name ) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getTemplate(name); } /** * Retrieves the requested template with the specified * character encoding. * * @param name The file name of the template to retrieve relative to the * template root. * @param encoding the character encoding of the template * * @return The requested template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws Exception if an error occurs in template initialization * * @since Velocity v1.1 */ public Template getTemplate( String name, String encoding ) throws ResourceNotFoundException, ParseErrorException, Exception { return RuntimeSingleton.getTemplate( name, encoding ); } /** * Implement this method to add your application data to the context, * calling the getTemplate() method to produce your return * value. *

      * In the event of a problem, you may handle the request directly * and return null or throw a more meaningful exception * for the error handler to catch. * * @param request servlet request from client * @param response servlet reponse * @param ctx The context to add your data to. * @return The template to merge with your context or null, indicating * that you handled the processing. * @throws Exception * * @since Velocity v1.1 */ protected Template handleRequest( HttpServletRequest request, HttpServletResponse response, Context ctx ) throws Exception { /* * invoke handleRequest */ Template t = handleRequest( ctx ); /* * if it returns null, this is the 'old' deprecated * way, and we want to mimic the behavior for a little * while anyway */ if (t == null) { throw new Exception ("handleRequest(Context) returned null - no template selected!" ); } return t; } /** * Implement this method to add your application data to the context, * calling the getTemplate() method to produce your return * value. *

      * In the event of a problem, you may simple return null * or throw a more meaningful exception. * * @deprecated Use * {@link #handleRequest( HttpServletRequest request, * HttpServletResponse response, Context ctx )} * * @param ctx The context to add your data to. * @return The template to merge with your context. * @throws Exception */ protected Template handleRequest( Context ctx ) throws Exception { throw new Exception ("You must override VelocityServlet.handleRequest( Context) " + " or VelocityServlet.handleRequest( HttpServletRequest, " + " HttpServletResponse, Context)" ); } /** * Invoked when there is an error thrown in any part of doRequest() processing. *

      * Default will send a simple HTML response indicating there was a problem. * * @param request original HttpServletRequest from servlet container. * @param response HttpServletResponse object from servlet container. * @param cause Exception that was thrown by some other part of process. * @throws ServletException * @throws IOException */ protected void error( HttpServletRequest request, HttpServletResponse response, Exception cause ) throws ServletException, IOException { StringBuffer html = new StringBuffer(); html.append(""); html.append("Error"); html.append(""); html.append("

      VelocityServlet: Error processing the template

      "); html.append("
      ");
              String why = cause.getMessage();
              if (why != null && why.trim().length() > 0)
              {
                  html.append(why);
                  html.append("
      "); } StringWriter sw = new StringWriter(); cause.printStackTrace( new PrintWriter( sw ) ); html.append( sw.toString() ); html.append("
      "); html.append(""); html.append(""); response.getOutputStream().print( html.toString() ); } } velocity-1.7/src/java/org/apache/velocity/io/0000755000175000017500000000000011675166252021077 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/io/UnicodeInputStream.java0000644000175000017500000002434011050652577025524 0ustar moellermoellerpackage org.apache.velocity.io; /* * 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. */ import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import org.apache.velocity.util.ExceptionUtils; /** * This is an input stream that is unicode BOM aware. This allows you to e.g. read * Windows Notepad Unicode files as Velocity templates. * * It allows you to check the actual encoding of a file by calling {@link #getEncodingFromStream()} on * the input stream reader. * * This class is not thread safe! When more than one thread wants to use an instance of UnicodeInputStream, * the caller must provide synchronization. * * @author Aki Nieminen * @author Henning P. Schmiedehausen * @version $Id: UnicodeInputStream.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class UnicodeInputStream extends InputStream { /** BOM Marker for UTF 8. See http://www.unicode.org/unicode/faq/utf_bom.html */ public static final UnicodeBOM UTF8_BOM = new UnicodeBOM("UTF-8", new byte [] { (byte)0xef, (byte)0xbb, (byte)0xbf }); /** BOM Marker for UTF 16, little endian. See http://www.unicode.org/unicode/faq/utf_bom.html */ public static final UnicodeBOM UTF16LE_BOM = new UnicodeBOM("UTF-16LE", new byte [] { (byte)0xff, (byte)0xfe }); /** BOM Marker for UTF 16, big endian. See http://www.unicode.org/unicode/faq/utf_bom.html */ public static final UnicodeBOM UTF16BE_BOM = new UnicodeBOM("UTF-16BE", new byte [] { (byte)0xfe, (byte)0xff }); /** * BOM Marker for UTF 32, little endian. See http://www.unicode.org/unicode/faq/utf_bom.html * * TODO: Does Java actually support this? */ public static final UnicodeBOM UTF32LE_BOM = new UnicodeBOM("UTF-32LE", new byte [] { (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 }); /** * BOM Marker for UTF 32, big endian. See http://www.unicode.org/unicode/faq/utf_bom.html * * TODO: Does Java actually support this? */ public static final UnicodeBOM UTF32BE_BOM = new UnicodeBOM("UTF-32BE", new byte [] { (byte)0x00, (byte)0x00, (byte)0xfe, (byte)0xff }); /** The maximum amount of bytes to read for a BOM */ private static final int MAX_BOM_SIZE = 4; /** Buffer for BOM reading */ private byte [] buf = new byte[MAX_BOM_SIZE]; /** Buffer pointer. */ private int pos = 0; /** The stream encoding as read from the BOM or null. */ private final String encoding; /** True if the BOM itself should be skipped and not read. */ private final boolean skipBOM; private final PushbackInputStream inputStream; /** * Creates a new UnicodeInputStream object. Skips a BOM which defines the file encoding. * * @param inputStream The input stream to use for reading. */ public UnicodeInputStream(final InputStream inputStream) throws IllegalStateException, IOException { this(inputStream, true); } /** * Creates a new UnicodeInputStream object. * * @param inputStream The input stream to use for reading. * @param skipBOM If this is set to true, a BOM read from the stream is discarded. This parameter should normally be true. */ public UnicodeInputStream(final InputStream inputStream, boolean skipBOM) throws IllegalStateException, IOException { super(); this.skipBOM = skipBOM; this.inputStream = new PushbackInputStream(inputStream, MAX_BOM_SIZE); try { this.encoding = readEncoding(); } catch (IOException ioe) { IllegalStateException ex = new IllegalStateException("Could not read BOM from Stream"); ExceptionUtils.setCause(ex, ioe); throw ex; } } /** * Returns true if the input stream discards the BOM. * * @return True if the input stream discards the BOM. */ public boolean isSkipBOM() { return skipBOM; } /** * Read encoding based on BOM. * * @return The encoding based on the BOM. * * @throws IllegalStateException When a problem reading the BOM occured. */ public String getEncodingFromStream() { return encoding; } /** * This method gets the encoding from the stream contents if a BOM exists. If no BOM exists, the encoding * is undefined. * * @return The encoding of this streams contents as decided by the BOM or null if no BOM was found. */ protected String readEncoding() throws IOException { pos = 0; UnicodeBOM encoding = null; // read first byte. if (readByte()) { // Build a list of matches // // 00 00 FE FF --> UTF 32 BE // EF BB BF --> UTF 8 // FE FF --> UTF 16 BE // FF FE --> UTF 16 LE // FF FE 00 00 --> UTF 32 LE switch (buf[0]) { case (byte)0x00: // UTF32 BE encoding = match(UTF32BE_BOM, null); break; case (byte)0xef: // UTF8 encoding = match(UTF8_BOM, null); break; case (byte)0xfe: // UTF16 BE encoding = match(UTF16BE_BOM, null); break; case (byte)0xff: // UTF16/32 LE encoding = match(UTF16LE_BOM, null); if (encoding != null) { encoding = match(UTF32LE_BOM, encoding); } break; default: encoding = null; break; } } pushback(encoding); return (encoding != null) ? encoding.getEncoding() : null; } private final UnicodeBOM match(final UnicodeBOM matchEncoding, final UnicodeBOM noMatchEncoding) throws IOException { byte [] bom = matchEncoding.getBytes(); for (int i = 0; i < bom.length; i++) { if (pos <= i) // Byte has not yet been read { if (!readByte()) { return noMatchEncoding; } } if (bom[i] != buf[i]) { return noMatchEncoding; } } return matchEncoding; } private final boolean readByte() throws IOException { int res = inputStream.read(); if (res == -1) { return false; } if (pos >= buf.length) { throw new IOException("BOM read error"); } buf[pos++] = (byte) res; return true; } private final void pushback(final UnicodeBOM matchBOM) throws IOException { int count = pos; // By default, all bytes are pushed back. int start = 0; if (matchBOM != null && skipBOM) { // We have a match (some bytes are part of the BOM) // and we want to skip the BOM. Push back only the bytes // after the BOM. start = matchBOM.getBytes().length; count = (pos - start); if (count < 0) { throw new IllegalStateException("Match has more bytes than available!"); } } inputStream.unread(buf, start, count); } /** * @see java.io.InputStream#close() */ public void close() throws IOException { inputStream.close(); } /** * @see java.io.InputStream#available() */ public int available() throws IOException { return inputStream.available(); } /** * @see java.io.InputStream#mark(int) */ public void mark(final int readlimit) { inputStream.mark(readlimit); } /** * @see java.io.InputStream#markSupported() */ public boolean markSupported() { return inputStream.markSupported(); } /** * @see java.io.InputStream#read() */ public int read() throws IOException { return inputStream.read(); } /** * @see java.io.InputStream#read(byte[]) */ public int read(final byte [] b) throws IOException { return inputStream.read(b); } /** * @see java.io.InputStream#read(byte[], int, int) */ public int read(final byte [] b, final int off, final int len) throws IOException { return inputStream.read(b, off, len); } /** * @see java.io.InputStream#reset() */ public void reset() throws IOException { inputStream.reset(); } /** * @see java.io.InputStream#skip(long) */ public long skip(final long n) throws IOException { return inputStream.skip(n); } /** * Helper class to bundle encoding and BOM marker. * * @author Henning P. Schmiedehausen * @version $Id: UnicodeInputStream.java 685685 2008-08-13 21:43:27Z nbubna $ */ static final class UnicodeBOM { private final String encoding; private final byte [] bytes; private UnicodeBOM(final String encoding, final byte [] bytes) { this.encoding = encoding; this.bytes = bytes; } String getEncoding() { return encoding; } byte [] getBytes() { return bytes; } } } velocity-1.7/src/java/org/apache/velocity/io/VelocityWriter.java0000644000175000017500000002161410513464370024731 0ustar moellermoellerpackage org.apache.velocity.io; /* * 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. */ import java.io.IOException; import java.io.Writer; /** * Implementation of a fast Writer. It was originally taken from JspWriter * and modified to have less syncronization going on. * * @author Jason van Zyl * @author Jon S. Stevens * @author Anil K. Vijendran * @version $Id: VelocityWriter.java 463298 2006-10-12 16:10:32Z henning $ */ public final class VelocityWriter extends Writer { /** * constant indicating that the Writer is not buffering output */ public static final int NO_BUFFER = 0; /** * constant indicating that the Writer is buffered and is using the * implementation default buffer size */ public static final int DEFAULT_BUFFER = -1; /** * constant indicating that the Writer is buffered and is unbounded; * this is used in BodyContent */ public static final int UNBOUNDED_BUFFER = -2; private int bufferSize; private boolean autoFlush; private Writer writer; private char cb[]; private int nextChar; private static int defaultCharBufferSize = 8 * 1024; /** * Create a buffered character-output stream that uses a default-sized * output buffer. * * @param writer Writer to wrap around */ public VelocityWriter(Writer writer) { this(writer, defaultCharBufferSize, true); } /** * private constructor. */ private VelocityWriter(int bufferSize, boolean autoFlush) { this.bufferSize = bufferSize; this.autoFlush = autoFlush; } /** * This method returns the size of the buffer used by the JspWriter. * * @return the size of the buffer in bytes, or 0 is unbuffered. */ public int getBufferSize() { return bufferSize; } /** * This method indicates whether the JspWriter is autoFlushing. * * @return if this JspWriter is auto flushing or throwing IOExceptions on * buffer overflow conditions */ public boolean isAutoFlush() { return autoFlush; } /** * Create a new buffered character-output stream that uses an output * buffer of the given size. * * @param writer Writer to wrap around * @param sz Output-buffer size, a positive integer * @param autoFlush * * @exception IllegalArgumentException If sz is <= 0 */ public VelocityWriter(Writer writer, int sz, boolean autoFlush) { this(sz, autoFlush); if (sz < 0) throw new IllegalArgumentException("Buffer size <= 0"); this.writer = writer; cb = sz == 0 ? null : new char[sz]; nextChar = 0; } /** * Flush the output buffer to the underlying character stream, without * flushing the stream itself. This method is non-private only so that it * may be invoked by PrintStream. */ private final void flushBuffer() throws IOException { if (bufferSize == 0) return; if (nextChar == 0) return; writer.write(cb, 0, nextChar); nextChar = 0; } /** * Discard the output buffer. */ public final void clear() { nextChar = 0; } private final void bufferOverflow() throws IOException { throw new IOException("overflow"); } /** * Flush the stream. * @throws IOException * */ public final void flush() throws IOException { flushBuffer(); if (writer != null) { writer.flush(); } } /** * Close the stream. * @throws IOException * */ public final void close() throws IOException { if (writer == null) return; flush(); } /** * @return the number of bytes unused in the buffer */ public final int getRemaining() { return bufferSize - nextChar; } /** * Write a single character. * @param c * @throws IOException * */ public final void write(int c) throws IOException { if (bufferSize == 0) { writer.write(c); } else { if (nextChar >= bufferSize) if (autoFlush) flushBuffer(); else bufferOverflow(); cb[nextChar++] = (char) c; } } /** * Our own little min method, to avoid loading * java.lang.Math if we've run out of file * descriptors and we're trying to print a stack trace. */ private final int min(int a, int b) { return (a < b ? a : b); } /** * Write a portion of an array of characters. * *

      Ordinarily this method stores characters from the given array into * this stream's buffer, flushing the buffer to the underlying stream as * needed. If the requested length is at least as large as the buffer, * however, then this method will flush the buffer and write the characters * directly to the underlying stream. Thus redundant * DiscardableBufferedWriters will not copy data unnecessarily. * * @param cbuf A character array * @param off Offset from which to start reading characters * @param len Number of characters to write * @throws IOException * */ public final void write(char cbuf[], int off, int len) throws IOException { if (bufferSize == 0) { writer.write(cbuf, off, len); return; } if (len == 0) { return; } if (len >= bufferSize) { /* If the request length exceeds the size of the output buffer, flush the buffer and then write the data directly. In this way buffered streams will cascade harmlessly. */ if (autoFlush) flushBuffer(); else bufferOverflow(); writer.write(cbuf, off, len); return; } int b = off, t = off + len; while (b < t) { int d = min(bufferSize - nextChar, t - b); System.arraycopy(cbuf, b, cb, nextChar, d); b += d; nextChar += d; if (nextChar >= bufferSize) if (autoFlush) flushBuffer(); else bufferOverflow(); } } /** * Write an array of characters. This method cannot be inherited from the * Writer class because it must suppress I/O exceptions. * @param buf * @throws IOException */ public final void write(char buf[]) throws IOException { write(buf, 0, buf.length); } /** * Write a portion of a String. * * @param s String to be written * @param off Offset from which to start reading characters * @param len Number of characters to be written * @throws IOException * */ public final void write(String s, int off, int len) throws IOException { if (bufferSize == 0) { writer.write(s, off, len); return; } int b = off, t = off + len; while (b < t) { int d = min(bufferSize - nextChar, t - b); s.getChars(b, b + d, cb, nextChar); b += d; nextChar += d; if (nextChar >= bufferSize) if (autoFlush) flushBuffer(); else bufferOverflow(); } } /** * Write a string. This method cannot be inherited from the Writer class * because it must suppress I/O exceptions. * @param s * @throws IOException */ public final void write(String s) throws IOException { if (s != null) { write(s, 0, s.length()); } } /** * resets this class so that it can be reused * @param writer * */ public final void recycle(Writer writer) { this.writer = writer; clear(); } } velocity-1.7/src/java/org/apache/velocity/Template.java0000644000175000017500000003317311206073012023072 0ustar moellermoellerpackage org.apache.velocity; /* * 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. */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.List; import org.apache.velocity.context.Context; import org.apache.velocity.context.InternalContextAdapterImpl; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.TemplateInitException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.directive.Scope; import org.apache.velocity.runtime.directive.StopCommand; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.runtime.resource.ResourceManager; /** * This class is used for controlling all template * operations. This class uses a parser created * by JavaCC to create an AST that is subsequently * traversed by a Visitor. * *

       * // set up and initialize Velocity before this code block
       *
       * Template template = Velocity.getTemplate("test.wm");
       * Context context = new VelocityContext();
       *
       * context.put("foo", "bar");
       * context.put("customer", new Customer());
       *
       * template.merge(context, writer);
       * 
      * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: Template.java 778045 2009-05-23 22:17:46Z nbubna $ */ public class Template extends Resource { /* * The name of the variable to use when placing * the scope object into the context. */ private String scopeName = "template"; private boolean provideScope = false; private VelocityException errorCondition = null; /** Default constructor */ public Template() { super(); setType(ResourceManager.RESOURCE_TEMPLATE); } /** * gets the named resource as a stream, parses and inits * * @return true if successful * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws IOException problem reading input stream */ public boolean process() throws ResourceNotFoundException, ParseErrorException { data = null; InputStream is = null; errorCondition = null; /* * first, try to get the stream from the loader */ try { is = resourceLoader.getResourceStream(name); } catch( ResourceNotFoundException rnfe ) { /* * remember and re-throw */ errorCondition = rnfe; throw rnfe; } /* * if that worked, lets protect in case a loader impl * forgets to throw a proper exception */ if (is != null) { /* * now parse the template */ try { BufferedReader br = new BufferedReader( new InputStreamReader( is, encoding ) ); data = rsvc.parse( br, name); initDocument(); return true; } catch( UnsupportedEncodingException uce ) { String msg = "Template.process : Unsupported input encoding : " + encoding + " for template " + name; errorCondition = new ParseErrorException( msg ); throw errorCondition; } catch ( ParseException pex ) { /* * remember the error and convert */ errorCondition = new ParseErrorException(pex, name); throw errorCondition; } catch ( TemplateInitException pex ) { errorCondition = new ParseErrorException( pex, name); throw errorCondition; } /** * pass through runtime exceptions */ catch( RuntimeException e ) { errorCondition = new VelocityException("Exception thrown processing Template " +getName(), e); throw errorCondition; } finally { /* * Make sure to close the inputstream when we are done. */ try { is.close(); } catch(IOException e) { // If we are already throwing an exception then we want the original // exception to be continued to be thrown, otherwise, throw a new Exception. if (errorCondition == null) { throw new VelocityException(e); } } } } else { /* * is == null, therefore we have some kind of file issue */ errorCondition = new ResourceNotFoundException("Unknown resource error for resource " + name ); throw errorCondition; } } /** * initializes the document. init() is not longer * dependant upon context, but we need to let the * init() carry the template name down throught for VM * namespace features * @throws TemplateInitException When a problem occurs during the document initialization. */ public void initDocument() throws TemplateInitException { /* * send an empty InternalContextAdapter down into the AST to initialize it */ InternalContextAdapterImpl ica = new InternalContextAdapterImpl( new VelocityContext() ); try { /* * put the current template name on the stack */ ica.pushCurrentTemplateName( name ); ica.setCurrentResource( this ); /* * init the AST */ ((SimpleNode)data).init( ica, rsvc); String property = scopeName+'.'+RuntimeConstants.PROVIDE_SCOPE_CONTROL; provideScope = rsvc.getBoolean(property, provideScope); } finally { /* * in case something blows up... * pull it off for completeness */ ica.popCurrentTemplateName(); ica.setCurrentResource( null ); } } /** * The AST node structure is merged with the * context to produce the final output. * * @param context Conext with data elements accessed by template * @param writer output writer for rendered template * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws MethodInvocationException When a method on a referenced object in the context could not invoked. */ public void merge( Context context, Writer writer) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { merge(context, writer, null); } /** * The AST node structure is merged with the * context to produce the final output. * * @param context Conext with data elements accessed by template * @param writer output writer for rendered template * @param macroLibraries a list of template files containing macros to be used when merging * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. * @throws MethodInvocationException When a method on a referenced object in the context could not invoked. * @since 1.6 */ public void merge( Context context, Writer writer, List macroLibraries) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException { /* * we shouldn't have to do this, as if there is an error condition, * the application code should never get a reference to the * Template */ if (errorCondition != null) { throw errorCondition; } if( data != null) { /* * create an InternalContextAdapter to carry the user Context down * into the rendering engine. Set the template name and render() */ InternalContextAdapterImpl ica = new InternalContextAdapterImpl( context ); /** * Set the macro libraries */ ica.setMacroLibraries(macroLibraries); if (macroLibraries != null) { for (int i = 0; i < macroLibraries.size(); i++) { /** * Build the macro library */ try { rsvc.getTemplate((String) macroLibraries.get(i)); } catch (ResourceNotFoundException re) { /* * the macro lib wasn't found. Note it and throw */ rsvc.getLog().error("template.merge(): " + "cannot find template " + (String) macroLibraries.get(i)); throw re; } catch (ParseErrorException pe) { /* * the macro lib was found, but didn't parse - syntax error * note it and throw */ rsvc.getLog().error("template.merge(): " + "syntax error in template " + (String) macroLibraries.get(i) + "."); throw pe; } catch (Exception e) { throw new RuntimeException("Template.merge(): parse failed in template " + (String) macroLibraries.get(i) + ".", e); } } } if (provideScope) { ica.put(scopeName, new Scope(this, ica.get(scopeName))); } try { ica.pushCurrentTemplateName( name ); ica.setCurrentResource( this ); ( (SimpleNode) data ).render( ica, writer); } catch (StopCommand stop) { if (!stop.isFor(this)) { throw stop; } else if (rsvc.getLog().isDebugEnabled()) { rsvc.getLog().debug(stop.getMessage()); } } catch (IOException e) { throw new VelocityException("IO Error rendering template '"+ name + "'", e); } finally { /* * lets make sure that we always clean up the context */ ica.popCurrentTemplateName(); ica.setCurrentResource( null ); if (provideScope) { Object obj = ica.get(scopeName); if (obj instanceof Scope) { Scope scope = (Scope)obj; if (scope.getParent() != null) { ica.put(scopeName, scope.getParent()); } else if (scope.getReplaced() != null) { ica.put(scopeName, scope.getReplaced()); } else { ica.remove(scopeName); } } } } } else { /* * this shouldn't happen either, but just in case. */ String msg = "Template.merge() failure. The document is null, " + "most likely due to parsing error."; throw new RuntimeException(msg); } } } velocity-1.7/src/java/org/apache/velocity/util/0000755000175000017500000000000011675166252021445 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/util/ExceptionUtils.java0000644000175000017500000000732211050652577025270 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * Use this to create a new Exception. This will run under JDK 1.3 or greater. * However, it running under JDK 1.4 it will set the cause. * * @author Llewellyn Falco * @since 1.5 */ public class ExceptionUtils { private static boolean causesAllowed = true; /** * Create a new RuntimeException, setting the cause if possible. * @param message * @param cause * @return A runtime exception object. */ public static RuntimeException createRuntimeException( String message, Throwable cause) { return (RuntimeException) createWithCause( RuntimeException.class, message, cause); } /** * Create a new Exception, setting the cause if possible. * @param clazz * @param message * @param cause * @return A Throwable. */ public static Throwable createWithCause(Class clazz, String message, Throwable cause) { Throwable re = null; if (causesAllowed) { try { Constructor constructor = clazz .getConstructor(new Class[]{String.class, Throwable.class}); re = (Throwable) constructor .newInstance(new Object[]{message, cause}); } catch (RuntimeException e) { throw e; } catch (Exception e) { causesAllowed = false; } } if (re == null) { try { Constructor constructor = clazz .getConstructor(new Class[]{String.class}); re = (Throwable) constructor .newInstance(new Object[]{message + " caused by " + cause}); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException("Error caused " + e); // should be impossible } } return re; } /** * Set the cause of the Exception. Will detect if this is not allowed. * @param onObject * @param cause */ public static void setCause(Throwable onObject, Throwable cause) { if (causesAllowed) { try { Method method = onObject.getClass().getMethod("initCause", new Class[]{Throwable.class}); method.invoke(onObject, new Object[]{cause}); } catch (RuntimeException e) { throw e; } catch (Exception e) { causesAllowed = false; } } } } velocity-1.7/src/java/org/apache/velocity/util/EnumerationIterator.java0000644000175000017500000000403310513464370026300 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.util.Iterator; import java.util.Enumeration; /** * An Iterator wrapper for an Enumeration. * * @author Geir Magnusson Jr. * @version $Id: EnumerationIterator.java 463298 2006-10-12 16:10:32Z henning $ */ public class EnumerationIterator implements Iterator { /** * The enumeration to iterate. */ private Enumeration enumeration = null; /** * Creates a new iteratorwrapper instance for the specified * Enumeration. * * @param enumeration The Enumeration to wrap. */ public EnumerationIterator(Enumeration enumeration) { this.enumeration = enumeration; } /** * Move to next element in the array. * * @return The next object in the array. */ public Object next() { return enumeration.nextElement(); } /** * Check to see if there is another element in the array. * * @return Whether there is another element. */ public boolean hasNext() { return enumeration.hasMoreElements(); } /** * Unimplemented. No analogy in Enumeration */ public void remove() { // not implemented } } velocity-1.7/src/java/org/apache/velocity/util/introspection/0000755000175000017500000000000011675166252024345 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/util/introspection/IntrospectorCacheImpl.java0000644000175000017500000001027211322700447031440 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.velocity.runtime.log.Log; /** * This is the internal introspector cache implementation. * * @author Henning P. Schmiedehausen * @version $Id: IntrospectorCacheImpl.java 898032 2010-01-11 19:51:03Z nbubna $ * @since 1.5 */ public final class IntrospectorCacheImpl implements IntrospectorCache { /** * define a public string so that it can be looked for if interested */ public final static String CACHEDUMP_MSG = "IntrospectorCache detected classloader change. Dumping cache."; /** Class logger */ private final Log log; /** * Holds the method maps for the classes we know about. Map: Class --> ClassMap object. */ private final Map classMapCache = new HashMap(); /** * Keep the names of the classes in another map. This is needed for a multi-classloader environment where it is possible * to have Class 'Foo' loaded by a classloader and then get asked to introspect on 'Foo' from another class loader. While these * two Class objects have the same name, a classMethodMaps.get(Foo.class) will return null. For that case, we * keep a set of class names to recognize this case. */ private final Set classNameCache = new HashSet(); /** * C'tor */ public IntrospectorCacheImpl(final Log log) { this.log = log; } /** * Clears the internal cache. */ public void clear() { synchronized (classMapCache) { classMapCache.clear(); classNameCache.clear(); log.debug(CACHEDUMP_MSG); } } /** * Lookup a given Class object in the cache. If it does not exist, * check whether this is due to a class change and purge the caches * eventually. * * @param c The class to look up. * @return A ClassMap object or null if it does not exist in the cache. */ public ClassMap get(final Class c) { if (c == null) { throw new IllegalArgumentException("class is null!"); } ClassMap classMap = (ClassMap)classMapCache.get(c); if (classMap == null) { /* * check to see if we have it by name. * if so, then we have an object with the same * name but loaded through a different class loader. * In that case, we will just dump the cache to be sure. */ synchronized (classMapCache) { if (classNameCache.contains(c.getName())) { clear(); } } } return classMap; } /** * Creates a class map for specific class and registers it in the * cache. Also adds the qualified name to the name->class map * for later Classloader change detection. * * @param c The class for which the class map gets generated. * @return A ClassMap object. */ public ClassMap put(final Class c) { final ClassMap classMap = new ClassMap(c, log); synchronized (classMapCache) { classMapCache.put(c, classMap); classNameCache.add(c.getName()); } return classMap; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/ClassMap.java0000644000175000017500000003163311206070062026700 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.util.MapFactory; /** * A cache of introspection information for a specific class instance. * Keys {@link java.lang.reflect.Method} objects by a concatenation of the * method name and the names of classes that make up the parameters. * * @author Jason van Zyl * @author Bob McWhirter * @author Attila Szegedi * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @author Nathan Bubna * @version $Id: ClassMap.java 778038 2009-05-23 21:52:50Z nbubna $ */ public class ClassMap { /** Set true if you want to debug the reflection code */ private static final boolean debugReflection = false; /** Class logger */ private final Log log; /** * Class passed into the constructor used to as * the basis for the Method map. */ private final Class clazz; private final MethodCache methodCache; /** * Standard constructor * @param clazz The class for which this ClassMap gets constructed. */ public ClassMap(final Class clazz, final Log log) { this.clazz = clazz; this.log = log; if (debugReflection && log.isDebugEnabled()) { log.debug("================================================================="); log.debug("== Class: " + clazz); } methodCache = createMethodCache(); if (debugReflection && log.isDebugEnabled()) { log.debug("================================================================="); } } /** * Returns the class object whose methods are cached by this map. * * @return The class object whose methods are cached by this map. */ public Class getCachedClass() { return clazz; } /** * Find a Method using the method name and parameter objects. * * @param name The method name to look up. * @param params An array of parameters for the method. * @return A Method object representing the method to invoke or null. * @throws MethodMap.AmbiguousException When more than one method is a match for the parameters. */ public Method findMethod(final String name, final Object[] params) throws MethodMap.AmbiguousException { return methodCache.get(name, params); } /** * Populate the Map of direct hits. These * are taken from all the public methods * that our class, its parents and their implemented interfaces provide. */ private MethodCache createMethodCache() { MethodCache methodCache = new MethodCache(log); // // Looks through all elements in the class hierarchy. This one is bottom-first (i.e. we start // with the actual declaring class and its interfaces and then move up (superclass etc.) until we // hit java.lang.Object. That is important because it will give us the methods of the declaring class // which might in turn be abstract further up the tree. // // We also ignore all SecurityExceptions that might happen due to SecurityManager restrictions (prominently // hit with Tomcat 5.5). // // We can also omit all that complicated getPublic, getAccessible and upcast logic that the class map had up // until Velocity 1.4. As we always reflect all elements of the tree (that's what we have a cache for), we will // hit the public elements sooner or later because we reflect all the public elements anyway. // // Ah, the miracles of Java for(;;) ... for (Class classToReflect = getCachedClass(); classToReflect != null ; classToReflect = classToReflect.getSuperclass()) { if (Modifier.isPublic(classToReflect.getModifiers())) { populateMethodCacheWith(methodCache, classToReflect); } Class [] interfaces = classToReflect.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { populateMethodCacheWithInterface(methodCache, interfaces[i]); } } // return the already initialized cache return methodCache; } /* recurses up interface heirarchy to get all super interfaces (VELOCITY-689) */ private void populateMethodCacheWithInterface(MethodCache methodCache, Class iface) { if (Modifier.isPublic(iface.getModifiers())) { populateMethodCacheWith(methodCache, iface); } Class[] supers = iface.getInterfaces(); for (int i=0; i < supers.length; i++) { populateMethodCacheWithInterface(methodCache, supers[i]); } } private void populateMethodCacheWith(MethodCache methodCache, Class classToReflect) { if (debugReflection && log.isDebugEnabled()) { log.debug("Reflecting " + classToReflect); } try { Method[] methods = classToReflect.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { int modifiers = methods[i].getModifiers(); if (Modifier.isPublic(modifiers)) { methodCache.put(methods[i]); } } } catch (SecurityException se) // Everybody feels better with... { if (log.isDebugEnabled()) { log.debug("While accessing methods of " + classToReflect + ": ", se); } } } /** * This is the cache to store and look up the method information. * * @author Henning P. Schmiedehausen * @version $Id: ClassMap.java 778038 2009-05-23 21:52:50Z nbubna $ */ private static final class MethodCache { private static final Object CACHE_MISS = new Object(); private static final String NULL_ARG = Object.class.getName(); private static final Map convertPrimitives = new HashMap(); static { convertPrimitives.put(Boolean.TYPE, Boolean.class.getName()); convertPrimitives.put(Byte.TYPE, Byte.class.getName()); convertPrimitives.put(Character.TYPE, Character.class.getName()); convertPrimitives.put(Double.TYPE, Double.class.getName()); convertPrimitives.put(Float.TYPE, Float.class.getName()); convertPrimitives.put(Integer.TYPE, Integer.class.getName()); convertPrimitives.put(Long.TYPE, Long.class.getName()); convertPrimitives.put(Short.TYPE, Short.class.getName()); } /** Class logger */ private final Log log; /** * Cache of Methods, or CACHE_MISS, keyed by method * name and actual arguments used to find it. */ private final Map cache = MapFactory.create(false); /** Map of methods that are searchable according to method parameters to find a match */ private final MethodMap methodMap = new MethodMap(); private MethodCache(Log log) { this.log = log; } /** * Find a Method using the method name and parameter objects. * * Look in the methodMap for an entry. If found, * it'll either be a CACHE_MISS, in which case we * simply give up, or it'll be a Method, in which * case, we return it. * * If nothing is found, then we must actually go * and introspect the method from the MethodMap. * * @param name The method name to look up. * @param params An array of parameters for the method. * @return A Method object representing the method to invoke or null. * @throws MethodMap.AmbiguousException When more than one method is a match for the parameters. */ public Method get(final String name, final Object [] params) throws MethodMap.AmbiguousException { String methodKey = makeMethodKey(name, params); Object cacheEntry = cache.get(methodKey); if (cacheEntry == CACHE_MISS) { // We looked this up before and failed. return null; } if (cacheEntry == null) { try { // That one is expensive... cacheEntry = methodMap.find(name, params); } catch(MethodMap.AmbiguousException ae) { /* * that's a miss :-) */ cache.put(methodKey, CACHE_MISS); throw ae; } cache.put(methodKey, (cacheEntry != null) ? cacheEntry : CACHE_MISS); } // Yes, this might just be null. return (Method) cacheEntry; } private void put(Method method) { String methodKey = makeMethodKey(method); // We don't overwrite methods because we fill the // cache from defined class towards java.lang.Object // and that would cause overridden methods to appear // as if they were not overridden. if (cache.get(methodKey) == null) { cache.put(methodKey, method); methodMap.add(method); if (debugReflection && log.isDebugEnabled()) { log.debug("Adding " + method); } } } /** * Make a methodKey for the given method using * the concatenation of the name and the * types of the method parameters. * * @param method to be stored as key * @return key for ClassMap */ private String makeMethodKey(final Method method) { Class[] parameterTypes = method.getParameterTypes(); int args = parameterTypes.length; if (args == 0) { return method.getName(); } StrBuilder methodKey = new StrBuilder((args+1)*16).append(method.getName()); for (int j = 0; j < args; j++) { /* * If the argument type is primitive then we want * to convert our primitive type signature to the * corresponding Object type so introspection for * methods with primitive types will work correctly. * * The lookup map (convertPrimitives) contains all eight * primitives (boolean, byte, char, double, float, int, long, short) * known to Java. So it should never return null for the key passed in. */ if (parameterTypes[j].isPrimitive()) { methodKey.append((String) convertPrimitives.get(parameterTypes[j])); } else { methodKey.append(parameterTypes[j].getName()); } } return methodKey.toString(); } private String makeMethodKey(String method, Object[] params) { int args = params.length; if (args == 0) { return method; } StrBuilder methodKey = new StrBuilder((args+1)*16).append(method); for (int j = 0; j < args; j++) { Object arg = params[j]; if (arg == null) { methodKey.append(NULL_ARG); } else { methodKey.append(arg.getClass().getName()); } } return methodKey.toString(); } } } velocity-1.7/src/java/org/apache/velocity/util/introspection/SecureIntrospectorControl.java0000644000175000017500000000303111050652577032405 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Interface used to determine which methods are allowed to be executed. * * @author wglass@forio.com * @version $Id: SecureIntrospectorControl.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface SecureIntrospectorControl { /** * Determine which methods and classes to prevent from executing. * * @param clazz Class for which method is being called * @param method method being called. This may be null in the case of a call to iterator, get, or set method * * @return true if method may be called on object */ public boolean checkObjectExecutePermission(Class clazz, String method); } velocity-1.7/src/java/org/apache/velocity/util/introspection/SecureUberspector.java0000644000175000017500000000703411202566437030653 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.util.RuntimeServicesAware; /** * Use a custom introspector that prevents classloader related method * calls. Use this introspector for situations in which template * writers are numerous or untrusted. Specifically, this introspector * prevents creation of arbitrary objects or reflection on objects. * *

      To use this introspector, set the following property: *

       * runtime.introspector.uberspect = org.apache.velocity.util.introspection.SecureUberspector
       * 
      * * @author Will Glass-Husain * @version $Id: SecureUberspector.java 774412 2009-05-13 15:54:07Z nbubna $ * @since 1.5 */ public class SecureUberspector extends UberspectImpl implements RuntimeServicesAware { RuntimeServices runtimeServices; public SecureUberspector() { super(); } /** * init - generates the Introspector. As the setup code * makes sure that the log gets set before this is called, * we can initialize the Introspector using the log object. */ public void init() { String [] badPackages = runtimeServices.getConfiguration() .getStringArray(RuntimeConstants.INTROSPECTOR_RESTRICT_PACKAGES); String [] badClasses = runtimeServices.getConfiguration() .getStringArray(RuntimeConstants.INTROSPECTOR_RESTRICT_CLASSES); introspector = new SecureIntrospectorImpl(badClasses, badPackages, log); } /** * Get an iterator from the given object. Since the superclass method * this secure version checks for execute permission. * * @param obj object to iterate over * @param i line, column, template info * @return Iterator for object */ public Iterator getIterator(Object obj, Info i) throws Exception { if (obj != null) { SecureIntrospectorControl sic = (SecureIntrospectorControl)introspector; if (sic.checkObjectExecutePermission(obj.getClass(), null)) { return super.getIterator(obj, i); } else { log.warn("Cannot retrieve iterator from " + obj.getClass() + " due to security restrictions."); } } return null; } /** * Store the RuntimeServices before the object is initialized.. * @param rs RuntimeServices object for initialization */ public void setRuntimeServices(RuntimeServices rs) { this.runtimeServices = rs; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/VelPropertySet.java0000644000175000017500000000363610513464370030157 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Interface used for setting values that appear to be properties in * Velocity. Ex. * * #set($foo.bar = "hello") * * @author Geir Magnusson Jr. * @version $Id: VelPropertySet.java 463298 2006-10-12 16:10:32Z henning $ */ public interface VelPropertySet { /** * method used to set the value in the object * * @param o Object on which the method will be called with the arg * @param arg value to be set * @return the value returned from the set operation (impl specific) * @throws Exception */ public Object invoke(Object o, Object arg) throws Exception; /** * specifies if this VelPropertySet is cacheable and able to be * reused for this class of object it was returned for * * @return true if can be reused for this class, false if not */ public boolean isCacheable(); /** * returns the method name used to set this 'property' * @return The method name used to set this 'property' */ public String getMethodName(); } velocity-1.7/src/java/org/apache/velocity/util/introspection/AbstractChainableUberspector.java0000644000175000017500000000720111202566437032753 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; /** * Default implementation of a {@link ChainableUberspector chainable uberspector} that forwards all calls to the wrapped * uberspector (when that is possible). It should be used as the base class for all chainable uberspectors. * * @version $Id: $ * @since 1.6 * @see ChainableUberspector */ public abstract class AbstractChainableUberspector extends UberspectImpl implements ChainableUberspector { /** The wrapped (decorated) uberspector. */ protected Uberspect inner; /** * {@inheritDoc} * * @see ChainableUberspector#wrap(org.apache.velocity.util.introspection.Uberspect) * @see #inner */ public void wrap(Uberspect inner) { this.inner = inner; } /** * init - the chainable uberspector is responsible for the initialization of the wrapped uberspector * * @see org.apache.velocity.util.introspection.Uberspect#init() */ //@Override public void init() { if (this.inner != null) { this.inner.init(); } } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getIterator(java.lang.Object, * org.apache.velocity.util.introspection.Info) */ //@SuppressWarnings("unchecked") //@Override public Iterator getIterator(Object obj, Info i) throws Exception { return (this.inner != null) ? this.inner.getIterator(obj, i) : null; } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getMethod(java.lang.Object, java.lang.String, * java.lang.Object[], org.apache.velocity.util.introspection.Info) */ //@Override public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { return (this.inner != null) ? this.inner.getMethod(obj, methodName, args, i) : null; } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getPropertyGet(java.lang.Object, java.lang.String, * org.apache.velocity.util.introspection.Info) */ //@Override public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { return (this.inner != null) ? this.inner.getPropertyGet(obj, identifier, i) : null; } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getPropertySet(java.lang.Object, java.lang.String, * java.lang.Object, org.apache.velocity.util.introspection.Info) */ //@Override public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { return (this.inner != null) ? this.inner.getPropertySet(obj, identifier, arg, i) : null; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/LinkingUberspector.java0000644000175000017500000001005611322700447031010 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; /** *

      * When the runtime.introspection.uberspect configuration property contains several * uberspector class names, it means those uberspectors will be chained. When an * uberspector in the list other than the leftmost does not implement ChainableUberspector, * then this utility class is used to provide a basic default chaining where the * first non-null result is kept for each introspection call. *

      * * @since 1.6 * @see ChainableUberspector * @version $Id: LinkingUberspector.java 10959 2008-07-01 00:12:29Z sdumitriu $ */ public class LinkingUberspector extends AbstractChainableUberspector { private Uberspect leftUberspect; private Uberspect rightUberspect; /** * Constructor that takes the two uberspectors to link */ public LinkingUberspector(Uberspect left,Uberspect right) { leftUberspect = left; rightUberspect = right; } /** * {@inheritDoc} *

      * Init both wrapped uberspectors *

      * * @see org.apache.velocity.util.introspection.Uberspect#init() */ //@Override public void init() { leftUberspect.init(); rightUberspect.init(); } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getIterator(java.lang.Object, * org.apache.velocity.util.introspection.Info) */ //@SuppressWarnings("unchecked") //@Override public Iterator getIterator(Object obj, Info i) throws Exception { Iterator it = leftUberspect.getIterator(obj,i); return it != null ? it : rightUberspect.getIterator(obj,i); } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getMethod(java.lang.Object, java.lang.String, * java.lang.Object[], org.apache.velocity.util.introspection.Info) */ //@Override public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { VelMethod method = leftUberspect.getMethod(obj,methodName,args,i); return method != null ? method : rightUberspect.getMethod(obj,methodName,args,i); } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getPropertyGet(java.lang.Object, java.lang.String, * org.apache.velocity.util.introspection.Info) */ //@Override public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { VelPropertyGet getter = leftUberspect.getPropertyGet(obj,identifier,i); return getter != null ? getter : rightUberspect.getPropertyGet(obj,identifier,i); } /** * {@inheritDoc} * * @see org.apache.velocity.util.introspection.Uberspect#getPropertySet(java.lang.Object, java.lang.String, * java.lang.Object, org.apache.velocity.util.introspection.Info) */ //@Override public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { VelPropertySet setter = leftUberspect.getPropertySet(obj,identifier,arg,i); return setter != null ? setter : rightUberspect.getPropertySet(obj,identifier,arg,i); } } velocity-1.7/src/java/org/apache/velocity/util/introspection/UberspectImpl.java0000644000175000017500000004451511322700447027764 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.RuntimeLoggerLog; import org.apache.velocity.runtime.parser.node.AbstractExecutor; import org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor; import org.apache.velocity.runtime.parser.node.GetExecutor; import org.apache.velocity.runtime.parser.node.MapGetExecutor; import org.apache.velocity.runtime.parser.node.MapSetExecutor; import org.apache.velocity.runtime.parser.node.PropertyExecutor; import org.apache.velocity.runtime.parser.node.PutExecutor; import org.apache.velocity.runtime.parser.node.SetExecutor; import org.apache.velocity.runtime.parser.node.SetPropertyExecutor; import org.apache.velocity.util.ArrayIterator; import org.apache.velocity.util.ArrayListWrapper; import org.apache.velocity.util.EnumerationIterator; /** * Implementation of Uberspect to provide the default introspective * functionality of Velocity * * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: UberspectImpl.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class UberspectImpl implements Uberspect, UberspectLoggable { /** * Our runtime logger. */ protected Log log; /** * the default Velocity introspector */ protected Introspector introspector; /** * init - generates the Introspector. As the setup code * makes sure that the log gets set before this is called, * we can initialize the Introspector using the log object. */ public void init() { introspector = new Introspector(log); } /** * Sets the runtime logger - this must be called before anything * else. * * @param log The logger instance to use. * @since 1.5 */ public void setLog(Log log) { this.log = log; } /** * @param runtimeLogger * @deprecated Use setLog(Log log) instead. */ public void setRuntimeLogger(RuntimeLogger runtimeLogger) { // in the off chance anyone still uses this method // directly, use this hack to keep it working setLog(new RuntimeLoggerLog(runtimeLogger)); } /** * To support iterative objects used in a #foreach() * loop. * * @param obj The iterative object. * @param i Info about the object's location. * @return An {@link Iterator} object. */ public Iterator getIterator(Object obj, Info i) throws Exception { if (obj.getClass().isArray()) { return new ArrayIterator(obj); } else if (obj instanceof Collection) { return ((Collection) obj).iterator(); } else if (obj instanceof Map) { return ((Map) obj).values().iterator(); } else if (obj instanceof Iterator) { if (log.isDebugEnabled()) { log.debug("The iterative object in the #foreach() loop at " + i + " is of type java.util.Iterator. Because " + "it is not resettable, if used in more than once it " + "may lead to unexpected results."); } return ((Iterator) obj); } else if (obj instanceof Enumeration) { if (log.isDebugEnabled()) { log.debug("The iterative object in the #foreach() loop at " + i + " is of type java.util.Enumeration. Because " + "it is not resettable, if used in more than once it " + "may lead to unexpected results."); } return new EnumerationIterator((Enumeration) obj); } else { // look for an iterator() method to support the JDK5 Iterable // interface or any user tools/DTOs that want to work in // foreach without implementing the Collection interface Class type = obj.getClass(); try { Method iter = type.getMethod("iterator", null); Class returns = iter.getReturnType(); if (Iterator.class.isAssignableFrom(returns)) { try { return (Iterator)iter.invoke(obj, null); } catch (Exception e) { throw new VelocityException("Error invoking the method 'iterator' on class '" + obj.getClass().getName() +"'", e); } } else { log.debug("iterator() method of reference in #foreach loop at " + i + " does not return a true Iterator."); } } catch (NoSuchMethodException nsme) { // eat this one, but let all other exceptions thru } } /* we have no clue what this is */ log.debug("Could not determine type of iterator in #foreach loop at " + i); return null; } /** * Method * @param obj * @param methodName * @param args * @param i * @return A Velocity Method. */ public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i) throws Exception { if (obj == null) { return null; } Method m = introspector.getMethod(obj.getClass(), methodName, args); if (m != null) { return new VelMethodImpl(m); } Class cls = obj.getClass(); // if it's an array if (cls.isArray()) { // check for support via our array->list wrapper m = introspector.getMethod(ArrayListWrapper.class, methodName, args); if (m != null) { // and create a method that knows to wrap the value // before invoking the method return new VelMethodImpl(m, true); } } // watch for classes, to allow calling their static methods (VELOCITY-102) else if (cls == Class.class) { m = introspector.getMethod((Class)obj, methodName, args); if (m != null) { return new VelMethodImpl(m); } } return null; } /** * Property getter * @param obj * @param identifier * @param i * @return A Velocity Getter Method. * @throws Exception */ public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { if (obj == null) { return null; } Class claz = obj.getClass(); /* * first try for a getFoo() type of property * (also getfoo() ) */ AbstractExecutor executor = new PropertyExecutor(log, introspector, claz, identifier); /* * Let's see if we are a map... */ if (!executor.isAlive()) { executor = new MapGetExecutor(log, claz, identifier); } /* * if that didn't work, look for get("foo") */ if (!executor.isAlive()) { executor = new GetExecutor(log, introspector, claz, identifier); } /* * finally, look for boolean isFoo() */ if (!executor.isAlive()) { executor = new BooleanPropertyExecutor(log, introspector, claz, identifier); } return (executor.isAlive()) ? new VelGetterImpl(executor) : null; } /** * Property setter * @param obj * @param identifier * @param arg * @param i * @return A Velocity Setter method. * @throws Exception */ public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { if (obj == null) { return null; } Class claz = obj.getClass(); /* * first try for a setFoo() type of property * (also setfoo() ) */ SetExecutor executor = new SetPropertyExecutor(log, introspector, claz, identifier, arg); /* * Let's see if we are a map... */ if (!executor.isAlive()) { executor = new MapSetExecutor(log, claz, identifier); } /* * if that didn't work, look for put("foo", arg) */ if (!executor.isAlive()) { executor = new PutExecutor(log, introspector, claz, arg, identifier); } return (executor.isAlive()) ? new VelSetterImpl(executor) : null; } /** * Implementation of VelMethod */ public static class VelMethodImpl implements VelMethod { final Method method; Boolean isVarArg; boolean wrapArray; /** * @param m */ public VelMethodImpl(Method m) { this(m, false); } /** * @since 1.6 */ public VelMethodImpl(Method method, boolean wrapArray) { this.method = method; this.wrapArray = wrapArray; } private VelMethodImpl() { method = null; } /** * @see VelMethod#invoke(java.lang.Object, java.lang.Object[]) */ public Object invoke(Object o, Object[] actual) throws Exception { // if we're pretending an array is a list... if (wrapArray) { o = new ArrayListWrapper(o); } if (isVarArg()) { Class[] formal = method.getParameterTypes(); int index = formal.length - 1; if (actual.length >= index) { Class type = formal[index].getComponentType(); actual = handleVarArg(type, index, actual); } } // call extension point invocation return doInvoke(o, actual); } /** * Offers an extension point for subclasses (in alternate Uberspects) * to alter the invocation after any array wrapping or varargs handling * has already been completed. * @since 1.6 */ protected Object doInvoke(Object o, Object[] actual) throws Exception { return method.invoke(o, actual); } /** * @return true if this method can accept a variable number of arguments * @since 1.6 */ public boolean isVarArg() { if (isVarArg == null) { Class[] formal = method.getParameterTypes(); if (formal == null || formal.length == 0) { this.isVarArg = Boolean.FALSE; } else { Class last = formal[formal.length - 1]; // if the last arg is an array, then // we consider this a varargs method this.isVarArg = Boolean.valueOf(last.isArray()); } } return isVarArg.booleanValue(); } /** * @param type The vararg class type (aka component type * of the expected array arg) * @param index The index of the vararg in the method declaration * (This will always be one less than the number of * expected arguments.) * @param actual The actual parameters being passed to this method * @returns The actual parameters adjusted for the varargs in order * to fit the method declaration. */ private Object[] handleVarArg(final Class type, final int index, Object[] actual) { // if no values are being passed into the vararg if (actual.length == index) { // copy existing args to new array Object[] newActual = new Object[actual.length + 1]; System.arraycopy(actual, 0, newActual, 0, actual.length); // create an empty array of the expected type newActual[index] = Array.newInstance(type, 0); actual = newActual; } // if one value is being passed into the vararg else if (actual.length == index + 1 && actual[index] != null) { // make sure the last arg is an array of the expected type Class argClass = actual[index].getClass(); if (!argClass.isArray() && IntrospectionUtils.isMethodInvocationConvertible(type, argClass, false)) { // create a 1-length array to hold and replace the last param Object lastActual = Array.newInstance(type, 1); Array.set(lastActual, 0, actual[index]); actual[index] = lastActual; } } // if multiple values are being passed into the vararg else if (actual.length > index + 1) { // put the last and extra actual in an array of the expected type int size = actual.length - index; Object lastActual = Array.newInstance(type, size); for (int i = 0; i < size; i++) { Array.set(lastActual, i, actual[index + i]); } // put all into a new actual array of the appropriate size Object[] newActual = new Object[index + 1]; for (int i = 0; i < index; i++) { newActual[i] = actual[i]; } newActual[index] = lastActual; // replace the old actual array actual = newActual; } return actual; } /** * @see org.apache.velocity.util.introspection.VelMethod#isCacheable() */ public boolean isCacheable() { return true; } /** * @see org.apache.velocity.util.introspection.VelMethod#getMethodName() */ public String getMethodName() { return method.getName(); } /** * @see org.apache.velocity.util.introspection.VelMethod#getReturnType() */ public Class getReturnType() { return method.getReturnType(); } } /** * * */ public static class VelGetterImpl implements VelPropertyGet { final AbstractExecutor getExecutor; /** * @param exec */ public VelGetterImpl(AbstractExecutor exec) { getExecutor = exec; } private VelGetterImpl() { getExecutor = null; } /** * @see org.apache.velocity.util.introspection.VelPropertyGet#invoke(java.lang.Object) */ public Object invoke(Object o) throws Exception { return getExecutor.execute(o); } /** * @see org.apache.velocity.util.introspection.VelPropertyGet#isCacheable() */ public boolean isCacheable() { return true; } /** * @see org.apache.velocity.util.introspection.VelPropertyGet#getMethodName() */ public String getMethodName() { return getExecutor.isAlive() ? getExecutor.getMethod().getName() : null; } } /** * */ public static class VelSetterImpl implements VelPropertySet { private final SetExecutor setExecutor; /** * @param setExecutor */ public VelSetterImpl(final SetExecutor setExecutor) { this.setExecutor = setExecutor; } private VelSetterImpl() { setExecutor = null; } /** * Invoke the found Set Executor. * * @param o is the Object to invoke it on. * @param value in the Value to set. * @return The resulting Object. * @throws Exception */ public Object invoke(final Object o, final Object value) throws Exception { return setExecutor.execute(o, value); } /** * @see org.apache.velocity.util.introspection.VelPropertySet#isCacheable() */ public boolean isCacheable() { return true; } /** * @see org.apache.velocity.util.introspection.VelPropertySet#getMethodName() */ public String getMethodName() { return setExecutor.isAlive() ? setExecutor.getMethod().getName() : null; } } } velocity-1.7/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java0000644000175000017500000000270510513464370031562 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Holds information for node-local context data introspection * information. * * @author Geir Magnusson Jr. * @version $Id: IntrospectionCacheData.java 463298 2006-10-12 16:10:32Z henning $ */ public class IntrospectionCacheData { /** * Object to pair with class - currently either a Method or * AbstractExecutor. It can be used in any way the using node * wishes. */ public Object thingy; /** * Class of context data object associated with the introspection * information */ public Class contextData; } velocity-1.7/src/java/org/apache/velocity/util/introspection/MethodMap.java0000644000175000017500000003401111363350247027056 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.velocity.util.MapFactory; /** * * @author Jason van Zyl * @author Bob McWhirter * @author Christoph Reck * @author Geir Magnusson Jr. * @author Attila Szegedi * @version $Id: MethodMap.java 935975 2010-04-20 16:04:55Z nbubna $ */ public class MethodMap { private static final int MORE_SPECIFIC = 0; private static final int LESS_SPECIFIC = 1; private static final int INCOMPARABLE = 2; /** * Keep track of all methods with the same name. */ Map methodByNameMap = MapFactory.create(false); /** * Add a method to a list of methods by name. * For a particular class we are keeping track * of all the methods with the same name. * @param method */ public void add(Method method) { String methodName = method.getName(); List l = get( methodName ); if ( l == null) { l = new ArrayList(); methodByNameMap.put(methodName, l); } l.add(method); } /** * Return a list of methods with the same name. * * @param key * @return List list of methods */ public List get(String key) { return (List) methodByNameMap.get(key); } /** *

      * Find a method. Attempts to find the * most specific applicable method using the * algorithm described in the JLS section * 15.12.2 (with the exception that it can't * distinguish a primitive type argument from * an object type argument, since in reflection * primitive type arguments are represented by * their object counterparts, so for an argument of * type (say) java.lang.Integer, it will not be able * to decide between a method that takes int and a * method that takes java.lang.Integer as a parameter. *

      * *

      * This turns out to be a relatively rare case * where this is needed - however, functionality * like this is needed. *

      * * @param methodName name of method * @param args the actual arguments with which the method is called * @return the most specific applicable method, or null if no * method is applicable. * @throws AmbiguousException if there is more than one maximally * specific applicable method */ public Method find(String methodName, Object[] args) throws AmbiguousException { List methodList = get(methodName); if (methodList == null) { return null; } int l = args.length; Class[] classes = new Class[l]; for(int i = 0; i < l; ++i) { Object arg = args[i]; /* * if we are careful down below, a null argument goes in there * so we can know that the null was passed to the method */ classes[i] = arg == null ? null : arg.getClass(); } return getBestMatch(methodList, classes); } private static Method getBestMatch(List methods, Class[] args) { List equivalentMatches = null; Method bestMatch = null; Class[] bestMatchTypes = null; for (Iterator i = methods.iterator(); i.hasNext(); ) { Method method = (Method)i.next(); if (isApplicable(method, args)) { if (bestMatch == null) { bestMatch = method; bestMatchTypes = method.getParameterTypes(); } else { Class[] methodTypes = method.getParameterTypes(); switch (compare(methodTypes, bestMatchTypes)) { case MORE_SPECIFIC: if (equivalentMatches == null) { bestMatch = method; bestMatchTypes = methodTypes; } else { // have to beat all other ambiguous ones... int ambiguities = equivalentMatches.size(); for (int a=0; a < ambiguities; a++) { Method other = (Method)equivalentMatches.get(a); switch (compare(methodTypes, other.getParameterTypes())) { case MORE_SPECIFIC: // ...and thus replace them all... bestMatch = method; bestMatchTypes = methodTypes; equivalentMatches = null; ambiguities = 0; break; case INCOMPARABLE: // ...join them... equivalentMatches.add(method); break; case LESS_SPECIFIC: // ...or just go away. break; } } } break; case INCOMPARABLE: if (equivalentMatches == null) { equivalentMatches = new ArrayList(bestMatchTypes.length); } equivalentMatches.add(method); break; case LESS_SPECIFIC: // do nothing break; } } } } if (equivalentMatches != null) { //System.out.println("ambiguous: "+equivalentMatches);//for debugging only throw new AmbiguousException(); } return bestMatch; } /** * Simple distinguishable exception, used when * we run across ambiguous overloading. Caught * by the introspector. */ public static class AmbiguousException extends RuntimeException { /** * Version Id for serializable */ private static final long serialVersionUID = -2314636505414551663L; } /** * Determines which method signature (represented by a class array) is more * specific. This defines a partial ordering on the method signatures. * @param c1 first signature to compare * @param c2 second signature to compare * @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if * c1 is less specific than c2, INCOMPARABLE if they are incomparable. */ private static int compare(Class[] c1, Class[] c2) { boolean c1MoreSpecific = false; boolean c2MoreSpecific = false; // compare lengths to handle comparisons where the size of the arrays // doesn't match, but the methods are both applicable due to the fact // that one is a varargs method if (c1.length > c2.length) { return MORE_SPECIFIC; } if (c2.length > c1.length) { return LESS_SPECIFIC; } // ok, move on and compare those of equal lengths for(int i = 0; i < c1.length; ++i) { if(c1[i] != c2[i]) { boolean last = (i == c1.length - 1); c1MoreSpecific = c1MoreSpecific || isStrictConvertible(c2[i], c1[i], last) || c2[i] == Object.class;//Object is always least-specific c2MoreSpecific = c2MoreSpecific || isStrictConvertible(c1[i], c2[i], last) || c1[i] == Object.class;//Object is always least-specific } } if(c1MoreSpecific) { if(c2MoreSpecific) { /* * If one method accepts varargs and the other does not, * call the non-vararg one more specific. */ boolean last1Array = c1[c1.length - 1].isArray(); boolean last2Array = c2[c2.length - 1].isArray(); if (last1Array && !last2Array) { return LESS_SPECIFIC; } if (!last1Array && last2Array) { return MORE_SPECIFIC; } /* * Incomparable due to cross-assignable arguments (i.e. * foo(String, Object) vs. foo(Object, String)) */ return INCOMPARABLE; } return MORE_SPECIFIC; } if(c2MoreSpecific) { return LESS_SPECIFIC; } /* * Incomparable due to non-related arguments (i.e. * foo(Runnable) vs. foo(Serializable)) */ return INCOMPARABLE; } /** * Returns true if the supplied method is applicable to actual * argument types. * * @param method method that will be called * @param classes arguments to method * @return true if method is applicable to arguments */ private static boolean isApplicable(Method method, Class[] classes) { Class[] methodArgs = method.getParameterTypes(); if (methodArgs.length > classes.length) { // if there's just one more methodArg than class arg // and the last methodArg is an array, then treat it as a vararg if (methodArgs.length == classes.length + 1 && methodArgs[methodArgs.length - 1].isArray()) { // all the args preceding the vararg must match for (int i = 0; i < classes.length; i++) { if (!isConvertible(methodArgs[i], classes[i], false)) { return false; } } return true; } else { return false; } } else if (methodArgs.length == classes.length) { // this will properly match when the last methodArg // is an array/varargs and the last class is the type of array // (e.g. String when the method is expecting String...) for(int i = 0; i < classes.length; ++i) { if(!isConvertible(methodArgs[i], classes[i], false)) { // if we're on the last arg and the method expects an array if (i == classes.length - 1 && methodArgs[i].isArray()) { // check to see if the last arg is convertible // to the array's component type return isConvertible(methodArgs[i], classes[i], true); } return false; } } } else if (methodArgs.length > 0) // more arguments given than the method accepts; check for varargs { // check that the last methodArg is an array Class lastarg = methodArgs[methodArgs.length - 1]; if (!lastarg.isArray()) { return false; } // check that they all match up to the last method arg for (int i = 0; i < methodArgs.length - 1; ++i) { if (!isConvertible(methodArgs[i], classes[i], false)) { return false; } } // check that all remaining arguments are convertible to the vararg type Class vararg = lastarg.getComponentType(); for (int i = methodArgs.length - 1; i < classes.length; ++i) { if (!isConvertible(vararg, classes[i], false)) { return false; } } } return true; } private static boolean isConvertible(Class formal, Class actual, boolean possibleVarArg) { return IntrospectionUtils. isMethodInvocationConvertible(formal, actual, possibleVarArg); } private static boolean isStrictConvertible(Class formal, Class actual, boolean possibleVarArg) { return IntrospectionUtils. isStrictMethodInvocationConvertible(formal, actual, possibleVarArg); } } velocity-1.7/src/java/org/apache/velocity/util/introspection/IntrospectorCache.java0000644000175000017500000000350211050652577030624 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * The introspector cache API definition. * * @author Henning P. Schmiedehausen * @version $Id: IntrospectorCache.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface IntrospectorCache { /** * Clears the internal cache. */ void clear(); /** * Lookup a given Class object in the cache. If it does not exist, * check whether this is due to a class change and purge the caches * eventually. * * @param c The class to look up. * @return A ClassMap object or null if it does not exist in the cache. */ ClassMap get(Class c); /** * Creates a class map for specific class and registers it in the * cache. Also adds the qualified name to the name->class map * for later Classloader change detection. * * @param c The class for which the class map gets generated. * @return A ClassMap object. */ ClassMap put(Class c); } velocity-1.7/src/java/org/apache/velocity/util/introspection/IntrospectionUtils.java0000644000175000017500000001667211050665114031071 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * * @author Jason van Zyl * @author Bob McWhirter * @author Christoph Reck * @author Geir Magnusson Jr. * @author Attila Szegedi * @author Nathan Bubna * @version $Id: IntrospectionUtils.java 476785 2006-11-19 10:06:21Z henning $ * @since 1.6 */ public class IntrospectionUtils { /** * Determines whether a type represented by a class object is * convertible to another type represented by a class object using a * method invocation conversion, treating object types of primitive * types as if they were primitive types (that is, a Boolean actual * parameter type matches boolean primitive formal type). This behavior * is because this method is used to determine applicable methods for * an actual parameter list, and primitive types are represented by * their object duals in reflective method calls. * * @param formal the formal parameter type to which the actual * parameter type should be convertible * @param actual the actual parameter type. * @param possibleVarArg whether or not we're dealing with the last parameter * in the method declaration * @return true if either formal type is assignable from actual type, * or formal is a primitive type and actual is its corresponding object * type or an object type of a primitive type that can be converted to * the formal type. */ public static boolean isMethodInvocationConvertible(Class formal, Class actual, boolean possibleVarArg) { /* if it's a null, it means the arg was null */ if (actual == null && !formal.isPrimitive()) { return true; } /* Check for identity or widening reference conversion */ if (actual != null && formal.isAssignableFrom(actual)) { return true; } /* Check for boxing with widening primitive conversion. Note that * actual parameters are never primitives. */ if (formal.isPrimitive()) { if(formal == Boolean.TYPE && actual == Boolean.class) return true; if(formal == Character.TYPE && actual == Character.class) return true; if(formal == Byte.TYPE && actual == Byte.class) return true; if(formal == Short.TYPE && (actual == Short.class || actual == Byte.class)) return true; if(formal == Integer.TYPE && (actual == Integer.class || actual == Short.class || actual == Byte.class)) return true; if(formal == Long.TYPE && (actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) return true; if(formal == Float.TYPE && (actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) return true; if(formal == Double.TYPE && (actual == Double.class || actual == Float.class || actual == Long.class || actual == Integer.class || actual == Short.class || actual == Byte.class)) return true; } /* Check for vararg conversion. */ if (possibleVarArg && formal.isArray()) { if (actual.isArray()) { actual = actual.getComponentType(); } return isMethodInvocationConvertible(formal.getComponentType(), actual, false); } return false; } /** * Determines whether a type represented by a class object is * convertible to another type represented by a class object using a * method invocation conversion, without matching object and primitive * types. This method is used to determine the more specific type when * comparing signatures of methods. * * @param formal the formal parameter type to which the actual * parameter type should be convertible * @param actual the actual parameter type. * @param possibleVarArg whether or not we're dealing with the last parameter * in the method declaration * @return true if either formal type is assignable from actual type, * or formal and actual are both primitive types and actual can be * subject to widening conversion to formal. */ public static boolean isStrictMethodInvocationConvertible(Class formal, Class actual, boolean possibleVarArg) { /* we shouldn't get a null into, but if so */ if (actual == null && !formal.isPrimitive()) { return true; } /* Check for identity or widening reference conversion */ if(formal.isAssignableFrom(actual)) { return true; } /* Check for widening primitive conversion. */ if(formal.isPrimitive()) { if(formal == Short.TYPE && (actual == Byte.TYPE)) return true; if(formal == Integer.TYPE && (actual == Short.TYPE || actual == Byte.TYPE)) return true; if(formal == Long.TYPE && (actual == Integer.TYPE || actual == Short.TYPE || actual == Byte.TYPE)) return true; if(formal == Float.TYPE && (actual == Long.TYPE || actual == Integer.TYPE || actual == Short.TYPE || actual == Byte.TYPE)) return true; if(formal == Double.TYPE && (actual == Float.TYPE || actual == Long.TYPE || actual == Integer.TYPE || actual == Short.TYPE || actual == Byte.TYPE)) return true; } /* Check for vararg conversion. */ if (possibleVarArg && formal.isArray()) { if (actual.isArray()) { actual = actual.getComponentType(); } return isStrictMethodInvocationConvertible(formal.getComponentType(), actual, false); } return false; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/ChainableUberspector.java0000644000175000017500000000235511053266633031273 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Interface that marks uberspectors as chainable, meaning that multiple uberspectors can be * combined in a chain (using the Decorator pattern). * * @version $Id: $ * @since 1.6 */ public interface ChainableUberspector extends Uberspect { /** * Specify the decorated Uberspector * * @param inner The decorated uberspector. */ public void wrap(Uberspect inner); } velocity-1.7/src/java/org/apache/velocity/util/introspection/SecureIntrospectorImpl.java0000644000175000017500000001225511075735346031701 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Method; import org.apache.velocity.runtime.log.Log; /** *

      Prevent "dangerous" classloader/reflection related calls. Use this * introspector for situations in which template writers are numerous * or untrusted. Specifically, this introspector prevents creation of * arbitrary objects and prevents reflection on objects. * *

      See documentation of checkObjectExecutePermission() for * more information on specific classes and methods blocked. * * @author Will Glass-Husain * @version $Id: SecureIntrospectorImpl.java 705375 2008-10-16 22:06:30Z nbubna $ * @since 1.5 */ public class SecureIntrospectorImpl extends Introspector implements SecureIntrospectorControl { private String[] badClasses; private String[] badPackages; public SecureIntrospectorImpl(String[] badClasses, String[] badPackages, Log log) { super(log); this.badClasses = badClasses; this.badPackages = badPackages; } /** * Get the Method object corresponding to the given class, name and parameters. * Will check for appropriate execute permissions and return null if the method * is not allowed to be executed. * * @param clazz Class on which method will be called * @param methodName Name of method to be called * @param params array of parameters to method * @return Method object retrieved by Introspector * @throws IllegalArgumentException The parameter passed in were incorrect. */ public Method getMethod(Class clazz, String methodName, Object[] params) throws IllegalArgumentException { if (!checkObjectExecutePermission(clazz, methodName)) { log.warn("Cannot retrieve method " + methodName + " from object of class " + clazz.getName() + " due to security restrictions."); return null; } else { return super.getMethod(clazz, methodName, params); } } /** * Determine which methods and classes to prevent from executing. Always blocks * methods wait() and notify(). Always allows methods on Number, Boolean, and String. * Prohibits method calls on classes related to reflection and system operations. * For the complete list, see the properties introspector.restrict.classes * and introspector.restrict.packages. * * @param clazz Class on which method will be called * @param methodName Name of method to be called * @see org.apache.velocity.util.introspection.SecureIntrospectorControl#checkObjectExecutePermission(java.lang.Class, java.lang.String) */ public boolean checkObjectExecutePermission(Class clazz, String methodName) { /** * check for wait and notify */ if (methodName != null && (methodName.equals("wait") || methodName.equals("notify")) ) { return false; } /** * Always allow the most common classes - Number, Boolean and String */ else if (Number.class.isAssignableFrom(clazz)) { return true; } else if (Boolean.class.isAssignableFrom(clazz)) { return true; } else if (String.class.isAssignableFrom(clazz)) { return true; } /** * Always allow Class.getName() */ else if (Class.class.isAssignableFrom(clazz) && (methodName != null) && methodName.equals("getName")) { return true; } /** * check the classname (minus any array info) * whether it matches disallowed classes or packages */ String className = clazz.getName(); if (className.startsWith("[L") && className.endsWith(";")) { className = className.substring(2, className.length() - 1); } int dotPos = className.lastIndexOf('.'); String packageName = (dotPos == -1) ? "" : className.substring(0, dotPos); for (int i = 0, size = badPackages.length; i < size; i++) { if (packageName.equals(badPackages[i])) { return false; } } for (int i = 0, size = badClasses.length; i < size; i++) { if (className.equals(badClasses[i])) { return false; } } return true; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java0000644000175000017500000000763111050652577030502 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Method; import org.apache.velocity.runtime.log.Log; /** * Lookup a a Method object for a particular class given the name of a method * and its parameters. * * The first time the Introspector sees a * class it creates a class method map for the * class in question. Basically the class method map * is a Hashtable where Method objects are keyed by a * concatenation of the method name and the names of * classes that make up the parameters. * * For example, a method with the following signature: * * public void method(String a, StringBuffer b) * * would be mapped by the key: * * "method" + "java.lang.String" + "java.lang.StringBuffer" * * This mapping is performed for all the methods in a class * and stored for. * @author Jason van Zyl * @author Bob McWhirter * @author Attila Szegedi * @author Paulo Gaspar * @author Henning P. Schmiedehausen * @version $Id: IntrospectorBase.java 685685 2008-08-13 21:43:27Z nbubna $ */ public abstract class IntrospectorBase { /** Class logger */ protected final Log log; /** The Introspector Cache */ private final IntrospectorCache introspectorCache; /** * C'tor. */ protected IntrospectorBase(final Log log) { this.log = log; introspectorCache = new IntrospectorCacheImpl(log); // TODO: Load that from properties. } /** * Gets the method defined by name and * params for the Class c. * * @param c Class in which the method search is taking place * @param name Name of the method being searched for * @param params An array of Objects (not Classes) that describe the * the parameters * * @return The desired Method object. * @throws IllegalArgumentException When the parameters passed in can not be used for introspection. * @throws MethodMap.AmbiguousException When the method map contains more than one match for the requested signature. */ public Method getMethod(final Class c, final String name, final Object[] params) throws IllegalArgumentException,MethodMap.AmbiguousException { if (c == null) { throw new IllegalArgumentException ("class object is null!"); } if (params == null) { throw new IllegalArgumentException("params object is null!"); } IntrospectorCache ic = getIntrospectorCache(); ClassMap classMap = ic.get(c); if (classMap == null) { classMap = ic.put(c); } return classMap.findMethod(name, params); } /** * Return the internal IntrospectorCache object. * * @return The internal IntrospectorCache object. * @since 1.5 */ protected IntrospectorCache getIntrospectorCache() { return introspectorCache; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/VelMethod.java0000644000175000017500000000363510567364664027114 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Method used for regular method invocation * * $foo.bar() * * * @author Geir Magnusson Jr. * @version $Id: VelMethod.java 510625 2007-02-22 19:06:28Z nbubna $ */ public interface VelMethod { /** * invocation method - called when the method invocation should be * performed and a value returned * @param o * @param params * @return The resulting object. * @throws Exception */ public Object invoke(Object o, Object[] params) throws Exception; /** * specifies if this VelMethod is cacheable and able to be * reused for this class of object it was returned for * * @return true if can be reused for this class, false if not */ public boolean isCacheable(); /** * returns the method name used * @return The method name used */ public String getMethodName(); /** * returns the return type of the method invoked * @return The return type of the method invoked */ public Class getReturnType(); } velocity-1.7/src/java/org/apache/velocity/util/introspection/UberspectLoggable.java0000644000175000017500000000314710513464370030576 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; /** * Marker interface to let an uberspector indicate it can and wants to * log * * Thanks to Paulo for the suggestion * * @author Nathan Bubna * @author Geir Magnusson Jr. * @version $Id: UberspectLoggable.java 463298 2006-10-12 16:10:32Z henning $ * */ public interface UberspectLoggable { /** * Sets the logger. This will be called before any calls to the * uberspector * @param log */ public void setLog(Log log); /** * @param logger * @deprecated Use setLog(Log log) instead. */ public void setRuntimeLogger(RuntimeLogger logger); } velocity-1.7/src/java/org/apache/velocity/util/introspection/Introspector.java0000644000175000017500000001036711052641200027666 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.lang.reflect.Method; import org.apache.velocity.runtime.RuntimeLogger; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.log.RuntimeLoggerLog; /** * This basic function of this class is to return a Method * object for a particular class given the name of a method * and the parameters to the method in the form of an Object[] * * The first time the Introspector sees a * class it creates a class method map for the * class in question. Basically the class method map * is a Hastable where Method objects are keyed by a * concatenation of the method name and the names of * classes that make up the parameters. * * For example, a method with the following signature: * * public void method(String a, StringBuffer b) * * would be mapped by the key: * * "method" + "java.lang.String" + "java.lang.StringBuffer" * * This mapping is performed for all the methods in a class * and stored for * @author Jason van Zyl * @author Bob McWhirter * @author Attila Szegedi * @author Paulo Gaspar * @author Henning P. Schmiedehausen * @version $Id: Introspector.java 687177 2008-08-19 22:00:32Z nbubna $ */ public class Introspector extends IntrospectorBase { /** * @param log A Log object to use for the introspector. * @since 1.5 */ public Introspector(final Log log) { super(log); } /** * @param logger A runtime logger object. * @deprecated RuntimeLogger is deprecated. Use Introspector(Log log). */ public Introspector(final RuntimeLogger logger) { this(new RuntimeLoggerLog(logger)); } /** * Gets the method defined by name and * params for the Class c. * * @param c Class in which the method search is taking place * @param name Name of the method being searched for * @param params An array of Objects (not Classes) that describe the * the parameters * * @return The desired Method object. * @throws IllegalArgumentException When the parameters passed in can not be used for introspection. */ public Method getMethod(final Class c, final String name, final Object[] params) throws IllegalArgumentException { try { return super.getMethod(c, name, params); } catch(MethodMap.AmbiguousException ae) { /* * whoops. Ambiguous. Make a nice log message and return null... */ StringBuffer msg = new StringBuffer("Introspection Error : Ambiguous method invocation ") .append(name) .append("("); for (int i = 0; i < params.length; i++) { if (i > 0) { msg.append(", "); } if (params[i] == null) { msg.append("null"); } else { msg.append(params[i].getClass().getName()); } } msg.append(") for class ") .append(c); log.debug(msg.toString()); } return null; } } velocity-1.7/src/java/org/apache/velocity/util/introspection/Info.java0000644000175000017500000000502611132301434026063 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.node.Node; /** * Little class to carry in info such as template name, line and column * for information error reporting from the uberspector implementations * * @author Geir Magnusson Jr. * @version $Id: Info.java 733416 2009-01-11 05:26:52Z byron $ */ public class Info { private int line; private int column; private String templateName; /** * @param source Usually a template name. * @param line The line number from source. * @param column The column number from source. */ public Info(String source, int line, int column) { this.templateName = source; this.line = line; this.column = column; } public Info(Node node) { this(node.getTemplateName(), node.getLine(), node.getColumn()); } /** * Force callers to set the location information. */ private Info() { } /** * @return The template name. */ public String getTemplateName() { return templateName; } /** * @return The line number. */ public int getLine() { return line; } /** * @return The column number. */ public int getColumn() { return column; } /** * Formats a textual representation of this object as SOURCE * [line X, column Y]. * * @return String representing this object. * @since 1.5 */ public String toString() { return Log.formatFileString(getTemplateName(), getLine(), getColumn()); } } velocity-1.7/src/java/org/apache/velocity/util/introspection/VelPropertyGet.java0000644000175000017500000000350410513464370030135 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ /** * Interface defining a 'getter'. For uses when looking for resolution of * property references * * $foo.bar * * @author Geir Magnusson Jr. * @version $Id: VelPropertyGet.java 463298 2006-10-12 16:10:32Z henning $ */ public interface VelPropertyGet { /** * invocation method - called when the 'get action' should be * preformed and a value returned * @param o * @return The resulting Object. * @throws Exception */ public Object invoke(Object o) throws Exception; /** * specifies if this VelPropertyGet is cacheable and able to be * reused for this class of object it was returned for * * @return true if can be reused for this class, false if not */ public boolean isCacheable(); /** * returns the method name used to return this 'property' * @return The method name used to return this 'property' */ public String getMethodName(); } velocity-1.7/src/java/org/apache/velocity/util/introspection/Uberspect.java0000644000175000017500000000454411202566437027146 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; /** * 'Federated' introspection/reflection interface to allow the introspection * behavior in Velocity to be customized. * * @author Geir Magusson Jr. * @version $Id: Uberspect.java 774412 2009-05-13 15:54:07Z nbubna $ */ public interface Uberspect { /** * Initializer - will be called before use */ public void init(); /** * To support iteratives - #foreach() * @param obj * @param info * @return An Iterator. */ public Iterator getIterator(Object obj, Info info) throws Exception; /** * Returns a general method, corresponding to $foo.bar( $woogie ) * @param obj * @param method * @param args * @param info * @return A Velocity Method. */ public VelMethod getMethod(Object obj, String method, Object[] args, Info info) throws Exception; /** * Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie) * @param obj * @param identifier * @param info * @return A Velocity Getter. */ public VelPropertyGet getPropertyGet(Object obj, String identifier, Info info) throws Exception; /** * Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir") * @param obj * @param identifier * @param arg * @param info * @return A Velocity Setter. */ public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info info) throws Exception; } velocity-1.7/src/java/org/apache/velocity/util/SimplePool.java0000644000175000017500000000601610513464370024366 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ /** * Simple object pool. Based on ThreadPool and few other classes * * The pool will ignore overflow and return null if empty. * * @author Gal Shachor * @author Costin * @author Geir Magnusson Jr. * @version $Id: SimplePool.java 463298 2006-10-12 16:10:32Z henning $ */ public final class SimplePool { /* * Where the objects are held. */ private Object pool[]; /** * max amount of objects to be managed * set via CTOR */ private int max; /** * index of previous to next * free slot */ private int current=-1; /** * @param max */ public SimplePool(int max) { this.max = max; pool = new Object[max]; } /** * Add the object to the pool, silent nothing if the pool is full * @param o */ public void put(Object o) { int idx=-1; synchronized(this) { /* * if we aren't full */ if (current < max - 1) { /* * then increment the * current index. */ idx = ++current; } if (idx >= 0) { pool[idx] = o; } } } /** * Get an object from the pool, null if the pool is empty. * @return The object from the pool. */ public Object get() { synchronized(this) { /* * if we have any in the pool */ if( current >= 0 ) { /* * remove the current one */ Object o = pool[current]; pool[current] = null; current--; return o; } } return null; } /** * Return the size of the pool * @return The pool size. */ public int getMax() { return max; } /** * for testing purposes, so we can examine the pool * * @return Array of Objects in the pool. */ Object[] getPool() { return pool; } } velocity-1.7/src/java/org/apache/velocity/util/ContextAware.java0000644000175000017500000000340311050652577024711 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import org.apache.velocity.context.Context; /** * Event handlers implementing this interface will automatically * have the method setContext called before each event. This * allows the event handler to use information in the latest context * when responding to the event. * *

      Important Note: Only local event handlers attached to the context * (as opposed to global event handlers initialized in the velocity.properties * file) should implement ContextAware. Since global event handlers are * singletons individual requests will not be able to count on the * correct context being loaded before a request. * * @author Will Glass-Husain * @version $Id: ContextAware.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface ContextAware { /** * Initialize the EventHandler. * @param context */ public void setContext( Context context ); } velocity-1.7/src/java/org/apache/velocity/util/TemplateNumber.java0000644000175000017500000000240411050652577025231 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ /** * Any object in the context which implements TemplateNumber will be treated * as a number for the purposes of arithmetic operations and comparison. * * @author Will Glass-Husain * @since 1.5 */ public interface TemplateNumber { /** * Returns a Number that can be used in a template. * @return A Number that can be used in a template. */ public Number getAsNumber(); } velocity-1.7/src/java/org/apache/velocity/util/MapFactory.java0000755000175000017500000001072111206070062024340 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.lang.reflect.Constructor; import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; /** * Factory class for creating Maps. * * The main purpose of this class is to take advantage of Java 5 * Concurrent classes if they are available. We use reflection to instantiate * java.util.concurrent classes to avoid compile time dependency on Java 5. * * See Issue 607 * for more info on this class. * @author Jarkko Viinamaki * @since 1.6 */ public class MapFactory { private static Constructor concurrentHashMapConstructor; static { try { concurrentHashMapConstructor = Class.forName("java.util.concurrent.ConcurrentHashMap") .getConstructor(new Class[] { int.class, float.class, int.class } ); } catch (Exception ex) { // not running under JRE 1.5+ } } /** * Creates a new instance of a class that implements Map interface * using the JDK defaults for initial size, load factor, etc. * * Note that there is a small performance penalty because concurrent * maps are created using reflection. * * @param allowNullKeys if true, the returned Map instance supports null keys * @return one of ConcurrentHashMap, HashMap, Hashtable */ public static Map create(boolean allowNullKeys) { return create(16, 0.75f, 16, allowNullKeys); } /** * Creates a new instance of a class that implements Map interface. * * Note that there is a small performance penalty because concurrent * maps are created using reflection. * * @param size initial size of the map * @param loadFactor smaller value = better performance, * larger value = better memory utilization * @param concurrencyLevel estimated number of writer Threads. * If this is smaller than 1, HashMap is always returned which is not * threadsafe. * @param allowNullKeys if true, the returned Map instance supports null keys * * @return one of ConcurrentHashMap, HashMap, Hashtable */ public static Map create(int size, float loadFactor, int concurrencyLevel, boolean allowNullKeys) { Map map = null; if (concurrencyLevel <= 1) { map = new HashMap(size, loadFactor); } else { if (concurrentHashMapConstructor != null) { // running under JRE 1.5+ try { map = (Map)concurrentHashMapConstructor.newInstance( new Object[] { new Integer(size), new Float(loadFactor), new Integer(concurrencyLevel) }); } catch (Exception ex) { throw new RuntimeException("this should not happen", ex); } } else { /* * Hashtable should be faster than * Collections.synchronizedMap(new HashMap()); * so favor it if there is no need for null key support */ if (allowNullKeys) { map = Collections.synchronizedMap(new HashMap(size, loadFactor)); } else { map = new Hashtable(size, loadFactor); } } } return map; } } velocity-1.7/src/java/org/apache/velocity/util/ClassUtils.java0000644000175000017500000002206211322700447024365 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.io.InputStream; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.parser.node.ASTMethod.MethodCacheKey; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.IntrospectionCacheData; import org.apache.velocity.util.introspection.VelMethod; /** * Simple utility functions for manipulating classes and resources * from the classloader. * * @author Will Glass-Husain * @version $Id: ClassUtils.java 898032 2010-01-11 19:51:03Z nbubna $ * @since 1.5 */ public class ClassUtils { /** * Utility class; cannot be instantiated. */ private ClassUtils() { } /** * Return the specified class. Checks the ThreadContext classloader first, * then uses the System classloader. Should replace all calls to * Class.forName( claz ) (which only calls the System class * loader) when the class might be in a different classloader (e.g. in a * webapp). * * @param clazz the name of the class to instantiate * @return the requested Class object * @throws ClassNotFoundException */ public static Class getClass(String clazz) throws ClassNotFoundException { /** * Use the Thread context classloader if possible */ ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader != null) { try { return Class.forName(clazz, true, loader); } catch (ClassNotFoundException E) { /** * If not found with ThreadContext loader, fall thru to * try System classloader below (works around bug in ant). */ } } /** * Thread context classloader isn't working out, so use system loader. */ return Class.forName(clazz); } /** * Return a new instance of the given class. Checks the ThreadContext * classloader first, then uses the System classloader. Should replace all * calls to Class.forName( claz ).newInstance() (which only * calls the System class loader) when the class might be in a different * classloader (e.g. in a webapp). * * @param clazz the name of the class to instantiate * @return an instance of the specified class * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ public static Object getNewInstance(String clazz) throws ClassNotFoundException,IllegalAccessException,InstantiationException { return getClass(clazz).newInstance(); } /** * Finds a resource with the given name. Checks the Thread Context * classloader, then uses the System classloader. Should replace all * calls to Class.getResourceAsString when the resource * might come from a different classloader. (e.g. a webapp). * @param claz Class to use when getting the System classloader (used if no Thread * Context classloader available or fails to get resource). * @param name name of the resource * @return InputStream for the resource. */ public static InputStream getResourceAsStream(Class claz, String name) { InputStream result = null; /** * remove leading slash so path will work with classes in a JAR file */ while (name.startsWith("/")) { name = name.substring(1); } ClassLoader classLoader = Thread.currentThread() .getContextClassLoader(); if (classLoader == null) { classLoader = claz.getClassLoader(); result = classLoader.getResourceAsStream( name ); } else { result= classLoader.getResourceAsStream( name ); /** * for compatibility with texen / ant tasks, fall back to * old method when resource is not found. */ if (result == null) { classLoader = claz.getClassLoader(); if (classLoader != null) result = classLoader.getResourceAsStream( name ); } } return result; } /** * Lookup a VelMethod object given the method signature that is specified in * the passed in parameters. This method first searches the cache, if not found in * the cache then uses reflections to inspect Object o, for the given method. * @param methodName Name of method * @param params Array of objects that are parameters to the method * @param paramClasses Array of Classes coresponding to the types in params. * @param o Object to introspect for the given method. * @param context Context from which the method cache is aquirred * @param node ASTNode, used for error reporting. * @param strictRef If no method is found, throw an exception, never return null in this case * @return VelMethod object if the object is found, null if not matching method is found */ public static VelMethod getMethod(String methodName, Object[] params, Class[] paramClasses, Object o, InternalContextAdapter context, SimpleNode node, boolean strictRef) { VelMethod method = null; try { /* * check the cache */ MethodCacheKey mck = new MethodCacheKey(methodName, paramClasses); IntrospectionCacheData icd = context.icacheGet(mck); /* * like ASTIdentifier, if we have cache information, and the Class of * Object o is the same as that in the cache, we are safe. */ if (icd != null && (o != null && icd.contextData == o.getClass())) { /* * get the method from the cache */ method = (VelMethod) icd.thingy; } else { /* * otherwise, do the introspection, and then cache it */ method = node.getRuntimeServices().getUberspect().getMethod(o, methodName, params, new Info(node.getTemplateName(), node.getLine(), node.getColumn())); if ((method != null) && (o != null)) { icd = new IntrospectionCacheData(); icd.contextData = o.getClass(); icd.thingy = method; context.icachePut(mck, icd); } } /* * if we still haven't gotten the method, either we are calling a method * that doesn't exist (which is fine...) or I screwed it up. */ if (method == null) { if (strictRef) { // Create a parameter list for the exception error message StringBuffer plist = new StringBuffer(); for (int i = 0; i < params.length; i++) { Class param = paramClasses[i]; plist.append(param == null ? "null" : param.getName()); if (i < params.length - 1) plist.append(", "); } throw new MethodInvocationException("Object '" + o.getClass().getName() + "' does not contain method " + methodName + "(" + plist + ")", null, methodName, node .getTemplateName(), node.getLine(), node.getColumn()); } else { return null; } } } catch (MethodInvocationException mie) { /* * this can come from the doIntrospection(), as the arg values are * evaluated to find the right method signature. We just want to propogate * it here, not do anything fancy */ throw mie; } catch (RuntimeException e) { /** * pass through application level runtime exceptions */ throw e; } catch (Exception e) { /* * can come from the doIntropection() also, from Introspector */ String msg = "ASTMethod.execute() : exception from introspection"; throw new VelocityException(msg, e); } return method; } } velocity-1.7/src/java/org/apache/velocity/util/RuntimeServicesAware.java0000644000175000017500000000273211050652577026420 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; /** * Use this interface to automatically * have the method setRuntimeServices called at initialization. * Applies to EventHandler and Uberspect implementations. * * @author Will Glass-Husain * @version $Id: RuntimeServicesAware.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface RuntimeServicesAware { /** * Called automatically when event cartridge is initialized. * @param rs RuntimeServices object assigned during initialization */ public void setRuntimeServices( RuntimeServices rs ); } velocity-1.7/src/java/org/apache/velocity/util/StringUtils.java0000644000175000017500000004303111050652577024575 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.StringTokenizer; /** * This class provides some methods for dynamically * invoking methods in objects, and some string * manipulation methods used by torque. The string * methods will soon be moved into the turbine * string utilities class. * * @author Jason van Zyl * @author Daniel Rall * @version $Id: StringUtils.java 685685 2008-08-13 21:43:27Z nbubna $ */ public class StringUtils { /** * Line separator for the OS we are operating on. */ private static final String EOL = System.getProperty("line.separator"); /** * Concatenates a list of objects as a String. * * @param list The list of objects to concatenate. * @return A text representation of the concatenated objects. */ public String concat(List list) { StringBuffer sb = new StringBuffer(); int size = list.size(); for (int i = 0; i < size; i++) { sb.append(list.get(i).toString()); } return sb.toString(); } /** * Return a package name as a relative path name * * @param pckge package name to convert to a directory. * @return String directory path. */ static public String getPackageAsPath(String pckge) { return pckge.replace( '.', File.separator.charAt(0) ) + File.separator; } /** *

      * Remove underscores from a string and replaces first * letters with capitals. Other letters are changed to lower case. *

      * *

      * For example foo_bar becomes FooBar * but foo_barBar becomes FooBarbar. *

      * * @param data string to remove underscores from. * @return String * @deprecated Use the org.apache.commons.util.StringUtils class * instead. Using its firstLetterCaps() method in conjunction * with a StringTokenizer will achieve the same result. */ static public String removeUnderScores (String data) { String temp = null; StringBuffer out = new StringBuffer(); temp = data; StringTokenizer st = new StringTokenizer(temp, "_"); while (st.hasMoreTokens()) { String element = (String) st.nextElement(); out.append ( firstLetterCaps(element)); } return out.toString(); } /** *

      * 'Camels Hump' replacement of underscores. *

      * *

      * Remove underscores from a string but leave the capitalization of the * other letters unchanged. *

      * *

      * For example foo_barBar becomes FooBarBar. *

      * * @param data string to hump * @return String */ static public String removeAndHump (String data) { return removeAndHump(data,"_"); } /** *

      * 'Camels Hump' replacement. *

      * *

      * Remove one string from another string but leave the capitalization of the * other letters unchanged. *

      * *

      * For example, removing "_" from foo_barBar becomes FooBarBar. *

      * * @param data string to hump * @param replaceThis string to be replaced * @return String */ static public String removeAndHump (String data,String replaceThis) { String temp = null; StringBuffer out = new StringBuffer(); temp = data; StringTokenizer st = new StringTokenizer(temp, replaceThis); while (st.hasMoreTokens()) { String element = (String) st.nextElement(); out.append ( capitalizeFirstLetter(element)); }//while return out.toString(); } /** *

      * Makes the first letter caps and the rest lowercase. *

      * *

      * For example fooBar becomes Foobar. *

      * * @param data capitalize this * @return String */ static public String firstLetterCaps ( String data ) { String firstLetter = data.substring(0,1).toUpperCase(); String restLetters = data.substring(1).toLowerCase(); return firstLetter + restLetters; } /** *

      * Capitalize the first letter but leave the rest as they are. *

      * *

      * For example fooBar becomes FooBar. *

      * * @param data capitalize this * @return String */ static public String capitalizeFirstLetter ( String data ) { String firstLetter = data.substring(0,1).toUpperCase(); String restLetters = data.substring(1); return firstLetter + restLetters; } /** * Create a string array from a string separated by delim * * @param line the line to split * @param delim the delimter to split by * @return a string array of the split fields */ public static String [] split(String line, String delim) { List list = new ArrayList(); StringTokenizer t = new StringTokenizer(line, delim); while (t.hasMoreTokens()) { list.add(t.nextToken()); } return (String []) list.toArray(new String[list.size()]); } /** * Chop i characters off the end of a string. * This method assumes that any EOL characters in String s * and the platform EOL will be the same. * A 2 character EOL will count as 1 character. * * @param s String to chop. * @param i Number of characters to chop. * @return String with processed answer. */ public static String chop(String s, int i) { return chop(s, i, EOL); } /** * Chop i characters off the end of a string. * A 2 character EOL will count as 1 character. * * @param s String to chop. * @param i Number of characters to chop. * @param eol A String representing the EOL (end of line). * @return String with processed answer. */ public static String chop(String s, int i, String eol) { if ( i == 0 || s == null || eol == null ) { return s; } int length = s.length(); /* * if it is a 2 char EOL and the string ends with * it, nip it off. The EOL in this case is treated like 1 character */ if ( eol.length() == 2 && s.endsWith(eol )) { length -= 2; i -= 1; } if ( i > 0) { length -= i; } if ( length < 0) { length = 0; } return s.substring( 0, length); } /** * @param argStr * @param vars * @return Substituted String. */ public static StringBuffer stringSubstitution( String argStr, Hashtable vars ) { return stringSubstitution( argStr, (Map) vars ); } /** * Perform a series of substitutions. The substitions * are performed by replacing $variable in the target * string with the value of provided by the key "variable" * in the provided hashtable. * * @param argStr target string * @param vars name/value pairs used for substitution * @return String target string with replacements. */ public static StringBuffer stringSubstitution(String argStr, Map vars) { StringBuffer argBuf = new StringBuffer(); for (int cIdx = 0 ; cIdx < argStr.length();) { char ch = argStr.charAt(cIdx); switch (ch) { case '$': StringBuffer nameBuf = new StringBuffer(); for (++cIdx ; cIdx < argStr.length(); ++cIdx) { ch = argStr.charAt(cIdx); if (ch == '_' || Character.isLetterOrDigit(ch)) nameBuf.append(ch); else break; } if (nameBuf.length() > 0) { String value = (String) vars.get(nameBuf.toString()); if (value != null) { argBuf.append(value); } } break; default: argBuf.append(ch); ++cIdx; break; } } return argBuf; } /** * Read the contents of a file and place them in * a string object. * * @param file path to file. * @return String contents of the file. */ public static String fileContentsToString(String file) { String contents = ""; File f = null; try { f = new File(file); if (f.exists()) { FileReader fr = null; try { fr = new FileReader(f); char[] template = new char[(int) f.length()]; fr.read(template); contents = new String(template); } catch (Exception e) { e.printStackTrace(); } finally { if (fr != null) { fr.close(); } } } } catch (Exception e) { e.printStackTrace(); } return contents; } /** * Remove/collapse multiple newline characters. * * @param argStr string to collapse newlines in. * @return String */ public static String collapseNewlines(String argStr) { char last = argStr.charAt(0); StringBuffer argBuf = new StringBuffer(); for (int cIdx = 0 ; cIdx < argStr.length(); cIdx++) { char ch = argStr.charAt(cIdx); if (ch != '\n' || last != '\n') { argBuf.append(ch); last = ch; } } return argBuf.toString(); } /** * Remove/collapse multiple spaces. * * @param argStr string to remove multiple spaces from. * @return String */ public static String collapseSpaces(String argStr) { char last = argStr.charAt(0); StringBuffer argBuf = new StringBuffer(); for (int cIdx = 0 ; cIdx < argStr.length(); cIdx++) { char ch = argStr.charAt(cIdx); if (ch != ' ' || last != ' ') { argBuf.append(ch); last = ch; } } return argBuf.toString(); } /** * Replaces all instances of oldString with newString in line. * Taken from the Jive forum package. * * @param line original string. * @param oldString string in line to replace. * @param newString replace oldString with this. * @return String string with replacements. */ public static final String sub(String line, String oldString, String newString) { int i = 0; if ((i = line.indexOf(oldString, i)) >= 0) { char [] line2 = line.toCharArray(); char [] newString2 = newString.toCharArray(); int oLength = oldString.length(); StringBuffer buf = new StringBuffer(line2.length); buf.append(line2, 0, i).append(newString2); i += oLength; int j = i; while ((i = line.indexOf(oldString, i)) > 0) { buf.append(line2, j, i - j).append(newString2); i += oLength; j = i; } buf.append(line2, j, line2.length - j); return buf.toString(); } return line; } /** * Returns the output of printStackTrace as a String. * * @param e A Throwable. * @return A String. */ public static final String stackTrace(Throwable e) { String foo = null; try { // And show the Error Screen. ByteArrayOutputStream ostr = new ByteArrayOutputStream(); e.printStackTrace( new PrintWriter(ostr,true) ); foo = ostr.toString(); } catch (Exception f) { // Do nothing. } return foo; } /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements * are resolved out. If the specified path attempts to go outside the * boundaries of the current context (i.e. too many ".." path elements * are present), return null instead. * * @param path Path to be normalized * @return String normalized path */ public static final String normalizePath(String path) { // Normalize the slashes and add leading slash if necessary String normalized = path; if (normalized.indexOf('\\') >= 0) { normalized = normalized.replace('\\', '/'); } if (!normalized.startsWith("/")) { normalized = "/" + normalized; } // Resolve occurrences of "//" in the normalized path while (true) { int index = normalized.indexOf("//"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 1); } // Resolve occurrences of "%20" in the normalized path while (true) { int index = normalized.indexOf("%20"); if (index < 0) break; normalized = normalized.substring(0, index) + " " + normalized.substring(index + 3); } // Resolve occurrences of "/./" in the normalized path while (true) { int index = normalized.indexOf("/./"); if (index < 0) break; normalized = normalized.substring(0, index) + normalized.substring(index + 2); } // Resolve occurrences of "/../" in the normalized path while (true) { int index = normalized.indexOf("/../"); if (index < 0) break; if (index == 0) return (null); // Trying to go outside our context int index2 = normalized.lastIndexOf('/', index - 1); normalized = normalized.substring(0, index2) + normalized.substring(index + 3); } // Return the normalized path that we have completed return (normalized); } /** * If state is true then return the trueString, else * return the falseString. * * @param state * @param trueString * @param falseString * @return Selected result. */ public String select(boolean state, String trueString, String falseString) { if (state) { return trueString; } else { return falseString; } } /** * Check to see if all the string objects passed * in are empty. * * @param list A list of {@link java.lang.String} objects. * @return Whether all strings are empty. */ public boolean allEmpty(List list) { int size = list.size(); for (int i = 0; i < size; i++) { if (list.get(i) != null && list.get(i).toString().length() > 0) { return false; } } return true; } /** * Trim all strings in a List. Changes the strings in the existing list. * @param list * @return List of trimmed strings. * @since 1.5 */ public static List trimStrings(List list) { if (list == null) return null; int sz = list.size(); for (int i = 0; i < sz; i++) list.set(i,nullTrim((String) list.get(i))); return list; } /** * Trim the string, but pass a null through. * @param s * @return List of trimmed Strings. * @since 1.5 */ public static String nullTrim(String s) { if (s == null) { return null; } else { return s.trim(); } } } velocity-1.7/src/java/org/apache/velocity/util/ArrayIterator.java0000644000175000017500000000627510513464370025102 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.util.Iterator; import java.util.NoSuchElementException; import java.lang.reflect.Array; /** *

      * An Iterator wrapper for an Object[]. This will * allow us to deal with all array like structures * in a consistent manner. *

      *

      * WARNING : this class's operations are NOT synchronized. * It is meant to be used in a single thread, newly created * for each use in the #foreach() directive. * If this is used or shared, synchronize in the * next() method. *

      * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: ArrayIterator.java 463298 2006-10-12 16:10:32Z henning $ */ public class ArrayIterator implements Iterator { /** * The objects to iterate. */ private Object array; /** * The current position and size in the array. */ private int pos; private int size; /** * Creates a new iterator instance for the specified array. * * @param array The array for which an iterator is desired. */ public ArrayIterator(Object array) { /* * if this isn't an array, then throw. Note that this is * for internal use - so this should never happen - if it does * we screwed up. */ if ( !array.getClass().isArray() ) { throw new IllegalArgumentException( "Programmer error : internal ArrayIterator invoked w/o array"); } this.array = array; pos = 0; size = Array.getLength( this.array ); } /** * Move to next element in the array. * * @return The next object in the array. */ public Object next() { if (pos < size ) return Array.get( array, pos++); /* * we screwed up... */ throw new NoSuchElementException("No more elements: " + pos + " / " + size); } /** * Check to see if there is another element in the array. * * @return Whether there is another element. */ public boolean hasNext() { return (pos < size ); } /** * No op--merely added to satify the Iterator interface. */ public void remove() { throw new UnsupportedOperationException(); } } velocity-1.7/src/java/org/apache/velocity/util/ArrayListWrapper.java0000644000175000017500000000307011050652577025560 0ustar moellermoellerpackage org.apache.velocity.util; /* * 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. */ import java.lang.reflect.Array; import java.util.AbstractList; /** * A class that wraps an array with a List interface. * * @author Chris Schultz <chris@christopherschultz.net$gt; * @version $Revision: 685685 $ $Date: 2006-04-14 19:40:41 $ * @since 1.6 */ public class ArrayListWrapper extends AbstractList { private Object array; public ArrayListWrapper(Object array) { this.array = array; } public Object get(int index) { return Array.get(array, index); } public Object set(int index, Object element) { Object old = get(index); Array.set(array, index, element); return old; } public int size() { return Array.getLength(array); } } velocity-1.7/src/java/org/apache/velocity/exception/0000755000175000017500000000000011675166252022466 5ustar moellermoellervelocity-1.7/src/java/org/apache/velocity/exception/ParseErrorException.java0000644000175000017500000002003011136073734027261 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.runtime.parser.ParseException; import org.apache.velocity.util.introspection.Info; /** * Application-level exception thrown when a resource of any type * has a syntax or other error which prevents it from being parsed. *
      * When this resource is thrown, a best effort will be made to have * useful information in the exception's message. For complete * information, consult the runtime log. * * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: ParseErrorException.java 736638 2009-01-22 13:42:52Z byron $ */ public class ParseErrorException extends VelocityException { /** * Version Id for serializable */ private static final long serialVersionUID = -6665197935086306472L; /** * The column number of the parsing error, or -1 if not defined. */ private int columnNumber = -1; /** * The line number of the parsing error, or -1 if not defined. */ private int lineNumber = -1; /** * The name of the template containing the error, or null if not defined. */ private String templateName = "*unset*"; /** * If applicable, contains the invalid syntax or reference that triggered this exception */ private String invalidSyntax; /** * If we modify the message, then we set this */ private String msg = null; /** * Create a ParseErrorException with the given message. * * @param exceptionMessage the error exception message */ public ParseErrorException(String exceptionMessage) { super(exceptionMessage); } private static final Pattern lexError = Pattern.compile("Lexical error.*TokenMgrError.*line (\\d+),.*column (\\d+)\\.(.*)"); /** * Create a ParseErrorException with the given ParseException. * * @param pex the parsing exception * @since 1.5 */ public ParseErrorException(ParseException pex, String templName) { super(pex.getMessage()); if (templName != null) templateName = templName; // Don't use a second C'tor, TemplateParseException is a subclass of // ParseException... if (pex instanceof ExtendedParseException) { ExtendedParseException xpex = (ExtendedParseException) pex; columnNumber = xpex.getColumnNumber(); lineNumber = xpex.getLineNumber(); templateName = xpex.getTemplateName(); } else { // We get here if the the Parser has thrown an exception. Unfortunately, // the error message created is hard coded by javacc, so here we alter // the error message, so that it is in our standard format. Matcher match = lexError.matcher(pex.getMessage()); if (match.matches()) { lineNumber = Integer.parseInt(match.group(1)); columnNumber = Integer.parseInt(match.group(2)); String restOfMsg = match.group(3); msg = "Lexical error, " + restOfMsg + " at " + Log.formatFileString(templateName, lineNumber, columnNumber); } // ugly, ugly, ugly... if (pex.currentToken != null && pex.currentToken.next != null) { columnNumber = pex.currentToken.next.beginColumn; lineNumber = pex.currentToken.next.beginLine; } } } /** * Create a ParseErrorException with the given ParseException. * * @param pex the parsing exception * @since 1.5 */ public ParseErrorException(VelocityException pex, String templName) { super(pex.getMessage()); if (templName != null) templateName = templName; // Don't use a second C'tor, TemplateParseException is a subclass of // ParseException... if (pex instanceof ExtendedParseException) { ExtendedParseException xpex = (ExtendedParseException) pex; columnNumber = xpex.getColumnNumber(); lineNumber = xpex.getLineNumber(); templateName = xpex.getTemplateName(); } else if (pex.getWrappedThrowable() instanceof ParseException) { ParseException pex2 = (ParseException) pex.getWrappedThrowable(); if (pex2.currentToken != null && pex2.currentToken.next != null) { columnNumber = pex2.currentToken.next.beginColumn; lineNumber = pex2.currentToken.next.beginLine; } } } /** * Create a ParseErrorRuntimeException with the given message and info * * @param exceptionMessage the error exception message * @param info an Info object with the current template info * @since 1.5 */ public ParseErrorException(String exceptionMessage, Info info) { super(exceptionMessage); columnNumber = info.getColumn(); lineNumber = info.getLine(); templateName = info.getTemplateName(); } /** * Create a ParseErrorRuntimeException with the given message and info * * @param exceptionMessage the error exception message * @param info an Info object with the current template info * @param invalidSyntax the invalid syntax or reference triggering this exception * @since 1.5 */ public ParseErrorException(String exceptionMessage, Info info, String invalidSyntax) { super(exceptionMessage); columnNumber = info.getColumn(); lineNumber = info.getLine(); templateName = info.getTemplateName(); this.invalidSyntax = invalidSyntax; } /** * Return the column number of the parsing error, or -1 if not defined. * * @return column number of the parsing error, or -1 if not defined * @since 1.5 */ public int getColumnNumber() { return columnNumber; } /** * Return the line number of the parsing error, or -1 if not defined. * * @return line number of the parsing error, or -1 if not defined * @since 1.5 */ public int getLineNumber() { return lineNumber; } /** * Return the name of the template containing the error, or null if not * defined. * * @return the name of the template containing the parsing error, or null * if not defined * @since 1.5 */ public String getTemplateName() { return templateName; } /** * Return the invalid syntax or reference that triggered this error, or null * if not defined. * * @return Return the invalid syntax or reference that triggered this error, or null * if not defined * @since 1.5 */ public String getInvalidSyntax() { return invalidSyntax; } /** * Return our custum message if we have one, else return the default message */ public String getMessage() { if (msg != null) return msg; return super.getMessage(); } } velocity-1.7/src/java/org/apache/velocity/exception/ResourceNotFoundException.java0000644000175000017500000000417711050652577030462 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ /** * Application-level exception thrown when a resource of any type * isn't found by the Velocity engine. *
      * When this exception is thrown, a best effort will be made to have * useful information in the exception's message. For complete * information, consult the runtime log. * * @author Geir Magnusson Jr. * @author Daniel Rall * @version $Id: ResourceNotFoundException.java 685685 2008-08-13 21:43:27Z nbubna $ */ public class ResourceNotFoundException extends VelocityException { /** * Version Id for serializable */ private static final long serialVersionUID = -4287732191458420347L; /** * @see VelocityException#VelocityException(String) */ public ResourceNotFoundException(final String exceptionMessage) { super(exceptionMessage); } /** * @see VelocityException#VelocityException(String, Throwable) * @since 1.5 */ public ResourceNotFoundException(final String exceptionMessage, final Throwable t) { super(exceptionMessage, t); } /** * @see VelocityException#VelocityException(Throwable) * @since 1.5 */ public ResourceNotFoundException(final Throwable t) { super(t); } } velocity-1.7/src/java/org/apache/velocity/exception/MacroOverflowException.java0000644000175000017500000000356011050665114027765 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ /** * Application-level exception thrown when macro calls within macro calls * exceeds the maximum allowed depth. The maximum allowable depth is given * in the configuration as velocimacro.max.depth. * @since 1.6 */ public class MacroOverflowException extends VelocityException { /** * Version Id for serializable */ private static final long serialVersionUID = 7305635093478106342L; /** * @param exceptionMessage The message to register. */ public MacroOverflowException(final String exceptionMessage) { super(exceptionMessage); } /** * @param exceptionMessage The message to register. * @param wrapped A throwable object that caused the Exception. */ public MacroOverflowException(final String exceptionMessage, final Throwable wrapped) { super(exceptionMessage, wrapped); } /** * @param wrapped A throwable object that caused the Exception. */ public MacroOverflowException(final Throwable wrapped) { super(wrapped); } } velocity-1.7/src/java/org/apache/velocity/exception/MathException.java0000755000175000017500000000236311322700447026075 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ /** * Separate exception class to distinguish math problems. * * @author Nathan Bubna * @since 1.6 * @version $Id: MathException.java 685685 2008-08-13 21:43:27Z nbubna $ */ public class MathException extends VelocityException { private static final long serialVersionUID = -7966507088645215583L; public MathException(final String exceptionMessage) { super(exceptionMessage); } } velocity-1.7/src/java/org/apache/velocity/exception/MethodInvocationException.java0000644000175000017500000000753411322700447030460 0ustar moellermoellerpackage org.apache.velocity.exception; import org.apache.velocity.runtime.log.Log; /* * 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. */ /** * Application-level exception thrown when a reference method is * invoked and an exception is thrown. *
      * When this exception is thrown, a best effort will be made to have * useful information in the exception's message. For complete * information, consult the runtime log. * * @author Geir Magnusson Jr. * @version $Id: MethodInvocationException.java 898032 2010-01-11 19:51:03Z nbubna $ */ public class MethodInvocationException extends VelocityException implements ExtendedParseException { /** * Version Id for serializable */ private static final long serialVersionUID = 7305685093478106342L; private String referenceName = ""; private final String methodName; private final int lineNumber; private final int columnNumber; private final String templateName; /** * CTOR - wraps the passed in exception for * examination later * * @param message * @param e Throwable that we are wrapping * @param methodName name of method that threw the exception * @param templateName The name of the template where the exception occured. */ public MethodInvocationException(final String message, final Throwable e, final String methodName, final String templateName, final int lineNumber, final int columnNumber) { super(message, e); this.methodName = methodName; this.templateName = templateName; this.lineNumber = lineNumber; this.columnNumber = columnNumber; } /** * Returns the name of the method that threw the * exception. * * @return String name of method */ public String getMethodName() { return methodName; } /** * Sets the reference name that threw this exception. * * @param ref name of reference */ public void setReferenceName(String ref) { referenceName = ref; } /** * Retrieves the name of the reference that caused the * exception. * * @return name of reference. */ public String getReferenceName() { return referenceName; } /** * @see ExtendedParseException#getColumnNumber() * @since 1.5 */ public int getColumnNumber() { return columnNumber; } /** * @see ExtendedParseException#getLineNumber() * @since 1.5 */ public int getLineNumber() { return lineNumber; } /** * @see ExtendedParseException#getTemplateName() * @since 1.5 */ public String getTemplateName() { return templateName; } /** * @see Exception#getMessage() * @since 1.5 */ public String getMessage() { StringBuffer message = new StringBuffer(); message.append(super.getMessage()); message.append(" at "); message.append(Log.formatFileString(templateName, lineNumber, columnNumber)); return message.toString(); } } velocity-1.7/src/java/org/apache/velocity/exception/ExtendedParseException.java0000644000175000017500000000345111050652577027743 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ /** * All Exceptions that can provide additional information about the place * where the error happened (template name, column and line number) can * implement this interface and the ParseErrorException will then be able * to deal with this information. * * @author Henning P. Schmiedehausen * @version $Id: ExtendedParseException.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public interface ExtendedParseException { /** * returns the Template name where this exception occured. * @return The Template name where this exception occured. */ String getTemplateName(); /** * returns the line number where this exception occured. * @return The line number where this exception occured. */ int getLineNumber(); /** * returns the column number where this exception occured. * @return The column number where this exception occured. */ int getColumnNumber(); } velocity-1.7/src/java/org/apache/velocity/exception/VelocityException.java0000644000175000017500000000467311050652577027015 0ustar moellermoellerpackage org.apache.velocity.exception; import org.apache.velocity.util.ExceptionUtils; /* * 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. */ /** * Base class for Velocity runtime exceptions thrown to the * application layer. * * @author Kyle F. Downey * @version $Id: VelocityException.java 685685 2008-08-13 21:43:27Z nbubna $ */ public class VelocityException extends RuntimeException { /** * Version Id for serializable */ private static final long serialVersionUID = 1251243065134956045L; private final Throwable wrapped; /** * @param exceptionMessage The message to register. */ public VelocityException(final String exceptionMessage) { super(exceptionMessage); wrapped = null; } /** * @param exceptionMessage The message to register. * @param wrapped A throwable object that caused the Exception. * @since 1.5 */ public VelocityException(final String exceptionMessage, final Throwable wrapped) { super(exceptionMessage); this.wrapped = wrapped; ExceptionUtils.setCause(this, wrapped); } /** * @param wrapped A throwable object that caused the Exception. * @since 1.5 */ public VelocityException(final Throwable wrapped) { super(); this.wrapped = wrapped; ExceptionUtils.setCause(this, wrapped); } /** * returns the wrapped Throwable that caused this * MethodInvocationException to be thrown * * @return Throwable thrown by method invocation * @since 1.5 */ public Throwable getWrappedThrowable() { return wrapped; } } velocity-1.7/src/java/org/apache/velocity/exception/TemplateInitException.java0000644000175000017500000000511011050652577027601 0ustar moellermoellerpackage org.apache.velocity.exception; /* * 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. */ import org.apache.velocity.runtime.parser.ParseException; /** * Exception generated to indicate parse errors caught during * directive initialization (e.g. wrong number of arguments) * * @author Will Glass-Husain * @version $Id: TemplateInitException.java 685685 2008-08-13 21:43:27Z nbubna $ * @since 1.5 */ public class TemplateInitException extends VelocityException implements ExtendedParseException { private final String templateName; private final int col; private final int line; /** * Version Id for serializable */ private static final long serialVersionUID = -4985224672336070621L; public TemplateInitException(final String msg, final String templateName, final int col, final int line) { super(msg); this.templateName = templateName; this.col = col; this.line = line; } public TemplateInitException(final String msg, ParseException parseException, final String templateName, final int col, final int line) { super(msg,parseException); this.templateName = templateName; this.col = col; this.line = line; } /** * Returns the Template name where this exception occured. * @return the template name */ public String getTemplateName() { return templateName; } /** * Returns the line number where this exception occured. * @return the line number */ public int getLineNumber() { return line; } /** * Returns the column number where this exception occured. * @return the line number */ public int getColumnNumber() { return col; } } velocity-1.7/src/site/0000755000175000017500000000000011675166252014645 5ustar moellermoellervelocity-1.7/src/site/site.xml0000644000175000017500000001264611110331372016321 0ustar moellermoeller Apache Velocity Project /images/velocity_project_wide.png http://velocity.apache.org/ Apache Velocity /images/velocity-logo.png org.apache.velocity.site velocity-site-skin 1.2.3 velocity-1.7/src/site/apt/0000755000175000017500000000000011675166252015431 5ustar moellermoellervelocity-1.7/src/site/apt/upgrading.apt0000644000175000017500000000426611363350301020107 0ustar moellermoeller ---- The Apache Velocity Project ---- dev@velocity.apache.org Upgrading from earlier versions Release with the same major number (1.x) are intended to be drop-in replacements. However, in most cases the versions of dependency jars must be adjusted because newer versions of Velocity might require updates. * Upgrading from Velocity 1.6 There are no changes in the dependencies since Velocity 1.6 * Deprecated $velocityCount; please use $foreach.count or $foreach.index * Deprecated $velocityHasNext; please use $foreach.hasNext, $foreach.first or $foreach.last * Deprecated velocimacro.context.localscope setting; please get/set local #macro references as members of the provided $macro scope control instead. (e.g. #set( $macro.foo = 'bar' ) and $macro.foo ) * Deprecated directive.evaluate.context.class setting; please get/set local #evaluate references as members of the provided $evaluate scope control instead. (e.g. #set( $evaluate.foo = 'bar' ) and $evaluate.foo ) * Deprecated #literal directive; please use #[[this syntax]]# instead. * Changed #stop to end template rendering rather than template parsing. * Removed obsolete Veltag (use VelocityViewTag in VelocityTools project) * Removed obsolete WebMacro conversion code. * Upgrading from Velocity 1.5 * {{{http://commons.apache.org/collections/}Commons Collections}} has been upgraded to version 3.2.1. * {{{http://commons.apache.org/lang/}Commons Lang}} has been upgraded to version 2.4. * {{{http://commons.apache.org/logging/}Commons Logging}} is required for compiling and using CommonsLogLogChute. * Upgrading from Velocity 1.4 or earlier * {{{http://www.jdom.org}JDOM}} has been upgraded to version 1.0. * {{{http://jakarta.apache.org/commons/collections/}Commons Collections}} has been upgraded to version 3.1. * {{{http://jakarta.apache.org/commons/lang/}Commons Lang}} 2.1 has been added. Optional: * {{{http://ant.apache.org}Apache Ant}} 1.6 or better is required for rebuilding. * {{{http://javacc.dev.java.net}Java CC}} 3.2 is recommended to compile the parser files. * {{http://www.hsqldb.org}HSQLDB}} 1.7.1 is required for running unit tests. velocity-1.7/src/site/resources/0000755000175000017500000000000011675166252016657 5ustar moellermoellervelocity-1.7/src/site/resources/images/0000755000175000017500000000000011675166252020124 5ustar moellermoellervelocity-1.7/src/site/resources/images/velocity-logo.png0000644000175000017500000000500210557734552023425 0ustar moellermoeller‰PNG  IHDRª2û°žgAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<PLTEÿÿÿ3fDi»ÉÖˆ ¸îñõ3\…Ap"NzÝäëf…£ÏÏç??Ÿª»Ì™­ÂÌÖàw’­Uw™úúý11˜€€ÀÔÔâµµÛ**–||¾ÓÓédd±‹‹Årr¹KK¤999üüþªªÕññøCííõ]]®QQR11))•"""^44™55„ööõii´ÂÂÎóóóbššš%%–##‘88£ööú""‘&&“=**”ŒŒŒŽ---ááð¢¢Ñþþþ””ÊÍÍÍ""77¡……Â$$‘ee­ **W&&’n$$’ ÚÚí~~¦xxv--šÊÊÊëëë»»Þbba%%rùùù//–ÈÈÆ{{{##’ 2LLLqqmÒÒÛääñÓÓÒÉÉäÝÝîùùü]][þþÿÃÃá77¦ eeføøøòòùmmµttt'''**|AA¡hh˜99œùùõýýý¦¦ÓššÍRR¨ z–––ÖÖÖÞÞÞ†††‚‚66c‘‘‘))“¶¶¶ÿÿý11—ΞžžŠßßåGG£55£ÏÏètt¹ççç))—têêõ""náááAA¨ííéûûý//¢nnn,,”VV`‰ ôôñ¯¯Þââß q''’55n55 JJGççîÎÎçÎÎæÏÏâBBŒÎÎÌÏÏØ))"e77œxx¼ ††‰‡‡‡55/~~ªªª««°UU JJ|dd^ïï÷PPZÀÀß±±Ø``¯¼¼º¶¶¯Äľðð÷;vvÁ''‘NN¨ööî''xÿÿþ^^‹èèòððò»ççá== &&v##>>ž??žZZ¥ÞÞéççô˜˜Ë@@’@@Ÿííæîîîii¹˜˜¢ûûûVV«XX«ððúžžÉzzœ''“ HH›77£FFF,,–..•ááèÜcQ ˆIDATxÚÔ™xEÇ÷nwv÷öµDr„MZ’cIL'´9!t’H ¤ Д¡JoF± Ø°¡Ø‘¦ØQ{±€]4:³ývç$!ñî}ÉÝîÛ·3¿›yï?³w!YúÀVDˆXTãÈÓ¡AZÞmÍÆôÐ@{ñ—²›CµÛ¾Ù'†iæ©l¾<2õ\•›ç»4) ~Ô‰'¦—qrUèUVú†ó¹ËZ¤7Ç_n>p`0ÉêùÜN-Ô„×Zyx÷uç2ƒ5¬Œš˜¿zñ k´–“s±ÿ«2³‚ 5«`õ¤Òi…I)egÃ?dn>—Ñ4zl¡N]Þf€ödÞ¦¼˜õii—Ò.åõËÍÈý›çÝ]R& jlä=‡<t¯ç?¿mRŸf~>ó§Z·>¹.£ŠorüH°$€/æ×Á…TznZúÆã Ç\÷ã±W'/X°à®o¶žÍ̉M8^Û‚ÃvÕPcÓ– pÿòïEÏŠïÞÜ߀Ãó㉬ñ‘o«¡6Š¢T ‡ß™bf“É\³Od19k‹êîÙ€3îШmÁ`˜¹½’³ŠýôÖn2™,Ê™žÙí™jŠjÑÜO×õÁ–`Úâá~Þ ·÷ ë8ÿPš…­;ä3xÂÒu@…& pc®ù¨š¨sÇOñpãT'HyÒlðØJÔÕ ?*W«;ШŽzbœÁ¿¨k%(Wìç#5€°Éº vŠ#j‹3j~¹qwйLKÆä—XJ´_Þ^j­ïûʽ¬÷[˜ ùqÀ«Ï J™u»œié‚YËX9cǤ~4‹K#N¨&Æ cífd0ñ‹N¾ÈÁ<ÖWBØŽÝ~‚A-hãÍnó÷q¨YáÈzÌ©GuÊW¤>i—쀙CIï„r¿I([³Z´Œž¨aû-}~›A½°Ç âô9ì’2Í¿ ½3JOÒp+¨VõŠÐ©&ÔBcQ…[8¥h JØã!›ŸÇ¦Æâ¶À3R_ "%5…Ðá|ÒvVÎbE²0ÄÆH©‚B-vÆZ` GJué@µÊÐà±’U.œæ{ŽâQŸÝ<ä)=*šlƒT&Þ!žŒj‘5M++†2´Fð)YB4ÙÍHµJc•pQ)ðî¹€!=¨Ï–öê½âÅIMYEp95hµc‡Ú™8|qáRÒÜPX%ÜÞ¬²²Mu笔Ý;6Vn!(iÈÐ(P¢™¥Ö¥Žíj²‰bÁÈù_¨r 0X%L «§õÀ’÷Ü_†Ü(õ8‹:ÛZÓ jÆ…P ê‰C•¦‰SrÖßB©_ŠñßýNŒ»UV¹)*]gT1Ö©(Nâ€A?¡Ý÷ܨž8TZƒEÈÅ+ájSw *syTTôâÂzü ¼3†ëUuðë-±¨„(ä.ysÊâ—IU„1"ý¤/м~{‰’²€¾ u;€ä¾•PmªM¡ ð+:+(½*V”fWFëQ-úIc±¤ÅåKá~ÏÓ9^ã›Ú>kuÄ£ Òʪ ­‰B=ÓN»‚Ê(9MK‹¥ åÌ”ªE< šEó|0q|T‘8>Ÿì4ò}É9<(z|í‹Eujš×G³YU“¼9°ˆW¤…Te̲j)¨VÑ/M8iÃFïáF|ôÙV?¯=6ù³É¯ÅMyqÌ?­=ð”¸JHúÊÇ1û°¨œ¶>jýÛ1c8ñÙI^òš¥„*¨+:)uÒô;•]ä|Z•Û4!!áݯ‡m¶-©Ý°Ç^:ùò3}a>€^£wÞ›E…4š¦Hi¿d–€då­M ,EëCI¿Q%f-ªË˜ÿ™#ú/‹àïLõùRónA¶>fSFJúBÀÛ,ùÌénP9Ò_ô Li&ŒÖœp¤.Ô!Iš¡EÕM饢6zºÃï¼»C*4ü/*ò¥´ózþ:´>D½ºfÅìTv…Eß:ÏWqpcÕ¦_?kô¡åâsöÿ‚*ì 1_/4Ê)‹>Rr­j­:³B¾:¢FÕ/¨˜´ø'-(V¾‡¨ç£v×;ª9à~_ÛÚ"¡ºº¬Ñ áõŒê²×ú®#«x¾z^÷òúDuWtÛ‰NÕ|Ѻ`ú-  •LŸ·²ß\"$,re—SBµ¤ñš¹å¡JÌ©ˆ Râì†àøõý_ t-þ$¬›¦IEND®B`‚velocity-1.7/src/changes/0000755000175000017500000000000011675166252015311 5ustar moellermoellervelocity-1.7/src/changes/changes.xml0000644000175000017500000013165411470267434017452 0ustar moellermoeller Changelog Fixed quotes escaping so that doubling single quotes only works when enclosing quotes are single quotes (and same behaviour for double quotes) Add access to template and directive debugging info via $.info. LogManager now catches UnsupportedOperationExceptions during LogChute init. Ensure that DataSourceResourceLoader closes PreparedStatements. Mark optional dependencies as such in OSGi bundle manifest. Add support for OSGi-ready manifests in build/release tasks. When comparing parameter types during method mapping, make Object always less specific than other types. Avoid NPEs in case of bad #foreach config. Use LinkedHashMap to maintain order of VTL-created maps. Treat \ as non-special in string literals, except when specifying unicode sequences. Allow escaping of quotes (single or double) within string literals by doubling them ("" or ''). Give #parse better log/exception messages and give IncludeEventHandler a chance to handle null #parse args. Fix $.x parsing failures (particularly helpful for jQuery users). Log Velocimacro additions at debug level, as in pre-1.6 versions. Add removeDirective(name) and loadDirective(classname) methods to allow runtime changes to the directive set. Throw an informative VelocityException when #define is given no parameter (instead of an ArrayIndexOutOfBoundsException). Throw an informative VelocityException when #parse is given no args (instead of an NPE). Add directive.if.tostring.nullcheck config switch to allow improved performance for those who do not need to check whether $foo.toString() returns null when doing #if( $foo ). Changed #stop to a directive implementation (get it out of the parser) and allow it to accept a message as an argument to be written to the logs for debugging purposes. Change the scoping behavior of Velocity, keeping it optional (everything global scoped by default) but now providing an explicit namespace in content-containing directives (like macros, #foreach, #parse, etc.) in which references that should stay local may be kept. This is accompanied by numerous related changes, including: <ul> <li>A Scope reference can now be automatically made available within each content directive: <ul> <li>$template in Template.merge and #parse content</li> <li>$macro in #macro</li> <li>$foreach in #foreach</li> <li>$evaluate in #evaluate or Velocity.evaluate(...) content</li> <li>$define in #define</li> <li>$&lt;amacro&gt; in #@&lt;amacro&gt; (where &lt;amacro&gt; is the name of a macro being called with a body)</li> </ul> </li> <li>For performance and compatibility these are all off by default, *except* for $foreach. The others may be enabled by setting a velocity property like: <br/><code>macro.provide.scope.control = true</code></li> <li>When scopes of the same type are nested make the parent Scope available through the child (e.g. $foreach.parent or $foreach.topmost).</li> <li>When a Scope reference overrides an existing reference that is not a Scope, make it available through the Scope (e.g. $foreach.replaced).</li> <li>Made #break work in any of the above scopes to exit the most immediate one, unless a different scope is provided as an argument (e.g. #break($macro) or #break($foreach.topmost)).</li> <li>Deprecated $velocityCount; please use $foreach.count or $foreach.index.</li> <li>Deprecated $velocityHasNext; please use $foreach.hasNext, $foreach.first or $foreach.last</li> <li>Deprecated velocimacro.context.localscope setting; please get/set local #macro references as members of the provided $macro scope control instead. (e.g. #set( $macro.foo = 'bar' ) and $macro.foo ).</li> <li>Deprecated directive.evaluate.context.class setting; please get/set local #evaluate references as members of the provided $evaluate scope control instead. (e.g. #set( $evaluate.foo = 'bar' ) and $evaluate.foo ).</li> </ul> All of the deprecated features will be removed in Velocity 2.0. Calling #set on a macro argument (for which a #set-able reference was passed) will no longer propagate the new value to the original reference, but merely set the value of the macro argument reference. This was an obscure, infrequently used feature and was decided to be more problematic and unpredictable than useful. In strict mode attempts to render references that evaluate to null will throw an exception. In the user wishes to suppress the exception and render nothing then the reference can be proceeded with '$!' as in $!foo. The non default VelocityEngine construtors now do not initialize the runtime system so that properties may be set after construction. Also fixes an Initialization race condition. Make velocimacro.arguments.strict=true work with block macros. Added a property for changing escape behavior such that putting a forward slash before a reference or macro always escapes the reference or macro and absorbs the forward slash regardless if the reference or macro is defined. Fix StringIndexOutOfBoundsException caused by #[[##x]]# (line comment on same line as end of textblock). Fix NPE caused by #@foo (w/o #end) in template. Minor performance tweaks based on Findbugs findings Pre 1.6 behavior of specifying #macro without parenthesis would throw a VelocityException has been restored. Add support for calling velocimacros with body content by prefixing the macro name with @. (e.g. #macro( foo )Here is $bodyContent#end #@foo()any valid VTL here#end) The $bodyContent reference may be renamed via a velocimacro.body.reference setting in your velocity.properties. Added #[[this is included in output but not parsed]]# syntax to replace and deprecate the much more limited #literal directive (which required parse-able content). Re-implement #stop so that it stops template execution and rendering. This Also addresses a performance bottleneck detected in the old implementation. #stop is a general use directive now, and not just for debugging. Reduce performance bottleneck with the referenceInsert event handler call Better error reporting when toString() throw an exception when testing an #if conditional. For example #if($foo) Added bracketed index syntax, $foo[0], or #set($foo[0] = 1) Removed java.lang.Exception from throws clause of Velocity and VelocityEngine API. Also removed IOException so that all method calls use unchecked exceptions. Removed obsolete WebMacro conversion tool and experimental Veltag (which has been replaced by VelocityViewTag from VelocityTools). Fix bug in #parse that threw an NPE when IncludeEventHandler returned null and inline macros are kept local. Fix double-checked locking in RuntimeInstance's optional lazy-init for Java 1.5+. Users of older JREs in multi-threaded environments MUST manually call init() on any thread-shared Velocity singleton or VelocityEngine instances to avoid race conditions. New auto-init feature is only supported on Java 1.5+. Fix 100% CPU loop hang under simultaneous HashMap calls in ClassMap due to classic bug in Sun's implementation. Now uses ConcurrentHashMap when available and Hashtable otherwise. Add directive.if.tostring.nullcheck config switch to match past performance for those who do not need to check whether $foo.toString() returns null when doing #if( $foo ). Fix obscure caching problem in multiple resource loader situations where resources may exist in more than one loader and appear and disappear from loaders. Fix old regression from 1.4 in supporting methods declared as abstract in a public class but implemented in a non-public class. Fix problem with FileResourceLoader's resourceExists() when configured w/multiple paths. Fix ClassMap introspection bug introduced in 1.5, where public super-interface methods implemented in protected or private classes were unreachable. Fix regression in proxying of macro argument #set calls. Note that in 1.7, calling #set on a macro argument (for which a #set-able reference was passed) will not propagate the new value to the original reference, but merely set the value of the macro argument reference. Fix loss of inline macros when #evaluate is used. Fix name of sources jar for maven deployment. Pre 1.6 behavior of specifying #macro without parenthesis would throw a VelocityException has been restored. Better error reporting when toString() throw an exception when testing an #if conditional. For example #if($foo) Fix $velocityHasNext so that it works in nested foreach blocks. Throw an exception in strict mode when >=, <=, < or > comparisons can't be made. Fix $velocityHasNext so it is not always true. Correct/enhance template name reporting for #include and #parse. Removed redundant error message in ASTReference. Fix limitation in new macro implementation that resisted #set calls to change references defined as arguments for the macro. Fix vararg bugs when calling overloaded methods like get(String,String,Object[]) and get(String,List). (e.g. in VelocityStruts' MessageTool) Fix NPE when null value is passed to array/vararg method. Track template name in Node, to get proper template name in the exception message when a reference in a macro causes that exception. Update Finnish and Spanish User Guide sections on division operation. Fix classpath for XMLApp example. Fix references to Oro dependency to make it clear that it is only necessary for certain reference event handlers. Remove old Anakia/Texen docs and examples. Fix bug in vararg support where an array passed to a vararg method was being wrapped in another array. Locked down versions for reporting plugins in Maven POM. Add Maven-Ant tasks for installing and deploying Maven artifacts, including previously missing source and javadoc jars (VELOCITY-554). Fix User Guide's Table of Contents anchor links. Fix parser bug that prevented references from immediately preceding #set directives. Revert change made for VELOCITY-285, as it broke pass-by-name nature of macro arguments. Fix line numbers in string literals. Fix line number for exceptions with body of #foreach directive. Log full macro stack when a RuntimeException occurs in a template. Format template and line/column numbers consistently in error and log messages. Don't override pre-configured log levels for JdkLogChute or Log4JLogChute. Add optional 'runtime.references.strict' property that has Velocity throw exceptions when it encounters undefined references or velocimacros in a template. Inlude Maven Ant tasks jar in downloads and add support for downloading from Maven2 repos. Fix problem with single backslash in interpolated (double-quoted) strings. Fix escaping of bracketed directives (e.g. \#{if}($foo)$bar\#{end}). Uberspectors chaining Add ability to set a connection timeout for URLResourceLoader. Make it easier to override ResourceFactory.getResource(...) in ResourceManagerImpl. Fix BooleanPropertyExecutor to recognize "public Boolean isFoo" properties. Add a separate resourceExists(String name) method to ResourceLoader(s) to improve performance. Fix missing # and $ characters within #literal() directive output. Add support for static utility classes: context.put("math", Math.class) -> $math.sin(0) Add #define directive set an unrendered block of VTL as a reference. (e.g. #define( $foo )Hello, $bar!#end #set( $bar = 'world') $foo -> Hello, world!) Add #break directive to exit #foreach loops early. Fixed major performance issues with Velocimacros. Removed many, various performance bottlenecks and concurrency issues. (Also see VELOCITY-595) New VTL syntax $velocityHasNext within #foreach loops Multi-line comments in macros were rendering extra *# when evaluated. Have VelocityCharStream use an exponential buffer expansion rate. Prevent exception due to simultaneous rendering of macros. New VTL syntax allows arrays to be treated like fixed length lists. Added support for varargs in method calls. Prevent NPE when template is parsed simultaneously by multiple users. (may apply only to macros). Users can now include libraries of macros with #parse in a template. Macro libraries can now be selected programatically when merging templates. Catch IllegalArgumentException when invoking method. Fixed parse error for map definitions ending with a reference. Add new property velocimacro.max.depth which limits max macro calling depth. Add ability to add directives programmatically Allow user directives to have no content. IncludeNotFound event handler was displaying "not found" template. Fix StringResourceLoader to make it possible to use more than one loader per VM. Make unicode encoding work in velocity templates. Add a ServletLogChute that allows logging through the servlet API. Ported from the Velocity Tools project. Add a CommonsLogLogChute that allows logging through commons-logging. Deprecate integrated texen and anakia, factor it out into separate jars. Added new directive #evaluate() to dynamically evaluate VTL. Fix to SecureUberspector to work properly with #foreach and iterators. Make FileResourceLoader unicode aware to allow skipping over BOM markers like those created by Windows Notepad. This is a workaround for a Java bug, where Java itself does not recognize the UTF-8 BOM as defined by the unicode standard. New StringResourceLoader can retrieve templates from repository of in-memory Strings. RuntimeInstance.getProperty now returns value set with RuntimeInstance.setProperty, even before initialization. When macros have incorrect number of arguments, if property "velocimacro.arguments.strict" is set to true a ParseErrorException will be thrown. MethodInvocationException now contains line, column, template name allowing application to produce more useful error messages. Fixed race condition in template retrieval that caused macros to fail under simultaneous load. New event handler InvalidReferenceHandler allows application to catch invalid references. Sample implementation collects them in list and optionally throws exception. New, optional SecureIntrospector prohibits methods that involve manipulation of classes, classloaders or reflection objects. Use this introspector to secure Velocity against a risk of template writers using reflection to perform malicious acts. Removed Serializable from InternalContextBase, because one of the members is not serializable anyway so this never worked (Found by Findbugs). Add an additional pair of Executors that are smart about Map. Method caching now uses consistent keys. Change the meaning of localscope for macros to allow access to references from calling context. Add a test for the DataSourceResource Loader. Fix a problem in the DataSourceResource Loader, removing a potential security issue with SQL injection. Build now creates the MD5 and SHA1 checksums for archives and jars. Fix a number of issues reported by running FindBugs on the Velocity source. Stop references from calling object.toString() twice. Pass through all runtime exceptions. Among other benefits, this allows plugins to throw a runtime exception to signify an application level problem in the calling application. When #include was followed by #parse with the same file name, a ClassCastException was thrown. Wrapped exceptions now have Cause property set on JDK 1.4. (note that Velocity continues to run under JDK 1.3). When Velocity is initialized, default.properties stream was not being closed. This made it difficult to undeploy webapps on Windows with Velocity unpacked. Upgraded to latest commons collection, fixing problem with non-recognition of configuration file encoding in rare circumstances. The Introspector could throw a NPE when a parameter to an overloaded method was null. If toString() returned null in a silent reference then "null" was displayed. Fixed bug in which empty body for #if (e.g. #if(some expression)#end caused ParseException. Added javacc task to build.xml simplifying modification process for editing syntax files. Velocity Engine was throwing NPE when used without a call to init(). Now gives a more meaningful exception message. Fixed problem with Uberspect Info class being created incorrectly. Added template name to Info allowing better error reporting. Numerous improvements to the documentation. Reorganized table of contents, moved community content to the Wiki, added article on using Velocity in web applications. When testing objects in VTL for equality, if both objects are a number, use number equality. If both objects are the same class, use the equals method. New behavior: If objects are different classes, compare the String representation of both objects rather than logging an error. Velocity would give error when last line of file was a ## comment. Added method to retrieve application attributes. Velocity now searches in the current thread's context classloader before the system classloader for all templates loaded with the ClasspathResourceLoader and for all user-defined ResourceLoaders, introspectors, event handlers, etc. A typical use for this is to have Velocity in the application container classpath while keeping templates and plugins in the webapp classpath. #set now sets references to null when required. For backwards compatibility this must be enabled by setting the configuration key directive.set.null.allowed to true. New optional event handler that escapes all references. Regular expressions can be used to configure which references have HTML, JavaScript, SQL, or XML escaping. New optional event handler implementation that forces #parse / #include to stay in same directory as parent template. New event handler to modify behavior of #parse / #include. FileResourceLoader now accepts absolute path when configured to accept it. String containing "##" was treated as unterminated String. Spruced up Geir's old URLResourceLoader and promoted it from the whiteboard to the main distribution. Throw Runtime exceptions from nodes up the chain. Revert the split between org.apache.velocity.runtime.parser.node.Node and org.apache.velocity.runtime.parser.Node. The parser now only uses ...parser.node.Node because this change broke custom directives. Made a lot of internal logging upgrades including: Deprecated LogSystem interface and replaced it (and all its implementations) with a new LogChute interface and implementations, added getLog() to RuntimeServices (and all its friends) to improve on and replace its now deprecated logging methods, added a JdkLogChute as a 3rd default option for those using JDK 1.4+, and added a StandardOutLogChute as final resort if other LogChute inits fail. See JIRA issues VELOCITY-403, VELOCITY-166, VELOCITY-403,VELOCITY-166,VELOCITY-78, VELOCITY-157, VELOCITY-159, VELOCITY-193. Removed all J2EE build tasks. Now automatically detects availability of javax.sql.Datasource (in JDK 1.4+) and builds DatasourceResourceLoader when allowed. ant build now downloads the required dependency jars from ibiblio.org Unified template name, line and column number reporting for ParserErrorException Dropped the non-functional Velocity compiler. Started separating out the JavaCC generated parts of the Velocity Parser. Not yet complete to avoid user visible changes. Scheduled to be completed for 2.0 Contributed a maven build for Velocity Reworked the ant build to product only two jars: velocity.jar and velocity-dep.jar. Removed the Configuration class and all methods that references it. This class was deprecated since Velocity 1.1 and was scheduled to be gone for Velocity 1.3 or 1.4. Now it was finally removed in 1.5. Added support for decimal numbers. MethodInvocationException now consistently thrown (previously was hidden when in parameter to Velocimacro). Fixed problem in which foreach loop would fail to call overloaded method. Removed ERROR level log message "Can't find 'VM_global_library.vm'". Anakia now generates consistent line endings based on platform. Requires upgrade to JDom 1.0. Anakia can now be pre-loaded with custom context values from an optional XML file. Directives can now be delimited with curly braces, for example #if($condition)something#{else}otherthing#{end}. Nulls now handled appropriate within #foreach. Upgraded JavaCC to version 3.2, providing JDK 1.5 compatibility. (Older version used keyword 'enum' which is reserved in JDK 1.5). DatasourceResourceLoader now allows injection of Datasource, allowing it to be used in Inversion of Control (IOC) frameworks. #stop now works properly. ClasspathResourceLoader now searches ContextClassLoader for template. Removed use of Log4J's deprecated Category and Priority classes in favor of the corresponding and supported Logger and Level. To update, replace necessary references, and Category.getInstance() with Logger.getLogger(). New Map literal syntax. Removed the long-deprecated Log4JLogSystem. Never fear, SimpleLog4JLogSystem remains. Enhanced the implementation of ResourceCacheImpl using Jakarta Commons Collections LRUMap class. The previous greedy implementation did not set an upper bound for the cache size, meaning that cached resources were never relinquished (a possible memory leak). You can continue to use that behavior by setting the resource.manager.cache.size for your cache to less than 1. Took dan's modified SimpleLog4jLogSystem, and renamed Log4JLogSystem, and put back old version of SimpleLog4JLogSystem, as deprecated. That way we can move forward with an up-to-date version that uses Logger, and for one release, be backwards compatile for the Category-using log4j crowd. Deprecated org.apache.velocity.tools.VelocityFormatter class in favor of the various format classes in the Velocity Tools library. Deprecated the org.apache.velocity.servlet.VelocityServlet class in favor of org.apache.velocity.tools.view.servlet.VelocityViewServlet from the Velocity Tools library. Servlet interaction is more a core competency of the Velocity Tools package than of Velocity's core. Fix to BaseTestCase as suggested by Will Glass-Husain to handle line endings Parameterized cache and mod time control in TexenTask based on patch from Henning. Fix to DatasourceResourceLoader - stop using the old Runtime singleton as would leak a little memory for each instance of VelocityEngine created. Hunted down by Will Glass-Husain. SimplePool now removes elements from pool on a get(). NOTE : Previously, it left the reference to the object in the pool. Fixes problem with single line comment embedded in a multi-line comment. Change for VELOCITY-221 and partial for VELOCITY-148, allowing newlines in directives. Change to finish request VELOCITY-148, allowing '+' as a string concat. We'll have to see how the community likes it. Didn't allow formal reference notation as first arg to foreach. To make using w/ XML easier allow alternative logical operators 'and', 'or', 'lt', 'gt', 'le', 'ge', 'eq', 'ne', 'not'. Allow newlines in strings. Tiny fix to VelocityWriter to prevent a NPE if someone passes it a null Anakia changes to accomodate finalization of JDOM API. In AnakiaJDOMFactory, AnakiaTask, and OutputWrapper Added template, line and column info to MIEs thrown by ASTMethod velocity-1.7/src/parser/0000755000175000017500000000000011675166252015175 5ustar moellermoellervelocity-1.7/src/parser/Parser.jjt0000644000175000017500000014045011353715726017145 0ustar moellermoeller/* * 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. */ /* * NOTE : please see documentation at bottom of this file. (It was placed there its tiring * to always have to page past it... :) */ options { /** The default package for this parser kit */ NODE_PACKAGE="org.apache.velocity.runtime.parser"; /** A source file will be generated for each non-terminal */ MULTI=true; /** * Each node will have access to the parser, I did this so * some global information can be shared via the parser. I * think this will come in handly keeping track of * context, and being able to push changes back into * the context when nodes make modifications to the * context by setting properties, variables and * what not. */ NODE_USES_PARSER=true; /** * The parser must be non-static in order for the * above option to work, otherwise the parser value * is passed in as null, which isn't all the useful ;) */ STATIC=false; /** * Enables the use of a visitor that each of nodes * will accept. This way we can separate the logic * of node processing in a visitor and out of the * nodes themselves. If processing changes then * the nothing has to change in the node code. */ VISITOR=true; /** * Declare that we are accepting unicode input and * that we are using a custom character stream class * Note that the char stream class is really a slightly * modified ASCII_CharStream, as it appears we are safe * because we only deal with pre-encoding-converted * Readers rather than raw input streams. */ UNICODE_INPUT=true; USER_CHAR_STREAM=true; /** * for debugging purposes. Keep false */ DEBUG_PARSER=false; DEBUG_TOKEN_MANAGER=false; } PARSER_BEGIN(Parser) package org.apache.velocity.runtime.parser; import java.io.*; import java.util.*; import org.apache.velocity.exception.VelocityException; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.*; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.directive.Macro; import org.apache.velocity.runtime.directive.MacroParseException; import org.apache.velocity.util.StringUtils; import org.apache.commons.lang.text.StrBuilder; import org.apache.velocity.runtime.RuntimeConstants; /** * This class is responsible for parsing a Velocity * template. This class was generated by JavaCC using * the JJTree extension to produce an Abstract * Syntax Tree (AST) of the template. * * Please look at the Parser.jjt file which is * what controls the generation of this class. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: Parser.jjt 928463 2010-03-28 18:11:34Z nbubna $ */ public class Parser { /** * Keep track of defined macros, used for escape processing */ private Map macroNames = new HashMap(); /** * Name of current template we are parsing. Passed to us in parse() */ public String currentTemplateName = ""; /** * Set to true if the property * RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE is set to true */ public boolean strictEscape = false; VelocityCharStream velcharstream = null; private RuntimeServices rsvc = null; /** * This constructor was added to allow the re-use of parsers. * The normal constructor takes a single argument which * an InputStream. This simply creates a re-usable parser * object, we satisfy the requirement of an InputStream * by using a newline character as an input stream. */ public Parser( RuntimeServices rs) { /* * need to call the CTOR first thing. */ this( new VelocityCharStream( new ByteArrayInputStream("\n".getBytes()), 1, 1 )); /* * now setup a VCS for later use */ velcharstream = new VelocityCharStream( new ByteArrayInputStream("\n".getBytes()), 1, 1 ); strictEscape = rs.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT_ESCAPE, false); /* * and save the RuntimeServices */ rsvc = rs; } /** * This was also added to allow parsers to be * re-usable. Normal JavaCC use entails passing an * input stream to the constructor and the parsing * process is carried out once. We want to be able * to re-use parsers: we do this by adding this * method and re-initializing the lexer with * the new stream that we want parsed. */ public SimpleNode parse( Reader reader, String templateName ) throws ParseException { SimpleNode sn = null; currentTemplateName = templateName; try { token_source.clearStateVars(); /* * reinitialize the VelocityCharStream * with the new reader */ velcharstream.ReInit( reader, 1, 1 ); /* * now reinit the Parser with this CharStream */ ReInit( velcharstream ); /* * do that voodoo... */ sn = process(); } catch (MacroParseException mee) { /* * thrown by the Macro class when something is amiss in the * Macro specification */ rsvc.getLog().error("Parser Error: " + templateName, mee); throw mee; } catch (ParseException pe) { rsvc.getLog().error("Parser Exception: " + templateName, pe); throw new TemplateParseException (pe.currentToken, pe.expectedTokenSequences, pe.tokenImage, currentTemplateName); } catch (TokenMgrError tme) { throw new ParseException("Lexical error: " + tme.toString()); } catch (Exception e) { String msg = "Parser Error: " + templateName; rsvc.getLog().error(msg, e); throw new VelocityException(msg, e); } currentTemplateName = ""; return sn; } /** * This method gets a Directive from the directives Hashtable */ public Directive getDirective(String directive) { return (Directive) rsvc.getDirective(directive); } /** * This method finds out of the directive exists in the directives Map. */ public boolean isDirective(String directive) { return rsvc.getDirective(directive) != null; } /** * Produces a processed output for an escaped control or * pluggable directive */ private String escapedDirective( String strImage ) { int iLast = strImage.lastIndexOf("\\"); String strDirective = strImage.substring(iLast + 1); boolean bRecognizedDirective = false; // we don't have to call substring method all the time in this method String dirTag = strDirective.substring(1); if (dirTag.charAt(0) == '{') { dirTag = dirTag.substring(1, dirTag.length() - 1); } /* * If this is a predefined derective or if we detect * a macro definition (this is aproximate at best) then * we absorb the forward slash. If in strict reference * mode then we always absord the forward slash regardless * if the derective is defined or not. */ if (strictEscape || isDirective(dirTag) || macroNames.containsKey(dirTag) || rsvc.isVelocimacro(dirTag, currentTemplateName)) { bRecognizedDirective = true; } else { /* order for speed? */ if ( dirTag.equals("if") || dirTag.equals("end") || dirTag.equals("set") || dirTag.equals("else") || dirTag.equals("elseif") ) { bRecognizedDirective = true; } } /* * if so, make the proper prefix string (let the escapes do their thing..) * otherwise, just return what it is.. */ if (bRecognizedDirective) return ( strImage.substring(0,iLast/2) + strDirective); else return ( strImage ); } /** * Check whether there is a left parenthesis with leading optional * whitespaces. This method is used in the semantic look ahead of * Directive method. This is done in code instead of as a production * for simplicity and efficiency. */ private boolean isLeftParenthesis() { char c; int no = 0; try { while(true) { /** * Read a character */ c = velcharstream.readChar(); no++; if (c == '(') { return true; } /** * if not a white space return */ else if (c != ' ' && c != '\n' && c != '\r' && c != '\t') { return false; } } } catch (IOException e) { } finally { /** * Backup the stream to the initial state */ velcharstream.backup(no); } return false; } } PARSER_END(Parser) TOKEN_MGR_DECLS: { private int fileDepth = 0; private int lparen = 0; private int rparen = 0; List stateStack = new ArrayList(50); public boolean debugPrint = false; private boolean inReference; public boolean inDirective; private boolean inComment; public boolean inSet; /** * pushes the current state onto the 'state stack', * and maintains the parens counts * public because we need it in PD & VM handling * * @return boolean : success. It can fail if the state machine * gets messed up (do don't mess it up :) */ public boolean stateStackPop() { ParserState s; try { s = (ParserState) stateStack.remove(stateStack.size() - 1); // stack.pop } catch(IndexOutOfBoundsException e) { // empty stack lparen=0; SwitchTo(DEFAULT); return false; } if( debugPrint ) System.out.println( " stack pop (" + stateStack.size() + ") : lparen=" + s.lparen + " newstate=" + s.lexstate ); lparen = s.lparen; rparen = s.rparen; SwitchTo(s.lexstate); return true; } /** * pops a state off the stack, and restores paren counts * * @return boolean : success of operation */ public boolean stateStackPush() { if( debugPrint ) System.out.println(" (" + stateStack.size() + ") pushing cur state : " + curLexState ); ParserState s = new ParserState(); s.lparen = lparen; s.rparen = rparen; s.lexstate = curLexState; lparen = 0; stateStack.add(s); // stack.push return true; } /** * Clears all state variables, resets to * start values, clears stateStack. Call * before parsing. */ public void clearStateVars() { stateStack.clear(); lparen = 0; rparen = 0; inReference = false; inDirective = false; inComment = false; inSet = false; return; } /** * Holds the state of the parsing process. */ private static class ParserState { int lparen; int rparen; int lexstate; } /** * handles the dropdown logic when encountering a RPAREN */ private void RPARENHandler() { /* * Ultimately, we want to drop down to the state below * the one that has an open (if we hit bottom (DEFAULT), * that's fine. It's just text schmoo. */ boolean closed = false; if (inComment) closed = true; while( !closed ) { /* * look at current state. If we haven't seen a lparen * in this state then we drop a state, because this * lparen clearly closes our state */ if( lparen > 0) { /* * if rparen + 1 == lparen, then this state is closed. * Otherwise, increment and keep parsing */ if( lparen == rparen + 1) { stateStackPop(); } else { rparen++; } closed = true; } else { /* * now, drop a state */ if(!stateStackPop()) break; } } } } /* ------------------------------------------------------------------------ * * Tokens * * Note : we now have another state, REFMODIFIER. This is sort of a * type of REFERENCE state, simply use to use the DIRECTIVE token * set when we are processing a $foo.bar() construct * * ------------------------------------------------------------------------- */ TOKEN: { { stateStackPush(); SwitchTo(REFINDEX); } } TOKEN: { { stateStackPop(); } } TOKEN: { | | } TOKEN: { } TOKEN: { } TOKEN : { | } TOKEN: { { if (!inComment) lparen++; /* * If in REFERENCE and we have seen the dot, then move * to REFMOD2 -> Modifier() */ if (curLexState == REFMODIFIER ) SwitchTo( REFMOD2 ); } } /* * we never will see a ')' in anything but DIRECTIVE and REFMOD2. * Each have their own */ TOKEN: { /* * We will eat any whitespace upto and including a newline for directives */ { RPARENHandler(); } } TOKEN: { /* * in REFMOD2, we don't want to bind the whitespace and \n like we * do when closing a directive. */ { /* * need to simply switch back to REFERENCE, not drop down the stack * because we can (infinitely) chain, ala * $foo.bar().blargh().woogie().doogie() */ SwitchTo( REFERENCE ); } } /*---------------------------------------------- * * escape "\\" handling for the built-in directives * *--------------------------------------------- */ TOKEN: { /* * We have to do this, because we want these to be a Text node, and * whatever follows to be peer to this text in the tree. * * We need to touch the ASTs for these, because we want an even # of \'s * to render properly in front of the block * * This is really simplistic. I actually would prefer to find them in * grammatical context, but I am neither smart nor rested, a receipe * for disaster, another long night with Mr. Parser, or both. */ )* "\\#" ( | ) > } /* * needed because #set is so wacky in it's desired behavior. We want set * to eat any preceeding whitespace so it is invisible in formatting. * (As it should be.) If this works well, I am going to chuck the whole MORE: * token abomination. * * We added the lexical states REFERENCE, REFMODIFIER, REFMOD2 to * address JIRA issue VELOCITY-631. With SET_DIRECTIVE only in the * DEFAULT lexical state the following VTL fails "$a#set($b = 1)" * because the Reference token uses LOOKAHEAD(2) combined with the * fact that we explicity set the lex state to REFERENCE with the $ * token, which means we would never evaulate this token during the * look ahead. This general issue is disscussed here: * * http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-ie.htm#tth_sEc3.12 * */ TOKEN: { { if (! inComment) { inDirective = true; if ( debugPrint ) System.out.print("#set : going to " + DIRECTIVE ); stateStackPush(); inSet = true; SwitchTo(DIRECTIVE); } /* * need the LPAREN action */ if (!inComment) { lparen++; /* * If in REFERENCE and we have seen the dot, then move * to REFMOD2 -> Modifier() */ if (curLexState == REFMODIFIER ) SwitchTo( REFMOD2 ); } } } <*> MORE : { /* * Note : DOLLARBANG is a duplicate of DOLLAR. They must be identical. */ { if (! inComment) { /* * if we find ourselves in REFERENCE, we need to pop down * to end the previous ref */ if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inReference = true; if ( debugPrint ) System.out.print( "$ : going to " + REFERENCE ); stateStackPush(); SwitchTo(REFERENCE); } } | { if (! inComment) { /* * if we find ourselves in REFERENCE, we need to pop down * to end the previous ref */ if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inReference = true; if ( debugPrint ) System.out.print( "$! : going to " + REFERENCE ); stateStackPush(); SwitchTo(REFERENCE); } } | "#[[" { if (!inComment) { inComment = true; stateStackPush(); SwitchTo( IN_TEXTBLOCK ); } } | <"#**" ~["#"]> { if (!inComment) { input_stream.backup(1); inComment = true; stateStackPush(); SwitchTo( IN_FORMAL_COMMENT); } } | "#*" { if (!inComment) { inComment=true; stateStackPush(); SwitchTo( IN_MULTI_LINE_COMMENT ); } } | { if (! inComment) { /* * We can have the situation where #if($foo)$foo#end. * We need to transition out of REFERENCE before going to DIRECTIVE. * I don't really like this, but I can't think of a legal way * you are going into DIRECTIVE while in REFERENCE. -gmj */ if (curLexState == REFERENCE || curLexState == REFMODIFIER ) { inReference = false; stateStackPop(); } inDirective = true; if ( debugPrint ) System.out.print("# : going to " + DIRECTIVE ); stateStackPush(); SwitchTo(PRE_DIRECTIVE); } } } // treat the single line comment case separately // to avoid ## errors TOKEN : { { if (!inComment) { if (curLexState == REFERENCE) { inReference = false; stateStackPop(); } inComment = true; stateStackPush(); SwitchTo(IN_SINGLE_LINE_COMMENT); } } } TOKEN : { | | } /* ----------------------------------------------------------------------- * * *_COMMENT Lexical tokens * *-----------------------------------------------------------------------*/ TOKEN : { { inComment = false; stateStackPop(); } } TOKEN : { { inComment = false; stateStackPop(); } } TOKEN : { { inComment = false; stateStackPop(); } } TOKEN : { { inComment = false; stateStackPop(); } } SKIP : { < ~[] > } MORE : { < ~[] > } /* ----------------------------------------------------------------------- * * DIRECTIVE Lexical State (some of it, anyway) * * ---------------------------------------------------------------------- */ TOKEN: { } TOKEN : { // < STRING_LITERAL: ("\"" ( (~["\""]) | ("\\" ( ["n","t","b","r","f"] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] | "u" ["0"-"9", "a"-"f", "A"-"F"] ["0"-"9", "a"-"f", "A"-"F"] ["0"-"9", "a"-"f", "A"-"F"] ["0"-"9", "a"-"f", "A"-"F"] ) ) | ("\"\"") | ( "\\" (" ")* "\n") )* "\"" ) | ("\'" ( (~["\'"]) | ("''") | ( "\\" (" ")* "\n") )* "\'" ) > { /* * - if we are in DIRECTIVE and haven't seen ( yet, then also drop out. * don't forget to account for the beloved yet wierd #set * - finally, if we are in REFMOD2 (remember : $foo.bar( ) then " is ok! */ if( curLexState == DIRECTIVE && !inSet && lparen == 0) stateStackPop(); } } TOKEN: { | } TOKEN : { { if ( debugPrint ) System.out.println(" NEWLINE :"); stateStackPop(); if (inSet) inSet = false; if (inDirective) inDirective = false; } } TOKEN : { | | | | | | | | | " | "gt" > | =" | "ge" > | | | | { inDirective = false; stateStackPop(); } | { SwitchTo(DIRECTIVE); } | { SwitchTo(DIRECTIVE); } | { inDirective = false; stateStackPop(); } } TOKEN: { <#DIGIT: [ "0"-"9" ] > /* * treat FLOATING_POINT_LITERAL and INTEGER_LITERAL differently as a range can only handle integers. */ /** * Note -- we also define an integer as ending with a double period, * in order to avoid 1..3 being defined as floating point (1.) then a period, then a integer */ | )+ ("..")? > { /* * Remove the double period if it is there */ if (matchedToken.image.endsWith("..")) { input_stream.backup(2); matchedToken.image = matchedToken.image.substring(0,matchedToken.image.length()-2); } /* * check to see if we are in set * ex. #set $foo = $foo + 3 * because we want to handle the \n after */ if ( lparen == 0 && !inSet && curLexState != REFMOD2 && curLexState != REFINDEX) { stateStackPop(); } } | )+ "." ()* ()? | ("-")? "." ()+ ()? | ("-")? ()+ > { /* * check to see if we are in set * ex. #set $foo = $foo + 3 * because we want to handle the \n after */ if ( lparen == 0 && !inSet && curLexState != REFMOD2) { stateStackPop(); } } | <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > } TOKEN: { <#LETTER: [ "a"-"z", "A" - "Z" ] > | <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_", "@" ] > | | ["_"] | ["@"]) ()* > | | ["_"]) ()* "}" > } /* ----------------------------------------------------------------------- * * REFERENCE Lexical States * * This is more than a single state, because of the structure of * the VTL references. We use three states because the set of tokens * for each state can be different. * * $foo.bar( "arg" ) * ^ ^ ^ * | | | * ----------- > REFERENCE : state initiated by the '$' character. Continues * | | until end of the reference, or the . character. * |------ > REFMODIFIER : state switched to when the is encountered. * | note that this is a switch, not a push. See notes at bottom * | re stateStack. * |-- > REFMOD2 : state switch to when the LPAREN is encountered. * again, this is a switch, not a push. * * During the REFERENCE or REFMODIFIER lex states we will switch to * REFINDEX if a bracket is encountered '['. for example: $foo[1] * or $foo.bar[1], $foo.bar( "arg" )[1] * ---------------------------------------------------------------------------- */ TOKEN : { <#ALPHA_CHAR: ["a"-"z", "A"-"Z"] > | <#ALPHANUM_CHAR: [ "a"-"z", "A"-"Z", "0"-"9" ] > | <#IDENTIFIER_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "-", "_" ] > | | ["_"]) ()* > | > { /* * push the alpha char back into the stream so the following identifier * is complete */ input_stream.backup(1); /* * and munge the so we just get a . when we have normal text that * looks like a ref.ident */ matchedToken.image = "."; if ( debugPrint ) System.out.print("DOT : switching to " + REFMODIFIER); SwitchTo(REFMODIFIER); } } TOKEN : { | { stateStackPop(); } } SPECIAL_TOKEN : { { /* * push every terminator character back into the stream */ input_stream.backup(1); inReference = false; if ( debugPrint ) System.out.print("REF_TERM :"); stateStackPop(); } } SPECIAL_TOKEN : { { if ( debugPrint ) System.out.print("DIRECTIVE_TERM :"); input_stream.backup(1); inDirective = false; stateStackPop(); } } /** * This method is what starts the whole parsing * process. After the parsing is complete and * the template has been turned into an AST, * this method returns the root of AST which * can subsequently be traversed by a visitor * which implements the ParserVisitor interface * which is generated automatically by JavaCC */ SimpleNode process() : {} { ( Statement() )* { return jjtThis; } } /** * These are the types of statements that * are acceptable in Velocity templates. */ void Statement() #void : {} { IfStatement() | LOOKAHEAD(2) Reference() | Comment() | Textblock() | SetDirective() | EscapedDirective() | Escape() | Directive() | Text() } /** * used to separate the notion of a valid directive that has been * escaped, versus something that looks like a directive and * is just schmoo. This is important to do as a separate production * that creates a node, because we want this, in either case, to stop * the further parsing of the Directive() tree. */ void EscapedDirective() : {} { { Token t = null; } t = { /* * churn and burn.. */ t.image = escapedDirective( t.image ); } } /** * Used to catch and process escape sequences in grammatical constructs * as escapes outside of VTL are just characters. Right now we have both * this and the EscapeDirective() construction because in the EscapeDirective() * case, we want to suck in the # and here we don't. We just want * the escapes to render correctly */ void Escape() : {} { { Token t = null; int count = 0; boolean control = false; } ( LOOKAHEAD(2) t = { count++; } )+ { /* * first, check to see if we have a control directive */ switch(t.next.kind ) { case IF_DIRECTIVE : case ELSE_DIRECTIVE : case ELSEIF_DIRECTIVE : case END : control = true; break; } /* * if that failed, lets lookahead to see if we matched a PD or a VM */ String nTag = t.next.image.substring(1); if (strictEscape || isDirective(nTag) || macroNames.containsKey(nTag) || rsvc.isVelocimacro(nTag, currentTemplateName)) { control = true; } jjtThis.val = ""; for( int i = 0; i < count; i++) jjtThis.val += ( control ? "\\" : "\\\\"); } } void Comment() : {} { ( ) ? | | } void Textblock() : {} { } void FloatingPointLiteral() : {} { } void IntegerLiteral() : {} { } void StringLiteral() : {} { } /** * This method corresponds to variable * references in Velocity templates. * The following are examples of variable * references that may be found in a * template: * * $foo * $bar * */ void Identifier() : {} { } void Word() : {} { } /** * Supports the arguments for the Pluggable Directives */ int DirectiveArg() #void : {} { Reference() { return ParserTreeConstants.JJTREFERENCE; } | Word() { return ParserTreeConstants.JJTWORD; } | StringLiteral() { return ParserTreeConstants.JJTSTRINGLITERAL; } | IntegerLiteral() { return ParserTreeConstants.JJTINTEGERLITERAL; } /* * Need to put this before the floating point expansion */ | LOOKAHEAD( [] ( Reference() | IntegerLiteral()) [] ) IntegerRange() { return ParserTreeConstants.JJTINTEGERRANGE; } | FloatingPointLiteral() { return ParserTreeConstants.JJTFLOATINGPOINTLITERAL; } | Map() { return ParserTreeConstants.JJTMAP; } | ObjectArray() { return ParserTreeConstants.JJTOBJECTARRAY; } | True() { return ParserTreeConstants.JJTTRUE; } | False() { return ParserTreeConstants.JJTFALSE; } } /** * Supports the Pluggable Directives * #foo( arg+ ) */ SimpleNode Directive() : { Token t = null; int argType; int argPos = 0; Directive d; int directiveType; boolean isVM = false; boolean doItNow = false; } { /* * note that if we were escaped, that is now handled by * EscapedDirective() */ ((t = ) | (t = )) { String directiveName; if (t.kind == ParserConstants.BRACKETED_WORD) { directiveName = t.image.substring(2, t.image.length() - 1); } else { directiveName = t.image.substring(1); } d = getDirective(directiveName); /* * Velocimacro support : if the directive is macro directive * then set the flag so after the block parsing, we add the VM * right then. (So available if used w/in the current template ) */ if (directiveName.equals("macro")) { doItNow = true; } /* * set the directive name from here. No reason for the thing to know * about parser tokens */ jjtThis.setDirectiveName(directiveName); if ( d == null) { if( directiveName.startsWith("@") ) { // block macro call of type: #@foobar($arg1 $arg2) astBody #end directiveType = Directive.BLOCK; } else { /* * if null, then not a real directive, but maybe a Velocimacro */ isVM = rsvc.isVelocimacro(directiveName, currentTemplateName); /* * Currently, all VMs are LINE directives */ directiveType = Directive.LINE; } } else { directiveType = d.getType(); } /* * now, switch us out of PRE_DIRECTIVE */ token_source.SwitchTo(DIRECTIVE); argPos = 0; } /** * Look for the patter [WHITESPACE] */ (LOOKAHEAD( { isLeftParenthesis() } ) /* * if this is indeed a token, match the #foo ( arg ) pattern */ (([] ) ( LOOKAHEAD(2) [] [ []] argType = DirectiveArg() { if (argType == ParserTreeConstants.JJTWORD) { if (doItNow && argPos == 0) { /* if #macro and it's the 0th arg, ok */ } else if (isVM) { throw new MacroParseException("Invalid arg #" + argPos + " in VM " + t.image, currentTemplateName, t); } /* if #foreach and it's the 2nd arg, ok */ else if (d != null && (!directiveName.equals("foreach") || argPos != 1)) { throw new MacroParseException("Invalid arg #" + argPos + " in directive " + t.image, currentTemplateName, t); } else { /* either schmoo or a late-defined macro, * VelocimacroProxy will have to check for latter. */ } } else { if (doItNow && argPos == 0) { /* if a VM and it's the 0th arg, not ok */ throw new MacroParseException("Invalid first arg" + " in #macro() directive - must be a" + " word token (no \' or \" surrounding)", currentTemplateName, t); } } argPos++; } )* [] ) { if (directiveType == Directive.LINE) { return jjtThis; } } | { if (doItNow) // doItNow is true if the directive is "macro" { // VELOCITY-667 We get here if we have a "#macro" construct // without parenthesis which is a parse error throw new MacroParseException("A macro declaration requires at least a name argument" , currentTemplateName, t); } /** * Not a directive */ token_source.stateStackPop(); token_source.inDirective = false; return jjtThis; } ) /* * and the following block if the PD needs it */ ( Statement() )* #Block { /* * VM : if we are processing a #macro directive, we need to * process the block. In truth, I can just register the name * and do the work later when init-ing. That would work * as long as things were always defined before use. This way * we don't have to worry about forward references and such... */ if (doItNow) { // Further checking of macro arguments Macro.checkArgs(rsvc, t, jjtThis, currentTemplateName); // Add the macro name so that we can peform escape processing // on defined macros String macroName = jjtThis.jjtGetChild(0).getFirstToken().image; macroNames.put(macroName, macroName); } /* * VM : end */ return jjtThis; } } /** * for creating a map in a #set * * #set($foo = {$foo : $bar, $blargh : $thingy}) */ void Map() : {} { ( LOOKAHEAD(2) Parameter() Parameter() ( Parameter() Parameter() )* | [ ] ) /** note: need both tokens as they are generated in different states **/ ( | ) } void ObjectArray() : {} { [ Parameter() ( Parameter() )* ] } /** * supports the [n..m] vector generator for use in * the #foreach() to generate measured ranges w/o * needing explicit support from the app/servlet */ void IntegerRange() : {} { [] ( Reference() | IntegerLiteral()) [] [] (Reference() | IntegerLiteral()) [] } /** * A Simplified parameter more suitable for an index position: $foo[$index] */ void IndexParameter() #void: {} { [] ( StringLiteral() | IntegerLiteral() | True() | False() | Reference() ) [ ] } /** * This method has yet to be fully implemented * but will allow arbitrarily nested method * calls */ void Parameter() #void: {} { [] ( StringLiteral() | IntegerLiteral() | LOOKAHEAD( [] ( Reference() | IntegerLiteral()) [] ) IntegerRange() | Map() | ObjectArray() | True() | False() | Reference() | FloatingPointLiteral() ) [ ] } /** * This method has yet to be fully implemented * but will allow arbitrarily nested method * calls */ void Method() : {} { Identifier() [ Parameter() ( Parameter() )* ] } void Index() : {} { IndexParameter() } void Reference() : {} { /* * A reference is either ${} or $ */ ( (Index())* (LOOKAHEAD(2) (LOOKAHEAD(3) Method() | Identifier() ) (Index())* )* ) | ( (Index())* (LOOKAHEAD(2) (LOOKAHEAD(3) Method() | Identifier() ) (Index())* )* ) } void True() : {} { } void False() : {} { } /** * This is somewhat of a kludge, the problem is that the parser picks * up on '$[' , or '$![' as being a Reference, and does not dismiss it even though * there is no between $ and [, This has something to do * with the LOOKAHEAD in Reference, but I never found a way to resolve * it in a more fashionable way.. */ TOKEN : { } /** * This method is responsible for allowing * all non-grammar text to pass through * unscathed. */ void Text() : {} { | | | | | | | | | | } /* ----------------------------------------------------------------------- * * Defined Directive Syntax * * ----------------------------------------------------------------------*/ void IfStatement() : {} { [] Expression() ( Statement() )* #Block [ LOOKAHEAD(1) ( ElseIfStatement() )+ ] [ LOOKAHEAD(1) ElseStatement() ] } void ElseStatement() : {} { ( Statement() )* #Block } void ElseIfStatement() : {} { [] Expression() ( Statement() )* #Block } /** * Currently support both types of set : * #set( expr ) * #set expr */ void SetDirective() : {} { ([] Reference() [] Expression() { /* * ensure that inSet is false. Leads to some amusing bugs... */ token_source.inSet = false; } [] ) } /* ----------------------------------------------------------------------- * * Expression Syntax * * ----------------------------------------------------------------------*/ void Expression() : {} { // LOOKAHEAD( PrimaryExpression() ) Assignment() //| ConditionalOrExpression() } void Assignment() #Assignment(2) : {} { PrimaryExpression() Expression() } void ConditionalOrExpression() #void : {} { ConditionalAndExpression() ( ConditionalAndExpression() #OrNode(2) )* } void ConditionalAndExpression() #void : {} { EqualityExpression() ( EqualityExpression() #AndNode(2) )* } void EqualityExpression() #void : {} { RelationalExpression() ( RelationalExpression() #EQNode(2) | RelationalExpression() #NENode(2) )* } void RelationalExpression() #void : {} { AdditiveExpression() ( AdditiveExpression() #LTNode(2) | AdditiveExpression() #GTNode(2) | AdditiveExpression() #LENode(2) | AdditiveExpression() #GENode(2) )* } void AdditiveExpression() #void : {} { MultiplicativeExpression() ( MultiplicativeExpression() #AddNode(2) | MultiplicativeExpression() #SubtractNode(2) )* } void MultiplicativeExpression() #void : {} { UnaryExpression() ( UnaryExpression() #MulNode(2) | UnaryExpression() #DivNode(2) | UnaryExpression() #ModNode(2) )* } void UnaryExpression() #void : {} { LOOKAHEAD(2) [] UnaryExpression() #NotNode(1) | PrimaryExpression() } void PrimaryExpression() #void : {} { [] ( StringLiteral() | Reference() | IntegerLiteral() | LOOKAHEAD( [] ( Reference() | IntegerLiteral()) [] ) IntegerRange() | FloatingPointLiteral() | Map() | ObjectArray() | True() | False() | Expression() ) [] } /* ====================================================================== Notes ----- template == the input stream for this parser, contains 'VTL' mixed in with 'schmoo' VTL == Velocity Template Language : the references, directives, etc schmoo == the non-VTL component of a template reference == VTL entity that represents data within the context. ex. $foo directive == VTL entity that denotes 'action' (#set, #foreach, #if ) defined directive (DD) == VTL directive entity that is expressed explicitly w/in this grammar pluggable directive (PD) == VTL directive entity that is defined outside of the grammar. PD's allow VTL to be easily expandable w/o parser modification. The problem with parsing VTL is that an input stream consists generally of little bits of VTL mixed in with 'other stuff, referred to as 'schmoo'. Unlike other languages, like C or Java, where the parser can punt whenever it encounters input that doesn't conform to the grammar, the VTL parser can't do that. It must simply output the schmoo and keep going. There are a few things that we do here : - define a set of parser states (DEFAULT, DIRECTIVE, REFERENCE, etc) - define for each parser state a set of tokens for each state - define the VTL grammar, expressed (mostly) in the productions such as Text(), SetStatement(), etc. It is clear that this expression of the VTL grammar (the contents of this .jjt file) is maturing and evolving as we learn more about how to parse VTL ( and as I learn about parsing...), so in the event this documentation is in disagreement w/ the source, the source takes precedence. :) Parser States ------------- DEFAULT : This is the base or starting state, and strangely enough, the default state. PRE_DIRECTIVE : State immediately following '#' before we figure out which defined or pluggable directive (or neither) we are working with. DIRECTIVE : This state is triggered by the a match of a DD or a PD. REFERENCE : Triggered by '$'. Analagous to PRE_DIRECTIVE. REFMODIFIER : Triggered by . when in REFERENCE. REFMOD2 : Triggered by ( when in REFMODIFIER (cont) Escape Sequences ---------------- The escape processing in VTL is very simple. The '\' character acts only as an escape when : 1) On or more touch a VTL element. A VTL element is either : 1) It preceeds a reference that is in the context. 2) It preceeds a defined directive (#set, #if, #end, etc) or a valid pluggable directive, such as #foreach In all other cases the '\' is just another piece of text. The purpose of this is to allow the non-VTL parts of a template (the 'schmoo') to not have to be altered for processing by Velocity. So if in the context $foo and $bar were defined and $woogie was not \$foo \$bar \$woogie would output $foo $bar \$woogie Further, you can stack them and they affect left to right, just like convention escape characters in other languages. \$foo = $foo \\$foo = \ \\\$foo = \$foo What You Expect --------------- The recent versions of the parser are trying to support precise output to support general template use. The directives do not render trailing whitespace and newlines if followed by a newline. They will render preceeding whitespace. The only exception is #set, which also eats preceeding whitespace. So, with a template : ------ #set $foo="foo" #if($foo) \$foo = $foo #end ------ it will render precisely : ------ $foo = foo ------ */ velocity-1.7/whiteboard/0000755000175000017500000000000011675166252015242 5ustar moellermoellervelocity-1.7/whiteboard/daveb/0000755000175000017500000000000011675166252016323 5ustar moellermoellervelocity-1.7/whiteboard/daveb/ToolOne.java0000644000175000017500000000214310513464370020535 0ustar moellermoeller/* * 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. */ import org.apache.velocity.context.*; /** * Test Tool */ public class ToolOne extends ContextTool { /** * This is the name put in the context */ public String getName() { return "toolone"; } public String sayHello() { return "Hello from Tool one"; } } velocity-1.7/whiteboard/daveb/ContextWithTools.java0000644000175000017500000000641710513464370022467 0ustar moellermoeller/* * 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. */ import java.util.*; import org.apache.velocity.context.AbstractContext; import org.apache.velocity.context.Context; import org.apache.velocity.runtime.Runtime; import org.apache.velocity.runtime.configuration.*; /** * Just a demo context that loads it's own tools. * * @author Dave Bryson * @version $Id: ContextWithTools.java 463298 2006-10-12 16:10:32Z henning $ */ public class ContextWithTools extends AbstractContext { public ContextWithTools() { super(); loadTools(); } /** * Load the tools specified in the Properties file * This can use a lot of work, but it works for testing. */ private void loadTools() { String toolPackages = VelocityResources.getString("ContextTools"); Enumeration tools = new StringTokenizer( toolPackages ); try { while ( tools.hasMoreElements() ) { String toolName = (String)tools.nextElement(); Object o = Class.forName( toolName ).newInstance(); ContextTool ct = (ContextTool)o; ct.setContext( this ); put( ct.getName(), ct); } } catch ( Exception cnf ) { Runtime.error( "Not loaded: " + cnf ); } } // Below: Implements the AbstractContext stuff /** storage for key/value pairs */ private HashMap context = new HashMap(); /** chaining CTOR */ public ContextWithTools( Context context ) { super( context ); loadTools(); } public Object internalGet( String key ) { return context.get( key ); } public Object internalPut( String key, Object value ) { return context.put( key, value ); } public boolean internalContainsKey(Object key) { return context.containsKey( key ); } public Object[] internalGetKeys() { return context.keySet().toArray(); } public Object internalRemove(Object key) { return context.remove( key ); } /** * Clones this context object * @return Object an instance of this Context */ public Object clone() { ContextWithTools clone = null; try { clone = (ContextWithTools) super.clone(); clone.context = (HashMap) context.clone(); } catch (CloneNotSupportedException cnse) { } return clone; } } velocity-1.7/whiteboard/daveb/ContextTool.java0000644000175000017500000000266710513464370021453 0ustar moellermoeller/* * 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. */ import java.io.Serializable; import org.apache.velocity.context.Context; /** * * @author Dave Bryson * @version $Id: ContextTool.java 463298 2006-10-12 16:10:32Z henning $ */ public abstract class ContextTool implements Serializable { /** Owner */ protected Context context; /** * keep a pointer to my context * in case there's other stuff in there * that I might want to use in the Tool */ public void setContext( Context c ) { this.context = c; } /** * Provides the name for the context */ public abstract String getName(); } velocity-1.7/whiteboard/daveb/myprops.properties0000644000175000017500000000310310513464370022137 0ustar moellermoeller# 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. runtime.log = velocity.log template.loader=org.apache.velocity.runtime.loader.FileTemplateLoader template.modificationCheckInterval = 2 # # # Path to templates. # Default=current directory # # template.path=. # # # Cache the templates? # # template.cache=false # Options for the Output template.encoding=8859_1 # This is for #foreach loops. You can # retrieve the current number of the item # being operated on by using the special # $velocityCount variable. Here you can specify # what to start the counter at 0 or 1. counter.initial.value = 1 # You can name what the counter # variable can be accessed as. counter.name = velocityCount # The value for the default content type to return # in VelocityServlet default.contentType=text/html # # Place to add context tools # ContextTools=ToolOne ToolTwo velocity-1.7/whiteboard/daveb/testtool.sh0000644000175000017500000000155610513464370020533 0ustar moellermoeller# !/bin/sh # 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. echo "Running TestTool" java -cp .:../../bin/classes ToolTest testtool.vm velocity-1.7/whiteboard/daveb/ToolTwo.java0000644000175000017500000000214510513464370020567 0ustar moellermoeller/* * 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. */ import org.apache.velocity.context.*; /** * another sample tool */ public class ToolTwo extends ContextTool { /** * the name put in the context */ public String getName() { return "tooltwo"; } public String sayHello() { return "Hello from Tool Two"; } } velocity-1.7/whiteboard/daveb/build.sh0000644000175000017500000000155110513464370017750 0ustar moellermoeller# !/bin/sh # 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. echo "Building TestTool" javac -classpath .:../../bin/classes *.java velocity-1.7/whiteboard/daveb/README.txt0000644000175000017500000000036407225246177020025 0ustar moellermoellerNothing fancy here. Just Experimental - playing with the use of a ContextTool. To build the classes run - build.sh ( of course you need to build Velocity first ) To run the small test - testtool.sh Where do we want to go with this stuff??velocity-1.7/whiteboard/daveb/dajarred/0000755000175000017500000000000011675166252020077 5ustar moellermoellervelocity-1.7/whiteboard/daveb/dajarred/Example.class0000644000175000017500000000662107250534251022516 0ustar moellermoellerÊþº¾-ºfghijlmnorsuv‡ˆ“”˜™£·¸tš›œžŸ ¡¢§¨©ª«¬ A A A "A B C D E F G H I &J K L &M N &O !P Q R S T #U V W kZ k[ k\ kb Š_ ‹] ‹` Z Ž„ ^ ’Z •Y –a –b —b ¦d ­~ ¯Z °^ °b ±c ²b ¶X()Ljava/lang/String;()Ljava/util/ArrayList;()V(Ljava/io/OutputStream;)V(Ljava/io/Writer;)V,(Ljava/lang/Object;)Ljava/lang/StringBuffer;(Ljava/lang/Object;)V(Ljava/lang/Object;)Z,(Ljava/lang/String;)Ljava/lang/StringBuffer;2(Ljava/lang/String;)Lorg/apache/velocity/Template;(Ljava/lang/String;)V8(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;8(Lorg/apache/velocity/context/Context;Ljava/io/Writer;)V([Ljava/lang/String;)V/example/test1.vm/example/yomama.vm/template/test1.vm/template/test2.vm:ArrayList element 1ArrayList element 2ArrayList element 3ArrayList element 4Code ConstantValueERRORERROR starting runtime: Example#Example : Syntax error in template 'Example : error : cannot find template  Example.java ExceptionsJAR_RESOURCE_LOADER_PATH1JAR_RESOURCE_LOADER_PATH2 LExample;LineNumberTableLjava/io/BufferedWriter;Ljava/io/PrintStream;Ljava/lang/Exception;Ljava/lang/String;Ljava/util/ArrayList;LocalVariableTableLorg/apache/velocity/Template;%Lorg/apache/velocity/VelocityContext;3Lorg/apache/velocity/exception/ParseErrorException; SourceFile Started... Try something that doesn't exist[Ljava/lang/String;addappendargsclosecontexteerrorexflushget template from template.jarget template from test.jargetNames getTemplateinitjar:file:template.jar!/jar:file:test.jar!/java/io/BufferedWriterjava/io/OutputStreamWriterjava/io/PrintStreamjava/lang/Exceptionjava/lang/Objectjava/lang/StringBufferjava/lang/Systemjava/lang/Throwablejava/util/ArrayListlistmmainmergeorg/apache/velocity/Template#org/apache/velocity/VelocityContext+org/apache/velocity/context/AbstractContext1org/apache/velocity/exception/ParseErrorException7org/apache/velocity/exception/ResourceNotFoundException#org/apache/velocity/runtime/RuntimeoutpeeprintStackTraceprintlnputsaytemplate templateFilethistoString$try template from template.jar againvelocity.propertieswriter!Ž„y€qz€qkZpŸ?*·(*µ2¸8*»"Y·*µ2*´2*¶5¶>W§L»Y ·-+¶/¶@¸3± '*|* TM V \kl'V*o+q>T‚?µ{+•Ypn&» Y·)L+¶.W+¶.W+¶.W+ ¶.W+°|¥§¨©ª$¬‚&µ{£–bpE}M+¸6M§=W²:»Y ·-+¶0¶@¶=§#N²:»Y ·-+¶0¶0-¶/¶@¶=»Y»Y²:·+·,YNN,Æ ,*´2-¶9-¶4-¶1§M²:,¶<,¶;± %$$mp|Zwz|~| € ‚!|$„%†DHRX’\“e™išmwpœqžxŸ|u‚>}µ{}´€n³ƒ%®…W¹}q x ¥ep·C»Y·'L¸?¸?+¶7¸?+¶7¸?+¶7¸?+¶7§ W ¸?±9<|>±³µ ·¸º»#½(¾.À3Á9³<Ã=ÅB¯‚CŒ‰;‘{ ²bp6²:*¶=±| ËÉ‚ ¤€†wvelocity-1.7/whiteboard/daveb/dajarred/template.jar0000644000175000017500000000201107250531644022375 0ustar moellermoellerPK”²b* META-INF/þÊPKPK”²b*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK ‰²b* template/PK…²b*template/test1.vmmŽ1 E{Nñ,’Bíí=@ÆžI6‡€›¨·w™Dmd(Xþ›÷Wk4ƒMk<èiÆ»#ÌäBkù&™ “R:WØp†O(/+QÖJɹ€>†qÍ·h(1Ž˜¢ËæýG#ćÝ<.ôà îÁ©±»™XH["™vFoF‚PgÅY+ÈY?®Bq¡4ùî»b|gÙ/{rœH6Ô¶Gõ I3~¬È2œ].Ñ 7-m9WoPK ú·=PKY²b*template/test2.vmmÁ‚0DïýŠr€ƒ½ûÄ{‹lRZC¢ï6½ØôÒ™×7Ö¢›8A¯  —›Ÿž°‘=ËBúvBÆØDR£’ ßPÞ¢lŒÙÃ:J‚ ÖÅg]{ÈZÑøzÞæB%c\Èõ“Š‚› PyÖ_ž#Lx(%…±†ïrÃÀÂ1è¼,+é°åõ¯Ø%ÝDø±*ËpvùDÿÑiµ¯åÞ|PK×¥-¢PK”²b* META-INF/þÊPK”²b*3ù5¤DD=META-INF/MANIFEST.MFPK ‰²b* Ãtemplate/PK…²b* ú·=êtemplate/test1.vmPKY²b*×¥-¢àtemplate/test2.vmPK2Ávelocity-1.7/whiteboard/daveb/dajarred/build.sh0000755000175000017500000000370110513464370021526 0ustar moellermoeller# !/bin/sh # 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. # ------------------------------------------------------------------- # -------------------------------------------- # No need to edit anything past here # -------------------------------------------- if test -z "${JAVA_HOME}" ; then echo "ERROR: JAVA_HOME not found in your environment." echo "Please, set the JAVA_HOME variable in your environment to match the" echo "location of the Java Virtual Machine you want to use." exit fi if test -f ${JAVA_HOME}/lib/tools.jar ; then CLASSPATH="${CLASSPATH}:${JAVA_HOME}/lib/tools.jar" fi # convert the existing path to unix if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi for i in ../../../build/lib/*.jar do CLASSPATH=$CLASSPATH:"$i" done for i in ../../../bin/*.jar do CLASSPATH=$CLASSPATH:"$i" done # convert the unix path to windows if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then CLASSPATH=`cygpath --path --windows "$CLASSPATH"` fi BUILDFILE=build.xml ${JAVA_HOME}/bin/java -classpath ${CLASSPATH} \ org.apache.tools.ant.Main \ -buildfile ${BUILDFILE} "$@" velocity-1.7/whiteboard/daveb/dajarred/velocity.properties0000755000175000017500000001107010513464370024045 0ustar moellermoeller# 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. # ---------------------------------------------------------------------------- # R U N T I M E L O G # ---------------------------------------------------------------------------- # This is the location of the Velocity Runtime log. # ---------------------------------------------------------------------------- runtime.log=velocity.log # ---------------------------------------------------------------------------- # T E M P L A T E E N C O D I N G # ---------------------------------------------------------------------------- template.encoding=8859_1 # ---------------------------------------------------------------------------- # C O N T E N T T Y P E # ---------------------------------------------------------------------------- # This is the default content type for the VelocityServlet. # ---------------------------------------------------------------------------- default.contentType=text/html # ---------------------------------------------------------------------------- # F O R E A C H P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control how the counter is accessed in the #foreach # directive. By default the reference $velocityCount will be available # in the body of the #foreach directive. The default starting value # for this reference is 1. # ---------------------------------------------------------------------------- counter.name = velocityCount counter.initial.value = 1 # ---------------------------------------------------------------------------- # I N C L U D E P R O P E R T I E S # ---------------------------------------------------------------------------- # These are the properties that governed the way #include'd content # is governed. # ---------------------------------------------------------------------------- include.output.errormsg.start = # ---------------------------------------------------------------------------- # P A R S E P R O P E R T I E S # ---------------------------------------------------------------------------- parse_directive.maxdepth = 10 # ---------------------------------------------------------------------------- # T E M P L A T E L O A D E R S # ---------------------------------------------------------------------------- # # # ---------------------------------------------------------------------------- resource.loader.1.public.name = Jar resource.loader.1.description = Velocity Jar Resource Loader resource.loader.1.class = org.apache.velocity.runtime.resource.loader.JarResourceLoader resource.loader.1.resource.path = jar:file:/test.jar!/ resource.loader.1.resource.path = jar:file:template.jar!/ resource.loader.1.cache = false resource.loader.1.modificationCheckInterval = 2 # ---------------------------------------------------------------------------- # E X T E R N A L S E R V I C E I N I T I A L I Z A T I O N # ---------------------------------------------------------------------------- # If this property is set to true then an external service will # set certain system properties and initialize the Velocity # Runtime. This method is used by Turbine to initialize the # Velocity Runtime for the TurbineVelocityService. # ---------------------------------------------------------------------------- external.init = false # ---------------------------------------------------------------------------- # VELOCIMACRO GLOBAL LIBRARY # ---------------------------------------------------------------------------- # name of default global library. It is expected to be in the regular # template path. You may remove it (either the file or this property) if # you wish with no harm. # ---------------------------------------------------------------------------- # velocimacro.library.global=VM_global_library.vm velocity-1.7/whiteboard/daveb/dajarred/test.jar0000755000175000017500000000200207250027506021541 0ustar moellermoellerPKX}b* META-INF/þÊPKPKX}b*META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h—æ)øf&åW—¤æ+xæ%ëiòrñrPK3ù5¤DDPK S}b*example/PKE}b*example/test1.vmmŽ;Â0D{ŸbÀ¤ ˆÐs€ˆÞ kbä²—ßíY+i°¶ñÎÓ›ÕÃä dL½M¸{“|À$ä”.Ä[l¸ÂG¬ÏXwJÈû›ShùÆì«yß¼{–õ¡†~9¡#x"Ô ¿™¼’"›2™q’²hAˆw¢ëäµeÁU(^)Mñò»nLñâØ¥('r~§Åv fÉ • +² W—/ô°F¢¹­æê PKk3ý˶8PKûxb*example/test2.vmmÁ‚0DïýŠr€ƒ½ûÄ{‹lRZC¢ï6½ØôÒ™×7Ö¢›8A¯  —›Ÿž°‘=ËBúvBÆØDR£’ ßPÞ¢lŒÙÃ:J‚ ÖÅg]{ÈZÑøzÞæB%c\Èõ“Š‚› PyÖ_ž#Lx(%…±†ïrÃÀÂ1è¼,+é°åõ¯Ø%ÝDø±*ËpvùDÿÑiµ¯åÞ|PK×¥-¢PKX}b* META-INF/þÊPKX}b*3ù5¤DD=META-INF/MANIFEST.MFPK S}b*Ãexample/PKE}b*k3ý˶8éexample/test1.vmPKûxb*×¥-¢Ýexample/test2.vmPK/½velocity-1.7/whiteboard/daveb/dajarred/Example.java0000755000175000017500000001143010513464370022327 0ustar moellermoeller/* * 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. */ import org.apache.velocity.runtime.Runtime; import org.apache.velocity.VelocityContext; import org.apache.velocity.Template; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import java.io.*; import java.util.ArrayList; /** * This class is a simple demonstration of how the Velocity Template Engine * can be used in a standalone application. * * @author Jason van Zyl * @author Geir Magnusson Jr. * @version $Id: Example.java 463298 2006-10-12 16:10:32Z henning $ */ public class Example { VelocityContext context = null; private final static String JAR_RESOURCE_LOADER_PATH1 = "jar:file:test.jar!/"; private final static String JAR_RESOURCE_LOADER_PATH2 = "jar:file:template.jar!/"; public Example() { try { /* * setup */ Runtime.init("velocity.properties"); //Runtime.setDefaultProperties(); //Runtime.setSourceProperty(Runtime.JAR_RESOURCE_LOADER_PATH, JAR_RESOURCE_LOADER_PATH1); //Runtime.setSourceProperty(Runtime.JAR_RESOURCE_LOADER_PATH, JAR_RESOURCE_LOADER_PATH2); //Runtime.init(); /* * Make a context object and populate with the data. This * is where the Velocity engine gets the data to resolve the * references (ex. $list) in the template */ context = new VelocityContext(); context.put("list", getNames()); } catch( Exception e ) { Runtime.error("ERROR starting runtime: " + e ); } } public void getTemplate( String templateFile) throws Exception{ try { Template template = null; try { template = Runtime.getTemplate(templateFile); } catch( ResourceNotFoundException rnfe ) { System.out.println("Example : error : cannot find template " + templateFile ); } catch( ParseErrorException pee ) { System.out.println("Example : Syntax error in template " + templateFile + ":" + pee ); } /* * Now have the template engine process your template using the * data placed into the context. Think of it as a 'merge' * of the template and the data to produce the output stream. */ BufferedWriter writer = writer = new BufferedWriter( new OutputStreamWriter(System.out)); if ( template != null) template.merge(context, writer); /* * flush and cleanup */ writer.flush(); writer.close(); } catch( Exception e ) { System.out.println(e); e.printStackTrace(); } } public ArrayList getNames() { ArrayList list = new ArrayList(); list.add("ArrayList element 1"); list.add("ArrayList element 2"); list.add("ArrayList element 3"); list.add("ArrayList element 4"); return list; } public static void main(String[] args) { Example ex = new Example(); try { say( "Started..." ); say("get template from template.jar"); ex.getTemplate( "/template/test1.vm" ); say("get template from test.jar"); ex.getTemplate( "/example/test1.vm" ); say("try template from template.jar again"); ex.getTemplate( "/template/test2.vm" ); say("Try something that doesn't exist"); ex.getTemplate( "/example/yomama.vm" ); } catch(Exception e ) { say("ERROR"); } } private static void say( String m ) { System.out.println(m); } } velocity-1.7/whiteboard/daveb/dajarred/build.xml0000755000175000017500000000466010513464370021721 0ustar moellermoeller velocity-1.7/whiteboard/daveb/dajarred/velocity.log0000644000175000017500000001240707254734331022441 0ustar moellermoellerMon Mar 05 05:41:45 EST 2001 [info] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : runtime.log = velocity.log Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : resource.loader.1.description = Velocity Jar Resource Loader Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : external.init = false Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : counter.initial.value = 1 Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : resource.loader.1.modificationCheckInterval = 2 Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : counter.name = velocityCount Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : include.output.errormsg.start = Mon Mar 05 05:41:45 EST 2001 [info] ** Property Override : parse_directive.maxdepth = 10 Mon Mar 05 05:41:45 EST 2001 [info] Log file being used is: /home/jvanzyl/js/jakarta-velocity/whiteboard/daveb/dajarred/velocity.log Mon Mar 05 05:41:45 EST 2001 [info] Resource Loader Instantiated: org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:45 EST 2001 [info] PATHS SIZE= 1 Mon Mar 05 05:41:45 EST 2001 [info] Try to load: jar:file:template.jar!/ Mon Mar 05 05:41:45 EST 2001 [info] Attemting to connect to jar:file:template.jar!/ Mon Mar 05 05:41:45 EST 2001 [info] Initialized JAR: jar:file:template.jar!/ Mon Mar 05 05:41:45 EST 2001 [info] JarResourceLoader initialized... Mon Mar 05 05:41:45 EST 2001 [info] Loaded Pluggable Directive: org.apache.velocity.runtime.directive.Literal Mon Mar 05 05:41:45 EST 2001 [info] Loaded Pluggable Directive: org.apache.velocity.runtime.directive.Macro Mon Mar 05 05:41:45 EST 2001 [info] Loaded Pluggable Directive: org.apache.velocity.runtime.directive.Parse Mon Mar 05 05:41:45 EST 2001 [info] Loaded Pluggable Directive: org.apache.velocity.runtime.directive.Include Mon Mar 05 05:41:45 EST 2001 [info] Loaded Pluggable Directive: org.apache.velocity.runtime.directive.Foreach Mon Mar 05 05:41:46 EST 2001 [info] Created: 20 parsers. Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : initialization starting. Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : adding VMs from global VM library template : VM_global_library.vm Mon Mar 05 05:41:46 EST 2001 [info] Attempting to find VM_global_library.vm with org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:46 EST 2001 [error] ResourceManager.getResource() exception: org.apache.velocity.exception.ResourceNotFoundException: Unknown resource error for resource VM_global_library.vm Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : error using global VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: Unknown resource error for resource VM_global_library.vm Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : no local VM library template used. Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : allowInline = true : VMs can be defined inline in templates Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed. Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : messages on : VM system will output logging messages Mon Mar 05 05:41:46 EST 2001 [info] Velocimacro : initialization complete. Mon Mar 05 05:41:46 EST 2001 [info] Velocity successfully started. Mon Mar 05 05:41:46 EST 2001 [info] Attempting to find /template/test1.vm with org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:46 EST 2001 [info] Attempting to find /example/test1.vm with org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:46 EST 2001 [error] ResourceManager.getResource() exception: org.apache.velocity.exception.ResourceNotFoundException: Unknown resource error for resource /example/test1.vm Mon Mar 05 05:41:46 EST 2001 [info] Attempting to find /template/test2.vm with org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:46 EST 2001 [info] Attempting to find /example/yomama.vm with org.apache.velocity.runtime.resource.loader.JarResourceLoader Mon Mar 05 05:41:46 EST 2001 [error] ResourceManager.getResource() exception: org.apache.velocity.exception.ResourceNotFoundException: Unknown resource error for resource /example/yomama.vm velocity-1.7/whiteboard/daveb/ToolTest.java0000644000175000017500000000337710513464370020745 0ustar moellermoeller/* * 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. */ import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Properties; import org.apache.velocity.*; import org.apache.velocity.Template; import org.apache.velocity.runtime.Runtime; /** * Just for testing */ public class ToolTest { public ToolTest(String templateFile) { try { Runtime.init( "myprops.properties" ); Template template = Runtime.getTemplate(templateFile); ContextWithTools context = new ContextWithTools(); context.put("test", "HEY!"); Writer writer = new BufferedWriter(new OutputStreamWriter(System.out)); template.merge(context, writer); writer.flush(); writer.close(); } catch( Exception e ) { Runtime.error(e); } } public static void main(String[] args) { ToolTest t; t = new ToolTest(args[0]); } } velocity-1.7/whiteboard/daveb/pdfvsl/0000755000175000017500000000000011675166252017621 5ustar moellermoellervelocity-1.7/whiteboard/daveb/pdfvsl/pdfsite.vsl0000755000175000017500000000745610513464370022014 0ustar moellermoeller## 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. #document() #macro ( makeSectionHeader $value ) #if ( $value.getAttributeValue("name") ) #set ( $titleName = $value.getAttributeValue("name") ) #else #set ( $titleName = "" ) #end $titleName #end #macro ( makeParagraph $value ) $xmlout.outputString($value) #end #macro ( makeSrc $value ) $escape.getText($value.getText()) #end #macro ( makeLink $value ) TO DO #end #macro (document) $root.getChild("properties").getChild("title").getText() pg #set ($allSections = $xpath.applyTo("body/section", $root)) #foreach ( $section in $allSections ) #makeSectionHeader($section) #foreach ( $item in $section.getChildren() ) #if ( $item.getName().equals("p") ) #makeParagraph($item) #elseif ( $item.getName().equals("source") ) #makeSrc($item) #end #end #end #end velocity-1.7/whiteboard/daveb/pdfvsl/build.sh0000644000175000017500000000320310513464370021242 0ustar moellermoeller# !/bin/sh # 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. if [ "$JAVA_HOME" = "" ] ; then echo You must set JAVA_HOME to point at your Java Development Kit directory exit 1 fi # convert the existing path to unix if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi CLASSPATH=${JAVA_HOME}/lib/tools.jar for i in ../../../build/lib/*.jar do CLASSPATH=$CLASSPATH:"$i" done for i in ../../../bin/*.jar do CLASSPATH=$CLASSPATH:"$i" done # convert the unix path to windows if [ "$OSTYPE" = "cygwin32" ] || [ "$OSTYPE" = "cygwin" ] ; then CLASSPATH=`cygpath --path --windows "$CLASSPATH"` fi CLASSPATH=${CLASSPATH}:../../../build/lib BUILDFILE=build.xml echo $CLASSPATH java $ANT_OPTS -classpath "$CLASSPATH" org.apache.tools.ant.Main \ -Dant.home=$ANT_HOME \ -buildfile ${BUILDFILE} \ "$@" velocity-1.7/whiteboard/daveb/pdfvsl/velocity.properties0000644000175000017500000001075010513464370023570 0ustar moellermoeller# 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. # ---------------------------------------------------------------------------- # R U N T I M E L O G # ---------------------------------------------------------------------------- # This is the location of the Velocity Runtime log. # ---------------------------------------------------------------------------- runtime.log = velocity.log # ---------------------------------------------------------------------------- # T E M P L A T E E N C O D I N G # ---------------------------------------------------------------------------- template.encoding=8859_1 # ---------------------------------------------------------------------------- # C O N T E N T T Y P E # ---------------------------------------------------------------------------- # This is the default content type for the VelocityServlet. # ---------------------------------------------------------------------------- default.contentType=text/html # ---------------------------------------------------------------------------- # F O R E A C H P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control how the counter is accessed in the #foreach # directive. By default the reference $velocityCount will be available # in the body of the #foreach directive. The default starting value # for this reference is 1. # ---------------------------------------------------------------------------- counter.name = velocityCount counter.initial.value = 1 # ---------------------------------------------------------------------------- # I N C L U D E P R O P E R T I E S # ---------------------------------------------------------------------------- # These are the properties that governed the way #include'd content # is governed. # ---------------------------------------------------------------------------- include.output.errormsg.start = # ---------------------------------------------------------------------------- # P A R S E P R O P E R T I E S # ---------------------------------------------------------------------------- parse_directive.maxdepth = 10 # ---------------------------------------------------------------------------- # T E M P L A T E L O A D E R S # ---------------------------------------------------------------------------- # # # ---------------------------------------------------------------------------- resource.loader.1.public.name = File resource.loader.1.description = Velocity File Resource Loader resource.loader.1.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader resource.loader.1.resource.path = . resource.loader.1.cache = false resource.loader.1.modificationCheckInterval = 2 # ---------------------------------------------------------------------------- # E X T E R N A L S E R V I C E I N I T I A L I Z A T I O N # ---------------------------------------------------------------------------- # If this property is set to true then an external service will # set certain system properties and initialize the Velocity # Runtime. This method is used by Turbine to initialize the # Velocity Runtime for the TurbineVelocityService. # ---------------------------------------------------------------------------- external.init = false # ---------------------------------------------------------------------------- # VELOCIMACRO GLOBAL LIBRARY # ---------------------------------------------------------------------------- # name of default global library. It is expected to be in the regular # template path. You may remove it (either the file or this property) if # you wish with no harm. # ---------------------------------------------------------------------------- # velocimacro.library.global=VM_global_library.vm velocity-1.7/whiteboard/daveb/pdfvsl/build.xml0000644000175000017500000000404610513464370021436 0ustar moellermoeller AnakiaTask is not present! Please check to make sure that velocity.jar is in your classpath. velocity-1.7/whiteboard/daveb/testtool.vm0000644000175000017500000000157410513464370020543 0ustar moellermoeller## 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. This is the tool test $test Tool 1: $toolone.sayHello() Tool 2: $tooltwo.sayHello() velocity-1.7/whiteboard/geir/0000755000175000017500000000000011675166252016170 5ustar moellermoellervelocity-1.7/whiteboard/geir/xmleb.jar0000644000175000017500000002522307357331423017775 0ustar moellermoellerPKhJE+ META-INF/þÊPKPKhJE+META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àår.JM,IMÑuª ë(h8ä¤*8çç”–¤é(xæ%ëiòrñrPK~CCPKÊIE+ README.txt]RÁŠÛ0½ë+æR6Ħôæ[Z ݲ…- %P ;–Ƕ²’ÆH²ÿ}GN·¤=ÍHóÞÌ{ãï£Ñ¯†Àø–¡RêhÜ` /òAìyö3®9]Ë&Á²¬MZ¢Sà8N†½ÂaŒºÏÅ_ ãçoOаù¨5ÅX(ub¨GcH½‰¹æ³Ô~$ô;XxOÔÀ×Ãù6àLA`;zk m¥¯à´ÅLýjN½ºàu(.}:ÙçüŸv¢bÊ\]@wßú$÷·öh#ßfx›)· y ‘n43ß&h¥y ˜ÓvRècïî;dá‚thüf› çâJ„¡™¶˜Ü:ÿ_Ù ƒi& ‹Ø%”Ѥ”OñAÆC BÅaÍ#ô8|z:χÓ)²ÿ@qDkEƒ¬r¿èSQ[£ÏÁÏ•²ç˜ª¹7‰jÆÐ”™PÊ8Tÿ‚Î]ÞÁ'„ýß@Q½Ù_ÝY_M Ü¿/>ìšÖýüg:d^Éël‘ÈφVeY¾ sóRÞ?J¬”ú PK8þDcª¸PK®HE+!XMLEasyBean$XMLEasyBeanNode.class…TyOQÿMK»íö ´€¨h·•‚÷Ôƒj‹G¼bXÊZ–ÔÅt·&øiüšFMŒÿ™ø¡ŒóvËUVÝdçÍÎûͼßû~ýþúAœÆ‚Š\ˆ¢¥¸Áe¹^QpUEØÛ™”âšÊbJŠë1LcFŠY ÉKqCÁM·TÄqAŠÛ îÚ,ýµAH×ô·z®¦[Õ\Ù©›Võ*!ôV¯5xSÕ6-7Ã&tyȆcÖrsº½ZÒß04RY5k+uÃ"„UÓNŽŸ”Š7u{cÖÐ-ÆDË–³j8f…A“¦e:S„¡Ô>ÔAé&™__aEÓ2毗ú#}¹Æ–ˆ³îÁÝ©´_ÁªáFR>÷˜î-¯Gæa΂—uŸ“‰Tw ‚Ñ3Ûµ!ŒúxøÇÕ}Žÿ£·“ÐWVò²Òó^Aö”γˆ‚eõ|M·mÙ¬}ÕM¶À]*1¦’ßi^úïLÜŽÏÔëúFÑ´e­Ôòz£^1n™²{bI¼@?î Ç Ã8B€ÀQ¹ÆÌÀ1ô ôI‘FRà Î*( ”0/0Œ{÷ñ@jù V~<’>üÊx¤à1¡ïØÎ™”¬KûnP‡Ð6ßînAGÁw~‚o ½”:¸wÐâ`ÄÇÕÿ$…–!݆?ã®îIƒ|)ô! [ÁZ@¶Â]¹òîÚç® Ù/NB>Q~û1À߃¬-ñ}äu\û Ò2›h´‰ –hÛDHû†ðÓÏP6ÙU£Z–Ù‡ÿs–'¡°:(ih§ ºé4úi AŽÎ2ê’ÍÓ$ ’œµ-¨vB„¥‘.²ÆH:Åô%±^-³…X)û‚»õ±lð ð!»ëŸ@«“Ó:iG)ÏÖQ¤š±†8V@ž# íRW¥•梥}h~B¨•f‰5 ™&t´Y¿C#™ìÚ[ã?„Je¶dùâ÷œ’M>ÂuÚBÇt¶³ÈÚ&šÏ›ÇäØ#šù„ ë/e"ö qîL¢”åH]‹Û€*½ôô]´„>ª` ŒÑ+Þå_Ó‡ZÔ£o¥¶Æˆsî|Ǹ›&_Ô˜CôPK£ÔÐñEâPK®HE+XMLEasyBean.classW[tTWþvær&‡“Z !(ÂdB2Ú"… V!„vtn)PêÉä$˜œgÎD[륵µ­XµU[•Š—¦ÞIm†Òh[oE«vé“Ë×ré»Ë¥._Ôï?3΄²|ù÷åüûûïÿÞçõÿ¼ô2|èÄ:vãT=¶ã ï×¹ç.L!CBRB†ëaaDè§B“1-ä´3:2×±¶Ž,r:>€¼‚GHQÃY«1¡cS>‡tlÀ½î áÃîá#>ªc#>&j|\òxp>‡„<,ËOÊìaxTÃc::pJŸ’Õ8‡O ×ã!|Fv>Âç4<¡Ó„Sž áó¢ädýEÑù)™=­áK MÇû’½faj¯eÚýÙaKÁHض•ïɘ…‚UPðç³YG¡5éaܼàP·B à˜©3 +’§Í³f¬è¤3±#²ÅoõsòX>íXy…Uåïé,¿æÓöhyŸL¶9nrfÊÚ3a橇:¡ Ÿ53éaÓ!£BpwÚN;w(ø"íG©X«nS2m[ýÅñ!+?`e¸ˆœ8á2d²æ05Š”EÚ–»ûp²[>i£–sصkC¤ýM,3hYÞéÍXã–͇*pÓ­ØÐ}C;Ùühlr<£3b{n«àª£÷N¦¬œ“ÎÚt¸nÙÃUi»þOi.jjÌÌ›)º—¨ZädO"án˜Ž™éÍç³ Ç¦H^Gö?hæ VUÈ?n¦m†.rò:‚Žd‹ù”µ?-Þ_îñ`—°¸ ïÄ»¬Éa`öèÁ>½ØoàNì×ðe_Áy \(moqdD’¨1ÉÈrÝÆx¶ÅÛ <ƒ¯ ¹`àkøº†oø&ž50ç4|ËÀ·ñ ß5ð=|ßÀpÑÀŒçñC…–ù|,ƒ[à ;Wt(Ï2ÇEõ4Ì(á’ÂÍó¬‰U)4xV¢Ë‹H(¬YàU£wo›‡uÍËg'ÊY¼â€3fåÛj8[–ÈTÑõ²—0WƒX=oàGø±†— ¼‚W üDÈOñ3?Ç/ ¼†+ ++M¿Äœ†_x]gkõ躚®‘v7¿Á1…µ^–«i;–y>²À¼åÉLaÅc11ˆ1ìC¿Dó·à ÖëØ1+“cvÇöY#f1ãÜeÚÃÉåžÄ™*8Ö8{F¶Èrj®vŸƒ´°eÖxÐÌåh‡Â¶Eê­ýš­rªt/`?0tÚJ9K±‡œly‡¾Ž\Ë×íI1~tINVúªy1ýX‚Yêß“eçN•³lí<~ůW¿uÏÖ5_þèÉ…Õó0’õW?c“lOº¡ÈIË`æ»G~?»N6?Å@ÛÖDÂfµSLé-°¥O{EÁrú\þˆÛÔøé¨çR0(¡ŠPnçKˆ öšÈ¢ vË'y­¸{ »H¾ybºBšråȲû °;[nöÔÃuš¹?gYg¦M%ãèsx¸g,._ám‘%ï4Á[µøuÄe çK²%MRaa ŠòX`8ª§¶ÞÐu%ò뉑´ìQg̽Ïba±0&I²tIUmöå²¹ÚR¯”V0SÁ ªz&¤™-¨Ÿyô£|:mç{ N.*ÎêäfrG^NîÈûÉïtÇz(¹×HßÍÕßbŠãæè%¨¨šE]t¾ÁKðÏ" ë`Ô7 MHh†| ï!]Ô†÷o+ùÚ c”ûc¸…J‘¬H¡Ç®m‘ÙºY[(8{Yˆð}Ú‰)r³á–eª5äòÔÅçQ?–Ýd”ÐÐQBc M%,çlEß¶nê7Çýa¿¯„•.mûKX„sX=Øy k¢%„§1Òçk!ض*gë¦ÑÛïaXO†Î*C§Ë°9î÷p´‘CDUXdºnÆõT‚¾[ëŽãhuÇs|x—½qšH¤¢¦¡Ec&œC7çé'èõ'yú)r=ÍÝó|H<Ã÷âð2ªD¦•£Ä>}u«º›Ï‘Âa¦°þž q¼OÅé–ƒQúeS<(¯Àˆ†ƒ ë4Vr(á–W±1˜F ®…¯AÂÁÞâÛ¡M£5 û›µËØR‡òdkß(‘4Õ¬…ý—Ñ®pá¿ 9=Ædé ¿¶1Of¨ÒzDíÍUãh$¥×èG¾_šùŠXÏwA'® †7è‘ßÑ#`EüÇ9ŽâÏüµù îÅ_q„'ýÄ/ à“Ä’ÌÙW6¥SLñsN]º$'Jˆ§E~™½ujBú¶ÚΔ+ [«ú®u±ÿ§®ÿ ìòë¿X©ÿ®Ñç(ŽUôÙɽÇå¢CǺÖnÇúËØ:ªØ’;ʇ@“ ÖàÇ`ïvrÕqlñ¨}[me¼RÍ]X•°jðÀÕãNVR(Mƒ$ewÍa;±Þžì˜ÃŽÁyàÛ õÝJJèKØY®i,“:bÅÄ)²»Oì1ƒ;ªv¬{U3B*ŒÕŠÛTvªTå½n{k@TSnï{ÔÿPKfͪ£”PKŒHE+XMLEasyBean.javaµZkoÛFýÿŠ»BR©J'ÝÝ/v„–阅,¹¢ä4( ”–FŠ£òaG[ä¿ï¹3÷”4Û.‘JgîëÜçÐ=}zBOi¶ä삾|¹ÊƒDÐ(\ˆ8ºIʘžÛϱ—·ånŸ„ëMFÖ¢O?<{öü ‡+™ÇË ­MäD)š”9$"ɃXÚ†ãT,Ã4KÂûœ·S/)O…1¥2OB=¹ã ÙÓJ&Ût@a¶!™¨o™gÌe+—á*\(‘bv"Ù†Y&–´KäC¸ÄM¶ 2|ð‰"ùÆkZÈx2‘Òé¶";3ª=·[Ú¥$W…Z ¹Äæ<Í`Q@]fÜË^2 1\±Ì€è;”"ðc6•deaS-]DA¸IÓ]] ³†K¡ ¬]æÐïÿ£„.¼c)ùVÄYP¸î^‘XIhd" ƒ(­àWnâaP7¦°òŸ¶ '/¿G$-a¼ˆò:'˜[ç2 pe˜ñ~ 1D-‹‚ŇX>Fb-˜ý™¡ÂÕ›1*Ä’8…ÓMd/ŃˆäJÜïkÆðu< ÈÚdÙîìôôññÑÔ6[&ëÓ¾Ý3ôN¸b`ícšÏ=»ØʘR¥0KE´NáJ9ðN€ª ¥ù‚± “å÷» Éö-Æ)Â!ÙQT°/\ñ/íŠ8ØÂüßþ|ƒ€nù^,²Þ€zC¹Ý"dpË2{-ŒF=í Ý NsšdoË)Øî[™‰ÿp'!Š…á´Â²F§4ÞÔP„\NùX'šªúsU=7lªÕí"¤œ#28\;çu壎ÛlwC©Cê°›Œy €*JPzeò%jSñ¸éÔ01€4«£>'nV•ß7‰Ìw…³kÏ'r5{ëL]Âýítrç]º—ôÛoŽß~KÎøÿ½#÷çÛ©ëûX›LÉ»¹yî%óéÔÏ<×7Žæ—ÞøÍ€.æ3Of4òn¼ˆf“ĹeŒ™L®èƯñĹðFÞì’{åÍÆIWéЭ3yÃùÈ™Òí|z;ñ]‚ÚL~éùÑãݸ—h%Þ‚ɽsÇ3ò¯ÑHÉun!¾Jc¯&óñ¥3ó&cØÃ<¼™OÃÉx6õ údêÓ… å‹‘«Å‚Koêglfu7\Pz¤RË¿u‡î– ;黣¶¾ûÓû°H—ÎóÆõÉê¢Å<ê€ÁÃùÔ½aS‘?¿ðgÞl>séÍdré3oßÞyC×?§ÑHM®˜ÇÜw3s”xpØû‹¹ï)H½ñÌNç·Œ@Ÿ®'o4uæìa`¯¼2Vf¾Éô+Àx(ï èíµ‹çSF[¡æ0>ÐÎjÛ—)l™ÎjöÒØ}3òÞ¸ã¡Ë«fôÖóÝ>üéù¼ÁÓ’ß:;Ÿ™a7B=}[ Ür6yWä\Þy*Bõf„ˆï™pÒÀøóáµqç½ü®"—9ŽZ‘¢ë¨aàAF9*z0Wª7o´tˆ-sÑ]ÑsnˆÈÛ{± ¢U+}OO\¾¶RÓ0æN¯[ŠŒ¿@[Ö¶T(â‡{Ð+ëôä$Üîd’Ñûà!°aDd;IìG0ô¼»æ¡[™L,¡ðQ^?x~ì<½ÒZi,…l´ï·¨‡¢%‹G{ñ.Ï@(‚íçÖ¦>ëR_ä«Zéò³\&îÇ…Ø1ê-•c‘ÙóéèüÐáŒcôÑÑGûã6²Ñ¬1¥¶ïü|«nÏÿÄž+ô0™ì+~ÜÁxg Šˆv¼ûR¬‚<ʮѲ£ÛúV'Ó±,ÒƒËW3øð¥P–Ó§*—ÈÇþYiÊí#£%ý|3*‡=g ‘Ë£ÊB`“ê³w»a¶W¹MꃇL–…ŠÑ=¼àŒ[CXŸQ1o&@sNž"„ʹ훕”ö=æžG)סžY yºGj,*æïßsðà‰ MC$§%*búö’õ>ø¸³ß£™ó0´HÂmŠ Æï~Ááu£­'ô" M"V/{Û Œ2y¶Fãß¾–»LÆQ Þ«7< Üë8OÁ‡~Lì§Á+ÍçÁ̾ñ–gߨüÝå÷Q¸0¨Mø]¨&>brX¦ÔôúÉ'OàJ¤Tã?Î4RrÁ<Õ°Qciå˜O>Šð%ÅyÁ·ŠWÊ)®§:ö b€8@©3U È€‰xÔ¬þù ifjüo³aÏ>Èàn‚¡Ž-˜qyˆí¨Ê! Í]©o}ï½”¥/ÔEá¨Bú’V(ÖâüàÞ‡ ¹ÊB§Æ>õ¡/ް¥††3EÔS£ªvX W«¯þPŸŸóc6úðQ&¥½Ì–Tè“m%¸4GEcMáU¬Ó/©ÒEeÐ6^P]_}$ S»cù༹±aÁó¼f¼Ž„“'lN$ƒ¥Îgyχê¨*G€c‰™Æ…&Ø!ˆ«QiyrŒä¡Y!ŧklÖ¯ñ$ØRžD¶0=veN™;™†\X¹Àñön*"YA‹e)d0 ”?ªÇ|ùû4[þ(‹³(¶z#0c\˜Ýõè;Íô¼AØøÑh'<‹ÄD6ŽªqµbµxԚїŠÒ^‹¬¶À4M[Ý  ¿_v–Pɽy/D[¶¡²ºãFÌX*¡Žï¾+çàÎú‡«t-U+WuᩚøP_–ªP+Lû²š¥µ¯Â»¦Ô§òa…øEµyDÿk"£F©£m½Ð{U9¡F6`ïjRïä_©JôoÑe¶Iä£êà_§ÈD½púëº|:éÖÛ©Èò$Öe£è•©‚{助ê—È©)è­veH”Å»Vû:z …0b‰H¿ RM6:ÞŠ.i¡ :)rWS[¦;V…y>õÅC®}çcùäwý« )Ȳ´_+æ 7¢z8´l<}Z¹¶¬M¯Êä®´ÈœfømdmïéÉ“'ø×ÆIÉ4E7ïn(¸êÑ¢µji‹¸œ‚{!+\Yf¦ÑlûXl†ž™x ïC,PŒŽÄm £` ‰¡Ukù´YrÑ?¿›Ì•· L¬–¹}=fÙ;!>´Kð§Æ/•‡V½4e~ª™|Ì·üÊq¯§c~‡Ùuh p²ŒÒÿ( /EñðDo°ƒår¸ £¥vŸñ@#éËGµšoƒ2‚kÄyd¡FPŸãë… uî‡#¯³ ð£ð»ïúGœlãUf‹U²ø‰£Î Ñ0Š'hd9?¡?m :~áØÊ=I³¿w?lŸ‰ƒ<ÝX]«]õiY æÕ(]Ä®Q"…sÆçKT1È­SàðWªÔ×¥zJ5Ýx¼šÍ-¹k§V³kiyÀ*áµ3©wæ+Î JíÈ„½¢gÍLä«k:ŒÀýxwµ¨–Öt,~5ךÅvÍ;}3—Š®Ð#'ÎÀòØ–Ú¶}4ª]–º§ I~ùu@œšª‘é[ý=>¯ÜÂïÚ9k“dPH+$ýYxQ*Kjht ]áØ¹IÂu§óƤ60ŒZ–}Éu•(«ß”j¾:þ+ÏõKqŸ¯×G²8å?Õó¶üWÑ"ù®Ó~[ñú« œ³º-»‘ÇZ[ŸÁ˜Ç!«· #qvzÊÆ²è_žýJýÿ!EZ©ÜZ©ßí:Âmö±¦å4Ø€¼vÞMùOr­wdœAŠGý50î4Ÿƒw‰äWìuH}rì­ÒçZl㕉*·µÉªµúÀ¥˽¿ô)WÍëÚZ‡5~4 VÿüÀî·tô÷îÞîH×h¤‡3ÌåóžÅ|ÒC£1ÝUÅÖê˜Q³wÙ‰ûš¼t a1Ño°­­ÅáPä7àA#P –!ùL“à²Ùiø(ÂSèsjÍ_`ô8œ¬gŸíZW+u4›C©AjÓgˆ²ÓTÁPy¢ˆ |ל`vVÛLEeP¯ÄÔ†'ÃàƒØŠ­"ƒ ü£6ªGCa}Dµ•³ôZ¿Ö i½¹©usB=˜ùн<RþyʼnG‹òw¿L -‰í"z˜’…iªƒŠVûIPÌl%¯Ïü À„§k˨¨”ò¤¥|þÿjjvW4âü`žˆ7²<‘}R¦œ° üãë¿PK6c”íI ©$PK®HE+XMLEasyBeanTest.class}U[oUþN|Yg»Íʼn[œ¦ÔmCê$uL­إЄ”œ ±s1)Ðsâl²Þuwש]n-BBðxå!¼ µ<Ø–x©/ð‹sÖ6iÒU,y朙9s¾¹ìœgÿþþ|Hౌ8¦$LËè” ¯…ðºàoHx³oáš„·etc*„”àé® þŽ 7d¼‹÷$Ü”Ñ/ÜÌÈ|VFï‹Íœ°¸Âbs[Æ|(á# ç1/c 2±$ãc, ’ !'î_‘±Š5 ë2F‘—ð CðºfhÎ †+ñÌ®º¯&uÕ(&³Ž¥Åô‹’±Uÿ¬¹Åz3šÁ*¥MnåÔM$þ’ª gâÞå¬Y± ü–&Œ×ç3sª]›áª‘ã¶3)Ž(Ãèi“jY-ìðä>×Í‚æÔh_N®¶7sF‘.WpWXðªZ*ëÜN¶“û%Ÿâ3R☫xÙÑLCÂç îA% ÇQÎT¶·¹Å€b©X¶f8j5Æ-Ë´bšs8¹WS°‰K‰Å–Žm E;Ð.{¡ï Ÿ5 ‡W†SÏÅÏ ¸P î$W–3" š‚]ì :ƒ¯ZÒ”p_‚¥À†ÓÁ®™Éf¾µfiŽÀ>ÔQ,VœrÅ¡À¸Zj)…ߊ û(¨¢&á¡‚/°¡àK‘ɰˆ;ãTQ |]Â× ¾½Çª&¼3ôfrqs— /îöŠè. ¶È\;y Ó­6–ñÊZçLúÈÙšM• +Ì ùŽd:/‘§vÀt H Ã-†«ž×y×>}̼ÍIæ!ÇlI¨¥ã/Ú¥;MxƒT;jñÂ'r§›*Áïo«ÛÍáª"^I.Qž—MÓ‘ðèh­ÜOV¹cÜšÕUÛæ6ÃÂûœÍÈ1{‚>áU”B«…“77mÇR Îÿ-í+‹z\;yxd´-bˆÆ3^Ýë†6p¨ku³+>©k%n¹‹é¤HÚ¤½nè9*#ŸÛzÅÞ!^ÐM[Üᎇ#³&·c™Z3±·Ü*ºZØËQ²Hrî„”ã" æ8į L|[D'¶„B$ýg¼ÖDW¾ßB¢ÿÄ_†–ò'&ê¦üˆ§¿!ÔD7ÉáSu(¤Q§‰DuôÔÑ[G_ý¤§M Ðb0Œ›ˆä¯6p¦Ž³8’ÈMTªã¥h ëªãÜZÔÿ'ÆšÎ7q>O ¼ÜÀ…”õGÂ:&ÈEA.àáê ¹,ø;FÄò•§ôbQÔ#°AÃn¸‚_ñ„8}Šñ*½zÀmøé™S0>d1ˆœÅ:¼K'ˆehä¡Dî£ßbßÓŒû 5üŒ‡ø…æÜ<Â3<ÆßøŽÚ&[Ù¥€ò ô61š÷Mû§¸’yJ¢ÙUÿ€üH«¤[žWQv5 =Ã&ØPK Ô.QFPK«HE+XMLEasyBeanTest.javaµWmsÛ6þî_±Õ—Ò)CǽëçzSZ¢lÞÈ¢Ž¤ìf2™)MA6’à€ dÍMÿ{€¤^(ÅIgz˜q„ØgwŸÝÅ‚goÎè ÅÏŒÜ2Iñ‰¥Z'’Ñ„§¬¨˜M÷LV\té\â¬>>åFò§gEVzN?¾{wya,êb‘(È:Dn–‘‘©4‚d“+¶pZÄ-x¥$¬õqJŠÕ#^P%j™2³òÈ‹Dnh)d^Ù´æê™„4¿¢V% ¾ä©Qi“6¡d2çJ±•R¬øõœ(üÀ“ebÍ‹'JE±àZÈØ¦år¦®ZÓ.žu‰egV*8\W ©æjàäQ¬ôVK’Á(„£6NðŠ2ài˜fãá¡YPšf Ï™ìhúñØèÜ㥳Þ.jØ÷ÿ1J[}b!Ò:g…JºÐ] *;’òD1É“¬ÚÑo†Í`ß™ÎË8&X±x‹$=¼H³z îî£ØÄ—-xRl솑V¨çQ’~.Ä:cOLÃ_µRƒX³Ò¸®ô6³lÅ2QˆÇÍž3z|¹ÈzVª¼º¸X¯×NbŽ9B>]œ;ƒVÞÍ@WβM˜C Á熒²d‰qfkWË–v‹Ä—&€k¦JªêTsÅåâm™HµéWH™'YÖÁw¡øgŠ"Éáþ@Oÿ“|@B3)~g©Ø4¸)W̵ÒA‚Ö¤ƒ&&È@zdºÎ‘iB‡[HÔ<’ÄçB±.ø–·E‹´ÄvCÏÖûö€×W‚Ô5_4Õ_UæïÖ[˜Ý®MeÆ’J ² o¢óË.H?9Úñ£N™£ãÔº—‚U¶%e°­>iuˇQå²eü¤[GæëÊU»û÷FŠºì Žoýˆ¢`?¸¡G˜ÏÂàÞy#úí77ÂÂ÷ß“;áïy¿ÎB/а„äßÍ&¾7Ò Ýiì{‘Mþt8™üéM×ó˜¦ALÿÎ!6Ôy䞘 Ætç…Ã[¬¸×þÄ?½c?žB'¡Ò¥™Æþp>qCšÍÃYy³µøÈ†׿óFè%þŠÉ»÷¦1E·îdbôº3wˆŸ­³ã`>¹±LáÆð㈆Á4}˜„]{0Þ½žxzP0òCok7w³!è‚ÑS[ÑÌú˜ƒ,~ºá[³ØÈûïç°I#÷νñ"²ŽÙÒû„!ÃyèÝiW@Q4¿Žb?žÇÝÁ(ÒØ‘ÞûC/zO“Lc1<zbר ˆÄ ̯ç‘o(õ§±†ó™fàœnƒKݹŽ0¸7Q™·A_~Ðh>Ltlz¸õ°j¶ k®¦#{Ãxï˜A áKïùKSïfâßxÓ¡§w ôàGÞ9âéGú€ßh~p¡v·¢Ãóšé^âÚ&ØäÉÝû&C›ÃH‘ÈoÓ©!&šoÛè Ÿÿ†ÑÕÒA㮨ÐvÌk`%²7š°¾AvÍ9OÐsÐ"rt"ÀÑ^ÑkÝQ·ì9É–½ò=ý|Ò×W.šË”ºÕ7=E_‘ÝÞm3Âÿ:Ý„þ ²èÍÅÙÏK!ýž¬‡ çº^.ÑC¸{˜|ßßóŒ\ô‹²V‘’,ÉöƒZm7¿€û…eÈ ow›Ý®¾Ÿ[WVm+rºž4D<Ø‹zÿÚÙ˜åe†®ûê!\Ð[P¯xâÅëÇÓF¯Ó×o<)˜ræá”õcÆS»ªªè×»‰—T›k–1«ÔÙÿÎÌ=ßémZÔpAª5^“nw‹µÌÎp¡Ç¡í„áÏT°uoÝ:‡Qˆ’›í|¤ÇŠ9¼àêà´úkb¼Ñnm㇧žÝktêï´û…ÐYÍe¥lzbÍ‹¼ DäâP Þ6Ö¾×(q*ê¬õø´Áư— ¬ºh'Î*¼?ú£qvb†ÑÙ½UAE=vÀ'}£Çृ>ðø¼gæÁÿðù“>[佤¬4Wcô5j¢M|O OBe…5ÐYFWØÂÅöBLJÑV¨­ú}i^”¥(k£“+çõÜè•=µeØËõv÷(}÷jLCµR{«Gû%ršZà8™H–ÁBÕ[º:éü/ưBú–~-Ý%…ÛØ¼äðÚ\¤](èé‹÷ÊÐÚ%ÃwßV‚ÍÍm²øiè=ì0–^:nÖλ>sztv8ø8}bÖ6ìv«ê„H³á,³ºz¶¾¼Ÿf¢býý]°v³WCvt{šr²ÈÙ[b[¡+SVýgMD#|›|Že’^Ó í~»¨ô×rЇ _ °xa5áã'JäSÕo½æBê8õMÓѲß}² ÈÇËO­œiífü PKiD”*QPKIE+xmleasybean.vm5‹;ƒ0ûwŠ•@‰"EÚÜÁ$Û’rRŽŸB9;³×dCÄŒþ¢á"ݳ4Ú»ûÊö*!¾²ÔHs¬“¸ÙD,ø‡&ïxÞŒ£^T[X7å88æÛ0áw<Ïà¼J÷•"PK©†jPK IE+xmleasybean.xml}»Â0 E÷|…ÉÂÖÐ7EfXCkÒHyTiA|>mCÅR!yð½¶ecùv^;|Áólá” WÇóáz»œ ÕÓ‘ïA2†³ `$§Œ•šLt{Õªª¡,D"ùlli)´–ÆIÄ.xÐäkŠwÊO¥¡è•£‰…bJg¿!£›^n×9Gñ 'oþ %¼ŠwÓ-/ØýÁyºÅï PK0¨’4¦=PKhJE+ META-INF/þÊPKhJE+~CC=META-INF/MANIFEST.MFPKÊIE+8þDcª¸ ÂREADME.txtPK®HE+£ÔÐñEâ!¤XMLEasyBean$XMLEasyBeanNode.classPK®HE+fͪ£”8XMLEasyBean.classPKŒHE+6c”íI ©$ XMLEasyBean.javaPK®HE+ Ô.QF’XMLEasyBeanTest.classPK«HE+iD”*QXMLEasyBeanTest.javaPKIE+©†ju&xmleasybean.vmPK IE+0¨’4¦='xmleasybean.xmlPK þ'velocity-1.7/whiteboard/geir/geir1.cmp0000644000175000017500000000056207226774727017714 0ustar moellermoellerSetBangStart() : called with val = 4 SetBangStart() : called with val = 5 This tests the pass by name some more, seeing if we can assign to a complete reference that we pass in (bangstartII) or, for the truly insane pass in a reference that a property is assumed within (BangstartII) Note that you wont see anything rendered, but SetBangStart will output to stdout velocity-1.7/whiteboard/geir/geir2.cmp0000644000175000017500000000043107226774727017710 0ustar moellermoeller global recurse 5 global recurse 4 global recurse 3 global recurse 2 global recurse 1 global recurse 5 global recurse 4 global recurse 3 global recurse 2 global recurse 1 velocity-1.7/whiteboard/geir/geir3.cmp0000644000175000017500000000053507226774727017716 0ustar moellermoellerThis tests to make sure that we only alter either the local arg in a VM, or the global context. So in foo, we are accessing the global 'b', and the fact that we were called from bar that has it's arg of 'b' is irrelevant. precall $b = 0 foo : $b = 0 foo after : $b = 8 woobie post foo : 4 bar post woobie : 4 postcall $b = 8 velocity-1.7/whiteboard/geir/test.sh0000755000175000017500000000166510513464370017506 0ustar moellermoeller# !/bin/sh # 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. CLASSPATH=. for jar in *.jar do CLASSPATH=${CLASSPATH}:${jar} done java -cp ${CLASSPATH} org.apache.velocity.test.misc.Test $1 > output 2>&1 velocity-1.7/whiteboard/geir/geir1.vm0000644000175000017500000000241710513464370017537 0ustar moellermoeller## 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. This tests the pass by name some more, seeing if we can assign to a complete reference that we pass in (bangstartII) or, for the truly insane pass in a reference that a property is assumed within (BangstartII) Note that you wont see anything rendered, but SetBangStart will output to stdout #macro( bangstart $a) #set( $a.BangStart = 4 ) #end #macro( bangstartII $a) #set( $a = 5 ) #end #macro( bar $b ) $b.bang() #end #bangstart( $provider ) #bangstartII( $provider.BangStart ) velocity-1.7/whiteboard/geir/velocity.properties0000644000175000017500000000171610513464370022141 0ustar moellermoeller# 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. resource.loader = url url.resource.loader.class = org.apache.velocity.runtime.resource.loader.URLResourceLoader url.resource.loader.root = http://localhost:8080/veltest/, file:///opt/ velocity-1.7/whiteboard/geir/delay.properties0000644000175000017500000000152210513464370021374 0ustar moellermoeller# 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. userdirective = org.apache.velocity.runtime.directive.Delay velocity-1.7/whiteboard/geir/geir2.vm0000644000175000017500000000164710513464370017544 0ustar moellermoeller## 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. #macro( recurse $a ) #set($a = $a - 1 ) #if( $a > 0 ) #recurse($a) #end #end #set($val = 5) #recurse($val) #recurse(5 ) velocity-1.7/whiteboard/geir/geir5.cmp0000644000175000017500000000020007226774727017705 0ustar moellermoellerThis is simple : tests to ensure that something passed through a chain of VMS is actually updated correctly in the context 2 velocity-1.7/whiteboard/geir/geir3.vm0000644000175000017500000000243710513464370017543 0ustar moellermoeller## 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. This tests to make sure that we only alter either the local arg in a VM, or the global context. So in foo, we are accessing the global 'b', and the fact that we were called from bar that has it's arg of 'b' is irrelevant. #macro( foo $a ) foo : \$b = $b #set ($b = $a * 2) foo after : \$b = $b #end #macro( bar $b) #woobie($b) bar post woobie : $b #end #macro( woobie $b) #foo($b) woobie post foo : $b #end #set($b = 0 ) #set($arg = 4) precall \$b = $b #bar( $arg) postcall \$b = $b velocity-1.7/whiteboard/geir/geir5.vm0000644000175000017500000000201610513464370017536 0ustar moellermoeller## 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. This is simple : tests to ensure that something passed through a chain of VMS is actually updated correctly in the context #macro(bar $a) #set($b = $a + $a) #end #macro( foo $b) #set($b = 1) #bar($b) #end #set($b = 0) #foo($b) $b velocity-1.7/whiteboard/geir/geir8.cmp0000644000175000017500000000011207226774727017712 0ustar moellermoellerTests to make sure string lits are working Hello geir Hello bill velocity-1.7/whiteboard/geir/geir8.vm0000644000175000017500000000172310513464370017545 0ustar moellermoeller## 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. Tests to make sure string lits are working #macro(foo $string $thename) $string #set($thename = "bill") $string #end #set($name = "geir") #foo("Hello $name" $name ) velocity-1.7/whiteboard/geir/InstanceExample.java0000644000175000017500000000540010513464370022102 0ustar moellermoeller/* * 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. */ import java.io.StringWriter; import java.util.Properties; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.VelocityContext; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.MethodInvocationException; /** * This class is a simple demonstration of how to use multiple instances * of the Velocity engine. * * @author Geir Magnusson Jr. * @version $Id: InstanceExample.java 463298 2006-10-12 16:10:32Z henning $ */ public class InstanceExample { public static void main( String args[] ) { /* first, we init the runtime engine. Defaults are fine. */ VelocityEngine ve1 = new VelocityEngine(); VelocityEngine ve2 = new VelocityEngine(); try { ve1.setProperty("runtime.log", "velengine1.log"); ve1.setProperty("file.resource.loader.path", "./template1"); ve1.init(); ve2.setProperty("runtime.log", "velengine2.log"); ve2.setProperty("file.resource.loader.path", "./template2"); ve2.init(); } catch(Exception e) { System.out.println("Problem initializing Velocity : " + e ); return; } /* lets make a Context and put data into it */ VelocityContext context = new VelocityContext(); context.put("name", "Velocity"); context.put("project", "Jakarta"); /* lets render a template */ StringWriter w1 = new StringWriter(); StringWriter w2 = new StringWriter(); try { ve1.mergeTemplate("instanceexample.vm", context, w1); ve2.mergeTemplate("instanceexample.vm", context, w2); } catch (Exception e ) { System.out.println("Problem merging template : " + e ); } System.out.println(" template 1 : " + w1 ); System.out.println(" template 2 : " + w2 ); } } velocity-1.7/whiteboard/geir/geir.cmp0000644000175000017500000000074107226774727017632 0ustar moellermoellerBang! : 0 Bang! : 1 Bang! : 2 Bang! : 3 Bang! : 4 Tests the basic arg passing for VMs We want to pass through two VMs ("hello geir") ( geir ) ( 1 ) ( true ) Hello from foo! foo: a foo: b Hello from foo! foo: 1 foo: 2 foo: 3 foo: 4 Hello from foo! foo: 4 foo: 5 foo: 6 foo: 7 foo: 8 foo: 9 foo: 10 This tests the pass-by-name feature >0< bar : 1 floog : 2 bar : 3 floog : 4 velocity-1.7/whiteboard/geir/geir.vm0000644000175000017500000000243510513464370017456 0ustar moellermoeller## 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. Tests the basic arg passing for VMs We want to pass through two VMs #macro( foo $a ) Hello from foo! #foreach($i in $a) foo: $i #end #end #macro( floog $a) floog : $a #end #set($woogie = "geir") #set($x = 4) #set($y = 10) #bar("hello $woogie") #bar( $woogie ) #bar( 1 ) #bar( true ) #foo( ["a","b"] ) #foo( [1..4] ) #foo( [$x..$y] ) This tests the pass-by-name feature #macro( bar $b ) bar : $b #floog( $b ) #end >$provider.bang()< #bar( $provider.bang() ) #bar( $provider.bang() ) velocity-1.7/whiteboard/geir/Local.java0000644000175000017500000000747210513464370020067 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import java.io.Writer; import java.io.IOException; import java.util.ArrayList; /** * Simple implementation of a 'context protector', as desired by * Christoph Reck. Used like * * #local($a $b $c ) * ... * #end * * and restores the value of the reference at the end of the block * Assumes that you can #set() the value of any reference in the list * * @author Geir Magnusson Jr. * @version $Id: Local.java 463298 2006-10-12 16:10:32Z henning $ */ public class Local extends Directive { protected Object[] refList; protected Node block; /** * Return name of this directive. */ public String getName() { return "local"; } /** * Return type of this directive. */ public int getType() { return BLOCK; } /** * */ public void init(RuntimeServices rs, InternalContextAdapter context, Node node) throws Exception { super.init( rs, context, node ); int numchildren = node.jjtGetNumChildren(); ArrayList al = new ArrayList(); /* * get all the references in our arg list */ for (int i=0; i < numchildren-1; i++) { SimpleNode sn = (SimpleNode) node.jjtGetChild(i); if (sn instanceof ASTReference ) { al.add(sn); } else { throw new Exception("Arg " + i + " not a reference."); } } refList = al.toArray(); block = node.jjtGetChild(node.jjtGetNumChildren() - 1); } /** * */ public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException { /* * get the current values for the references we have */ ArrayList vals = new ArrayList(); for (int i = 0; i < refList.length; i++) { Object o = ((ASTReference) refList[i]).value(context); vals.add(o); } /* * now render the block */ boolean retVal = block.render(context, writer); /* * now restore the original values */ for (int i = 0; i < refList.length; i++) { ASTReference astr = (ASTReference) refList[i]; astr.setValue(context, vals.get(i)); } return true; } } velocity-1.7/whiteboard/geir/Delay.java0000644000175000017500000000675310513464370020074 0ustar moellermoellerpackage org.apache.velocity.runtime.directive; /* * 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. */ import java.io.Writer; import java.io.IOException; import java.util.List; import java.util.ArrayList; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.parser.Token; import org.apache.velocity.runtime.parser.node.NodeUtils; /** * * @author Geir Magnusson Jr. */ public class Delay extends Directive { List astStrings = null; public String getName() { return "delay"; } public int getType() { return BLOCK; } public void init( RuntimeServices rs, InternalContextAdapter context, Node node) throws Exception { super.init( rs, context, node ); astStrings = getASTAsStringArray( node.jjtGetChild(1) ); } public boolean render( InternalContextAdapter context, Writer writer, Node node) throws IOException { /* * what is our arg? */ int ival = 0; try { Integer val = (Integer) node.jjtGetChild(0).value(context); ival = val.intValue(); } catch( Exception ee ) {} System.out.println( "value : " + ival ); if ( ival > 1 ) { writer.write("#delay( " + --ival + " )\n " ); for( int i = 0; i < astStrings.size(); i++ ) { writer.write( (String) astStrings.get( i ) ); } writer.write("#end"); } else { for( int i = 0; i < astStrings.size(); i++ ) { writer.write( (String) astStrings.get( i ) ); } } return true; } private static List getASTAsStringArray( Node rootNode ) { /* * this assumes that we are passed in the root * node of the code block */ Token t = rootNode.getFirstToken(); Token tLast = rootNode.getLastToken(); /* * now, run down the part of the tree bounded by * our first and last tokens */ ArrayList list = new ArrayList(); t = rootNode.getFirstToken(); while( t != tLast ) { list.add( NodeUtils.tokenLiteral( t ) ); t = t.next; } /* * make sure we get the last one... */ list.add( NodeUtils.tokenLiteral( t ) ); return list; } } velocity-1.7/whiteboard/henning/0000755000175000017500000000000011675166252016670 5ustar moellermoellervelocity-1.7/whiteboard/henning/using_ivy/0000755000175000017500000000000011675166252020704 5ustar moellermoellervelocity-1.7/whiteboard/henning/using_ivy/ivy.xml0000644000175000017500000000313210513464370022224 0ustar moellermoeller velocity-1.7/whiteboard/henning/using_ivy/lib/0000755000175000017500000000000011675166252021452 5ustar moellermoellervelocity-1.7/whiteboard/henning/using_ivy/lib/LICENSE.ivy0000644000175000017500000000304110402641463023250 0ustar moellermoellerBSD License for Ivy Copyright (c) 2005-2006, JAYASOFT All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of JAYASOFT nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. velocity-1.7/whiteboard/henning/using_ivy/build.properties0000644000175000017500000000606710513464370024122 0ustar moellermoeller# 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. # # This file is used by build.xml and testcases.xml # # Global defaults name= Velocity project= velocity version= 1.5-dev final.name= ${project}-${version} # compile switches debug= on optimize= on deprecation= off # Needs to be configured with system location of javacc for parser task javacc.home= *unset* velocity.build.dir= build build.dir= ${velocity.dir}/bin # The source tree runs through a filter copy task to # allow substitution of version, date etc. and will # end up in build.src build.src= ${build.dir}/src build.lib= ${build.dir}/lib build.test.src= ${build.dir}/test-src build.dest= ${build.dir}/classes build.deps= ${build.dir}/deps build.test.dest= ${build.dir}/test-classes build.javadoc= ${build.dir}/apidocs build.test= ${build.dir}/test build.test.reports= ${build.dir}/test-reports build.docs= ${build.dir}/docs # Various local pathes in the distribution src.java.dir= ${velocity.dir}/src/java src.parser.dir = ${velocity.dir}/src/parser test.java.dir= ${velocity.dir}/src/test test.dir= ${velocity.dir}/test example.dir= ${velocity.dir}/examples xdocs.dir= ${velocity.dir}/xdocs docs.dir= ${velocity.dir}/docs # @TODO Move parser build out of the tree. build.parser= ${src.java.dir}/org/apache/velocity/runtime/parser # Running the tests test.haltonerror= true test.haltonfailure= true # Building the distribution dist.root= ${build.dir}/dist dist.dir= ${dist.root}/${final.name} # Set to "project.xml" for distribution and "project-website.xml" # when building docs for web site docs.project= project.xml # Set to Sun Javadocs javadocs.ref.jsdk= http://java.sun.com/j2se/1.4.2/docs/api/ # ####################################################################### # # Downloading jars from ibiblio repository using the ivy resolver # # ####################################################################### # # Settings for the proxy to use for download. Change this if you must # use a proxy from your host. If the proxy.host property is unset, no # proxy is used. proxy.host= proxy.port= 80 # # Jars to be included in the velocity-dep jar jar.avalon-logkit.version= 2.1 jar.commons-collections.version= 3.1 jar.commons-lang.version= 2.1 jar.oro.version= 2.0.8 # # Where does ivy store its dependencies ivy.lib.dir= ${build.lib} velocity-1.7/whiteboard/henning/using_ivy/README0000644000175000017500000000060510402641463021552 0ustar moellermoellerCopy all files in this directory into the "build" directory of the Velocity tree to use the ivy dependency resolver (http://www.jayasoft.org/ivy/) instead of our self-rolled ibiblio download. Make sure that the ivy jar ends up in build/lib ivy features a local file cache (just like maven), dependency checking and resolving and a lot more stuff. It also has an Apache friendly license. velocity-1.7/whiteboard/henning/using_ivy/build.xml0000644000175000017500000007676610513464370022543 0ustar moellermoeller **************************************************************************** ** ** help is no longer supported. Please run 'ant -projecthelp' ** *************************************************************************** Global settings: java.home = ${java.home} user.home = ${user.home} java.class.path = ${java.class.path} Velocity settings: Version: ${version} Debug: ${debug} Optimize: ${optimize} Deprecation: ${deprecation} Target settings (relative to build tree root): Velocity Source: ${build.src} Velocity Classes: ${build.dest} Velocity API Docs: ${build.javadoc} Velocity Docs: ${build.docs} Velocity Test Reports: ${build.test.reports} ******************************************************** ** ** The javax.sql.Datasource class has not been found on ** your classpath. This means that your newly built ** Velocity jar will not contain the JDBC based resource ** loaders. If this is a problem, please use a JDK for ** building that contains the javax.sql.Datasource class. ** ******************************************************** ******************************************************** ** ** The java.util.logging.Logger class has not been found on your ** classpath. This means that your newly built Velocity jar will ** not contain JDK 1.4 compatible logging code. If this is a ** problem, please use a 1.4 or newer JDK for building. ** ******************************************************** Could not run javacc: *********************************************************** ** You have not configured your JavaCC installation ** location in the javacc.home property. *********************************************************** Could not run javacc: *********************************************************** ** ** JavaCC 3.1 or later must be installed at ${javacc.home}. ** Ant must be at least version 1.6.x. ** *********************************************************** *********************************************************** ** Creating Parser.jj and Parser.java in source tree. ** ** Note: ASTNode files generated by jjtree are ** not generated with this task. To create new ASTNode files, ** run jjtree manually then copy the relevant files into ** the runtime/parser/node directory (deleting all other ** generated files). ** *********************************************************** ************************************************************** ** Building the examples : ** examples/appexample1 : application example ** examples/appexample2 : application example ** examples/context_example : example context implementations ** examples/logger_example : how to make an external logger ** examples/xmlapp_example : how to access XML data in a template ** examples/event_example : how to use Velocity's event handlers ************************************************************** ####################################################### # # Now using Anakia to transform the XML documentation # to HTML. # # using project file: ${docs.project} # # Note: set property "docs.project" to "project.xml" # for distribution and "project-website.xml" for # website. ####################################################### velocity-1.7/whiteboard/henning/jdk14/0000755000175000017500000000000011675166252017605 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk14/EscapeReference.java0000644000175000017500000001167610513464370023472 0ustar moellermoellerpackage org.apache.velocity.app.event.implement; /* * 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. */ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.velocity.app.event.ReferenceInsertionEventHandler; import org.apache.velocity.app.event.RuntimeServicesAware; import org.apache.velocity.runtime.RuntimeServices; /** * Base class for escaping references. To use it, override the following methods: *
      *
      String escape(String text)
      *
      escape the provided text
      *
      String getMatchAttribute()
      *
      retrieve the configuration attribute used to match references (see below)
      *
      * *

      By default, all references are escaped. However, by setting the match attribute * in the configuration file to a regular expression, users can specify which references * to escape. For example the following configuration property tells the EscapeSqlReference * event handler to only escape references that start with "sql". * (e.g. $sql, $sql.toString(),, etc). * *

       * eventhandler.escape.sql.match = /sql.*/
       * 
       * 
      * * * Regular expressions should follow the "regex5" format used by the java.util.regex package * * @author Will Glass-Husain * @version $Id: EscapeReference.java 463298 2006-10-12 16:10:32Z henning $ */ public abstract class EscapeReference implements ReferenceInsertionEventHandler,RuntimeServicesAware { private RuntimeServices rs; private String matchRegExp = null; private Pattern pattern = null; /** * Escape the given text. Override this in a subclass to do the actual * escaping. * * @param text the text to escape * @return the escaped text */ protected abstract String escape(Object text); /** * Specify the configuration attribute that specifies the * regular expression. Ideally should be in a form *
      eventhandler.escape.XYZ.match
      * *

      where XYZ is the type of escaping being done. * @return configuration attribute */ protected abstract String getMatchAttribute(); /** * Escape the provided text if it matches the configured regular expression. */ public Object referenceInsert(String reference, Object value) { if(value == null) { return value; } if (pattern == null) { return escape(value); } else if (pattern.matcher(reference).find()) { return escape(value); } else { return value; } } /** * Called automatically when event cartridge is initialized. */ public void setRuntimeServices(RuntimeServices rs) throws Exception { this.rs = rs; /** * Get the regular expression pattern. */ matchRegExp = rs.getConfiguration().getString(getMatchAttribute()); if (matchRegExp != null) { matchRegExp = matchRegExp.trim(); if (matchRegExp.startsWith("/") && matchRegExp.endsWith("/")) { matchRegExp = matchRegExp.substring(1, matchRegExp.length() - 1); } if (matchRegExp.length() == 0) { matchRegExp = null; } } /** * Test the regular expression for a well formed pattern */ if (matchRegExp != null) { try { pattern = Pattern.compile(matchRegExp); } catch (PatternSyntaxException pse) { rs.getLog().error("Invalid regular expression '" + matchRegExp + "'. No escaping will be performed."); } } } /** * Retrieve a reference to RuntimeServices. Use this for checking additional * configuration properties. * @return */ protected RuntimeServices getRuntimeServices() { return rs; } } velocity-1.7/whiteboard/henning/jdk14/README0000644000175000017500000000024710331173441020452 0ustar moellermoellerThis is an alternative implementation of EscapeReference intended for JDK 1.4 which allows us to drop oro from the runtime dependencies once we move to JDK 1.4+ only. velocity-1.7/whiteboard/henning/jdk15/0000755000175000017500000000000011675166253017607 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/0000755000175000017500000000000011675166253020376 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/0000755000175000017500000000000011675166252021354 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/org/0000755000175000017500000000000011675166252022143 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/0000755000175000017500000000000011675166252023364 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/velocity/0000755000175000017500000000000011675166252025222 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/velocity/util/0000755000175000017500000000000011675166252026177 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/velocity/util/introspection/0000755000175000017500000000000011675166253031100 5ustar moellermoeller././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootvelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/velocity/util/introspection/JDK15UberspectTestCase.javavelocity-1.7/whiteboard/henning/jdk15/src/test/org/apache/velocity/util/introspection/JDK15Uberspect0000644000175000017500000000506510513464370033453 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; import java.util.Properties; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeSingleton; public class JDK15UberspectTestCase extends TestCase { public JDK15UberspectTestCase(final String name) { super(name); } public void setUp() throws Exception { Properties p = new Properties(); p.put(RuntimeConstants.UBERSPECT_CLASSNAME, JDK15UberspectImpl.class.getName()); RuntimeSingleton.init(p); } public static Test suite() { return new TestSuite(JDK15UberspectTestCase.class); } public void testIterable() throws Exception { TestIterator itobj = new TestIterator(); TestIterable io = new TestIterable(itobj); Uberspect u = RuntimeSingleton.getUberspect(); assertEquals("Wrong Uberspector configured!", JDK15UberspectImpl.class, u.getClass()); Iterator it = u.getIterator(io, null); assertNotNull("The introspector did not return an iterator!", it); assertEquals("The introspector did return a wrong iterator!", itobj, it); } public static class TestIterator implements Iterator { public boolean hasNext() { return false; } public Object next() { return null; } public void remove() { } } public static class TestIterable implements Iterable { private final Iterator it; public TestIterable(final Iterator it) { this.it = it; } public Iterator iterator() { return it; } } } velocity-1.7/whiteboard/henning/jdk15/src/java/0000755000175000017500000000000011675166253021317 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/java/org/0000755000175000017500000000000011675166253022106 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/0000755000175000017500000000000011675166253023327 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/velocity/0000755000175000017500000000000011675166253025165 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/velocity/util/0000755000175000017500000000000011675166253026142 5ustar moellermoellervelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/velocity/util/introspection/0000755000175000017500000000000011675166253031042 5ustar moellermoeller././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootvelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/velocity/util/introspection/JDK15UberspectImpl.javavelocity-1.7/whiteboard/henning/jdk15/src/java/org/apache/velocity/util/introspection/JDK15Uberspect0000644000175000017500000000326010513464370033410 0ustar moellermoellerpackage org.apache.velocity.util.introspection; /* * 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. */ import java.util.Iterator; /** * JDK 1.5 extension of the Uberspector that allows Iterable Objects to be * put into the Context to be used with #foreach * * @author Henning P. Schmiedehausen * @version $Id: JDK15UberspectImpl.java 463298 2006-10-12 16:10:32Z henning $ */ public class JDK15UberspectImpl extends UberspectImpl { /** * To support iterative objects used in a #foreach() * loop. * * @param obj The iterative object. * @param i Info about the object's location. */ public Iterator getIterator(Object obj, Info i) throws Exception { if (obj instanceof Iterable) { return ((Iterable) obj).iterator(); } else { return super.getIterator(obj, i); } } } velocity-1.7/whiteboard/henning/jdk15/README0000644000175000017500000000046410450525347020464 0ustar moellermoellerThis is an Uberspect Implementation (with test) that only compiles under JDK 1.5 but allows Objects that implement Iterable to be used in #foreach() Use it by adding the following line to your velocity.properties: runtime.introspector.uberspect = org.apache.velocity.util.introspection.JDK15UberspectImpl velocity-1.7/pom.xml0000644000175000017500000002515111470267434014430 0ustar moellermoeller 4.0.0 org.apache apache 4 org.apache.velocity velocity 1.7 Apache Velocity http://velocity.apache.org/engine/devel/ Apache Velocity is a general purpose template engine. 2000 jar 2.0.9 install src/java src/test org.apache.maven.plugins maven-site-plugin UTF-8 UTF-8 ${basedir}/xdocs/docs src/java **/*.java velocity.apache.org scpexe://people.apache.org/www/velocity.apache.org/engine/releases/velocity-1.7 apache.releases Apache Release Distribution Repository scp://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository apache.snapshots Apache Development Snapshot Repository scp://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository Will Glass-Husain wglass wglass@forio.com Forio Business Simulations Java Developer Geir Magnusson Jr. geirm geirm@optonline.net Independent (DVSL Maven) Java Developer Daniel Rall dlr dlr@finemaltcoding.com CollabNet, Inc. Java Developer Henning P. Schmiedehausen henning hps@intermeta.de INTERMETA - Gesellschaft für Mehrwertdienste mbH Java Developer 2 Nathan Bubna nbubna nathan@esha.com ESHA Research Java Developer commons-collections commons-collections 3.2.1 commons-lang commons-lang 2.4 oro oro 2.0.8 true jdom jdom 1.0 provided commons-logging commons-logging 1.1 provided avalon-framework avalon-framework log4j log4j javax.servlet servlet-api log4j log4j 1.2.12 provided javax.servlet servlet-api 2.3 provided logkit logkit 2.0 provided ant ant 1.6 provided werken-xpath werken-xpath 0.9.4 provided junit junit 3.8.1 test hsqldb hsqldb 1.7.1 test org.apache.maven.plugins maven-project-info-reports-plugin 2.1 dependencies issue-tracking license summary scm org.apache.maven.plugins maven-changes-plugin 2.0 changes-report jira-report ${jira.browse.url}/%ISSUE% 12311337 fixfor=12310290&sorter/field=issuekey&sorter/order=ASC 100 http://velocity.apache.org/who-we-are.html org.codehaus.mojo taglist-maven-plugin 2.2 TODO FIXME org.apache.maven.plugins maven-jxr-plugin 2.1 org.apache.maven.plugins maven-javadoc-plugin 2.5 http://java.sun.com/j2se/1.4.2/docs/api http://jakarta.apache.org/oro/api http://jakarta.apache.org/commons/lang/api-release http://jakarta.apache.org/commons/collections/api-release http://www.jdom.org/docs/apidocs http://logging.apache.org/log4j/docs/api http://excalibur.apache.org/apidocs http://tomcat.apache.org/tomcat-4.1-doc/servletapi org.apache.maven.plugins maven-changelog-plugin 2.1 org.codehaus.mojo findbugs-maven-plugin 1.2 true Low Max build/findbugs-exclude.xml xdocs org.apache.maven.plugins maven-compiler-plugin 1.4 1.4 scm:svn:http://svn.apache.org/repos/asf/velocity/engine/trunk scm:svn:https://svn.apache.org/repos/asf/velocity/engine/trunk HEAD http://svn.apache.org/viewvc/velocity/engine/trunk https://issues.apache.org/jira/browse JIRA ${jira.browse.url}/VELOCITY velocity-1.7/README.txt0000644000175000017500000001266311355211500014576 0ustar moellermoeller--------------- Apache Velocity --------------- Welcome to Apache Velocity! Apache Velocity is a general purpose template engine written in Java. For more information about Velocity, please look at the HTML documentation in the docs/ directory, as well as the Velocity web site. http://velocity.apache.org/index.html The following top level directories are in the Velocity distribution archive. Please consult the documentation in each of the lower level directories for information that is specific to their contents. build/ This is where the build scripts live. convert/ The WebMacro to Apache Velocity conversion program. docs/ Velocity Documentation in HTML format. docs/api/ Velocity Javadocs. examples/ Examples how to use Velocity. lib/ Dependencies for building and using Velocity. lib/test/ Dependencies needed for the various unit tests. src/ This is where all of the source code is located. test/ Contains test files needed for the unit tests. xdocs/ Here are the .xml files for building the .html files related to the website and documentation. The files located in docs/ have been built from these sources. Caveat! This is the directory structure of the distribution archive. If you checked out the source from the Apache Subversion Repository, the directory layout is slightly different. REQUIREMENTS ------------ Apache Velocity will run with any version of Java greater than 1.3. Building from source requires Java version 1.4 (or greater) and ant 1.6 or greater. INCLUDED PRE-BUILT JARS ----------------------- If you are using an offical Apache Velocity release distribution, you will find two pre-built jars in the top level directory. 1) velocity-.jar: This jar does not include any external dependencies needed by Velocity, such as the commons-collection classes, the Avalon Logkit, or Apache Jakarta ORO. We do this to allow you to use whatever version of collections, logkit, etc that you wish w/o fear of collision. These jars are included in the distribution, in the build/lib directory, or at the respective project sites. 2) velocity-dep-.jar: This jar includes all dependencies that were present in previous distribution jars. It is intended as a convenience to allow you to drop this distribution in place of existing 1.1 or 1.2-dep distributions. Please see the WHY_TWO_JARS.txt file for more information. UPGRADING FROM EARLIER RELEASES ------------------------------- Release with the same major number (1.x) are intended to be drop-in replacements. However, in most cases the versions of dependency jars must be adjusted because newer versions of Velocity might require updates. Upgrading from Velocity 1.4 or earlier * JDOM has been upgraded to version 1.0. * Commons Collections has been upgraded to version 3.1. * Commons Lang 2.1 has been added. Optional: * Apache Ant 1.6 or better is required for rebuilding. * Java CC 3.2 is recommended to compile the parser files. * HSQLDB 1.7.1 is required for running unit tests. Upgrading from Velocity 1.5 * Commons Collections has been upgraded to version 3.2.1. * Commons Lang has been upgraded to version 2.4. * Commons Logging 1.1 has been added. Optional: * Maven Ant 2.0.9 is required for the Maven Ant tasks. * Java CC 4.1 is recommended to compile the parser files. Upgrading from Velocity 1.6 Optional: * SpringSource Bundlor 1.0 is required for building releases BUILDING APACHE VELOCITY ------------------------ In order to use the latest version of Apache Velocity, you may want to build it. Building is easy. All components necessary to build are included or get downloaded from the internet during the build, except for the Java 2 SDK and the Ant build tool. You can find details on how to build Velocity online at: http://velocity.apache.org/engine/devel/build.html Note that you must use Ant version 1.7 or later. *IMPORTANT* As the Apache Velocity build process wants to download a number of jars from the internet, you must be online when you are building for the first time. To build Velocity's jar, change directory into the build/ directory and enter: ant jar This will create a bin/ directory containing the Velocity .jar file. Be sure to update your classpath to include Velocity's .jar file, or when using a modern servlet container, put it in the WEB-INF/lib directory. If you wish to build a jar that contains all dependencies, we have provided an optional build target for your convenience: ant jar-dep This will build a complete Velocity jar with dependencies included, and it can be found in the /bin directory as velocity-dep-.jar KNOWN ISSUES AND LIMITATIONS ---------------------------- When running findbugs on a project, the default heap size might not be enough to complete the build. For now there is no way to fork findbugs and run with its own memory requirements, but the following system variable will allow you to do so when running it via Maven: export MAVEN_OPTS=-Xmx384M TRYING THE EXAMPLES ------------------- After building Velocity, you can also buld the examples that are included with the Velocity distribution. These examples show how to use Velocity in your Java applications. There also are examples of how to use Anakia, a XML transformation engine. For more information, please see the README.txt in the examples/ directory. - The Apache Velocity Team velocity-1.7/CONTRIBUTORS0000644000175000017500000000163111140340352014751 0ustar moellermoellerThis project is an effort by many people. If you feel that your name should be in here and has been omitted in error, please open an issue with the Apache Velocity Issue tracker located at https://issues.apache.org/jira/browse/VELOCITY Adrian Tarau Aki Nieminen Alexey Pachenko Anil K. Vijendran Attila Szegedi Bob McWhirter Byron Foster Christoph Reck Claude Brisson Daniel Rall Dave Bryson David Kinnvall Eelco Hillenius Fedor Karpelevitch Gal Shachor Geir Magnusson Jr. Henning P. Schmiedehausen Jarkko Viinamäki Jason van Zyl Jeff Bowden Jon S. Stevens Jose Alberto Fernandez Kasper Nielsen Kent Johnson Kyle F. Downey Leon Messerschmidt Llewellyn Falco Matt Raible Matthijs Lambooy Nathan Bubna Paulo Gaspar Peter Romianowski Robert Burrell Donkin Sam Ruby Sean Legassick Serge Knystautas Stephane Bailliez Stephen Habermann Sylwester Lachiewicz Will Glass-Husain velocity-1.7/WHY_TWO_JARS.txt0000644000175000017500000000511511110356751015661 0ustar moellermoellerWHY ARE THERE TWO JARS? WHAT'S THE DIFFERENCE? =============================================== We are including two jars with the Velocity distribution. This document describes the differences and what they are intended for. Both jars are included in the root directory of the Velocity distribution. CAVEAT: Up and including the 1.4 release of Velocity, there was a wealth of different jars including J2EE code, containing just the runtime or the tools. This lead to some confusion about the naming and the purpose of the various jars. Starting with the 1.5 release of Velocity, there is now one jar, velocity-.jar, which contains all Velocity code and a second jar, velocity-dep-.jar, which contains all Velocity code and its external dependencies. velocity-.jar ---------------------- This jar contains only the velocity specific code in the org.apache.velocity.* packages. If you want to integrate Velocity in your own code or a larger project, we recommend that you use this jar. It has some external dependencies which are listed in the developer docs. Make sure that you have these dependencies present in your application. Please see the developers guide for more information. velocity-dep-.jar -------------------------- This jar is intended to be used when you do standalone development with Velocity. It contains all of the Velocity engine code (runtime, anakia, texen and their respective ant tasks) and also all external dependencies from other jars, repackaged into a single jar. Currently that is: oro org.apache.oro.* packages, from http://jakarta.apache.org/oro/ commons-lang org.apache.commons.lang.* packages, from http://jakarta.apache.org/commons/lang/ Avalon Logkit org.apache.log.* packages and a subset of commons-collections org.apache.commons.collections.* packages from http://jakarta.apache.org/commons/collections/ These classes are strictly intended for Velocity use! If you want to use the velocity-dep jar, do not rely on any of the other classes being present. We reserve the right to change the supporting classes (those not in the org.apache.velocity.* packages) at any time for any release. When using this jar without anything else, you are also restricted to using the Avalon Logkit for logging (or JDK 1.4 logging if you run under JDK 1.4 or newer). This jar should only be used for the Velocity runtime. The various tools (Anakia, Texen, Webmacro converter) have additional dependencies that are not inside this jar! velocity-1.7/experimental/0000755000175000017500000000000011675166253015610 5ustar moellermoellervelocity-1.7/experimental/localdirective/0000755000175000017500000000000011675166253020601 5ustar moellermoellervelocity-1.7/experimental/localdirective/foo.vm0000644000175000017500000000166610513464370021730 0ustar moellermoeller## 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. #set($foo = 1) $foo #local( $foo) $foo #set($foo = 2) $foo #local($foo) #set($foo = 5) $foo #end $foo #end $foo velocity-1.7/experimental/localdirective/LocalDirective.java0000644000175000017500000000672510513464370024336 0ustar moellermoeller/* * 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. */ import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.runtime.parser.node.Node; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.parser.ParserTreeConstants; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.runtime.parser.node.ASTReference; import java.io.Writer; import java.io.IOException; import java.util.Map; import java.util.HashMap; import java.util.Iterator; /** * Simple directive to provide ability to trap a local value for * iteration. * * Ex : * * #set($foo = 1) * $foo * #local($foo) * #set($foo = 2) * $foo * #end * $foo * * should output * * 1 * 2 * 1 * * @version $Id: LocalDirective.java 463298 2006-10-12 16:10:32Z henning $ */ public class LocalDirective extends Directive { public String getName() { return "local"; } public int getType() { return BLOCK; } public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, MethodInvocationException, ResourceNotFoundException, ParseErrorException { Map data = new HashMap(); int num = node.jjtGetNumChildren(); /* * get the references */ for (int i=0; i < num; i++) { SimpleNode child = (SimpleNode) node.jjtGetChild(i); /* * if a block, just execute */ if (child.getType() == ParserTreeConstants.JJTBLOCK) { child.render(context, writer); break; } else { /* save the values - for now, just w/ ref to test */ if (child.getType() == ParserTreeConstants.JJTREFERENCE) { data.put(child, child.execute(null, context)); } else { System.out.println("unhandled type"); } } } Iterator it = data.keySet().iterator(); while(it.hasNext()) { ASTReference ref = (ASTReference) it.next(); ref.setValue(context, data.get(ref)); } return true; } } velocity-1.7/experimental/localdirective/recurse.vm0000644000175000017500000000212210513464370022601 0ustar moellermoeller## 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. #macro(foo $value) $value #if ($value > 0) #set($value = $value - 1) #foo($value) #end $value #end #macro(foofoo $value) $value #local($value) #if ($value > 0) #set($value = $value - 1) #foofoo($value) #end #end $value #end #foo(5) #foofoo(5) velocity-1.7/experimental/localdirective/velocity.properties0000644000175000017500000000146210513464370024547 0ustar moellermoeller# 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. userdirective=LocalDirective velocity-1.7/experimental/localdirective/readme.txt0000644000175000017500000000036007745555412022600 0ustar moellermoellerThis is an implementation of a #local() directive. Use : #local($arg $arg1...) #end and the values for $arg etc will be 'protected' - the will be the same after the block as before. Currently this is limited to references $ velocity-1.7/experimental/templatetool/0000755000175000017500000000000011675166253020321 5ustar moellermoellervelocity-1.7/experimental/templatetool/TemplateTool.java0000644000175000017500000001005210513464370023562 0ustar moellermoeller/* * 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. */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Iterator; import org.apache.velocity.Template; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.parser.node.SimpleNode; import org.apache.velocity.runtime.parser.node.ASTReference; import org.apache.velocity.runtime.visitor.BaseVisitor; /** * * @author Geir Magnusson Jr. * @version $Id: TemplateTool.java 463298 2006-10-12 16:10:32Z henning $ */ public class TemplateTool { /** * returns a list of references in a template in the * order that they are encountered */ public static List referenceList( Template template ) { SimpleNode sn = (SimpleNode) template.getData(); ReferenceListVisitor rlv = new ReferenceListVisitor(); sn.jjtAccept( rlv, null ); return rlv.getList(); } /** * returns a map of references as keys, and number of times * they are used in the template. There is no order * information */ public static Map referenceHistogram( Template template ) { /* * get the list */ List list = referenceList( template ); HashMap hm = new HashMap(); int count = 0; for( int i = 0; i < list.size(); i++) { String ref = (String) list.get(i); Integer ival = (Integer) hm.get( ref ); if ( ival == null) count = 0; else count = ival.intValue(); count++; hm.put( ref, new Integer(count) ); } return hm; } public static void main( String args[] ) throws Exception { if (args.length < 1) { System.out.println("Need template arg..."); return; } VelocityEngine ve = new VelocityEngine(); ve.init(); Template t = ve.getTemplate( args[0] ); List l = TemplateTool.referenceList( t ); System.out.println("References, in order :"); System.out.println("======================"); for( int i = 0; i < l.size(); i++) { System.out.println(" " + l.get(i)); } Map m = TemplateTool.referenceHistogram( t ); System.out.println("References, with Frequency Count :"); System.out.println("=================================="); for( Iterator iter = m.keySet().iterator() ; iter.hasNext(); ) { String key = (String) iter.next(); System.out.println(" " + key + " : " + m.get( key ) ); } } /** * Visitor to accumulate references. */ static class ReferenceListVisitor extends BaseVisitor { List list = null; ReferenceListVisitor() { list = new ArrayList(); } public List getList() { return list; } public Object visit( ASTReference node, Object data) { String lit = node.literal(); list.add(lit); /* * feed the children... */ data = node.childrenAccept(this, data); return data; } } } velocity-1.7/experimental/templatetool/README.txt0000644000175000017500000000133107400712131021774 0ustar moellermoellerTemplateTool This is the start of a little tool for debug-ish / validation-ish template activities. Currently, it is able to return a list of the references used in a template, as well as a frequency map of those references. To test, simply compile (need Velocity jar, of course), and then $ java TemplateTool