KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > app > webui > servlet > SubmitServlet


1 /*
2  * SubmitServlet.java
3  *
4  * Version: $Revision: 1.45 $
5  *
6  * Date: $Date: 2006/11/27 16:16:49 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.app.webui.servlet;
41
42 import java.io.BufferedInputStream JavaDoc;
43 import java.io.File JavaDoc;
44 import java.io.FileInputStream JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.InputStream JavaDoc;
47 import java.sql.SQLException JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.LinkedList JavaDoc;
50 import java.util.List JavaDoc;
51
52 import javax.servlet.ServletException JavaDoc;
53 import javax.servlet.http.HttpServletRequest JavaDoc;
54 import javax.servlet.http.HttpServletResponse JavaDoc;
55
56 import org.apache.log4j.Logger;
57 import org.dspace.app.webui.util.DCInput;
58 import org.dspace.app.webui.util.DCInputsReader;
59 import org.dspace.app.webui.util.FileUploadRequest;
60 import org.dspace.app.webui.util.JSPManager;
61 import org.dspace.app.webui.util.SubmissionInfo;
62 import org.dspace.app.webui.util.UIUtil;
63 import org.dspace.authorize.AuthorizeException;
64 import org.dspace.content.Bitstream;
65 import org.dspace.content.BitstreamFormat;
66 import org.dspace.content.Bundle;
67 import org.dspace.content.Collection;
68 import org.dspace.content.Community;
69 import org.dspace.content.DCDate;
70 import org.dspace.content.DCPersonName;
71 import org.dspace.content.DCSeriesNumber;
72 import org.dspace.content.DCValue;
73 import org.dspace.content.FormatIdentifier;
74 import org.dspace.content.Item;
75 import org.dspace.content.MetadataField;
76 import org.dspace.content.WorkspaceItem;
77 import org.dspace.core.ConfigurationManager;
78 import org.dspace.core.Constants;
79 import org.dspace.core.Context;
80 import org.dspace.core.LogManager;
81 import org.dspace.eperson.EPerson;
82 import org.dspace.license.CreativeCommons;
83 import org.dspace.workflow.WorkflowItem;
84 import org.dspace.workflow.WorkflowManager;
85
86 /**
87  * Submission servlet for DSpace. Handles the initial submission of items, as
88  * well as the editing of items further down the line.
89  * <p>
90  * Whenever the submit servlet receives a GET request, this is taken to indicate
91  * the start of a fresh new submission, where no collection has been selected,
92  * and the submission process is started from scratch.
93  * <p>
94  * All other interactions happen via POSTs. Part of the post will normally be a
95  * (hidden) "step" parameter, which will correspond to the form that the user
96  * has just filled out. If this is absent, step 0 (select collection) is
97  * assumed, meaning that it's simple to place "Submit to this collection"
98  * buttons on collection home pages.
99  * <p>
100  * According to the step number of the incoming form, the values posted from the
101  * form are processed (using the process* methods), and the item updated as
102  * appropriate. The servlet then forwards control of the request to the
103  * appropriate JSP (from jsp/submit) to render the next stage of the process or
104  * an error if appropriate. Each of these JSPs may require that attributes be
105  * passed in. Check the comments at the top of a JSP to see which attributes are
106  * needed. All submit-related forms require a properly initialised
107  * SubmissionInfo object to be present in the the "submission.info" attribute.
108  * This holds the core information relevant to the submission, e.g. the item,
109  * personal workspace or workflow item, the submitting "e-person", and the
110  * target collection.
111  * <p>
112  * When control of the request reaches a JSP, it is assumed that all checks,
113  * interactions with the database and so on have been performed and that all
114  * necessary information to render the form is in memory. e.g. The
115  * SubmitFormInfo object passed in must be correctly filled out. Thus the JSPs
116  * do no error or integrity checking; it is the servlet's responsibility to
117  * ensure that everything is prepared. The servlet is fairly diligent about
118  * ensuring integrity at each step.
119  * <p>
120  * Each step has an integer constant defined below. The main sequence of the
121  * submission procedure always runs from 0 upwards, until SUBMISSION_COMPLETE.
122  * Other, not-in-sequence steps (such as the cancellation screen and the
123  * "previous version ID verification" screen) have numbers much higher than
124  * SUBMISSION_COMPLETE. These conventions allow the progress bar component of
125  * the submission forms to render the user's progress through the process.
126  *
127  * @author Robert Tansley
128  * @version $Revision: 1.45 $
129  */

