eu.planets_project.tb.impl.persistency.ExperimentPersistencyImpl.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.tb.impl.persistency.ExperimentPersistencyImpl.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.impl.persistency;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.ejb.Stateless;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import javax.rmi.PortableRemoteObject;

import eu.planets_project.tb.api.model.Experiment;
import eu.planets_project.tb.api.persistency.ExperimentPersistencyRemote;
import eu.planets_project.tb.impl.model.ExperimentImpl;
import eu.planets_project.tb.impl.model.exec.BatchExecutionRecordImpl;
import eu.planets_project.tb.impl.model.exec.ExecutionRecordImpl;
import eu.planets_project.tb.impl.model.exec.ExecutionStageRecordImpl;
import eu.planets_project.tb.impl.model.exec.ServiceRecordImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementEventImpl;
import eu.planets_project.tb.impl.model.measure.MeasurementImpl;

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

/**
 * 
 * @author Andrew Jackson <Andrew.Jackson@bl.uk>
 */
@Stateless
public class ExperimentPersistencyImpl implements ExperimentPersistencyRemote {

    /* For Hypersonic, use this: */
    public static final String BLOB_TYPE = "BINARY";
    public static final String TEXT_TYPE = "VARCHAR";
    /* For MySQL, use this: */
    //public static final String BLOB_TYPE = "LONGBLOB";
    //public static final String TEXT_TYPE = "LONGTEXT";

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

    @PersistenceContext(unitName = "testbed", type = PersistenceContextType.TRANSACTION)
    private EntityManager manager;

    public void deleteExperiment(long id) {
        ExperimentImpl t_helper = manager.find(ExperimentImpl.class, id);
        manager.remove(t_helper);
    }

    public void deleteExperiment(Experiment experiment) {
        ExperimentImpl t_helper = manager.find(ExperimentImpl.class, experiment.getEntityID());
        manager.remove(t_helper);
    }

    public Experiment findExperiment(long id) {
        return manager.find(ExperimentImpl.class, id);
    }

    public long persistExperiment(Experiment experiment) {
        log.debug("Persisting experiment: "
                + experiment.getExperimentSetup().getBasicProperties().getExperimentName());
        manager.persist(experiment);
        return experiment.getEntityID();
    }

    public void updateExperiment(Experiment experiment) {
        log.info(
                "Updating experiment: " + experiment.getExperimentSetup().getBasicProperties().getExperimentName());
        // FIXME Remove this stack trace:
        //new Exception("Updating experiment...").printStackTrace();
        log.info("Experiment currently has " + experiment.getExperimentExecutable().getNumBatchExecutionRecords()
                + " batch exec records");
        manager.merge(experiment);
        log.info("Updated experiment: " + experiment.getExperimentSetup().getBasicProperties().getExperimentName());
    }

    @SuppressWarnings("unchecked")
    public List<Experiment> queryAllExperiments() {
        log.info("Looking up all experiments.");
        // FIXME This is not needed: Exception e = new Exception("All Experiments.");
        // e.printStackTrace();
        Query query = manager.createQuery("from ExperimentImpl");
        return query.getResultList();
    }

    @SuppressWarnings("unchecked")
    public boolean queryIsExperimentNameUnique(String expName) {
        log.info("Checking uniqueness of exp. name: " + expName);
        Query query = manager
                .createQuery("SELECT sExpName FROM BasicPropertiesImpl WHERE LOWER(sExpName)=LOWER(:expname)");
        query.setParameter("expname", expName);
        List<String> results = (List<String>) query.getResultList();
        if (results.size() == 0)
            return true;

        return false;
    }

    @SuppressWarnings("unchecked")
    public List<Experiment> searchAllExperiments(String toFind) {
        // Not case sensitive, wildcarded:
        log.info("Searching for experiments that match: " + toFind);
        // TODO Augment this with more fields.
        Query query = manager.createQuery(
                "FROM ExperimentImpl AS e WHERE LOWER(e.expSetup.basicProperties.sExpName) LIKE :toFindLike OR LOWER(e.expSetup.basicProperties.sSummary) LIKE :toFindLike");
        // This should work, but does not.  It is unclear why. the type of the toFind should not be String.
        // OR :toFind MEMBER OF e.expSetup.basicProperties.vInvolvedUsers");
        //query.setParameter("toFind", toFind );
        query.setParameter("toFindLike", "%" + toFind.toLowerCase() + "%");
        return query.getResultList();
    }

