All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dspace.app.util.SubmissionInfo Maven / Gradle / Ivy

/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.app.util;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.InProgressSubmission;

import org.dspace.submit.AbstractProcessingStep;
import org.dspace.workflow.WorkflowItem;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;

/**
 * Information about an item being editing with the submission UI
 * 
 * @author Robert Tansley
 * @version $Revision: 6526 $
 */
public class SubmissionInfo
{
    /** log4j logger */
    private static Logger log = Logger.getLogger(SubmissionInfo.class);
    
    /** The item which is being submitted */
    private InProgressSubmission submissionItem = null;

    /**
    * The Submission process config, which holds all info about the submission
    * process that this item is going through (including all steps, etc)
    */
    private SubmissionConfig submissionConfig = null;
    
    /**
    * Handle of the collection where this item is being submitted
    */
    private String collectionHandle = null;
    
    /***************************************************************************
    * Holds all information used to build the Progress Bar in a key,value set.
    * Keys are the number of the step, followed by the number of the page
    * within the step (e.g. "2.1" = The first page of Step 2) (e.g. "5.2" = The
    * second page of Step 5) Values are the Headings to display for each step
    * (e.g. "Describe")
    **************************************************************************/
    private Map progressBar = null;
    
    /** The element or element_qualifier to show more input boxes for */
    private String moreBoxesFor;

    /** The element or element_qualifier to scroll to initially using anchor */
    private String jumpToField;

    /** If non-empty, form-relative indices of missing fields */
    private List missingFields;

    /** Specific bundle we're dealing with */
    private Bundle bundle;

    /** Specific bitstream we're dealing with */
    private Bitstream bitstream;
    
    /** Reader for submission process configuration file * */
    private static SubmissionConfigReader submissionConfigReader;
    
    /**
     * Default Constructor - PRIVATE
     * 

* Create a SubmissionInfo object * using the load() method! * */ private SubmissionInfo() { } /** * Loads all known submission information based on the given in progress * submission and request object. *

* If subItem is null, then just loads the default submission information * for a new submission. * * @param request * The HTTP Servlet Request object * @param subItem * The in-progress submission we are loading information for * * @return a SubmissionInfo object * * @throws ServletException * if an error occurs */ 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 = new SubmissionConfigReader(); forceReload=true; } // save the item which is going through the submission process subInfo.setSubmissionItem(subItem); // Only if the submission item is created can we set its collection String collectionHandle = SubmissionConfigReader.DEFAULT_COLLECTION; if (subItem != null) { collectionHandle = subItem.getCollection().getHandle(); } // save this collection handle to this submission info object subInfo.setCollectionHandle(collectionHandle); // load Submission Process config for this item's collection // (Note: this also loads the Progress Bar info, since it is // dependent on the Submission config) loadSubmissionConfig(request, subInfo, forceReload); return subInfo; } /** * Is this submission in the workflow process? * * @return true if the current submission is in the workflow process */ public boolean isInWorkflow() { return ((this.submissionItem != null) && (this.submissionItem instanceof WorkflowItem || this.submissionItem instanceof XmlWorkflowItem)); } /** * Return the current in progress submission * * @return the InProgressSubmission object representing the current * submission */ public InProgressSubmission getSubmissionItem() { return this.submissionItem; } /** * Updates the current in progress submission item * * @param subItem * the new InProgressSubmission object */ public void setSubmissionItem(InProgressSubmission subItem) { this.submissionItem = subItem; } /** * Return the current submission process config (which includes all steps * which need to be completed for the submission to be successful) * * @return the SubmissionConfig object, which contains info on all the steps * in the current submission process */ public SubmissionConfig getSubmissionConfig() { return this.submissionConfig; } /** * Causes the SubmissionConfig to be completely reloaded from the 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). * * @param request * The HTTP Servlet Request object * * @throws ServletException * if an error occurs */ public void reloadSubmissionConfig(HttpServletRequest request) throws ServletException { // Only if the submission item is created can we set its collection String collectionHandle = SubmissionConfigReader.DEFAULT_COLLECTION; if (this.submissionItem != null) { collectionHandle = submissionItem.getCollection().getHandle(); } this.setCollectionHandle(collectionHandle); // force a reload of the submission process configuration loadSubmissionConfig(request, this, true); } /** * Returns a particular global step definition based on its ID. *

* Global step definitions are those defined in the * section of the configuration file. * * @param stepID * step's identifier * * @return the SubmissionStepConfig representing the step * * @throws ServletException * if no default submission process configuration defined */ public SubmissionStepConfig getStepConfig(String stepID) throws ServletException { return submissionConfigReader.getStepConfig(stepID); } /** * Return text information suitable for logging. *

