/*
* UploadStep.java
*
* Version: $Revision: 3705 $
*
* Date: $Date: 2009-04-11 19:02:24 +0200 (Sat, 11 Apr 2009) $
*
* Copyright (c) 2002, Hewlett-Packard Company and Massachusetts
* Institute of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Hewlett-Packard Company nor the name of the
* Massachusetts Institute of Technology nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package org.dspace.app.xmlui.aspect.submission.submit.jorum;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.log4j.Logger;
import org.dspace.app.xmlui.aspect.submission.AbstractSubmissionStep;
import org.dspace.app.xmlui.aspect.submission.submit.EditFileStep;
import org.dspace.app.xmlui.aspect.submission.submit.ReviewStep;
import org.dspace.app.xmlui.utils.UIException;
import org.dspace.app.xmlui.wing.Message;
import org.dspace.app.xmlui.wing.WingException;
import org.dspace.app.xmlui.wing.element.Body;
import org.dspace.app.xmlui.wing.element.Button;
import org.dspace.app.xmlui.wing.element.Cell;
import org.dspace.app.xmlui.wing.element.CheckBox;
import org.dspace.app.xmlui.wing.element.Division;
import org.dspace.app.xmlui.wing.element.File;
import org.dspace.app.xmlui.wing.element.List;
import org.dspace.app.xmlui.wing.element.Row;
import org.dspace.app.xmlui.wing.element.Table;
import org.dspace.app.xmlui.wing.element.Text;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
import org.dspace.content.BitstreamFormat;
import org.dspace.content.Bundle;
import org.dspace.content.Collection;
import org.dspace.content.DCValue;
import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager;
import org.dspace.workflow.WorkflowItem;
import org.xml.sax.SAXException;
import uk.ac.jorum.dspace.utils.BundleUtils;
/**
* This is a step of the item submission processes. The upload
* stages allows the user to upload files into the submission. The
* form is optimized for one file, but allows the user to upload
* more if needed.
* <P>
* The form is brokenup into three sections:
* <P>
* Part A: Ask the user to upload a file
* Part B: List previously uploaded files
* Part C: The standard action bar
*
* @author Scott Phillips
* @author Tim Donohue (updated for Configurable Submission)
*/
public class JorumUploadStep extends AbstractSubmissionStep {
private static Logger log = Logger.getLogger(JorumUploadStep.class);
/***Added by CG ****/
protected static final Message T_url_label = message("xmlui.Submission.submit.jorum.JorumUploadStep.url_label");
protected static final Message T_url_help = message("xmlui.Submission.submit.jorum.JorumUploadStep.url_help");
protected static final Message T_url_error = message("xmlui.Submission.submit.jorum.JorumUploadStep.url_error");
protected static final Message T_virus_check_failed = message("xmlui.Submission.submit.jorum.JorumUploadStep.virus_check_failed");
private static final String T_URL_DIV_TITLE = "url_div";
private static final String T_URL_TEXT = "url";
private static final String SCHEMA = "dc";
private static final String URL_IDENTIFIER = "identifier";
//altered
protected static final Message J_head = message("xmlui.Submission.submit.jorum.JorumUploadStep.head");
/*******/
/** Language Strings for Uploading **/
protected static final Message T_head = message("xmlui.Submission.submit.UploadStep.head");
protected static final Message T_file = message("xmlui.Submission.submit.UploadStep.file");
protected static final Message T_file_help = message("xmlui.Submission.submit.UploadStep.file_help");
protected static final Message T_file_error = message("xmlui.Submission.submit.UploadStep.file_error");
protected static final Message T_upload_error = message("xmlui.Submission.submit.UploadStep.upload_error");
protected static final Message T_description = message("xmlui.Submission.submit.UploadStep.description");
protected static final Message T_description_help = message("xmlui.Submission.submit.UploadStep.description_help");
protected static final Message T_submit_upload = message("xmlui.Submission.submit.UploadStep.submit_upload");
protected static final Message T_head2 = message("xmlui.Submission.submit.UploadStep.head2");
protected static final Message T_column0 = message("xmlui.Submission.submit.UploadStep.column0");
protected static final Message T_column1 = message("xmlui.Submission.submit.UploadStep.column1");
protected static final Message T_column2 = message("xmlui.Submission.submit.UploadStep.column2");
protected static final Message T_column3 = message("xmlui.Submission.submit.UploadStep.column3");
protected static final Message T_column4 = message("xmlui.Submission.submit.UploadStep.column4");
protected static final Message T_column5 = message("xmlui.Submission.submit.UploadStep.column5");
protected static final Message T_column6 = message("xmlui.Submission.submit.UploadStep.column6");
protected static final Message T_unknown_name = message("xmlui.Submission.submit.UploadStep.unknown_name");
protected static final Message T_unknown_format = message("xmlui.Submission.submit.UploadStep.unknown_format");
protected static final Message T_supported = message("xmlui.Submission.submit.UploadStep.supported");
protected static final Message T_known = message("xmlui.Submission.submit.UploadStep.known");
protected static final Message T_unsupported = message("xmlui.Submission.submit.UploadStep.unsupported");
protected static final Message T_submit_edit = message("xmlui.Submission.submit.UploadStep.submit_edit");
protected static final Message T_checksum = message("xmlui.Submission.submit.UploadStep.checksum");
protected static final Message T_submit_remove = message("xmlui.Submission.submit.UploadStep.submit_remove");
/**
* Global reference to edit file page
* (this is used when a user requests to edit a bitstream)
**/
private EditFileStep editFile = null;
/**
* Establish our required parameters, abstractStep will enforce these.
*/
public JorumUploadStep() {
this.requireSubmission = true;
this.requireStep = true;
}
/**
* Check if user has requested to edit information about an
* uploaded file
*/
public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
throws ProcessingException, SAXException, IOException {
super.setup(resolver, objectModel, src, parameters);
//If this page for editing an uploaded file's information
//was requested, then we need to load EditFileStep instead!
if (this.errorFlag == org.dspace.submit.step.UploadStep.STATUS_EDIT_BITSTREAM) {
this.editFile = new EditFileStep();
this.editFile.setup(resolver, objectModel, src, parameters);
} else
this.editFile = null;
}
public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException,
AuthorizeException {
//If we are actually editing an uploaded file's information,
//then display that body instead!
if (this.editFile != null) {
editFile.addBody(body);
return;
}
//Check for existence of url bundle. If not there, it's a file submission
boolean isUrl = BundleUtils.checkUrl(submissionInfo);
// Get a list of all files in the original bundle
Item item = submission.getItem();
Collection collection = submission.getCollection();
String actionURL = contextPath + "/handle/" + collection.getHandle() + "/submit/" + knot.getId() + ".continue";
boolean workflow = submission instanceof WorkflowItem;
// Need to work out what bundle we're going to display
Bundle[] bundles = BundleUtils.getBundlesForDisplay(item, context);
// Added by CG
Bitstream[] bitstreams = null;
int length = bundles.length;
if (length > 0) {
if(length == 1){
bitstreams = bundles[0].getBitstreams();
}else{
// we're displaying related cps
bitstreams = new Bitstream[length];
int count = 0;
for(Bundle b : bundles){
bitstreams[count] = b.getBitstreams()[0];
count++;
}
}
}else{
bitstreams = new Bitstream[0];
}
// Part A:
// First ask the user if they would like to upload a new file (may be the first one)
Division div = body.addInteractiveDivision("submit-upload", actionURL, Division.METHOD_MULTIPART,
"primary submission");
div.setHead(T_submission_head);
addSubmissionProgressList(div);
List upload = null;
if (!workflow) {
// Only add the upload capabilities for new item submissions
upload = div.addList("submit-upload-new", List.TYPE_FORM);
//upload.setHead(T_head);
upload.setHead(J_head);
if (!isUrl) {
File file = upload.addItem().addFile("file");
file.setLabel(T_file);
file.setHelp(T_file_help);
file.setRequired();
//if no files found error was thrown by processing class, display it!
if (this.errorFlag == org.dspace.submit.step.jorum.JorumUploadStep.STATUS_NO_FILES_ERROR) {
file.addError(T_file_error);
}
// if an upload error was thrown by processing class, display it!
if (this.errorFlag == org.dspace.submit.step.jorum.JorumUploadStep.STATUS_UPLOAD_ERROR) {
file.addError(T_upload_error);
}
// GH
// if an upload error was thrown by processing class, display it!
if (this.errorFlag == org.dspace.submit.step.jorum.JorumUploadStep.VIRUS_CHECK_FAILED) {
Object[] adminEmail = {ConfigurationManager.getProperty("mail.admin")};
file.addError(T_virus_check_failed.parameterize(adminEmail));
}
// GH - end
Button uploadSubmit = upload.addItem().addButton("submit_upload");
uploadSubmit.setValue(T_submit_upload);
}
else{
/***Added by CG ****/
String urlValue = "http://";
//It is a url
Text url = upload.addItem(T_URL_DIV_TITLE,"").addText(T_URL_TEXT);
url.setLabel(T_url_label);
url.setHelp(T_url_help);
//Get the metadata from the item to see if the identifier has already been set
DCValue[] dcVals = item.getMetadata(SCHEMA, URL_IDENTIFIER, null, Item.ANY);
for(DCValue value : dcVals){
urlValue = value.value;
}
url.setValue(urlValue);
//The error flag will be set from JorumUploadStep processing class if no url entered.
if (this.errorFlag == org.dspace.submit.step.jorum.JorumUploadStep.STATUS_MISSING_URL) {
url.addError(T_url_error);
//reset the error flag
this.errorFlag=0;
}
//Not sure this really does anything?
url.setRequired(true);
}
/*******/
}
// Part B:
// If the user has allready uploaded files provide a list for the user.
if (bitstreams.length > 0 || workflow) {
Table summary = div.addTable("submit-upload-summary", (bitstreams.length * 2) + 2, 6);
summary.setHead(T_head2);
Row header = summary.addRow(Row.ROLE_HEADER);
header.addCellContent(T_column1); // select checkbox
header.addCellContent(T_column2); // file name
header.addCellContent(T_column6); // edit button
for (Bitstream bitstream : bitstreams) {
int id = bitstream.getID();
String name = bitstream.getName();
String url = contextPath + "/bitstream/item/" + item.getID() + "/" + name;
long bytes = bitstream.getSize();
String algorithm = bitstream.getChecksumAlgorithm();
String checksum = bitstream.getChecksum();
BitstreamFormat format = bitstream.getFormat();
int support = format.getSupportLevel();
Row row = summary.addRow();
if (!workflow) {
// Workflow users can not remove files.
CheckBox remove = row.addCell().addCheckBox("remove");
remove.setLabel("remove");
remove.addOption(id);
} else {
row.addCell();
}
row.addCell().addXref(url, name);
// Edited by CG
Row size = summary.addRow();
size.addCell();
Cell checksumCell = size.addCell(null, null, 0, 6, null);
checksumCell.addHighlight("bold").addContent(T_column3);
checksumCell.addContent(" : ");
checksumCell.addContent(bytes + " bytes");
Row formatRow = summary.addRow();
formatRow.addCell();
Cell formatCell = formatRow.addCell(null, null, 0, 6, null);
formatCell.addHighlight("bold").addContent(T_column5);
formatCell.addContent(" : ");
if (format == null) {
formatCell.addContent(T_unknown_format);
} else {
formatCell.addContent(format.getMIMEType());
switch (support) {
case 1:
formatCell.addContent(T_supported);
break;
case 2:
formatCell.addContent(T_known);
break;
case 3:
formatCell.addContent(T_unsupported);
break;
}
}
}
if (!workflow) {
// Workflow user's can not remove files.
Row actionRow = summary.addRow();
actionRow.addCell();
Button removeSeleceted = actionRow.addCell(null, null, 0, 6, null).addButton("submit_remove_selected");
removeSeleceted.setValue(T_submit_remove);
}
upload = div.addList("submit-upload-new-part2", List.TYPE_FORM);
}
// Part C:
// add standard control/paging buttons
addControlButtons(upload);
}
/**
* Each submission step must define its own information to be reviewed
* during the final Review/Verify Step in the submission process.
* <P>
* The information to review should be tacked onto the passed in
* List object.
* <P>
* NOTE: To remain consistent across all Steps, you should first
* add a sub-List object (with this step's name as the heading),
* by using a call to reviewList.addList(). This sublist is
* the list you return from this method!
*
* @param reviewList
* The List to which all reviewable information should be added
* @return
* The new sub-List object created by this step, which contains
* all the reviewable information. If this step has nothing to
* review, then return null!
*/
public List addReviewSection(List reviewList) throws SAXException, WingException, UIException, SQLException,
IOException, AuthorizeException {
// Create a new list section for this step (and set its heading)
List uploadSection = reviewList.addList("submit-review-" + this.stepAndPage, List.TYPE_FORM);
uploadSection.setHead(T_head);
//Review all uploaded files
Bundle[] bundles = submission.getItem().getBundles("ORIGINAL");
Bitstream[] bitstreams = new Bitstream[0];
if (bundles.length > 0) {
bitstreams = bundles[0].getBitstreams();
}
for (Bitstream bitstream : bitstreams) {
BitstreamFormat bitstreamFormat = bitstream.getFormat();
int id = bitstream.getID();
String name = bitstream.getName();
String url = contextPath + "/retrieve/" + id + "/" + name;
String format = bitstreamFormat.getShortDescription();
Message support = ReviewStep.T_unknown;
if (bitstreamFormat.getSupportLevel() == BitstreamFormat.KNOWN)
support = T_known;
else if (bitstreamFormat.getSupportLevel() == BitstreamFormat.SUPPORTED)
support = T_supported;
org.dspace.app.xmlui.wing.element.Item file = uploadSection.addItem();
file.addXref(url, name);
file.addContent(" - " + format + " ");
file.addContent(support);
}
//return this new "upload" section
return uploadSection;
}
}