    /**
     * A Factory method to build a reference to this interface.
     * @return
     */
    public static ExperimentPersistencyRemote getInstance() {
        try {
            Context jndiContext = getInitialContext();
            ExperimentPersistencyRemote dao_r = (ExperimentPersistencyRemote) PortableRemoteObject.narrow(
                    jndiContext.lookup("testbed/ExperimentPersistencyImpl/remote"),
                    ExperimentPersistencyRemote.class);
            return dao_r;
        } catch (NamingException e) {
            //TODO integrate message into logging mechanism
            System.out.println("Failure in getting PortableRemoteObject: " + e.toString());
            return null;
        }
    }

    private static Context getInitialContext() throws javax.naming.NamingException {
        return new javax.naming.InitialContext();
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExperimentPersistencyRemote#getPagedExperiments(int, int, java.lang.String, boolean)
     */
    @SuppressWarnings("unchecked")
    public List<Experiment> getPagedExperiments(int firstRow, int numberOfRows, String sortField,
            boolean descending) {
        log.info("Searching for experiments that match: " + firstRow + "," + numberOfRows + " : " + sortField
                + " : " + descending);
        // Execute the query:
        Query query = manager.createQuery("FROM ExperimentImpl AS e " + createOrderBy(sortField, descending));
        query.setFirstResult(firstRow);
        query.setMaxResults(numberOfRows);
        List<Experiment> resultList = query.getResultList();
        log.info("Search complete.");
        return resultList;

        /*
        String propertyName;
        if( "experimenter".equals(sortField) ) {
        //            this.findExperiment(1).getExperimentSetup().getBasicProperties().getExperimenter();
        propertyName = "expSetup.basicProperties.sExpName";
        } else {
        //          this.findExperiment(1).getExperimentSetup().getBasicProperties().getExperimentName();
        propertyName = "expSetup.basicProperties.sExpName";
        }
        Order order;
        if( descending ) {
        //    query.setParameter("deasc", "descending");
        order = Order.asc(propertyName);
        } else {
        //    query.setParameter("deasc", "ascending");
        order = Order.desc(propertyName);
        }
            
        Session hibernateSession = null;
        if (manager.getDelegate() instanceof org.hibernate.ejb.HibernateEntityManager) {
        hibernateSession = ((org.hibernate.ejb.HibernateEntityManager) manager
                .getDelegate()).getSession();
        } else {
        hibernateSession = (org.hibernate.Session) manager.getDelegate();
        }
            
        return hibernateSession.createCriteria(ExperimentImpl.class)
        .addOrder( order )
        .setFirstResult(firstRow)
        .setMaxResults(numberOfRows)
        .list();
        */
    }

    private String createOrderBy(String sortField, boolean descending) {
        String orderby, deasc;
        if ("experimenter".equals(sortField)) {
            orderby = "e.expSetup.basicProperties.sExperimenterID";
        } else if ("type".equals(sortField)) {
            orderby = "e.expSetup.basicProperties.sExperimentApproach";
        } else if ("startDate".equals(sortField)) {
            orderby = "e.startDate";
        } else if ("execDate".equals(sortField)) {
            orderby = "e.executable.execEndDate";
            //        } else if( "currentStage".equals(sortField) ) {  // FIXME Current stage NOT STORED IN DATABASE!
            //            orderby = "e.???";
        } else {
            orderby = "e.expSetup.basicProperties.sExpName";
        }
        if (descending) {
            deasc = "DESC";
        } else {
            deasc = "ASC";
        }
        return "ORDER BY " + orderby + " " + deasc;
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExperimentPersistencyRemote#getNumberOfExperiments()
     */
    public int getNumberOfExperiments() {
        log.info("Counting the experiments...");
        int ne = ((Long) manager.createQuery("SELECT COUNT(e.id) FROM ExperimentImpl AS e").getSingleResult())
                .intValue();
        log.info("There are " + ne + " experiments.");
        return ne;
    }

    public List<ServiceRecordImpl> getServiceRecords() {
        List<ServiceRecordImpl> list = new ArrayList<ServiceRecordImpl>();
        //        Query query = manager.createQuery("SELECT s.serviceRecord FROM ExperimentImpl AS e INNER JOIN e.executable.executionRecords AS x INNER JOIN x.runs AS r INNER JOIN r.stages AS s");
        List<Experiment> experiments = this.queryAllExperiments();
        for (Experiment exp : experiments) {
            if (exp.getExperimentExecutable() != null
                    && exp.getExperimentExecutable().getBatchExecutionRecords() != null) {
                Set<BatchExecutionRecordImpl> batches = exp.getExperimentExecutable().getBatchExecutionRecords();
                for (BatchExecutionRecordImpl batch : batches) {
                    if (batch != null && batch.getRuns() != null) {
                        for (ExecutionRecordImpl run : batch.getRuns()) {
                            for (ExecutionStageRecordImpl stage : run.getStages()) {
                                if (stage.getServiceRecord() != null)
                                    list.add(stage.getServiceRecord());
                            }
                        }
                    }
                }
            }
        }
        return list;
    }

    // FIXME This does not work.

    //@SuppressWarnings("unchecked")
    public ServiceRecordImpl findServiceRecordByHashcode(String serviceHash) {
        Query query = manager.createQuery(
                "SELECT s.serviceRecord FROM ExperimentImpl AS exp LEFT JOIN exp.executable.executionRecords AS rec LEFT JOIN rec.runs AS run LEFT JOIN run.stages AS stage WHERE stage.serviceHash = :hash");
        query.setParameter("hash", serviceHash);
        List<ServiceRecordImpl> srs = query.getResultList();
        if (srs == null)
            return null;
        if (srs.size() == 0)
            return null;
        return srs.get(0);
        /*
        */
        /*
        for( ServiceRecordImpl record : this.getServiceRecords() ) {
        if( serviceHash.equals( record.getServiceHash()) ) return record;
        }
        return null;
        */
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExecutionRecordPersistency#findMeasurement(long)
     */
    public MeasurementImpl findMeasurement(long id) {
        return manager.find(MeasurementImpl.class, id);
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExecutionRecordPersistency#removeMeasurement(eu.planets_project.tb.impl.model.measure.MeasurementImpl)
     */
    public void removeMeasurement(MeasurementImpl m) {
        log.info("Removing measurement " + m.getId());
        if (m.getId() == -1)
            return;
        // This never seems to work, no matter what I do. Not clear why. Cascade issues?
        //manager.remove( m );
        // So, instead, manually clip it out:
        Query query = manager.createNativeQuery("DELETE FROM MeasurementImpl WHERE id=:id");
        query.setParameter("id", m.getId());
        query.executeUpdate();
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExecutionRecordPersistency#findMeasurementEvent(long)
     */
    public MeasurementEventImpl findMeasurementEvent(long id) {
        return manager.find(MeasurementEventImpl.class, id);
    }

    /* (non-Javadoc)
     * @see eu.planets_project.tb.api.persistency.ExecutionRecordPersistency#removeMeasurementEvent(eu.planets_project.tb.impl.model.measure.MeasurementEventImpl)
     */
    public void removeMeasurementEvent(MeasurementEventImpl me) {
        // See above for removeMeasurement case and problems with this not working.
        //manager.remove( me );
        /* No longer done this way.
        for( MeasurementImpl m : me.getMeasurements() ) {
        this.removeMeasurement(m);
        }
        */
        Query query = manager.createNativeQuery("DELETE FROM MeasurementEventImpl WHERE id=:id");
        query.setParameter("id", me.getId());
        query.executeUpdate();
    }

}