1 /* 2 * $Id$ 3 * 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 package org.apache.struts.tiles2.commands; 22 23 import org.apache.commons.chain.Command; 24 import org.apache.struts.chain.contexts.ServletActionContext; 25 import org.apache.struts.config.ForwardConfig; 26 import org.apache.tiles.TilesContainer; 27 import org.apache.tiles.access.TilesAccess; 28 import org.apache.tiles.request.ApplicationContext; 29 import org.apache.tiles.request.Request; 30 import org.apache.tiles.request.jakarta.servlet.ServletRequest; 31 import org.apache.tiles.request.jakarta.servlet.ServletUtil; 32 import org.slf4j.Logger; 33 import org.slf4j.LoggerFactory; 34 35 /** 36 * Command class intended to perform responsibilities of the 37 * TilesRequestProcessor in Struts 1.1. Does not actually dispatch requests, 38 * but simply prepares the chain context for a later forward as appropriate. 39 * Should be added to a chain before something which would handle a 40 * conventional ForwardConfig. 41 * 42 * <p>This class will never have any effect on the chain unless a 43 * {@code TilesDefinitionFactory} can be found; however it does not consider 44 * the absence of a definition factory to be a fatal error; the command simply 45 * returns false and lets the chain continue.</p> 46 * 47 * <p>To initialize the {@code TilesDefinitionFactory}, use 48 * {@code org.apache.struts.chain.commands.legacy.TilesPlugin}. This class is a 49 * simple extension to {@code org.apache.struts.tiles2.TilesPlugin} which 50 * simply does not interfere with your choice of {@code RequestProcessor} 51 * implementation.</p> 52 */ 53 public class TilesPreProcessor implements Command<ServletActionContext> { 54 55 56 // ------------------------------------------------------ Instance Variables 57 58 59 /** 60 * The {@code Log} instance for this class. 61 */ 62 private final Logger log = 63 LoggerFactory.getLogger(TilesPreProcessor.class); 64 65 // ---------------------------------------------------------- Public Methods 66 67 68 /** 69 * If the current {@code ForwardConfig} is using "tiles", perform necessary 70 * pre-processing to set up the {@code TilesContext} and substitute a new 71 * {@code ForwardConfig} which is understandable to a 72 * {@code RequestDispatcher}. 73 * 74 * <p>Note that if the command finds a previously existing 75 * {@code AttributeContext} in the request, then it infers that it has been 76 * called from within another tile, so instead of changing the 77 * {@code ForwardConfig} in the chain {@code Context}, the command uses 78 * {@code RequestDispatcher} to <em>include</em> the tile, and returns 79 * true, indicating that the processing chain is complete.</p> 80 * 81 * @param sacontext The {@code Context} for the current request 82 * 83 * @throws Exception If something goes wrong. 84 * 85 * @return {@code false} in most cases, but true if we determine 86 * that we're processing in "include" mode. 87 */ 88 public boolean execute(ServletActionContext sacontext) throws Exception { 89 90 // Is there a Tiles Definition to be processed? 91 ForwardConfig forwardConfig = sacontext.getForwardConfig(); 92 if (forwardConfig == null || forwardConfig.getPath() == null) { 93 // this is not a serious error, so log at low priority 94 log.debug("No forwardConfig or no path, so pass to next command."); 95 return (false); 96 } 97 98 99 ApplicationContext applicationContext = ServletUtil 100 .getApplicationContext(sacontext.getContext()); 101 Request request = new ServletRequest(applicationContext, 102 sacontext.getRequest(), sacontext.getResponse()); 103 TilesContainer container = TilesAccess.getContainer(applicationContext); 104 if (container == null) { 105 log.debug("Tiles container not found, so pass to next command."); 106 return false; 107 } 108 109 if (container.isValidDefinition(forwardConfig.getPath(), request)) { 110 container.render(forwardConfig.getPath(), request); 111 sacontext.setForwardConfig(null); 112 } else { 113 // ignore not found 114 log.debug("Cannot find definition '{}'", forwardConfig.getPath()); 115 } 116 117 return false; 118 } 119 }