* This method is used by several of the Step classes * to log major events during the submission process (e.g. when * license agreement was accepted, when item was submitted, * when it was available in DSpace, etc.) * * @return the type and ID of the submission, bundle and/or bitstream for * logging */ public String getSubmissionLogInfo() { String info = ""; if (isInWorkflow()) { info = info + "workflow_id=" + getSubmissionItem().getID(); } else { info = info + "workspace_item_id" + getSubmissionItem().getID(); } if (getBundle() != null) { info = info + ",bundle_id=" + getBundle().getID(); } if (getBitstream() != null) { info = info + ",bitstream_id=" + getBitstream().getID(); } return info; } /** * Gets the handle of the collection to which this item is being submitted * * @return the collection handle */ public String getCollectionHandle() { return this.collectionHandle; } /** * Sets the handle of the collection to which this item is being submitted * * @param handle * the new collection handle */ public void setCollectionHandle(String handle) { this.collectionHandle = handle; } /** * Return the information used to build the progress bar (this includes all * the steps in this submission, as well as the ordering and names of the * steps). *

* Returns a Hashmap, with the following specifics: *

* Keys are the number of the step, followed by the number of the page * within the step *

* (e.g. "2.1" = The first page of Step 2) *

* (e.g. "5.2" = The second page of Step 5) *

* Values are the Headings to display for each step (e.g. "Describe") * * @return a Hashmap of Progress Bar information. */ public Map getProgressBarInfo() { return this.progressBar; } /** * Return the current bitstream we're working with (This is used during * upload processes, or user interfaces that are dealing with bitstreams) * * @return the Bitstream object for the bitstream */ public Bitstream getBitstream() { return this.bitstream; } /** * Sets the current bitstream we're working with (This is used during upload * processes, or user interfaces that are dealing with bitstreams) * * @param bits * the bitstream */ public void setBitstream(Bitstream bits) { this.bitstream = bits; } /** * Return the current bundle we're working with (This is used during upload * processes, or user interfaces that are dealing with bundles/bitstreams) * * @return the Bundle object for the bundle */ public Bundle getBundle() { return this.bundle; } /** * Sets the current bundle we're working with (This is used during upload * processes, or user interfaces that are dealing with bundles/bitstreams) * * @param bund * the bundle */ public void setBundle(Bundle bund) { this.bundle = bund; } /** * Return form related indices of the required fields which were not filled * out by the user. * * @return a List of empty fields which are required */ public List getMissingFields() { return this.missingFields; } /** * Sets the form related indices of the required fields which were not * filled out by the user. * * @param missing * the List of empty fields which are required */ public void setMissingFields(List missing) { this.missingFields = missing; } /** * Return metadata field which user has requested more input boxes be * displayed (by pressing "Add More" on one of the "Describe" pages) * * @return the String name of the field element */ public String getMoreBoxesFor() { return this.moreBoxesFor; } /** * Sets the metadata field which user has requested more input boxes be * displayed (by pressing "Add More" on one of the "Describe" pages) * * @param fieldname * the name of the field element on the page */ public void setMoreBoxesFor(String fieldname) { this.moreBoxesFor = fieldname; } /** * Return metadata field which JSP should "jump to" (i.e. set focus on) when * the JSP next loads. This is used during the Describe step. * * @return the String name of the field element */ public String getJumpToField() { return this.jumpToField; } /** * Sets metadata field which JSP should "jump to" (i.e. set focus on) when * the JSP next loads. This is used during the Describe step. * * @param fieldname * the name of the field on the page */ public void setJumpToField(String fieldname) { this.jumpToField = fieldname; } /** * Load necessary information to build the Progress Bar for the Item * Submission Progress. * * This information is returned in the form of a HashMap (which is then * stored as a part of the SubmissionInfo). The HashMap takes the following * form: * * Keys - the number of the step, followed by the number of the page within * the step (e.g. "2.1" = The first page of Step 2) (e.g. "5.2" = The second * page of Step 5) * * Values - the headings to display for each step (e.g. "Describe", * "Verify") * * @param request * The HTTP Servlet Request object * @param subInfo * the SubmissionInfo object we are loading into * @param forceReload * If true, this method reloads from scratch (and overwrites * cached progress bar info) * */ private static void loadProgressBar(HttpServletRequest request, SubmissionInfo subInfo, boolean forceReload) { Map progressBarInfo = null; log.debug("Loading Progress Bar Info"); if (!forceReload) { // first, attempt to load from cache progressBarInfo = loadProgressBarFromCache(request .getSession()); } if (progressBarInfo != null && log.isDebugEnabled()) { log.debug("Found Progress Bar Info in cache: " + progressBarInfo.size() + " pages to display in progress bar"); } // if unable to load from cache, must load from scratch else { progressBarInfo = new LinkedHashMap(); // loop through all steps for (int i = 0; i < subInfo.submissionConfig.getNumberOfSteps(); i++) { // get the current step info SubmissionStepConfig currentStep = subInfo.submissionConfig .getStep(i); String stepNumber = Integer.toString(currentStep .getStepNumber()); String stepHeading = currentStep.getHeading(); // as long as this step is visible, include it in // the Progress Bar if (currentStep.isVisible()) { // default to just one page in this step int numPages = 1; try { // load the processing class for this step ClassLoader loader = subInfo.getClass() .getClassLoader(); Class stepClass = (Class)loader.loadClass(currentStep.getProcessingClassName()); // call the "getNumberOfPages()" method of the class // to get it's number of pages AbstractProcessingStep step = stepClass.newInstance(); // get number of pages from servlet numPages = step.getNumberOfPages(request, subInfo); } catch (Exception e) { log.error( "Error loading progress bar information from Step Class '" + currentStep.getProcessingClassName() + "' Error:", e); } // save each of the step's pages to the progress bar for (int j = 1; j <= numPages; j++) { String pageNumber = Integer.toString(j); // store ("stepNumber.pageNumber", Heading) for each // page in the step progressBarInfo.put(stepNumber + "." + pageNumber, stepHeading); }// end for each page } }// end for each step log.debug("Loaded Progress Bar Info from scratch: " + progressBarInfo.size() + " pages to display in progress bar"); // cache this new progress bar saveProgressBarToCache(request.getSession(), progressBarInfo); }// end if null // save progressBarInfo to submission Info subInfo.progressBar = progressBarInfo; } /** * Saves all progress bar information into session cache. This saves us from * having to reload this same progress bar over and over again. * * @param session * The HTTP Session object * @param progressBarInfo * The progress bar info to cache * */ private static void saveProgressBarToCache(HttpSession session, Map progressBarInfo) { // cache progress bar info to Session session.setAttribute("submission.progressbar", progressBarInfo); } /** * Attempts to retrieve progress bar information (for a particular * collection) from session cache. * * If the progress bar info cannot be found, returns null * * @param session * The HTTP Session object * * @return progressBarInfo HashMap (if found), or null (if not) * */ private static Map loadProgressBarFromCache(HttpSession session) { return (Map) session.getAttribute("submission.progressbar"); } /** * Loads SubmissionConfig object for the given submission info object. If a * SubmissionConfig object cannot be loaded, a Servlet Error is thrown. *

* This method just loads this SubmissionConfig object internally, so that * it is available via a call to "getSubmissionConfig()" * * @param request * The HTTP Servlet Request object * @param subInfo * the SubmissionInfo object we are loading into * @param forceReload * If true, this method reloads from scratch (and overwrites * cached SubmissionConfig) * */ private static void loadSubmissionConfig(HttpServletRequest request, SubmissionInfo subInfo, boolean forceReload) throws ServletException { log.debug("Loading Submission Config information"); if (!forceReload) { // first, try to load from cache subInfo.submissionConfig = loadSubmissionConfigFromCache(request .getSession(), subInfo.getCollectionHandle(), subInfo .isInWorkflow()); } if (subInfo.submissionConfig == null || forceReload) { // reload the proper Submission process config // (by reading the XML config file) subInfo.submissionConfig = submissionConfigReader .getSubmissionConfig(subInfo.getCollectionHandle(), subInfo .isInWorkflow()); // cache this new submission process configuration saveSubmissionConfigToCache(request.getSession(), subInfo.submissionConfig, subInfo.getCollectionHandle(), subInfo.isInWorkflow()); // also must force reload Progress Bar info, // since it's based on the Submission config loadProgressBar(request, subInfo, true); } else { log.debug("Found Submission Config in session cache!"); // try and reload progress bar from cache loadProgressBar(request, subInfo, false); } } /** * Saves SubmissionConfig object into session cache. This saves us from * having to reload this object during every "Step". * * @param session * The HTTP Session object * @param subConfig * The SubmissionConfig to cache * @param collectionHandle * The Collection handle this SubmissionConfig corresponds to * @param isWorkflow * Whether this SubmissionConfig corresponds to a workflow * * */ private static void saveSubmissionConfigToCache(HttpSession session, SubmissionConfig subConfig, String collectionHandle, boolean isWorkflow) { // cache the submission process config // and the collection it corresponds to session.setAttribute("submission.config", subConfig); session.setAttribute("submission.config.collection", collectionHandle); session.setAttribute("submission.config.isWorkflow", Boolean.valueOf( isWorkflow)); } /** * Loads SubmissionConfig object from session cache for the given * Collection. If a SubmissionConfig object cannot be found, null is * returned. * * @param session * The HTTP Session object * @param collectionHandle * The Collection handle of the SubmissionConfig to load * @param isWorkflow * whether or not we loading the Submission process for a * workflow item * * @return The cached SubmissionConfig for this collection */ private static SubmissionConfig loadSubmissionConfigFromCache( HttpSession session, String collectionHandle, boolean isWorkflow) { // attempt to load submission process config // from cache for the current collection String cachedHandle = (String) session .getAttribute("submission.config.collection"); Boolean cachedIsWorkflow = (Boolean) session .getAttribute("submission.config.isWorkflow"); // only load from cache if the collection handle and // workflow item status both match! if (collectionHandle.equals(cachedHandle) && isWorkflow == cachedIsWorkflow.booleanValue()) { return (SubmissionConfig) session.getAttribute("submission.config"); } else { return null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy