All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.struts.tiles.TilesPlugin Maven / Gradle / Ivy

/*
 * $Id: TilesPlugin.java 471754 2006-11-06 14:55:09Z husted $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.struts.tiles;

import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.chain.ComposableRequestProcessor;
import org.apache.struts.config.ControllerConfig;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.PlugInConfig;
import org.apache.struts.util.RequestUtils;

/**
 * Tiles Plugin used to initialize Tiles.
 * This plugin is to be used with Struts 1.1 in association with
 * {@link TilesRequestProcessor}.
 * 
* This plugin creates one definition factory for each Struts-module. The definition factory * configuration is read first from 'web.xml' (backward compatibility), then it is * overloaded with values found in the plugin property values. *
* The plugin changes the Struts configuration by specifying a {@link TilesRequestProcessor} as * request processor. If you want to use your own RequestProcessor, * it should subclass TilesRequestProcessor. *
* This plugin can also be used to create one single factory for all modules. * This behavior is enabled by specifying moduleAware=false in each * plugin properties. In this case, the definition factory * configuration file is read by the first Tiles plugin to be initialized. The order is * determined by the order of modules declaration in web.xml. The first module * is always the default one if it exists. * The plugin should be declared in each struts-config.xml file in order to * properly initialize the request processor. * @since Struts 1.1 */ public class TilesPlugin implements PlugIn { /** * Commons Logging instance. */ protected static Log log = LogFactory.getLog(TilesPlugin.class); /** * Is the factory module aware? */ protected boolean moduleAware = false; /** * Tiles util implementation classname. This property can be set * by user in the plugin declaration. */ protected String tilesUtilImplClassname = null; /** * Associated definition factory. */ protected DefinitionsFactory definitionFactory = null; /** * The plugin config object provided by the ActionServlet initializing * this plugin. */ protected PlugInConfig currentPlugInConfigObject=null; /** * Get the module aware flag. * @return true: user wants a single factory instance, * false: user wants multiple factory instances (one per module with Struts) */ public boolean isModuleAware() { return moduleAware; } /** * Set the module aware flag. * This flag is only meaningful if the property tilesUtilImplClassname is not * set. * @param moduleAware true: user wants a single factory instance, * false: user wants multiple factory instances (one per module with Struts) */ public void setModuleAware(boolean moduleAware) { this.moduleAware = moduleAware; } /** *

Receive notification that the specified module is being * started up.

* * @param servlet ActionServlet that is managing all the modules * in this web application. * @param moduleConfig ModuleConfig for the module with which * this plugin is associated. * * @exception ServletException if this PlugIn cannot * be successfully initialized. */ public void init(ActionServlet servlet, ModuleConfig moduleConfig) throws ServletException { // Create factory config object DefinitionsFactoryConfig factoryConfig = readFactoryConfig(servlet, moduleConfig); // Set the module name in the config. This name will be used to compute // the name under which the factory is stored. factoryConfig.setFactoryName(moduleConfig.getPrefix()); // Set RequestProcessor class this.initRequestProcessorClass(moduleConfig); this.initTilesUtil(); this.initDefinitionsFactory(servlet.getServletContext(), moduleConfig, factoryConfig); } /** * Set TilesUtil implementation according to properties 'tilesUtilImplClassname' * and 'moduleAware'. These properties are taken into account only once. A * side effect is that only the values set in the first initialized plugin are * effectively taken into account. * @throws ServletException */ private void initTilesUtil() throws ServletException { if (TilesUtil.isTilesUtilImplSet()) { return; } // Check if user has specified a TilesUtil implementation classname or not. // If no implementation is specified, check if user has specified one // shared single factory for all module, or one factory for each module. if (this.getTilesUtilImplClassname() == null) { if (isModuleAware()) { TilesUtil.setTilesUtil(new TilesUtilStrutsModulesImpl()); } else { TilesUtil.setTilesUtil(new TilesUtilStrutsImpl()); } } else { // A classname is specified for the tilesUtilImp, use it. try { TilesUtilStrutsImpl impl = (TilesUtilStrutsImpl) RequestUtils .applicationClass(getTilesUtilImplClassname()) .newInstance(); TilesUtil.setTilesUtil(impl); } catch (ClassCastException ex) { throw new ServletException( "Can't set TilesUtil implementation to '" + getTilesUtilImplClassname() + "'. TilesUtil implementation should be a subclass of '" + TilesUtilStrutsImpl.class.getName() + "'"); } catch (Exception ex) { throw new ServletException( "Can't set TilesUtil implementation.", ex); } } } /** * Initialize the DefinitionsFactory this module will use. * @param servletContext * @param moduleConfig * @param factoryConfig * @throws ServletException */ private void initDefinitionsFactory( ServletContext servletContext, ModuleConfig moduleConfig, DefinitionsFactoryConfig factoryConfig) throws ServletException { // Check if a factory already exist for this module definitionFactory = ((TilesUtilStrutsImpl) TilesUtil.getTilesUtil()).getDefinitionsFactory( servletContext, moduleConfig); if (definitionFactory != null) { log.info( "Factory already exists for module '" + moduleConfig.getPrefix() + "'. The factory found is from module '" + definitionFactory.getConfig().getFactoryName() + "'. No new creation."); return; } // Create configurable factory try { definitionFactory = TilesUtil.createDefinitionsFactory( servletContext, factoryConfig); } catch (DefinitionsFactoryException ex) { log.error( "Can't create Tiles definition factory for module '" + moduleConfig.getPrefix() + "'."); throw new ServletException(ex); } log.info( "Tiles definition factory loaded for module '" + moduleConfig.getPrefix() + "'."); } /** * End plugin. */ public void destroy() { definitionFactory.destroy(); definitionFactory = null; } /** * Create FactoryConfig and initialize it from web.xml and struts-config.xml. * * @param servlet ActionServlet that is managing all the modules * in this web application. * @param config ModuleConfig for the module with which * this plugin is associated. * @exception ServletException if this PlugIn cannot * be successfully initialized. */ protected DefinitionsFactoryConfig readFactoryConfig( ActionServlet servlet, ModuleConfig config) throws ServletException { // Create tiles definitions config object DefinitionsFactoryConfig factoryConfig = new DefinitionsFactoryConfig(); // Get init parameters from web.xml files try { DefinitionsUtil.populateDefinitionsFactoryConfig( factoryConfig, servlet.getServletConfig()); } catch (Exception ex) { if (log.isDebugEnabled()){ log.debug("", ex); } ex.printStackTrace(); throw new UnavailableException( "Can't populate DefinitionsFactoryConfig class from 'web.xml': " + ex.getMessage()); } // Get init parameters from struts-config.xml try { Map strutsProperties = findStrutsPlugInConfigProperties(servlet, config); factoryConfig.populate(strutsProperties); } catch (Exception ex) { if (log.isDebugEnabled()) { log.debug("", ex); } throw new UnavailableException( "Can't populate DefinitionsFactoryConfig class from '" + config.getPrefix() + "/struts-config.xml':" + ex.getMessage()); } return factoryConfig; } /** * Find original properties set in the Struts PlugInConfig object. * First, we need to find the index of this plugin. Then we retrieve the array of configs * and then the object for this plugin. * @param servlet ActionServlet that is managing all the modules * in this web application. * @param config ModuleConfig for the module with which * this plug in is associated. * * @exception ServletException if this PlugIn cannot * be successfully initialized. */ protected Map findStrutsPlugInConfigProperties( ActionServlet servlet, ModuleConfig config) throws ServletException { return currentPlugInConfigObject.getProperties(); } /** * Set RequestProcessor to appropriate Tiles {@link RequestProcessor}. * First, check if a RequestProcessor is specified. If yes, check if it extends * the appropriate {@link TilesRequestProcessor} class. If not, set processor class to * TilesRequestProcessor. * * @param config ModuleConfig for the module with which * this plugin is associated. * @throws ServletException On errors. */ protected void initRequestProcessorClass(ModuleConfig config) throws ServletException { String tilesProcessorClassname = TilesRequestProcessor.class.getName(); ControllerConfig ctrlConfig = config.getControllerConfig(); String configProcessorClassname = ctrlConfig.getProcessorClass(); // Check if specified classname exist Class configProcessorClass; try { configProcessorClass = RequestUtils.applicationClass(configProcessorClassname); } catch (ClassNotFoundException ex) { log.fatal( "Can't set TilesRequestProcessor: bad class name '" + configProcessorClassname + "'."); throw new ServletException(ex); } // Check to see if request processor uses struts-chain. If so, // no need to replace the request processor. if (ComposableRequestProcessor.class.isAssignableFrom(configProcessorClass)) { return; } // Check if it is the default request processor or Tiles one. // If true, replace by Tiles' one. if (configProcessorClassname.equals(RequestProcessor.class.getName()) || configProcessorClassname.endsWith(tilesProcessorClassname)) { ctrlConfig.setProcessorClass(tilesProcessorClassname); return; } // Check if specified request processor is compatible with Tiles. Class tilesProcessorClass = TilesRequestProcessor.class; if (!tilesProcessorClass.isAssignableFrom(configProcessorClass)) { // Not compatible String msg = "TilesPlugin : Specified RequestProcessor not compatible with TilesRequestProcessor"; if (log.isFatalEnabled()) { log.fatal(msg); } throw new ServletException(msg); } } /** * Set Tiles util implemention classname. * If this property is set, the flag moduleAware will not be used anymore. * @param tilesUtilImplClassname Classname. */ public void setTilesUtilImplClassname(String tilesUtilImplClassname) { this.tilesUtilImplClassname = tilesUtilImplClassname; } /** * Get Tiles util implemention classname. * @return The classname or null if none is set. */ public String getTilesUtilImplClassname() { return tilesUtilImplClassname; } /** * Method used by the ActionServlet initializing this plugin. * Set the plugin config object read from module config. * @param plugInConfigObject PlugInConfig. */ public void setCurrentPlugInConfigObject(PlugInConfig plugInConfigObject) { this.currentPlugInConfigObject = plugInConfigObject; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy