/**
* 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.content.packager;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bundle;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.license.CreativeCommons;
import edu.harvard.hul.ois.mets.Agent;
import edu.harvard.hul.ois.mets.Mets;
import edu.harvard.hul.ois.mets.MetsHdr;
import edu.harvard.hul.ois.mets.Role;
import edu.harvard.hul.ois.mets.helper.MetsException;
import edu.harvard.hul.ois.mets.Type;
import edu.harvard.hul.ois.mets.Name;
import edu.harvard.hul.ois.mets.helper.PCData;
/**
* Packager plugin to produce a
* METS (Metadata Encoding & Transmission Standard) package
* that is accepted as a DSpace METS SIP (Submission Information Package).
* See <a href="http://www.loc.gov/standards/mets/">http://www.loc.gov/standards/mets/</a>
* for more information on METS.
* <p>
* This class does not produce a true DSpace DIP, because there was no
* DIP standard when it was implemented. It does contain some features
* beyond the requirements of a SIP (e.g. deposit licenses), anticipating
* the DIP specification.
* <p>
* DSpaceMETSDisseminator was intended to be an useful example of a packager
* plugin, and a way to create packages acceptable to the METS SIP importer.
*
* @author Larry Stone
* @version $Revision$
*/
public class DSpaceMETSDisseminator
extends AbstractMETSDisseminator
{
/**
* Identifier for the package we produce, i.e. DSpace METS SIP
* Profile. Though not strictly true, there is no DIP standard yet
* so it's the most meaningful label we can apply.
*/
private static final String PROFILE_LABEL = "DSpace METS SIP Profile 1.0";
// MDTYPE value for deposit license -- "magic string"
// NOTE: format is <label-for-METS>:<DSpace-crosswalk-name>
private static final String DSPACE_DEPOSIT_LICENSE_MDTYPE = "DSpaceDepositLicense:DSPACE_DEPLICENSE";
// MDTYPE value for CC license in RDF -- "magic string"
// NOTE: format is <label-for-METS>:<DSpace-crosswalk-name>
private static final String CREATIVE_COMMONS_RDF_MDTYPE = "CreativeCommonsRDF:DSPACE_CCRDF";
// MDTYPE value for CC license in Text -- "magic string"
// NOTE: format is <label-for-METS>:<DSpace-crosswalk-name>
private static final String CREATIVE_COMMONS_TEXT_MDTYPE = "CreativeCommonsText:DSPACE_CCTXT";
/**
* Return identifier string for the profile this produces.
*
* @return string name of profile.
*/
@Override
public String getProfile()
{
return PROFILE_LABEL;
}
/**
* Returns name of METS fileGrp corresponding to a DSpace bundle name.
* They are mostly the same except for bundle "ORIGINAL" maps to "CONTENT".
* Don't worry about the metadata bundles since they are not
* packaged as fileGrps, but in *mdSecs.
* @param bname name of DSpace bundle.
* @return string name of fileGrp
*/
@Override
public String bundleToFileGrp(String bname)
{
if (bname.equals("ORIGINAL"))
{
return "CONTENT";
}
else
{
return bname;
}
}
/**
* Create metsHdr element - separate so subclasses can override.
*/
@Override
public MetsHdr makeMetsHdr(Context context, DSpaceObject dso,
PackageParameters params)
{
MetsHdr metsHdr = new MetsHdr();
// FIXME: CREATEDATE is now: maybe should be item create?
metsHdr.setCREATEDATE(new Date());
// Agent
Agent agent = new Agent();
agent.setROLE(Role.CUSTODIAN);
agent.setTYPE(Type.ORGANIZATION);
Name name = new Name();
name.getContent()
.add(new PCData(ConfigurationManager
.getProperty("dspace.name")));
agent.getContent().add(name);
metsHdr.getContent().add(agent);
return metsHdr;
}
/**
* Get DMD choice for Item. It defaults to MODS, but is overridden
* by the package parameters if they contain any "dmd" keys. The
* params may contain one or more values for "dmd"; each of those is
* the name of a crosswalk plugin, optionally followed by colon and
* its METS MDTYPE name.
*/
@Override
public String [] getDmdTypes(Context context, DSpaceObject dso, PackageParameters params)
throws SQLException, IOException, AuthorizeException
{
// XXX FIXME maybe let dmd choices be configured in DSpace config?
String result[] = null;
if (params != null)
{
result = params.getProperties("dmd");
}
if (result == null || result.length == 0)
{
result = new String[1];
result[0] = "MODS";
}
return result;
}
/**
* Get name of technical metadata crosswalk for Bitstreams.
* Default is PREMIS. This is both the name of the crosswalk plugin
* and the METS MDTYPE.
*/
@Override
public String[] getTechMdTypes(Context context, DSpaceObject dso, PackageParameters params)
throws SQLException, IOException, AuthorizeException
{
if (dso.getType() == Constants.BITSTREAM)
{
String result[] = new String[1];
result[0] = "PREMIS";
return result;
}
else
{
return new String[0];
}
}
@Override
public String[] getSourceMdTypes(Context context, DSpaceObject dso, PackageParameters params)
throws SQLException, IOException, AuthorizeException
{
return new String[0];
}
@Override
public String[] getDigiprovMdTypes(Context context, DSpaceObject dso, PackageParameters params)
throws SQLException, IOException, AuthorizeException
{
return new String[0];
}
/**
* Add rights MD (licenses) for DSpace item. These
* may include a deposit license, and Creative Commons.
*/
@Override
public String[] getRightsMdTypes(Context context, DSpaceObject dso, PackageParameters params)
throws SQLException, IOException, AuthorizeException
{
List<String> result = new ArrayList<String>();
if (dso.getType() == Constants.ITEM)
{
Item item = (Item)dso;
if (PackageUtils.findDepositLicense(context, item) != null)
{
result.add(DSPACE_DEPOSIT_LICENSE_MDTYPE);
}
if (CreativeCommons.getLicenseRdfBitstream(item) != null)
{
result.add(CREATIVE_COMMONS_RDF_MDTYPE);
}
else if (CreativeCommons.getLicenseTextBitstream(item) != null)
{
result.add(CREATIVE_COMMONS_TEXT_MDTYPE);
}
}
return result.toArray(new String[result.size()]);
}
// This is where we'd elaborate on the default structMap; nothing to add, yet.
@Override
public void addStructMap(Context context, DSpaceObject dso,
PackageParameters params, Mets mets)
throws SQLException, IOException, AuthorizeException, MetsException
{
}
// only exclude metadata bundles from package.
@Override
public boolean includeBundle(Bundle bundle)
{
return ! PackageUtils.isMetaInfoBundle(bundle);
}
/**
* Returns a user help string which should describe the
* additional valid command-line options that this packager
* implementation will accept when using the <code>-o</code> or
* <code>--option</code> flags with the Packager script.
*
* @return a string describing additional command-line options available
* with this packager
*/
@Override
public String getParameterHelp()
{
String parentHelp = super.getParameterHelp();
//Return superclass help info, plus the extra parameter/option that this class supports
return parentHelp +
"\n\n" +
"* dmd=[dmdSecType] " +
"(Repeatable) Type(s) of the METS <dmdSec> which should be created in the dissemination package (defaults to MODS)";
}
}