EMMA Coverage Report (generated Tue May 18 22:13:27 CDT 2004)
[all classes][org.apache.velocity.runtime.directive]

COVERAGE SUMMARY FOR SOURCE FILE [Include.java]

nameclass, %method, %block, %line, %
Include.java100% (1/1)86%  (6/7)47%  (116/249)61%  (28/46)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Include100% (1/1)86%  (6/7)47%  (116/249)61%  (28/46)
outputErrorToStream (Writer, String): void 0%   (0/1)0%   (0/18)0%   (0/5)
renderOutput (Node, InternalContextAdapter, Writer): boolean 100% (1/1)30%  (33/109)52%  (11/21)
render (InternalContextAdapter, Writer, Node): boolean 100% (1/1)43%  (30/69)67%  (6/9)
Include (): void 100% (1/1)100% (9/9)100% (3/3)
getName (): String 100% (1/1)100% (2/2)100% (1/1)
getType (): int 100% (1/1)100% (2/2)100% (1/1)
init (RuntimeServices, InternalContextAdapter, Node): void 100% (1/1)100% (40/40)100% (6/6)

1 
2package org.apache.velocity.runtime.directive;
3 
4/*
5 * Copyright 2000-2001,2004 The Apache Software Foundation.
6 * 
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 * 
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 * 
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 
20import java.io.Writer;
21import java.io.IOException;
22 
23import org.apache.velocity.context.InternalContextAdapter;
24import org.apache.velocity.runtime.RuntimeServices;
25import org.apache.velocity.runtime.RuntimeConstants;
26import org.apache.velocity.runtime.parser.ParserTreeConstants;
27import org.apache.velocity.runtime.parser.node.Node;
28import org.apache.velocity.runtime.resource.Resource;
29 
30import org.apache.velocity.exception.MethodInvocationException;
31import org.apache.velocity.exception.ResourceNotFoundException;
32 
33/**
34 * Pluggable directive that handles the #include() statement in VTL. 
35 * This #include() can take multiple arguments of either 
36 * StringLiteral or Reference.
37 *
38 * Notes:
39 * -----
40 *  1) The included source material can only come from somewhere in 
41 *    the TemplateRoot tree for security reasons. There is no way 
42 *    around this.  If you want to include content from elsewhere on
43 *    your disk, use a link from somwhere under Template Root to that 
44 *    content.
45 *
46 *  2) By default, there is no output to the render stream in the event of
47 *    a problem.  You can override this behavior with two property values :
48 *       include.output.errormsg.start
49 *       include.output.errormsg.end
50 *     If both are defined in velocity.properties, they will be used to
51 *     in the render output to bracket the arg string that caused the 
52 *     problem.
53 *     Ex. : if you are working in html then
54 *       include.output.errormsg.start=<!-- #include error :
55 *       include.output.errormsg.end= -->
56 *     might be an excellent way to start...
57 *
58 *  3) As noted above, #include() can take multiple arguments.
59 *    Ex : #include( "foo.vm" "bar.vm" $foo )
60 *    will simply include all three if valid to output w/o any
61 *    special separator.
62 *
63 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
64 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
65 * @author <a href="mailto:kav@kav.dk">Kasper Nielsen</a>
66 * @version $Id: Include.java,v 1.26.4.1 2004/03/03 23:22:56 geirm Exp $
67 */
68public class Include extends InputBase
69{
70    private String outputMsgStart = "";
71    private String outputMsgEnd = "";
72 
73    /**
74     * Return name of this directive.
75     */
76    public String getName()
77    {
78        return "include";
79    }        
80    
81    /**
82     * Return type of this directive.
83     */
84    public int getType()
85    {
86        return LINE;
87    }        
88 
89    /**
90     *  simple init - init the tree and get the elementKey from
91     *  the AST
92     */
93    public void init(RuntimeServices rs, InternalContextAdapter context,
94                     Node node) 
95        throws Exception
96    {
97        super.init( rs, context, node );
98 
99        /*
100         *  get the msg, and add the space so we don't have to
101         *  do it each time
102         */
103        outputMsgStart = rsvc.getString(RuntimeConstants.ERRORMSG_START);
104        outputMsgStart = outputMsgStart + " ";
105        
106        outputMsgEnd = rsvc.getString(RuntimeConstants.ERRORMSG_END );
107        outputMsgEnd = " " + outputMsgEnd;   
108    }
109 
110    /**
111     *  iterates through the argument list and renders every
112     *  argument that is appropriate.  Any non appropriate
113     *  arguments are logged, but render() continues.
114     */
115    public boolean render(InternalContextAdapter context, 
116                           Writer writer, Node node)
117        throws IOException, MethodInvocationException,
118               ResourceNotFoundException
119    {
120        /*
121         *  get our arguments and check them
122         */
123 
124        int argCount = node.jjtGetNumChildren();
125 
126        for( int i = 0; i < argCount; i++)
127        {
128            /*
129             *  we only handle StringLiterals and References right now
130             */
131 
132            Node n = node.jjtGetChild(i);
133 
134            if ( n.getType() ==  ParserTreeConstants.JJTSTRINGLITERAL || 
135                 n.getType() ==  ParserTreeConstants.JJTREFERENCE )
136            {
137                if (!renderOutput( n, context, writer ))
138                    outputErrorToStream( writer, "error with arg " + i 
139                        + " please see log.");
140            }
141            else
142            {
143                rsvc.error("#include() error : invalid argument type : " 
144                    + n.toString());
145                outputErrorToStream( writer, "error with arg " + i 
146                    + " please see log.");
147            }
148        }
149        
150        return true;
151    }
152 
153    /**
154     *  does the actual rendering of the included file
155     *
156     *  @param node AST argument of type StringLiteral or Reference
157     *  @param context valid context so we can render References
158     *  @param writer output Writer
159     *  @return boolean success or failure.  failures are logged
160     */
161    private boolean renderOutput( Node node, InternalContextAdapter context, 
162                                  Writer writer )
163        throws IOException, MethodInvocationException,
164               ResourceNotFoundException
165    {
166        String arg = "";
167        
168        if ( node == null )
169        {
170            rsvc.error("#include() error :  null argument");
171            return false;
172        }
173            
174        /*
175         *  does it have a value?  If you have a null reference, then no.
176         */        
177        Object value = node.value( context );
178        if ( value == null)
179        {
180            rsvc.error("#include() error :  null argument");
181            return false;
182        }
183 
184        /*
185         *  get the path
186         */
187        arg = value.toString();
188 
189        Resource resource = null;
190 
191        try
192        {
193            resource = rsvc.getContent(arg, getInputEncoding(context));
194        }
195        catch ( ResourceNotFoundException rnfe )
196        {
197                       /*
198                        * the arg wasn't found.  Note it and throw
199                        */
200                        
201                rsvc.error("#include(): cannot find resource '" + arg +
202                       "', called from template " +
203                       context.getCurrentTemplateName() + " at (" +
204                       getLine() + ", " + getColumn() + ")" );
205                throw rnfe;
206        }
207 
208        catch (Exception e)
209        {
210                rsvc.error("#include(): arg = '" + arg +
211                       "', called from template " +
212                       context.getCurrentTemplateName() + " at (" +
213                       getLine() + ", " + getColumn() + ") : " + e);
214        }            
215        
216        if ( resource == null )
217            return false;
218       
219        writer.write((String)resource.getData());       
220        return true;
221    }
222 
223    /**
224     *  Puts a message to the render output stream if ERRORMSG_START / END
225     *  are valid property strings.  Mainly used for end-user template
226     *  debugging.
227     */
228    private void outputErrorToStream( Writer writer, String msg )
229        throws IOException
230    {        
231        if ( outputMsgStart != null  && outputMsgEnd != null)
232        {
233            writer.write(outputMsgStart);
234            writer.write(msg);
235            writer.write(outputMsgEnd);
236        }
237        return;
238    }
239}

[all classes][org.apache.velocity.runtime.directive]
EMMA 2.0.4015 (stable) (C) Vladimir Roubtsov