1 /*
2 * $Id: TilesUtil.java 54929 2004-10-16 16:38:42Z germuska $
3 *
4 * Copyright 1999-2004 The Apache Software Foundation.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.struts.tiles;
20
21 import java.io.IOException;
22
23 import javax.servlet.ServletContext;
24 import javax.servlet.ServletException;
25 import javax.servlet.ServletRequest;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28 import javax.servlet.jsp.PageContext;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 /**
34 * Class containing utility methods for Tiles.
35 * Methods of this class are static and thereby accessible from anywhere.
36 * The underlying implementation can be changed with
37 * {@link #setTilesUtil(TilesUtilImpl)}.
38 * <br>
39 * Real implementation classes should derive from the {@link TilesUtilImpl} class.
40 * <br>
41 * Some methods are specified to throw the <code>UnsupportedOperationException</code>
42 * if the underlying implementation doesn't support the operation.
43 */
44 public class TilesUtil {
45
46 /** Commons Logging instance.*/
47 protected static Log log = LogFactory.getLog(TilesUtil.class);
48
49 /** The implementation of tilesUtilImpl */
50 protected static TilesUtilImpl tilesUtilImpl = new TilesUtilImpl();
51
52 /**
53 * Get the real implementation.
54 * @return The underlying implementation object.
55 */
56 static public TilesUtilImpl getTilesUtil() {
57 return tilesUtilImpl;
58 }
59
60 /**
61 * Set the real implementation.
62 * This method should be called only once.
63 * Successive calls have no effect.
64 * @param tilesUtil The implementaion.
65 */
66 static public void setTilesUtil(TilesUtilImpl tilesUtil) {
67 if (implAlreadySet) {
68 return;
69 }
70 tilesUtilImpl = tilesUtil;
71 implAlreadySet = true;
72 }
73
74 /**
75 * Getter to know if the underlying implementation is already set to another
76 * value than the default value.
77 * @return <code>true</code> if {@link #setTilesUtil} has already been called.
78 */
79 static boolean isTilesUtilImplSet() {
80 return implAlreadySet;
81 }
82
83 /** Flag to know if internal implementation has been set by the setter method */
84 private static boolean implAlreadySet = false;
85
86 /**
87 * Do a forward using request dispatcher.
88 *
89 * This method is used by the Tiles package anytime a forward is required.
90 * @param uri Uri or Definition name to forward.
91 * @param request Current page request.
92 * @param response Current page response.
93 * @param servletContext Current servlet context.
94 */
95 public static void doForward(
96 String uri,
97 HttpServletRequest request,
98 HttpServletResponse response,
99 ServletContext servletContext)
100 throws IOException, ServletException {
101
102 tilesUtilImpl.doForward(uri, request, response, servletContext);
103 }
104
105 /**
106 * Do an include using request dispatcher.
107 *
108 * This method is used by the Tiles package when an include is required.
109 * The Tiles package can use indifferently any form of this method.
110 * @param uri Uri or Definition name to forward.
111 * @param request Current page request.
112 * @param response Current page response.
113 * @param servletContext Current servlet context.
114 */
115 public static void doInclude(
116 String uri,
117 HttpServletRequest request,
118 HttpServletResponse response,
119 ServletContext servletContext)
120 throws IOException, ServletException {
121
122 tilesUtilImpl.doInclude(uri, request, response, servletContext);
123 }
124
125 /**
126 * Do an include using PageContext.include().
127 *
128 * This method is used by the Tiles package when an include is required.
129 * The Tiles package can use indifferently any form of this method.
130 * @param uri Uri or Definition name to forward.
131 * @param pageContext Current page context.
132 */
133 public static void doInclude(String uri, PageContext pageContext)
134 throws IOException, ServletException {
135 tilesUtilImpl.doInclude(uri, pageContext);
136 }
137
138 /**
139 * Get definition factory from appropriate servlet context.
140 * @return Definitions factory or <code>null</code> if not found.
141 */
142 public static DefinitionsFactory getDefinitionsFactory(
143 ServletRequest request,
144 ServletContext servletContext) {
145 return tilesUtilImpl.getDefinitionsFactory(request, servletContext);
146 }
147
148 /**
149 * Create Definition factory from specified configuration object.
150 * Create a ConfigurableDefinitionsFactory and initialize it with the configuration
151 * object. This later can contain the factory classname to use.
152 * Factory is made accessible from tags.
153 * <p>
154 * Fallback of several factory creation methods.
155 *
156 * @param servletContext Servlet Context passed to newly created factory.
157 * @param factoryConfig Configuration object passed to factory.
158 * @return newly created factory of type ConfigurableDefinitionsFactory.
159 * @throws DefinitionsFactoryException If an error occur while initializing factory
160 */
161 public static DefinitionsFactory createDefinitionsFactory(
162 ServletContext servletContext,
163 DefinitionsFactoryConfig factoryConfig)
164 throws DefinitionsFactoryException {
165 return tilesUtilImpl.createDefinitionsFactory(servletContext, factoryConfig);
166 }
167
168 /**
169 * Get a definition by its name.
170 * First, retrieve definition factory and then get requested definition.
171 * Throw appropriate exception if definition or definition factory is not found.
172 * @param definitionName Name of requested definition.
173 * @param request Current servelet request.
174 * @param servletContext current servlet context.
175 * @throws FactoryNotFoundException Can't find definition factory.
176 * @throws DefinitionsFactoryException General error in factory while getting definition.
177 * @throws NoSuchDefinitionException No definition found for specified name
178 */
179 public static ComponentDefinition getDefinition(
180 String definitionName,
181 ServletRequest request,
182 ServletContext servletContext)
183 throws FactoryNotFoundException, DefinitionsFactoryException {
184
185 try {
186 return getDefinitionsFactory(request, servletContext).getDefinition(
187 definitionName,
188 (HttpServletRequest) request,
189 servletContext);
190
191 } catch (NullPointerException ex) { // Factory not found in context
192 throw new FactoryNotFoundException("Can't get definitions factory from context.");
193 }
194 }
195
196 /**
197 * Reset internal state.
198 * This method is used by test suites to reset the class to its original state.
199 */
200 protected static void testReset() {
201 implAlreadySet = false;
202 tilesUtilImpl = new TilesUtilImpl();
203 }
204
205 }