View Javadoc

1   /*
2    * $Id: TilesUtil.java 421151 2006-07-12 06:07:14Z wsmoak $
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         doInclude(uri, pageContext, true);
136     }
137 
138     /***
139      * Do an include using PageContext.include().
140      *
141      * This method is used by the Tiles package when an include is required.
142      * The Tiles package can use indifferently any form of this method.
143      * @param uri Uri or Definition name to forward.
144      * @param flush If the writer should be flushed before the include
145      * @param pageContext Current page context.
146      */
147     public static void doInclude(String uri, PageContext pageContext, boolean flush)
148         throws IOException, ServletException {
149         tilesUtilImpl.doInclude(uri, pageContext, flush);
150     }
151 
152     /***
153      * Get definition factory from appropriate servlet context.
154      * @return Definitions factory or <code>null</code> if not found.
155      */
156     public static DefinitionsFactory getDefinitionsFactory(
157         ServletRequest request,
158         ServletContext servletContext) {
159         return tilesUtilImpl.getDefinitionsFactory(request, servletContext);
160     }
161 
162     /***
163      * Create Definition factory from specified configuration object.
164      * Create a ConfigurableDefinitionsFactory and initialize it with the configuration
165      * object. This later can contain the factory classname to use.
166      * Factory is made accessible from tags.
167      * <p>
168      * Fallback of several factory creation methods.
169      *
170      * @param servletContext Servlet Context passed to newly created factory.
171      * @param factoryConfig Configuration object passed to factory.
172      * @return newly created factory of type ConfigurableDefinitionsFactory.
173      * @throws DefinitionsFactoryException If an error occur while initializing factory
174      */
175     public static DefinitionsFactory createDefinitionsFactory(
176         ServletContext servletContext,
177         DefinitionsFactoryConfig factoryConfig)
178         throws DefinitionsFactoryException {
179         return tilesUtilImpl.createDefinitionsFactory(servletContext, factoryConfig);
180     }
181 
182     /***
183      * Get a definition by its name.
184      * First, retrieve definition factory and then get requested definition.
185      * Throw appropriate exception if definition or definition factory is not found.
186      * @param definitionName Name of requested definition.
187      * @param request Current servelet request.
188      * @param servletContext current servlet context.
189      * @throws FactoryNotFoundException Can't find definition factory.
190      * @throws DefinitionsFactoryException General error in factory while getting definition.
191      * @throws NoSuchDefinitionException No definition found for specified name
192      */
193     public static ComponentDefinition getDefinition(
194         String definitionName,
195         ServletRequest request,
196         ServletContext servletContext)
197         throws FactoryNotFoundException, DefinitionsFactoryException {
198 
199         try {
200             return getDefinitionsFactory(request, servletContext).getDefinition(
201                 definitionName,
202                 (HttpServletRequest) request,
203                 servletContext);
204 
205         } catch (NullPointerException ex) { // Factory not found in context
206             throw new FactoryNotFoundException("Can't get definitions factory from context.");
207         }
208     }
209 
210     /***
211      * Reset internal state.
212      * This method is used by test suites to reset the class to its original state.
213      */
214     protected static void testReset() {
215         implAlreadySet = false;
216         tilesUtilImpl = new TilesUtilImpl();
217     }
218 
219 }