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

COVERAGE SUMMARY FOR SOURCE FILE [Generator.java]

nameclass, %method, %block, %line, %
Generator.java100% (1/1)83%  (20/24)62%  (287/462)66%  (70.2/107)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Generator100% (1/1)83%  (20/24)62%  (287/462)66%  (70.2/107)
Generator (Properties): void 0%   (0/1)0%   (0/18)0%   (0/5)
Generator (String): void 0%   (0/1)0%   (0/43)0%   (0/12)
fillContextHash (Context, Hashtable): void 0%   (0/1)0%   (0/19)0%   (0/5)
getContext (Hashtable): Context 0%   (0/1)0%   (0/8)0%   (0/2)
getWriter (String, String): Writer 100% (1/1)30%  (10/33)54%  (2.2/4)
getTemplate (String, String): Template 100% (1/1)37%  (10/27)54%  (2.2/4)
parse (String, String, String, String, String, Object): String 100% (1/1)66%  (61/92)61%  (9.2/15)
setDefaultProps (): void 100% (1/1)68%  (26/38)72%  (7.2/10)
fillContextProperties (Context): void 100% (1/1)94%  (44/47)86%  (12/14)
shutdown (): void 100% (1/1)96%  (22/23)89%  (8/9)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
Generator (): void 100% (1/1)100% (15/15)100% (5/5)
fillContextDefaults (Context): void 100% (1/1)100% (12/12)100% (3/3)
getInstance (): Generator 100% (1/1)100% (2/2)100% (1/1)
getOutputPath (): String 100% (1/1)100% (5/5)100% (1/1)
getTemplatePath (): String 100% (1/1)100% (5/5)100% (1/1)
parse (String, Context): String 100% (1/1)100% (28/28)100% (7/7)
parse (String, String): String 100% (1/1)100% (7/7)100% (1/1)
parse (String, String, String, Object): String 100% (1/1)100% (9/9)100% (1/1)
setInputEncoding (String): void 100% (1/1)100% (4/4)100% (2/2)
setOutputEncoding (String): void 100% (1/1)100% (4/4)100% (2/2)
setOutputPath (String): void 100% (1/1)100% (7/7)100% (2/2)
setTemplatePath (String): void 100% (1/1)100% (7/7)100% (2/2)
setVelocityEngine (VelocityEngine): void 100% (1/1)100% (4/4)100% (2/2)

1package org.apache.velocity.texen;
2 
3/*
4 * Copyright 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.File;
20import java.io.InputStream;
21import java.io.FileInputStream;
22import java.io.BufferedInputStream;
23import java.io.Writer;
24import java.io.FileWriter;
25import java.io.StringWriter;
26import java.io.OutputStreamWriter;
27import java.io.BufferedWriter;
28import java.io.FileOutputStream;
29 
30import java.util.Enumeration;
31import java.util.Hashtable;
32import java.util.Iterator;
33import java.util.Properties;
34 
35import org.apache.velocity.Template;
36import org.apache.velocity.context.Context;
37import org.apache.velocity.VelocityContext;
38import org.apache.velocity.app.VelocityEngine;
39 
40/**
41 * A text/code generator class
42 *
43 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
44 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
45 * @version $Id: Generator.java,v 1.20.4.1 2004/03/03 23:23:07 geirm Exp $ 
46 */
47public class Generator
48{
49    /**
50     * Where the texen output will placed.
51     */
52    public static final String OUTPUT_PATH = "output.path";
53    
54    /**
55     * Where the velocity templates live.
56     */
57    public static final String TEMPLATE_PATH = "template.path";
58    
59    /**
60     * Default properties file used for controlling the
61     * tools placed in the context.
62     */
63    private static final String DEFAULT_TEXEN_PROPERTIES =
64        "org/apache/velocity/texen/defaults/texen.properties";
65 
66    /**
67     * Default properties used by texen.
68     */
69    private Properties props = new Properties();
70    
71    /**
72     * Context used for generating the texen output.
73     */
74    private Context controlContext;
75 
76    /**
77     * Keep track of the file writers used for outputting
78     * to files. If we come across a file writer more
79     * then once then the additional output will be
80     * appended to the file instead of overwritting
81     * the contents.
82     */
83    private Hashtable writers = new Hashtable();
84 
85    /**
86     * The generator tools used for creating additional
87     * output withing the control template. This could
88     * use some cleaning up.
89     */
90    private static Generator instance = new Generator();
91 
92    /**
93     * This is the encoding for the output file(s).
94     */
95    protected String outputEncoding;
96 
97    /**
98     * This is the encoding for the input file(s)
99     * (templates).
100     */
101    protected String inputEncoding;
102    
103    /**
104     * Velocity engine.
105     */
106    protected VelocityEngine ve;
107 
108    /**
109     * Default constructor.
110     */
111    private Generator()
112    {
113        setDefaultProps();
114    }
115 
116    /**
117     * Create a new generator object with default properties.
118     *
119     * @return Generator generator used in the control context.
120     */
121    public static Generator getInstance()
122    {
123        return instance;
124    }
125    
126    /**
127     * Set the velocity engine.
128     */
129    public void setVelocityEngine(VelocityEngine ve)
130    {
131        this.ve = ve;
132    }        
133 
134    /**
135     * Create a new generator object with properties loaded from
136     * a file.  If the file does not exist or any other exception
137     * occurs during the reading operation the default properties
138     * are used.
139     *
140     * @param String properties used to help populate the control context.
141     * @return Generator generator used in the control context.
142     */
143    public Generator (String propFile)
144    {
145        try
146        {
147            BufferedInputStream bi = null;
148            try
149            {
150                bi = new BufferedInputStream (new FileInputStream (propFile));
151                props.load (bi);
152            }
153            finally
154            {
155                if (bi != null)
156                {
157                    bi.close();
158                }
159            }
160        }
161        catch (Exception e)
162        {
163            /*
164             * If something goes wrong we use default properties
165             */
166            setDefaultProps();
167        }
168    }
169    
170    /**
171     * Create a new Generator object with a given property
172     * set. The property set will be duplicated.
173     *
174     * @param Properties properties object to help populate the control context.
175     */
176    public Generator (Properties props)
177    {
178        this.props = (Properties)props.clone();
179    }
180    
181    /**
182     * Set default properties.
183     */
184    protected void setDefaultProps()
185    {
186        ClassLoader classLoader = VelocityEngine.class.getClassLoader();
187        try
188        {
189            InputStream inputStream = null;
190            try
191            {
192                inputStream = classLoader.getResourceAsStream(
193                    DEFAULT_TEXEN_PROPERTIES);
194            
195                props.load( inputStream );
196            }
197            finally
198            {
199                if (inputStream != null)
200                {
201                    inputStream.close();
202                }
203            }
204        }
205        catch (Exception ioe)
206        {
207            System.err.println("Cannot get default properties!");
208        }
209    }
210    
211    /**
212     * Set the template path, where Texen will look
213     * for Velocity templates.
214     *
215     * @param String template path for velocity templates.
216     */
217    public void setTemplatePath(String templatePath)
218    {
219        props.put(TEMPLATE_PATH, templatePath);
220    }
221 
222    /**
223     * Get the template path.
224     *
225     * @return String template path for velocity templates.
226     */
227    public String getTemplatePath()
228    {
229        return props.getProperty(TEMPLATE_PATH);
230    }
231 
232    /**
233     * Set the output path for the generated
234     * output.
235     *
236     * @return String output path for texen output.
237     */
238    public void setOutputPath(String outputPath)
239    {
240        props.put(OUTPUT_PATH, outputPath);
241    }
242 
243    /**
244     * Get the output path for the generated
245     * output.
246     *
247     * @return String output path for texen output.
248     */
249    public String getOutputPath()
250    {
251        return props.getProperty(OUTPUT_PATH);
252    }
253 
254    /**
255     * Set the output encoding.
256     */
257    public void setOutputEncoding(String outputEncoding)
258    {
259        this.outputEncoding = outputEncoding;
260    }
261 
262    /**
263     * Set the input (template) encoding.
264     */
265    public void setInputEncoding(String inputEncoding)
266    {
267        this.inputEncoding = inputEncoding;
268    }
269 
270    /**
271     * Returns a writer, based on encoding and path.
272     *
273     * @param path      path to the output file
274     * @param encoding  output encoding
275     */
276    public Writer getWriter(String path, String encoding) throws Exception {
277        Writer writer;
278        if (encoding == null || encoding.length() == 0 || encoding.equals("8859-1") || encoding.equals("8859_1")) {
279            writer = new FileWriter(path);
280        }
281        else {
282            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), encoding));
283        }
284        return writer;
285    }
286 
287    /**
288     * Returns a template, based on encoding and path.
289     *
290     * @param templateName  name of the template
291     * @param encoding      template encoding
292     */
293    public Template getTemplate(String templateName, String encoding) throws Exception {
294        Template template;
295        if (encoding == null || encoding.length() == 0 || encoding.equals("8859-1") || encoding.equals("8859_1")) {
296            template = ve.getTemplate(templateName);
297        }
298        else {
299            template = ve.getTemplate(templateName, encoding);
300        }
301        return template;
302    }
303 
304    /**
305     * Parse an input and write the output to an output file.  If the
306     * output file parameter is null or an empty string the result is
307     * returned as a string object.  Otherwise an empty string is returned.
308     *
309     * @param String input template
310     * @param String output file
311     */ 
312    public String parse (String inputTemplate, String outputFile) 
313        throws Exception
314    {
315        return parse(inputTemplate, outputFile, null, null);
316    }
317    
318    /**
319     * Parse an input and write the output to an output file.  If the
320     * output file parameter is null or an empty string the result is
321     * returned as a string object.  Otherwise an empty string is returned.
322     * You can add objects to the context with the objs Hashtable.
323     *
324     * @param String input template
325     * @param String output file
326     * @param String id for object to be placed in the control context
327     * @param String object to be placed in the context
328     * @return String generated output from velocity
329     */
330    public String parse (String inputTemplate,
331                         String outputFile,
332                         String objectID,
333                         Object object)
334        throws Exception
335    {
336        return parse(inputTemplate, null, outputFile, null, objectID, object);
337    }
338    /**
339     * Parse an input and write the output to an output file.  If the
340     * output file parameter is null or an empty string the result is
341     * returned as a string object.  Otherwise an empty string is returned.
342     * You can add objects to the context with the objs Hashtable.
343     *
344     * @param String input template
345     * @param String inputEncoding template encoding
346     * @param String output file
347     * @param String outputEncoding encoding of output file
348     * @param String id for object to be placed in the control context
349     * @param String object to be placed in the context
350     * @return String generated output from velocity
351     */ 
352    public String parse (String inputTemplate, 
353                         String intputEncoding,
354                         String outputFile,
355                         String outputEncoding,
356                         String objectID,
357                         Object object)
358        throws Exception
359    {
360        if (objectID != null && object != null)
361        {
362            controlContext.put(objectID, object);
363        }            
364        
365        Template template = getTemplate(inputTemplate, inputEncoding != null ? inputEncoding : this.inputEncoding);
366        
367        if (outputFile == null || outputFile.equals(""))
368        {
369            StringWriter sw = new StringWriter();
370            template.merge (controlContext,sw);
371            return sw.toString();
372        }
373        else
374        {
375            Writer writer = null;
376            
377            if (writers.get(outputFile) == null)
378            {
379                /*
380                 * We have never seen this file before so create
381                 * a new file writer for it.
382                 */
383                writer = getWriter(
384                            getOutputPath() + File.separator + outputFile,
385                            outputEncoding != null ? outputEncoding : this.outputEncoding
386                         );
387                    
388                /*
389                 * Place the file writer in our collection
390                 * of file writers.
391                 */
392                writers.put(outputFile, writer);
393            }
394            else
395            {
396                writer = (Writer) writers.get(outputFile);
397            }                
398            
399            VelocityContext vc = new VelocityContext( controlContext );
400            template.merge (vc,writer);
401 
402            // commented because it is closed in shutdown();
403            //fw.close();
404            
405            return "";
406        }
407    }
408 
409    /**
410     * Parse the control template and merge it with the control
411     * context. This is the starting point in texen.
412     *
413     * @param String control template
414     * @param Context control context
415     * @return String generated output
416     */
417    public String parse (String controlTemplate, Context controlContext)
418        throws Exception
419    {
420        this.controlContext = controlContext;
421        fillContextDefaults(this.controlContext);
422        fillContextProperties(this.controlContext);
423 
424        Template template = getTemplate(controlTemplate, inputEncoding);
425        StringWriter sw = new StringWriter();
426        template.merge (controlContext,sw);
427        
428        return sw.toString();
429    }
430 
431 
432    /**
433     * Create a new context and fill it with the elements of the
434     * objs Hashtable.  Default objects and objects that comes from
435     * the properties of this Generator object is also added.
436     *
437     * @param Hashtable objects to place in the control context
438     * @return Context context filled with objects
439     */ 
440    protected Context getContext (Hashtable objs)
441    {
442        fillContextHash (controlContext,objs);
443        return controlContext;
444    }
445 
446    /** 
447     * Add all the contents of a Hashtable to the context.
448     *
449     * @param Context context to fill with objects
450     * @param Hashtable source of objects
451     */
452    protected void fillContextHash (Context context, Hashtable objs)
453    {
454        Enumeration enum = objs.keys();
455        while (enum.hasMoreElements())
456        {
457            String key = enum.nextElement().toString();
458            context.put (key, objs.get(key));
459        }
460    }
461 
462    /**
463     * Add properties that will aways be in the context by default
464     *
465     * @param Context control context to fill with default values.
466     */
467    protected void fillContextDefaults (Context context)
468    {
469        context.put ("generator", instance);
470        context.put ("outputDirectory", getOutputPath());
471    }
472    
473    /**
474     * Add objects to the context from the current properties.
475     *
476     * @param Context control context to fill with objects
477     *                that are specified in the default.properties
478     *                file
479     */
480    protected void fillContextProperties (Context context)
481    {
482        Enumeration enum = props.propertyNames();
483        
484        while (enum.hasMoreElements())
485        {
486            String nm = (String)enum.nextElement();
487            if (nm.startsWith ("context.objects."))
488            {
489                
490                String contextObj = props.getProperty (nm);
491                int colon = nm.lastIndexOf ('.');
492                String contextName = nm.substring (colon+1);
493                
494                try
495                {
496                    Class cls = Class.forName (contextObj);
497                    Object o = cls.newInstance();
498                    context.put (contextName,o);
499                }
500                catch (Exception e)
501                {
502                    e.printStackTrace();
503                    //TO DO: Log Something Here
504                }
505            }
506        }
507    }
508 
509    /**
510     * Properly shut down the generator, right now
511     * this is simply flushing and closing the file
512     * writers that we have been holding on to.
513     */
514    public void shutdown()
515    {
516        Iterator iterator = writers.values().iterator();
517        
518        while(iterator.hasNext())
519        {
520            Writer writer = (Writer) iterator.next();
521                        
522            try
523            {
524                writer.flush();
525                writer.close();
526            }
527            catch (Exception e)
528            {
529                /* do nothing */
530            }
531        }
532        // clear the file writers cache
533        writers.clear();
534    }
535}

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