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

COVERAGE SUMMARY FOR SOURCE FILE [Template.java]

nameclass, %method, %block, %line, %
Template.java100% (1/1)100% (4/4)64%  (131/205)70%  (35.2/50)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Template100% (1/1)100% (4/4)64%  (131/205)70%  (35.2/50)
process (): boolean 100% (1/1)58%  (66/113)61%  (15.8/26)
merge (Context, Writer): void 100% (1/1)60%  (33/55)68%  (9.5/14)
initDocument (): void 100% (1/1)82%  (23/28)97%  (5.8/6)
Template (): void 100% (1/1)100% (9/9)100% (4/4)

1package org.apache.velocity;
2 
3/*
4 * Copyright 2000-2001,2004 The Apache Software Foundation.
5 * 
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 * 
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 * 
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 
19import java.io.InputStream;
20import java.io.Writer;
21import java.io.BufferedReader;
22import java.io.InputStreamReader;
23import java.io.UnsupportedEncodingException;
24 
25import org.apache.velocity.runtime.resource.Resource;
26import org.apache.velocity.runtime.parser.ParseException;
27import org.apache.velocity.runtime.parser.node.SimpleNode;
28 
29import org.apache.velocity.VelocityContext;
30import org.apache.velocity.context.Context;
31import org.apache.velocity.context.InternalContextAdapterImpl;
32 
33import org.apache.velocity.exception.ResourceNotFoundException;
34import org.apache.velocity.exception.ParseErrorException;
35import org.apache.velocity.exception.MethodInvocationException;
36 
37/**
38 * This class is used for controlling all template
39 * operations. This class uses a parser created
40 * by JavaCC to create an AST that is subsequently
41 * traversed by a Visitor. 
42 *
43 * <pre>
44 * Template template = Velocity.getTemplate("test.wm");
45 * Context context = new VelocityContext();
46 *
47 * context.put("foo", "bar");
48 * context.put("customer", new Customer());
49 *
50 * template.merge(context, writer);
51 * </pre>
52 *
53 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
54 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
55 * @version $Id: Template.java,v 1.36.4.1 2004/03/03 22:28:24 geirm Exp $
56 */
57public class Template extends Resource
58{
59    /**
60     *   To keep track of whether this template has been
61     *   initialized. We use the document.init(context)
62     *   to perform this.
63     */
64    private boolean initialized = false;
65 
66    private Exception errorCondition = null;
67 
68    /** Default constructor */
69    public Template()
70    {
71    }
72 
73    /**
74     *  gets the named resource as a stream, parses and inits
75     *
76     * @return true if successful
77     * @throws ResourceNotFoundException if template not found
78     *          from any available source.
79     * @throws ParseErrorException if template cannot be parsed due
80     *          to syntax (or other) error.
81     * @throws Exception some other problem, should only be from 
82     *          initialization of the template AST.
83     */
84    public boolean process()
85        throws ResourceNotFoundException, ParseErrorException, Exception
86    {
87        data = null;
88        InputStream is = null;
89        errorCondition = null;
90 
91        /*
92         *  first, try to get the stream from the loader
93         */
94        try 
95        {
96            is = resourceLoader.getResourceStream(name);
97        }
98        catch( ResourceNotFoundException rnfe )
99        {
100            /*
101             *  remember and re-throw
102             */
103 
104            errorCondition = rnfe;
105            throw rnfe;
106        }
107 
108        /*
109         *  if that worked, lets protect in case a loader impl
110         *  forgets to throw a proper exception
111         */
112 
113        if (is != null)
114        {
115            /*
116             *  now parse the template
117             */
118 
119            try
120            {
121                BufferedReader br = new BufferedReader( new InputStreamReader( is, encoding ) );
122 
123                data = rsvc.parse( br, name);
124                initDocument();
125                return true;
126            }
127            catch( UnsupportedEncodingException  uce )
128            {   
129                String msg = "Template.process : Unsupported input encoding : " + encoding 
130                + " for template " + name;
131 
132                errorCondition  = new ParseErrorException( msg );
133                throw errorCondition;
134            }
135            catch ( ParseException pex )
136            {
137                /*
138                 *  remember the error and convert
139                 */
140 
141               errorCondition =  new ParseErrorException( pex.getMessage() );
142               throw errorCondition;
143            }
144            catch( Exception e )
145            {
146                /*
147                 *  who knows?  Something from initDocument()
148                 */
149 
150                errorCondition = e;
151                throw e;
152            }
153            finally 
154            {
155                /*
156                 *  Make sure to close the inputstream when we are done.
157                 */
158                is.close();
159            }
160        }    
161        else
162        {
163            /* 
164             *  is == null, therefore we have some kind of file issue
165             */
166 
167            errorCondition = new ResourceNotFoundException("Unknown resource error for resource " + name );
168            throw errorCondition;
169        }
170    }
171 
172    /**
173     *  initializes the document.  init() is not longer 
174     *  dependant upon context, but we need to let the 
175     *  init() carry the template name down throught for VM
176     *  namespace features
177     */
178    public void initDocument()
179        throws Exception
180    {
181        /*
182         *  send an empty InternalContextAdapter down into the AST to initialize it
183         */
184        
185        InternalContextAdapterImpl ica = new InternalContextAdapterImpl(  new VelocityContext() );
186 
187        try
188        {
189            /*
190             *  put the current template name on the stack
191             */
192 
193            ica.pushCurrentTemplateName( name );
194            
195            /*
196             *  init the AST
197             */
198 
199            ((SimpleNode)data).init( ica, rsvc);
200        }
201        finally
202        {
203            /*  
204             *  in case something blows up...
205             *  pull it off for completeness
206             */
207 
208            ica.popCurrentTemplateName();
209        }
210 
211    }
212 
213    /**
214     * The AST node structure is merged with the
215     * context to produce the final output. 
216     *
217     * Throws IOException if failure is due to a file related
218     * issue, and Exception otherwise
219     *
220     *  @param context Conext with data elements accessed by template
221     *  @param writer output writer for rendered template
222     *  @throws ResourceNotFoundException if template not found
223     *          from any available source.
224     *  @throws ParseErrorException if template cannot be parsed due
225     *          to syntax (or other) error.
226     *  @throws  Exception  anything else. 
227     */
228    public void merge( Context context, Writer writer)
229        throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, Exception
230    {
231        /*
232         *  we shouldn't have to do this, as if there is an error condition, 
233         *  the application code should never get a reference to the 
234         *  Template
235         */
236 
237        if (errorCondition != null)
238        {
239            throw errorCondition;
240        }
241 
242        if( data != null)
243        {
244            /*
245             *  create an InternalContextAdapter to carry the user Context down
246             *  into the rendering engine.  Set the template name and render()
247             */
248 
249            InternalContextAdapterImpl ica = new InternalContextAdapterImpl( context );
250 
251            try
252            {
253                ica.pushCurrentTemplateName( name );
254                ica.setCurrentResource( this );
255 
256                ( (SimpleNode) data ).render( ica, writer);
257            }
258            finally
259            {
260                /*
261                 *  lets make sure that we always clean up the context 
262                 */
263                ica.popCurrentTemplateName();
264                ica.setCurrentResource( null );
265            }
266        }
267        else
268        {
269            /*
270             * this shouldn't happen either, but just in case.
271             */
272 
273            String msg = "Template.merge() failure. The document is null, " + 
274                "most likely due to parsing error.";
275 
276            rsvc.error(msg);
277            throw new Exception(msg);
278        }
279    }
280}
281 
282 

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