![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.velocity.runtime.directive.Macro Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.portal.template.velocity
Show all versions of com.liferay.portal.template.velocity
Liferay Portal Template Velocity
The newest version!
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 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 685685 2008-08-13 21:43:27Z 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;
}
/**
* 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);
/*
* again, don't do squat. We want the AST of the macro
* block to hang off of this but we don't want to
* init it... it's useless...
*/
}
/**
* Used by Parser.java to process VMs during the parsing process.
*
* This method does not render the macro to the output stream,
* but rather processes the macro body into the internal
* representation used by {#link
* org.apache.velocity.runtime.directive.VelocimacroProxy}
* objects, and if not currently used, adds it to the macro
* Factory.
* @param rs
* @param t
* @param node
* @param sourceTemplate
* @throws IOException
* @throws ParseException
*/
public static void processAndRegister(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);
}
// get the arguments to the use of the VM - element 0 contains the macro name
String argArray[] = getArgArray(node, rs);
/*
* we already have the macro parsed as AST so there is no point to
* transform it into a String again
*/
rs.addVelocimacro(argArray[0], node.jjtGetChild(numArgs - 1), argArray, sourceTemplate);
/*
* Even if the add attempt failed, we don't log anything here.
* Logging must be done at VelocimacroFactory or VelocimacroManager because
* those classes know the real reason.
*/
}
/**
* 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());
}
}
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;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy