View Javadoc

1   /*
2    * Copyright (c) 2001 - 2005 ivata limited.
3    * All rights reserved.
4    * -----------------------------------------------------------------------------
5    * ivata masks may be redistributed under the GNU General Public
6    * License as published by the Free Software Foundation;
7    * version 2 of the License.
8    *
9    * These programs are free software; you can redistribute them and/or
10   * modify them under the terms of the GNU General Public License
11   * as published by the Free Software Foundation; version 2 of the License.
12   *
13   * These programs are distributed in the hope that they will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16   *
17   * See the GNU General Public License in the file LICENSE.txt for more
18   * details.
19   *
20   * If you would like a copy of the GNU General Public License write to
21   *
22   * Free Software Foundation, Inc.
23   * 59 Temple Place - Suite 330
24   * Boston, MA 02111-1307, USA.
25   *
26   *
27   * To arrange commercial support and licensing, contact ivata at
28   *                  http://www.ivata.com/contact.jsp
29   * -----------------------------------------------------------------------------
30   * $Log: FindAction.java,v $
31   * Revision 1.8.2.1  2005/10/08 10:54:23  colinmacleod
32   * Added temporary workarounds for bugs in ivata groupware v0.11.x
33   *
34   * Revision 1.8  2005/04/27 17:23:28  colinmacleod
35   * Fixed bugs resulting from ivata masks changes
36   * for ivata groupware v0.11.
37   *
38   * Revision 1.7  2005/04/09 18:04:18  colinmacleod
39   * Changed copyright text to GPL v2 explicitly.
40   *
41   * Revision 1.6  2005/03/10 10:36:52  colinmacleod
42   * Added base class name, display only as attributes
43   * (as well as the request parameters).
44   *
45   * Revision 1.5  2005/01/19 13:14:02  colinmacleod
46   * Renamed CausedByException to SystemException.
47   *
48   * Revision 1.4  2005/01/07 08:08:24  colinmacleod
49   * Moved up a version number.
50   * Changed copyright notices to 2005.
51   * Updated the documentation:
52   *   - started working on multiproject:site docu.
53   *   - changed the logo.
54   * Added checkstyle and fixed LOADS of style issues.
55   * Added separate thirdparty subproject.
56   * Added struts (in web), util and webgui (in webtheme) from ivata op.
57   *
58   * Revision 1.3  2004/12/29 15:32:19  colinmacleod
59   * List/input mask actions are no longer hard-coded.
60   * Overrides added via request parameters - defaults via new methods on the
61   * factory.
62   *
63   * Revision 1.2  2004/11/12 15:10:41  colinmacleod
64   * Moved persistence classes from ivata op as a replacement for
65   * ValueObjectLocator.
66   *
67   * Revision 1.1.1.1  2004/05/16 20:40:32  colinmacleod
68   * Ready for 0.1 release
69   * -----------------------------------------------------------------------------
70   */
71  package com.ivata.mask.web.struts;
72  import javax.servlet.http.HttpServletRequest;
73  import javax.servlet.http.HttpServletResponse;
74  import javax.servlet.http.HttpSession;
75  
76  import org.apache.log4j.Logger;
77  import org.apache.struts.action.ActionErrors;
78  import org.apache.struts.action.ActionForm;
79  import org.apache.struts.action.ActionMapping;
80  import com.ivata.mask.Mask;
81  import com.ivata.mask.MaskFactory;
82  import com.ivata.mask.persistence.FinderException;
83  import com.ivata.mask.persistence.PersistenceManager;
84  import com.ivata.mask.persistence.PersistenceSession;
85  import com.ivata.mask.util.SystemException;
86  import com.ivata.mask.util.StringHandling;
87  import com.ivata.mask.valueobject.ValueObject;
88  /***
89   * <p>
90   * View a value object in a mask for display or deletion.
91   * </p>
92   *
93   * @since ivata masks 0.1 (2004-05-10)
94   * @author Colin MacLeod
95   * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
96   * @version $Revision: 1.8.2.1 $
97   */
98  public class FindAction extends MaskAction {
99      /***
100      * Refer to {@link Logger}.
101      */
102     private static Logger log = Logger.getLogger(FindAction.class);
103     /***
104      * Class of value object we are to find.
105      */
106     private String baseClassName;
107     /***
108      * <code>true</code> if we should only display the value object (rather than
109      * edit it).
110      */
111     private Boolean displayOnly;
112     /***
113      * Unique identifier of the value object.
114      */
115     private String idString;
116     /***
117      * <p>
118      * This factory is needed to access the masks and groups of masks.
119      * </p>
120      */
121     private MaskFactory maskFactory;
122     /***
123      * <p>
124      * Used to locate the value objects by their unique identifier.
125      * </p>
126      */
127     private PersistenceManager persistenceManager;
128     /***
129      * <p>
130      * Create a new AddAction with the given value object locator.
131      * </p>
132      *
133      * @param persistenceManagerParam
134      *            used to locate the value objects by their unique identifier.
135      * @param maskFactoryParam
136      *            This factory is needed to access the masks and groups of
137      *            masks.
138      * @param authenticatorParam
139      *            used to confirm whether or not the user should be allowed to
140      *            continue, in the <code>execute</code> method.
141      */
142     public FindAction(final PersistenceManager persistenceManagerParam,
143             final MaskFactory maskFactoryParam,
144             final MaskAuthenticator authenticatorParam) {
145         super(maskFactoryParam, authenticatorParam);
146         this.maskFactory = maskFactoryParam;
147         this.persistenceManager = persistenceManagerParam;
148     }
149     /***
150      * <p>
151      * Override this method to create a different class of input mask form.
152      * </p>
153      *
154      * @param requestParam
155      *            request we are processing.
156      * @param valueObjectParam
157      *            value object to be displayed/edited.
158      * @param maskParam
159      *            mask to be edited.
160      * @param baseClassParam
161      *            base class of all value objects to show in the list or
162      *            associated with this mask.
163      * @since ivata op (0.10) (2004-12-31)
164      * @return new instance of <code>InputMaskForm</code>.
165      */
166     protected InputMaskForm createInputMaskForm(
167             final HttpServletRequest requestParam,
168             final ValueObject valueObjectParam, final Mask maskParam,
169             final Class baseClassParam) {
170         return new InputMaskForm(valueObjectParam, maskParam, baseClassParam);
171     }
172     /***
173      * <p>
174      * Generic method called by the <strong>Struts </strong> interface. Looks
175      * for a request parameter called &quot;idString&quot; and removes the value
176      * object with this id.
177      * </p>
178      *
179      * <p>
180      * Additionally, specifying a request parameter called &quot;readOnly&quot;
181      * to <code>true</code> will cause the mask form to be created in read
182      * only (display) mode.
183      * </p>
184      *
185      * <p>
186      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
187      * </p>
188      *
189      * @param mapping
190      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
191      * @param errors
192      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
193      * @param form
194      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
195      * @param request
196      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
197      * @param response
198      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
199      * @param session
200      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
201      * @return Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
202      * @throws SystemException
203      * Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
204      */
205     public String execute(final ActionMapping mapping,
206             final ActionErrors errors, final ActionForm form,
207             final HttpServletRequest request,
208             final HttpServletResponse response, final HttpSession session)
209             throws SystemException {
210         // first the mandatory parameters - you can set these in a subclass
211         // if you choose
212         String baseClassNameRequest = request.getParameter("baseClass");
213         if (baseClassNameRequest != null) {
214             baseClassName = baseClassNameRequest;
215         }
216         String idStringRequest = request.getParameter("idString");
217         if (idStringRequest != null) {
218             idString = idStringRequest;
219         }
220         String displayOnlyRequest = request.getParameter("displayOnly");
221         if ((displayOnlyRequest != null)
222                 || (displayOnly == null)) {
223             displayOnly = new Boolean("true".equals(displayOnlyRequest));
224         }
225         if (idString == null) {
226             throw new ValueObjectException(
227                     "You must specify a request parameter called 'idString'");
228         }
229         if (baseClassName == null) {
230             throw new ValueObjectException(
231                     "You must specify a request parameter called 'baseClass'");
232         }
233         Class baseClass;
234         try {
235             baseClass = Class.forName(baseClassName);
236         } catch (ClassNotFoundException e) {
237             throw new ValueObjectException(e);
238         }
239         PersistenceSession persistenceSession = persistenceManager
240                 .openSession();
241         try {
242             assert (!StringHandling.isNullOrEmpty(idString));
243             ValueObject valueObject;
244             try {
245                 valueObject = persistenceManager.findByPrimaryKey(
246                         persistenceSession, baseClass, idString);
247             } catch(FinderException e) {
248                 valueObject = null;
249             }
250             if ((valueObject == null)
251                     && log.isDebugEnabled()) {
252                 log.debug("No value object found with id string '"
253                             + idString
254                             + "'");
255             }
256             Mask mask = maskFactory.getMask(baseClass, getInputMask(request,
257                     form));
258             if (mask == null) {
259                 throw new NullPointerException(
260                         "ERROR in ViewAction: no mask for baseClass '"
261                                 + baseClass + "', type 'mask'");
262             }
263             InputMaskForm maskForm;
264             if (form instanceof InputMaskForm) {
265                 maskForm = (InputMaskForm) form;
266             } else {
267                 maskForm = createInputMaskForm(request, valueObject, mask,
268                         baseClass);
269             }
270             // only set the display only status if it was explicitly set to
271             // something
272             if (displayOnly.booleanValue()) {
273                 maskForm.setDisplayOnly(true);
274             }
275             request.setAttribute(InputMaskForm.REQUEST_ATTRIBUTE, maskForm);
276             // TODO: workaround for ivata groupware
277             session.setAttribute(InputMaskForm.REQUEST_ATTRIBUTE, maskForm);
278             return "success";
279         } finally {
280             persistenceSession.close();
281         }
282     }
283     /***
284      * Class of value object we are to find.
285      *
286      * @return Returns the baseClassName.
287      */
288     protected String getBaseClassName() {
289         return baseClassName;
290     }
291     /***
292      * <code>true</code> if we should only display the value object (rather than
293      * edit it).
294      *
295      * @return Returns the displayOnly.
296      */
297     protected Boolean getDisplayOnly() {
298         return displayOnly;
299     }
300     /***
301      * Unique identifier of the value object.
302      *
303      * @return Returns the idString.
304      */
305     protected String getIdString() {
306         return idString;
307     }
308     /***
309      * Class of value object we are to find.
310      *
311      * @param baseClassNameParam The baseClassName to set.
312      */
313     protected void setBaseClassName(String baseClassNameParam) {
314         if (log.isDebugEnabled()) {
315             log.debug("setBaseClassName before: '" + baseClassName
316                     + "', after: '" + baseClassNameParam + "'");
317         }
318 
319         baseClassName = baseClassNameParam;
320     }
321     /***
322      * <code>true</code> if we should only display the value object (rather than
323      * edit it).
324      *
325      * @param displayOnlyParam The displayOnly to set.
326      */
327     protected void setDisplayOnly(Boolean displayOnlyParam) {
328         if (log.isDebugEnabled()) {
329             log.debug("setDisplayOnly before: '" + displayOnly + "', after: '"
330                     + displayOnlyParam + "'");
331         }
332 
333         displayOnly = displayOnlyParam;
334     }
335     /***
336      * Unique identifier of the value object.
337      *
338      * @param idStringParam The idString to set.
339      */
340     protected void setIdString(String idStringParam) {
341         if (log.isDebugEnabled()) {
342             log.debug("setIdString before: '" + idString + "', after: '"
343                     + idStringParam + "'");
344         }
345 
346         idString = idStringParam;
347     }
348 }
349