001: /*
002: * ReviewStep.java
003: *
004: * Version: $Revision: 1.4 $
005: *
006: * Date: $Date: 2006/07/13 23:20:54 $
007: *
008: * Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
009: * Institute of Technology. All rights reserved.
010: *
011: * Redistribution and use in source and binary forms, with or without
012: * modification, are permitted provided that the following conditions are
013: * met:
014: *
015: * - Redistributions of source code must retain the above copyright
016: * notice, this list of conditions and the following disclaimer.
017: *
018: * - Redistributions in binary form must reproduce the above copyright
019: * notice, this list of conditions and the following disclaimer in the
020: * documentation and/or other materials provided with the distribution.
021: *
022: * - Neither the name of the Hewlett-Packard Company nor the name of the
023: * Massachusetts Institute of Technology nor the names of their
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
030: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
032: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
033: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
034: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
035: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
036: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
037: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
038: * DAMAGE.
039: */
040: package org.dspace.app.xmlui.aspect.submission.submit;
041:
042: import java.io.IOException;
043: import java.sql.SQLException;
044: import java.util.Map;
045: import java.util.Set;
046:
047: import org.apache.avalon.framework.parameters.Parameters;
048: import org.apache.cocoon.ProcessingException;
049: import org.apache.cocoon.environment.SourceResolver;
050: import org.apache.log4j.Logger;
051: import org.dspace.app.util.SubmissionConfig;
052: import org.dspace.app.util.SubmissionStepConfig;
053: import org.dspace.app.xmlui.utils.UIException;
054: import org.dspace.app.xmlui.aspect.submission.AbstractStep;
055: import org.dspace.app.xmlui.aspect.submission.AbstractSubmissionStep;
056: import org.dspace.app.xmlui.aspect.submission.FlowUtils;
057: import org.dspace.app.xmlui.wing.Message;
058: import org.dspace.app.xmlui.wing.WingException;
059: import org.dspace.app.xmlui.wing.element.Body;
060: import org.dspace.app.xmlui.wing.element.Division;
061: import org.dspace.app.xmlui.wing.element.List;
062: import org.dspace.authorize.AuthorizeException;
063: import org.dspace.content.Collection;
064: import org.dspace.submit.step.UploadStep;
065: import org.xml.sax.SAXException;
066:
067: /**
068: * This is a step of the item submission processes. This is where the user
069: * reviews everything they have entered about the item up to this point.
070: * <P>
071: * This step is dynamic, since when using the Configurable Submission
072: * it is unknown what steps are available and in what order.
073: * <P>
074: * This step builds a form with which consists of a separate section
075: * for each step which implements the "addReviewSection()" method
076: * of AbstractSubmissionStep class.
077: *
078: * @author Scott Phillips
079: * @author Tim Donohue (updated for Configurable Submission)
080: */
081: public class ReviewStep extends AbstractSubmissionStep {
082:
083: /** Language Strings **/
084: protected static final Message T_head = message("xmlui.Submission.submit.ReviewStep.head");
085: protected static final Message T_yes = message("xmlui.Submission.submit.ReviewStep.yes");
086: protected static final Message T_no = message("xmlui.Submission.submit.ReviewStep.no");
087: protected static final Message T_submit_jump = message("xmlui.Submission.submit.ReviewStep.submit_jump");
088: protected static final Message T_no_metadata = message("xmlui.Submission.submit.ReviewStep.no_metadata");
089: protected static final Message T_unknown = message("xmlui.Submission.submit.ReviewStep.unknown");
090: protected static final Message T_known = message("xmlui.Submission.submit.ReviewStep.known");
091: protected static final Message T_supported = message("xmlui.Submission.submit.ReviewStep.supported");
092:
093: /* The SourceResolver used to setup this class */
094: private SourceResolver resolver;
095:
096: /* The source string used to setup this class */
097: private String src;
098:
099: /** log4j logger */
100: private static Logger log = Logger.getLogger(UploadStep.class);
101:
102: /**
103: * Establish our required parameters, abstractStep will enforce these.
104: */
105: public ReviewStep() {
106: this .requireSubmission = true;
107: this .requireStep = true;
108: }
109:
110: /**
111: * Save these setup parameters, to use for loading up
112: * the previous step's review information
113: */
114: public void setup(SourceResolver resolver, Map objectModel,
115: String src, Parameters parameters)
116: throws ProcessingException, SAXException, IOException {
117: super .setup(resolver, objectModel, src, parameters);
118:
119: this .resolver = resolver;
120: this .src = src;
121: }
122:
123: public void addBody(Body body) throws SAXException, WingException,
124: UIException, SQLException, IOException, AuthorizeException {
125: // Get actionable URL
126: Collection collection = submission.getCollection();
127: String actionURL = contextPath + "/handle/"
128: + collection.getHandle() + "/submit";
129:
130: SubmissionConfig subConfig = submissionInfo
131: .getSubmissionConfig();
132:
133: //Part A:
134: // Build the main Review Form!
135: Division div = body.addInteractiveDivision("submit-upload",
136: actionURL, Division.METHOD_POST, "primary submission");
137: div.setHead(T_submission_head);
138: addSubmissionProgressList(div);
139:
140: List review = div.addList("submit-review", List.TYPE_FORM);
141: review.setHead(T_head);
142:
143: // Part B:
144: // Add review section for each step
145:
146: //get a list of all pages in progress bar
147: //(this is to ensure we are no looping through non-interactive steps)
148: Set submissionPagesSet = submissionInfo.getProgressBarInfo()
149: .keySet();
150: String[] submissionPages = (String[]) submissionPagesSet
151: .toArray(new String[submissionPagesSet.size()]);
152:
153: //loop through each page in progress bar,
154: //adding each as a separate section to the review form
155: for (int i = 0; i < submissionPages.length; i++) {
156: double currentStepAndPage = Double.valueOf(
157: submissionPages[i]).doubleValue();
158:
159: //If the step we are looking at is this current
160: // Review/Verify step, exit the for loop,
161: // since we have completed all steps up to this one!
162: if (currentStepAndPage == this .stepAndPage) {
163: break;
164: }
165:
166: //load up step configuration
167: SubmissionStepConfig stepConfig = subConfig
168: .getStep(FlowUtils.getStep(currentStepAndPage));
169:
170: //load the step's XML-UI Class
171: AbstractStep stepUIClass = loadXMLUIClass(stepConfig
172: .getXMLUIClassName());
173:
174: try {
175: //initialize this class (with proper step parameter)
176: parameters.setParameter("step", Double
177: .toString(currentStepAndPage));
178: stepUIClass.setup(resolver, objectModel, src,
179: parameters);
180: } catch (Exception e) {
181: throw new UIException(
182: "Unable to initialize AbstractStep identified by "
183: + stepConfig.getXMLUIClassName() + ":",
184: e);
185: }
186:
187: //If this stepUIClass is not a value AbstractSubmissionStep,
188: //we will be unable to display its review information!
189: if (stepUIClass instanceof AbstractSubmissionStep) {
190: //add the Review section for this step,
191: //and return a reference to that newly created step section
192: List stepSection = ((AbstractSubmissionStep) stepUIClass)
193: .addReviewSection(review);
194:
195: //as long as this step has something to review
196: if (stepSection != null) {
197: //add a Jump To button for this section
198: addJumpButton(stepSection, T_submit_jump,
199: currentStepAndPage);
200: }
201: } else {
202: //Log a warning that this step cannot be reviewed!
203: log
204: .warn("The Step represented by "
205: + stepConfig.getXMLUIClassName()
206: + " is not a valid AbstractSubmissionStep, so it cannot be reviewed during the ReviewStep!");
207: }
208: }
209:
210: // Part C:
211: // add standard control/paging buttons
212: addControlButtons(review);
213:
214: div.addHidden("submission-continue").setValue(knot.getId());
215: }
216:
217: /**
218: * Each submission step must define its own information to be reviewed
219: * during the final Review/Verify Step in the submission process.
220: * <P>
221: * The information to review should be tacked onto the passed in
222: * List object.
223: * <P>
224: * NOTE: To remain consistent across all Steps, you should first
225: * add a sub-List object (with this step's name as the heading),
226: * by using a call to reviewList.addList(). This sublist is
227: * the list you return from this method!
228: *
229: * @param reviewList
230: * The List to which all reviewable information should be added
231: * @return
232: * The new sub-List object created by this step, which contains
233: * all the reviewable information. If this step has nothing to
234: * review, then return null!
235: */
236: public List addReviewSection(List reviewList) throws SAXException,
237: WingException, UIException, SQLException, IOException,
238: AuthorizeException {
239: //Review step cannot review itself :)
240: return null;
241: }
242:
243: /**
244: * Recycle
245: */
246: public void recycle() {
247: super .recycle();
248: }
249:
250: /**
251: * Loads the specified XML-UI class
252: * which will generate the review information
253: * for a given step
254: *
255: * @return AbstractStep which references
256: * the XML-UI Class
257: */
258: private AbstractStep loadXMLUIClass(String transformerClassName)
259: throws UIException {
260: try {
261: //retrieve an instance of the transformer class
262: ClassLoader loader = this .getClass().getClassLoader();
263: Class stepClass = loader.loadClass(transformerClassName);
264:
265: // this XML-UI class *must* be a valid AbstractStep,
266: // or else we'll have problems here
267: return (AbstractStep) stepClass.newInstance();
268: } catch (ClassNotFoundException cnfe) {
269: //means that we couldn't find a class by the given name
270: throw new UIException("Class Not Found: "
271: + transformerClassName, cnfe);
272: } catch (Exception e) {
273: //means we couldn't instantiate the class as an AbstractStep
274: throw new UIException(
275: "Unable to instantiate class "
276: + transformerClassName
277: + ". "
278: + "Please make sure it extends org.dspace.app.xmlui.submission.AbstractSubmissionStep!",
279: e);
280: }
281: }
282:
283: }
|