Package org.dspace.embargo

Source Code of org.dspace.embargo.EmbargoManager

/*
* EmbargoManager.java
*
* Version: $Revision: 1.10 $
*
* Date: $Date: 2009/09/08 20:03:45 $
*
* Copyright (c) 2002-2009, The DSpace Foundation.  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.embargo;

import java.sql.SQLException;
import java.util.Date;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.cli.ParseException;

import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.ItemIterator;
import org.dspace.content.DCDate;
import org.dspace.content.DCValue;
import org.dspace.content.DSpaceObject;
import org.dspace.content.MetadataSchema;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.core.PluginManager;
import org.dspace.handle.HandleManager;

/**
* Public interface to the embargo subsystem.
*
* Configuration properties: (with examples)
*   # DC metadata field to hold the user-supplied embargo terms
*   embargo.field.terms = dc.embargo.terms
*   # DC metadata field to hold computed "lift date" of embargo
*   embargo.field.lift = dc.date.available
*   # String to indicate indefinite (forever) embargo in terms
*   embargo.terms.open = Indefinite
*   # implementation of embargo setter plugin
*   plugin.single.org.dspace.embargo.EmbargoSetter = edu.my.Setter
*   # implementation of embargo lifter plugin
*   plugin.single.org.dspace.embargo.EmbargoLifter = edu.my.Lifter
*
* @author Larry Stone
* @author Richard Rodgers
*/
public class EmbargoManager
{
    /** Special date signalling an Item is to be embargoed forever.
     ** The actual date is the first day of the year 10,000 UTC.
     **/
    public static final DCDate FOREVER = new DCDate("10000-01-01");

    /** log4j category */
    private static Logger log = Logger.getLogger(EmbargoManager.class);

    // Metadata field components for user-supplied embargo terms
    // set from the DSpace configuration by init()
    private static String terms_schema = null;
    private static String terms_element = null;
    private static String terms_qualifier = null;

    // Metadata field components for lift date, encoded as a DCDate
    // set from the DSpace configuration by init()
    private static String lift_schema = null;
    private static String lift_element = null;
    private static String lift_qualifier = null;

    // plugin implementations
    // set from the DSpace configuration by init()
    private static EmbargoSetter setter = null;
    private static EmbargoLifter lifter = null;

    /**
     * Put an Item under embargo until the specified lift date.
     * Calls EmbargoSetter plugin to adjust Item access control policies.
     *
     * @param context the DSpace context
     * @param item the item to embargo
     * @param lift date on which the embargo is to be lifted.
     */
    public static void setEmbargo(Context context, Item item, DCDate lift)
        throws SQLException, AuthorizeException, IOException
    {
        init();
        String slift = lift.toString();
        boolean ignoreAuth = context.ignoreAuthorization();
        try
        {
            context.setIgnoreAuthorization(true);
            item.clearMetadata(lift_schema, lift_element, lift_qualifier, Item.ANY);
            item.addMetadata(lift_schema, lift_element, lift_qualifier, null, slift);
            log.info("Set embargo on Item "+item.getHandle()+", expires on: "+slift);
            setter.setEmbargo(context, item);
            item.update();
        }
        finally
        {
            context.setIgnoreAuthorization(ignoreAuth);
        }
    }

    /**
     * Get the embargo lift date for an Item, if any.  This looks for the
     * metadata field configured to hold embargo terms, and gives it
     * to the EmbargoSetter plugin's method to interpret it into
     * an absolute timestamp.  This is intended to be called at the time
     * the Item is installed into the archive.
     * <p>
     * Note that the plugin is *always* called, in case it gets its cue for
     * the embargo date from sources other than, or in addition to, the
     * specified field.
     *
     * @param context the DSpace context
     * @param item the item to embargo
     * @return lift date on which the embargo is to be lifted, or null if none
     */
    public static DCDate getEmbargoDate(Context context, Item item)
        throws SQLException, AuthorizeException, IOException
    {
        init();
        DCValue terms[] = item.getMetadata(terms_schema, terms_element, terms_qualifier, Item.ANY);
        DCDate result = setter.parseTerms(context, item, terms.length > 0 ? terms[0].value : null);

        // sanity check: do not allow an embargo lift date in the past.
        if (result != null && result.toDate().before(new Date()))
        {
            throw new IllegalArgumentException("Embargo lift date must be in the future, but this is in the past: "+result.toString());
        }
        return result;
    }

