001    /*
002     * Jpkg - Java library and tools for operating system package creation.
003     *
004     * Copyright (c) 2007 Three Rings Design, Inc.
005     * All rights reserved.
006     *
007     * Redistribution and use in source and binary forms, with or without
008     * modification, are permitted provided that the following conditions
009     * are met:
010     * 1. Redistributions of source code must retain the above copyright
011     *    notice, this list of conditions and the following disclaimer.
012     * 2. Redistributions in binary form must reproduce the above copyright
013     *    notice, this list of conditions and the following disclaimer in the
014     *    documentation and/or other materials provided with the distribution.
015     * 3. Neither the name of the copyright owner nor the names of contributors
016     *    may be used to endorse or promote products derived from this software
017     *    without specific prior written permission.
018     *
019     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
023     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
024     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
025     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
026     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
027     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
029     * POSSIBILITY OF SUCH DAMAGE.
030     */
031    package com.threerings.jpkg.ant;
032    
033    import java.io.Writer;
034    
035    import org.apache.velocity.VelocityContext;
036    import org.apache.velocity.app.VelocityEngine;
037    import org.apache.velocity.exception.MethodInvocationException;
038    import org.apache.velocity.exception.ParseErrorException;
039    import org.apache.velocity.exception.ResourceNotFoundException;
040    import org.apache.velocity.runtime.RuntimeConstants;
041    import org.apache.velocity.runtime.RuntimeServices;
042    import org.apache.velocity.runtime.log.LogChute;
043    import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
044    
045    /**
046     * A helper class to generate silent velocity engines and work with {@link VelocityTemplate} classes.
047     */
048    public class VelocityHelper
049    {
050        /**
051         * A null logger for Velocity.
052         */
053        private static final LogChute _nullLogger = new LogChute() {
054            public void init (RuntimeServices rs) throws Exception {}
055            public void log (int level, String message) {}
056            public void log (int level, String message, Throwable t) {}
057            public boolean isLevelEnabled (int level)
058            {
059                return false;
060            }
061        };
062    
063        /** The quieted engine. */
064        private static final VelocityEngine _engine;
065    
066        /**
067         * Initialize the static engine to be quiet.
068         */
069        static
070        {
071            _engine = new VelocityEngine();
072            _engine.setProperty(RuntimeConstants.VM_LIBRARY, "");
073            _engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
074            _engine.setProperty("classpath." + RuntimeConstants.RESOURCE_LOADER + ".class",
075                ClasspathResourceLoader.class.getName());
076            _engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, _nullLogger);
077    
078            try {
079                _engine.init();
080            } catch (final Exception e) {
081                throw new RuntimeException("Failed to initialize Velocity engine", e);
082            }
083        }
084    
085        /**
086         * Merge the supplied {@link VelocityTemplate}, performing all substitutions defined, into
087         * the supplied {@link Writer}.
088         * @param template The {@link VelocityTemplate} to merge.
089         * @param writer The {@link Writer} to write the merged template to.
090         * @throws MethodInvocationException If the merge fails.
091         * @throws ParseErrorException If the template is invalid.
092         * @throws ResourceNotFoundException If the template could not be found in the classpath.
093         * @throws Exception If any other failure occurs constructing the merging the template.
094         */
095        public static void mergeTemplate (VelocityTemplate template, Writer writer)
096            throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, Exception
097        {
098            final VelocityContext context = new VelocityContext();
099            template.populateContext(context);
100    
101            _engine.getTemplate(template.getTemplateName()).merge(context, writer);
102        }
103    }