001: /*
002: * Copyright (c) 2001 - 2005 ivata limited.
003: * All rights reserved.
004: * -----------------------------------------------------------------------------
005: * ivata masks may be redistributed under the GNU General Public
006: * License as published by the Free Software Foundation;
007: * version 2 of the License.
008: *
009: * These programs are free software; you can redistribute them and/or
010: * modify them under the terms of the GNU General Public License
011: * as published by the Free Software Foundation; version 2 of the License.
012: *
013: * These programs are distributed in the hope that they will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: *
017: * See the GNU General Public License in the file LICENSE.txt for more
018: * details.
019: *
020: * If you would like a copy of the GNU General Public License write to
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place - Suite 330
024: * Boston, MA 02111-1307, USA.
025: *
026: *
027: * To arrange commercial support and licensing, contact ivata at
028: * http://www.ivata.com/contact.jsp
029: * -----------------------------------------------------------------------------
030: * $Log: FindAction.java,v $
031: * Revision 1.15 2005/10/14 14:03:57 colinmacleod
032: * Changed order of imports. Fixed long comment.
033: *
034: * Revision 1.14 2005/10/12 18:36:58 colinmacleod
035: * Standardized format of Logger declaration - to make it easier to find
036: * instances which are not both static and final.
037: *
038: * Revision 1.13 2005/10/11 18:54:06 colinmacleod
039: * Fixed some checkstyle and javadoc issues.
040: *
041: * Revision 1.12 2005/10/09 09:55:17 colinmacleod
042: * Merged changes from ivata masks v0.6.2 into main trunk.
043: *
044: * Revision 1.11 2005/10/03 10:17:25 colinmacleod
045: * Fixed some style and javadoc issues.
046: *
047: * Revision 1.10 2005/10/02 14:06:34 colinmacleod
048: * Added/improved log4j logging.
049: *
050: * Revision 1.9 2005/09/29 12:18:44 colinmacleod
051: * Added session parameter to persistenceManager.openSession().
052: *
053: * Revision 1.8.2.1 2005/10/08 10:54:23 colinmacleod
054: * Added temporary workarounds for bugs in ivata groupware v0.11.x
055: *
056: * Revision 1.8 2005/04/27 17:23:28 colinmacleod
057: * Fixed bugs resulting from ivata masks changes
058: * for ivata groupware v0.11.
059: *
060: * Revision 1.7 2005/04/09 18:04:18 colinmacleod
061: * Changed copyright text to GPL v2 explicitly.
062: *
063: * Revision 1.6 2005/03/10 10:36:52 colinmacleod
064: * Added base class name, display only as attributes
065: * (as well as the request parameters).
066: *
067: * Revision 1.5 2005/01/19 13:14:02 colinmacleod
068: * Renamed CausedByException to SystemException.
069: *
070: * Revision 1.4 2005/01/07 08:08:24 colinmacleod
071: * Moved up a version number.
072: * Changed copyright notices to 2005.
073: * Updated the documentation:
074: * - started working on multiproject:site docu.
075: * - changed the logo.
076: * Added checkstyle and fixed LOADS of style issues.
077: * Added separate thirdparty subproject.
078: * Added struts (in web), util and webgui (in webtheme) from ivata op.
079: *
080: * Revision 1.3 2004/12/29 15:32:19 colinmacleod
081: * List/input mask actions are no longer hard-coded.
082: * Overrides added via request parameters - defaults via new methods on the
083: * factory.
084: *
085: * Revision 1.2 2004/11/12 15:10:41 colinmacleod
086: * Moved persistence classes from ivata op as a replacement for
087: * ValueObjectLocator.
088: *
089: * Revision 1.1.1.1 2004/05/16 20:40:32 colinmacleod
090: * Ready for 0.1 release
091: * -----------------------------------------------------------------------------
092: */
093: package com.ivata.mask.web.struts;
094:
095: import javax.servlet.http.HttpServletRequest;
096: import javax.servlet.http.HttpServletResponse;
097: import javax.servlet.http.HttpSession;
098:
099: import org.apache.log4j.Logger;
100: import org.apache.struts.action.ActionForm;
101: import org.apache.struts.action.ActionMapping;
102: import org.sourceforge.clientsession.ClientSession;
103:
104: import com.ivata.mask.Mask;
105: import com.ivata.mask.MaskFactory;
106: import com.ivata.mask.persistence.FinderException;
107: import com.ivata.mask.persistence.PersistenceManager;
108: import com.ivata.mask.persistence.PersistenceSession;
109: import com.ivata.mask.util.StringHandling;
110: import com.ivata.mask.util.SystemException;
111: import com.ivata.mask.valueobject.ValueObject;
112:
113: /**
114: * <p>
115: * View a value object in a mask for display or deletion.
116: * </p>
117: *
118: * @since ivata masks 0.1 (2004-05-10)
119: * @author Colin MacLeod <a
120: * href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
121: * @version $Revision: 1.15 $
122: */
123: public class FindAction extends MaskAction {
124: /**
125: * Logger for this class.
126: */
127: private static final Logger logger = Logger
128: .getLogger(FindAction.class);
129:
130: /**
131: * Class of value object we are to find.
132: */
133: private String baseClassName;
134:
135: /**
136: * <code>true</code> if we should only display the value object (rather
137: * than edit it).
138: */
139: private Boolean displayOnly;
140:
141: /**
142: * Unique identifier of the value object.
143: */
144: private String idString;
145:
146: /**
147: * <p>
148: * This factory is needed to access the masks and groups of masks.
149: * </p>
150: */
151: private MaskFactory maskFactory;
152:
153: /**
154: * <p>
155: * Used to locate the value objects by their unique identifier.
156: * </p>
157: */
158: private PersistenceManager persistenceManager;
159:
160: /**
161: * <p>
162: * Create a new AddAction with the given value object locator.
163: * </p>
164: *
165: * @param persistenceManagerParam
166: * used to locate the value objects by their unique identifier.
167: * @param maskFactoryParam
168: * This factory is needed to access the masks and groups of
169: * masks.
170: * @param authenticatorParam
171: * used to confirm whether or not the user should be allowed to
172: * continue, in the <code>execute</code> method.
173: */
174: public FindAction(final PersistenceManager persistenceManagerParam,
175: final MaskFactory maskFactoryParam,
176: final MaskAuthenticator authenticatorParam) {
177: super (maskFactoryParam, authenticatorParam);
178: this .maskFactory = maskFactoryParam;
179: this .persistenceManager = persistenceManagerParam;
180: }
181:
182: /**
183: * <p>
184: * Override this method to create a different class of input mask form.
185: * </p>
186: *
187: * @param requestParam
188: * request we are processing.
189: * @param valueObjectParam
190: * value object to be displayed/edited.
191: * @param maskParam
192: * mask to be edited.
193: * @param baseClassParam
194: * base class of all value objects to show in the list or
195: * associated with this mask.
196: * @since ivata op (0.10) (2004-12-31)
197: * @return new instance of <code>InputMaskForm</code>.
198: */
199: protected InputMaskForm createInputMaskForm(
200: final HttpServletRequest requestParam,
201: final ValueObject valueObjectParam, final Mask maskParam,
202: final Class baseClassParam) {
203: if (logger.isDebugEnabled()) {
204: logger.debug("createInputMaskForm(HttpServletRequest "
205: + "requestParam = " + requestParam
206: + ", ValueObject valueObjectParam = "
207: + valueObjectParam + ", Mask maskParam = "
208: + maskParam + ", Class baseClassParam = "
209: + baseClassParam + ") - start");
210: }
211:
212: InputMaskForm returnInputMaskForm = new InputMaskForm(
213: valueObjectParam, maskParam, baseClassParam);
214: if (logger.isDebugEnabled()) {
215: logger
216: .debug("createInputMaskForm(HttpServletRequest, "
217: + "ValueObject, Mask, Class) - end - return value = "
218: + returnInputMaskForm);
219: }
220: return returnInputMaskForm;
221: }
222:
223: /**
224: * <p>
225: * Generic method called by the <strong>Struts </strong> interface. Looks
226: * for a request parameter called "idString" and removes the value
227: * object with this id.
228: * </p>
229: *
230: * <p>
231: * Additionally, specifying a request parameter called "readOnly"
232: * to <code>true</code> will cause the mask form to be created in read
233: * only (display) mode.
234: * </p>
235: *
236: * <p>
237: * <copyDoc>Refer to {@link com.ivata.mask.web.struts.MaskAction#execute}.
238: * </copyDoc>
239: * </p>
240: *
241: * @param mapping {@inheritDoc}
242: * @param form {@inheritDoc}
243: * @param request {@inheritDoc}
244: * @param response {@inheritDoc}
245: * @param session {@inheritDoc}
246: * @param clientSession {@inheritDoc}
247: * @return {@inheritDoc}
248: * @throws SystemException {@inheritDoc}
249: */
250: public String execute(final ActionMapping mapping,
251: final ActionForm form, final HttpServletRequest request,
252: final HttpServletResponse response,
253: final HttpSession session, final ClientSession clientSession)
254: throws SystemException {
255: if (logger.isDebugEnabled()) {
256: logger.debug("execute(ActionMapping mapping = " + mapping
257: + ", ActionForm form = " + form
258: + ", HttpServletRequest request = " + request
259: + ", HttpServletResponse response = " + response
260: + ", HttpSession session = " + session
261: + ", ClientSession clientSession = "
262: + clientSession + ") - start");
263: }
264:
265: // first the mandatory parameters - you can set these in a subclass
266: // if you choose
267: String baseClassNameRequest = request.getParameter("baseClass");
268: if (baseClassNameRequest != null) {
269: baseClassName = baseClassNameRequest;
270: }
271: String idStringRequest = request.getParameter("idString");
272: if (idStringRequest != null) {
273: idString = idStringRequest;
274: }
275: String displayOnlyRequest = request.getParameter("displayOnly");
276: if ((displayOnlyRequest != null) || (displayOnly == null)) {
277: displayOnly = new Boolean("true".equals(displayOnlyRequest));
278: }
279: if (idString == null) {
280: throw new ValueObjectException(
281: "You must specify a request parameter called 'idString'");
282: }
283: if (baseClassName == null) {
284: throw new ValueObjectException(
285: "You must specify a request parameter called 'baseClass'");
286: }
287: Class baseClass;
288: try {
289: baseClass = Class.forName(baseClassName);
290: } catch (ClassNotFoundException e) {
291: logger
292: .error(
293: "execute(ActionMapping, ActionErrors, ActionForm, "
294: + "HttpServletRequest, HttpServletResponse, HttpSession, "
295: + "ClientSession)", e);
296:
297: throw new ValueObjectException(e);
298: }
299: PersistenceSession persistenceSession = persistenceManager
300: .openSession(request.getSession());
301: try {
302: assert (!StringHandling.isNullOrEmpty(idString));
303: ValueObject valueObject;
304: try {
305: valueObject = persistenceManager.findByPrimaryKey(
306: persistenceSession, baseClass, idString);
307: } catch (FinderException e) {
308: logger
309: .error(
310: "execute(ActionMapping, ActionErrors, "
311: + "ActionForm, HttpServletRequest, "
312: + "HttpServletResponse, HttpSession, ClientSession)",
313: e);
314:
315: valueObject = null;
316: }
317: if ((valueObject == null) && logger.isDebugEnabled()) {
318: logger.debug("No value object found with id string '"
319: + idString + "'");
320: }
321: Mask mask = maskFactory.getMask(baseClass, getInputMask(
322: request, form));
323: if (mask == null) {
324: throw new NullPointerException(
325: "ERROR in ViewAction: no mask for baseClass '"
326: + baseClass + "', type 'mask'");
327: }
328: InputMaskForm maskForm;
329: if (form instanceof InputMaskForm) {
330: maskForm = (InputMaskForm) form;
331: } else {
332: maskForm = createInputMaskForm(request, valueObject,
333: mask, baseClass);
334: }
335: // only set the display only status if it was explicitly set to
336: // something
337: if (displayOnly.booleanValue()) {
338: maskForm.setDisplayOnly(true);
339: }
340: request.setAttribute(InputMaskForm.REQUEST_ATTRIBUTE,
341: maskForm);
342:
343: if (logger.isDebugEnabled()) {
344: logger
345: .debug("execute(ActionMapping, ActionErrors, "
346: + "ActionForm, HttpServletRequest, "
347: + "HttpServletResponse, HttpSession, ClientSession) "
348: + "- end - return value = success");
349: }
350: return "success";
351: } finally {
352: persistenceSession.close();
353: }
354: }
355:
356: /**
357: * Class of value object we are to find.
358: *
359: * @return Returns the baseClassName.
360: */
361: protected String getBaseClassName() {
362: if (logger.isDebugEnabled()) {
363: logger.debug("getBaseClassName() - start");
364: }
365:
366: if (logger.isDebugEnabled()) {
367: logger.debug("getBaseClassName() - end - return value = "
368: + baseClassName);
369: }
370: return baseClassName;
371: }
372:
373: /**
374: * <code>true</code> if we should only display the value object (rather
375: * than edit it).
376: *
377: * @return Returns the displayOnly.
378: */
379: protected Boolean getDisplayOnly() {
380: if (logger.isDebugEnabled()) {
381: logger.debug("getDisplayOnly() - start");
382: }
383:
384: if (logger.isDebugEnabled()) {
385: logger.debug("getDisplayOnly() - end - return value = "
386: + displayOnly);
387: }
388: return displayOnly;
389: }
390:
391: /**
392: * Unique identifier of the value object.
393: *
394: * @return Returns the idString.
395: */
396: protected String getIdString() {
397: if (logger.isDebugEnabled()) {
398: logger.debug("getIdString() - start");
399: }
400:
401: if (logger.isDebugEnabled()) {
402: logger.debug("getIdString() - end - return value = "
403: + idString);
404: }
405: return idString;
406: }
407:
408: /**
409: * Class of value object we are to find.
410: *
411: * @param baseClassNameParam
412: * The baseClassName to set.
413: */
414: protected void setBaseClassName(final String baseClassNameParam) {
415: if (logger.isDebugEnabled()) {
416: logger.debug("setBaseClassName before: '" + baseClassName
417: + "', after: '" + baseClassNameParam + "'");
418: }
419:
420: baseClassName = baseClassNameParam;
421:
422: if (logger.isDebugEnabled()) {
423: logger.debug("setBaseClassName(String) - end");
424: }
425: }
426:
427: /**
428: * <code>true</code> if we should only display the value object (rather
429: * than edit it).
430: *
431: * @param displayOnlyParam
432: * The displayOnly to set.
433: */
434: protected void setDisplayOnly(final Boolean displayOnlyParam) {
435: if (logger.isDebugEnabled()) {
436: logger.debug("setDisplayOnly before: '" + displayOnly
437: + "', after: '" + displayOnlyParam + "'");
438: }
439:
440: displayOnly = displayOnlyParam;
441:
442: if (logger.isDebugEnabled()) {
443: logger.debug("setDisplayOnly(Boolean) - end");
444: }
445: }
446:
447: /**
448: * Unique identifier of the value object.
449: *
450: * @param idStringParam
451: * The idString to set.
452: */
453: protected void setIdString(final String idStringParam) {
454: if (logger.isDebugEnabled()) {
455: logger.debug("setIdString before: '" + idString
456: + "', after: '" + idStringParam + "'");
457: }
458:
459: idString = idStringParam;
460:
461: if (logger.isDebugEnabled()) {
462: logger.debug("setIdString(String) - end");
463: }
464: }
465: }
|