130 public class SubmitServlet extends DSpaceServlet
131 {
132     // Steps in the submission process
133

134     /** Selection collection step */
135     public static final int SELECT_COLLECTION = 0;
136
137     /** Ask initial questions about the submission step */
138     public static final int INITIAL_QUESTIONS = 1;
139
140     /** Edit DC metadata first page step */
141     public static final int EDIT_METADATA_1 = 2;
142
143     /** Edit DC metadata last page step
144      * Current value allows up to 6 distinct pages.
145      * If more are needed, renumber this value and those
146      * that follow it (up to SUBMISSION_COMPLETE), but
147      * note that the progress bar will stretch badly beyond 6.
148      */

149     public static final int EDIT_METADATA_2 = 7;
150
151     /**
152      * Upload files step. Note this doesn't correspond to an actual page, since
153      * the upload file step consists of a number of pages with no definite
154      * order. This is just used for the progress bar.
155      */

156     public static final int UPLOAD_FILES = 8;
157
158     /** Review submission step */
159     public static final int REVIEW_SUBMISSION = 9;
160
161     /** optional CC license step */
162     public static final int CC_LICENSE = 10;
163
164     /** Grant (deposit) license step */
165     public static final int GRANT_LICENSE = 11;
166
167     /** Submission completed step */
168     public static final int SUBMISSION_COMPLETE = 12;
169     
170     // Steps which aren't part of the main sequence, but rather
171
// short "diversions" are given high step numbers. The main sequence
172
// is defined as being steps 0 to SUBMISSION_COMPLETE.
173

174     /** Cancellation of a submission */
175     public static final int SUBMISSION_CANCELLED = 101;
176
177     /** List of uploaded files */
178     public static final int FILE_LIST = 102;
179
180     /** Choose file page */
181     public static final int CHOOSE_FILE = 103;
182
183     /** File format page */
184     public static final int GET_FILE_FORMAT = 104;
185
186     /** Error uploading file */
187     public static final int UPLOAD_ERROR = 105;
188
189     /** Change file description page */
190     public static final int CHANGE_FILE_DESCRIPTION = 106;
191
192     /**
193      * Verify pruning of extra files, titles, dates as a result of changing an
194      * answer to one of the initial questions
195      */

196     public static final int VERIFY_PRUNE = 107;
197
198     /** log4j logger */
199     private static Logger log = Logger.getLogger(SubmitServlet.class);
200     
201     /** hash of all submission forms details */
202     private DCInputsReader inputsReader;
203     
204     public SubmitServlet()
205         throws ServletException JavaDoc
206     {
207     // read configurable submissions forms data
208
inputsReader = new DCInputsReader();
209     }
210
211     protected void doDSGet(Context context, HttpServletRequest JavaDoc request,
212             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
213             SQLException JavaDoc, AuthorizeException
214     {
215         /*
216          * Possible GET parameters:
217          *
218          * resume= <workspace_item_id> - Resumes submitting the given workspace
219          * item
220          *
221          * workflow= <workflow_id> - Starts editing the given workflow item in
222          * workflow mode
223          *
224          * With no parameters, A GET starts a new submission. What happens
225          * depends on the context of the user (where they are.) If they're not
226          * in a community or collection, they can choose any collection from the
227          * list of all collections. If they're in a community, the list of
228          * collections they can choose from will be limited to those within the
229          * current community. If the user has selected a collection, a new
230          * submission will be started in that collection.
231          */

232         String JavaDoc workspaceID = request.getParameter("resume");
233
234         if (workspaceID != null)
235         {
236             try
237             {
238                 WorkspaceItem wi = WorkspaceItem.find(context, Integer
239                         .parseInt(workspaceID));
240
241                 SubmissionInfo si = new SubmissionInfo();
242                 si.submission = wi;
243                 doStep(context, request, response, si, INITIAL_QUESTIONS);
244             }
245             catch (NumberFormatException JavaDoc nfe)
246             {
247                 log.warn(LogManager.getHeader(context, "bad_workspace_id",
248                         "bad_id=" + workspaceID));
249                 JSPManager.showInvalidIDError(request, response, workspaceID,
250                         -1);
251             }
252
253             return;
254         }
255
256         String JavaDoc workflowID = request.getParameter("workflow");
257
258         if (workflowID != null)
259         {
260             try
261             {
262                 WorkflowItem wi = WorkflowItem.find(context, Integer
263                         .parseInt(workflowID));
264
265                 SubmissionInfo si = new SubmissionInfo();
266                 si.submission = wi;
267                 doStep(context, request, response, si, INITIAL_QUESTIONS);
268             }
269             catch (NumberFormatException JavaDoc nfe)
270             {
271                 log.warn(LogManager.getHeader(context, "bad_workflow_id",
272                         "bad_id=" + workflowID));
273                 JSPManager
274                         .showInvalidIDError(request, response, workflowID, -1);
275             }
276
277             return;
278         }
279
280         Community com = UIUtil.getCommunityLocation(request);
281         Collection col = UIUtil.getCollectionLocation(request);
282
283         if (col != null)
284         {
285             // In a collection, skip the "choose selection" stage
286
// Create a workspace item
287
WorkspaceItem wi = WorkspaceItem.create(context, col, true);
288
289             // Proceed to first step
290
SubmissionInfo si = new SubmissionInfo();
291             si.submission = wi;
292             doStep(context, request, response, si, INITIAL_QUESTIONS);
293             context.complete();
294         }
295         else
296         {
297             Collection[] collections;
298
299             if (com != null)
300             {
301                 // In a community. Show collections in that community only.
302
collections = Collection.findAuthorized(context, com,
303                         Constants.ADD);
304             }
305             else
306             {
307                 // Show all collections
308
collections = Collection.findAuthorized(context, null,
309                         Constants.ADD);
310             }
311
312             log.info(LogManager.getHeader(context, "select_collection", ""));
313
314             request.setAttribute("collections", collections);
315             JSPManager.showJSP(request, response,
316                     "/submit/select-collection.jsp");
317         }
318     }
319
320     protected void doDSPost(Context context, HttpServletRequest JavaDoc request,
321             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
322             SQLException JavaDoc, AuthorizeException
323     {
324         // First of all, we need to work out if this is a multipart request
325
// The file upload page uses those
326
String JavaDoc contentType = request.getContentType();
327
328         if ((contentType != null)
329                 && (contentType.indexOf("multipart/form-data") != -1))
330         {
331             // This is a multipart request, so it's a file upload
332
processChooseFile(context, request, response);
333
334             return;
335         }
336
337         // First get the step
338
int step = UIUtil.getIntParameter(request, "step");
339
340         // select collection is a special case - no submissioninfo object
341
// If no step was given, we also assume "select collection"
342
// (Submit button on collection home page or elsewhere)
343
if ((step == SELECT_COLLECTION) || (step == -1))
344         {
345             processSelectCollection(context, request, response);
346
347             return;
348         }
349
350         // Get submission info
351
SubmissionInfo subInfo = getSubmissionInfo(context, request);
352
353         if (subInfo == null)
354         {
355             /*
356              * Work around for problem where people select "is a thesis", see
357              * the error page, and then use their "back" button thinking they
358              * can start another submission - it's been removed so the ID in the
359              * form is invalid. If we detect the "removed_thesis" attribute we
360              * display a friendly message instead of an integrity error.
361              */

362             if (request.getSession().getAttribute("removed_thesis") != null)
363             {
364                 request.getSession().removeAttribute("removed_thesis");
365                 JSPManager.showJSP(request, response,
366                         "/submit/thesis-removed-workaround.jsp");
367
368                 return;
369             }
370             else
371             {
372                 /*
373                  * If the submission info was invalid, set the step to an
374                  * invalid number so an integrity error will be shown
375                  */

376                 step = -1;
377             }
378         }
379         
380         if (step >= EDIT_METADATA_1 && step <= EDIT_METADATA_2)
381         {
382             processEditMetadata(context, request, response, subInfo, step);
383             return;
384         }
385
386         switch (step)
387         {
388         case INITIAL_QUESTIONS:
389             processInitialQuestions(context, request, response, subInfo);
390
391             break;
392   
393         case GET_FILE_FORMAT:
394             processGetFileFormat(context, request, response, subInfo);
395
396             break;
397
398         case FILE_LIST:
399             processFileList(context, request, response, subInfo);
400
401             break;
402
403         case UPLOAD_ERROR:
404             processUploadError(context, request, response, subInfo);
405
406             break;
407
408         case CHANGE_FILE_DESCRIPTION:
409             processChangeFileDescription(context, request, response, subInfo);
410
411             break;
412
413         case REVIEW_SUBMISSION:
414             processReview(context, request, response, subInfo);
415
416             break;
417
418         case CC_LICENSE:
419             processCC(context, request, response, subInfo);
420
421             break;
422
423         case GRANT_LICENSE:
424             processLicense(context, request, response, subInfo);
425
426             break;
427
428         case SUBMISSION_CANCELLED:
429             processCancellation(context, request, response, subInfo);
430
431             break;
432
433         case VERIFY_PRUNE:
434             processVerifyPrune(context, request, response, subInfo);
435
436             break;
437
438         default:
439             log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
440                     .getRequestLogInfo(request)));
441             JSPManager.showIntegrityError(request, response);
442         }
443     }
444
445     //****************************************************************
446
//****************************************************************
447
// METHODS FOR PROCESSING POSTED FORMS
448
//****************************************************************
449
//****************************************************************
450

451     /**
452      * Process the selection collection stage, or the clicking of a "submit to
453      * this collection" button on a collection home page.
454      *
455      * @param context
456      * current DSpace context
457      * @param request
458      * current servlet request object
459      * @param response
460      * current servlet response object
461      */

462     private void processSelectCollection(Context context,
463             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
464             throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
465             AuthorizeException
466     {
467         // The user might have clicked cancel. We don't do a
468
// standard cancellation at this stage, since we don't
469
// actually have an item to keep or remove yet.
470
if (request.getParameter("submit_cancel") != null)
471         {
472             // Just send them to their "My DSpace" for now.
473
response.sendRedirect(response.encodeRedirectURL(request
474                     .getContextPath()
475                     + "/mydspace"));
476
477             return;
478         }
479
480         // First we find the collection
481
int id = UIUtil.getIntParameter(request, "collection");
482         Collection col = Collection.find(context, id);
483
484         // Show an error if we don't have a collection
485
if (col == null)
486         {
487             JSPManager.showInvalidIDError(request, response, request
488                     .getParameter("collection"), Constants.COLLECTION);
489         }
490         else
491         {
492             WorkspaceItem wi = WorkspaceItem.create(context, col, true);
493
494             // Proceed to first step
495
SubmissionInfo si = new SubmissionInfo();
496             si.submission = wi;
497             doStep(context, request, response, si, INITIAL_QUESTIONS);
498
499             context.complete();
500         }
501     }
502
503     /**
504      * process input from initial-questions.jsp
505      *
506      * @param context
507      * current DSpace context
508      * @param request
509      * current servlet request object
510      * @param response
511      * current servlet response object
512      * @param subInfo
513      * submission info object
514      */

515     private void processInitialQuestions(Context context,
516             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
517             SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
518             SQLException JavaDoc, AuthorizeException
519     {
520         String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_next");
521
522         // Firstly, check for a click of the cancel button.
523
if (buttonPressed.equals("submit_cancel"))
524         {
525             doCancellation(request, response, subInfo, INITIAL_QUESTIONS,
526                     INITIAL_QUESTIONS);
527
528             return;
529         }
530
531         // Get the values from the form
532
boolean multipleTitles = UIUtil.getBoolParameter(request,
533                 "multiple_titles");
534         boolean publishedBefore = UIUtil.getBoolParameter(request,
535                 "published_before");
536         boolean multipleFiles = UIUtil.getBoolParameter(request,
537                 "multiple_files");
538         boolean isThesis = ConfigurationManager
539                 .getBooleanProperty("webui.submit.blocktheses")
540                 && UIUtil.getBoolParameter(request, "is_thesis");
541
542         if (isWorkflow(subInfo))
543         {
544             // Thesis question does not appear in workflow mode..
545
isThesis = false;
546
547             // Pretend "multiple files" is true in workflow mode
548
// (There will always be the license file)
549
multipleFiles = true;
550         }
551
552         // First and foremost - if it's a thesis, reject the submission
553
if (isThesis)
554         {
555             WorkspaceItem wi = (WorkspaceItem) subInfo.submission;
556             wi.deleteAll();
557
558             // Remember that we've removed a thesis in the session
559
request.getSession().setAttribute("removed_thesis",
560                     new Boolean JavaDoc(true));
561
562             // Display appropriate message
563
JSPManager.showJSP(request, response, "/submit/no-theses.jsp");
564
565             context.complete();
566
567             return;
568         }
569
570         // Now check to see if the changes will remove any values
571
// (i.e. multiple files, titles or an issue date.)
572
boolean willRemoveTitles = false;
573         boolean willRemoveDate = false;
574         boolean willRemoveFiles = false;
575
576         if (multipleTitles == false)
577         {
578             DCValue[] altTitles = subInfo.submission.getItem().getDC(
579                     "title", "alternative", Item.ANY);
580
581             willRemoveTitles = altTitles.length > 0;
582         }
583
584         if (publishedBefore == false)
585         {
586             DCValue[] dateIssued = subInfo.submission.getItem().getDC("date",
587                     "issued", Item.ANY);
588             DCValue[] citation = subInfo.submission.getItem().getDC(
589                     "identifier", "citation", Item.ANY);
590             DCValue[] publisher = subInfo.submission.getItem().getDC(
591                     "publisher", null, Item.ANY);
592
593             willRemoveDate = (dateIssued.length > 0) || (citation.length > 0)
594                     || (publisher.length > 0);
595         }
596
597         if (multipleFiles == false)
598         {
599             // see if number of bitstreams in "ORIGINAL" bundle > 1
600
// FIXME: Assumes multiple bundles, clean up someday...
601
Bundle[] bundles = subInfo.submission.getItem().getBundles(
602                     "ORIGINAL");
603
604             if (bundles.length > 0)
605             {
606                 Bitstream[] bitstreams = bundles[0].getBitstreams();
607
608                 willRemoveFiles = bitstreams.length > 1;
609             }
610         }
611
612         // If anything is going to be removed from the item as a result
613
// of changing the answer to one of the questions, we need
614
// to inform the user and make sure that's OK
615
if (willRemoveTitles || willRemoveDate || willRemoveFiles)
616         {
617             // Verify pruning of extra bits
618
request.setAttribute("submission.info", subInfo);
619             request
620                     .setAttribute("multiple.titles",
621                             new Boolean JavaDoc(multipleTitles));
622             request.setAttribute("published.before", new Boolean JavaDoc(
623                     publishedBefore));
624             request.setAttribute("multiple.files", new Boolean JavaDoc(multipleFiles));
625             request.setAttribute("will.remove.titles", new Boolean JavaDoc(
626                     willRemoveTitles));
627             request.setAttribute("will.remove.date",
628                     new Boolean JavaDoc(willRemoveDate));
629             request.setAttribute("will.remove.files", new Boolean JavaDoc(
630                     willRemoveFiles));
631             request.setAttribute("button.pressed", UIUtil.getSubmitButton(
632                     request, "submit_next"));
633
634             JSPManager.showJSP(request, response, "/submit/verify-prune.jsp");
635         }
636         else
637         {
638             // Nothing needs removing, so just make the changes
639
subInfo.submission.setMultipleTitles(multipleTitles);
640             subInfo.submission.setPublishedBefore(publishedBefore);
641
642             // "Multiple files" irrelevant in workflow mode
643
if (!isWorkflow(subInfo))
644             {
645                 subInfo.submission.setMultipleFiles(multipleFiles);
646             }
647
648             subInfo.submission.update();
649
650             // On to the next stage
651
if (buttonPressed.equals("submit_next"))
652             {
653                 // Update user's progress
654
userHasReached(subInfo, EDIT_METADATA_1);
655
656                 // User has clicked "Next"
657
doStep(context, request, response, subInfo, EDIT_METADATA_1);
658             }
659             else
660             {
661                 // Progress bar button clicked
662
doStepJump(context, request, response, subInfo);
663             }
664
665             context.complete();
666         }
667     }
668
669     /**
670      * Process input from "verify prune" step
671      *
672      * @param context
673      * current DSpace context
674      * @param request
675      * current servlet request object
676      * @param response
677      * current servlet response object
678      * @param subInfo
679      * submission info object
680      */

681     private void processVerifyPrune(Context context,
682             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
683             SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
684             SQLException JavaDoc, AuthorizeException
685     {
686         if (request.getParameter("do_not_proceed") != null)
687         {
688             // User cancelled
689
doStep(context, request, response, subInfo, INITIAL_QUESTIONS);
690
691             return;
692         }
693
694         // User elected to proceed - do the pruning
695
// Get the values from the form
696
boolean multipleTitles = UIUtil.getBoolParameter(request,
697                 "multiple_titles");
698         boolean publishedBefore = UIUtil.getBoolParameter(request,
699                 "published_before");
700
701         // Multiple files question does not appear in workflow mode.
702
// Since the submission will have a license, the answer to
703
// this question will always be "yes"
704
boolean multipleFiles = (isWorkflow(subInfo) || UIUtil
705                 .getBoolParameter(request, "multiple_files"));
706
707         Item item = subInfo.submission.getItem();
708
709         if (!multipleTitles)
710         {
711             item.clearDC("title", "alternative", Item.ANY);
712         }
713
714         if (publishedBefore == false)
715         {
716             item.clearDC("date", "issued", Item.ANY);
717             item.clearDC("identifier", "citation", Item.ANY);
718             item.clearDC("publisher", null, Item.ANY);
719         }
720
721         if (multipleFiles == false)
722         {
723             // remove all but first bitstream from bundle[0]
724
// FIXME: Assumes multiple bundles, clean up someday...
725
// (only messes with the first bundle.)
726
Bundle[] bundles = item.getBundles("ORIGINAL");
727
728             if (bundles.length > 0)
729             {
730                 Bitstream[] bitstreams = bundles[0].getBitstreams();
731
732                 // Remove all but the first bitstream
733
for (int i = 1; i < bitstreams.length; i++)
734                 {
735                     bundles[0].removeBitstream(bitstreams[i]);
736                 }
737             }
738         }
739
740         // Nothing needs removing, so just make the changes
741
subInfo.submission.setMultipleTitles(multipleTitles);
742         subInfo.submission.setPublishedBefore(publishedBefore);
743
744         // "Multiple files" irrelevant in workflow mode
745
if (!isWorkflow(subInfo))
746         {
747             subInfo.submission.setMultipleFiles(multipleFiles);
748         }
749
750         subInfo.submission.update();
751
752         // Everything went OK if we get to here, so now response
753
// to the original button press
754
if (request.getParameter("submit_next") != null)
755         {
756             // Update user's progress
757
userHasReached(subInfo, EDIT_METADATA_1);
758
759             // User has clicked "Next"
760
doStep(context, request, response, subInfo, EDIT_METADATA_1);
761
762             context.complete();
763         }
764         else
765         {
766             // Progress bar button clicked
767
doStepJump(context, request, response, subInfo);
768
769             context.complete();
770         }
771     }
772
773     /**
774      * process input from edit-metadata.jsp
775      *
776      * @param context
777      * current DSpace context
778      * @param request
779      * current servlet request object
780      * @param response
781      * current servlet response object
782      * @param subInfo
783      * submission info object
784      * @param curStep
785      * page number in edit sequence, starting at zero
786      */

787     private void processEditMetadata(Context context,
788         HttpServletRequest JavaDoc request,
789         HttpServletResponse JavaDoc response,
790         SubmissionInfo subInfo,
791         int curStep)
792         throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc, AuthorizeException
793     {
794         String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_next");
795
796         // Firstly, check for a click of the cancel button.
797
if (buttonPressed.equals("submit_cancel"))
798         {
799             doCancellation(request, response, subInfo, curStep, curStep);
800             return;
801         }
802
803         Item item = subInfo.submission.getItem();
804         
805         // lookup applicable inputs
806
Collection c = subInfo.submission.getCollection();
807         DCInput[] inputs = inputsReader.getInputs(c.getHandle()).getPageRows(curStep - EDIT_METADATA_1,
808                                      subInfo.submission.hasMultipleTitles(),
809                                      subInfo.submission.isPublishedBefore());
810  
811         // clear out all item metadata defined for this collection and page
812
for (int i = 0; i < inputs.length; i++)
813         {
814             String JavaDoc dcQualifier = inputs[i].getQualifier();
815             if (dcQualifier == null && inputs[i].getInputType().equals("qualdrop_value"))
816             {
817                 dcQualifier = Item.ANY;
818             }
819             item.clearMetadata(inputs[i].getSchema(), inputs[i].getElement(), dcQualifier, Item.ANY);
820         }
821
822         // now update the item metadata.
823
String JavaDoc fieldName;
824         boolean moreInput = false;
825         for (int j = 0; j < inputs.length; j++)
826         {
827            String JavaDoc dcElement = inputs[j].getElement();
828            String JavaDoc dcQualifier = inputs[j].getQualifier();
829            String JavaDoc dcSchema = inputs[j].getSchema();
830            if (dcQualifier != null && ! dcQualifier.equals(Item.ANY))
831            {
832                 fieldName = dcSchema + "_" + dcElement + '_' + dcQualifier;
833            }
834            else
835            {
836                 fieldName = dcSchema + "_" + dcElement;
837            }
838
839            String JavaDoc inputType = inputs[j].getInputType();
840            if (inputType.equals("name"))
841            {
842                 readNames(request, item, dcSchema, dcElement, dcQualifier,
843                           inputs[j].getRepeatable());
844            }
845            else if (inputType.equals("date"))
846            {
847                 readDate(request, item, dcSchema, dcElement, dcQualifier);
848            }
849            else if (inputType.equals("series"))
850            {
851                 readSeriesNumbers(request, item, dcSchema, dcElement, dcQualifier,
852                                   inputs[j].getRepeatable());
853            }
854            else if (inputType.equals("qualdrop_value"))
855            {
856               List JavaDoc quals = getRepeatedParameter(request, dcSchema + "_" + dcElement + "_qualifier");
857               List JavaDoc vals = getRepeatedParameter(request, dcSchema + "_" + dcElement + "_value");
858               for (int z = 0; z < vals.size(); z++)
859               {
860                     String JavaDoc thisQual = (String JavaDoc)quals.get(z);
861                     if ( "".equals(thisQual) )
862                     {
863                         thisQual = null;
864                     }
865                     String JavaDoc thisVal = (String JavaDoc)vals.get(z);
866                     if (! buttonPressed.equals("submit_" + dcSchema + "_" + dcElement + "_remove_" + z) &&
867                         ! thisVal.equals(""))
868                     {
869                         item.addMetadata(dcSchema, dcElement, thisQual, null, thisVal);
870                     }
871               }
872            }
873            else if (inputType.equals("dropdown"))
874            {
875               String JavaDoc[] vals = request.getParameterValues(fieldName);
876               if (vals != null)
877               {
878                 for (int z = 0; z < vals.length; z++)
879                 {
880                     if (!vals[z].equals(""))
881                     {
882                         item.addMetadata(dcSchema, dcElement, dcQualifier, "en", vals[z]);
883                     }
884                 }
885               }
886            }
887            else if ((inputType.equals("onebox")) || (inputType.equals("twobox")) ||
888                     (inputType.equals("textarea")))
889            {
890                 readText(request, item, dcSchema, dcElement, dcQualifier,
891                          inputs[j].getRepeatable(), "en");
892            }
893            else
894            {
895                throw new ServletException JavaDoc("Field "+ fieldName +
896                                           " has an unknown input type: " + inputType);
897            }
898
899            // Proceed according to button pressed
900
if (! moreInput && buttonPressed.equals("submit_" + fieldName + "_more"))
901            {
902               subInfo.moreBoxesFor = fieldName;
903               subInfo.jumpToField = fieldName;
904               moreInput = true;
905            }
906         }
907         
908         int nextStep = -1;
909         if ( moreInput )
910         {
911             nextStep = curStep;
912         }
913         
914         if (buttonPressed.equals("submit_prev"))
915         {
916             // NB: code here assumes steps are sequentially numbered!
917
nextStep = curStep-1;
918         }
919         else if (buttonPressed.equals("submit_next"))
920         {
921             // scan for missing fields
922
String JavaDoc gotoField = null;
923             subInfo.missingFields = new ArrayList JavaDoc();
924             //subInfo.missingRowNums = new Vector();
925
for (int i = 0; i < inputs.length; i++)
926             {
927                 String JavaDoc element = inputs[i].getElement();
928                 String JavaDoc qual = inputs[i].getQualifier();
929                 String JavaDoc schema = inputs[i].getSchema();
930                 log.info(" inner "+schema);
931                 DCValue[] valArray = item.getMetadata(schema, element, qual, Item.ANY);
932                 boolean isEmpty = (valArray.length == 0);
933                 if (inputs[i].isRequired() && isEmpty)
934                 {
935                     subInfo.missingFields.add( new Integer JavaDoc(i) );
936                     if (qual != null && !qual.equals("*"))
937                     {
938                         gotoField = schema + "_" + element + '_' + qual;
939                     }
940                     else
941                     {
942                         gotoField = schema + "_" + element;
943                     }
944                 }
945             }
946             // return to current edit metadata screen if any fields missing
947
if (subInfo.missingFields.size() > 0 )
948             {
949                 subInfo.jumpToField = gotoField;
950                 nextStep = curStep;
951             }
952             else
953             {
954                 // determine next step - skipping unused MD pages
955
int lastMDPage = EDIT_METADATA_1 + inputsReader.getNumberInputPages(c.getHandle()) - 1;
956                 if ( curStep == lastMDPage )
957                 {
958                     curStep = EDIT_METADATA_2;
959                 }
960                 userHasReached(subInfo, curStep+1);
961                 nextStep = curStep+1;
962             }
963         }
964         else if (buttonPressed.indexOf("remove") > -1)
965         {
966             // Remove button pressed - stay with same form
967
nextStep = curStep;
968         }
969
970         // Write changes to database
971
subInfo.submission.update();
972
973         if (nextStep != -1)
974         {
975             doStep(context, request, response, subInfo, nextStep);
976         }
977         else
978         {
979             doStepJump(context, request, response, subInfo);
980         }
981
982         context.complete();
983     }
984
985     /**
986      * Process the input from the choose file page
987      *
988      * @param context
989      * current DSpace context
990      * @param request
991      * current servlet request object
992      * @param response
993      * current servlet response object
994      */

995     private void processChooseFile(Context context, HttpServletRequest JavaDoc request,
996             HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc,
997             SQLException JavaDoc, AuthorizeException
998     {
999         File JavaDoc temp = null;
1000        FileUploadRequest wrapper = null;
1001        SubmissionInfo subInfo = null;
1002        boolean ok = false;
1003        String JavaDoc buttonPressed = null;
1004        BitstreamFormat bf = null;
1005        Bitstream b = null;
1006
1007        /*
1008         * To distinguish between an IOException caused by a problem with the
1009         * file upload and one caused by displaying a JSP, we do all the upload
1010         * handling in a try/catch block
1011         */

1012        try
1013        {
1014            // Wrap multipart request to get the submission info
1015
wrapper = new FileUploadRequest(request);
1016
1017            subInfo = getSubmissionInfo(context, wrapper);
1018            buttonPressed = UIUtil.getSubmitButton(wrapper, "submit_next");
1019
1020            if ((subInfo != null) && buttonPressed.equals("submit_next"))
1021            {
1022                // Create the bitstream
1023
Item item = subInfo.submission.getItem();
1024
1025                temp = wrapper.getFile("file");
1026
1027                if (temp != null && temp.length() > 0)
1028                {
1029                    // Read the temp file into a bitstream
1030
InputStream JavaDoc is = new BufferedInputStream JavaDoc(
1031                            new FileInputStream JavaDoc(temp));
1032
1033                    // do we already have a bundle?
1034
Bundle[] bundles = item.getBundles("ORIGINAL");
1035
1036                    if (bundles.length < 1)
1037                    {
1038                        // set bundle's name to ORIGINAL
1039
b = item.createSingleBitstream(is, "ORIGINAL");
1040                    }
1041                    else
1042                    {
1043                        // we have a bundle already, just add bitstream
1044
b = bundles[0].createBitstream(is);
1045                    }
1046
1047                    // Strip all but the last filename. It would be nice
1048
// to know which OS the file came from.
1049
String JavaDoc noPath = wrapper.getFilesystemName("file");
1050
1051                    while (noPath.indexOf('/') > -1)
1052                    {
1053                        noPath = noPath.substring(noPath.indexOf('/') + 1);
1054                    }
1055
1056                    while (noPath.indexOf('\\') > -1)
1057                    {
1058                        noPath = noPath.substring(noPath.indexOf('\\') + 1);
1059                    }
1060
1061                    b.setName(noPath);
1062                    b.setSource(wrapper.getFilesystemName("file"));
1063                    b.setDescription(wrapper.getParameter("description"));
1064
1065                    // Identify the format
1066
bf = FormatIdentifier.guessFormat(context, b);
1067
1068                    b.setFormat(bf);
1069                    
1070                    // Update to DB
1071
b.update();
1072                    item.update();
1073
1074                    if (bf == null || !bf.isInternal())
1075                    {
1076                        ok = true;
1077                    }
1078                    else
1079                    {
1080                        log.info("Attempt to upload file format marked as internal system use only");
1081                    }
1082                }
1083            }
1084        }
1085        catch (IOException JavaDoc ie)
1086        {
1087            // Problem with uploading
1088
log.warn(LogManager.getHeader(context, "upload_error", ""), ie);
1089        }
1090
1091        if (subInfo == null)
1092        {
1093            // In any event, if we don't have the submission info, the request
1094
// was malformed
1095
log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
1096                    .getRequestLogInfo(request)));
1097        }
1098        else if (buttonPressed.equals("submit_cancel"))
1099        {
1100            doCancellation(request, response, subInfo,
1101                    SubmitServlet.CHOOSE_FILE, SubmitServlet.UPLOAD_FILES);
1102        }
1103        else if (buttonPressed.equals("submit_prev"))
1104        {
1105            // Slightly tricky; if the user clicks on "previous,"
1106
// and they haven't uploaded any files yet, the previous
1107
// screen is the edit metadata 2 page. If there are
1108
// upload files, we go back to the file list page,
1109
// without uploading the file they've specified.
1110
if (subInfo.submission.getItem().getBundles("ORIGINAL").length > 0)
1111            {
1112                // Have files, go to list
1113
showUploadFileList(request, response, subInfo, false, false);
1114            }
1115            else
1116            {
1117                // No files, go back to last edit metadata page
1118
Collection c = subInfo.submission.getCollection();
1119                int lastPage = EDIT_METADATA_1 +
1120                               inputsReader.getNumberInputPages( c.getHandle() ) - 1;
1121                doStep(context, request, response, subInfo, lastPage);
1122            }
1123        }
1124        else if (buttonPressed.equals("submit_next"))
1125        {
1126            // "Next" pressed - the actual upload was handled above.
1127
if (ok)
1128            {
1129                // Uploaded etc. OK
1130
if (bf != null)
1131                {
1132                    // Format was identified
1133
showUploadFileList(request, response, subInfo, true, false);
1134                }
1135                else
1136                {
1137                    // Format couldn't be identified
1138
showGetFileFormat(context, request, response, subInfo, b);
1139                }
1140
1141                context.complete();
1142            }
1143            else
1144            {
1145                // If we get here, there was a problem uploading, but we
1146
// still know which submission we're dealing with
1147
showProgressAwareJSP(request, response, subInfo,
1148                             "/submit/upload-error.jsp");
1149            }
1150        }
1151        else
1152        {
1153            doStepJump(context, wrapper, response, subInfo);
1154        }
1155
1156        // Remove temp file if it's still around
1157
if (temp != null)
1158        {
1159            temp.delete();
1160        }
1161    }
1162
1163    /**
1164     * Process input from get file type page
1165     *
1166     * @param context
1167     * current DSpace context
1168     * @param request
1169     * current servlet request object
1170     * @param response
1171     * current servlet response object
1172     * @param subInfo
1173     * submission info object
1174     */

1175    private void processGetFileFormat(Context context,
1176            HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1177            SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
1178            SQLException JavaDoc, AuthorizeException
1179    {
1180        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit");
1181
1182        if (subInfo.bitstream != null)
1183        {
1184            // Did the user select a format?
1185
int typeID = UIUtil.getIntParameter(request, "format");
1186
1187            BitstreamFormat format = BitstreamFormat.find(context, typeID);
1188
1189            if (format != null)
1190            {
1191                subInfo.bitstream.setFormat(format);
1192            }
1193            else
1194            {
1195                String JavaDoc userDesc = request.getParameter("format_description");
1196                subInfo.bitstream.setUserFormatDescription(userDesc);
1197            }
1198
1199            subInfo.bitstream.update();
1200
1201            if (buttonPressed.equals("submit"))
1202            {
1203                showUploadFileList(request, response, subInfo, true, false);
1204            }
1205            else
1206            {
1207                doStepJump(context, request, response, subInfo);
1208            }
1209
1210            context.complete();
1211        }
1212        else
1213        {
1214            log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
1215                    .getRequestLogInfo(request)));
1216            JSPManager.showIntegrityError(request, response);
1217        }
1218    }
1219
1220    /**
1221     * Process input from file list page
1222     *
1223     * @param context
1224     * current DSpace context
1225     * @param request
1226     * current servlet request object
1227     * @param response
1228     * current servlet response object
1229     * @param subInfo
1230     * submission info object
1231     */

1232    private void processFileList(Context context, HttpServletRequest JavaDoc request,
1233            HttpServletResponse JavaDoc response, SubmissionInfo subInfo)
1234            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
1235            AuthorizeException
1236    {
1237        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_next");
1238        Item item = subInfo.submission.getItem();
1239
1240        if (buttonPressed.equals("submit_cancel"))
1241        {
1242            doCancellation(request, response, subInfo, SubmitServlet.FILE_LIST,
1243                    SubmitServlet.UPLOAD_FILES);
1244        }
1245        else if (buttonPressed.equals("submit_prev"))
1246        {
1247            // In some cases, this might be expected to go back
1248
// to the "choose file" page, but that doesn't make
1249
// a great deal of sense, so go back to last edit metadata page.
1250
Collection c = subInfo.submission.getCollection();
1251            int lastPage = EDIT_METADATA_1 +
1252                           inputsReader.getNumberInputPages( c.getHandle() ) - 1;
1253            doStep(context, request, response, subInfo, lastPage);
1254        }
1255        else if (buttonPressed.equals("submit_next"))
1256        {
1257            // Finished the uploading of files
1258
// FIXME Validation check here
1259
// set primary bitstream
1260
if (request.getParameter("primary_bitstream_id") != null)
1261            {
1262                Bundle[] bundles = item.getBundles("ORIGINAL");
1263                bundles[0].setPrimaryBitstreamID(new Integer JavaDoc(request
1264                        .getParameter("primary_bitstream_id")).intValue());
1265                bundles[0].update();
1266            }
1267
1268            userHasReached(subInfo, REVIEW_SUBMISSION);
1269            doStep(context, request, response, subInfo, REVIEW_SUBMISSION);
1270            context.complete();
1271        }
1272        else if (buttonPressed.equals("submit_more"))
1273        {
1274            // set primary bitstream
1275
if (request.getParameter("primary_bitstream_id") != null)
1276            {
1277                Bundle[] bundles = item.getBundles("ORIGINAL");
1278                bundles[0].setPrimaryBitstreamID(new Integer JavaDoc(request
1279                        .getParameter("primary_bitstream_id")).intValue());
1280                bundles[0].update();
1281                context.commit();
1282            }
1283
1284            // Upload another file
1285
showProgressAwareJSP(request, response, subInfo, "/submit/choose-file.jsp");
1286        }
1287        else if (buttonPressed.equals("submit_show_checksums"))
1288        {
1289            // Show the checksums
1290
showUploadFileList(request, response, subInfo, false, true);
1291        }
1292        else if (buttonPressed.startsWith("submit_describe_"))
1293        {
1294            // Change the description of a bitstream
1295
Bitstream bitstream;
1296
1297            // Which bitstream does the user want to describe?
1298
try
1299            {
1300                int id = Integer.parseInt(buttonPressed.substring(16));
1301                bitstream = Bitstream.find(context, id);
1302            }
1303            catch (NumberFormatException JavaDoc nfe)
1304            {
1305                bitstream = null;
1306            }
1307
1308            if (bitstream == null)
1309            {
1310                // Invalid or mangled bitstream ID
1311
log.warn(LogManager.getHeader(context, "integrity_error",
1312                        UIUtil.getRequestLogInfo(request)));
1313                JSPManager.showIntegrityError(request, response);
1314
1315                return;
1316            }
1317
1318            // Display the form letting them change the description
1319
subInfo.bitstream = bitstream;
1320            showProgressAwareJSP(request, response, subInfo,
1321                         "/submit/change-file-description.jsp");
1322        }
1323        else if (buttonPressed.startsWith("submit_remove_"))
1324        {
1325            // A "remove" button must have been pressed
1326
Bitstream bitstream;
1327
1328            // Which bitstream does the user want to describe?
1329
try
1330            {
1331                int id = Integer.parseInt(buttonPressed.substring(14));
1332                bitstream = Bitstream.find(context, id);
1333            }
1334            catch (NumberFormatException JavaDoc nfe)
1335            {
1336                bitstream = null;
1337            }
1338
1339            if (bitstream == null)
1340            {
1341                // Invalid or mangled bitstream ID
1342
log.warn(LogManager.getHeader(context, "integrity_error",
1343                        UIUtil.getRequestLogInfo(request)));
1344                JSPManager.showIntegrityError(request, response);
1345
1346                return;
1347            }
1348
1349            // remove bitstream from bundle..
1350
// delete bundle if it's now empty
1351
Bundle[] bundles = bitstream.getBundles();
1352
1353            bundles[0].removeBitstream(bitstream);
1354
1355            Bitstream[] bitstreams = bundles[0].getBitstreams();
1356
1357            // remove bundle if it's now empty
1358
if (bitstreams.length < 1)
1359            {
1360                item.removeBundle(bundles[0]);
1361                item.update();
1362            }
1363
1364            showFirstUploadPage(context, request, response, subInfo);
1365            context.complete();
1366        }
1367        else if (buttonPressed.startsWith("submit_format_"))
1368        {
1369            // A "format is wrong" button must have been pressed
1370
Bitstream bitstream;
1371
1372            // Which bitstream does the user want to describe?
1373
try
1374            {
1375                int id = Integer.parseInt(buttonPressed.substring(14));
1376                bitstream = Bitstream.find(context, id);
1377            }
1378            catch (NumberFormatException JavaDoc nfe)
1379            {
1380                bitstream = null;
1381            }
1382
1383            if (bitstream == null)
1384            {
1385                // Invalid or mangled bitstream ID
1386
log.warn(LogManager.getHeader(context, "integrity_error",
1387                        UIUtil.getRequestLogInfo(request)));
1388                JSPManager.showIntegrityError(request, response);
1389
1390                return;
1391            }
1392
1393            subInfo.bitstream = bitstream;
1394            showGetFileFormat(context, request, response, subInfo, bitstream);
1395        }
1396        else
1397        {
1398            doStepJump(context, request, response, subInfo);
1399        }
1400    }
1401
1402    /**
1403     * Process input from the upload error page
1404     *
1405     * @param context
1406     * current DSpace context
1407     * @param request
1408     * current servlet request object
1409     * @param response
1410     * current servlet response object
1411     * @param subInfo
1412     * submission info object
1413     */

1414    private void processUploadError(Context context,
1415            HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1416            SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
1417            SQLException JavaDoc, AuthorizeException
1418    {
1419        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_next");
1420
1421        // no real options on the page, just retry!
1422
if (buttonPressed.equals("submit"))
1423        {
1424            showProgressAwareJSP(request, response, subInfo,
1425                                 "/submit/choose-file.jsp");
1426        }
1427        else
1428        {
1429            doStepJump(context, request, response, subInfo);
1430        }
1431    }
1432
1433    /**
1434     * Process input from the "change file description" page
1435     *
1436     * @param context
1437     * current DSpace context
1438     * @param request
1439     * current servlet request object
1440     * @param response
1441     * current servlet response object
1442     * @param subInfo
1443     * submission info object
1444     */

1445    private void processChangeFileDescription(Context context,
1446            HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1447            SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
1448            SQLException JavaDoc, AuthorizeException
1449    {
1450        if (subInfo.bitstream != null)
1451        {
1452            subInfo.bitstream.setDescription(request
1453                    .getParameter("description"));
1454            subInfo.bitstream.update();
1455
1456            if (request.getParameter("submit") != null)
1457            {
1458                showUploadFileList(request, response, subInfo, false, false);
1459            }
1460            else
1461            {
1462                doStepJump(context, request, response, subInfo);
1463            }
1464
1465            context.complete();
1466        }
1467        else
1468        {
1469            log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
1470                    .getRequestLogInfo(request)));
1471            JSPManager.showIntegrityError(request, response);
1472        }
1473    }
1474
1475    /**
1476     * Process information from "submission cancelled" page
1477     *
1478     * @param context
1479     * current DSpace context
1480     * @param request
1481     * current servlet request object
1482     * @param response
1483     * current servlet response object
1484     * @param subInfo
1485     * submission info object
1486     */

1487    private void processCancellation(Context context,
1488            HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1489            SubmissionInfo subInfo) throws ServletException JavaDoc, IOException JavaDoc,
1490            SQLException JavaDoc, AuthorizeException
1491    {
1492        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_back");
1493
1494        if (buttonPressed.equals("submit_back"))
1495        {
1496            // User wants to continue with submission
1497
int previous = UIUtil.getIntParameter(request, "previous_step");
1498
1499            doStep(context, request, response, subInfo, previous);
1500        }
1501        else if (buttonPressed.equals("submit_remove"))
1502        {
1503            // User wants to cancel and remove
1504
// Cancellation page only applies to workspace items
1505
WorkspaceItem wi = (WorkspaceItem) subInfo.submission;
1506
1507            wi.deleteAll();
1508
1509            JSPManager.showJSP(request, response,
1510                    "/submit/cancelled-removed.jsp");
1511
1512            context.complete();
1513        }
1514        else if (buttonPressed.equals("submit_keep"))
1515        {
1516            // Save submission for later - just show message
1517
JSPManager.showJSP(request, response, "/submit/saved.jsp");
1518        }
1519        else
1520        {
1521            doStepJump(context, request, response, subInfo);
1522        }
1523    }
1524
1525    /**
1526     * Process button click on "review submission" page
1527     *
1528     * @param context
1529     * current DSpace context
1530     * @param request
1531     * current servlet request object
1532     * @param response
1533     * current servlet response object
1534     * @param subInfo
1535     * submission info object
1536     */

1537    private void processReview(Context context, HttpServletRequest JavaDoc request,
1538            HttpServletResponse JavaDoc response, SubmissionInfo subInfo)
1539            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
1540            AuthorizeException
1541    {
1542        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_cancel");
1543
1544        if (buttonPressed.equals("submit_cancel"))
1545        {
1546            doCancellation(request, response, subInfo, REVIEW_SUBMISSION,
1547                    REVIEW_SUBMISSION);
1548        }
1549        else if (buttonPressed.equals("submit_next"))
1550        {
1551            // If the user is performing the initial submission
1552
// of an item, we go to the grant license stage
1553
if (!isWorkflow(subInfo))
1554            {
1555                // proceed to next step conditional on CC
1556
int nextStep = CreativeCommons.isEnabled() ? CC_LICENSE
1557                        : GRANT_LICENSE;
1558                userHasReached(subInfo, nextStep);
1559                doStep(context, request, response, subInfo, nextStep);
1560                context.complete();
1561            }
1562            else
1563            {
1564                // The user is performing an edit as part
1565
// of a workflow task, so we take them
1566
// back to the relevant perform task page
1567
request.setAttribute("workflow.item", subInfo.submission);
1568                JSPManager.showJSP(request, response,
1569                        "/mydspace/perform-task.jsp");
1570            }
1571        }
1572        else if (buttonPressed.equals("submit_prev"))
1573        {
1574            // Back to file upload
1575
doStep(context, request, response, subInfo, UPLOAD_FILES);
1576        }
1577        else
1578        {
1579            doStepJump(context, request, response, subInfo);
1580        }
1581    }
1582
1583    /**
1584     * Process the input from the license page
1585     *
1586     * @param context
1587     * current DSpace context
1588     * @param request
1589     * current servlet request object
1590     * @param response
1591     * current servlet response object
1592     * @param subInfo
1593     * submission info object
1594     */

1595    private void processLicense(Context context, HttpServletRequest JavaDoc request,
1596            HttpServletResponse JavaDoc response, SubmissionInfo subInfo)
1597            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
1598            AuthorizeException
1599    {
1600        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_cancel");
1601
1602        if (buttonPressed.equals("submit_grant"))
1603        {
1604            // License granted
1605
log.info(LogManager.getHeader(context, "accept_license",
1606                    getSubmissionLogInfo(subInfo)));
1607
1608            // Add the license to the item
1609
Item item = subInfo.submission.getItem();
1610            EPerson submitter = context.getCurrentUser();
1611
1612            // FIXME: Probably need to take this from the form at some point
1613
String JavaDoc license = subInfo.submission.getCollection().getLicense();
1614
1615            item.licenseGranted(license, submitter);
1616
1617            // Start the workflow
1618
WorkflowManager.start(context, (WorkspaceItem) subInfo.submission);
1619
1620            // FIXME: pass in more information about what happens next?
1621
showProgressAwareJSP(request, response, subInfo, "/submit/complete.jsp");
1622            context.complete();
1623        }
1624        else if (request.getParameter("submit_reject") != null)
1625        {
1626            // User has rejected license.
1627
log.info(LogManager.getHeader(context, "reject_license",
1628                    getSubmissionLogInfo(subInfo)));
1629
1630            // Show information page.
1631
JSPManager.showJSP(request, response,
1632                    "/submit/license-rejected.jsp");
1633        }
1634        else
1635        {
1636            doStepJump(context, request, response, subInfo);
1637        }
1638    }
1639
1640    /**
1641     * Process the input from the CC license page
1642     *
1643     * @param context
1644     * current DSpace context
1645     * @param request
1646     * current servlet request object
1647     * @param response
1648     * current servlet response object
1649     * @param subInfo
1650     * submission info object
1651     */

1652    private void processCC(Context context, HttpServletRequest JavaDoc request,
1653            HttpServletResponse JavaDoc response, SubmissionInfo subInfo)
1654            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc,
1655            AuthorizeException
1656    {
1657        String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "submit_next");
1658
1659        // Firstly, check for a click of the cancel button.
1660
if (buttonPressed.equals("submit_cancel"))
1661        {
1662            doCancellation(request, response, subInfo, CC_LICENSE, CC_LICENSE);
1663        }
1664        else if (buttonPressed.equals("submit_prev"))
1665        {
1666            // Back to review submission
1667
doStep(context, request, response, subInfo, REVIEW_SUBMISSION);
1668        }
1669        else if (buttonPressed.equals("submit_next"))
1670        {
1671            // Update user's progress
1672
userHasReached(subInfo, GRANT_LICENSE);
1673
1674            // User has clicked "Next"
1675
doStep(context, request, response, subInfo, GRANT_LICENSE);
1676            context.complete();
1677        }
1678        else if (buttonPressed.equals("submit_no_cc"))
1679        {
1680            // Skipping the CC license - remove any existing license selection
1681
CreativeCommons
1682                    .removeLicense(context, subInfo.submission.getItem());
1683            userHasReached(subInfo, GRANT_LICENSE);
1684            doStep(context, request, response, subInfo, GRANT_LICENSE);
1685            context.complete();
1686        }
1687        else
1688        {
1689            // RLR hack - need to distinguish between progress bar real
1690
// submission
1691
String JavaDoc ccLicenseUrl = request.getParameter("cc_license_url");
1692            if ((ccLicenseUrl != null) && (ccLicenseUrl.length() > 0))
1693            {
1694                Item item = subInfo.submission.getItem();
1695
1696                // set the CC license
1697
CreativeCommons.setLicense(context, item, ccLicenseUrl);
1698
1699                userHasReached(subInfo, GRANT_LICENSE);
1700                doStep(context, request, response, subInfo, GRANT_LICENSE);
1701                context.complete();
1702            }
1703            else
1704            {
1705                doStepJump(context, request, response, subInfo);
1706            }
1707        }
1708    }
1709
1710    //****************************************************************
1711
//****************************************************************
1712
// METHODS FOR SHOWING FORMS
1713
//****************************************************************
1714
//****************************************************************
1715

1716    /**
1717     * Process a click on a buttonin the progress bar. to jump to a step. This
1718     * method should be called when it has been determined that no other button
1719     * has been pressed.
1720     *
1721     * @param context
1722     * DSpace context object
1723     * @param request
1724     * the request object
1725     * @param response
1726     * the response object
1727     * @param subInfo
1728     * SubmissionInfo pertaining to this submission
1729     */

1730    private void doStepJump(Context context, HttpServletRequest JavaDoc request,
1731            HttpServletResponse JavaDoc response, SubmissionInfo subInfo)
1732            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc
1733    {
1734        // Find the button that was pressed. It would start with
1735
// "submit_jump_".
1736
String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "");
1737
1738        // Now, if the request was a multi-part (file upload), we need to
1739
// get the original request back out, as the wrapper causes problems
1740
// further down the line.
1741
if (request instanceof FileUploadRequest)
1742        {
1743            FileUploadRequest fur = (FileUploadRequest) request;
1744            request = fur.getOriginalRequest();
1745        }
1746
1747        int nextStep = -1;
1748
1749        if (buttonPressed.startsWith("submit_jump_"))
1750        {
1751            // Button on progress bar pressed
1752
try
1753            {
1754                nextStep = Integer.parseInt(buttonPressed.substring(12));
1755            }
1756            catch (NumberFormatException JavaDoc ne)
1757            {
1758                // mangled number
1759
nextStep = -1;
1760            }
1761
1762            // Integrity check: make sure they aren't going
1763
// forward or backward too far
1764
if (nextStep <= SubmitServlet.SELECT_COLLECTION)
1765            {
1766                nextStep = -1;
1767            }
1768
1769            if (!isWorkflow(subInfo) && (nextStep > getStepReached(subInfo)))
1770            {
1771                nextStep = -1;
1772            }
1773        }
1774
1775        if (nextStep == -1)
1776        {
1777            // Either no button pressed, or an illegal stage
1778
// reached. UI doesn't allow this, so something's
1779
// wrong if that happens.
1780
log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
1781                    .getRequestLogInfo(request)));
1782            JSPManager.showIntegrityError(request, response);
1783        }
1784        else
1785        {
1786            // Do the relevant step
1787
doStep(context, request, response, subInfo, nextStep);
1788        }
1789    }
1790
1791    /**
1792     * Display the page for the relevant step. Pass in a step number between
1793     * SubmitServlet.INITIAL_QUESTIONS and SubmitServlet.SUBMISSION_COMPLETE -
1794     * other cases (such as cancellations and multi-file upload interactions)
1795     * are handled elsewhere.
1796     *
1797     * @param context
1798     * DSpace context
1799     * @param request
1800     * the request object
1801     * @param response
1802     * the response object
1803     * @param subInfo
1804     * SubmissionInfo pertaining to this submission
1805     * @param step
1806     * the step number to display
1807     */

