eu.planets_project.tb.gui.backing.data.DigitalObjectCompare.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.tb.gui.backing.data.DigitalObjectCompare.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2010 The Planets Project Partners.
 *
 * 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.tb.gui.backing.data;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.model.SelectItem;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.planets_project.ifr.core.storage.api.DataRegistry;
import eu.planets_project.ifr.core.storage.api.DataRegistryFactory;
import eu.planets_project.services.characterise.Characterise;
import eu.planets_project.services.characterise.CharacteriseResult;
import eu.planets_project.services.compare.Compare;
import eu.planets_project.services.compare.CompareResult;
import eu.planets_project.services.compare.PropertyComparison;
import eu.planets_project.services.compare.PropertyComparison.Equivalence;
import eu.planets_project.services.datatypes.Property;
import eu.planets_project.services.datatypes.ServiceDescription;
import eu.planets_project.services.datatypes.ServiceReport;
import eu.planets_project.services.identify.Identify;
import eu.planets_project.services.identify.IdentifyResult;
import eu.planets_project.tb.api.properties.ManuallyMeasuredProperty;
import eu.planets_project.tb.gui.UserBean;
import eu.planets_project.tb.gui.backing.ExperimentBean;
import eu.planets_project.tb.gui.backing.ServiceBrowser;
import eu.planets_project.tb.gui.backing.exp.ExperimentInspector;
import eu.planets_project.tb.gui.backing.exp.MeasuredComparisonEventBean;
import eu.planets_project.tb.gui.backing.exp.ResultsForDigitalObjectBean;
import eu.planets_project.tb.gui.backing.exp.utils.ManualMeasurementBackingBean;
import eu.planets_project.tb.gui.backing.exp.view.MeasuredComparisonBean;
import eu.planets_project.tb.gui.util.JSFUtil;
import eu.planets_project.tb.impl.model.eval.PropertyEvaluation;
import eu.planets_project.tb.impl.model.exec.ExecutionRecordImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementAgent;
import eu.planets_project.tb.impl.model.measure.MeasurementEventImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementTarget;
import eu.planets_project.tb.impl.model.measure.MeasurementAgent.AgentType;
import eu.planets_project.tb.impl.model.measure.MeasurementTarget.TargetType;
import eu.planets_project.tb.impl.properties.ManuallyMeasuredPropertyHandlerImpl;
import eu.planets_project.tb.impl.services.mockups.workflow.IdentifyWorkflow;
import eu.planets_project.tb.impl.services.wrappers.CharacteriseWrapper;
import eu.planets_project.tb.impl.services.wrappers.CompareWrapper;
import eu.planets_project.tb.impl.services.wrappers.IdentifyWrapper;

/**
 * @author AnJackson
 *
 */
public class DigitalObjectCompare {

    static private Log log = LogFactory.getLog(DigitalObjectCompare.class);

    // The data sources are managed here:
    DataRegistry dataRegistry = DataRegistryFactory.getDataRegistry();

    private String dobUri1;
    private String dobUri2;

    /**
     * @return the dob1
     */
    public String getDobUri1() {
        return dobUri1;
    }

    /**
     * @param dobUri the dobUri to set
     */
    public void setDobUri1(String dobUri1) {
        dobUri1 = DigitalObjectInspector.uriEncoder(dobUri1).toASCIIString();
        this.dobUri1 = dobUri1;
    }

    /**
     * @return the dob1
     */
    public String getDobUri2() {
        return dobUri2;
    }

    /**
     * @param dobUri the dobUri to set
     */
    public void setDobUri2(String dobUri2) {
        dobUri2 = DigitalObjectInspector.uriEncoder(dobUri2).toASCIIString();
        this.dobUri2 = dobUri2;
    }

    /**
     * @param dobUri
     * @return
     */
    static public DigitalObjectTreeNode lookupDob(String dobUri) {
        if (dobUri == null)
            return null;
        // Create as a URI:
        URI item;
        try {
            item = new URI(dobUri);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return null;
        }
        // Lookup and return:
        DigitalObjectTreeNode itemNode = new DigitalObjectTreeNode(item, DataRegistryFactory.getDataRegistry());
        return itemNode;
    }

    public DigitalObjectTreeNode getDob1() {
        return lookupDob(this.dobUri1);
    }

    public DigitalObjectTreeNode getDob2() {
        return lookupDob(this.dobUri2);
    }

