001: package org.apache.velocity.runtime.parser.node;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.IOException;
023: import java.io.Writer;
024:
025: import org.apache.commons.lang.builder.ToStringBuilder;
026: import org.apache.velocity.context.InternalContextAdapter;
027: import org.apache.velocity.exception.MethodInvocationException;
028: import org.apache.velocity.exception.ParseErrorException;
029: import org.apache.velocity.exception.ResourceNotFoundException;
030: import org.apache.velocity.exception.TemplateInitException;
031: import org.apache.velocity.runtime.directive.Directive;
032: import org.apache.velocity.runtime.parser.ParseException;
033: import org.apache.velocity.runtime.parser.Parser;
034: import org.apache.velocity.runtime.parser.ParserVisitor;
035: import org.apache.velocity.util.ExceptionUtils;
036:
037: /**
038: * This class is responsible for handling the pluggable
039: * directives in VTL.
040: *
041: * For example : #foreach()
042: *
043: * Please look at the Parser.jjt file which is
044: * what controls the generation of this class.
045: *
046: * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
047: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
048: * @author <a href="mailto:kav@kav.dk">Kasper Nielsen</a>
049: * @version $Id: ASTDirective.java 471381 2006-11-05 08:56:58Z wglass $
050: */
051: public class ASTDirective extends SimpleNode {
052: private Directive directive = null;
053: private String directiveName = "";
054: private boolean isDirective;
055:
056: /**
057: * @param id
058: */
059: public ASTDirective(int id) {
060: super (id);
061: }
062:
063: /**
064: * @param p
065: * @param id
066: */
067: public ASTDirective(Parser p, int id) {
068: super (p, id);
069: }
070:
071: /**
072: * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.ParserVisitor, java.lang.Object)
073: */
074: public Object jjtAccept(ParserVisitor visitor, Object data) {
075: return visitor.visit(this , data);
076: }
077:
078: /**
079: * @see org.apache.velocity.runtime.parser.node.SimpleNode#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
080: */
081: public Object init(InternalContextAdapter context, Object data)
082: throws TemplateInitException {
083: super .init(context, data);
084:
085: /*
086: * only do things that are not context dependant
087: */
088:
089: if (parser.isDirective(directiveName)) {
090: isDirective = true;
091:
092: try {
093: directive = (Directive) parser.getDirective(
094: directiveName).getClass().newInstance();
095: } catch (InstantiationException e) {
096: throw ExceptionUtils.createRuntimeException(
097: "Couldn't initialize "
098: + "directive of class "
099: + parser.getDirective(directiveName)
100: .getClass().getName(), e);
101: } catch (IllegalAccessException e) {
102: throw ExceptionUtils.createRuntimeException(
103: "Couldn't initialize "
104: + "directive of class "
105: + parser.getDirective(directiveName)
106: .getClass().getName(), e);
107: }
108:
109: directive.init(rsvc, context, this );
110:
111: directive.setLocation(getLine(), getColumn());
112: } else if (rsvc.isVelocimacro(directiveName, context
113: .getCurrentTemplateName())) {
114: /*
115: * we seem to be a Velocimacro.
116: */
117:
118: isDirective = true;
119: directive = rsvc.getVelocimacro(directiveName, context
120: .getCurrentTemplateName());
121:
122: try {
123: directive.init(rsvc, context, this );
124: }
125:
126: /**
127: * correct the line/column number if an exception is caught
128: */
129: catch (TemplateInitException die) {
130: throw new TemplateInitException(die.getMessage(),
131: (ParseException) die.getWrappedThrowable(), die
132: .getTemplateName(), die
133: .getColumnNumber()
134: + getColumn(), die.getLineNumber()
135: + getLine());
136: }
137: directive.setLocation(getLine(), getColumn());
138: } else {
139: isDirective = false;
140: }
141:
142: return data;
143: }
144:
145: /**
146: * @see org.apache.velocity.runtime.parser.node.SimpleNode#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer)
147: */
148: public boolean render(InternalContextAdapter context, Writer writer)
149: throws IOException, MethodInvocationException,
150: ResourceNotFoundException, ParseErrorException {
151: /*
152: * normal processing
153: */
154:
155: if (isDirective) {
156: directive.render(context, writer, this );
157: } else {
158: if (context.getAllowRendering()) {
159: writer.write("#");
160: writer.write(directiveName);
161: }
162: }
163:
164: return true;
165: }
166:
167: /**
168: * Sets the directive name. Used by the parser. This keeps us from having to
169: * dig it out of the token stream and gives the parse the change to override.
170: * @param str
171: */
172: public void setDirectiveName(String str) {
173: directiveName = str;
174: }
175:
176: /**
177: * Gets the name of this directive.
178: * @return The name of this directive.
179: */
180: public String getDirectiveName() {
181: return directiveName;
182: }
183:
184: public String toString() {
185: return new ToStringBuilder(this ).appendSuper(super .toString())
186: .append("directiveName", getDirectiveName()).toString();
187: }
188:
189: }
|