1808    private void doStep(Context context, HttpServletRequest JavaDoc request,
1809            HttpServletResponse JavaDoc response, SubmissionInfo subInfo, int step)
1810            throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc
1811    {
1812        // determine collection
1813
Collection c = subInfo.submission.getCollection();
1814        
1815        if ( step >= EDIT_METADATA_1 && step <= EDIT_METADATA_2 )
1816        {
1817            // requires configurable form info per collection
1818
request.setAttribute( "submission.inputs", inputsReader.getInputs(c.getHandle()));
1819            // also indicate page
1820
request.setAttribute( "submission.page", new Integer JavaDoc(step) );
1821        showProgressAwareJSP(request, response, subInfo,
1822                             "/submit/edit-metadata.jsp");
1823            return;
1824        }
1825
1826        switch (step)
1827        {
1828        case INITIAL_QUESTIONS:
1829            // requires configurable form info per collection
1830
request.setAttribute( "submission.inputs", inputsReader.getInputs(c.getHandle()));
1831            showProgressAwareJSP(request, response, subInfo,
1832                         "/submit/initial-questions.jsp");
1833            break;
1834            
1835        /* EDIT_METADATA cases handled above */
1836            
1837        case UPLOAD_FILES:
1838            showFirstUploadPage(context, request, response, subInfo);
1839
1840            break;
1841
1842        case CHOOSE_FILE:
1843            showProgressAwareJSP(request, response, subInfo,
1844                             "/submit/choose-file.jsp");
1845            break;
1846
1847        case FILE_LIST:
1848            showUploadFileList(request, response, subInfo, false, false);
1849            break;
1850
1851        case REVIEW_SUBMISSION:
1852            // requires configurable form info per collection
1853
request.setAttribute( "submission.inputs", inputsReader.getInputs(c.getHandle()));
1854            showProgressAwareJSP(request, response, subInfo,
1855                             "/submit/review.jsp");
1856            break;
1857
1858        case GRANT_LICENSE:
1859            request.setAttribute("license", c.getLicense());
1860            showProgressAwareJSP(request, response, subInfo,
1861                             "/submit/show-license.jsp");
1862            break;
1863
1864        case CC_LICENSE:
1865
1866            // Do we already have a CC license?
1867
Item item = subInfo.submission.getItem();
1868            boolean exists = CreativeCommons.hasLicense(context, item);
1869            request.setAttribute("cclicense.exists", new Boolean JavaDoc(exists) );
1870            showProgressAwareJSP(request, response, subInfo,
1871                             "/submit/creative-commons.jsp");
1872            break;
1873
1874        case SUBMISSION_COMPLETE:
1875            showProgressAwareJSP(request, response, subInfo,
1876                             "/submit/complete.jsp");
1877            break;
1878
1879        default:
1880            log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
1881                    .getRequestLogInfo(request)));
1882            JSPManager.showIntegrityError(request, response);
1883        }
1884    }
1885
1886    /**
1887     * Respond to the user clicking "cancel".
1888     *
1889     * @param request
1890     * current servlet request object
1891     * @param response
1892     * current servlet response object
1893     * @param subInfo
1894     * SubmissionInfo object
1895     * @param step
1896     * step corresponding to the page the user clicked "cancel" on.
1897     * @param displayStep
1898     * the step the user had reached in terms of the progress bar.
1899     */

1900    private void doCancellation(HttpServletRequest JavaDoc request,
1901            HttpServletResponse JavaDoc response, SubmissionInfo subInfo, int step,
1902            int displayStep) throws ServletException JavaDoc, IOException JavaDoc, SQLException JavaDoc
1903    {
1904        // If this is a workflow item, we need to return the
1905
// user to the "perform task" page
1906
if (isWorkflow(subInfo))
1907        {
1908            request.setAttribute("workflow.item", subInfo.submission);
1909            JSPManager.showJSP(request, response, "/mydspace/perform-task.jsp");
1910        }
1911        else
1912        {
1913            request.setAttribute("step", String.valueOf(step));
1914            request.setAttribute("display.step", String.valueOf(displayStep));
1915            showProgressAwareJSP(request, response, subInfo, "/submit/cancel.jsp");
1916        }
1917    }
1918
1919    /**
1920     * Display the first appropriate page in the file upload sequence. Which
1921     * page this is depends on whether the user has uploaded any files in this
1922     * item already.
1923     *
1924     * @param context
1925     * the DSpace context object
1926     * @param request
1927     * the request object
1928     * @param response
1929     * the response object
1930     * @param subInfo
1931     * the SubmissionInfo object
1932     */

1933    private void showFirstUploadPage(Context context,
1934            HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1935            SubmissionInfo subInfo) throws SQLException JavaDoc, ServletException JavaDoc,
1936            IOException JavaDoc
1937    {
1938        Bundle[] bundles = subInfo.submission.getItem().getBundles("ORIGINAL");
1939
1940        if (bundles.length > 0)
1941        {
1942            // The item has files associated with it.
1943
showUploadFileList(request, response, subInfo, false, false);
1944        }
1945        else
1946        {
1947            // No items uploaded yet; show the "choose file" page
1948
doStep(context, request, response, subInfo, CHOOSE_FILE);
1949        }
1950    }
1951
1952    /**
1953     * Show the upload file page
1954     *
1955     * @param request
1956     * the request object
1957     * @param response
1958     * the response object
1959     * @param subInfo
1960     * the SubmissionInfo object
1961     * @param justUploaded
1962     * pass in true if the user just successfully uploaded a file
1963     * @param showChecksums
1964     * pass in true if checksums should be displayed
1965     */