    /* -------------------- Additional code for deeper inspection --------------------- */

    /** */
    private String compareService;
    private ServiceReport compareServiceReport;
    private String compareServiceException;
    private String compareServiceStackTrace;
    private MeasurementEventImpl me;

    /**
     * @return the compareService
     */
    public String getCompareService() {
        return compareService;
    }

    /**
     * @param compareService the compareService to set
     */
    public void setCompareService(String compareService) {
        this.compareService = compareService;
    }

    public void runCompareService() {
        log.info("Looking for properties using: " + this.getCompareService());

        // Reset:
        this.compareServiceReport = null;
        this.compareServiceException = null;
        this.compareServiceStackTrace = null;

        // Return nothing if no service is selected:
        if (this.getCompareService() == null)
            return;

        // Run the service:
        try {
            URL surl = new URL(this.getCompareService());

            Map<URL, ServiceDescription> compareServices = this.getCompareServices();
            ServiceDescription sd = compareServices.get(surl);

            if (sd.getType().equals(Compare.class.getCanonicalName())) {

                Compare chr = new CompareWrapper(surl);
                CompareResult cr = chr.compare(this.getDob1().getDob(), this.getDob2().getDob(), null);
                this.compareServiceReport = cr.getReport();

                me = this.createMeasurementEvent();
                if (me != null) {
                    this.fillComparisonEvent(me, chr, cr);
                    ExperimentInspector.persistExperiment();
                }

            } else if (sd.getType().equals(Identify.class.getCanonicalName())) {
                Identify idf = new IdentifyWrapper(surl);
                IdentifyResult ir1 = idf.identify(this.getDob1().getDob(), null);
                this.compareServiceReport = ir1.getReport();
                IdentifyResult ir2 = idf.identify(this.getDob2().getDob(), null);
                this.compareServiceReport = ir2.getReport();

                me = this.createMeasurementEvent();
                if (me != null) {
                    me.setAgent(new MeasurementAgent(idf.describe()));
                    me.setDate(Calendar.getInstance());
                    this.recordIdentifyComparison(me, ir1, this.getDobUri1(), ir2, this.getDobUri2());

                    ExperimentInspector.persistExperiment();
                }

            } else if (sd.getType().equals(Characterise.class.getCanonicalName())) {
                Characterise chr = new CharacteriseWrapper(surl);
                CharacteriseResult cr1 = chr.characterise(this.getDob1().getDob(), null);
                this.compareServiceReport = cr1.getReport();
                CharacteriseResult cr2 = chr.characterise(this.getDob2().getDob(), null);
                this.compareServiceReport = cr2.getReport();

                me = this.createMeasurementEvent();
                if (me != null) {
                    me.setAgent(new MeasurementAgent(chr.describe()));
                    me.setDate(Calendar.getInstance());
                    this.recordPropertyComparison(me, cr1.getProperties(), this.getDobUri1(), cr2.getProperties(),
                            this.getDobUri2());

                    ExperimentInspector.persistExperiment();
                }

            } else {
                this.compareServiceException = "ERROR: Do not know how to invoke this service!";
                log.error("Could not invoke service: " + this.getCompareService());
            }

            return;
        } catch (Exception e) {
            log.error("FAILED! " + e);
            this.compareServiceException = e.toString();

            this.compareServiceStackTrace = this.stackTraceToString(e);
            e.printStackTrace();

            return;
        }
    }

    /**
     * @param me 
     * @param chr
     * @param cr
     */
    private void fillComparisonEvent(MeasurementEventImpl me, Compare chr, CompareResult cr) {
        me.setAgent(new MeasurementAgent(chr.describe()));
        me.setDate(Calendar.getInstance());
        for (PropertyComparison pc : cr.getComparisons()) {
            MeasurementImpl m = new MeasurementImpl(me, pc.getComparison());
            MeasurementTarget mt = new MeasurementTarget();
            mt.setType(TargetType.DIGITAL_OBJECT_PAIR);
            // Get data on the first object:
            mt.getDigitalObjects().add(0, this.getDobUri1());
            mt.setDigitalObjectProperties(0, pc.getFirstProperties());
            log.info("Got PC1: " + pc.getFirstProperties());
            // Get data on the second object:
            mt.getDigitalObjects().add(1, this.getDobUri2());
            mt.setDigitalObjectProperties(1, pc.getSecondProperties());
            log.info("Got PC2: " + pc.getSecondProperties());
            // Add to the measurement:
            m.setTarget(mt);
            // Equivalence Data:
            m.setEquivalence(pc.getEquivalence());
            me.addMeasurement(m);
        }
    }

