Package eu.planets_project.pp.plato.action.workflow

Source Code of eu.planets_project.pp.plato.action.workflow.DefineSampleRecordsAction

/*******************************************************************************
* Copyright (c) 2006-2010 Vienna University of Technology,
* Department of Software Technology and Interactive Systems
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/

package eu.planets_project.pp.plato.action.workflow;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.application.FacesMessage;

import org.apache.commons.logging.Log;
import org.jboss.annotation.ejb.cache.Cache;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.RaiseEvent;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.faces.FacesMessages;

import eu.planets_project.pp.plato.action.interfaces.IDefineSampleRecords;
import eu.planets_project.pp.plato.action.interfaces.IIdentifyRequirements;
import eu.planets_project.pp.plato.action.interfaces.IWorkflowStep;
import eu.planets_project.pp.plato.bean.PrepareChangesForPersist;
import eu.planets_project.pp.plato.bean.UploadBean;
import eu.planets_project.pp.plato.model.Alternative;
import eu.planets_project.pp.plato.model.ByteStream;
import eu.planets_project.pp.plato.model.DigitalObject;
import eu.planets_project.pp.plato.model.PlanState;
import eu.planets_project.pp.plato.model.SampleObject;
import eu.planets_project.pp.plato.model.User;
import eu.planets_project.pp.plato.model.Values;
import eu.planets_project.pp.plato.model.XcdlDescription;
import eu.planets_project.pp.plato.model.tree.Leaf;
import eu.planets_project.pp.plato.model.tree.ObjectiveTree;
import eu.planets_project.pp.plato.services.PlatoServiceException;
import eu.planets_project.pp.plato.services.characterisation.DROIDIntegration;
import eu.planets_project.pp.plato.services.characterisation.FormatHit;
import eu.planets_project.pp.plato.services.characterisation.FormatIdentification;
import eu.planets_project.pp.plato.services.characterisation.FormatIdentification.FormatIdentificationResult;
import eu.planets_project.pp.plato.services.characterisation.fits.FitsIntegration;
import eu.planets_project.pp.plato.services.characterisation.jhove.JHoveAdaptor;
import eu.planets_project.pp.plato.services.characterisation.jhove.tree.JHoveTree;
import eu.planets_project.pp.plato.services.characterisation.xcl.XcdlExtractor;
import eu.planets_project.pp.plato.util.Downloader;
import eu.planets_project.pp.plato.util.FileUtils;
import eu.planets_project.pp.plato.util.OS;
import eu.planets_project.pp.plato.util.PlatoLogger;
import eu.planets_project.pp.plato.xml.plato.StringCapsule;

/**
* Implements actions for workflow step 'Define Sample Records'
*
* We use DROID to identify the record the user has uploaded. ({@link DROIDIntegration} is
* doing the job. {@link FormatIdentification} is the information we receive from DROID. 
*
* @author Hannes Kulovits
*/
@Stateful
@Scope(ScopeType.SESSION)
@Name("defineSampleRecords")
@Cache(org.jboss.ejb3.cache.NoPassivationCache.class)
public class DefineSampleRecordsAction extends AbstractWorkflowStep
implements   IDefineSampleRecords {
  
    /**
     *
     */
    private static final long serialVersionUID = -6430869564062683806L;

    @Override
    protected void doClearEm() {
        super.doClearEm();
        records = selectedPlan.getSampleRecordsDefinition().getRecords();
       
        OS.deleteDirectory(tempDir);
        tempDigitalObjects.clear();       
    }
   
    protected boolean needsClearEm() {
        return true;
    }
    private static final Log log = PlatoLogger.getLogger(DefineSampleRecordsAction.class);

    /**
     * This is our successor step. Needed for {@link #getSuccessor()}
     */
    @In(create = true)
    IIdentifyRequirements identifyRequirements;

    /**
     * SampleObject to be uploaded and added to the list of sample objects.
     */
    @Out(required=false)
    private DigitalObject sampleRecordToUpload = new DigitalObject();

    /**
     * Logged in user.
     */
    @In (required=false)
    private User user;

    @Out
    private UploadBean uploadBean = new UploadBean();
   
    /**
     * Used to remove unused records when saving. We need this list because we aske the user
     * if he/she really wants to remove the record.
     */
    private List<SampleObject> recordsToRemove = new ArrayList<SampleObject>();

    /**
     * Still needed, despite it is loaded elsewhere, because seam needs that.
     * To suppress warning (... is never read locally) we annotate
     */
    @SuppressWarnings("unused")
    @DataModel
    private List<SampleObject> records;

    /**
     * DataModelSelection for {@link #records}
     */
    @DataModelSelection
    private SampleObject record;


    @Out(required = false)
    private JHoveTree jhoveTree;
   
    private JHoveAdaptor jHoveAdaptor;
    private FitsIntegration fits;
   
    /**
     * this determines the behaviour of the remove-buttons on the pag (see
     * there) - to remove sample records from the list
     */
    @Out
    private int allowRemove = -1;

    @Out(required = false)
    private String[] possibleFormatsString;

    @Out(required = false)
    private SampleObject identifiedRecord;

    @Out(required = false)
    private Map<String, FormatHit> possibleFormats = new HashMap<String, FormatHit>();

    @Out(required = false)
    private StringCapsule selectedFormat = new StringCapsule();

    @Out(required = false)
    private String formatMessage = null;

    public DefineSampleRecordsAction() {
        requiredPlanState = new Integer(PlanState.BASIS_DEFINED);
    }

    /**
     * @see AbstractWorkflowStep#getSuccessor()
     */
    protected IWorkflowStep getSuccessor() {
        return identifyRequirements;
    }

    /**
     * Ensures that at least one record is defined befor continuing.
     *
     * @see AbstractWorkflowStep#validate(boolean)
     */
    public boolean validate(boolean showValidationErrors) {
        if (selectedPlan.getSampleRecordsDefinition().getRecords().size() == 0) {
            if (showValidationErrors) {
                FacesMessages
                        .instance()
                        .add(FacesMessage.SEVERITY_ERROR,
                                "At least one record must be added to proceed with the workflow.");
            }
            return false;
        }
      
        List<String> names = new ArrayList<String>();
        for (SampleObject record: selectedPlan.getSampleRecordsDefinition().getRecords()) {
            if (names.contains(record.getShortName())) {
                if (showValidationErrors) {
                    FacesMessages
                            .instance()
                            .add(FacesMessage.SEVERITY_ERROR,
                                    "There are two records with the same short name '"+record.getShortName()+"'. Please provide unique names.");
                }
                return false;
            }
            names.add(record.getShortName());
        }
        return true;
    }

    /**
     * saves the sample records and then calls super.save to save the rest. each
     * record with an id equal to zero has not been persited before.
     *
     * @see AbstractWorkflowStep#save()
     */
    @Override
    public String save() {
        /*
         * We need to persist the AlternativesDefinition here first, because
         * every SampleObject is used as a key for the Uploads Hashmap in the
         * Experiment of every Alternative. Therefore if one SampleObject is removed,
         * but still used as a key for the HashMap Hibernate will throw error,
         * because of foreign Key Relationship.
         *
         * So when SampleObject is removed from the System we remove it from the
         * Hashmap too, then Save all Alternatives with the Experiments and DigitalObject
         * Hashmaps -> the Sample Recordarg0 to remove is referenced nowhere in the project
         * and the SampleRecordDefinition can be saved....?
         * Or wait! One thing before that... all the Values objects have changed in #removeRecord()
         * and we have to persist these as well before deleting the sampleobject.
         * THEN the SampleRecordDefinition can be saved.
         */
        /** dont forget to prepare changed entities e.g. set current user */
        PrepareChangesForPersist prep = new PrepareChangesForPersist(user.getUsername());

        em.persist(em.merge(selectedPlan.getAlternativesDefinition()));
        for (SampleObject record : selectedPlan.getSampleRecordsDefinition()
                .getRecords()) {
           
            prep.prepare(record);
           
            if (record.getId() == 0) { // the record has not yet been persisted                               
                String filename = tempDigitalObjects.get((DigitalObject)record);
               
                try {
                    if (filename != null && filename != "") {
                        File file = new File(filename);
                        byte[] data = FileUtils.getBytesFromFile(file);
                        record.getData().setData(data);
                    }
                } catch(IOException e) {
                    log.error(e);
                }

                em.persist(record);
            } else {
                if (!recordsToRemove.contains(record)) {
                    em.persist(em.merge(record));
                }
            }
        }

        // remove temporary files from hard disk
        for (String filename : tempDigitalObjects.values()) {
            File file = new File(filename);
            file.delete();          
        }
        tempDigitalObjects.clear();
       
        // If we removed samples, persist all the Values objects of all leaves in the tree
        // - that leads to the orphan VALUE objects to be deleted from the database.
        if (recordsToRemove.size() > 0) {
            for (Leaf l: selectedPlan.getTree().getRoot().getAllLeaves()) {
                for (Alternative a: selectedPlan.getAlternativesDefinition().getConsideredAlternatives()) {
                    Values v = l.getValues(a.getName());
                    if (v != null) {
                        em.persist(em.merge(v));
                    } else {
                        log.error("values is NULL: "+l.getName()+", "+a.getName());
                    }
                }
            }
            em.flush();
        }
       
        super.save(selectedPlan.getSampleRecordsDefinition());
       
        /* these are removed by the parent entity because of DELETE_ORPHANS!
        for (SampleObject record : recordsToRemove) {
            if (record.getId() != 0) {
                // this record is already persisted - remove it
                em.remove(em.merge(record));
            }
        }
        */
        recordsToRemove.clear();
        changed = "";
       
        return null;
    }

    /**
     * Adds a new record to the list of sample records in the project. This is a sample record
     * without data.
     */
    public String newRecord() {
        SampleObject newRecord = new SampleObject();

        selectedPlan.getSampleRecordsDefinition().addRecord(newRecord);
        // this SampleRecordsDefinition has been changed
        selectedPlan.getSampleRecordsDefinition().touch();

        return null;
    }

    /**
     * Removes a record from the list of samplerecords in the project AND also
     * removes all associated:
     * <ul>
     *    <li>evaluation values contained in the tree</li>
     *    <li>experiment results and their xcdl-files</li>
     * </ul>
     * - if there are any.
     */
    public String removeRecord() {
        log.info("Removing SampleObject from Plan: " + record.getFullname());
        recordsToRemove.add(record);
        selectedPlan.removeSampleObject(record);
       
        if (record == identifiedRecord) {
            identifiedRecord = null;
            possibleFormats.clear();
            possibleFormatsString = null;
        }

        allowRemove = -1;
        return null;
    }
   
    private int addAllRecords(File file) {
        log.debug("adding record for file "+file.toString());
        if (file.isFile()) {
            try {
                sampleRecordToUpload.getData().setData(FileUtils.getBytesFromFile(file));
                sampleRecordToUpload.setFullname(file.getName());
                upload();
            } catch (IOException e) {
                log.error(e);
                FacesMessages.instance().add(FacesMessage.SEVERITY_WARN,
                   "Could not read: "+file.getName()+": "+e.getMessage());
            }
            return 1;
        } else {
            int number = 0;
            for (File f: file.listFiles()) {
                number += addAllRecords(f.getAbsoluteFile());
            }
            return number;
        }
    }

    public String addAllRecords() {
        if (uploadBean.getPath() == null || "".equals(uploadBean.getPath())) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_INFO,
                "You have to provide a directory pointing to a local path up here at the server before adding these files.");
            return null;
        }
        File directory = new File(uploadBean.getPath());
        if (!directory.isDirectory()) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_INFO,
            "You have to provide a directory pointing to a local path up here at the server before adding these files.");
            return null;
        }
        int number = addAllRecords(directory.getAbsoluteFile());
        FacesMessages.instance().add(FacesMessage.SEVERITY_INFO,
            "Added "+number+" records to your project.");
        return null;
    }
   
    private Map<DigitalObject, String> tempDigitalObjects = new HashMap<DigitalObject, String>();
   
    private File tempDir = null;
   
    /**
     * Uploads a file into a newly created sample record and adds this sample
     * record to the list in the project.
     *
     * @return always returns null
     */
    public String upload() {
        if (!sampleRecordToUpload.isDataExistent()) {

            log.debug("No file for upload selected.");
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR,
                    "You have to select a file before starting upload.");

            return null;
        }

        changed = "true";
        SampleObject record = new SampleObject();
        String fullName = new File(sampleRecordToUpload.getFullname()).getName();
        record.setFullname(fullName);
        record.setShortName(record.getFullname().substring(0,Math.min(20,record.getFullname().length())));
        record.setContentType(sampleRecordToUpload.getContentType());
        selectedPlan.getSampleRecordsDefinition().addRecord(record);
       
        writeTempFile(sampleRecordToUpload, record);

        // identify format of newly uploaded records
        if (shouldCharacterise(record)) {
            identifyFormat(record);
//              describeInXcdl(record);
              characteriseFits(record);
        }
       
        // need to initialize jhove tree by upload of a new sample record
        if (record.getJhoveXMLString() == null || "".equals(record.getJhoveXMLString())) {
           record.setJhoveXMLString(jHoveAdaptor.describe(tempDigitalObjects.get(record)));
        }
       
        log.debug("Content-Type: " + sampleRecordToUpload.getContentType());
        log.debug("Size of Records Array: "
                + selectedPlan.getSampleRecordsDefinition().getRecords()
                        .size());
        log.debug("FileName: " + sampleRecordToUpload.getFullname());
        log.debug("Length of File: " + sampleRecordToUpload.getData().getSize());
        log.debug("added SampleObject: " + record.getFullname());
        log.debug("JHove initialized: " + (record.getJhoveXMLString() != null));
       
        sampleRecordToUpload.setData(new ByteStream());
       
        System.gc();
       
        return null;
    }
   
    /**
     * For some objects (such as raw camera files), calling characterisation tools is useless and
     * needs resources. This function tells us if we should attempt characterisation.
     * @param record SampleObject to be checked
     * @return true if object should be characterised, false if it's better not to do that
     */
    private boolean shouldCharacterise(SampleObject record) {
        String fullName = record.getFullname();
        if (fullName.toUpperCase().endsWith(".CR2") ||
            fullName.toUpperCase().endsWith(".NEF") ||
            fullName.toUpperCase().endsWith(".CRW")) {
            return false;
        }
        return true;
    }

    /**
     *
     * @param dataObject is currently holding the byte stream
     * @param sampleObject the things that is going to be stored in the database
     * @return
     */
    private void writeTempFile(DigitalObject dataObject, SampleObject sampleObject) {

        String filename = dataObject.getFullname();
        String fileExtension = "";
        int bodyEnd = filename.lastIndexOf(".");
        if (bodyEnd >= 0) {
            fileExtension = filename.substring(bodyEnd);
        }
       
        String tempFileName = tempDir.getAbsolutePath()+System.nanoTime() + fileExtension;
       
        OutputStream fileStream;
        try {
            fileStream = new  BufferedOutputStream (new FileOutputStream(tempFileName));
            byte[] data = dataObject.getData().getData();
            fileStream.write(data);
            fileStream.close();
           
            // put the temp file in the map
            tempDigitalObjects.put(sampleObject, tempFileName);
            sampleObject.getData().setSize(data.length);
           
        } catch (FileNotFoundException e) {
            log.error(e);
        } catch (IOException e) {
            log.error(e);
        }
    }

    /**
     * @see AbstractWorkflowStep#discard()
     */
    @Override
    @RaiseEvent("reload")
    public String discard() {
        String result = super.discard();
        recordsToRemove.clear();

        // delete all temporary files from hard disk
        for (DigitalObject o: tempDigitalObjects.keySet()) {
            File file = new File(tempDigitalObjects.get(o));
            file.delete();
        }
        tempDigitalObjects.clear();       
       
        // prepare the records
        init();
        return result;
    }

    /**
     * @see AbstractWorkflowStep#init()
     */
    @Override
    public void init() {
        if (tempDir != null) {
            OS.deleteDirectory(tempDir);
        }
        tempDir = new File(OS.getTmpPath() + "sampleobjects" + System.nanoTime()+File.separator);
        tempDir.mkdir();
        tempDir.deleteOnExit();
        tempDigitalObjects.clear();
       
        allowRemove = -1;
        jhoveTree = new JHoveTree();
        jHoveAdaptor=new JHoveAdaptor();
       
        try {
            fits = new FitsIntegration();
        } catch (Throwable e) {
            fits = null;
            log.error("Could not instantiate FITS, it is not configured properly.", e);
            FacesMessages.instance().add(FacesMessage.SEVERITY_WARN, "Could not instantiate FITS, it is not configured properly.");
        }
    
        records = selectedPlan.getSampleRecordsDefinition().getRecords();
        boolean updated = false;
        for (SampleObject record : records) {
            if (record.getJhoveXMLString() == null || "".equals(record.getJhoveXMLString())) {
                record.setJhoveXMLString(new JHoveAdaptor().describe(em.merge(record)));
                updated = true;
            }
        }
        if (updated) {
            em.persist(em.merge(selectedPlan.getSampleRecordsDefinition()));
        }
       
        identifiedRecord = null;
        possibleFormats.clear();
        possibleFormatsString = null;
    }

    /**
     * checks if the record contains evaluation values. If yes, the user should
     * be asked for confirmation before removing it. If not, the record is
     * removed. *
     *
     * @see ObjectiveTree#hasValues(int[],Alternative)
     *
     * @return always returns null
     */
    public String askRemoveRecord() {
        if (record == null
                || selectedPlan.getSampleRecordsDefinition().getRecords()
                        .size() == 0) {
            allowRemove = -1;
            return null;
        }

        int rec[] = { selectedPlan.getSampleRecordsDefinition().getRecords()
                .indexOf(record) };
       
        // we need to construct the list of all altenative names because the tree doesnt know it
        Set<String> alternatives = new HashSet<String>();
        for (Alternative a: selectedPlan.getAlternativesDefinition().getConsideredAlternatives()) {
            alternatives.add(a.getName());
        }
       
        if (selectedPlan.getTree().hasValues(rec, alternatives)) {
            allowRemove = record.getId();
        } else {
            removeRecord();
        }
        return null;
    }

    public int getAllowRemove() {
        return allowRemove;
    }

    /**
     * @see AbstractWorkflowStep#destroy()
     */
    @Destroy
    @Remove
    public void destroy() {
    }

    /**
     * @see AbstractWorkflowStep#getWorkflowstepName()
     */
    protected String getWorkflowstepName() {
        return "defineSampleRecords";
    }

    /**
     * Downloads currently selected sample record. Uses {@link eu.planets_project.pp.plato.util.Downloader}
     * to perform the download.
     */
    public void download(Object object) {
        if (object instanceof DigitalObject) {
            DigitalObject dObject = (DigitalObject) object;
            if (tempDigitalObjects.containsKey(dObject)) {
                Downloader.instance().download(dObject,tempDigitalObjects.get(object));
            } else {
                DigitalObject merged = em.merge(dObject);
                Downloader.instance().download(merged);
            }
        }
    }

    /**
     * Sets the format of SampleObject {@link #identifiedRecord} to the currently selected format
     * of all {@link #possibleFormats}.
     */
    public void changeFormat(){
        if ((selectedFormat.getValue() != null) && (identifiedRecord != null)) {
            FormatHit hit = possibleFormats.get(selectedFormat.getValue());
            if (hit != null) {
                identifiedRecord.getFormatInfo().assignValues(hit.getFormat());
                identifiedRecord.touch();
//                FacesContext context = FacesContext.getCurrentInstance();
//                context.renderResponse();
                log.warn("format changed to: "+selectedFormat.getValue());
            }
        }
       
      }

    /**
     * Selects The last selected format already set by {@link #changeFormat(Object)}.
     */
    public void selectFormat(){
        identifiedRecord = null;
        possibleFormatsString = null;
        formatMessage = null;
    }

    /**
     * Identifies the format of the uploaded sample record <param>object</param> with the help of DROID.
     * <ul>
     *    <li>If there is an exact match, the new format is set.</li>
     *    <li>If there there are only tentative hits, the list {@link #possibleFormats} is populated and the user has to choose.</li>
     *    <li>If format identification fails {@link #formatMessage} is set.</li>
     * </ul>
     *
     * @param object SampleObject to be identified. Must be of type SampleObject at the moment.
     *
     */
    public void identifyFormat(Object object) {
       
        formatMessage = null;
       
        if (! (object instanceof SampleObject))
            return;
        try {
           
            SampleObject rec = (SampleObject)object;
            identifiedRecord = rec;           
            possibleFormats.clear();
            possibleFormatsString = null;
           
            /**
             * DROID is used for file identification.
             */
            FormatIdentification ident = null;
           
            String filename = tempDigitalObjects.get(rec);
           
            if (filename == null || "".equals(filename)) {
                SampleObject rec2 = em.merge(rec);
                ident = DROIDIntegration.getInstance().identifyFormat(rec2.getData().getData(), rec2.getFullname());   
            } else {
                ident = DROIDIntegration.getInstance().identify(filename);
            }
           
            if (ident.getResult() == FormatIdentificationResult.ERROR) {
                /*
                 * DROID could not identify this file.
                 */
                log.error(ident.getInfo());
                formatMessage = "DROID could not identify the format of the file." + ident.getInfo();
            } else if (ident.getResult() == FormatIdentificationResult.NOHIT) {
                /*
                 * DROID could not identify this file.
                 */
                log.info(ident.getInfo());
                formatMessage = "DROID could not identify the format of the file." + ident.getInfo();
            } else if ((ident.getResult() == FormatIdentificationResult.POSITIVE) &&
                    (ident.getFormatHits().size() == 1)){
                /*
                 *  exact match, format identification successful
                 */
                rec.getFormatInfo().assignValues(ident.getFormatHits().get(0).getFormat());
                rec.touch();
                formatMessage = ident.getInfo();
            } else {
                /*
                 * Here, we either have more than one POSITIVE hit or any number of TENTATIVE hits.
                 * DROID provides only some guesses as it cannot identify it, the user has to decide.
                 */
                formatMessage = "Droid identified several potential formats of this file. " + ident.getInfo() + " Please choose the most adequate one:";

                for (FormatHit hit : ident.getFormatHits()){
                    String key = hit.getFormat().getName();
                    if (hit.getFormat().getVersion() != null)
                        key = key + ' ' + hit.getFormat().getVersion();

                    possibleFormats.put(key, hit);
                }
               
                possibleFormatsString = possibleFormats.keySet().toArray(new String[]{});
                // set format info to first entry in the list - as the drop down box suggests
                selectedFormat.setValue(possibleFormatsString[0]);
                rec.getFormatInfo().assignValues(possibleFormats.get(selectedFormat.getValue()).getFormat());
                rec.touch();

                FacesMessages.instance().add(FacesMessage.SEVERITY_INFO, ident.getInfo());
            }
        } catch (Exception e) {
            /*
             * An error occured, maybe it would help to try it again.
             */
            log.error("Failed to identify fileformat." + e);
            formatMessage = "Could not identify the format of the file.";

        }
    }

    public DigitalObject getSampleRecordToUpload() {
        return sampleRecordToUpload;
    }

    public void setSampleRecordToUpload(DigitalObject sampleRecord) {
        this.sampleRecordToUpload = sampleRecord;
    }
   
    public String characteriseXcdl(Object object) {
        if (object instanceof DigitalObject) {
           
            describeInXcdl((DigitalObject)object);
        }
       
        return "";
    }

    private boolean describeInXcdl(DigitalObject record) {
        XcdlExtractor extractor = new XcdlExtractor();
        XcdlDescription xcdl = null;
        if (record != null && record.isDataExistent()) {
            try {
                String filepath =  tempDigitalObjects.get(record);
                if ((filepath != null) && (!"".equals(filepath))) {
                    xcdl = extractor.extractProperties(record.getFullname(), filepath);
                } else {
                    DigitalObject rec2 = em.merge(record);
                    xcdl = extractor.extractProperties(rec2);
                }
               
                //xcdl = extractor.extractProperties(record.getFullname(), record);
            } catch (PlatoServiceException e) {
                log.error("XCDL characterisation failed: "+e.getMessage(),e);
                return false;
            }
        }
        if (xcdl != null) {
            // extraction succeeded
            record.setXcdlDescription(xcdl);
            return true;
        } else {
            // property extraction failed, remove old xcdl info
            record.setXcdlDescription(null);
            return false;
        }
    }
   
    /**
     * Extracts object properties of all sample records.
     */
    public void extractObjectProperties(){
        List<SampleObject> records = selectedPlan.getSampleRecordsDefinition().getRecords();
        ArrayList<String> failed = new ArrayList<String>();
       
        for (SampleObject record : records) {
            if (!describeInXcdl(record)) {
                failed.add(record.getFullname() + ": The description service returned an invalid result.")
            }
        }
        if (failed.size() == 0) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_INFO, "Successfully described all sample records.");
        } else {
            StringBuffer msg = new StringBuffer();
            msg.append("Description failed for following sample records:<br/><br/>");
            msg.append("<ul>");
            for (String f : failed) {
                msg.append("<li>").append(f).append("</li>");
            }
            msg.append("</ul>");
           
            FacesMessages.instance().add(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Some sample records could not be decribed successfully.", msg.toString()));
        }
       
    }
    /**
     * Creates from the SampleObject object, retrieved by injection, a Tree with
     * all the characteristics extracted from JhoveXMLString present in the record
     *
     */
    public String characteriseJHoveTree(Object object) {
        if(object instanceof SampleObject){
            SampleObject tmpRec = (SampleObject)object;
            if (tmpRec != null) {
                jhoveTree=jHoveAdaptor.digestString(tmpRec.getFullname(), tmpRec.getJhoveXMLString());
            }
        }
      
        return null;
    }

    public String characteriseFits(Object object) {
        if (fits == null) {
            log.debug("FITS is not available and needs to be reconfigured.");
            return null;
        }
        if(object instanceof SampleObject){
            SampleObject sample = (SampleObject)object;
            if (sample != null && sample.isDataExistent()) {
                try {
                    String fitsXML = null;
                    String filepath =  tempDigitalObjects.get(sample);
                    if ((filepath != null) && (!"".equals(filepath))) {
                        fitsXML = fits.characterise(new File(filepath));
                    } else {
                        SampleObject mergedObj = em.merge(sample);
                        writeTempFile(mergedObj, sample);
                        filepath =  tempDigitalObjects.get(sample);
                        fitsXML = fits.characterise(new File(filepath));
                    }
                    sample.setFitsXMLString(fitsXML);
                    identifiedRecord = sample;
                } catch (PlatoServiceException e) {
                    log.error("characterisation with FITS failed.",e);
                    return null;
                }
            }
        }
      
        return null;
    }
}
TOP

Related Classes of eu.planets_project.pp.plato.action.workflow.DefineSampleRecordsAction

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.