001/* 002 * Copyright 2002-2010 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.view.velocity; 018 019import java.lang.reflect.Method; 020import java.util.Map; 021import javax.servlet.http.HttpServletRequest; 022import javax.servlet.http.HttpServletResponse; 023 024import org.apache.velocity.VelocityContext; 025import org.apache.velocity.context.Context; 026 027import org.springframework.util.ClassUtils; 028import org.springframework.util.ReflectionUtils; 029 030/** 031 * {@link VelocityView} subclass which adds support for Velocity Tools toolboxes 032 * and Velocity Tools ViewTool callbacks / Velocity Tools 1.3 init methods. 033 * 034 * <p>Specify a "toolboxConfigLocation", for example "/WEB-INF/toolbox.xml", 035 * to automatically load a Velocity Tools toolbox definition file and expose 036 * all defined tools in the specified scopes. If no config location is 037 * specified, no toolbox will be loaded and exposed. 038 * 039 * <p>This view will always create a special Velocity context, namely an 040 * instance of the ChainedContext class which is part of the view package 041 * of Velocity tools. This allows to use tools from the view package of 042 * Velocity Tools, like LinkTool, which need to be initialized with a special 043 * context that implements the ViewContext interface (i.e. a ChainedContext). 044 * 045 * <p>This view also checks tools that are specified as "toolAttributes": 046 * If they implement the ViewTool interface, they will get initialized with 047 * the Velocity context. This allows tools from the view package of Velocity 048 * Tools, such as LinkTool, to be defined as 049 * {@link #setToolAttributes "toolAttributes"} on a VelocityToolboxView, 050 * instead of in a separate toolbox XML file. 051 * 052 * <p>This is a separate class mainly to avoid a required dependency on 053 * the view package of Velocity Tools in {@link VelocityView} itself. 054 * As of Spring 3.0, this class requires Velocity Tools 1.3 or higher. 055 * 056 * @author Juergen Hoeller 057 * @since 1.1.3 058 * @see #setToolboxConfigLocation 059 * @see #initTool 060 * @see org.apache.velocity.tools.view.context.ViewContext 061 * @see org.apache.velocity.tools.view.context.ChainedContext 062 * @deprecated as of Spring 4.3, in favor of FreeMarker 063 */ 064@Deprecated 065public class VelocityToolboxView extends VelocityView { 066 067 private String toolboxConfigLocation; 068 069 070 /** 071 * Set a Velocity Toolbox config location, for example "/WEB-INF/toolbox.xml", 072 * to automatically load a Velocity Tools toolbox definition file and expose 073 * all defined tools in the specified scopes. If no config location is 074 * specified, no toolbox will be loaded and exposed. 075 * <p>The specified location string needs to refer to a ServletContext 076 * resource, as expected by ServletToolboxManager which is part of 077 * the view package of Velocity Tools. 078 * @see org.apache.velocity.tools.view.servlet.ServletToolboxManager#getInstance 079 */ 080 public void setToolboxConfigLocation(String toolboxConfigLocation) { 081 this.toolboxConfigLocation = toolboxConfigLocation; 082 } 083 084 /** 085 * Return the Velocity Toolbox config location, if any. 086 */ 087 protected String getToolboxConfigLocation() { 088 return this.toolboxConfigLocation; 089 } 090 091 092 /** 093 * Overridden to create a ChainedContext, which is part of the view package 094 * of Velocity Tools, as special context. ChainedContext is needed for 095 * initialization of ViewTool instances. 096 * @see #initTool 097 */ 098 @Override 099 @SuppressWarnings({ "rawtypes", "unchecked" }) 100 protected Context createVelocityContext( 101 Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { 102 103 // Create a ChainedContext instance. 104 org.apache.velocity.tools.view.context.ChainedContext velocityContext = 105 new org.apache.velocity.tools.view.context.ChainedContext( 106 new VelocityContext(model), getVelocityEngine(), request, response, getServletContext()); 107 108 // Load a Velocity Tools toolbox, if necessary. 109 if (getToolboxConfigLocation() != null) { 110 org.apache.velocity.tools.view.ToolboxManager toolboxManager = 111 org.apache.velocity.tools.view.servlet.ServletToolboxManager.getInstance( 112 getServletContext(), getToolboxConfigLocation()); 113 Map toolboxContext = toolboxManager.getToolbox(velocityContext); 114 velocityContext.setToolbox(toolboxContext); 115 } 116 117 return velocityContext; 118 } 119 120 /** 121 * Overridden to check for the ViewContext interface which is part of the 122 * view package of Velocity Tools. This requires a special Velocity context, 123 * like ChainedContext as set up by {@link #createVelocityContext} in this class. 124 */ 125 @Override 126 protected void initTool(Object tool, Context velocityContext) throws Exception { 127 // Velocity Tools 1.3: a class-level "init(Object)" method. 128 Method initMethod = ClassUtils.getMethodIfAvailable(tool.getClass(), "init", Object.class); 129 if (initMethod != null) { 130 ReflectionUtils.invokeMethod(initMethod, tool, velocityContext); 131 } 132 } 133 134}