    /**
     */
    private void recordIdentifyComparison(MeasurementEventImpl me, IdentifyResult ir1, String dobUri1,
            IdentifyResult ir2, String dobUri2) {
        this.recordIdentifyMeasurement(me, ir1, dobUri1);
        this.recordIdentifyMeasurement(me, ir2, dobUri2);
    }

    private void recordIdentifyMeasurement(MeasurementEventImpl me, IdentifyResult ir, String dob) {
        for (URI fmt : ir.getTypes()) {
            MeasurementImpl m = new MeasurementImpl(IdentifyWorkflow.MEASURE_IDENTIFY_FORMAT);
            m.setValue(fmt.toASCIIString());
            m.setTarget(new MeasurementTarget());
            m.getTarget().setType(TargetType.DIGITAL_OBJECT);
            m.getTarget().getDigitalObjects().add(dob);
            me.addMeasurement(m);

        }
        // Also record the method:
        if (ir.getMethod() != null) {
            MeasurementImpl m = new MeasurementImpl(IdentifyWorkflow.MEASURE_IDENTIFY_METHOD);
            m.setValue(ir.getMethod().name());
            m.setTarget(new MeasurementTarget());
            m.getTarget().setType(TargetType.DIGITAL_OBJECT);
            m.getTarget().getDigitalObjects().add(dob);
            me.addMeasurement(m);
        }
    }

    private void recordPropertyComparison(MeasurementEventImpl me, List<Property> properties1, String dobUri1,
            List<Property> properties2, String dobUri2) {
        this.recordPropertyMeasurements(me, properties1, dobUri1);
        this.recordPropertyMeasurements(me, properties2, dobUri2);
    }

    private void recordPropertyMeasurements(MeasurementEventImpl me, List<Property> props, String dob) {
        for (Property p : props) {
            MeasurementImpl m = new MeasurementImpl(me, p);
            m.setTarget(new MeasurementTarget());
            m.getTarget().setType(TargetType.DIGITAL_OBJECT);
            m.getTarget().getDigitalObjects().add(dob);
            me.addMeasurement(m);
        }
    }

    /**
     * @return
     */
    public ServiceReport getCompareServiceReport() {
        return compareServiceReport;
    }

    /**
     * @return the compareServiceException
     */
    public String getCompareServiceException() {
        return compareServiceException;
    }

    /**
     * @return the compareServiceStackTrace
     */
    public String getCompareServiceStackTrace() {
        return compareServiceStackTrace;
    }

    /**
     * @return
     */
    public MeasurementEventImpl getMeasurementEvent() {
        return this.me;
    }

    /**
     * @return
     */
    public List<SelectItem> getCompareServiceList() {
        log.info("IN: getCompareServiceList");
        /*
                String input = this.getInputFormat();
                if( ! this.isInputSet() ) input = null;
                String output = this.getOutputFormat();
                if( ! this.isOutputSet() ) output = null;
        */
        List<ServiceDescription> sdl = new ArrayList<ServiceDescription>(this.getCompareServices().values());

        return ServiceBrowser.mapServicesToSelectList(sdl);
    }

    private Map<URL, ServiceDescription> getCompareServices() {
        Map<URL, ServiceDescription> map = new HashMap<URL, ServiceDescription>();

        // Find all services:
        ServiceBrowser sb = (ServiceBrowser) JSFUtil.getManagedObject("ServiceBrowser");
        List<ServiceDescription> sdl = sb.getCompareServices();
        sdl.addAll(sb.getCharacteriseServices());
        sdl.addAll(sb.getIdentifyServices());

        // Create map:
        for (ServiceDescription sd : sdl) {
            map.put(sd.getEndpoint(), sd);
        }

        return map;
    }

    /* ------------------------------------------ */

    protected String stackTraceToString(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        return sw.toString();
    }

    /**
     * Truncates the property values at a max. fixed length of 500 chars
     * @return
     */
    private static List<Property> truncatePropertyValues(List<Property> in) {
        List<Property> ret = new ArrayList<Property>();
        //iterate over the properties and truncate when more than 500 chars 
        if ((in == null) || (in.size() <= 0)) {
            return ret;
        }
        for (Property p : in) {
            if (p.getValue().length() > 500) {
                //add a truncated value String
                ret.add(new Property(p.getUri(), p.getName(), p.getValue().substring(0, 500) + "[..]"));
            } else {
                //add the original result
                ret.add(p);
            }
        }
        return ret;
    }

    /**
     * @return
     */
    public List<MeasuredComparisonBean> getMeasurementComparisons() {
        List<MeasuredComparisonBean> ms = new ArrayList<MeasuredComparisonBean>();
        ResultsForDigitalObjectBean res = new ResultsForDigitalObjectBean(this.getDobUri1());
        if (res == null || res.getExecutionRecord() == null) {
            if (this.me != null) {
                log.info("Pulling getExperimentMeasurements from the temporary space.");
                ms.addAll(MeasuredComparisonBean.createFromEvents(this.getDobUri1(), this.getDobUri2(), null,
                        this.me));
            }
            log.info("Got getExperimentMeasurements " + ms.size());
            return ms;
        }
        // Otherwise, pull from DB:
        log.info("Pulling getExperimentMeasurements from the DB.");
        Set<MeasurementEventImpl> measurementEvents = res.getExecutionRecord().getMeasurementEvents();
        List<MeasurementEventImpl> mevl = new ArrayList<MeasurementEventImpl>(measurementEvents);
        Collections.sort(mevl, Collections.reverseOrder());
        ms.addAll(MeasuredComparisonBean.createFromEvents(this.getDobUri1(), this.getDobUri2(),
                res.getExecutionRecord().getPropertyEvaluation(),
                mevl.toArray(new MeasurementEventImpl[mevl.size()])));
        log.info("Got getExperimentMeasurements from Events, " + ms.size() + " out of " + mevl.size());
        return ms;
    }

    /**
     * Get any stored measurements:
     * 
     * @return
     */
    public List<MeasurementEventImpl> getMeasurementEvents() {
        List<MeasurementEventImpl> ms = new ArrayList<MeasurementEventImpl>();
        ResultsForDigitalObjectBean res = new ResultsForDigitalObjectBean(this.getDobUri1());
        if (res == null || res.getExecutionRecord() == null) {
            if (this.me != null) {
                log.info("Pulling getExperimentMeasurements from the temporary space.");
                ms.add(this.me);
            }
            log.info("Got getExperimentMeasurements " + ms.size());
            return ms;
        }
        // Otherwise, pull from DB:
        log.info("Pulling getExperimentMeasurements from the DB.");
        Set<MeasurementEventImpl> measurementEvents = res.getExecutionRecord().getMeasurementEvents();
        ms.addAll(measurementEvents);
        return ms;
    }

    /**
     * @return
     */
    public MeasuredComparisonEventBean getManualMeasurementEventBean() {
        MeasurementEventImpl me = this.getManualMeasurementEvent();
        MeasuredComparisonEventBean meb = new MeasuredComparisonEventBean(me, this.getDobUri1(), this.getDobUri2());
        return meb;
    }

    /**
     * @return
     */
    private MeasurementEventImpl getManualMeasurementEvent() {
        MeasurementEventImpl me = null;
        ResultsForDigitalObjectBean res = new ResultsForDigitalObjectBean(this.getDobUri1());
        if (res == null || res.getExecutionRecord() == null)
            return null;
        Set<MeasurementEventImpl> measurementEvents = res.getExecutionRecord().getMeasurementEvents();
        for (MeasurementEventImpl mee : measurementEvents) {
            if (mee.getAgent() != null && mee.getAgent().getType() == AgentType.USER) {
                me = mee;
            }
        }
        // If none, create one and pass it back.
        if (me == null) {
            log.info("Creating Manual Measurement Event.");
            me = this.createMeasurementEvent();
            UserBean user = (UserBean) JSFUtil.getManagedObject("UserBean");
            me.setAgent(new MeasurementAgent(user));
            ExperimentInspector.persistExperiment();
        }
        return me;
    }

    private String newManVal1;
    private String newManVal2;
    //private String newManCmp;
    //private EquivalenceStatement newManEqu;

    /**
     * @return the newManVal1
     */
    public String getNewManVal1() {
        return newManVal1;
    }

    /**
     * @param newManVal1 the newManVal1 to set
     */
    public void setNewManVal1(String newManVal1) {
        this.newManVal1 = newManVal1;
    }

    /**
     * @return the newManVal2
     */
    public String getNewManVal2() {
        return newManVal2;
    }

