/* Copyright (c) 2003 eInnovation Inc. All rights reserved This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ /* * (c) Copyright 2001 MyCorporation. * All Rights Reserved. */ package com.openedit.generators; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.Writer; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.runtime.RuntimeConstants; import org.openedit.repository.filesystem.FileItem; import com.openedit.Generator; import com.openedit.OpenEditException; import com.openedit.OpenEditRuntimeException; import com.openedit.WebPageRequest; import com.openedit.error.ContentNotAvailableException; import com.openedit.page.Page; import com.openedit.servlet.OpenEditEngine; import com.openedit.util.OutputFiller; /** * This generator uses Velocity to process a template file, which (hopefully) uses the content on * the given page. * * @author Chris Burkey */ public class VelocityGenerator extends BaseGenerator implements Generator { public static Log log = LogFactory.getLog(VelocityGenerator.class); public File fieldRootDirectory; protected VelocityEngine fieldEngine; protected OpenEditEngine fieldOpenEditEngine; public VelocityGenerator() { } public void generate( WebPageRequest inContext, Page inPage, Output inOut ) throws OpenEditException { if( log.isDebugEnabled()) { log.debug( "Rendering " + inPage ); } if( !inPage.exists() ) //TODO: Create a new existed() method to speed up checks { String vir = inPage.get("virtual"); if ( !Boolean.parseBoolean(vir) ) { log.info("Missing: " +inPage.getPath()); try { inOut.getWriter().write("404: " + inPage.getPath()); return; } catch (IOException e) { throw new ContentNotAvailableException("Missing: " +inPage.getPath(),inPage.getPath()); } } else { return; //do nothing } } try { if ( inPage.isBinary() ) { //this should not happen InputStream in = inPage.getInputStream(); new OutputFiller().fill(in, inContext.getOutputStream()); return; } inContext.unpackageVariables(); //TODO: Remove this silliness VelocityContext context = new VelocityContext(inContext.getPageMap()); Writer writer = inOut.getWriter(); if ( inPage.getContentItem() instanceof FileItem) //Faster and does cache { String path = inPage.getContentItem().getPath(); //log.info( "Rendering " + inPage ); String filter = inPage.getProperty("oetextfilter"); if( filter != null ) { path = path + "?filter=" + filter + "&locale=" + inContext.getLocale(); } getEngine().mergeTemplate( path, inPage.getCharacterEncoding(),context, writer ); } else //do a string eval MUCH SLOWER { Reader in = inPage.getReader(); //log.info( "Eval " + inPage ); getEngine().evaluate(context, writer, inPage.getPath(), in); } writer.flush(); } catch (MethodInvocationException ex) { if (ex.getWrappedThrowable() instanceof ContentNotAvailableException) { throw new OpenEditException("Error generating " + inPage.getPath(), (OpenEditException)ex.getWrappedThrowable()); } if (ex.getWrappedThrowable() instanceof OpenEditException) { throw (OpenEditException) ex.getWrappedThrowable(); } Throwable wrapped = ex.getWrappedThrowable(); if( ignoreError( wrapped )) { //ignore return; } throw new OpenEditException(wrapped); } catch ( ParseErrorException pex ) { throw new OpenEditException(pex.getMessage() + " on " + inPage.getPath(),pex); } catch ( Exception ioex ) { if( ignoreError(ioex) ) { log.info("Browser canceled request"); return; } if (ioex instanceof OpenEditException) { throw (OpenEditException) ioex; } throw new OpenEditException(ioex); } } protected void init() { //Velocity.setProperty( "runtime.log.logsystem.class", getClass().getName() ); //RuntimeSingleton.init(); // initialize velocity /** * Load the Velocity properties file. If the argument given is null then no properties * will be used (i.e. the getVelocityProperties() methfod will return an empty Properties * object.) */ //Map velocityProperties = new HashMap(); Properties velocityProperties = new Properties(); velocityProperties.put(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "com.openedit.generators.VelocityLogger"); /* velocityProperties.put( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.SimpleLog4JLogSystem"); velocityProperties.put("runtime.log.logsystem.log4j.category", "syslog"); */ velocityProperties.put("resource.loader","file" ); //valid options might be file, class, jar velocityProperties.put("runtime.log.invalid.references", "false"); velocityProperties.put("resource.manager.logwhenfound", "false"); velocityProperties.put("file.resource.loader.cache", "true"); velocityProperties.put(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE, "300"); //89 is the default velocityProperties.put("file.resource.loader.modificationCheckInterval", "2"); // 2 seconds of cache velocityProperties.put("velocimacro.permissions.allow.inline", "true"); velocityProperties.put("velocimacro.permissions.allow.inline.to.replace.global", "true"); velocityProperties.put("velocimacro.context.localscope", "true"); velocityProperties.setProperty("file.resource.loader.path", getRootDirectory() .getAbsolutePath()); String vmpath = "/system/display/velocitymacros.vm"; File vm = new File(getRootDirectory(),vmpath); if( !vm.exists()) { vmpath = "/WEB-INF/base/system/display/velocitymacros.vm"; vm = new File(getRootDirectory(),vmpath); if(!vm.exists()) { vmpath = "/WEB-INF/base/openedit/display/velocitymacros.vm"; vm = new File(getRootDirectory(),vmpath); } } if(vm.exists()) { velocityProperties.put("velocimacro.library", vmpath); } velocityProperties.put("file.resource.loader.description","OpenEdit File Resource Loader" ); velocityProperties.put("file.resource.loader.class","com.openedit.generators.GeneratedResourceLoader"); // file.resource.loader.cache=true // file.resource.loader.modificationCheckInterval=60 // // # // # Class resource loader information // # // class.resource.loader.description=Velocity Classpath Resource Loader // class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader // class.resource.loader.cache=true // class.resource.loader.modificationCheckInterval=0 //Velocity had a bug that it required log4j unless you use the static instance. //getEngine().set(eprops); //fieldEngine = new VelocityEngine(velocityProperties); try { //velocityProperties.put("file.resource.loader.instance", getGeneratedResourceLoader()); getEngine().setApplicationAttribute("openEditEngine", getOpenEditEngine()); getEngine().init(velocityProperties); /* Class c = getEngine().getClass(); // get the reflected object Field field = c.getDeclaredField("rt"); field.setAccessible(true); RuntimeInstance rt = (RuntimeInstance)field.get(getEngine()); //Set resourceManager Class rtclass = rt.getClass(); Field rmfield = rtclass.getDeclaredField("resourceManager"); rmfield.setAccessible(true); rmfield.set(rt, getGeneratedResourceLoader()); */ } catch( Exception ex) { throw new OpenEditRuntimeException(ex); } } public File getRootDirectory() { return fieldRootDirectory; } public void setRootDirectory(File inRootDirectory) { fieldRootDirectory = inRootDirectory; } public VelocityEngine getEngine() { if( fieldEngine == null) { fieldEngine = new VelocityEngine(); init(); } return fieldEngine; } public void setEngine(VelocityEngine inEngine) { fieldEngine = inEngine; } public OpenEditEngine getOpenEditEngine() { return fieldOpenEditEngine; } public void setOpenEditEngine(OpenEditEngine inOpenEditEngine) { fieldOpenEditEngine = inOpenEditEngine; } }