You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by wg...@apache.org on 2007/08/22 18:31:34 UTC
svn commit: r568691 [1/2] - in /velocity/engine/trunk:
src/java/org/apache/velocity/ src/java/org/apache/velocity/context/
src/java/org/apache/velocity/runtime/directive/
src/java/org/apache/velocity/runtime/parser/
src/java/org/apache/velocity/runtime...
Author: wglass
Date: Wed Aug 22 09:31:31 2007
New Revision: 568691
URL: http://svn.apache.org/viewvc?rev=568691&view=rev
Log:
refactoring of macro parsing to allow macros to be parsed at run time. addresses combination of #parse and macro calls from VELOCITY-362, VELOCITY-277, VELOCITY-146. Also adds new feature -- developers can specify macro libraries to be included at merge time with new overloaded mergeTemplate method call. (VELOCITY-529).
Added:
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java (with props)
velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java (with props)
velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java (with props)
velocity/engine/trunk/test/macrolibs/
velocity/engine/trunk/test/macrolibs/compare/
velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp (with props)
velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp (with props)
velocity/engine/trunk/test/macrolibs/compare/vm_library_local.cmp (with props)
velocity/engine/trunk/test/macrolibs/vm_library.vm (with props)
velocity/engine/trunk/test/macrolibs/vm_library1.vm (with props)
velocity/engine/trunk/test/macrolibs/vm_library2.vm (with props)
velocity/engine/trunk/test/macrolibs/vm_library_global.vm (with props)
velocity/engine/trunk/test/macrolibs/vm_library_local.vm (with props)
velocity/engine/trunk/test/parsemacros/
velocity/engine/trunk/test/parsemacros/compare/
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_1.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_1b.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_2.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_2b.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_3.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_3b.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_4.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro1_4b.cmp (with props)
velocity/engine/trunk/test/parsemacros/compare/parseMacro2.cmp (with props)
velocity/engine/trunk/test/parsemacros/parseMacro1.vm (with props)
velocity/engine/trunk/test/parsemacros/parseMacro2.vm (with props)
velocity/engine/trunk/test/parsemacros/vm_library1.vm (with props)
velocity/engine/trunk/test/parsemacros/vm_library2.vm (with props)
Modified:
velocity/engine/trunk/src/java/org/apache/velocity/Template.java
velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java
velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java
velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Parse.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj
velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
velocity/engine/trunk/src/parser/Parser.jjt
velocity/engine/trunk/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java
velocity/engine/trunk/test/macroforwarddefine/compare/velocity.log.cmp
Modified: velocity/engine/trunk/src/java/org/apache/velocity/Template.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/Template.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/Template.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/Template.java Wed Aug 22 09:31:31 2007
@@ -25,6 +25,7 @@
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;
@@ -228,6 +229,27 @@
public void merge( Context context, Writer writer)
throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, IOException
{
+ 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.
+ * @throws IOException Might be thrown while rendering.
+ */
+ public void merge( Context context, Writer writer, List macroLibraries)
+ throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, IOException
+ {
/*
* we shouldn't have to do this, as if there is an error condition,
* the application code should never get a reference to the
@@ -248,6 +270,52 @@
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);
+ }
+ }
+ }
+
try
{
ica.pushCurrentTemplateName( name );
@@ -278,5 +346,6 @@
}
}
}
+
Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/EvaluateContext.java Wed Aug 22 09:31:31 2007
@@ -21,6 +21,7 @@
import java.util.HashSet;
import java.util.Set;
+import java.util.List;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.event.EventCartridge;
@@ -287,6 +288,22 @@
}
/**
+ * @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 )
@@ -320,6 +337,7 @@
return innerContext.getCurrentResource();
}
}
+
Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextAdapterImpl.java Wed Aug 22 09:31:31 2007
@@ -23,6 +23,8 @@
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
@@ -192,6 +194,21 @@
icb.setAllowRendering(v);
}
+ /**
+ * @see org.apache.velocity.context.InternalHousekeepingContext#setMacroLibraries(List)
+ */
+ public void setMacroLibraries(List macroLibraries)
+ {
+ icb.setMacroLibraries(macroLibraries);
+ }
+
+ /**
+ * @see org.apache.velocity.context.InternalHousekeepingContext#getMacroLibraries()
+ */
+ public List getMacroLibraries()
+ {
+ return icb.getMacroLibraries();
+ }
/* --- Context interface methods --- */
@@ -202,13 +219,13 @@
{
return context.put( key , value );
}
-
+
/**
* @see InternalWrapperContext#localPut(String, Object)
*/
public Object localPut(final String key, final Object value)
{
- return put(key, value);
+ return put(key, value);
}
/**
@@ -296,5 +313,6 @@
return null;
}
}
+
Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalContextBase.java Wed Aug 22 09:31:31 2007
@@ -21,6 +21,7 @@
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;
@@ -75,6 +76,12 @@
private boolean allowRendering = true;
/**
+ * 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
@@ -172,6 +179,22 @@
allowRendering = v;
}
+ /**
+ * @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)
@@ -193,4 +216,5 @@
return eventCartridge;
}
}
+
Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/InternalHousekeepingContext.java Wed Aug 22 09:31:31 2007
@@ -23,6 +23,8 @@
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
@@ -111,5 +113,19 @@
* @param v
*/
void setAllowRendering(boolean v);
+
+ /**
+ * 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();
}
Modified: velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/context/VMContext.java Wed Aug 22 09:31:31 2007
@@ -20,6 +20,7 @@
*/
import java.util.HashMap;
+import java.util.List;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.RuntimeConstants;
@@ -326,6 +327,22 @@
}
/**
+ * @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 )
@@ -359,6 +376,7 @@
return innerContext.getCurrentResource();
}
}
+
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Foreach.java Wed Aug 22 09:31:31 2007
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
+import java.util.List;
import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.context.Context;
@@ -254,6 +255,22 @@
public void setAllowRendering(boolean v)
{
innerContext.setAllowRendering(v);
+ }
+
+ /**
+ * @see org.apache.velocity.context.InternalContextAdapter#setMacroLibraries(List)
+ */
+ public void setMacroLibraries(List macroLibraries)
+ {
+ innerContext.setMacroLibraries(macroLibraries);
+ }
+
+ /**
+ * @see org.apache.velocity.context.InternalContextAdapter#getMacroLibraries()
+ */
+ public List getMacroLibraries()
+ {
+ return innerContext.getMacroLibraries();
}
}
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Parse.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Parse.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Parse.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/Parse.java Wed Aug 22 09:31:31 2007
@@ -21,6 +21,8 @@
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;
@@ -214,6 +216,23 @@
return false;
}
+ /**
+ * 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
*/
@@ -224,7 +243,7 @@
((SimpleNode) t.getData()).render( context, writer );
}
}
-
+
/*
* if it's a MIE, it came from the render.... throw it...
*/
Added: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java?rev=568691&view=auto
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java (added)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java Wed Aug 22 09:31:31 2007
@@ -0,0 +1,236 @@
+package 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.parser.node.Node;
+import org.apache.velocity.runtime.parser.Token;
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.TemplateInitException;
+import org.apache.velocity.util.introspection.Info;
+
+import java.io.Writer;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 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. Ifn a implementation cannot be
+ * found the literal text is rendered.
+ */
+
+public class RuntimeMacro extends Directive
+{
+ /**
+ * Name of the macro
+ */
+ private String macroName = "";
+
+ /**
+ * source template name
+ */
+ private String sourceTemplate = "";
+
+ /**
+ * Internal context adapter of macro caller.
+ */
+ private InternalContextAdapter context = null;
+
+ /**
+ * Literal text of the macro
+ */
+ private String literal = "";
+
+ /**
+ * Node of the macro call
+ */
+ private Node node = null;
+
+ /**
+ * Create a RuntimeMacro instance. Macro name and source
+ * template stored for later use.
+ *
+ * @param macroName name of the macro
+ * @param sourceTemplate template where macro call is made
+ */
+ public RuntimeMacro(String macroName, String sourceTemplate)
+ {
+ if (macroName == null || sourceTemplate == null)
+ {
+ throw new IllegalArgumentException("Null arguments");
+ }
+
+ this.macroName = macroName;
+ this.sourceTemplate = sourceTemplate;
+ }
+
+ /**
+ * 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;
+ }
+
+
+ /**
+ * Intialize the Runtime macro. At the init time no implementation so we
+ * just save the values to use at the rende time.
+ *
+ * @param rs runtime services
+ * @param context InternalContexAdapter
+ * @param node node conating the macro call
+ */
+ public void init(RuntimeServices rs, InternalContextAdapter context,
+ Node node)
+ {
+ super.init(rs, context, node);
+ rsvc = rs;
+ this.context = context;
+ this.node = node;
+
+ StringBuffer buffer = new StringBuffer();
+ Token t = node.getFirstToken();
+
+ /**
+ * Retrieve the literal text
+ */
+ while (t != null && t != node.getLastToken())
+ {
+ buffer.append(t.image);
+ t = t.next;
+ }
+
+ if (t != null)
+ {
+ buffer.append(t.image);
+ }
+ /**
+ * Store the literal text
+ */
+ literal = buffer.toString();
+ }
+
+ /**
+ * 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 successfull
+ * @throws IOException
+ * @throws ResourceNotFoundException
+ * @throws ParseErrorException
+ * @throws MethodInvocationException
+ */
+ public boolean render(InternalContextAdapter context, Writer writer,
+ Node node)
+ throws IOException, ResourceNotFoundException,
+ ParseErrorException, MethodInvocationException
+ {
+ VelocimacroProxy vmProxy = null;
+
+ /**
+ * first look in the source template
+ */
+ Object o = rsvc.getVelocimacro(macroName,
+ sourceTemplate);
+ if (o != null && o instanceof VelocimacroProxy)
+ {
+ vmProxy = (VelocimacroProxy)o;
+ }
+
+ /**
+ * if not found, look in the macro libraries.
+ */
+ if (vmProxy == null)
+ {
+ List macroLibraries = context.getMacroLibraries();
+ if (macroLibraries != null)
+ {
+ for (int i = 0; i < macroLibraries.size(); i++)
+ {
+ o = rsvc.getVelocimacro(macroName,
+ (String)macroLibraries.get(i));
+
+ /**
+ * Get the first matching macro
+ */
+ if (o != null && o instanceof VelocimacroProxy)
+ {
+ vmProxy = (VelocimacroProxy) o;
+ break;
+ }
+ }
+ }
+ }
+
+ if (vmProxy != null)
+ {
+ /**
+ * initialize the macro if necessary
+ */
+ try
+ {
+ vmProxy.init(rsvc, this.context, this.node);
+ }
+ catch (TemplateInitException die)
+ {
+ Info info = new Info( sourceTemplate, node.getLine(), node.getColumn() );
+
+ throw new ParseErrorException(die.getMessage(), info);
+ }
+ /**
+ * render it
+ */
+ return vmProxy.render(context, writer, node);
+ }
+
+ /**
+ * If we cannot find an implementation write the literal text
+ */
+ writer.write(literal);
+ return true;
+ }
+}
Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/src/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.java Wed Aug 22 09:31:31 2007
@@ -210,6 +210,51 @@
return ( strImage );
}
+ /**
+ * Check whether their is a left parenthesis with leading optional
+ * whitespaces. This method is used in the semantic look ahead of
+ * Directive method. It requires lot of changes to implement the
+ * required look ahead as a BNF production and the code will become
+ * inefficient.
+ */
+ private boolean isLeftParantheses()
+ {
+ 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
@@ -671,14 +716,6 @@
isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
- if (!isVM)
- {
- token_source.stateStackPop();
- token_source.inDirective = false;
- {if (true) return jjtn000;}
- }
-
-
/*
* Currently, all VMs are LINE directives
*/
@@ -697,47 +734,48 @@
token_source.SwitchTo(DIRECTIVE);
argPos = 0;
- 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;
- }
+ if (isLeftParantheses()) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
jj_consume_token(WHITESPACE);
break;
default:
- jj_la1[9] = jj_gen;
+ jj_la1[8] = jj_gen;
;
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
+ 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[10] = jj_gen;
+ jj_la1[9] = jj_gen;
;
}
- break;
- default:
- jj_la1[11] = jj_gen;
- ;
- }
- argType = DirectiveArg();
+ 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)
@@ -771,20 +809,28 @@
}
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);
+ }
+ 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 {
+ /**
+ * 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);
@@ -2531,349 +2577,321 @@
finally { jj_save(11, xla); }
}
- final private boolean jj_3R_82() {
- if (jj_scan_token(COMMA)) return true;
- if (jj_3R_25()) return true;
- return false;
- }
-
- final private boolean jj_3_8() {
- if (jj_3R_29()) return true;
+ final private boolean jj_3R_52() {
+ if (jj_3R_65()) return true;
return false;
}
- final private boolean jj_3R_26() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_31() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3_11()) {
+ jj_scanpos = xsp;
+ if (jj_3R_58()) return true;
+ }
return false;
}
- final private boolean jj_3R_66() {
- if (jj_scan_token(FALSE)) return true;
+ final private boolean jj_3_11() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ if (jj_scan_token(LOGICAL_NOT)) return true;
+ if (jj_3R_31()) return true;
return false;
}
- final private boolean jj_3R_65() {
- if (jj_scan_token(TRUE)) return true;
+ final private boolean jj_3R_58() {
+ if (jj_3R_67()) return true;
return false;
}
- final 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_30()) return true;
- }
+ final private boolean jj_3R_51() {
+ if (jj_3R_64()) return true;
return false;
}
- final private boolean jj_3R_57() {
+ final private boolean jj_3R_85() {
+ if (jj_scan_token(COMMA)) return true;
+ if (jj_3R_25()) return true;
+ if (jj_scan_token(COLON)) return true;
if (jj_3R_25()) return true;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_82()) { jj_scanpos = xsp; break; }
- }
- return false;
- }
-
- final 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_28()) return true;
- }
return false;
}
- final private boolean jj_3R_35() {
- if (jj_scan_token(LCURLY)) return true;
- if (jj_scan_token(IDENTIFIER)) return true;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_9()) { jj_scanpos = xsp; break; }
- }
- if (jj_scan_token(RCURLY)) return true;
+ final private boolean jj_3R_50() {
+ if (jj_3R_63()) return true;
return false;
}
- final private boolean jj_3_12() {
- if (jj_scan_token(LBRACKET)) return true;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_32()) {
- jj_scanpos = xsp;
- if (jj_3R_33()) return true;
- }
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- if (jj_scan_token(DOUBLEDOT)) return true;
+ final private boolean jj_3R_49() {
+ if (jj_3R_61()) return true;
return false;
}
- final private boolean jj_3_2() {
- if (jj_scan_token(DOUBLE_ESCAPE)) return true;
+ final private boolean jj_3R_48() {
+ if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_34() {
- if (jj_scan_token(IDENTIFIER)) return true;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_7()) { jj_scanpos = xsp; break; }
- }
+ final private boolean jj_3R_47() {
+ if (jj_3R_60()) return true;
return false;
}
- final private boolean jj_3R_81() {
- if (jj_scan_token(LPAREN)) return true;
+ final private boolean jj_3R_84() {
+ if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_80() {
- if (jj_3R_66()) return true;
+ final private boolean jj_3R_69() {
+ if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_79() {
- if (jj_3R_65()) return true;
+ final private boolean jj_3R_86() {
+ if (jj_scan_token(COMMA)) return true;
+ if (jj_3R_25()) return true;
return false;
}
- final private boolean jj_3R_20() {
+ final private boolean jj_3R_25() {
Token xsp;
xsp = jj_scanpos;
- if (jj_3R_34()) {
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_47()) {
jj_scanpos = xsp;
- if (jj_3R_35()) return true;
+ if (jj_3R_48()) {
+ jj_scanpos = xsp;
+ if (jj_3R_49()) {
+ jj_scanpos = xsp;
+ if (jj_3R_50()) {
+ jj_scanpos = xsp;
+ 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()) return true;
+ }
+ }
+ }
+ }
+ }
+ }
}
+ }
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
return false;
}
- final private boolean jj_3R_78() {
- if (jj_3R_64()) return true;
+ final private boolean jj_3R_22() {
+ if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_77() {
- if (jj_3R_63()) return true;
+ final private boolean jj_3R_83() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_76() {
- if (jj_3R_62()) return true;
+ final private boolean jj_3R_68() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_75() {
- if (jj_3R_61()) return true;
+ final private boolean jj_3R_71() {
+ if (jj_3R_25()) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_86()) { jj_scanpos = xsp; break; }
+ }
return false;
}
- final private boolean jj_3R_74() {
- if (jj_3R_36()) return true;
+ final private boolean jj_3_1() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_73() {
+ final private boolean jj_3R_21() {
if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3_6() {
+ final private boolean jj_3R_61() {
if (jj_scan_token(LBRACKET)) return true;
Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
xsp = jj_scanpos;
- if (jj_3R_26()) {
+ if (jj_3R_68()) {
jj_scanpos = xsp;
- if (jj_3R_27()) return true;
+ if (jj_3R_69()) return true;
}
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
if (jj_scan_token(DOUBLEDOT)) return true;
- return false;
- }
-
- final private boolean jj_3R_29() {
- if (jj_3R_56()) return true;
- if (jj_scan_token(LPAREN)) return true;
- Token xsp;
xsp = jj_scanpos;
- if (jj_3R_57()) jj_scanpos = xsp;
- if (jj_scan_token(REFMOD2_RPAREN)) return true;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_83()) {
+ jj_scanpos = xsp;
+ if (jj_3R_84()) return true;
+ }
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ if (jj_scan_token(RBRACKET)) return true;
return false;
}
- final private boolean jj_3R_72() {
- if (jj_3R_60()) return true;
+ final private boolean jj_3R_64() {
+ if (jj_scan_token(LBRACKET)) return true;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_71()) jj_scanpos = xsp;
+ if (jj_scan_token(RBRACKET)) return true;
return false;
}
- final private boolean jj_3R_67() {
+ final private boolean jj_3R_70() {
Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_72()) {
- jj_scanpos = xsp;
- if (jj_3R_73()) {
- jj_scanpos = xsp;
- if (jj_3R_74()) {
- jj_scanpos = xsp;
- if (jj_3R_75()) {
- jj_scanpos = xsp;
- if (jj_3R_76()) {
- jj_scanpos = xsp;
- if (jj_3R_77()) {
- jj_scanpos = xsp;
- if (jj_3R_78()) {
- jj_scanpos = xsp;
- if (jj_3R_79()) {
- jj_scanpos = xsp;
- if (jj_3R_80()) {
- jj_scanpos = xsp;
- if (jj_3R_81()) return true;
- }
- }
- }
- }
- }
- }
- }
- }
- }
return false;
}
- final private boolean jj_3R_55() {
- if (jj_3R_62()) return true;
- return false;
- }
-
- final private boolean jj_3R_54() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_46() {
+ if (jj_3R_66()) return true;
return false;
}
- final private boolean jj_3R_53() {
- if (jj_3R_66()) return true;
+ final private boolean jj_3_5() {
+ if (jj_3R_25()) return true;
+ if (jj_scan_token(COLON)) return true;
+ if (jj_3R_25()) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_85()) { jj_scanpos = xsp; break; }
+ }
return false;
}
- final private boolean jj_3R_52() {
+ final private boolean jj_3R_45() {
if (jj_3R_65()) return true;
return false;
}
- final private boolean jj_3R_31() {
+ final private boolean jj_3R_63() {
+ if (jj_scan_token(LEFT_CURLEY)) return true;
Token xsp;
xsp = jj_scanpos;
- if (jj_3_11()) {
+ if (jj_3_5()) {
jj_scanpos = xsp;
- if (jj_3R_58()) return true;
+ if (jj_3R_70()) return true;
+ }
+ xsp = jj_scanpos;
+ if (jj_scan_token(7)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(65)) return true;
}
return false;
}
- final private boolean jj_3_11() {
+ final private boolean jj_3_3() {
+ if (jj_scan_token(LBRACKET)) return true;
Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
- if (jj_scan_token(LOGICAL_NOT)) return true;
- if (jj_3R_31()) return true;
- return false;
- }
-
- final private boolean jj_3R_58() {
- if (jj_3R_67()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_21()) {
+ jj_scanpos = xsp;
+ if (jj_3R_22()) return true;
+ }
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ if (jj_scan_token(DOUBLEDOT)) return true;
return false;
}
- final private boolean jj_3R_51() {
+ final private boolean jj_3R_44() {
if (jj_3R_64()) return true;
return false;
}
- final private boolean jj_3R_85() {
- if (jj_scan_token(COMMA)) return true;
- if (jj_3R_25()) return true;
- if (jj_scan_token(COLON)) return true;
- if (jj_3R_25()) return true;
+ final private boolean jj_3R_43() {
+ if (jj_3R_63()) return true;
return false;
}
- final private boolean jj_3R_50() {
- if (jj_3R_63()) return true;
+ final private boolean jj_3R_42() {
+ if (jj_3R_62()) return true;
return false;
}
- final private boolean jj_3R_49() {
+ final private boolean jj_3R_41() {
if (jj_3R_61()) return true;
return false;
}
- final private boolean jj_3R_48() {
+ final private boolean jj_3R_40() {
if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_47() {
+ final private boolean jj_3R_39() {
if (jj_3R_60()) return true;
return false;
}
- final private boolean jj_3R_84() {
- if (jj_3R_36()) return true;
- return false;
- }
-
- final private boolean jj_3R_22() {
- if (jj_3R_36()) return true;
+ final private boolean jj_3R_38() {
+ if (jj_3R_59()) return true;
return false;
}
- final private boolean jj_3R_69() {
- if (jj_3R_36()) return true;
+ final private boolean jj_3R_23() {
+ if (jj_scan_token(COMMA)) return true;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
return false;
}
- final private boolean jj_3R_86() {
- if (jj_scan_token(COMMA)) return true;
- if (jj_3R_25()) return true;
+ final private boolean jj_3R_37() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_25() {
+ final private boolean jj_3R_24() {
Token xsp;
xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_47()) {
+ if (jj_3R_37()) {
jj_scanpos = xsp;
- if (jj_3R_48()) {
+ if (jj_3R_38()) {
jj_scanpos = xsp;
- if (jj_3R_49()) {
+ if (jj_3R_39()) {
jj_scanpos = xsp;
- if (jj_3R_50()) {
+ if (jj_3R_40()) {
jj_scanpos = xsp;
- if (jj_3R_51()) {
+ if (jj_3R_41()) {
jj_scanpos = xsp;
- if (jj_3R_52()) {
+ if (jj_3R_42()) {
jj_scanpos = xsp;
- if (jj_3R_53()) {
+ if (jj_3R_43()) {
jj_scanpos = xsp;
- if (jj_3R_54()) {
+ if (jj_3R_44()) {
jj_scanpos = xsp;
- if (jj_3R_55()) return true;
+ if (jj_3R_45()) {
+ jj_scanpos = xsp;
+ if (jj_3R_46()) return true;
+ }
}
}
}
@@ -2882,130 +2900,153 @@
}
}
}
+ return false;
+ }
+
+ final private boolean jj_3R_59() {
+ if (jj_scan_token(WORD)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_56() {
+ if (jj_scan_token(IDENTIFIER)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_4() {
+ Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_23()) jj_scanpos = xsp;
+ if (jj_3R_24()) return true;
return false;
}
- final private boolean jj_3R_83() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_30() {
+ if (jj_3R_56()) return true;
return false;
}
- final private boolean jj_3_1() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_60() {
+ if (jj_scan_token(STRING_LITERAL)) return true;
return false;
}
- final private boolean jj_3R_21() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_36() {
+ if (jj_scan_token(INTEGER_LITERAL)) return true;
return false;
}
- final private boolean jj_3R_68() {
+ final private boolean jj_3R_28() {
+ if (jj_3R_56()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_33() {
+ if (jj_3R_36()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_62() {
+ if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_32() {
if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_71() {
+ final private boolean jj_3R_27() {
+ if (jj_3R_36()) return true;
+ return false;
+ }
+
+ final private boolean jj_3_10() {
+ if (jj_3R_29()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_82() {
+ if (jj_scan_token(COMMA)) return true;
if (jj_3R_25()) return true;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_86()) { jj_scanpos = xsp; break; }
- }
return false;
}
- final private boolean jj_3R_61() {
- if (jj_scan_token(LBRACKET)) return true;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_68()) {
- jj_scanpos = xsp;
- if (jj_3R_69()) return true;
- }
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- if (jj_scan_token(DOUBLEDOT)) return true;
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_83()) {
- jj_scanpos = xsp;
- if (jj_3R_84()) return true;
- }
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- if (jj_scan_token(RBRACKET)) return true;
+ final private boolean jj_3_8() {
+ if (jj_3R_29()) return true;
return false;
}
- final private boolean jj_3R_64() {
- if (jj_scan_token(LBRACKET)) return true;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_71()) jj_scanpos = xsp;
- if (jj_scan_token(RBRACKET)) return true;
+ final private boolean jj_3R_26() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_46() {
- if (jj_3R_66()) return true;
+ final private boolean jj_3R_66() {
+ if (jj_scan_token(FALSE)) return true;
return false;
}
- final private boolean jj_3R_70() {
+ final private boolean jj_3R_65() {
+ if (jj_scan_token(TRUE)) return true;
+ return false;
+ }
+
+ final private boolean jj_3_9() {
+ if (jj_scan_token(DOT)) return true;
Token xsp;
xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
+ if (jj_3_10()) {
+ jj_scanpos = xsp;
+ if (jj_3R_30()) return true;
+ }
return false;
}
- final private boolean jj_3_5() {
- if (jj_3R_25()) return true;
- if (jj_scan_token(COLON)) return true;
+ final private boolean jj_3R_57() {
if (jj_3R_25()) return true;
Token xsp;
while (true) {
xsp = jj_scanpos;
- if (jj_3R_85()) { jj_scanpos = xsp; break; }
+ if (jj_3R_82()) { jj_scanpos = xsp; break; }
}
return false;
}
- final private boolean jj_3R_45() {
- if (jj_3R_65()) return true;
- return false;
- }
-
- final private boolean jj_3R_63() {
- if (jj_scan_token(LEFT_CURLEY)) return true;
+ final private boolean jj_3_7() {
+ if (jj_scan_token(DOT)) return true;
Token xsp;
xsp = jj_scanpos;
- if (jj_3_5()) {
+ if (jj_3_8()) {
jj_scanpos = xsp;
- if (jj_3R_70()) return true;
+ if (jj_3R_28()) return true;
}
- xsp = jj_scanpos;
- if (jj_scan_token(7)) {
- jj_scanpos = xsp;
- if (jj_scan_token(65)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_35() {
+ if (jj_scan_token(LCURLY)) return true;
+ if (jj_scan_token(IDENTIFIER)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_9()) { jj_scanpos = xsp; break; }
}
+ if (jj_scan_token(RCURLY)) return true;
return false;
}
- final private boolean jj_3_3() {
+ final private boolean jj_3_12() {
if (jj_scan_token(LBRACKET)) return true;
Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
xsp = jj_scanpos;
- if (jj_3R_21()) {
+ if (jj_3R_32()) {
jj_scanpos = xsp;
- if (jj_3R_22()) return true;
+ if (jj_3R_33()) return true;
}
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
@@ -3013,76 +3054,131 @@
return false;
}
- final private boolean jj_3R_44() {
+ final private boolean jj_3_2() {
+ if (jj_scan_token(DOUBLE_ESCAPE)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_34() {
+ if (jj_scan_token(IDENTIFIER)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_7()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_81() {
+ if (jj_scan_token(LPAREN)) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_80() {
+ if (jj_3R_66()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_79() {
+ if (jj_3R_65()) return true;
+ return false;
+ }
+
+ final private boolean jj_3R_20() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_34()) {
+ jj_scanpos = xsp;
+ if (jj_3R_35()) return true;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_78() {
if (jj_3R_64()) return true;
return false;
}
- final private boolean jj_3R_43() {
+ final private boolean jj_3R_77() {
if (jj_3R_63()) return true;
return false;
}
- final private boolean jj_3R_42() {
+ final private boolean jj_3R_76() {
if (jj_3R_62()) return true;
return false;
}
- final private boolean jj_3R_41() {
+ final private boolean jj_3R_75() {
if (jj_3R_61()) return true;
return false;
}
- final private boolean jj_3R_40() {
+ final private boolean jj_3R_74() {
if (jj_3R_36()) return true;
return false;
}
- final private boolean jj_3R_39() {
- if (jj_3R_60()) return true;
+ final private boolean jj_3R_73() {
+ if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_23() {
- if (jj_scan_token(COMMA)) return true;
+ final private boolean jj_3_6() {
+ if (jj_scan_token(LBRACKET)) return true;
Token xsp;
xsp = jj_scanpos;
if (jj_scan_token(26)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_26()) {
+ jj_scanpos = xsp;
+ if (jj_3R_27()) return true;
+ }
+ xsp = jj_scanpos;
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ if (jj_scan_token(DOUBLEDOT)) return true;
return false;
}
- final private boolean jj_3R_38() {
- if (jj_3R_59()) return true;
+ final private boolean jj_3R_29() {
+ if (jj_3R_56()) return true;
+ if (jj_scan_token(LPAREN)) return true;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_57()) jj_scanpos = xsp;
+ if (jj_scan_token(REFMOD2_RPAREN)) return true;
return false;
}
- final private boolean jj_3R_37() {
- if (jj_3R_20()) return true;
+ final private boolean jj_3R_72() {
+ if (jj_3R_60()) return true;
return false;
}
- final private boolean jj_3R_24() {
+ final private boolean jj_3R_67() {
Token xsp;
xsp = jj_scanpos;
- if (jj_3R_37()) {
+ if (jj_scan_token(26)) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_72()) {
jj_scanpos = xsp;
- if (jj_3R_38()) {
+ if (jj_3R_73()) {
jj_scanpos = xsp;
- if (jj_3R_39()) {
+ if (jj_3R_74()) {
jj_scanpos = xsp;
- if (jj_3R_40()) {
+ if (jj_3R_75()) {
jj_scanpos = xsp;
- if (jj_3R_41()) {
+ if (jj_3R_76()) {
jj_scanpos = xsp;
- if (jj_3R_42()) {
+ if (jj_3R_77()) {
jj_scanpos = xsp;
- if (jj_3R_43()) {
+ if (jj_3R_78()) {
jj_scanpos = xsp;
- if (jj_3R_44()) {
+ if (jj_3R_79()) {
jj_scanpos = xsp;
- if (jj_3R_45()) {
+ if (jj_3R_80()) {
jj_scanpos = xsp;
- if (jj_3R_46()) return true;
+ if (jj_3R_81()) return true;
}
}
}
@@ -3095,68 +3191,18 @@
return false;
}
- final private boolean jj_3R_59() {
- if (jj_scan_token(WORD)) return true;
- return false;
- }
-
- final private boolean jj_3R_56() {
- if (jj_scan_token(IDENTIFIER)) return true;
- return false;
- }
-
- final private boolean jj_3_4() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_scan_token(26)) jj_scanpos = xsp;
- xsp = jj_scanpos;
- if (jj_3R_23()) jj_scanpos = xsp;
- if (jj_3R_24()) return true;
- return false;
- }
-
- final private boolean jj_3R_60() {
- if (jj_scan_token(STRING_LITERAL)) return true;
- return false;
- }
-
- final private boolean jj_3R_30() {
- if (jj_3R_56()) return true;
- return false;
- }
-
- final private boolean jj_3R_36() {
- if (jj_scan_token(INTEGER_LITERAL)) return true;
- return false;
- }
-
- final private boolean jj_3R_28() {
- if (jj_3R_56()) return true;
- return false;
- }
-
- final private boolean jj_3R_33() {
- if (jj_3R_36()) return true;
- return false;
- }
-
- final private boolean jj_3R_62() {
- if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+ final private boolean jj_3R_55() {
+ if (jj_3R_62()) return true;
return false;
}
- final private boolean jj_3R_32() {
+ final private boolean jj_3R_54() {
if (jj_3R_20()) return true;
return false;
}
- final private boolean jj_3R_27() {
- if (jj_3R_36()) return true;
- return false;
- }
-
- final private boolean jj_3_10() {
- if (jj_3R_29()) return true;
+ final private boolean jj_3R_53() {
+ if (jj_3R_66()) return true;
return false;
}
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/Parser.jj Wed Aug 22 09:31:31 2007
@@ -265,6 +265,51 @@
else
return ( strImage );
}
+
+ /**
+ * Check weather their is a left parenthesis with leading optional
+ * whitespaces. This method is used in the semantic look ahead of
+ * Directive method. It requires lot of changes to implement the
+ * required look ahead as a BNF production and the code will become
+ * inefficient.
+ */
+ private boolean isLeftParantheses()
+ {
+ 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)
@@ -1449,14 +1494,6 @@
isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
- if (!isVM)
- {
- token_source.stateStackPop();
- token_source.inDirective = false;
- return jjtn000;
- }
-
-
/*
* Currently, all VMs are LINE directives
*/
@@ -1478,12 +1515,14 @@
}
-
+ /**
+ * Look for the patter [WHITESPACE] <LPAREN>
+ */
+ (LOOKAHEAD( { isLeftParantheses() } )
/*
* if this is indeed a token, match the #foo ( arg ) pattern
*/
-
- [<WHITESPACE>] <LPAREN> ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
+ (([<WHITESPACE>] <LPAREN>) ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
argType = DirectiveArg()
{
@@ -1522,14 +1561,24 @@
argPos++;
}
- )* [<WHITESPACE>] <RPAREN>
+ )* [<WHITESPACE>] <RPAREN>)
{
if (directiveType == Directive.LINE)
{
return jjtn000;
}
- }/*@bgen(jjtree) Block */
+ }
+ |
+ {
+ /**
+ * Not a directive
+ */
+ token_source.stateStackPop();
+ token_source.inDirective = false;
+ return jjtn000;
+ }
+ )/*@bgen(jjtree) Block */
{
ASTBlock jjtn001 = new ASTBlock(this, JJTBLOCK);
boolean jjtc001 = true;
@@ -1537,7 +1586,6 @@
}
try {
/*@egen*/
-
/*
* and the following block if the PD needs it
*/
Modified: velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java (original)
+++ velocity/engine/trunk/src/java/org/apache/velocity/runtime/parser/node/ASTDirective.java Wed Aug 22 09:31:31 2007
@@ -29,6 +29,7 @@
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.parser.ParseException;
import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.util.ExceptionUtils;
@@ -119,20 +120,22 @@
directive.setLocation( getLine(), getColumn() );
}
- else if (rsvc.isVelocimacro( directiveName, context.getCurrentTemplateName() ))
+ else
{
- /*
- * we seem to be a Velocimacro.
+ /**
+ * Create a new RuntimeMacro
*/
+ directive = new RuntimeMacro(directiveName,
+ context.getCurrentTemplateName());
- isDirective = true;
- directive = rsvc.getVelocimacro( directiveName, context.getCurrentTemplateName());
-
- try
+ /**
+ * Initialize it
+ */
+ try
{
directive.init( rsvc, context, this );
}
-
+
/**
* correct the line/column number if an exception is caught
*/
@@ -145,12 +148,9 @@
die.getLineNumber() + getLine());
}
directive.setLocation( getLine(), getColumn() );
- }
- else
- {
- isDirective = false;
- }
+ isDirective = true;
+ }
return data;
}
@@ -208,5 +208,6 @@
}
}
+
Modified: velocity/engine/trunk/src/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/parser/Parser.jjt?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/parser/Parser.jjt (original)
+++ velocity/engine/trunk/src/parser/Parser.jjt Wed Aug 22 09:31:31 2007
@@ -286,6 +286,50 @@
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 isLeftParantheses()
+ {
+ 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)
@@ -1327,14 +1371,6 @@
isVM = rsvc.isVelocimacro(directiveName, currentTemplateName);
- if (!isVM)
- {
- token_source.stateStackPop();
- token_source.inDirective = false;
- return jjtThis;
- }
-
-
/*
* Currently, all VMs are LINE directives
*/
@@ -1356,12 +1392,14 @@
}
-
+ /**
+ * Look for the patter [WHITESPACE] <LPAREN>
+ */
+ (LOOKAHEAD( { isLeftParantheses() } )
/*
* if this is indeed a token, match the #foo ( arg ) pattern
*/
-
- [<WHITESPACE>] <LPAREN> ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
+ (([<WHITESPACE>] <LPAREN>) ( LOOKAHEAD(2) [<WHITESPACE>] [<COMMA> [<WHITESPACE>]]
argType = DirectiveArg()
{
@@ -1400,7 +1438,7 @@
argPos++;
}
- )* [<WHITESPACE>] <RPAREN>
+ )* [<WHITESPACE>] <RPAREN>)
{
if (directiveType == Directive.LINE)
@@ -1408,7 +1446,16 @@
return jjtThis;
}
}
-
+ |
+ {
+ /**
+ * Not a directive
+ */
+ token_source.stateStackPop();
+ token_source.inDirective = false;
+ return jjtThis;
+ }
+ )
/*
* and the following block if the PD needs it
*/
Modified: velocity/engine/trunk/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java (original)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/MacroForwardDefineTestCase.java Wed Aug 22 09:31:31 2007
@@ -25,6 +25,10 @@
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.test.misc.TestLogChute;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import java.io.*;
/**
* Make sure that a forward referenced macro inside another macro definition does
@@ -57,7 +61,7 @@
* Collects the log messages.
*/
private TestLogChute logger = new TestLogChute();
-
+
/**
* Default constructor.
*/
@@ -70,18 +74,16 @@
throws Exception
{
assureResultsDirectoryExists(RESULTS_DIR);
-
+
// use Velocity.setProperty (instead of properties file) so that we can use actual instance of log
Velocity.setProperty(RuntimeConstants.RESOURCE_LOADER,"file");
Velocity.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH );
Velocity.setProperty(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID,"true");
- Velocity.setProperty(RuntimeConstants.VM_LIBRARY, "macros.vm");
// actual instance of logger
logger = new TestLogChute();
Velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM,logger);
Velocity.setProperty("runtime.log.logsystem.test.level", "error");
-
Velocity.init();
}
@@ -93,6 +95,11 @@
public void testLogResult()
throws Exception
{
+ VelocityContext context = new VelocityContext();
+ Template template = Velocity.getTemplate("macros.vm");
+
+ template.merge(context, new StringWriter());
+
if ( !isMatch(logger.getLog(), COMPARE_DIR, "velocity.log", "cmp"))
{
fail("Output incorrect.");
Added: velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java?rev=568691&view=auto
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java (added)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java Wed Aug 22 09:31:31 2007
@@ -0,0 +1,244 @@
+package org.apache.velocity.test;
+
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.runtime.log.NullLogChute;
+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))
+ {
+ fail("Processed template did not match expected output");
+ }
+
+ /*
+ * 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, NullLogChute.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, NullLogChute.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");
+ }
+ }
+}
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/ParseWithMacroLibsTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision
Added: velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java?rev=568691&view=auto
==============================================================================
--- velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java (added)
+++ velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java Wed Aug 22 09:31:31 2007
@@ -0,0 +1,277 @@
+package 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.runtime.log.NullLogChute;
+
+/**
+ * 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, NullLogChute.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, NullLogChute.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");
+ }
+ }
+
+ /**
+ * 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");
+ }
+ }
+}
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/src/test/org/apache/velocity/test/VMLibraryTestCase.java
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision
Modified: velocity/engine/trunk/test/macroforwarddefine/compare/velocity.log.cmp
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/test/macroforwarddefine/compare/velocity.log.cmp?rev=568691&r1=568690&r2=568691&view=diff
==============================================================================
--- velocity/engine/trunk/test/macroforwarddefine/compare/velocity.log.cmp (original)
+++ velocity/engine/trunk/test/macroforwarddefine/compare/velocity.log.cmp Wed Aug 22 09:31:31 2007
@@ -1,8 +1,16 @@
- [error] VM #test1: error : too few arguments to macro. Wanted 1 got 0
- [error] VM #test2: error : too few arguments to macro. Wanted 1 got 0
- [error] VM #test3: error : too few arguments to macro. Wanted 1 got 0
- [error] VM #test4: error : too few arguments to macro. Wanted 1 got 0
- [error] VM #test1: error : too many arguments to macro. Wanted 1 got 2
- [error] VM #test2: error : too many arguments to macro. Wanted 1 got 2
- [error] VM #test3: error : too many arguments to macro. Wanted 1 got 2
- [error] VM #test4: error : too many arguments to macro. Wanted 1 got 2
+ [error] VM #test1: error : too few arguments to macro. Wanted 1 got 0
+ [error] VM error test1. Null AST
+ [error] VM #test2: error : too few arguments to macro. Wanted 1 got 0
+ [error] VM error test2. Null AST
+ [error] VM #test3: error : too few arguments to macro. Wanted 1 got 0
+ [error] VM error test3. Null AST
+ [error] VM #test4: error : too few arguments to macro. Wanted 1 got 0
+ [error] VM error test4. Null AST
+ [error] VM #test1: error : too many arguments to macro. Wanted 1 got 2
+ [error] VM error test1. Null AST
+ [error] VM #test2: error : too many arguments to macro. Wanted 1 got 2
+ [error] VM error test2. Null AST
+ [error] VM #test3: error : too many arguments to macro. Wanted 1 got 2
+ [error] VM error test3. Null AST
+ [error] VM #test4: error : too many arguments to macro. Wanted 1 got 2
+ [error] VM error test4. Null AST
Added: velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp?rev=568691&view=auto
==============================================================================
--- velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp (added)
+++ velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp Wed Aug 22 09:31:31 2007
@@ -0,0 +1,8 @@
+This is a test file for loading macro libs programatically
+
+call foo
+#foo(1)
+#bar(2)
+
+no macro definition
+#abc(2)
Propchange: velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/test/macrolibs/compare/vm_library.cmp
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision
Added: velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp
URL: http://svn.apache.org/viewvc/velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp?rev=568691&view=auto
==============================================================================
--- velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp (added)
+++ velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp Wed Aug 22 09:31:31 2007
@@ -0,0 +1,11 @@
+This 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)
\ No newline at end of file
Propchange: velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/engine/trunk/test/macrolibs/compare/vm_library_global.cmp
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision