001: /*
002: * $Id: TilesUtil.java 471754 2006-11-06 14:55:09Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: package org.apache.struts.tiles;
023:
024: import java.io.IOException;
025:
026: import javax.servlet.ServletContext;
027: import javax.servlet.ServletException;
028: import javax.servlet.ServletRequest;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031: import javax.servlet.jsp.PageContext;
032:
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035:
036: /**
037: * Class containing utility methods for Tiles.
038: * Methods of this class are static and thereby accessible from anywhere.
039: * The underlying implementation can be changed with
040: * {@link #setTilesUtil(TilesUtilImpl)}.
041: * <br>
042: * Real implementation classes should derive from the {@link TilesUtilImpl} class.
043: * <br>
044: * Some methods are specified to throw the <code>UnsupportedOperationException</code>
045: * if the underlying implementation doesn't support the operation.
046: */
047: public class TilesUtil {
048:
049: /** Commons Logging instance.*/
050: protected static Log log = LogFactory.getLog(TilesUtil.class);
051:
052: /** The implementation of tilesUtilImpl */
053: protected static TilesUtilImpl tilesUtilImpl = new TilesUtilImpl();
054:
055: /**
056: * Get the real implementation.
057: * @return The underlying implementation object.
058: */
059: static public TilesUtilImpl getTilesUtil() {
060: return tilesUtilImpl;
061: }
062:
063: /**
064: * Set the real implementation.
065: * This method should be called only once.
066: * Successive calls have no effect.
067: * @param tilesUtil The implementaion.
068: */
069: static public void setTilesUtil(TilesUtilImpl tilesUtil) {
070: if (implAlreadySet) {
071: return;
072: }
073: tilesUtilImpl = tilesUtil;
074: implAlreadySet = true;
075: }
076:
077: /**
078: * Getter to know if the underlying implementation is already set to another
079: * value than the default value.
080: * @return <code>true</code> if {@link #setTilesUtil} has already been called.
081: */
082: static boolean isTilesUtilImplSet() {
083: return implAlreadySet;
084: }
085:
086: /** Flag to know if internal implementation has been set by the setter method */
087: private static boolean implAlreadySet = false;
088:
089: /**
090: * Do a forward using request dispatcher.
091: *
092: * This method is used by the Tiles package anytime a forward is required.
093: * @param uri Uri or Definition name to forward.
094: * @param request Current page request.
095: * @param response Current page response.
096: * @param servletContext Current servlet context.
097: */
098: public static void doForward(String uri,
099: HttpServletRequest request, HttpServletResponse response,
100: ServletContext servletContext) throws IOException,
101: ServletException {
102:
103: tilesUtilImpl.doForward(uri, request, response, servletContext);
104: }
105:
106: /**
107: * Do an include using request dispatcher.
108: *
109: * This method is used by the Tiles package when an include is required.
110: * The Tiles package can use indifferently any form of this method.
111: * @param uri Uri or Definition name to forward.
112: * @param request Current page request.
113: * @param response Current page response.
114: * @param servletContext Current servlet context.
115: */
116: public static void doInclude(String uri,
117: HttpServletRequest request, HttpServletResponse response,
118: ServletContext servletContext) throws IOException,
119: ServletException {
120:
121: tilesUtilImpl.doInclude(uri, request, response, servletContext);
122: }
123:
124: /**
125: * Do an include using PageContext.include().
126: *
127: * This method is used by the Tiles package when an include is required.
128: * The Tiles package can use indifferently any form of this method.
129: * @param uri Uri or Definition name to forward.
130: * @param pageContext Current page context.
131: */
132: public static void doInclude(String uri, PageContext pageContext)
133: throws IOException, ServletException {
134: doInclude(uri, pageContext, true);
135: }
136:
137: /**
138: * Do an include using PageContext.include().
139: *
140: * This method is used by the Tiles package when an include is required.
141: * The Tiles package can use indifferently any form of this method.
142: * @param uri Uri or Definition name to forward.
143: * @param flush If the writer should be flushed before the include
144: * @param pageContext Current page context.
145: */
146: public static void doInclude(String uri, PageContext pageContext,
147: boolean flush) throws IOException, ServletException {
148: tilesUtilImpl.doInclude(uri, pageContext, flush);
149: }
150:
151: /**
152: * Get definition factory from appropriate servlet context.
153: * @return Definitions factory or <code>null</code> if not found.
154: */
155: public static DefinitionsFactory getDefinitionsFactory(
156: ServletRequest request, ServletContext servletContext) {
157: return tilesUtilImpl.getDefinitionsFactory(request,
158: servletContext);
159: }
160:
161: /**
162: * Create Definition factory from specified configuration object.
163: * Create a ConfigurableDefinitionsFactory and initialize it with the configuration
164: * object. This later can contain the factory classname to use.
165: * Factory is made accessible from tags.
166: * <p>
167: * Fallback of several factory creation methods.
168: *
169: * @param servletContext Servlet Context passed to newly created factory.
170: * @param factoryConfig Configuration object passed to factory.
171: * @return newly created factory of type ConfigurableDefinitionsFactory.
172: * @throws DefinitionsFactoryException If an error occur while initializing factory
173: */
174: public static DefinitionsFactory createDefinitionsFactory(
175: ServletContext servletContext,
176: DefinitionsFactoryConfig factoryConfig)
177: throws DefinitionsFactoryException {
178: return tilesUtilImpl.createDefinitionsFactory(servletContext,
179: 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, ServletRequest request,
195: ServletContext servletContext)
196: throws FactoryNotFoundException,
197: DefinitionsFactoryException {
198:
199: try {
200: return getDefinitionsFactory(request, servletContext)
201: .getDefinition(definitionName,
202: (HttpServletRequest) request,
203: servletContext);
204:
205: } catch (NullPointerException ex) { // Factory not found in context
206: throw new FactoryNotFoundException(
207: "Can't get definitions factory from context.");
208: }
209: }
210:
211: /**
212: * Reset internal state.
213: * This method is used by test suites to reset the class to its original state.
214: */
215: protected static void testReset() {
216: implAlreadySet = false;
217: tilesUtilImpl = new TilesUtilImpl();
218: }
219:
220: }
|