From 80356f5c2ec031e5d7df2eec7a55b6bd67105fda Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 8 Jan 2008 17:53:25 +0000 Subject: [PATCH] Merged 'item-submission-JSPUI.xml' and 'item-submission-XMLUI.xml' files into a single 'item-submission.xml' configuration file (based on suggestions from Graham Triggs). Small updates throughout API for Configurable Submission to support this merged configuration file (majority of changes in dspace-api and dspace-jspui modules). Also includes updates to Configurable Submission documentation and small updates to I18N to make the XMLUI and JSPUI keys more parallel. git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2491 9c30dcfa-912a-0410-8fc2-9e0234be79fd --- .../org/dspace/app/util/SubmissionConfig.java | 4 +- .../app/util/SubmissionConfigReader.java | 74 ++--- .../org/dspace/app/util/SubmissionInfo.java | 17 +- .../dspace/app/util/SubmissionStepConfig.java | 64 +++-- .../dspace/submit/AbstractProcessingStep.java | 64 ++++- .../org/dspace/submit/step/DescribeStep.java | 23 +- .../submit/step/InitialQuestionsStep.java | 5 + .../org/dspace/submit/step/UploadStep.java | 5 +- .../src/main/resources/Messages.properties | 1 + .../app/webui/servlet/MyDSpaceServlet.java | 2 +- .../webui/servlet/SubmissionController.java | 106 +++++-- .../org/dspace/app/webui/submit/JSPStep.java | 33 ++- .../app/webui/submit/JSPStepManager.java | 145 +++++----- .../webui/submit/step/JSPCompleteStep.java | 28 +- .../webui/submit/step/JSPDescribeStep.java | 46 +++- .../submit/step/JSPInitialQuestionsStep.java | 47 +++- .../app/webui/submit/step/JSPLicenseStep.java | 35 ++- .../app/webui/submit/step/JSPSampleStep.java | 50 +++- .../submit/step/JSPSelectCollectionStep.java | 35 ++- .../app/webui/submit/step/JSPUploadStep.java | 143 +++------- .../app/webui/submit/step/JSPVerifyStep.java | 50 +++- .../app/webui/util/FileUploadRequest.java | 11 +- .../src/main/webapp/submit/progressbar.jsp | 5 +- .../xmlui/aspect/submission/AbstractStep.java | 4 +- .../xmlui/aspect/submission/FlowUtils.java | 14 +- .../aspects/Submission/submission.js | 2 +- .../src/main/webapp/i18n/messages.xml | 18 +- dspace/config/item-submission-XMLUI.xml | 178 ------------ dspace/config/item-submission.dtd | 4 +- ...bmission-JSPUI.xml => item-submission.xml} | 138 ++++++---- dspace/docs/submission.html | 258 ++++++++---------- 31 files changed, 835 insertions(+), 774 deletions(-) delete mode 100644 dspace/config/item-submission-XMLUI.xml rename dspace/config/{item-submission-JSPUI.xml => item-submission.xml} (56%) diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfig.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfig.java index b9d745f9a2..070a94bf58 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfig.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfig.java @@ -48,7 +48,7 @@ import org.apache.log4j.Logger; /** * Class representing a single Item Submission config definition, organized into * steps. This class represents the structure of a single 'submission-process' - * node in the item-submission-[UI Name].xml configuration file. + * node in the item-submission.xml configuration file. * * @see org.dspace.app.util.SubmissionConfigReader * @see org.dspace.app.util.SubmissionStepConfig @@ -73,7 +73,7 @@ public class SubmissionConfig /** * Constructs a new Submission Configuration object, based on the XML - * configuration file (item-submission-[UI Name].xml) + * configuration file (item-submission.xml) * * @param submissionName * the submission process name diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfigReader.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfigReader.java index f1c0b0d12f..e89c3957c3 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfigReader.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionConfigReader.java @@ -56,7 +56,7 @@ import org.dspace.core.ConfigurationManager; /** * Item Submission configuration generator for DSpace. Reads and parses the - * installed submission process configuration file, item-submission-[UI name].xml, from + * installed submission process configuration file, item-submission.xml, from * the configuration directory. This submission process definiton details the * ordering of the steps (and number of steps) that occur during the Item * Submission Process. There may be multiple Item Submission processes defined, @@ -96,9 +96,6 @@ public class SubmissionConfigReader private String configDir = ConfigurationManager.getProperty("dspace.dir") + File.separator + "config" + File.separator; - /** Name of the User Interface which this Submission Configuration corresponds to */ - private String UIName; - /** * Hashmap which stores which submission process configuration is used by * which collection, computed from the item submission config file @@ -125,27 +122,12 @@ public class SubmissionConfigReader private SubmissionConfig lastSubmissionConfig = null; /** - * Default Constructor - PRIVATE + * Load Submission Configuration from the + * item-submission.xml configuration file */ - private SubmissionConfigReader() + public SubmissionConfigReader() throws ServletException { - } - - /** - * Load Submission Configuration for a specific user interface(UI). - * The submission configuration file name is formatted as follows: - * item-submission-UIName.xml - *

- * E.g. for a value of "XMLUI", uses the config file named - * item-submission-XMLUI.xml - * - * @param UIName - * the name of the UI to load the Submission configuration for - */ - public SubmissionConfigReader(String UIName) throws ServletException - { - this.UIName = UIName; - buildInputs(configDir + SUBMIT_DEF_FILE_PREFIX + "-" + UIName + SUBMIT_DEF_FILE_SUFFIX); + buildInputs(configDir + SUBMIT_DEF_FILE_PREFIX + SUBMIT_DEF_FILE_SUFFIX); } /** @@ -218,7 +200,7 @@ public class SubmissionConfigReader if (submitName == null) { throw new ServletException( - "No item submission process configuration designated as 'default' in 'submission-map' section of 'item-submission-" + getUIName() + ".xml'."); + "No item submission process configuration designated as 'default' in 'submission-map' section of 'item-submission.xml'."); } log.debug("Loading submission process config named '" + submitName @@ -242,7 +224,7 @@ public class SubmissionConfigReader { throw new ServletException( "Missing the Item Submission process config '" + submitName - + "' (or unable to load) from 'item-submission-" + getUIName() + ".xml'."); + + "' (or unable to load) from 'item-submission.xml'."); } log.debug("Submission process config '" + submitName @@ -332,16 +314,16 @@ public class SubmissionConfigReader if (!foundMap) { throw new ServletException( - "No collection to item submission map ('submission-map') found in 'item-submission-" + getUIName() + ".xml'"); + "No collection to item submission map ('submission-map') found in 'item-submission.xml'"); } if (!foundStepDefs) { - throw new ServletException("No 'step-definitions' section found in 'item-submission-" + getUIName() + ".xml'"); + throw new ServletException("No 'step-definitions' section found in 'item-submission.xml'"); } if (!foundSubmitDefs) { throw new ServletException( - "No 'submission-definitions' section found in 'item-submission-" + getUIName() + ".xml'"); + "No 'submission-definitions' section found in 'item-submission.xml'"); } } @@ -366,17 +348,17 @@ public class SubmissionConfigReader if (id == null) { throw new SAXException( - "name-map element is missing collection-handle attribute in 'item-submission-" + getUIName() + ".xml'"); + "name-map element is missing collection-handle attribute in 'item-submission.xml'"); } if (value == null) { throw new SAXException( - "name-map element is missing submission-name attribute in 'item-submission-" + getUIName() + ".xml'"); + "name-map element is missing submission-name attribute in 'item-submission.xml'"); } if (content != null && content.length() > 0) { throw new SAXException( - "name-map element has content in 'item-submission-" + getUIName() + ".xml', it should be empty."); + "name-map element has content in 'item-submission.xml', it should be empty."); } collectionToSubmissionConfig.put(id, value); } // ignore any child node that isn't a "name-map" @@ -410,12 +392,12 @@ public class SubmissionConfigReader if (stepID == null) { throw new SAXException( - "step element has no 'id' attribute in 'item-submission-" + getUIName() + ".xml', which is required in the 'step-definitions' section"); + "step element has no 'id' attribute in 'item-submission.xml', which is required in the 'step-definitions' section"); } else if (stepDefns.containsKey(stepID)) { throw new SAXException( - "There are two step elements with the id '" + stepID + "' in 'item-submission-" + getUIName() + ".xml'"); + "There are two step elements with the id '" + stepID + "' in 'item-submission.xml'"); } HashMap stepInfo = processStepChildNodes("step-definition", nd); @@ -428,7 +410,7 @@ public class SubmissionConfigReader if (stepDefns.size() < 1) { throw new ServletException( - "step-definition section has no steps! A step with id='collection' is required in 'item-submission-" + getUIName() + ".xml'!"); + "step-definition section has no steps! A step with id='collection' is required in 'item-submission.xml'!"); } // Sanity check to see that the required "collection" step is defined @@ -437,7 +419,7 @@ public class SubmissionConfigReader throw new ServletException( "The step-definition section is REQUIRED to have a step with id='" + SubmissionStepConfig.SELECT_COLLECTION_STEP - + "' in 'item-submission-" + getUIName() + ".xml'! This step is used to ensure that a new item submission is assigned to a collection."); + + "' in 'item-submission.xml'! This step is used to ensure that a new item submission is assigned to a collection."); } // Sanity check to see that the required "complete" step is defined @@ -446,7 +428,7 @@ public class SubmissionConfigReader throw new ServletException( "The step-definition section is REQUIRED to have a step with id='" + SubmissionStepConfig.COMPLETE_STEP - + "' in 'item-submission-" + getUIName() + ".xml'! This step is used to perform all processing necessary at the completion of the submission (e.g. starting workflow)."); + + "' in 'item-submission.xml'! This step is used to perform all processing necessary at the completion of the submission (e.g. starting workflow)."); } } @@ -482,13 +464,13 @@ public class SubmissionConfigReader if (submitName == null) { throw new SAXException( - "'submission-process' element has no 'name' attribute in 'item-submission-" + getUIName() + ".xml'"); + "'submission-process' element has no 'name' attribute in 'item-submission.xml'"); } else if (submitNames.contains(submitName)) { throw new SAXException( "There are two 'submission-process' elements with the name '" - + submitName + "' in 'item-submission-" + getUIName() + ".xml'."); + + submitName + "' in 'item-submission.xml'."); } submitNames.add(submitName); @@ -530,7 +512,7 @@ public class SubmissionConfigReader + submitName + " contains a step with id=" + stepID - + ". There is no step with this 'id' defined in the 'step-definition' section of 'item-submission-" + getUIName() + ".xml'."); + + ". There is no step with this 'id' defined in the 'step-definition' section of 'item-submission.xml'."); } // Ignore all children of a step element with an @@ -554,7 +536,7 @@ public class SubmissionConfigReader { throw new ServletException( "Item Submission process config named " - + submitName + " has no steps defined in 'item-submission-" + getUIName() + ".xml'"); + + submitName + " has no steps defined in 'item-submission.xml'"); } // ALL Item Submission processes MUST BEGIN with selecting a @@ -579,7 +561,7 @@ public class SubmissionConfigReader if (numSubmitProcesses == 0) { throw new ServletException( - "No 'submission-process' elements/definitions found in 'item-submission-" + getUIName() + ".xml'"); + "No 'submission-process' elements/definitions found in 'item-submission.xml'"); } } @@ -627,7 +609,7 @@ public class SubmissionConfigReader { String msg = "Required field " + missing + " missing in a 'step' in the " + configSection - + " of the item submission configuration file ('item-submission-" + getUIName() + ".xml')"; + + " of the item submission configuration file ('item-submission.xml')"; throw new SAXException(msg); } @@ -706,12 +688,4 @@ public class SubmissionConfigReader // Didn't find a text node return null; } - - public String getUIName() { - return UIName; - } - - private void setUIName(String name) { - UIName = name; - } } diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionInfo.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionInfo.java index bb15bec032..153c2c8f51 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionInfo.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionInfo.java @@ -127,11 +127,7 @@ public class SubmissionInfo * for a new submission. * * @param request - * The HTTP Servlet Request object - * @param briefUIName - * The brief name of the User Interface to - * load the Submission Configuration and Information for - * (e.g. "jspui" or "xmlui") + * The HTTP Servlet Request object * @param subItem * The in-progress submission we are loading information for * @@ -140,19 +136,16 @@ public class SubmissionInfo * @throws ServletException * if an error occurs */ - public static SubmissionInfo load(HttpServletRequest request, - String briefUIName, InProgressSubmission subItem) throws ServletException + public static SubmissionInfo load(HttpServletRequest request, InProgressSubmission subItem) throws ServletException { boolean forceReload = false; SubmissionInfo subInfo = new SubmissionInfo(); // load SubmissionConfigReader only the first time // or if we're using a different UI now. - if (submissionConfigReader == null || - submissionConfigReader.getUIName() == null || - !submissionConfigReader.getUIName().equals(briefUIName)) + if (submissionConfigReader == null) { - submissionConfigReader = new SubmissionConfigReader(briefUIName); + submissionConfigReader = new SubmissionConfigReader(); forceReload=true; } @@ -223,7 +216,7 @@ public class SubmissionInfo /** * Causes the SubmissionConfig to be completely reloaded from the XML - * configuration file (item-submission-[UI Name].xml). + * configuration file (item-submission.xml). *

* Note: This also reloads the progress bar info, since the progress bar * depends entirely on the submission process (and its steps). diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java index b52886f1c1..e415d2fe94 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java @@ -48,7 +48,7 @@ import org.apache.log4j.Logger; * Class representing configuration for a single step within an Item Submission * Process. In other words, this is a single step in the SubmissionConfig class. * This class represents the structure of a single 'step' node in the - * item-submission-[UI Name].xml configuration file. + * item-submission.xml configuration file. * * @see org.dspace.app.util.SubmissionConfigReader * @see org.dspace.app.util.SubmissionConfig @@ -79,19 +79,22 @@ public class SubmissionStepConfig /** the name of the java processing class for this step */ private String processingClassName = null; - - /** the review-jsp for this step */ - private String reviewJSP = null; - + /** whether or not this step is editable during workflow (default=true) */ private boolean workflowEditable = true; + /** + * The full name of the JSP-UI binding class for this step. This field is + * ONLY used by the JSP-UI. + **/ + private String jspBindingClassName = null; + /** * The full name of the Manakin XML-UI Transformer class which will generate * the necessary DRI for displaying this class in Manakin. This field is * ONLY used by the Manakin XML-UI. */ - private String xmlUIClassName = null; + private String xmlBindingClassName = null; /** The number of this step in the current SubmissionConfig */ private int number = -1; @@ -119,8 +122,8 @@ public class SubmissionStepConfig id = (String) stepMap.get("id"); heading = (String) stepMap.get("heading"); processingClassName = (String) stepMap.get("processing-class"); - reviewJSP = (String) stepMap.get("review-jsp"); - xmlUIClassName = (String) stepMap.get("xml-ui-class"); + jspBindingClassName = (String) stepMap.get("jspui-binding"); + xmlBindingClassName = (String) stepMap.get("xmlui-binding"); String wfEditString = (String) stepMap.get("workflow-editable"); if (wfEditString != null && wfEditString.length() > 0) @@ -156,9 +159,8 @@ public class SubmissionStepConfig /** * Get the class which handles all processing for this step. *

- * This class must extend either the org.dspace.submit.SubmissionStep class - * (for JSP UI) or org.dspace.submit.AbstractProcessingStep class (for - * Manakin XML UI). + * This class must extend the org.dspace.submit.AbstractProcessingStep class, + * and provide processing for BOTH the JSP-UI and XML-UI * * @return the class's full class path (e.g. * "org.dspace.submit.step.MySampleStep") @@ -168,36 +170,38 @@ public class SubmissionStepConfig return processingClassName; } - /** - * Get the review jsp for this step. The "review jsp" is a JSP page which - * will load all the user's answers given for this step to allow the user to - * review his/her answers. - * - * This "review jsp" is used by the "Verify" step to allow the user to - * verify/review all of his/her answers. - * - * @return the JSPs full path - */ - public String getReviewJSP() - { - return reviewJSP; - } - /** * Retrieve the full class name of the Manakin Transformer which will * generate this step's DRI, for display in Manakin XML-UI. *

* This class must extend the - * org.dspace.app.xmlui.submit.step.SubmissionStep class. + * org.dspace.app.xmlui.aspect.submission.StepTransformer class. *

* This property is only used by the Manakin XML-UI, and therefore is not - * relevant if you are using JSPs. + * relevant if you are using the JSP-UI. * - * @return the full java class name of the Transformer for this class + * @return the full java class name of the Transformer to use for this step */ public String getXMLUIClassName() { - return xmlUIClassName; + return xmlBindingClassName; + } + + /** + * Retrieve the full class name of the JSP-UI "binding" class which will + * initialize and call the necessary JSPs for display in the JSP-UI + *

+ * This class must extend the + * org.dspace.app.webui.submit.JSPStep class. + *

+ * This property is only used by the JSP-UI, and therefore is not + * relevant if you are using the XML-UI (aka. Manakin). + * + * @return the full java class name of the JSPStep to use for this step + */ + public String getJSPUIClassName() + { + return jspBindingClassName; } /** diff --git a/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java b/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java index 328d44e08a..2d21d8cc84 100644 --- a/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/AbstractProcessingStep.java @@ -125,6 +125,9 @@ public abstract class AbstractProcessingStep /** List of all user interface fields which had errors during processing * */ private List errorFields = null; + + private static String ERROR_FIELDS_ATTRIBUTE = "dspace.submit.error_fields"; + /** * Do any processing of the information input by the user, and/or perform @@ -159,47 +162,84 @@ public abstract class AbstractProcessingStep * step processing. This list is for usage in generating the appropriate * error message(s) in the UI. *

- * The list of fields which had errors should be set by the step's + * The list of fields which had errors should be set by the AbstractProcessingStep's * doProcessing() method, so that it can be accessed later by whatever UI is * generated. * + * @param request + * current servlet request object * @return List of error fields (as Strings) */ - public final List getErrorFields() + public static final List getErrorFields(HttpServletRequest request) { - return this.errorFields; + return (List) request.getAttribute(ERROR_FIELDS_ATTRIBUTE); + } + + /** + * Sets th list of all UI fields which had errors that occurred during the + * step processing. This list is for usage in generating the appropriate + * error message(s) in the UI. + *

+ * The list of fields which had errors should be set by the AbstractProcessingStep's + * doProcessing() method, so that it can be accessed later by whatever UI is + * generated. + * + * @param request + * current servlet request object + * @param errorFields + * List of all fields (as Strings) which had errors + */ + private static final void setErrorFields(HttpServletRequest request, List errorFields) + { + if(errorFields==null) + request.removeAttribute(ERROR_FIELDS_ATTRIBUTE); + else + request.setAttribute(ERROR_FIELDS_ATTRIBUTE, errorFields); } /** - * Add a single UI field to the internal list of all error fields (which can + * Add a single UI field to the list of all error fields (which can * later be retrieved using getErrorFields()) *

- * The list of fields which had errors should be set by the step's + * The list of fields which had errors should be set by the AbstractProcessingStep's * doProcessing() method, so that it can be accessed later by whatever UI is * generated. * * @param fieldName * the name of the field which had an error */ - protected final void addErrorField(String fieldName) + protected static final void addErrorField(HttpServletRequest request, String fieldName) { - if (this.errorFields == null) + //get current list + List errorFields = getErrorFields(request); + + if (errorFields == null) { - this.errorFields = new ArrayList(); + errorFields = new ArrayList(); } - this.errorFields.add(fieldName); + //add this field + errorFields.add(fieldName); + + //save updated list + setErrorFields(request, errorFields); } /** * Clears the list of all fields that errored out during the previous step's * processing. * + * @param request + * current servlet request object + * */ - protected final void clearErrorFields() + protected static final void clearErrorFields(HttpServletRequest request) { - if (this.errorFields != null) - this.errorFields.clear(); + //get current list + List errorFields = getErrorFields(request); + + if (errorFields != null) + setErrorFields(request,null); } /** diff --git a/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java b/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java index 465794a1bd..04d3083117 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/DescribeStep.java @@ -106,12 +106,8 @@ public class DescribeStep extends AbstractProcessingStep /** Constructor */ public DescribeStep() throws ServletException { - // load inputsReader only the first time - if (inputsReader == null) - { - // read configurable submissions forms data - inputsReader = new DCInputsReader(); - } + //load the DCInputsReader + getInputsReader(); } @@ -268,7 +264,7 @@ public class DescribeStep extends AbstractProcessingStep // Step 3: // Check to see if any fields are missing - clearErrorFields(); + clearErrorFields(request); for (int i = 0; i < inputs.length; i++) { DCValue[] values = item.getMetadata(inputs[i].getSchema(), @@ -277,7 +273,7 @@ public class DescribeStep extends AbstractProcessingStep if (inputs[i].isRequired() && values.length == 0) { // since this field is missing add to list of error fields - addErrorField(getFieldName(inputs[i])); + addErrorField(request, getFieldName(inputs[i])); } } @@ -294,7 +290,7 @@ public class DescribeStep extends AbstractProcessingStep return STATUS_MORE_INPUT_REQUESTED; } // if one or more fields errored out, return - else if (getErrorFields() != null && getErrorFields().size() > 0) + else if (getErrorFields(request) != null && getErrorFields(request).size() > 0) { return STATUS_MISSING_REQUIRED_FIELDS; } @@ -353,8 +349,15 @@ public class DescribeStep extends AbstractProcessingStep * * @return the current DCInputsReader */ - public static DCInputsReader getInputsReader() + public static DCInputsReader getInputsReader() throws ServletException { + // load inputsReader only the first time + if (inputsReader == null) + { + // read configurable submissions forms data + inputsReader = new DCInputsReader(); + } + return inputsReader; } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java b/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java index 7b835ff312..603993ba0d 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/InitialQuestionsStep.java @@ -232,6 +232,11 @@ public class InitialQuestionsStep extends AbstractProcessingStep // to inform the user and make sure that's OK, before saving! if (willRemoveTitles || willRemoveDate || willRemoveFiles) { + //save what we will need to prune to request (for UI to process) + request.setAttribute("will.remove.titles", new Boolean(willRemoveTitles)); + request.setAttribute("will.remove.date", new Boolean(willRemoveDate)); + request.setAttribute("will.remove.files", new Boolean(willRemoveFiles)); + return STATUS_VERIFY_PRUNE; // we will need to do pruning! } } diff --git a/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java b/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java index 3b7cafd675..b9f6d3b5a2 100644 --- a/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java +++ b/dspace-api/src/main/java/org/dspace/submit/step/UploadStep.java @@ -59,6 +59,7 @@ import org.dspace.content.Bundle; import org.dspace.content.FormatIdentifier; import org.dspace.content.Item; import org.dspace.core.Context; +import org.dspace.core.ConfigurationManager; import org.dspace.submit.AbstractProcessingStep; /** @@ -465,8 +466,8 @@ public class UploadStep extends AbstractProcessingStep Bitstream b = null; //NOTE: File should already be uploaded. - //Manakin does this automatically. - //For JSP-UI, the JSPUploadStep.doProcessing() does the actual upload + //Manakin does this automatically via Cocoon. + //For JSP-UI, the SubmissionController.uploadFiles() does the actual upload Enumeration attNames = request.getAttributeNames(); diff --git a/dspace-api/src/main/resources/Messages.properties b/dspace-api/src/main/resources/Messages.properties index 1004793644..168fd71468 100644 --- a/dspace-api/src/main/resources/Messages.properties +++ b/dspace-api/src/main/resources/Messages.properties @@ -855,6 +855,7 @@ jsp.submit.no-theses.info5 = Thank you for jsp.submit.no-theses.title = Theses Not Accepted in DSpace jsp.submit.progressbar.complete = Complete jsp.submit.progressbar.describe = Describe +jsp.submit.progressbar.initial-questions = Describe jsp.submit.progressbar.license = License jsp.submit.progressbar.select = Select jsp.submit.progressbar.upload = Upload diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/MyDSpaceServlet.java b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/MyDSpaceServlet.java index b10f8c683c..2fae1e4146 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/MyDSpaceServlet.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/MyDSpaceServlet.java @@ -553,7 +553,7 @@ public class MyDSpaceServlet extends DSpaceServlet // Load the Submission Process for the collection this WSI is // associated with Collection c = wsi.getCollection(); - SubmissionConfigReader subConfigReader = new SubmissionConfigReader(SubmissionController.UI_NAME); + SubmissionConfigReader subConfigReader = new SubmissionConfigReader(); SubmissionConfig subConfig = subConfigReader.getSubmissionConfig(c .getHandle(), false); diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/SubmissionController.java b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/SubmissionController.java index cf1bf8edfb..4d5e885d2e 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/SubmissionController.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/servlet/SubmissionController.java @@ -39,8 +39,13 @@ */ package org.dspace.app.webui.servlet; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.sql.SQLException; +import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -50,6 +55,7 @@ import org.apache.log4j.Logger; import org.dspace.app.util.SubmissionInfo; import org.dspace.app.util.SubmissionStepConfig; +import org.dspace.app.util.Util; import org.dspace.app.webui.submit.JSPStepManager; import org.dspace.app.webui.util.FileUploadRequest; import org.dspace.app.webui.util.JSPManager; @@ -62,6 +68,7 @@ import org.dspace.core.Context; import org.dspace.core.LogManager; import org.dspace.workflow.WorkflowItem; import org.dspace.submit.AbstractProcessingStep; +import org.dspace.submit.step.UploadStep; /** * Submission Manager servlet for DSpace. Handles the initial submission of @@ -124,9 +131,6 @@ public class SubmissionController extends DSpaceServlet /** First step after "select collection" */ public static int FIRST_STEP = 1; - /** "Name" of the JSP User Interface - Used to load SubmissionInfo **/ - public static String UI_NAME = "JSPUI"; - /** path to the JSP shown once the submission is completed */ private static String COMPLETE_JSP = "/submit/complete.jsp"; @@ -170,7 +174,7 @@ public class SubmissionController extends DSpaceServlet .parseInt(workspaceID)); //load submission information - SubmissionInfo si = SubmissionInfo.load(request, UI_NAME, wi); + SubmissionInfo si = SubmissionInfo.load(request, wi); //TD: Special case - If a user is resuming a submission //where the submission process now has less steps, then @@ -214,7 +218,7 @@ public class SubmissionController extends DSpaceServlet .parseInt(workflowID)); //load submission information - SubmissionInfo si = SubmissionInfo.load(request, UI_NAME, wi); + SubmissionInfo si = SubmissionInfo.load(request, wi); //For workflows, first step is step #0 //(since Select Collection is already filtered out) @@ -254,6 +258,9 @@ public class SubmissionController extends DSpaceServlet && (contentType.indexOf("multipart/form-data") != -1)) { request = wrapMultipartRequest(request); + + //also, upload any files and save their contents to Request (for later processing by UploadStep) + uploadFiles(context, request); } // Reload submission info from request parameters @@ -394,7 +401,7 @@ public class SubmissionController extends DSpaceServlet try { - JSPStepManager stepManager = JSPStepManager.loadStep(currentStepConfig.getProcessingClassName()); + JSPStepManager stepManager = JSPStepManager.loadStep(currentStepConfig); //tell the step class to do its processing boolean stepFinished = stepManager.processStep(context, request, response, subInfo); @@ -482,20 +489,7 @@ public class SubmissionController extends DSpaceServlet else { // The Submission is COMPLETE!! - /* - log.info(LogManager.getHeader(context, "submission_complete", - "Completed submission with id=" - + subInfo.getSubmissionItem().getID())); - - // save that user has reached last step - userHasReached(subInfo, currentStepNum + 1); - - // Start the workflow - WorkflowManager.start(context, (WorkspaceItem)subInfo.getSubmissionItem()); - - // commit changes to database & close context - context.complete(); - */ + // save our current Submission information into the Request object saveSubmissionInfo(request, subInfo); @@ -905,19 +899,19 @@ public class SubmissionController extends DSpaceServlet { int workflowID = UIUtil.getIntParameter(request, "workflow_id"); - info = SubmissionInfo.load(request, UI_NAME, WorkflowItem.find(context, workflowID)); + info = SubmissionInfo.load(request, WorkflowItem.find(context, workflowID)); } else if(request.getParameter("workspace_item_id") != null) { int workspaceID = UIUtil.getIntParameter(request, "workspace_item_id"); - info = SubmissionInfo.load(request, UI_NAME, WorkspaceItem.find(context, workspaceID)); + info = SubmissionInfo.load(request, WorkspaceItem.find(context, workspaceID)); } else { //by default, initialize Submission Info with no item - info = SubmissionInfo.load(request, UI_NAME, null); + info = SubmissionInfo.load(request, null); } // We must have a submission object if after the first step, @@ -1297,4 +1291,70 @@ public class SubmissionController extends DSpaceServlet throw new ServletException(e); } } + + + /** + * Upload any files found on the Request, and save them back as + * Request attributes, for further processing by the appropriate user interface. + * + * @param context + * current DSpace context + * @param request + * current servlet request object + */ + public void uploadFiles(Context context, HttpServletRequest request) + throws ServletException + { + FileUploadRequest wrapper = null; + String filePath = null; + InputStream fileInputStream = null; + + try + { + // if we already have a FileUploadRequest, use it + if (Class.forName("org.dspace.app.webui.util.FileUploadRequest") + .isInstance(request)) + { + wrapper = (FileUploadRequest) request; + } + else + { + // Wrap multipart request to get the submission info + wrapper = new FileUploadRequest(request); + } + + Enumeration fileParams = wrapper.getFileParameterNames(); + while(fileParams.hasMoreElements()) + { + String fileName = (String) fileParams.nextElement(); + + File temp = wrapper.getFile(fileName); + + //if file exists and has a size greater than zero + if (temp != null && temp.length() > 0) + { + // Read the temp file into an inputstream + fileInputStream = new BufferedInputStream( + new FileInputStream(temp)); + + filePath = wrapper.getFilesystemName(fileName); + + // cleanup our temp file + temp.delete(); + + //save this file's info to request (for UploadStep class) + request.setAttribute(fileName + "-path", filePath); + request.setAttribute(fileName + "-inputstream", fileInputStream); + request.setAttribute(fileName + "-description", wrapper.getParameter("description")); + } + } + } + catch (Exception e) + { + // Problem with uploading + log.warn(LogManager.getHeader(context, "upload_error", ""), e); + throw new ServletException(e); + } + } + } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStep.java b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStep.java index 840577f13d..23118e849c 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStep.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStep.java @@ -60,10 +60,10 @@ import org.dspace.core.Context; import org.dspace.submit.AbstractProcessingStep; /** - * Interface for DSpace Submission Steps which use the JSP UI. + * Abstract 'binding' class for DSpace Submission Steps which use the JSP-UI. *

* These methods revolve around the following: (1) pre-processing of data to - * prepare for display, (2) displaying data on JSP, and (3) processing of any + * prepare for display, (2) displaying the JSP, and (3) post-processing of any * user input (or alternatively backend processing, for non-interactive steps). *

* For the JSP UI, the job of this class is to maintain the context of where the @@ -78,7 +78,7 @@ import org.dspace.submit.AbstractProcessingStep; * specified will be displayed *

  • If showJSP() was not specified from doPreProcessing(), then the * doProcessing() method is called an the step completes immediately
  • - *
  • Call doProcessing() method after the user returns from the JSP, in order + *
  • Call doProcessing() method on appropriate AbstractProcessingStep after the user returns from the JSP, in order * to process the user input
  • *
  • Call doPostProcessing() method to determine if more user interaction is * required, and if further JSPs need to be called.
  • @@ -96,7 +96,7 @@ import org.dspace.submit.AbstractProcessingStep; * @author Tim Donohue * @version $Revision$ */ -public interface JSPStep +public abstract class JSPStep { /** * Value to return from doPreProcessing to specify not to load any JSP Page @@ -127,7 +127,7 @@ public interface JSPStep * @param subInfo * submission info object */ - public void doPreProcessing(Context context, HttpServletRequest request, + public abstract void doPreProcessing(Context context, HttpServletRequest request, HttpServletResponse response, SubmissionInfo subInfo) throws ServletException, IOException, SQLException, AuthorizeException; @@ -155,8 +155,29 @@ public interface JSPStep * @param status * any status/errors reported by doProcessing() method */ - public void doPostProcessing(Context context, HttpServletRequest request, + public abstract void doPostProcessing(Context context, HttpServletRequest request, HttpServletResponse response, SubmissionInfo subInfo, int status) throws ServletException, IOException, SQLException, AuthorizeException; + + + /** + * Return the URL path (e.g. /submit/review-metadata.jsp) of the JSP + * which will review the information that was gathered in this Step. + *

    + * This Review JSP is loaded by the 'Verify' Step, in order to dynamically + * generate a submission verification page consisting of the information + * gathered in all the enabled submission steps. + * + * @param context + * current DSpace context + * @param request + * current servlet request object + * @param response + * current servlet response object + * @param subInfo + * submission info object + */ + public abstract String getReviewJSP(Context context, HttpServletRequest request, + HttpServletResponse response, SubmissionInfo subInfo); } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStepManager.java b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStepManager.java index 926bc71687..f971d7ec67 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStepManager.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/JSPStepManager.java @@ -60,33 +60,10 @@ import org.dspace.core.Context; import org.dspace.submit.AbstractProcessingStep; /** - * Abstract class for DSpace Submission Steps which use the JSP UI. + * Manages and processes all JSP-UI classes for DSpace Submission steps. *

    - * These methods revolve around the following: (1) pre-processing of data to - * prepare for display, (2) displaying data on JSP, and (3) processing of any - * user input (or alternatively backend processing, for non-interactive steps). - *

    - * For the JSP UI, the job of this class is to maintain the context of where the - * user is within the current "step" of the submission process. Each "step" can - * consist of multiple "pages" (which roughly correspond to HTML displays), so - * this class helps manage which page the user should see next. - *

    - * The methods of the JSPStepManager are called in this order: - *

    + * This manager is utilized by the SubmissionController to appropriately + * load each JSP-UI step, and process any information returned by each step * * @see org.dspace.submit.AbstractProcessingStep * @see org.dspace.app.webui.servlet.SubmissionController @@ -101,9 +78,17 @@ public class JSPStepManager private static Logger log = Logger.getLogger(JSPStepManager.class); /** - * Current JSP step that is being processed by the JSPStepManager + * Current Processing class for step that is being processed by the JSPStepManager + * This is the class that performs processing of information entered in during a step */ - private JSPStep step = null; + private AbstractProcessingStep stepProcessing = null; + + /** + * Current JSP-UI binding class for step that is being processed by the JSPStepManager + * This is the class that manages calling all JSPs, and determines if additional processing + * of information (or confirmation) is necessary. + */ + private JSPStep stepJSPUI = null; /** * The SubmissionStepConfig object describing the current step @@ -114,36 +99,62 @@ public class JSPStepManager * Initialize the current JSPStepManager object, by loading the * specified step class. * - * @param JSPStepClassName - * the full class name of the JSPStep which - * this JSPStepManager should initialize with + * @param stepConfig + * the SubmissionStepConfig object which describes + * this step's configuration in the item-submission.xml * * @throws Exception * if the JSPStep cannot be loaded or the class * specified doesn't implement the JSPStep interface */ - public static JSPStepManager loadStep(String JSPStepClassName) throws Exception + public static JSPStepManager loadStep(SubmissionStepConfig stepConfig) throws Exception { + JSPStepManager stepManager = new JSPStepManager(); - // load the step class (using the current class loader) + //save step configuration + stepManager.stepConfig = stepConfig; + + + /* + * First, load the step processing class (using the current class loader) + */ ClassLoader loader = stepManager.getClass().getClassLoader(); Class stepClass = loader - .loadClass(JSPStepClassName); + .loadClass(stepConfig.getProcessingClassName()); Object stepInstance = stepClass.newInstance(); - if(stepInstance instanceof JSPStep && - stepInstance instanceof AbstractProcessingStep) + if(stepInstance instanceof AbstractProcessingStep) { // load the JSPStep interface for this step - stepManager.step = (JSPStep) stepClass.newInstance(); + stepManager.stepProcessing = (AbstractProcessingStep) stepClass.newInstance(); } else { - throw new Exception("The submission step class specified by '" + JSPStepClassName + - "' EITHER does not implement the interface org.dspace.app.webui.JSPStep" + - " OR does not extend the class org.dspace.submit.AbstractProcessingStep!" + + throw new Exception("The submission step class specified by '" + stepConfig.getProcessingClassName() + + "' does not extend the class org.dspace.submit.AbstractProcessingStep!" + + " Therefore it cannot be used by the Configurable Submission as the !"); + } + + + /* + * Next, load the step's JSPUI binding class (using the current class loader) + */ + stepClass = loader + .loadClass(stepConfig.getJSPUIClassName()); + + stepInstance = stepClass.newInstance(); + + if(stepInstance instanceof JSPStep) + { + // load the JSPStep interface for this step + stepManager.stepJSPUI = (JSPStep) stepClass.newInstance(); + } + else + { + throw new Exception("The submission step class specified by '" + stepConfig.getJSPUIClassName() + + "' does not extend the class org.dspace.app.webui.JSPStep!" + " Therefore it cannot be used by the Configurable Submission for the JSP user interface!"); } @@ -187,27 +198,13 @@ public class JSPStepManager SQLException, AuthorizeException { /* - * The following HttpServletRequest attributes are required by - * initializeStep(): - * - * step = SubmissionStepConfig - the current Submission step - * configuration - * * This method SHOULD NOT BE OVERRIDDEN, unless it's absolutely * necessary. If you override this method, make sure you call the * "doStepStart()" and "doStepEnd()" methods at the appropriate time in - * your initializeStep() method. + * your processStep() method. * */ - /* - * Load Submission Information & Step Information - */ - - // retrieve our current Submission Process Step - this.stepConfig = SubmissionController - .getCurrentStepConfig(request, subInfo); - /* * Figure out Current Page in this Step */ @@ -310,7 +307,7 @@ public class JSPStepManager log.debug("Doing pre-processing for step " + this.getClass().getName()); // first, do any pre-processing and get the JSP to display - step.doPreProcessing(context, request, response, subInfo); + stepJSPUI.doPreProcessing(context, request, response, subInfo); // Complete this step, if this response has not already // been committed. @@ -326,13 +323,13 @@ public class JSPStepManager log.debug("Calling processing for step " + this.getClass().getName()); - int errorFlag = ((AbstractProcessingStep)step).doProcessing(context, request, response, subInfo); + int errorFlag = stepProcessing.doProcessing(context, request, response, subInfo); // if it didn't complete successfully, try and log this error! if (errorFlag != AbstractProcessingStep.STATUS_COMPLETE) { // see if an error message was defined! - String errorMessage = ((AbstractProcessingStep)step).getErrorMessage(errorFlag); + String errorMessage = stepProcessing.getErrorMessage(errorFlag); // if not defined, construct a dummy error if (errorMessage == null) @@ -424,7 +421,7 @@ public class JSPStepManager // and need to do the processing for this step log.debug("Calling processing for step " + this.getClass().getName()); - int status = ((AbstractProcessingStep)step).doProcessing(context, request, response, subInfo); + int status = stepProcessing.doProcessing(context, request, response, subInfo); log.debug("Calling post-processing for step " + this.getClass().getName()); @@ -432,7 +429,7 @@ public class JSPStepManager // After doing the processing, we have to do any post-processing // of any potential error messages, in case we need to re-display // the JSP - step.doPostProcessing(context, request, response, subInfo, status); + stepJSPUI.doPostProcessing(context, request, response, subInfo, status); int currentPage = AbstractProcessingStep.getCurrentPage(request); @@ -539,7 +536,7 @@ public class JSPStepManager protected final boolean hasMorePages(HttpServletRequest request, SubmissionInfo subInfo, int pageNumber) throws ServletException { - int numberOfPages = ((AbstractProcessingStep)step).getNumberOfPages(request, subInfo); + int numberOfPages = stepProcessing.getNumberOfPages(request, subInfo); if (pageNumber < numberOfPages) { @@ -692,4 +689,30 @@ public class JSPStepManager // save to request request.setAttribute("jsp", pathToJSP); } + + + /** + * Return the URL path (e.g. /submit/review-metadata.jsp) of the JSP + * which will review the information that was gathered in the currently + * loaded Step. + *

    + * This Review JSP is loaded by the 'Verify' Step, in order to dynamically + * generate a submission verification page consisting of the information + * gathered in all the enabled submission steps. + * + * @param context + * current DSpace context + * @param request + * current servlet request object + * @param response + * current servlet response object + * @param subInfo + * submission info object + */ + public String getReviewJSP(Context context, HttpServletRequest request, + HttpServletResponse response, SubmissionInfo subInfo) + { + return stepJSPUI.getReviewJSP(context, request, response, subInfo); + } + } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPCompleteStep.java b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPCompleteStep.java index 1d37755942..495e4b6919 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPCompleteStep.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPCompleteStep.java @@ -55,7 +55,7 @@ import org.dspace.core.Context; import org.dspace.submit.step.CompleteStep; /** - * This is the class which defines what happens once a submission completes! + * This is the JSP binding class which defines what happens once a submission completes! *

    * This JSPCompleteStep class works with the SubmissionController servlet and * when using the JSP-UI @@ -68,12 +68,11 @@ import org.dspace.submit.step.CompleteStep; * * @see org.dspace.app.webui.servlet.SubmissionController * @see org.dspace.app.webui.submit.JSPStep - * @see org.dspace.submit.step.CompleteStep * * @author Tim Donohue * @version $Revision$ */ -public class JSPCompleteStep extends CompleteStep implements JSPStep +public class JSPCompleteStep extends JSPStep { /** log4j logger */ private static Logger log = Logger.getLogger(JSPCompleteStep.class); @@ -142,5 +141,28 @@ public class JSPCompleteStep extends CompleteStep implements JSPStep //No post-processing necessary, since submission is complete! } + /** + * Return the URL path (e.g. /submit/review-metadata.jsp) of the JSP + * which will review the information that was gathered in this Step. + *

    + * This Review JSP is loaded by the 'Verify' Step, in order to dynamically + * generate a submission verification page consisting of the information + * gathered in all the enabled submission steps. + * + * @param context + * current DSpace context + * @param request + * current servlet request object + * @param response + * current servlet response object + * @param subInfo + * submission info object + */ + public String getReviewJSP(Context context, HttpServletRequest request, + HttpServletResponse response, SubmissionInfo subInfo) + { + return NO_JSP; //no need to return a Review JSP as we are completed! + } + } diff --git a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPDescribeStep.java b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPDescribeStep.java index ba779f93e6..0b1653a524 100644 --- a/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPDescribeStep.java +++ b/dspace-jspui/src/main/java/org/dspace/app/webui/submit/step/JSPDescribeStep.java @@ -61,12 +61,12 @@ import org.dspace.core.LogManager; import org.dspace.submit.step.DescribeStep; /** - * Describe step for DSpace submission process. Handles the pages that gather + * Describe step for DSpace JSP-UI submission process. Handles the pages that gather * descriptive information (i.e. metadata) for an item being submitted into * DSpace. *

    - * This JSPStepManager class works with the SubmissionController servlet - * for the JSP-UI + * This JSPStep class works with the SubmissionController servlet + * for the JSP-UI. *

    * The following methods are called in this order: *