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

org.dspace.content.packager.DSpaceMETSIngester Maven / Gradle / Ivy

There is a newer version: 8.0
Show newest version
/**
 * 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.io.InputStream;
import java.sql.SQLException;

import org.dspace.app.mediafilter.MediaFilter;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.content.crosswalk.MetadataValidationException;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.factory.CoreServiceFactory;
import org.dspace.core.service.PluginService;
import org.jdom.Element;

/**
 * Packager plugin to ingest a
 * METS (Metadata Encoding and Transmission Standard) package
 * that conforms to the DSpace METS SIP (Submission Information Package) Profile.
 * See http://www.loc.gov/standards/mets/
 * for more information on METS, and
 * 
 * http://www.dspace.org/standards/METS/SIP/profilev0p9p1/metssipv0p9p1.pdf
 * (or a similar file in the /standards/METS/SIP resource hierarchy)
 * for more information about the DSpace METS SIP profile.
 *
 * @author Larry Stone
 * @author Tim Donohue
 * @version $Revision$
 * @see org.dspace.content.packager.METSManifest
 * @see AbstractMETSIngester
 * @see AbstractPackageIngester
 * @see PackageIngester
 */
public class DSpaceMETSIngester
    extends AbstractMETSIngester {
    // first part of required mets@PROFILE value
    protected static final String PROFILE_START = "DSpace METS SIP Profile";

    // just check the profile name.
    @Override
    void checkManifest(METSManifest manifest)
        throws MetadataValidationException {
        String profile = manifest.getProfile();
        if (profile == null) {
            throw new MetadataValidationException("Cannot accept METS with no PROFILE attribute!");
        } else if (!profile.startsWith(PROFILE_START)) {
            throw new MetadataValidationException("METS has unacceptable PROFILE value, profile=" + profile);
        }
    }

    /**
     * Choose DMD section(s) to crosswalk.
     * 

* The algorithm is:
* 1. Use whatever the dmd parameter specifies as the primary DMD.
* 2. If (1) is unspecified, find MODS (preferably) or DC as primary DMD.
* 3. If (1) or (2) succeeds, crosswalk it and ignore all other DMDs with * same GROUPID
* 4. Crosswalk remaining DMDs not eliminated already. * * @throws CrosswalkException if crosswalk error * @throws PackageValidationException if validation error * @throws IOException if IO error * @throws SQLException if database error * @throws AuthorizeException if authorization error */ @Override public void crosswalkObjectDmd(Context context, DSpaceObject dso, METSManifest manifest, MdrefManager callback, Element dmds[], PackageParameters params) throws CrosswalkException, PackageValidationException, AuthorizeException, SQLException, IOException { int found = -1; // Check to see what dmdSec the user specified in the 'dmd' parameter String userDmd = null; if (params != null) { userDmd = params.getProperty("dmd"); } if (userDmd != null && userDmd.length() > 0) { for (int i = 0; i < dmds.length; ++i) { if (userDmd.equalsIgnoreCase(manifest.getMdType(dmds[i]))) { found = i; } } } // MODS is preferred, if nothing specified by user if (found == -1) { for (int i = 0; i < dmds.length; ++i) { //NOTE: METS standard actually says this should be MODS (all uppercase). But, // just in case, we're going to be a bit more forgiving. if ("MODS".equalsIgnoreCase(manifest.getMdType(dmds[i]))) { found = i; } } } // DC acceptable if no MODS if (found == -1) { for (int i = 0; i < dmds.length; ++i) { //NOTE: METS standard actually says this should be DC (all uppercase). But, // just in case, we're going to be a bit more forgiving. if ("DC".equalsIgnoreCase(manifest.getMdType(dmds[i]))) { found = i; } } } String groupID = null; if (found >= 0) { manifest.crosswalkItemDmd(context, params, dso, dmds[found], callback); groupID = dmds[found].getAttributeValue("GROUPID"); if (groupID != null) { for (int i = 0; i < dmds.length; ++i) { String g = dmds[i].getAttributeValue("GROUPID"); if (g != null && !g.equals(groupID)) { manifest.crosswalkItemDmd(context, params, dso, dmds[i], callback); } } } } else { // otherwise take the first. Don't xwalk more than one because // each xwalk _adds_ metadata, and could add duplicate fields. if (dmds.length > 0) { manifest.crosswalkItemDmd(context, params, dso, dmds[0], callback); } } } /** * Policy: For DSpace deposit license, take deposit license * supplied by explicit argument first, else use collection's * default deposit license. * For Creative Commons, look for a rightsMd containing a CC license. * * @throws PackageValidationException if validation error * @throws IOException if IO error * @throws SQLException if database error * @throws AuthorizeException if authorization error */ @Override public void addLicense(Context context, Item item, String license, Collection collection, PackageParameters params) throws PackageValidationException, AuthorizeException, SQLException, IOException { if (PackageUtils.findDepositLicense(context, item) == null) { PackageUtils.addDepositLicense(context, license, item, collection); } } @Override public void finishObject(Context context, DSpaceObject dso, PackageParameters params) throws PackageValidationException, CrosswalkException, AuthorizeException, SQLException, IOException { // nothing to do. } @Override public int getObjectType(METSManifest manifest) throws PackageValidationException { return Constants.ITEM; } // return name of derived file as if MediaFilter created it, or null // only needed when importing a SIP without canonical DSpace derived file naming. private String makeDerivedFilename(String bundleName, String origName) { PluginService pluginService = CoreServiceFactory.getInstance().getPluginService(); // get the MediaFilter that would create this bundle: String mfNames[] = pluginService.getAllPluginNames(MediaFilter.class); for (int i = 0; i < mfNames.length; ++i) { MediaFilter mf = (MediaFilter) pluginService.getNamedPlugin(MediaFilter.class, mfNames[i]); if (bundleName.equals(mf.getBundleName())) { return mf.getFilteredName(origName); } } return null; } /** * Take a second pass over files to correct names of derived files * (e.g. thumbnails, extracted text) to what DSpace expects: * * @throws MetadataValidationException if validation error * @throws IOException if IO error * @throws SQLException if database error * @throws AuthorizeException if authorization error */ @Override public void finishBitstream(Context context, Bitstream bs, Element mfile, METSManifest manifest, PackageParameters params) throws MetadataValidationException, SQLException, AuthorizeException, IOException { String bundleName = METSManifest.getBundleName(mfile); if (!bundleName.equals(Constants.CONTENT_BUNDLE_NAME)) { String opath = manifest.getOriginalFilePath(mfile); if (opath != null) { // String ofileId = origFile.getAttributeValue("ID"); // Bitstream obs = (Bitstream)fileIdToBitstream.get(ofileId); String newName = makeDerivedFilename(bundleName, opath); if (newName != null) { //String mfileId = mfile.getAttributeValue("ID"); //Bitstream bs = (Bitstream)fileIdToBitstream.get(mfileId); bs.setName(context, newName); bitstreamService.update(context, bs); } } } } @Override public String getConfigurationName() { return "dspaceSIP"; } public boolean probe(Context context, InputStream in, PackageParameters params) { throw new UnsupportedOperationException("PDF package ingester does not implement probe()"); } /** * Returns a user help string which should describe the * additional valid command-line options that this packager * implementation will accept when using the -o or * --option 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] " + "Type of the METS which should be used for primary item metadata (defaults to MODS, then DC)"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy