001/* 002 * Copyright 2002-2014 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.tiles3; 018 019import java.util.Locale; 020import java.util.Map; 021import javax.servlet.http.HttpServletRequest; 022import javax.servlet.http.HttpServletResponse; 023 024import org.apache.tiles.TilesContainer; 025import org.apache.tiles.access.TilesAccess; 026import org.apache.tiles.renderer.DefinitionRenderer; 027import org.apache.tiles.request.AbstractRequest; 028import org.apache.tiles.request.ApplicationContext; 029import org.apache.tiles.request.Request; 030import org.apache.tiles.request.render.Renderer; 031import org.apache.tiles.request.servlet.ServletRequest; 032import org.apache.tiles.request.servlet.ServletUtil; 033 034import org.springframework.web.context.request.RequestAttributes; 035import org.springframework.web.context.request.RequestContextHolder; 036import org.springframework.web.context.request.ServletRequestAttributes; 037import org.springframework.web.servlet.support.JstlUtils; 038import org.springframework.web.servlet.support.RequestContext; 039import org.springframework.web.servlet.support.RequestContextUtils; 040import org.springframework.web.servlet.view.AbstractUrlBasedView; 041 042/** 043 * {@link org.springframework.web.servlet.View} implementation that renders 044 * through the Tiles Request API. The "url" property is interpreted as name of a 045 * Tiles definition. 046 * 047 * @author Nicolas Le Bas 048 * @author mick semb wever 049 * @author Rossen Stoyanchev 050 * @author Sebastien Deleuze 051 * @since 3.2 052 */ 053public class TilesView extends AbstractUrlBasedView { 054 055 private Renderer renderer; 056 057 private boolean exposeJstlAttributes = true; 058 059 private boolean alwaysInclude = false; 060 061 private ApplicationContext applicationContext; 062 063 064 /** 065 * Set the {@link Renderer} to use. 066 * If not set, by default {@link DefinitionRenderer} is used. 067 */ 068 public void setRenderer(Renderer renderer) { 069 this.renderer = renderer; 070 } 071 072 /** 073 * Whether to expose JSTL attributes. By default set to {@code true}. 074 * @see JstlUtils#exposeLocalizationContext(RequestContext) 075 */ 076 protected void setExposeJstlAttributes(boolean exposeJstlAttributes) { 077 this.exposeJstlAttributes = exposeJstlAttributes; 078 } 079 080 /** 081 * Specify whether to always include the view rather than forward to it. 082 * <p>Default is "false". Switch this flag on to enforce the use of a 083 * Servlet include, even if a forward would be possible. 084 * @since 4.1.2 085 * @see TilesViewResolver#setAlwaysInclude 086 */ 087 public void setAlwaysInclude(boolean alwaysInclude) { 088 this.alwaysInclude = alwaysInclude; 089 } 090 091 @Override 092 public void afterPropertiesSet() throws Exception { 093 super.afterPropertiesSet(); 094 095 this.applicationContext = ServletUtil.getApplicationContext(getServletContext()); 096 if (this.renderer == null) { 097 TilesContainer container = TilesAccess.getContainer(this.applicationContext); 098 this.renderer = new DefinitionRenderer(container); 099 } 100 } 101 102 103 @Override 104 public boolean checkResource(final Locale locale) throws Exception { 105 HttpServletRequest servletRequest = null; 106 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); 107 if (requestAttributes instanceof ServletRequestAttributes) { 108 servletRequest = ((ServletRequestAttributes) requestAttributes).getRequest(); 109 } 110 Request request = new ServletRequest(this.applicationContext, servletRequest, null) { 111 @Override 112 public Locale getRequestLocale() { 113 return locale; 114 } 115 }; 116 return this.renderer.isRenderable(getUrl(), request); 117 } 118 119 @Override 120 protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, 121 HttpServletResponse response) throws Exception { 122 123 exposeModelAsRequestAttributes(model, request); 124 if (this.exposeJstlAttributes) { 125 JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext())); 126 } 127 if (this.alwaysInclude) { 128 request.setAttribute(AbstractRequest.FORCE_INCLUDE_ATTRIBUTE_NAME, true); 129 } 130 131 Request tilesRequest = createTilesRequest(request, response); 132 this.renderer.render(getUrl(), tilesRequest); 133 } 134 135 /** 136 * Create a Tiles {@link Request}. 137 * <p>This implementation creates a {@link ServletRequest}. 138 * @param request the current request 139 * @param response the current response 140 * @return the Tiles request 141 */ 142 protected Request createTilesRequest(final HttpServletRequest request, HttpServletResponse response) { 143 return new ServletRequest(this.applicationContext, request, response) { 144 @Override 145 public Locale getRequestLocale() { 146 return RequestContextUtils.getLocale(request); 147 } 148 }; 149 } 150 151}