View Javadoc

1   /*
2    * $Id: CopyFormToContext.java 471754 2006-11-06 14:55:09Z husted $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.struts.chain.commands.generic;
22  
23  import org.apache.struts.action.ActionForm;
24  import org.apache.struts.chain.commands.ActionCommandBase;
25  import org.apache.struts.chain.contexts.ActionContext;
26  import org.apache.struts.chain.contexts.ActionContextBase;
27  import org.apache.struts.config.ActionConfig;
28  
29  /**
30   * <p>Subclass this command and configure it as part of a per-forward chain to
31   * perform any necessary pre-population or other preparation for a form before
32   * control is dispatched to the view layer.</p>
33   *
34   * @version $Id: CopyFormToContext.java 471754 2006-11-06 14:55:09Z husted $
35   */
36  public class CopyFormToContext extends ActionCommandBase {
37      // ------------------------------------------------------ Instance Variables
38  
39      /**
40       * <p>The name of a form bean as configured in a struts-config.xml file
41       * for this module.  </p>
42       *
43       * <p> Either actionPath or both this and scope are required configuration
44       * properties.</p>
45       */
46      private String formName = null;
47  
48      /**
49       * <p>The name of a scope, such as "request" or "session" in which the
50       * form to be prepared will be placed for reference by the view and other
51       * parts of Struts.</p>
52       *
53       * <p>Either <code>actionPath</code> or both this and
54       * <code>formName</code> are required configuration properties.</p>
55       */
56      private String scope = null;
57  
58      /**
59       * <p>The path of an <code>&lt;action&gt;</code> mapping as configured in
60       * a <code>struts-config.xml</code> file for this module.  This action
61       * will be looked up, and its <code>name</code> and <code>scope</code>
62       * values will be used as if those values were configured directly in this
63       * instance's <code>formName</code> and <code>scope</code>
64       * properties.</p>
65       *
66       * <p>Either <code>this</code> or both <code>scope</code> and
67       * <code>formName</code> are required configuration properties.</p>
68       */
69      private String actionPath = null;
70  
71      /**
72       * The context key under which the form which was looked up will be
73       * stored. Defaults to "actionForm" but may be overridden in cases where
74       * the "request" ActionForm must be preserved.
75       */
76      private String toKey = ActionContextBase.ACTION_FORM_KEY;
77  
78      // ------------------------------------------------------ Properties
79  
80      /**
81       * <p>Return ActionPath property.</p>
82       *
83       * @return ActionPath property
84       */
85      public String getActionPath() {
86          return this.actionPath;
87      }
88  
89      /**
90       * <p>Set ActionPath property.</p>
91       *
92       * @param actionPath New valuefor ActionPath
93       */
94      public void setActionPath(String actionPath) {
95          this.actionPath = actionPath;
96      }
97  
98      /**
99       * <p>Return FormName property.</p>
100      *
101      * @return FormName property
102      */
103     public String getFormName() {
104         return this.formName;
105     }
106 
107     /**
108      * <p>Set FormName property.</p>
109      *
110      * @param formName New valuefor FormName
111      */
112     public void setFormName(String formName) {
113         this.formName = formName;
114     }
115 
116     /**
117      * <p>Return Scope property.</p>
118      *
119      * @return Scope property
120      */
121     public String getScope() {
122         return this.scope;
123     }
124 
125     /**
126      * <p>Set Scope property.</p>
127      *
128      * @param scope New valuefor Scope
129      */
130     public void setScope(String scope) {
131         this.scope = scope;
132     }
133 
134     /**
135      * <p>Return ToKey property.</p>
136      *
137      * @return ToKey property
138      */
139     public String getToKey() {
140         return this.toKey;
141     }
142 
143     /**
144      * <p>Set ToKey property.</p>
145      *
146      * @param toKey New valuefor FormName
147      */
148     public void setToKey(String toKey) {
149         this.toKey = toKey;
150     }
151 
152     // ------------------------------------------------------
153 
154     /**
155      * <p>Look up an ActionForm instance based on the configured properties of
156      * this command and copy it into the <code>Context</code>.  After this
157      * command successfully executes, an ActionForm instance will exist in the
158      * specified scope and will be available, for example for backing fields
159      * in an HTML form.  It will also be in the <code>ActionContext</code>
160      * available for another command to do prepopulation of values or other
161      * preparation.</p>
162      *
163      * @param actionContext Our ActionContext
164      * @return TRUE if processing should halt
165      * @throws Exception on any error
166      */
167     public boolean execute(ActionContext actionContext)
168         throws Exception {
169         ActionForm form = findOrCreateForm(actionContext);
170 
171         if (isEmpty(getToKey())) {
172             throw new IllegalStateException("Property 'toKey' must be defined.");
173         }
174 
175         actionContext.put(getToKey(), form);
176 
177         return false;
178     }
179 
180     /**
181      * <p>Based on the properties of this command and the given
182      * <code>ActionContext</code>, find or create an ActionForm instance for
183      * preparation.</p>
184      *
185      * @param context ActionContextBase class that we are processing
186      * @return ActionForm instance
187      * @throws IllegalArgumentException On ActionConfig not found
188      * @throws IllegalStateException    On undefined scope and formbean
189      * @throws IllegalAccessException   On failed instantiation
190      * @throws InstantiationException   If ActionContext is not subsclass of
191      *                                  ActionContextBase
192      */
193     protected ActionForm findOrCreateForm(ActionContext context)
194         throws IllegalAccessException, InstantiationException {
195         String effectiveFormName;
196         String effectiveScope;
197 
198         if (!(isEmpty(this.getActionPath()))) {
199             ActionConfig actionConfig =
200                 context.getModuleConfig().findActionConfig(this.getActionPath());
201 
202             if (actionConfig == null) {
203                 throw new IllegalArgumentException(
204                     "No ActionConfig found for path " + this.getActionPath());
205             }
206 
207             effectiveFormName = actionConfig.getName();
208             effectiveScope = actionConfig.getScope();
209         } else {
210             effectiveFormName = this.getFormName();
211             effectiveScope = this.getScope();
212         }
213 
214         if (isEmpty(effectiveScope) || isEmpty(effectiveFormName)) {
215             throw new IllegalStateException("Both scope [" + effectiveScope
216                 + "] and formName [" + effectiveFormName + "] must be defined.");
217         }
218 
219         return findOrCreateForm(context, effectiveFormName, effectiveScope);
220     }
221 
222     /**
223      * <p>Actually find or create an instance of ActionForm configured under
224      * the form-bean-name <code>effectiveFormName</code>, looking in in the
225      * <code>ActionContext's</code> scope as identified by
226      * <code>effectiveScope</code>. If a form is created, it will also be
227      * stored in that scope.</p>
228      *
229      * <p><b>NOTE:</b> This specific method depends on the instance of
230      * <code>ActionContext</code> which is passed being a subclass of
231      * <code>ActionContextBase</code>, which implements the utility method
232      * <code>findOrCreateActionForm</code>. </p>
233      *
234      * @param ctx               The ActionContext we are processing
235      * @param effectiveFormName the target form name
236      * @param effectiveScope    The target scope
237      * @return ActionForm instnace, storing in scope if created
238      * @throws InstantiationException   If ActionContext is not subsclass of
239      *                                  ActionContextBase
240      * @throws InstantiationException   If object cannot be created
241      * @throws IllegalArgumentException On form not found in/ scope
242      * @throws IllegalAccessException   On failed instantiation
243      * @throws IllegalStateException    If ActionContext is not a subclass of
244      *                                  ActionBase
245      */
246     protected ActionForm findOrCreateForm(ActionContext ctx,
247         String effectiveFormName, String effectiveScope)
248         throws IllegalAccessException, InstantiationException {
249         ActionContextBase context;
250 
251         try {
252             context = (ActionContextBase) ctx;
253         } catch (ClassCastException e) {
254             throw new IllegalStateException("ActionContext [" + ctx + "]"
255                 + " must be subclass of ActionContextBase");
256         }
257 
258         ActionForm form =
259             context.findOrCreateActionForm(effectiveFormName, effectiveScope);
260 
261         if (form == null) {
262             throw new IllegalArgumentException("No form found under scope ["
263                 + effectiveScope + "] and formName [" + effectiveFormName + "]");
264         }
265 
266         return form;
267     }
268 
269     /**
270      * <p>Convenience method to test for an empty string.</p>
271      *
272      * @param test String to test
273      * @return TRUE if test is null or zero-length
274      */
275     private boolean isEmpty(String test) {
276         return (test == null) || (test.trim().length() == 0);
277     }
278 }