    /**
     * Lift the embargo on an item which is assumed to be under embargo.
     * Call the plugin to manage permissions in its own way, then delete
     * the administrative metadata fields that dictated embargo date.
     *
     * @param context the DSpace context
     * @param item the item on which to lift the embargo
     */
    public static void liftEmbargo(Context context, Item item)
        throws SQLException, AuthorizeException, IOException
    {
        init();
        lifter.liftEmbargo(context, item);
        item.clearMetadata(lift_schema, lift_element, lift_qualifier, Item.ANY);

        // set the dc.date.available value to right now
        item.clearMetadata(MetadataSchema.DC_SCHEMA, "date", "available", Item.ANY);
        item.addMetadata(MetadataSchema.DC_SCHEMA, "date", "available", null, DCDate.getCurrent().toString());

        log.info("Lifting embargo on Item "+item.getHandle());
        item.update();
    }

    /**
     * Command-line service to scan for every Items with an expired embargo,
     * and then lift that embargo.
     *
     * Options:
     *   -c,--check         Function: ONLY check the state of embargoed Items, do
     *                      NOT lift any embargoes.
     *   -h,--help          help
     *   -i,--identifier    Process ONLY this Handle identifier(s), which must be
     *                      an Item.  Can be repeated.
     *   -l,--lift          Function: ONLY lift embargoes, do NOT check the state
     *                      of any embargoed Items.
     *   -n,--dryrun        Do not change anything in the data model, print
     *                      message instead.
     *   -v,--verbose       Print a line describing action taken for each
     *                      embargoed Item found.
     *   -q,--quiet         No output except upon error
     */
    public static void main(String argv[])
    {
        init();
        int status = 0;

        Options options = new Options();
        options.addOption("v", "verbose", false,
                "Print a line describing action taken for each embargoed Item found.");
        options.addOption("q", "quiet", false,
                "Do not print anything except for errors.");
        options.addOption("n", "dryrun", false,
                "Do not change anything in the data model, print message instead.");
        options.addOption("i", "identifier", true,
                        "Process ONLY this Handle identifier(s), which must be an Item.  Can be repeated.");
        options.addOption("c", "check", false,
                        "Function: ONLY check the state of embargoed Items, do NOT lift any embargoes.");
        options.addOption("l", "lift", false,
                        "Function: ONLY lift embargoes, do NOT check the state of any embargoed Items.");
        options.addOption("h", "help", false, "help");
        CommandLine line = null;
        try
        {
            line = new PosixParser().parse(options, argv);
        }
        catch(ParseException e)
        {
            System.err.println("Command error: " + e.getMessage());
            new HelpFormatter().printHelp(EmbargoManager.class.getName(), options);
            System.exit(1);
        }

        if (line.hasOption('h'))
        {
            new HelpFormatter().printHelp(EmbargoManager.class.getName(), options);
            System.exit(0);
        }

        // sanity check, --lift and --check are mutually exclusive:
        if (line.hasOption('l') && line.hasOption('c'))
        {
            System.err.println("Command error: --lift and --check are mutually exclusive, try --help for assistance.");
            System.exit(1);
        }

        Context context = null;
        try
        {
            context = new Context();
            context.setIgnoreAuthorization(true);
            Date now = new Date();
            
            // scan items under embargo
            if (line.hasOption('i'))
            {
                for (String handle : line.getOptionValues('i'))
                {
                    DSpaceObject dso = HandleManager.resolveToObject(context, handle);
                    if (dso == null)
                    {
                        System.err.println("Error, cannot resolve handle="+handle+" to a DSpace Item.");
                        status = 1;
                    }
                    else if (dso.getType() != Constants.ITEM)
                    {
                        System.err.println("Error, the handle="+handle+" is not a DSpace Item.");
                        status = 1;
                    }
                    else
                    {
                        if (processOneItem(context, (Item)dso, line, now))
                            status = 1;
                    }
                }
            }
            else
            {
                ItemIterator ii = Item.findByMetadataField(context, lift_schema, lift_element, lift_qualifier, Item.ANY);
                while (ii.hasNext())
                {
                    if (processOneItem(context, ii.next(), line, now))
                        status = 1;
                }
            }
            log.debug("Cache size at end = "+context.getCacheSize());
            context.complete();
            context = null;
        }
        catch (Exception e)
        {
            System.err.println("ERROR, got exception: "+e);
            e.printStackTrace();
            status = 1;
        }
        finally
        {
            if (context != null)
            {
                try
                {
                    context.abort();
                }
                catch (Exception e)
                {
                }
            }
        }
        System.exit(status);
    }

