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