001: /*
002: * $Id: CopyFormToContext.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: package org.apache.struts.chain.commands.generic;
022:
023: import org.apache.struts.action.ActionForm;
024: import org.apache.struts.chain.commands.ActionCommandBase;
025: import org.apache.struts.chain.contexts.ActionContext;
026: import org.apache.struts.chain.contexts.ActionContextBase;
027: import org.apache.struts.config.ActionConfig;
028:
029: /**
030: * <p>Subclass this command and configure it as part of a per-forward chain to
031: * perform any necessary pre-population or other preparation for a form before
032: * control is dispatched to the view layer.</p>
033: *
034: * @version $Id: CopyFormToContext.java 471754 2006-11-06 14:55:09Z husted $
035: */
036: public class CopyFormToContext extends ActionCommandBase {
037: // ------------------------------------------------------ Instance Variables
038:
039: /**
040: * <p>The name of a form bean as configured in a struts-config.xml file
041: * for this module. </p>
042: *
043: * <p> Either actionPath or both this and scope are required configuration
044: * properties.</p>
045: */
046: private String formName = null;
047:
048: /**
049: * <p>The name of a scope, such as "request" or "session" in which the
050: * form to be prepared will be placed for reference by the view and other
051: * parts of Struts.</p>
052: *
053: * <p>Either <code>actionPath</code> or both this and
054: * <code>formName</code> are required configuration properties.</p>
055: */
056: private String scope = null;
057:
058: /**
059: * <p>The path of an <code><action></code> mapping as configured in
060: * a <code>struts-config.xml</code> file for this module. This action
061: * will be looked up, and its <code>name</code> and <code>scope</code>
062: * values will be used as if those values were configured directly in this
063: * instance's <code>formName</code> and <code>scope</code>
064: * properties.</p>
065: *
066: * <p>Either <code>this</code> or both <code>scope</code> and
067: * <code>formName</code> are required configuration properties.</p>
068: */
069: private String actionPath = null;
070:
071: /**
072: * The context key under which the form which was looked up will be
073: * stored. Defaults to "actionForm" but may be overridden in cases where
074: * the "request" ActionForm must be preserved.
075: */
076: private String toKey = ActionContextBase.ACTION_FORM_KEY;
077:
078: // ------------------------------------------------------ Properties
079:
080: /**
081: * <p>Return ActionPath property.</p>
082: *
083: * @return ActionPath property
084: */
085: public String getActionPath() {
086: return this .actionPath;
087: }
088:
089: /**
090: * <p>Set ActionPath property.</p>
091: *
092: * @param actionPath New valuefor ActionPath
093: */
094: public void setActionPath(String actionPath) {
095: this .actionPath = actionPath;
096: }
097:
098: /**
099: * <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(
173: "Property 'toKey' must be defined.");
174: }
175:
176: actionContext.put(getToKey(), form);
177:
178: return false;
179: }
180:
181: /**
182: * <p>Based on the properties of this command and the given
183: * <code>ActionContext</code>, find or create an ActionForm instance for
184: * preparation.</p>
185: *
186: * @param context ActionContextBase class that we are processing
187: * @return ActionForm instance
188: * @throws IllegalArgumentException On ActionConfig not found
189: * @throws IllegalStateException On undefined scope and formbean
190: * @throws IllegalAccessException On failed instantiation
191: * @throws InstantiationException If ActionContext is not subsclass of
192: * ActionContextBase
193: */
194: protected ActionForm findOrCreateForm(ActionContext context)
195: throws IllegalAccessException, InstantiationException {
196: String effectiveFormName;
197: String effectiveScope;
198:
199: if (!(isEmpty(this .getActionPath()))) {
200: ActionConfig actionConfig = context.getModuleConfig()
201: .findActionConfig(this .getActionPath());
202:
203: if (actionConfig == null) {
204: throw new IllegalArgumentException(
205: "No ActionConfig found for path "
206: + this .getActionPath());
207: }
208:
209: effectiveFormName = actionConfig.getName();
210: effectiveScope = actionConfig.getScope();
211: } else {
212: effectiveFormName = this .getFormName();
213: effectiveScope = this .getScope();
214: }
215:
216: if (isEmpty(effectiveScope) || isEmpty(effectiveFormName)) {
217: throw new IllegalStateException("Both scope ["
218: + effectiveScope + "] and formName ["
219: + effectiveFormName + "] must be defined.");
220: }
221:
222: return findOrCreateForm(context, effectiveFormName,
223: effectiveScope);
224: }
225:
226: /**
227: * <p>Actually find or create an instance of ActionForm configured under
228: * the form-bean-name <code>effectiveFormName</code>, looking in in the
229: * <code>ActionContext's</code> scope as identified by
230: * <code>effectiveScope</code>. If a form is created, it will also be
231: * stored in that scope.</p>
232: *
233: * <p><b>NOTE:</b> This specific method depends on the instance of
234: * <code>ActionContext</code> which is passed being a subclass of
235: * <code>ActionContextBase</code>, which implements the utility method
236: * <code>findOrCreateActionForm</code>. </p>
237: *
238: * @param ctx The ActionContext we are processing
239: * @param effectiveFormName the target form name
240: * @param effectiveScope The target scope
241: * @return ActionForm instnace, storing in scope if created
242: * @throws InstantiationException If ActionContext is not subsclass of
243: * ActionContextBase
244: * @throws InstantiationException If object cannot be created
245: * @throws IllegalArgumentException On form not found in/ scope
246: * @throws IllegalAccessException On failed instantiation
247: * @throws IllegalStateException If ActionContext is not a subclass of
248: * ActionBase
249: */
250: protected ActionForm findOrCreateForm(ActionContext ctx,
251: String effectiveFormName, String effectiveScope)
252: throws IllegalAccessException, InstantiationException {
253: ActionContextBase context;
254:
255: try {
256: context = (ActionContextBase) ctx;
257: } catch (ClassCastException e) {
258: throw new IllegalStateException("ActionContext [" + ctx
259: + "]" + " must be subclass of ActionContextBase");
260: }
261:
262: ActionForm form = context.findOrCreateActionForm(
263: effectiveFormName, effectiveScope);
264:
265: if (form == null) {
266: throw new IllegalArgumentException(
267: "No form found under scope [" + effectiveScope
268: + "] and formName [" + effectiveFormName
269: + "]");
270: }
271:
272: return form;
273: }
274:
275: /**
276: * <p>Convenience method to test for an empty string.</p>
277: *
278: * @param test String to test
279: * @return TRUE if test is null or zero-length
280: */
281: private boolean isEmpty(String test) {
282: return (test == null) || (test.trim().length() == 0);
283: }
284: }
|