    /**
     * @param newManVal2 the newManVal2 to set
     */
    public void setNewManVal2(String newManVal2) {
        this.newManVal2 = newManVal2;
    }

    /**
     */
    public void storeManualMeasurement() {
        // Look up the definition:
        ManuallyMeasuredPropertyHandlerImpl mm = ManuallyMeasuredPropertyHandlerImpl.getInstance();
        UserBean user = (UserBean) JSFUtil.getManagedObject("UserBean");
        ManualMeasurementBackingBean mmbb = (ManualMeasurementBackingBean) JSFUtil
                .getManagedObject("ManualMeasurementBackingBean");
        List<ManuallyMeasuredProperty> mps = mm.loadAllManualProperties(user.getUserid());
        ManuallyMeasuredProperty mp = null;
        for (ManuallyMeasuredProperty amp : mps) {
            if (amp.getURI().equals(mmbb.getNewManProp()))
                mp = amp;
        }
        if (mp == null) {
            log.error("No property [" + mmbb.getNewManProp() + "] found!");
            return;
        }
        // Lookup the event:
        MeasurementEventImpl mev = this.getManualMeasurementEvent();
        // Make the property
        Property p = new Property.Builder(URI.create(mp.getURI())).description(mp.getDescription())
                .name(mp.getName()).build();
        DigitalObjectCompare.createMeasurement(mev, p, this.dobUri1, this.newManVal1);
        DigitalObjectCompare.createMeasurement(mev, p, this.dobUri2, this.newManVal2);
        ExperimentInspector.persistExperiment();
    }

    /**
     */
    public void updateManualMeasurementEnvironment() {
        ExperimentInspector.persistExperiment();
    }

    /**
     * A single-property measurement:
     * @param p
     * @param dobUri
     * @param value
     */
    public static void createMeasurement(MeasurementEventImpl mev, Property p, String dobUri, String value) {
        // Make
        MeasurementImpl m = new MeasurementImpl(mev);
        // Create a property from the manual one:
        m.setProperty(new Property.Builder(p).build());
        //m.setUserEquivalence(this.newManEqu);
        m.setEquivalence(Equivalence.UNKNOWN);
        m.setValue(value);
        MeasurementTarget target = new MeasurementTarget();
        target.setType(TargetType.DIGITAL_OBJECT);
        target.getDigitalObjects().add(0, dobUri);
        /*
        target.setDigitalObjectProperty( 0, 
                new Property.Builder( p ).value(value).build()
            );
        */
        m.setTarget(target);
        // And add it, and persist:
        mev.addMeasurement(m);
    }

    /**
     * @return
     */
    public String getManualMeasurementEnvironment() {
        if (this.getManualMeasurementEvent() == null)
            return "";
        return this.getManualMeasurementEvent().getAgent().getUserEnvironmentDescription();
    }

    public void setManualMeasurementEnvironment(String env) {
        this.getManualMeasurementEvent().getAgent().setUserEnvironmentDescription(env);
    }

    /**
     * @return
     */
    private MeasurementEventImpl createMeasurementEvent() {
        ResultsForDigitalObjectBean res = new ResultsForDigitalObjectBean(this.getDobUri1());
        // If there is no experiment, return a non-DB event:
        if (res == null)
            return new MeasurementEventImpl((ExecutionRecordImpl) null);
        if (res.getExecutionRecord() == null)
            return new MeasurementEventImpl((ExecutionRecordImpl) null);

        // Otherwise, create an event that is attached to the experiment:
        MeasurementEventImpl me = new MeasurementEventImpl(res.getExecutionRecord());
        res.getExecutionRecord().getMeasurementEvents().add(me);
        return me;
    }

    /**
     * 
     */
    public void redirectBackToCompare() {
        ExperimentBean expBean = (ExperimentBean) JSFUtil.getManagedObject("ExperimentBean");
        if (expBean == null) {
            JSFUtil.redirect(
                    "/reader/dob_compare.faces?eid=dobUri1=" + this.getDobUri1() + "&dobUri2=" + this.getDobUri2());
        }
        JSFUtil.redirect("/exp/dob_compare.faces?eid=" + expBean.getExperiment().getEntityID() + "&dobUri1="
                + this.getDobUri1() + "&dobUri2=" + this.getDobUri2());
    }

    /**
     * @return
     */
    public List<SelectItem> getEquivalenceOptions() {
        return PropertyEvaluation.getEquivalenceOptions();
    }
}