Source code: com/clra/web/SaveParticipationAction.java
1 /*
2 * Copyright (c) Carnegie Lake Rowing Association 2002. All rights reserved.
3 * Distributed under the GPL license. See doc/COPYING.
4 * $RCSfile: SaveParticipationAction.java,v $
5 * $Date: 2003/03/13 17:49:23 $
6 * $Revision: 1.5 $
7 */
8
9 package com.clra.web;
10
11 import com.clra.rowing.IParticipant;
12 import com.clra.rowing.ParticipantSnapshot;
13 import com.clra.rowing.RowingException;
14 import com.clra.rowing.RowingUtils;
15 import com.clra.rowing.SeatPreference;
16 import com.clra.util.ErrorUtils;
17 import java.io.IOException;
18 import java.rmi.RemoteException;
19 import java.text.SimpleDateFormat;
20 import java.util.Calendar;
21 import java.util.Date;
22 import javax.ejb.CreateException;
23 import javax.naming.NamingException;
24 import javax.servlet.ServletException;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpSession;
27 import javax.servlet.http.HttpServletResponse;
28 import org.apache.log4j.Category;
29 import org.apache.struts.action.Action;
30 import org.apache.struts.action.ActionForm;
31 import org.apache.struts.action.ActionForward;
32 import org.apache.struts.action.ActionMapping;
33
34 /**
35 * A workflow manager that pulls data about a rowing session from
36 * an input form. The data is used to invoke business logic that
37 * creates, edits, publishes, views, deletes or cancels a rowing session.
38 * See the related workflow manager, <tt>EditParticipationAction</tt>, which
39 * initializes an input form with data from a rowing session.
40 *
41 * @author <a href="mailto:rphall@pluto.njcc.com>Rick Hall</a>
42 * @version $Revision: 1.5 $ $Date: 2003/03/13 17:49:23 $
43 */
44 public final class SaveParticipationAction extends Action {
45
46 private final static String base = SaveParticipationAction.class.getName();
47 private final static Category theLog = Category.getInstance( base );
48
49 // Some local aliases, to make code lines shorter
50 private final static String CREATE = ParticipationForm.CREATE;
51 private final static String EDIT = ParticipationForm.EDIT;
52 private final static String VIEW = ParticipationForm.VIEW;
53 private final static String DELETE = ParticipationForm.DELETE;
54 private final static String CANCEL = ParticipationForm.CANCEL;
55
56 private final static String MEMBER = Constants.USER_KEY;
57 private final static String ROWINGID = Constants.ROWINGSESSION_KEY;
58 private final static String PARTICIPANTID = Constants.PARTICIPANT_KEY;
59
60 // Used to format debug and log messages
61 private final static SimpleDateFormat dateFormat =
62 new SimpleDateFormat("MM/dd/yy h:mm a");
63
64 /**
65 * Handle the workflow step in data about a rowing session is pulled
66 * from an input form. The data is used to invoke business logic that
67 * creates, edits, publishes, views, deletes or cancels a rowing session.
68 *
69 * @param mapping The ActionMapping used to select this instance
70 * @param actionForm The optional ActionForm bean for this request (if any)
71 * @param request The HTTP request we are processing
72 * @param response The HTTP response we are creating
73 *
74 * @exception IOException if an input/output error occurs
75 * @exception ServletException if a servlet exception occurs
76 */
77 public ActionForward perform(ActionMapping mapping, ActionForm form,
78 HttpServletRequest request, HttpServletResponse response)
79 throws IOException, ServletException {
80
81 // A null return value indicates that processing should continue
82 ActionForward retVal = null;
83
84 // Extract the workflow
85 HttpSession session = request.getSession();
86 String workflow = request.getParameter("action");
87 if (workflow == null) {
88 // The workflow is cancelled by default
89 theLog.info( "null workflow: cancelled 'SaveParticipation'" );
90 // FIXME add status message
91 retVal = mapping.findForward("success");
92 }
93 else if ( isCancelled(request) ) {
94 theLog.info("'" + workflow + "' workflow: cancelled 'SaveParticipation'");
95 // FIXME add status message
96 retVal = mapping.findForward("success");
97 }
98 else {
99 theLog.info( "proceeding with 'SaveParticipation'" );
100 if ( retVal != null ) { throw new Error( "design error" ); }
101 }
102
103 // Extract the form action
104 ParticipationForm subform = (ParticipationForm) form;
105 if ( theLog.isDebugEnabled() ) {
106 StringBuffer sb = new StringBuffer();
107 sb.append( "ParticipationForm: action == '" + subform.getAction() + "'" );
108 sb.append( ", seatPreference == '" + subform.getSeatPreference() + "'" );
109 sb.append( ", rowingId == " + subform.getRowingId() );
110 sb.append( ", state == '" + subform.getState() + "'" );
111 sb.append( ", date == "
112 + dateFormat.format(subform.getDateTimeAsDateObject()) );
113 sb.append( ", level == '" + subform.getLevel() + "'" );
114 sb.append( ", type == '" + subform.getType() + "'" );
115 theLog.debug( new String(sb) );
116 }
117 String formAction = subform.getAction();
118 if ( retVal == null && formAction == null ) {
119 theLog.error( "null formAction" );
120 // FIXME add error message
121 retVal = mapping.findForward("failure");
122 }
123
124 // Get the id of the targetted member, rowing session and participant
125 // FIXME : should this stuff be form data?
126 Integer rowingId = null;
127 Integer participantId = null;
128 Integer memberId = null;
129 if ( retVal == null ) {
130
131 // Trim the (non-null) form action
132 formAction = formAction.trim();
133
134 rowingId = (Integer) session.getAttribute(ROWINGID);
135 participantId = (Integer) session.getAttribute(PARTICIPANTID);
136 memberId = null;
137 Object o = request.getSession().getAttribute( MEMBER );
138 try {
139 memberId = ((MemberView) o).getId();
140 }
141 catch( Exception x ) {
142 theLog.error( ErrorUtils.createDbgMsg( "perform", x ) );
143 }
144
145 if ( theLog.isDebugEnabled() ) {
146 theLog.debug( "rowingId == " + rowingId );
147 theLog.debug( "memberId == " + memberId );
148 theLog.debug( "participantId == " + participantId );
149 }
150
151 if ( CREATE.equalsIgnoreCase(formAction) ) {
152 if ( rowingId == null && memberId == null ) {
153 String msg = "Missing rowingId/memberId for formAction '"
154 + formAction + "'";
155 theLog.error( msg );
156 // response.sendError(HttpServletResponse.SC_BAD_REQUEST,
157 // messages.getMessage("error.norowingId"));
158 // FIXME note that continuing with retVal==null won't work here
159 // return null;
160 //
161 // FIXME append error messages
162 retVal = mapping.findForward("failure");
163 }
164 }
165 else {
166 if ( participantId == null ) {
167 String msg = "Missing participantId for formAction '"
168 + formAction + "'";
169 theLog.error( msg );
170 // response.sendError(HttpServletResponse.SC_BAD_REQUEST,
171 // messages.getMessage("error.norowingId"));
172 // FIXME note that continuing with retVal==null won't work here
173 // return null;
174 //
175 // FIXME append error messages
176 retVal = mapping.findForward("failure");
177 }
178 }
179
180 } // end extract rowingId, memberId, participantId
181
182 // Extract the seat preference
183 SeatPreference sp = null;
184 if ( retVal == null ) {
185 String s = subform.getSeatPreference();
186 try {
187 sp = SeatPreference.getSeatPreference(s);
188 }
189 catch( Exception x ) {
190 String msg = ErrorUtils.createDbgMsg( "editParticipant", x );
191 theLog.error( msg, x );
192 // FIXME append error messages
193 retVal = mapping.findForward("failure");
194 }
195
196 }
197
198 // Check for oddball: CREATE with null seatPreference
199 if ( retVal==null && CREATE.equalsIgnoreCase(formAction) && sp==null ) {
200
201 if ( theLog.isDebugEnabled() ) {
202 String msg = "Cancelling CREATE with null seat preference";
203 theLog.debug( msg );
204 }
205
206 retVal = mapping.findForward("success");
207 }
208
209 // Perform the action specified by the form
210 if ( retVal == null ) {
211
212 if ( theLog.isDebugEnabled() ) {
213 String msg = "Processing formAction/rowingId/memberId/participantId: "
214 + formAction + "/" + rowingId + "/" + memberId + "/" + participantId;
215 theLog.debug( msg );
216 }
217
218 // All required validations were done by the form itself
219
220 try {
221
222 if ( CREATE.equalsIgnoreCase(formAction) ) {
223 createParticipant( rowingId, memberId, sp );
224 // FIXME append status messages
225 }
226 else if ( VIEW.equalsIgnoreCase(formAction) ) {
227 // Nothing to do
228 }
229 else if ( EDIT.equalsIgnoreCase(formAction) ) {
230 editParticipant( participantId, sp );
231 // FIXME append status messages
232 }
233 else {
234 String msg = "design error: " + formAction + "/" + rowingId
235 + "/" + memberId + "/" + participantId;
236 throw new Error( msg );
237 }
238
239 // Processing is complete.
240 if ( theLog.isDebugEnabled() ) {
241 String msg = "Forwarding to 'success' page: " + formAction
242 + "/" + rowingId + "/" + memberId + "/" + participantId;
243 theLog.debug( msg );
244 }
245 retVal = mapping.findForward("success");
246
247 }
248 catch( Exception x ) {
249 String msg = ErrorUtils.createDbgMsg( "perform2", x );
250 theLog.error( msg, x );
251 // FIXME append error messages
252 retVal = mapping.findForward("failure");
253 }
254
255 } // End: Perform the action specified by the form
256
257 // Remove the obsolete form bean, participantId and rowingId
258 if (mapping.getAttribute() != null) {
259 if ("request".equals(mapping.getScope())) {
260 request.removeAttribute(mapping.getAttribute());
261 }
262 else {
263 session.removeAttribute(mapping.getAttribute());
264 }
265 }
266 session.removeAttribute(PARTICIPANTID);
267 session.removeAttribute(ROWINGID);
268
269 // Forward control to the appropriate page
270 if ( retVal == null ) {
271 String msg = "null retVal for workflow/formAction == '" + workflow
272 + "'/'" + formAction + "'";
273 throw new Error( msg );
274 }
275 if ( theLog.isDebugEnabled() ) {
276 theLog.debug( "Forwarding to " + retVal.toString() );
277 }
278
279 return retVal;
280 } // perform
281
282 private static void createParticipant( Integer rowingId, Integer memberId,
283 SeatPreference sp ) throws Exception {
284
285 if ( sp == null ) {
286 String msg = "null seat preference";
287 theLog.error( msg );
288 throw new WebException( msg );
289 }
290
291 IParticipant ip = RowingUtils.createParticipant( memberId, rowingId, sp );
292
293 if ( theLog.isInfoEnabled() ) {
294 String msg = "participant created: id == " + ip.getParticipantId();
295 theLog.info( msg );
296 }
297
298 return;
299 } // createParticipant(Integer,Integer,ParticipationForm)
300
301 private static void editParticipant( final Integer participantId,
302 final SeatPreference sp ) throws Exception {
303
304 IParticipant ip = RowingUtils.findParticipant( participantId );
305
306 if ( sp == null ) {
307 // FIXME define a state-safe delete()
308 ip.remove();
309 if ( theLog.isInfoEnabled() ) {
310 String msg = "rowing session removed: participantId == "
311 + participantId + ", seatPreference == '" + null + "'";
312 theLog.info( msg );
313 }
314 }
315 else {
316 ip.setSeatPreference( sp );
317 if ( theLog.isInfoEnabled() ) {
318 String msg = "rowing session edited: participantId == "
319 + participantId + ", seatPreference == '" + sp.getName() + "'";
320 theLog.info( msg );
321 }
322 }
323
324
325 return;
326 } // editParticipant(Integer,ParticipationForm)
327
328 } // SaveParticipationAction
329
330 /*
331 * $Log: SaveParticipationAction.java,v $
332 * Revision 1.5 2003/03/13 17:49:23 rphall
333 * Fixed bug listed on SourceForge
334 *
335 * Revision 1.4 2003/02/26 03:38:46 rphall
336 * Added copyright and GPL license
337 *
338 * Revision 1.3 2003/02/19 22:09:18 rphall
339 * Removed gratuitous use of CLRA acronym
340 *
341 * Revision 1.2 2002/01/30 15:25:37 rphall
342 * Removed System.out.println debugging
343 */
344