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 }