/*
* Created on Mar 19, 2003
*/
package net.sf.jportlet.service.velocity;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletConfig;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import net.sf.jportlet.impl.PortletRequestImpl;
import net.sf.jportlet.portlet.PortletRequest;
import net.sf.jportlet.portlet.PortletResponse;
import net.sf.jportlet.portlet.application.PortletProxy;
import net.sf.jportlet.service.PortletServiceAdapter;
import net.sf.jportlet.service.PortletServiceConfig;
import net.sf.jportlet.service.PortletServiceException;
/**
* Implementation of {@link net.sf.jportlet.service.velocity.VelocityService}
*
* @author <a href="mailto:tchbansi@sourceforge.net">Herve Tchepannou</a>
*/
public class VelocityServiceImpl
extends PortletServiceAdapter
implements VelocityService
{
//~ Instance fields --------------------------------------------------------
private VelocityEngine _engine;
//~ Methods ----------------------------------------------------------------
/**
* @see net.sf.jportlet.service.velocity.VelocityService#merge(java.lang.String, net.sf.jportlet.portlet.PortletRequest, net.sf.jportlet.portlet.PortletResponse)
*/
public void merge( String path,
PortletRequest request,
PortletResponse response )
throws PortletServiceException
{
merge( path, request, response, null );
}
/**
* @see net.sf.jportlet.service.velocity.VelocityService#merge(java.lang.String, net.sf.jportlet.portlet.PortletRequest, net.sf.jportlet.portlet.PortletResponse, java.util.Map)
*/
public void merge( String path,
PortletRequest request,
PortletResponse response,
Map context )
throws PortletServiceException
{
boolean debug = _log.isDebugEnabled( );
if ( debug )
{
_log.debug( "merge(" + path + ", context=" + context + ")" );
}
try
{
Context ctx = createContext( request, response, context );
Template template = _engine.getTemplate( path );
template.merge( ctx, response.getWriter( ) );
}
catch ( ParseErrorException p )
{
_log.error( "Unexpected error", p );
throw new PortletServiceException( "Error in the template", p );
}
catch ( ResourceNotFoundException r )
{
_log.error( "Unexpected error", r );
throw new PortletServiceException( "Template not found: " + path, r );
}
catch ( Exception e )
{
_log.error( "Unexpected error", e );
throw new PortletServiceException( e );
}
}
private Context createContext( PortletRequest request,
PortletResponse response,
Map context )
{
VelocityContext ctx = new VelocityContext( );
/* Inherited context */
if ( context != null )
{
putAll( context, ctx );
}
/* Request attributes */
PortletRequestImpl req = ( PortletRequestImpl ) request;
Map attributes = req.getAttributes( );
putAll( attributes, ctx );
/* Standard context variables */
PortletProxy proxy = req.getProxy( );
put( PROXY, proxy, ctx );
put( PORTLET, proxy.getPortlet( ), ctx );
put( REQUEST, request, ctx );
put( RESPONSE, response, ctx );
put( RUNTIME, new Runtime( ), ctx );
return ctx;
}
private void putAll( Map map,
Context ctx )
{
Iterator it = map.keySet( ).iterator( );
while ( it.hasNext( ) )
{
String name = ( String ) it.next( );
Object value = map.get( name );
put( name, value, ctx );
}
}
private void put( String name,
Object value,
Context ctx )
{
if ( value != null )
{
if ( _log.isDebugEnabled( ) )
{
_log.debug( "putting into VelocityContext: " + name + "=" + value );
}
ctx.put( name, value );
}
}
private Properties getProperties( ServletConfig servletConfig )
{
Properties props = new Properties( );
/* General */
props.put( Velocity.RESOURCE_LOADER, "file,class" );
/* Classpath resource loader */
props.put( "class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader" );
/* File resource loader */
props.put( Velocity.FILE_RESOURCE_LOADER_CACHE, "true" );
props.put( Velocity.FILE_RESOURCE_LOADER_PATH, servletConfig.getServletContext( ).getRealPath( "/" ) );
/* Logging */
props.put( Velocity.RUNTIME_LOG, "jportlet_velocity.log" );
props.put( "runtime.log.logsystem.log4j.category", VelocityEngine.class.getName( ) );
props.put( "resource.manager.logwhenfound", "false" );
/* Macros */
props.put( "velocimacro.library", "net/sf/jportlet/portlet/html/__macros.vm" );
return props;
}
/**
* @see net.sf.jportlet.service.PortletService#getServiceName()
*/
public String getServiceName( )
{
return VelocityService.NAME;
}
/**
* @see net.sf.jportlet.service.PortletService#init(net.sf.jportlet.service.PortletServiceConfig)
*/
public void init( PortletServiceConfig serviceConfig )
throws PortletServiceException
{
super.init( serviceConfig );
try
{
_engine = new VelocityEngine( );
_engine.init( getProperties( serviceConfig.getServletConfig( ) ) );
}
catch ( Exception e )
{
throw new PortletServiceException( e );
}
}
}