1966    private void showUploadFileList(HttpServletRequest JavaDoc request,
1967            HttpServletResponse JavaDoc response, SubmissionInfo subInfo,
1968            boolean justUploaded, boolean showChecksums) throws SQLException JavaDoc,
1969            ServletException JavaDoc, IOException JavaDoc
1970    {
1971        // Set required attributes
1972
request.setAttribute("just.uploaded", new Boolean JavaDoc(justUploaded));
1973        request.setAttribute("show.checksums", new Boolean JavaDoc(showChecksums));
1974
1975        // Always go to advanced view in workflow mode
1976
if (isWorkflow(subInfo) || subInfo.submission.hasMultipleFiles())
1977        {
1978            showProgressAwareJSP(request, response, subInfo,
1979                     "/submit/upload-file-list.jsp");
1980        }
1981        else
1982        {
1983            // FIXME: Assume one and only one bitstream
1984
showProgressAwareJSP(request, response, subInfo,
1985                     "/submit/show-uploaded-file.jsp");
1986        }
1987    }
1988
1989    /**
1990     * Get the type of a file from the user
1991     *
1992     * @param context
1993     * context object
1994     * @param request
1995     * the request object
1996     * @param response
1997     * the response object
1998     * @param subInfo
1999     * the SubmissionInfo object
2000     * @param bitstream
2001     * the Bitstream to get the type of
2002     */

