001package org.apache.turbine.modules.screens; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.commons.lang3.StringUtils; 023import org.apache.commons.lang3.exception.ExceptionUtils; 024import org.apache.turbine.TurbineConstants; 025import org.apache.turbine.annotation.TurbineConfiguration; 026import org.apache.turbine.annotation.TurbineService; 027import org.apache.turbine.pipeline.PipelineData; 028import org.apache.turbine.services.template.TemplateService; 029import org.apache.turbine.services.velocity.VelocityService; 030import org.apache.turbine.util.RunData; 031import org.apache.velocity.context.Context; 032 033/** 034 * Base Velocity Screen. The buildTemplate() assumes the template 035 * parameter has been set in the PipelineData object. This provides the 036 * ability to execute several templates from one Screen. 037 * 038 * <p> 039 * 040 * If you need more specific behavior in your application, extend this 041 * class and override the doBuildTemplate() method. 042 * 043 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> 044 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 045 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> 046 * @version $Id$ 047 */ 048public class VelocityScreen 049 extends TemplateScreen 050{ 051 /** The prefix for lookup up screen pages */ 052 protected static final String prefix = PREFIX + "/"; 053 054 /** Injected service instance */ 055 @TurbineService 056 protected VelocityService velocity; 057 058 /** Injected service instance */ 059 @TurbineService 060 protected TemplateService templateService; 061 062 @TurbineConfiguration( TurbineConstants.TEMPLATE_ERROR_KEY ) 063 protected String templateError = TurbineConstants.TEMPLATE_ERROR_VM; 064 065 /** 066 * Velocity Screens extending this class should override this 067 * method to perform any particular business logic and add 068 * information to the context. 069 * 070 * @param pipelineData Turbine information. 071 * @param context Context for web pages. 072 * @throws Exception a generic exception. 073 */ 074 protected void doBuildTemplate(PipelineData pipelineData, 075 Context context) 076 throws Exception 077 { 078 // empty 079 } 080 081 /** 082 * Needs to be implemented to make TemplateScreen like us. The 083 * actual method that you should override is the one with the 084 * context in the parameter list. 085 * 086 * @param pipelineData Turbine information. 087 * @throws Exception a generic exception. 088 */ 089 @Override 090 protected void doBuildTemplate(PipelineData pipelineData) 091 throws Exception 092 { 093 doBuildTemplate(pipelineData, velocity.getContext(pipelineData)); 094 } 095 096 /** 097 * This builds the Velocity template. 098 * 099 * @param pipelineData Turbine information. 100 * @return the content of the screen 101 * @throws Exception a generic exception. 102 */ 103 @Override 104 public String buildTemplate(PipelineData pipelineData) 105 throws Exception 106 { 107 RunData data = pipelineData.getRunData(); 108 String screenData = null; 109 110 Context context = velocity.getContext(pipelineData); 111 112 String screenTemplate = data.getTemplateInfo().getScreenTemplate(); 113 String templateName 114 = templateService.getScreenTemplateName(screenTemplate); 115 116 // The Template Service could not find the Screen 117 if (StringUtils.isEmpty(templateName)) 118 { 119 log.error("Screen " + screenTemplate + " not found!"); 120 throw new Exception("Could not find screen for " + screenTemplate); 121 } 122 123 try 124 { 125 // if a layout has been defined return the results, otherwise 126 // send the results directly to the output stream. 127 if (getLayout(pipelineData) == null) 128 { 129 velocity.handleRequest(context, 130 prefix + templateName, 131 data.getResponse().getOutputStream()); 132 } 133 else 134 { 135 screenData = 136 velocity.handleRequest(context, prefix + templateName); 137 } 138 } 139 catch (Exception e) 140 { 141 // If there is an error, build a $processingException and 142 // attempt to call the error.vm template in the screens 143 // directory. 144 context.put (TurbineConstants.PROCESSING_EXCEPTION_PLACEHOLDER, e.toString()); 145 context.put (TurbineConstants.STACK_TRACE_PLACEHOLDER, ExceptionUtils.getStackTrace(e)); 146 147 screenData = velocity.handleRequest(context, prefix + templateError); 148 } 149 150 return screenData; 151 } 152}