eu.prestoprime.plugin.rights.RightsTasks.java Source code

Java tutorial

Introduction

Here is the source code for eu.prestoprime.plugin.rights.RightsTasks.java

Source

/**
 * RightsTasks.java
 * Author: Francesco Gallo (gallo@eurix.it)
 * 
 * This file is part of PrestoPRIME Preservation Platform (P4).
 * 
 * Copyright (C) 2012 EURIX Srl, Torino, Italy
 *  
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package eu.prestoprime.plugin.rights;

import it.eurix.archtools.data.DataException;
import it.eurix.archtools.data.model.AIP;
import it.eurix.archtools.data.model.DIP;
import it.eurix.archtools.data.model.DIP.DCField;
import it.eurix.archtools.data.model.IPException;
import it.eurix.archtools.data.model.SIP;
import it.eurix.archtools.persistence.DatabaseException;
import it.eurix.archtools.tool.ToolException;
import it.eurix.archtools.tool.ToolOutput;
import it.eurix.archtools.tool.impl.MessageDigestExtractor;
import it.eurix.archtools.workflow.exceptions.TaskExecutionFailedException;
import it.eurix.archtools.workflow.plugin.WfPlugin;
import it.eurix.archtools.workflow.plugin.WfPlugin.WfService;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;

import eu.prestoprime.conf.ConfigurationManager;
import eu.prestoprime.conf.P4PropertyManager.P4Property;
import eu.prestoprime.datamanagement.P4DataManager;
import eu.prestoprime.model.ext.rights.Results;
import eu.prestoprime.model.ext.rights.Results.Row;
import eu.prestoprime.model.ext.rights.RightsIndex;
import eu.prestoprime.plugin.p4.tools.Dot;
import eu.prestoprime.plugin.p4.tools.XSLTProc;

@WfPlugin(name = "RightsPlugin")
public class RightsTasks {

    private static final Logger logger = LoggerFactory.getLogger(RightsTasks.class);

    @WfService(name = "rights_management", version = "2.0.0")
    public void management(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamFile) throws TaskExecutionFailedException {

        // get sipID
        String sipID = dParamsString.get("sipID");

        // get sip
        SIP sip = null;
        try {
            sip = P4DataManager.getInstance().getSIPByID(sipID);

            // check if rights are either in mdWrap or in mdRef
            List<String> rightsList = sip.executeQuery("//mets:rightsMD/mets:mdRef/@xlink:href");

            Node rights = null;
            if (rightsList.size() != 0) {
                // in mdRef
                String rightsURL = rightsList.get(0);

                // download
                try {
                    HttpClient client = new DefaultHttpClient();
                    HttpUriRequest request = new HttpGet(rightsURL);
                    HttpEntity entity = client.execute(request).getEntity();
                    if (entity != null) {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
                        String line;
                        StringBuffer sb = new StringBuffer();
                        while ((line = reader.readLine()) != null) {
                            sb.append(line.trim());
                        }
                        // parse
                        rights = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                                .parse(new ByteArrayInputStream(sb.toString().getBytes()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                // in mdWrap
                // parse
                List<Node> rightsNodeList = sip.executeNodeQuery("//mets:rightsMD/mets:mdWrap/mets:xmlData/*[1]");
                if (rightsNodeList.size() != 0) {
                    rights = rightsNodeList.get(0);
                }
            }

            if (rights != null) {
                TransformerFactory.newInstance().newTransformer().transform(new DOMSource(rights),
                        new StreamResult(System.out));

                // add rights to sip resources
                String rightsID = sip.setRights(rights);

                // send rightsID to other tasks
                dParamsString.put("rightsID", rightsID);

                // create rightsFile
                File owlFile = File.createTempFile("rights-", ".owl");
                TransformerFactory.newInstance().newTransformer().transform(new DOMSource(rights),
                        new StreamResult(owlFile));

                // create graph
                XSLTProc xsltproc = new XSLTProc();
                String digraphxsl = xsltproc.addResourceFile("writedigraph.xsl");
                xsltproc.setXSLFile(digraphxsl);
                xsltproc.addStringParam("colors", "on");

                xsltproc.extract(owlFile.getAbsolutePath());
                String dotGraphFilePath = xsltproc.getOutputFile();

                String owlGraphName = rightsID + ".png";
                File owlGraph = new File(dParamsString.get("graphFolder"), owlGraphName);

                new Dot().createGraph(dotGraphFilePath, owlGraph.getAbsolutePath());

                // index rights
                RightsUtils.indexRights(sipID, owlFile);
                owlFile.delete();

            } else {
                logger.debug("No rights found...");
                // there aren't rights
            }
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to retrieve the SIP...");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to add rights to the SIP...");
        } catch (IOException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to write rights on file...");
        } catch (ToolException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to run XSLTproc...");
        } catch (Exception e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to extract graph...");
        } finally {
            P4DataManager.getInstance().releaseIP(sip);
        }
    }

    @WfService(name = "configure_rights_storage", version = "0.8.0")
    public void configureStorage(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        String aipID = dParamsString.get("id");

        String p4storeFolder = ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_STORAGE_VOLUME)
                + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_STORAGE_FOLDER)
                + File.separator + aipID;

        String graphFolder = p4storeFolder + File.separator
                + ConfigurationManager.getPropertyInstance().getProperty(P4Property.P4_GRAPH_FOLDER);
        new File(graphFolder).mkdirs();
        dParamsString.put("graphFolder", graphFolder);
    }

    @WfService(name = "rights_update", version = "0.8.0")
    public void update(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        // retrieve dynamic parameters
        String id = dParamsString.get("id");
        File rightsFile = dParamsFile.get("resultFile");

        // update AIP
        try {
            // parse resultFile
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Node node = dbf.newDocumentBuilder().parse(rightsFile);

            // get AIP
            AIP aip = P4DataManager.getInstance().getAIPByID(id);

            // update AIP
            String rightsID = aip.updateSection(node, "rights");

            // add MPEG-21 MCO as additional format
            List<String> formatList = aip.getDCField(DCField.format);
            boolean hasMPEG21MCOFormat = false;
            for (String format : formatList) {
                if (format.contains("MPEG-21 MCO")) {
                    hasMPEG21MCOFormat = true;
                    break;
                }
            }
            if (!hasMPEG21MCOFormat) {
                formatList.add("MPEG-21 MCO (ISO/IEC 21000-21)");
                aip.setDCField(DCField.format, formatList);
            }

            // create graph
            XSLTProc xsltproc = new XSLTProc();
            String digraphxsl = xsltproc.addResourceFile("writedigraph.xsl");
            xsltproc.setXSLFile(digraphxsl);
            xsltproc.addStringParam("colors", "on");

            xsltproc.extract(rightsFile.getAbsolutePath());
            String dotGraphFilePath = xsltproc.getOutputFile();

            String owlGraphName = rightsID + ".png";
            File owlGraph = new File(dParamsString.get("graphFolder"), owlGraphName);

            new Dot().createGraph(dotGraphFilePath, owlGraph.getAbsolutePath());

            // index rights
            RightsUtils.indexRights(id, rightsFile);
            rightsFile.delete();

            // release AIP
            P4DataManager.getInstance().releaseIP(aip);

            logger.debug("Updated QA section...");
        } catch (Exception e) {
            throw new TaskExecutionFailedException("Unable to update AIP...\n" + e.getMessage());
        }
    }

    @WfService(name = "query_rights_by_owl", version = "1.2.0")
    public void queryRights(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamsFile) throws TaskExecutionFailedException {

        // get dynamic parameters
        File rightsFile = dParamsFile.get("rightsFile");

        try {
            Results queryResults = new Results();
            long searchTime = Long.MAX_VALUE, totalTime = Long.MAX_VALUE;

            long time1 = System.currentTimeMillis();

            List<String> rightsResult = queryRights(rightsFile.getAbsolutePath());

            long time2 = System.currentTimeMillis();

            searchTime = time2 - time1;

            if (rightsResult == null) {
                queryResults.setFailure("Error retrieving information");

            } else {

                logger.debug("Number of RightsModel objects: " + rightsResult.size());

                queryResults.setSuccess(true);

                for (String aipId : rightsResult) {

                    logger.debug("Retrieving rigths info for AIP " + aipId);
                    Row row = new Row();
                    row.setEeIdentifier(aipId);

                    DIP dip = P4DataManager.getInstance().getDIPByID(aipId);

                    StringBuffer sb = new StringBuffer();

                    for (String title : dip.getDCField(DCField.title)) {
                        sb.append(title + " ");
                    }
                    sb.append("###");
                    for (String description : dip.getDCField(DCField.description)) {
                        sb.append(description + " ");
                    }
                    row.setContent(sb.toString());

                    String downloadIcon = null;
                    if (dip.getThumbnail() != null)
                        downloadIcon = dip.getThumbnail().toString();
                    logger.debug("Icon URL for download: " + downloadIcon);

                    row.setIcon(downloadIcon);

                    String graphHRef = dip.getGraph().toString();

                    logger.debug("Graph URL for download: " + graphHRef);

                    row.setRightsgraph(graphHRef);

                    queryResults.getRow().add(row);
                    logger.debug("Added query results for AIP: " + aipId);

                }

                StringWriter sw = new StringWriter();
                RightsUtils.getRightsContext().createMarshaller().marshal(queryResults, sw);
                dParamsString.put("result", sw.toString());

                long time3 = System.currentTimeMillis();

                totalTime = time3 - time1;
            }

            logger.debug("Search time: " + searchTime + " ms");
            logger.debug("Total time: " + totalTime + " ms");

        } catch (Exception e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to execute rights query");
        }
    }

    /**
     * Execution: xsltproc --stringparam ppavro /tmp/ppavro.owl --stringparam
     * countrycodes /tmp/ebu_Iso3166CountryCodeCS.xml --stringparam
     * languagecodes /tmp/ebu_Iso639_1LanguageCodeCS.xml --stringparam querydoc
     * /tmp/query.owl /tmp/RightsCompareFromIndex.xsl /tmp/RightsIndex.xml
     * 
     * @throws DataException
     * @throws ToolException
     * @throws IOException
     * @throws JAXBException
     */

    private List<String> queryRights(String owlQueryFilePath)
            throws DataException, ToolException, IOException, JAXBException {

        // List<RightsModel> resultRights = new ArrayList<RightsModel>();
        List<String> resultRights = new ArrayList<String>();

        XSLTProc xsltproc = new XSLTProc();

        logger.debug("Initialized XSLTProc...");

        // step 1: clean up OWL file
        String byPassXsl = xsltproc.addResourceFile("ByPassIntrsctns.xsl");
        xsltproc.setXSLFile(byPassXsl);
        xsltproc.extract(owlQueryFilePath);
        String step1Result = xsltproc.getOutputFile();

        // step2: extract RightsInstance

        // stylesheet
        String rightsxsl = xsltproc.addResourceFile("RightsCompareFromIndex.xsl");
        xsltproc.setXSLFile(rightsxsl);
        // add stringparams
        String ppavro = xsltproc.addResourceFile("ppavro.owl");
        xsltproc.addStringParam("ppavro", ppavro);
        String countrycodes = xsltproc.addResourceFile("ebu_Iso3166CountryCodeCS.xml");
        xsltproc.addStringParam("countrycodes", countrycodes);
        String languagecodes = xsltproc.addResourceFile("ebu_Iso639_LanguageCodeCS.xml");
        xsltproc.addStringParam("languagecodes", languagecodes);
        xsltproc.addStringParam("querydoc", step1Result);

        // index file
        RightsIndex rightsIndex = RightsUtils.getRightsIndex();

        if (rightsIndex == null)
            return null;

        File indexTempFile = File.createTempFile("RightsIndex-", ".xml");
        indexTempFile.deleteOnExit();

        RightsUtils.getRightsContext().createMarshaller().marshal(rightsIndex, indexTempFile);

        String indexFile = indexTempFile.getAbsolutePath();

        logger.debug("Looping on Rights Index...");

        xsltproc.extract(indexFile);
        String resultFilePath = xsltproc.getOutputFile();

        logger.debug("Scanning file: " + resultFilePath);

        FileInputStream resultInputStream = new FileInputStream(resultFilePath);

        Scanner scanner = new Scanner(resultInputStream);

        while (scanner.hasNextLine()) {
            String line = (String) scanner.nextLine();
            if (line.startsWith("true")) {
                logger.debug("--------------------------------------------------------");
                logger.debug("Found matching EE with identifier: " + line.split(",")[1]);
                String dcIdentifier = line.split(",")[1].trim();
                String dcIdentifierNoFrags = dcIdentifier.split("#")[0]; // remove
                // media
                // fragments
                logger.debug("DC identifier: " + dcIdentifierNoFrags);

                Map<String, String> elements = new HashMap<String, String>();
                elements.put("identifier", dcIdentifierNoFrags);
                String aipId = P4DataManager.getInstance().getAIPByDCID(dcIdentifierNoFrags);

                /*
                 * logger.debug("Retrieving RightsModel for AIP "+aipId);
                 * 
                 * List<RightsModel> rightsModelList =
                 * manager.findRightsByAIPId(aipId);
                 * 
                 * if(rightsModelList.size()>1){
                 * logger.error("RightsModel is not unique!!! Skipping...");
                 * continue; }
                 * 
                 * resultRights.add(rightsModelList.get(0));
                 */
                resultRights.add(aipId);
                logger.debug("Added AIP to RightsResult list: " + aipId);
                logger.debug("--------------------------------------------------------");

            }
        }

        logger.debug("XSLTProc elapsed time: " + xsltproc.getExecTime());

        return resultRights;

    }

    @WfService(name = "rebuild_rights_index", version = "2.2.0")
    public void rebuildIndex(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamFile) throws TaskExecutionFailedException {

        try {

            RightsUtils.deleteRightsIndex();

            logger.debug("Successfully cleared search index...");

            List<String> aipIdList;

            aipIdList = P4DataManager.getInstance().getAllAIP(null);

            if (aipIdList.isEmpty()) {
                logger.debug("No AIPs found.");
            }

            int indexedAIP = 0;

            for (String aipId : aipIdList) {

                logger.debug("Indexing AIP " + aipId);

                DIP dip = P4DataManager.getInstance().getDIPByID(aipId);

                if (Boolean.valueOf(dip.hasDatatype("rights"))) {

                    List<Node> rightsNodeList = dip.getMDResourceAsDOM("rights");

                    if (rightsNodeList == null || rightsNodeList.size() == 0)
                        continue;

                    Node rights = rightsNodeList.get(0);

                    // create rightsFile
                    File owlFile = File.createTempFile("rights-", ".owl");
                    TransformerFactory.newInstance().newTransformer().transform(new DOMSource(rights),
                            new StreamResult(owlFile));

                    // index rights
                    RightsUtils.indexRights(aipId, owlFile);
                    owlFile.delete();

                    logger.debug("Successfully indexed rights for AIP: " + aipId);

                    indexedAIP++;
                }

            }

            logger.debug("Rights Indexing completed. Number of indexed AIPs: " + indexedAIP + " out of "
                    + aipIdList.size());

        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to access data from DB");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to get rights from DIP");
        } catch (DatabaseException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to store Rights Index to DB");
        } catch (Exception e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to rebuild rights index");
        }
    }

    @WfService(name = "avmaterial_update", version = "2.2.0")
    public void addAVToRigthsOnly(Map<String, String> sParams, Map<String, String> dParamsString,
            Map<String, File> dParamFile) throws TaskExecutionFailedException {

        // dynamic parameters
        String aipID = dParamsString.get("aipID");
        String mimeType = dParamsString.get("mimetype");
        String filePath = dParamsString.get("filePath");
        String fileMD5 = dParamsString.get("fileMD5");
        long fileSize = 0;

        DIP dip = null;
        try {
            dip = P4DataManager.getInstance().getDIPByID(aipID);

            // if is rights_only
            if (dip.hasRights() && !dip.hasAVMaterial()) {
                // check file
                File file = new File(filePath);
                if (file.isFile()) {
                    fileSize = file.length();

                    MessageDigestExtractor mde = new MessageDigestExtractor();
                    ToolOutput<MessageDigestExtractor.AttributeType> output = mde.extract(filePath);
                    if (fileMD5 != null
                            && output.getAttribute(MessageDigestExtractor.AttributeType.MD5) != fileMD5) {
                        throw new TaskExecutionFailedException("MD5 doesn't corresponds...");
                    }
                    fileMD5 = output.getAttribute(MessageDigestExtractor.AttributeType.MD5);
                } else {
                    throw new TaskExecutionFailedException("Invalid file...");
                }
            } else {
                throw new TaskExecutionFailedException(
                        "Trying to update a non rights_only AIP with aipID " + aipID + "...");
            }
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Could not retrieve AIP " + aipID + "...");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Could not determine if AIP has rights nor AVMaterial...");
        } catch (ToolException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to extract MD5 from file " + filePath + "...");
        } finally {
            dip = null;
        }

        try {
            P4DataManager.getInstance().invalidateAIP(aipID);
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to invalidate AIP with aipID " + aipID + "...");
        }

        String sipID = aipID;
        dParamsString.remove("aipID");
        dParamsString.put("sipID", sipID);

        SIP sip = null;
        try {
            sip = P4DataManager.getInstance().getSIPByID(sipID);

            sip.addExternalFile(mimeType, filePath, fileMD5, fileSize);
        } catch (DataException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException("Unable to delete rights_only AIP with aipID " + aipID + "...");
        } catch (IPException e) {
            e.printStackTrace();
            throw new TaskExecutionFailedException(
                    "Unable to add new file to invalidated SIP " + sipID + "(ex AIP)...");
        } finally {
            P4DataManager.getInstance().releaseIP(sip);
        }
    }
}