Save This Page
Home » xwork-2.1.5 » com.opensymphony » xwork2 » [javadoc | source]
    1   /*
    2    * Copyright (c) 2002-2006 by OpenSymphony
    3    * All rights reserved.
    4    */
    5   package com.opensymphony.xwork2;
    6   
    7   import com.opensymphony.xwork2.config.ConfigurationException;
    8   import com.opensymphony.xwork2.config.entities.ActionConfig;
    9   import com.opensymphony.xwork2.config.entities.InterceptorConfig;
   10   import com.opensymphony.xwork2.config.entities.ResultConfig;
   11   import com.opensymphony.xwork2.inject.Container;
   12   import com.opensymphony.xwork2.inject.Inject;
   13   import com.opensymphony.xwork2.interceptor.Interceptor;
   14   import com.opensymphony.xwork2.util.ClassLoaderUtil;
   15   import com.opensymphony.xwork2.util.logging.Logger;
   16   import com.opensymphony.xwork2.util.logging.LoggerFactory;
   17   import com.opensymphony.xwork2.util.reflection.ReflectionException;
   18   import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler;
   19   import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
   20   import com.opensymphony.xwork2.validator.Validator;
   21   
   22   import java.io.Serializable;
   23   import java.util.HashMap;
   24   import java.util.Map;
   25   
   26   
   27   /**
   28    * ObjectFactory is responsible for building the core framework objects. Users may register their 
   29    * own implementation of the ObjectFactory to control instantiation of these Objects.
   30    * <p/>
   31    * This default implementation uses the {@link #buildBean(Class,java.util.Map) buildBean} 
   32    * method to create all classes (interceptors, actions, results, etc).
   33    * <p/>
   34    *
   35    * @author Jason Carreira
   36    */
   37   public class ObjectFactory implements Serializable {
   38       private static final Logger LOG = LoggerFactory.getLogger(ObjectFactory.class);
   39   
   40       private transient ClassLoader ccl;
   41       private Container container;
   42       protected ReflectionProvider reflectionProvider;
   43   
   44       @Inject(value="objectFactory.classloader", required=false)
   45       public void setClassLoader(ClassLoader cl) {
   46           this.ccl = cl;
   47       }
   48       
   49       @Inject
   50       public void setReflectionProvider(ReflectionProvider prov) {
   51           this.reflectionProvider = prov;
   52       }
   53   
   54       public ObjectFactory() {
   55       }
   56       
   57       public ObjectFactory(ReflectionProvider prov) {
   58           this.reflectionProvider = prov;
   59       }
   60       
   61       @Inject
   62       public void setContainer(Container container) {
   63           this.container = container;
   64       }
   65   
   66       /**
   67        * @deprecated Since 2.1
   68        */
   69       @Deprecated public static ObjectFactory getObjectFactory() {
   70           return ActionContext.getContext().getContainer().getInstance(ObjectFactory.class);
   71       }
   72   
   73       /**
   74        * Allows for ObjectFactory implementations that support
   75        * Actions without no-arg constructors.
   76        *
   77        * @return true if no-arg constructor is required, false otherwise
   78        */
   79       public boolean isNoArgConstructorRequired() {
   80           return true;
   81       }
   82   
   83       /**
   84        * Utility method to obtain the class matched to className. Caches look ups so that subsequent
   85        * lookups will be faster.
   86        *
   87        * @param className The fully qualified name of the class to return
   88        * @return The class itself
   89        * @throws ClassNotFoundException
   90        */
   91       public Class getClassInstance(String className) throws ClassNotFoundException {
   92           if (ccl != null) {
   93               return ccl.loadClass(className);
   94           }
   95   
   96           return ClassLoaderUtil.loadClass(className, this.getClass());
   97       }
   98   
   99       /**
  100        * Build an instance of the action class to handle a particular request (eg. web request)
  101        * @param actionName the name the action configuration is set up with in the configuration
  102        * @param namespace the namespace the action is configured in
  103        * @param config the action configuration found in the config for the actionName / namespace
  104        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  105        * @return instance of the action class to handle a web request
  106        * @throws Exception
  107        */
  108       public Object buildAction(String actionName, String namespace, ActionConfig config, Map<String, Object> extraContext) throws Exception {
  109           return buildBean(config.getClassName(), extraContext);
  110       }
  111   
  112       /**
  113        * Build a generic Java object of the given type.
  114        *
  115        * @param clazz the type of Object to build
  116        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  117        */
  118       public Object buildBean(Class clazz, Map<String, Object> extraContext) throws Exception {
  119           return clazz.newInstance();
  120       }
  121   
  122       /**
  123        * @param obj
  124        */
  125       protected Object injectInternalBeans(Object obj) {
  126           if (obj != null && container != null) {
  127               container.inject(obj);
  128           }
  129           return obj;
  130       }
  131   
  132       /**
  133        * Build a generic Java object of the given type.
  134        *
  135        * @param className the type of Object to build
  136        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  137        */
  138       public Object buildBean(String className, Map<String, Object> extraContext) throws Exception {
  139           return buildBean(className, extraContext, true);
  140       }
  141       
  142       /**
  143        * Build a generic Java object of the given type.
  144        *
  145        * @param className the type of Object to build
  146        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  147        */
  148       public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
  149           Class clazz = getClassInstance(className);
  150           Object obj = buildBean(clazz, extraContext);
  151           if (injectInternal) {
  152               injectInternalBeans(obj);
  153           }
  154           return obj;
  155       }
  156   
  157       /**
  158        * Builds an Interceptor from the InterceptorConfig and the Map of
  159        * parameters from the interceptor reference. Implementations of this method
  160        * should ensure that the Interceptor is parameterized with both the
  161        * parameters from the Interceptor config and the interceptor ref Map (the
  162        * interceptor ref params take precedence), and that the Interceptor.init()
  163        * method is called on the Interceptor instance before it is returned.
  164        *
  165        * @param interceptorConfig    the InterceptorConfig from the configuration
  166        * @param interceptorRefParams a Map of params provided in the Interceptor reference in the
  167        *                             Action mapping or InterceptorStack definition
  168        */
  169       public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map<String, String> interceptorRefParams) throws ConfigurationException {
  170           String interceptorClassName = interceptorConfig.getClassName();
  171           Map<String, String> thisInterceptorClassParams = interceptorConfig.getParams();
  172           Map<String, String> params = (thisInterceptorClassParams == null) ? new HashMap<String, String>() : new HashMap<String, String>(thisInterceptorClassParams);
  173           params.putAll(interceptorRefParams);
  174   
  175           String message;
  176           Throwable cause;
  177   
  178           try {
  179               // interceptor instances are long-lived and used across user sessions, so don't try to pass in any extra context
  180               Interceptor interceptor = (Interceptor) buildBean(interceptorClassName, null);
  181               reflectionProvider.setProperties(params, interceptor);
  182               interceptor.init();
  183   
  184               return interceptor;
  185           } catch (InstantiationException e) {
  186               cause = e;
  187               message = "Unable to instantiate an instance of Interceptor class [" + interceptorClassName + "].";
  188           } catch (IllegalAccessException e) {
  189               cause = e;
  190               message = "IllegalAccessException while attempting to instantiate an instance of Interceptor class [" + interceptorClassName + "].";
  191           } catch (ClassCastException e) {
  192               cause = e;
  193               message = "Class [" + interceptorClassName + "] does not implement com.opensymphony.xwork2.interceptor.Interceptor";
  194           } catch (Exception e) {
  195               cause = e;
  196               message = "Caught Exception while registering Interceptor class " + interceptorClassName;
  197           } catch (NoClassDefFoundError e) {
  198               cause = e;
  199               message = "Could not load class " + interceptorClassName + ". Perhaps it exists but certain dependencies are not available?";
  200           }
  201   
  202           throw new ConfigurationException(message, cause, interceptorConfig);
  203       }
  204   
  205       /**
  206        * Build a Result using the type in the ResultConfig and set the parameters in the ResultConfig.
  207        *
  208        * @param resultConfig the ResultConfig found for the action with the result code returned
  209        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  210        */
  211       public Result buildResult(ResultConfig resultConfig, Map<String, Object> extraContext) throws Exception {
  212           String resultClassName = resultConfig.getClassName();
  213           Result result = null;
  214   
  215           if (resultClassName != null) {
  216               result = (Result) buildBean(resultClassName, extraContext);
  217               Map<String, String> params = resultConfig.getParams();
  218               if (params != null) {
  219                   for (Map.Entry<String, String> paramEntry : params.entrySet()) {
  220                       try {
  221                           reflectionProvider.setProperty(paramEntry.getKey(), paramEntry.getValue(), result, extraContext, true);
  222                       } catch (ReflectionException ex) {
  223                           if (result instanceof ReflectionExceptionHandler) {
  224                               ((ReflectionExceptionHandler) result).handle(ex);
  225                           }
  226                       }
  227                   }
  228               }
  229           }
  230   
  231           return result;
  232       }
  233   
  234       /**
  235        * Build a Validator of the given type and set the parameters on it
  236        *
  237        * @param className the type of Validator to build
  238        * @param params    property name -> value Map to set onto the Validator instance
  239        * @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
  240        */
  241       public Validator buildValidator(String className, Map<String, String> params, Map<String, Object> extraContext) throws Exception {
  242           Validator validator = (Validator) buildBean(className, null);
  243           reflectionProvider.setProperties(params, validator);
  244   
  245           return validator;
  246       }
  247   
  248       static class ContinuationsClassLoader extends ClassLoader {
  249           
  250       }
  251   }

Save This Page
Home » xwork-2.1.5 » com.opensymphony » xwork2 » [javadoc | source]