Save This Page
Home » Struts-1.3.10 » org.apache.struts » config » [javadoc | source]
    1   /*
    2    * $Id: FormBeanConfig.java 54929 2004-10-16 16:38:42Z germuska $ 
    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   
   20   package org.apache.struts.config;
   21   
   22   
   23   import java.io.Serializable;
   24   import java.util.HashMap;
   25   import org.apache.commons.beanutils.DynaBean;
   26   import org.apache.commons.beanutils.MutableDynaClass;
   27   import org.apache.struts.action.DynaActionForm;
   28   import org.apache.struts.action.DynaActionFormClass;
   29   import org.apache.struts.action.ActionServlet;
   30   import org.apache.struts.action.ActionForm;
   31   import org.apache.struts.validator.BeanValidatorForm;
   32   
   33   
   34   /**
   35    * <p>A JavaBean representing the configuration information of a
   36    * <code>&lt;form-bean&gt;</code> element in a Struts
   37    * configuration file.<p>
   38    *
   39    * @version $Rev: 54929 $ $Date: 2004-10-16 17:38:42 +0100 (Sat, 16 Oct 2004) $
   40    * @since Struts 1.1
   41    */
   42   
   43   public class FormBeanConfig implements Serializable {
   44   
   45   
   46       // ----------------------------------------------------- Instance Variables
   47   
   48   
   49       /**
   50        * Has this component been completely configured?
   51        */
   52       protected boolean configured = false;
   53   
   54   
   55       /**
   56        * The set of FormProperty elements defining dynamic form properties for
   57        * this form bean, keyed by property name.
   58        */
   59       protected HashMap formProperties = new HashMap();
   60   
   61   
   62       /**
   63        * <p>The lockable object we can synchronize on when creating DynaActionFormClass.</p>
   64        */
   65       protected String lock = "";
   66   
   67   
   68       // ------------------------------------------------------------- Properties
   69   
   70   
   71       /**
   72        * The DynaActionFormClass associated with a DynaActionForm.
   73        */
   74       protected transient DynaActionFormClass dynaActionFormClass;
   75   
   76       /**
   77        * <p>Return the DynaActionFormClass associated with a DynaActionForm.</p>
   78        *
   79        * @exception IllegalArgumentException if the ActionForm is not dynamic
   80        */
   81       public DynaActionFormClass getDynaActionFormClass() {
   82   
   83           if (dynamic == false) {
   84               throw new IllegalArgumentException("ActionForm is not dynamic");
   85           }
   86           synchronized (lock) {
   87               if (dynaActionFormClass == null) {
   88                   dynaActionFormClass = new DynaActionFormClass(this);
   89               }
   90           }
   91           return dynaActionFormClass;
   92       }
   93   
   94   
   95       /**
   96        * Is the form bean class an instance of DynaActionForm with dynamic
   97        * properties?
   98        */
   99       protected boolean dynamic = false;
  100   
  101       public boolean getDynamic() {
  102           return (this.dynamic);
  103       }
  104   
  105       /**
  106        * @deprecated The value to be returned by <code>getDynamic()</code>
  107        * is now computed automatically in <code>setType()</code>
  108        */
  109       public void setDynamic(boolean dynamic) {
  110           if (configured) {
  111               throw new IllegalStateException("Configuration is frozen"); 
  112           }
  113           ; // No action required
  114       }
  115   
  116       /**
  117        * The unique identifier of this form bean, which is used to reference this
  118        * bean in <code>ActionMapping</code> instances as well as for the name of
  119        * the request or session attribute under which the corresponding form bean
  120        * instance is created or accessed.
  121        */
  122       protected String name = null;
  123   
  124       public String getName() {
  125           return (this.name);
  126       }
  127   
  128       public void setName(String name) {
  129           if (configured) {
  130               throw new IllegalStateException("Configuration is frozen");
  131           }
  132           this.name = name;
  133       }
  134   
  135   
  136       /**
  137        * The fully qualified Java class name of the implementation class
  138        * to be used or generated.
  139        */
  140       protected String type = null;
  141   
  142       public String getType() {
  143           return (this.type);
  144       }
  145   
  146       public void setType(String type) {
  147           if (configured) {
  148               throw new IllegalStateException("Configuration is frozen");
  149           }
  150           this.type = type;
  151           Class dynaBeanClass = DynaActionForm.class;
  152           Class formBeanClass = formBeanClass();
  153           if (formBeanClass != null) {
  154               if (dynaBeanClass.isAssignableFrom(formBeanClass)) {
  155                   this.dynamic = true;
  156               } else {
  157                   this.dynamic = false;
  158               }
  159           } else {
  160               this.dynamic = false;
  161           }
  162       }
  163   
  164       /**
  165        * Is this DynaClass currently restricted (for DynaBeans with a MutableDynaClass).
  166        */
  167       protected boolean restricted = false;
  168   
  169       /**
  170        * <p>Indicates whether a MutableDynaClass is currently restricted.</p>
  171        * <p>If so, no changes to the existing registration of property names, 
  172        *    data types, readability, or writeability are allowed.</p>
  173        */
  174       public boolean isRestricted() {
  175           return restricted;
  176       }
  177   
  178       /**
  179        * <p>Set whether a MutableDynaClass is currently restricted.</p>
  180        * <p>If so, no changes to the existing registration of property names, 
  181        *    data types, readability, or writeability are allowed.</p>
  182        */
  183       public void setRestricted(boolean restricted) {
  184           this.restricted = restricted;
  185       }
  186   
  187   
  188       // --------------------------------------------------------- Public Methods
  189   
  190   
  191       /**
  192        * <p>Create and return an <code>ActionForm</code> instance appropriate
  193        * to the information in this <code>FormBeanConfig</code>.</p>
  194        *
  195        * @param servlet The action servlet
  196        * @return ActionForm instance
  197        * @exception IllegalAccessException if the Class or the appropriate
  198        *  constructor is not accessible
  199        * @exception InstantiationException if this Class represents an abstract
  200        *  class, an array class, a primitive type, or void; or if instantiation
  201        *  fails for some other reason
  202        */
  203       public ActionForm createActionForm(ActionServlet servlet)
  204           throws IllegalAccessException, InstantiationException {
  205   
  206           Object obj = null;
  207   
  208           // Create a new form bean instance
  209           if (getDynamic()) {
  210               obj = getDynaActionFormClass().newInstance();
  211           } else {
  212               obj = formBeanClass().newInstance();
  213           }
  214   
  215           ActionForm form = null;
  216           if (obj instanceof ActionForm) {
  217               form = (ActionForm)obj;
  218           } else  {
  219               form = new BeanValidatorForm(obj);
  220           }
  221   
  222           form.setServlet(servlet);
  223   
  224           if (form instanceof DynaBean && 
  225               ((DynaBean)form).getDynaClass() instanceof MutableDynaClass) {
  226               DynaBean         dynaBean  = (DynaBean)form;
  227               MutableDynaClass dynaClass = (MutableDynaClass)dynaBean.getDynaClass();
  228   
  229               // Add properties
  230               dynaClass.setRestricted(false);
  231               FormPropertyConfig props[] = findFormPropertyConfigs();
  232               for (int i = 0; i < props.length; i++) {
  233                   dynaClass.add(props[i].getName(), props[i].getTypeClass());
  234                   dynaBean.set(props[i].getName(), props[i].initial());
  235               }
  236               dynaClass.setRestricted(isRestricted());
  237   
  238           }
  239   
  240           return form;
  241   
  242       }
  243   
  244   
  245       /**
  246        * Add a new <code>FormPropertyConfig</code> instance to the set associated
  247        * with this module.
  248        *
  249        * @param config The new configuration instance to be added
  250        *
  251        * @exception IllegalArgumentException if this property name has already
  252        *  been defined
  253        */
  254       public void addFormPropertyConfig(FormPropertyConfig config) {
  255   
  256           if (configured) {
  257               throw new IllegalStateException("Configuration is frozen");
  258           }
  259           if (formProperties.containsKey(config.getName())) {
  260               throw new IllegalArgumentException("Property " +
  261                                                  config.getName() +
  262                                                  " already defined");
  263           }
  264           formProperties.put(config.getName(), config);
  265   
  266       }
  267   
  268   
  269       /**
  270        * Return the form property configuration for the specified property
  271        * name, if any; otherwise return <code>null</code>.
  272        *
  273        * @param name Form property name to find a configuration for
  274        */
  275       public FormPropertyConfig findFormPropertyConfig(String name) {
  276   
  277           return ((FormPropertyConfig) formProperties.get(name));
  278   
  279       }
  280   
  281   
  282       /**
  283        * Return the form property configurations for this module.  If there
  284        * are none, a zero-length array is returned.
  285        */
  286       public FormPropertyConfig[] findFormPropertyConfigs() {
  287   
  288           FormPropertyConfig results[] =
  289               new FormPropertyConfig[formProperties.size()];
  290           return ((FormPropertyConfig[]) formProperties.values().toArray(results));
  291   
  292       }
  293   
  294   
  295       /**
  296        * Freeze the configuration of this component.
  297        */
  298       public void freeze() {
  299   
  300           configured = true;
  301   
  302           FormPropertyConfig[] fpconfigs = findFormPropertyConfigs();
  303           for (int i = 0; i < fpconfigs.length; i++) {
  304               fpconfigs[i].freeze();
  305           }
  306   
  307       }
  308   
  309   
  310       /**
  311        * Remove the specified form property configuration instance.
  312        *
  313        * @param config FormPropertyConfig instance to be removed
  314        */
  315       public void removeFormPropertyConfig(FormPropertyConfig config) {
  316   
  317           if (configured) {
  318               throw new IllegalStateException("Configuration is frozen");
  319           }
  320           formProperties.remove(config.getName());
  321   
  322       }
  323   
  324   
  325       /**
  326        * Return a String representation of this object.
  327        */
  328       public String toString() {
  329   
  330           StringBuffer sb = new StringBuffer("FormBeanConfig[");
  331           sb.append("name=");
  332           sb.append(this.name);
  333           sb.append(",type=");
  334           sb.append(this.type);
  335           sb.append("]");
  336           return (sb.toString());
  337   
  338       }
  339   
  340   
  341       // ------------------------------------------------------ Protected Methods
  342   
  343   
  344       /**
  345        * Return the <code>Class</code> instance for the form bean implementation
  346        * configured by this <code>FormBeanConfig</code> instance.  This method
  347        * uses the same algorithm as <code>RequestUtils.applicationClass()</code>
  348        * but is reproduced to avoid a runtime dependence.
  349        */
  350       protected Class formBeanClass() {
  351   
  352           ClassLoader classLoader =
  353               Thread.currentThread().getContextClassLoader();
  354           if (classLoader == null) {
  355               classLoader = this.getClass().getClassLoader();
  356           }
  357           try {
  358               return (classLoader.loadClass(getType()));
  359           } catch (Exception e) {
  360               return (null);
  361           }
  362   
  363       }
  364   
  365   
  366   }

Save This Page
Home » Struts-1.3.10 » org.apache.struts » config » [javadoc | source]