    // lift or check embargo on one Item, handle exceptions
    // return flase on success, true if there was fatal exception.
    private static boolean processOneItem(Context context, Item item, CommandLine line, Date now)
        throws Exception
    {
        boolean status = false;
        DCValue lift[] = item.getMetadata(lift_schema, lift_element, lift_qualifier, Item.ANY);

        if (lift.length > 0)
        {
            // need to survive any failure on a single item, go on to process the rest.
            try
            {
                DCDate liftDate = new DCDate(lift[0].value);
                log.debug("Testing embargo on item="+item.getHandle()+", date="+liftDate.toString());
                if (liftDate.toDate().before(now))
                {
                    if (line.hasOption('v'))
                        System.err.println("Lifting embargo from Item handle="+item.getHandle()+", lift date="+lift[0].value);
                    if (line.hasOption('n'))
                    {
                        if (!line.hasOption('q'))
                            System.err.println("DRY RUN: would have lifted embargo from Item handle="+item.getHandle()+", lift date="+lift[0].value);
                    }
                    else if (!line.hasOption('c'))
                        liftEmbargo(context, item);
                }
                else if (!line.hasOption('l'))
                {
                    if (line.hasOption('v'))
                        System.err.println("Checking current embargo on Item handle="+item.getHandle()+", lift date="+lift[0].value);
                    setter.checkEmbargo(context, item);
                }
            }
            catch (Exception e)
            {
                log.error("Failed attempting to lift embargo, item="+item.getHandle()+": ", e);
                System.err.println("Failed attempting to lift embargo, item="+item.getHandle()+": "+ e);
                status = true;
            }
        }
        context.removeCached(item, item.getID());
        return status;
    }

    // initialize - get plugins and MD field settings from config
    private static void init()
    {
        if (terms_schema == null)
        {
            String terms = ConfigurationManager.getProperty("embargo.field.terms");
            String lift = ConfigurationManager.getProperty("embargo.field.lift");
            if (terms == null || lift == null)
                throw new IllegalStateException("Missing one or more of the required DSpace configuration properties for EmbargoManager, check your configuration file.");
            terms_schema = getSchemaOf(terms);
            terms_element = getElementOf(terms);
            terms_qualifier = getQualifierOf(terms);
            lift_schema = getSchemaOf(lift);
            lift_element = getElementOf(lift);
            lift_qualifier = getQualifierOf(lift);

            setter = (EmbargoSetter)PluginManager.getSinglePlugin(EmbargoSetter.class);
            if (setter == null)
                throw new IllegalStateException("The EmbargoSetter plugin was not defined in DSpace configuration.");
            lifter = (EmbargoLifter)PluginManager.getSinglePlugin(EmbargoLifter.class);
            if (lifter == null)
                throw new IllegalStateException("The EmbargoLifter plugin was not defined in DSpace configuration.");

        }
    }

    // return the schema part of "schema.element.qualifier" metadata field spec
    private static String getSchemaOf(String field)
    {
        String sa[] = field.split("\\.", 3);
        return sa[0];
    }

    // return the element part of "schema.element.qualifier" metadata field spec, if any
    private static String getElementOf(String field)
    {
        String sa[] = field.split("\\.", 3);
        return sa.length > 1 ? sa[1] : null;
    }

    // return the qualifier part of "schema.element.qualifier" metadata field spec, if any
    private static String getQualifierOf(String field)
    {
        String sa[] = field.split("\\.", 3);
        return sa.length > 2 ? sa[2] : null;
    }
}
TOP

Related Classes of org.dspace.embargo.EmbargoManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.