2003    private void showGetFileFormat(Context context, HttpServletRequest JavaDoc request,
2004            HttpServletResponse JavaDoc response, SubmissionInfo subInfo,
2005            Bitstream bitstream) throws SQLException JavaDoc, ServletException JavaDoc,
2006            IOException JavaDoc
2007    {
2008        BitstreamFormat[] formats = BitstreamFormat.findNonInternal(context);
2009
2010        subInfo.bitstream = bitstream;
2011
2012        request.setAttribute("bitstream.formats", formats);
2013 
2014        // What does the system think it is?
2015
BitstreamFormat guess = FormatIdentifier
2016                .guessFormat(context, bitstream);
2017
2018        request.setAttribute("guessed.format", guess);
2019
2020        showProgressAwareJSP(request, response, subInfo,
2021                         "/submit/get-file-format.jsp");
2022    }
2023
2024    //****************************************************************
2025
//****************************************************************
2026
// MISCELLANEOUS CONVENIENCE METHODS
2027
//****************************************************************
2028
//****************************************************************
2029

2030    /**
2031     * Show a JSP after setting attributes needed by progress bar
2032     * @param request the request object
2033     * @param response the response object
2034     * @param subInfo the SubmissionInfo object
2035     * @param jspPath relative path to JSP
2036     */

2037     private void showProgressAwareJSP(
2038            HttpServletRequest JavaDoc request,
2039            HttpServletResponse JavaDoc response,
2040            SubmissionInfo subInfo,
2041            String JavaDoc jspPath)
2042            throws ServletException JavaDoc, IOException JavaDoc
2043     {
2044        // all JSPs displaying the progress bar need to know the
2045
// number of metadata edit pages
2046
subInfo.numMetadataPages =
2047            inputsReader.getNumberInputPages(subInfo.submission.getCollection().getHandle());
2048        request.setAttribute("submission.info", subInfo);
2049        
2050        JSPManager.showJSP(request, response, jspPath);
2051     }
2052
2053    /**
2054     * Get a filled-out submission info object from the parameters in the
2055     * current request. If there is a problem, <code>null</code> is returned.
2056     *
2057     * @param context
2058     * DSpace context
2059     * @param request
2060     * HTTP request
2061     *
2062     * @return filled-out submission info, or null
2063     */

2064    private SubmissionInfo getSubmissionInfo(Context context,
2065            HttpServletRequest JavaDoc request) throws SQLException JavaDoc
2066    {
2067        SubmissionInfo info = new SubmissionInfo();
2068
2069        if (request.getParameter("workflow_id") != null)
2070        {
2071            int workflowID = UIUtil.getIntParameter(request, "workflow_id");
2072            info.submission = WorkflowItem.find(context, workflowID);
2073        }
2074        else
2075        {
2076            int workspaceID = UIUtil.getIntParameter(request,
2077                    "workspace_item_id");
2078            info.submission = WorkspaceItem.find(context, workspaceID);
2079        }
2080
2081        // Is something wrong?
2082
if (info.submission == null)
2083        {
2084            return null;
2085        }
2086
2087        if (request.getParameter("bundle_id") != null)
2088        {
2089            int bundleID = UIUtil.getIntParameter(request, "bundle_id");
2090            info.bundle = Bundle.find(context, bundleID);
2091        }
2092
2093        if (request.getParameter("bitstream_id") != null)
2094        {
2095            int bitstreamID = UIUtil.getIntParameter(request, "bitstream_id");
2096            info.bitstream = Bitstream.find(context, bitstreamID);
2097        }
2098
2099        return info;
2100    }
2101
2102    /**
2103     * Is the submission in the workflow process?
2104     *
2105     * @param si
2106     * the submission info
2107     * @return true if the submission is in the workflow process
2108     */

2109    public static boolean isWorkflow(SubmissionInfo si)
2110    {
2111        return ((si.submission != null) && si.submission instanceof WorkflowItem);
2112    }
2113
2114    /**
2115     * Return the submission info as hidden parameters for an HTML form
2116     *
2117     * @param si
2118     * the submission info
2119     * @return HTML hidden parameters
2120     */

2121    public static String JavaDoc getSubmissionParameters(SubmissionInfo si)
2122    {
2123        String JavaDoc info = "";
2124
2125        if (isWorkflow(si))
2126        {
2127            info = info + "<input type=\"hidden\" name=\"workflow_id\" value=\""
2128                    + si.submission.getID() + "\"/>";
2129        }
2130        else
2131        {
2132            info = info + "<input type=\"hidden\" name=\"workspace_item_id\" value=\""
2133                    + si.submission.getID() + "\"/>";
2134        }
2135
2136        if (si.bundle != null)
2137        {
2138            info = info + "<input type=\"hidden\" name=\"bundle_id\" value=\""
2139                    + si.bundle.getID() + "\"/>";
2140        }
2141
2142        if (si.bitstream != null)
2143        {
2144            info = info + "<input type=\"hidden\" name=\"bitstream_id\" value=\""
2145                    + si.bitstream.getID() + "\"/>";
2146        }
2147
2148        return info;
2149    }
2150
2151    /**
2152     * Return text information suitable for logging
2153     *
2154     * @param si
2155     * the submission info
2156     * @return the type and ID of the submission, bundle and/or bitstream for
2157     * logging
2158     */

2159    public String JavaDoc getSubmissionLogInfo(SubmissionInfo si)
2160    {
2161        String JavaDoc info = "";
2162
2163        if (isWorkflow(si))
2164        {
2165            info = info + "workflow_id=" + si.submission.getID();
2166        }
2167        else
2168        {
2169            info = info + "workspace_item_id" + si.submission.getID();
2170        }
2171
2172        if (si.bundle != null)
2173        {
2174            info = info + ",bundle_id=" + si.bundle.getID();
2175        }
2176
2177        if (si.bitstream != null)
2178        {
2179            info = info + ",bitstream_id=" + si.bitstream.getID();
2180        }
2181
2182        return info;
2183    }
2184
2185    /**
2186     * Indicate the user has advanced to the given stage. This will only
2187     * actually do anything when it's a user initially entering a submission. It
2188     * will only increase the "stage reached" column - it will not "set back"
2189     * where a user has reached.
2190     *
2191     * @param subInfo
2192     * the SubmissionInfo object pertaining to the current submission
2193     * @param step
2194     * the step the user has just reached
2195     */

2196    private void userHasReached(SubmissionInfo subInfo, int step)
2197            throws SQLException JavaDoc, AuthorizeException, IOException JavaDoc
2198    {
2199        if (!isWorkflow(subInfo))
2200        {
2201            WorkspaceItem wi = (WorkspaceItem) subInfo.submission;
2202
2203            if (step > wi.getStageReached())
2204            {
2205                wi.setStageReached(step);
2206                wi.update();
2207            }
2208        }
2209    }
2210
2211    /**
2212     * Find out which step a user has reached in the submission process. If the
2213     * submission is in the workflow process, this returns REVIEW_SUBMISSION.
2214     *
2215     * @param subInfo
2216     * submission info object
2217     *
2218     * @return step reached, between SELECT_COLLECTION and SUBMISSION_COMPLETE
2219     */

2220    public static int getStepReached(SubmissionInfo subInfo)
2221    {
2222        if (isWorkflow(subInfo))
2223        {
2224            return -1;
2225        }
2226        else
2227        {
2228            WorkspaceItem wi = (WorkspaceItem) subInfo.submission;
2229            int i = wi.getStageReached();
2230
2231            // Uninitialised workspace items give "-1" as the stage reached
2232
// this is a special value used by the progress bar, so we change
2233
// it to "INITIAL_QUESTIONS"
2234
if (i == -1)
2235            {
2236                i = INITIAL_QUESTIONS;
2237            }
2238
2239            return i;
2240        }
2241    }
2242
2243    //****************************************************************
2244
//****************************************************************
2245
// METHODS FOR FILLING DC FIELDS FROM METADATA FORMS
2246
//****************************************************************
2247
//****************************************************************
2248

2249    /**
2250     * Set relevant DC fields in an item from name values in the form. Some
2251     * fields are repeatable in the form. If this is the case, and the field is
2252     * "contributor.author", the names in the request will be from the fields as
2253     * follows:
2254     *
2255     * contributor_author_last_0 -> last name of first author
2256     * contributor_author_first_0 -> first name(s) of first author
2257     * contributor_author_last_1 -> last name of second author
2258     * contributor_author_first_1 -> first name(s) of second author
2259     *
2260     * and so on. If the field is unqualified:
2261     *
2262     * contributor_last_0 -> last name of first contributor contributor_first_0 ->
2263     * first name(s) of first contributor
2264     *
2265     * If the parameter "submit_contributor_author_remove_n" is set, that value
2266     * is removed.
2267     *
2268     * Otherwise the parameters are of the form:
2269     *
2270     * contributor_author_last contributor_author_first
2271     *
2272     * The values will be put in separate DCValues, in the form "last name,
2273     * first name(s)", ordered as they appear in the list. These will replace
2274     * any existing values.
2275     *
2276     * @param request
2277     * the request object
2278     * @param item
2279     * the item to update
2280     * @param schema
2281     * the DC schema
2282     * @param element
2283     * the DC element
2284     * @param qualifier
2285     * the DC qualifier, or null if unqualified
2286     * @param repeated
2287     * set to true if the field is repeatable on the form
2288     */

2289    private void readNames(HttpServletRequest JavaDoc request, Item item,
2290            String JavaDoc schema, String JavaDoc element, String JavaDoc qualifier, boolean repeated)
2291    {
2292        String JavaDoc dcname = MetadataField.formKey(schema,element,qualifier);
2293
2294        // Names to add
2295
List JavaDoc firsts = new LinkedList JavaDoc();
2296        List JavaDoc lasts = new LinkedList JavaDoc();
2297
2298        if (repeated)
2299        {
2300            firsts = getRepeatedParameter(request, dcname + "_first");
2301            lasts = getRepeatedParameter(request, dcname + "_last");
2302
2303            // Find out if the relevant "remove" button was pressed
2304
String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "");
2305            String JavaDoc removeButton = "submit_" + dcname + "_remove_";
2306
2307            if (buttonPressed.startsWith(removeButton))
2308            {
2309                int valToRemove = Integer.parseInt(buttonPressed
2310                        .substring(removeButton.length()));
2311
2312                firsts.remove(valToRemove);
2313                lasts.remove(valToRemove);
2314            }
2315        }
2316        else
2317        {
2318            // Just a single name
2319
String JavaDoc lastName = request.getParameter(dcname + "_last");
2320            String JavaDoc firstNames = request.getParameter(dcname + "_first");
2321
2322            lasts.add(lastName);
2323            firsts.add(firstNames);
2324        }
2325
2326        // Remove existing values
2327
item.clearMetadata(schema, element, qualifier, Item.ANY);
2328
2329        // Put the names in the correct form
2330
for (int i = 0; i < lasts.size(); i++)
2331        {
2332            String JavaDoc f = (String JavaDoc) firsts.get(i);
2333            String JavaDoc l = (String JavaDoc) lasts.get(i);
2334
2335            // only add if lastname is non-empty
2336
if ((l != null) && !((l.trim()).equals("")))
2337            {
2338                // Ensure first name non-null
2339
if (f == null)
2340                {
2341                    f = "";
2342                }
2343
2344                // If there is a comma in the last name, we take everything
2345
// after that comma, and add it to the right of the
2346
// first name
2347
int comma = l.indexOf(',');
2348
2349                if (comma >= 0)
2350                {
2351                    f = f + l.substring(comma + 1);
2352                    l = l.substring(0, comma);
2353
2354                    // Remove leading whitespace from first name
2355
while (f.startsWith(" "))
2356                    {
2357                        f = f.substring(1);
2358                    }
2359                }
2360
2361                // Add to the database
2362
item.addMetadata(schema, element, qualifier, null, new DCPersonName(l, f)
2363                        .toString());
2364            }
2365        }
2366    }
2367
2368    /**
2369     * Fill out an item's DC values from a plain standard text field. If the
2370     * field isn't repeatable, the input field name is called:
2371     *
2372     * element_qualifier
2373     *
2374     * or for an unqualified element:
2375     *
2376     * element
2377     *
2378     * Repeated elements are appended with an underscore then an integer. e.g.:
2379     *
2380     * title_alternative_0 title_alternative_1
2381     *
2382     * The values will be put in separate DCValues, ordered as they appear in
2383     * the list. These will replace any existing values.
2384     *
2385     * @param request
2386     * the request object
2387     * @param item
2388     * the item to update
2389     * @param schema
2390     * the short schema name
2391     * @param element
2392     * the DC element
2393     * @param qualifier
2394     * the DC qualifier, or null if unqualified
2395     * @param repeated
2396     * set to true if the field is repeatable on the form
2397     * @param lang
2398     * language to set (ISO code)
2399     */

2400    private void readText(HttpServletRequest JavaDoc request, Item item, String JavaDoc schema,
2401            String JavaDoc element, String JavaDoc qualifier, boolean repeated, String JavaDoc lang)
2402    {
2403        // FIXME: Of course, language should be part of form, or determined
2404
// some other way
2405
String JavaDoc dcname = MetadataField.formKey(schema,element,qualifier);
2406
2407        // Values to add
2408
List JavaDoc vals = new LinkedList JavaDoc();
2409
2410        if (repeated)
2411        {
2412            vals = getRepeatedParameter(request, dcname);
2413
2414            // Find out if the relevant "remove" button was pressed
2415
String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "");
2416            String JavaDoc removeButton = "submit_" + dcname + "_remove_";
2417
2418            if (buttonPressed.startsWith(removeButton))
2419            {
2420                int valToRemove = Integer.parseInt(buttonPressed
2421                        .substring(removeButton.length()));
2422
2423                vals.remove(valToRemove);
2424            }
2425        }
2426        else
2427        {
2428            // Just a single name
2429
vals.add(request.getParameter(dcname).trim());
2430            ;
2431        }
2432
2433        // Remove existing values
2434
item.clearMetadata(schema, element, qualifier, Item.ANY);
2435
2436        // Put the names in the correct form
2437
for (int i = 0; i < vals.size(); i++)
2438        {
2439            // Add to the database if non-empty
2440
String JavaDoc s = (String JavaDoc) vals.get(i);
2441
2442            if ((s != null) && !s.equals(""))
2443            {
2444                item.addMetadata(schema, element, qualifier, lang, s);
2445            }
2446        }
2447    }
2448
2449    /**
2450     * Fill out a DC date field with the value from a form. The date is taken
2451     * from the three parameters:
2452     *
2453     * element_qualifier_year element_qualifier_month element_qualifier_day
2454     *
2455     * The granularity is determined by the values that are actually set. If the
2456     * year isn't set (or is invalid)
2457     *
2458     * @param request
2459     * the request object
2460     * @param item
2461     * the item to update
2462     * @param schema
2463     * the DC schema
2464     * @param element
2465     * the DC element
2466     * @param qualifier
2467     * the DC qualifier, or null if unqualified
2468     * @throws SQLException
2469     */

2470    private void readDate(HttpServletRequest JavaDoc request, Item item,
2471            String JavaDoc schema, String JavaDoc element, String JavaDoc qualifier) throws SQLException JavaDoc
2472    {
2473        String JavaDoc dcname = MetadataField.formKey(schema,element,qualifier);
2474
2475        int year = UIUtil.getIntParameter(request, dcname + "_year");
2476        int month = UIUtil.getIntParameter(request, dcname + "_month");
2477        int day = UIUtil.getIntParameter(request, dcname + "_day");
2478
2479        // FIXME: Probably should be some more validation
2480
// Make a standard format date
2481
DCDate d = new DCDate();
2482
2483        d.setDateLocal(year, month, day, -1, -1, -1);
2484
2485        item.clearMetadata(schema, element, qualifier, Item.ANY);
2486
2487        if (year > 0)
2488        {
2489            // Only put in date if there is one!
2490
item.addMetadata(schema, element, qualifier, null, d.toString());
2491        }
2492    }
2493
2494    /**
2495     * Set relevant DC fields in an item from series/number values in the form.
2496     * Some fields are repeatable in the form. If this is the case, and the
2497     * field is "relation.ispartof", the names in the request will be from the
2498     * fields as follows:
2499     *
2500     * relation_ispartof_series_0 relation_ispartof_number_0
2501     * relation_ispartof_series_1 relation_ispartof_number_1
2502     *
2503     * and so on. If the field is unqualified:
2504     *
2505     * relation_series_0 relation_number_0
2506     *
2507     * Otherwise the parameters are of the form:
2508     *
2509     * relation_ispartof_series relation_ispartof_number
2510     *
2511     * The values will be put in separate DCValues, in the form "last name,
2512     * first name(s)", ordered as they appear in the list. These will replace
2513     * any existing values.
2514     *
2515     * @param request
2516     * the request object
2517     * @param item
2518     * the item to update
2519     * @param schema
2520     * the DC schema
2521     * @param element
2522     * the DC element
2523     * @param qualifier
2524     * the DC qualifier, or null if unqualified
2525     * @param repeated
2526     * set to true if the field is repeatable on the form
2527     */

2528    private void readSeriesNumbers(HttpServletRequest JavaDoc request, Item item,
2529            String JavaDoc schema, String JavaDoc element, String JavaDoc qualifier, boolean repeated)
2530        {
2531        String JavaDoc dcname = MetadataField.formKey(schema,element,qualifier);
2532
2533        // Names to add
2534
List JavaDoc series = new LinkedList JavaDoc();
2535        List JavaDoc numbers = new LinkedList JavaDoc();
2536
2537        if (repeated)
2538        {
2539            series = getRepeatedParameter(request, dcname + "_series");
2540            numbers = getRepeatedParameter(request, dcname + "_number");
2541
2542            // Find out if the relevant "remove" button was pressed
2543
String JavaDoc buttonPressed = UIUtil.getSubmitButton(request, "");
2544            String JavaDoc removeButton = "submit_" + dcname + "_remove_";
2545
2546            if (buttonPressed.startsWith(removeButton))
2547            {
2548                int valToRemove = Integer.parseInt(buttonPressed
2549                        .substring(removeButton.length()));
2550
2551                series.remove(valToRemove);
2552                numbers.remove(valToRemove);
2553            }
2554        }
2555        else
2556        {
2557            // Just a single name
2558
String JavaDoc s = request.getParameter(dcname + "_series");
2559            String JavaDoc n = request.getParameter(dcname + "_number");
2560
2561            // Only put it in if there was a name present
2562
if ((s != null) && !s.equals(""))
2563            {
2564                series.add(s);
2565                numbers.add(n);
2566            }
2567        }
2568
2569        // Remove existing values
2570
item.clearMetadata(schema, element, qualifier, Item.ANY);
2571
2572        // Put the names in the correct form
2573
for (int i = 0; i < series.size(); i++)
2574        {
2575            String JavaDoc s = ((String JavaDoc) series.get(i)).trim();
2576            String JavaDoc n = ((String JavaDoc) numbers.get(i)).trim();
2577
2578            // Only add non-empty
2579
if (!s.equals("") || !n.equals(""))
2580            {
2581                item.addMetadata(schema, element, qualifier, null, new DCSeriesNumber(s, n)
2582                        .toString());
2583            }
2584        }
2585    }
2586
2587    /**
2588     * Get repeated values from a form. If "foo" is passed in, values in the
2589     * form of parameters "foo_0", "foo_1", etc. are returned.
2590     *
2591     * @param request
2592     * the HTTP request containing the form information
2593     * @param param
2594     * the repeated parameter
2595     *
2596     * @return a List of Strings
2597     */

2598    private List JavaDoc getRepeatedParameter(HttpServletRequest JavaDoc request, String JavaDoc param)
2599    {
2600        List JavaDoc vals = new LinkedList JavaDoc();
2601
2602        int i = 0;
2603        boolean foundLast = false;
2604
2605        // Iterate through the values in the form.
2606
while (!foundLast)
2607        {
2608            String JavaDoc s = request.getParameter(param + "_" + i);
2609
2610            // We're only going to add non-null values
2611
if (s != null)
2612            {
2613                vals.add(s.trim());
2614            }
2615            else
2616            {
2617                // If the value was null (as opposed to present,
2618
// but empty) we've reached the last name
2619
foundLast = true;
2620            }
2621
2622            i++;
2623        }
2624
2625        return vals;
2626    }
2627}
2628
Popular Tags