PersistenceController.java :  » JPA » vars-redux » vars » annotation » ui » Java Open Source

Java Open Source » JPA » vars redux 
vars redux » vars » annotation » ui » PersistenceController.java
/*
 * @(#)PersistenceController.java   2009.12.12 at 09:31:16 PST
 *
 * Copyright 2009 MBARI
 *
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */



package vars.annotation.ui;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Vector;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import org.mbari.net.URLUtilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vars.DAO;
import vars.ILink;
import vars.annotation.AnnotationDAOFactory;
import vars.annotation.AnnotationFactory;
import vars.annotation.Association;
import vars.annotation.AssociationDAO;
import vars.annotation.CameraData;
import vars.annotation.Observation;
import vars.annotation.ObservationDAO;
import vars.annotation.VideoArchive;
import vars.annotation.VideoArchiveDAO;
import vars.annotation.VideoArchiveSet;
import vars.annotation.VideoFrame;
import vars.annotation.ui.roweditor.RowEditorPanel;
import vars.annotation.ui.table.ObservationTable;
import vars.annotation.ui.table.ObservationTableModel;
import vars.knowledgebase.ConceptDAO;

/**
 * PersistenceService manages database transactions for the user-interface. It will keep the
 * persistent objects AND the user interface in synch.
 *
 * @version        Enter version here..., 2009.11.16 at 10:49:40 PST
 * @author         Brian Schlining [brian@mbari.org]
 */
public class PersistenceController {

    private static final NumberFormat f0123 = new DecimalFormat("0000");
    private static final NumberFormat f01 = new DecimalFormat("00");
    private final Logger log = LoggerFactory.getLogger(getClass());
    private final AnnotationDAOFactory annotationDAOFactory;
    private final AnnotationFactory annotationFactory;
    private final ToolBelt toolBelt;

    /**
     * Constructs ...
     *
     * @param toolBelt
     */
    public PersistenceController(ToolBelt toolBelt) {
        super();
        this.toolBelt = toolBelt;
        this.annotationDAOFactory = toolBelt.getAnnotationDAOFactory();
        this.annotationFactory = toolBelt.getAnnotationFactory();
    }

    /**
     *
     * @param observations
     * @return
     */
    public Collection<Observation> deleteAllAssociationsFrom(Collection<Observation> observations) {
        Collection<Observation> updateObservations = new ArrayList<Observation>();
        DAO dao = toolBelt.getAnnotationDAOFactory().newDAO();
        dao.startTransaction();

        for (Observation observation : observations) {
            observation = dao.find(observation);

            if (observation != null) {

                for (Association association : new ArrayList<Association>(observation.getAssociations())) {
                    observation.removeAssociation(association);
                    dao.remove(association);
                }

                updateObservations.add(observation);
            }
        }
        dao.endTransaction();
        dao.close();
        updateUI();
        return updateObservations;
    }

    /**
     *
     * @param associations
     */
    public void deleteAssociations(Collection<Association> associations) {
        final DAO dao = annotationDAOFactory.newDAO();
        Collection<Observation> modifiedObservations = new ArrayList<Observation>();
        dao.startTransaction();

        for (Association association : associations) {
            association = dao.find(association);

            if (association != null) {
                final Observation observation = association.getObservation();
                observation.removeAssociation(association);
                dao.remove(association);

                if (!modifiedObservations.contains(observation)) {
                    modifiedObservations.add(observation);
                }
            }
        }

        dao.endTransaction();
        dao.close();
        updateUI(modifiedObservations);
    }

    /**
     *
     * @param videoArchive
     * @return
     */
    public VideoArchive deleteEmptyVideoFramesFrom(VideoArchive videoArchive) {
        final DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();
        videoArchive = dao.find(videoArchive);
        Collection<VideoFrame> videoFrames = new ArrayList<VideoFrame>(videoArchive.getEmptyVideoFrames());
        for (VideoFrame videoFrame : videoFrames) {
            videoArchive.removeVideoFrame(videoFrame);
            dao.remove(videoFrame);
        }
        dao.endTransaction();
        dao.close();
        return videoArchive;
    }

    /**
     *
     * @param observations
     */
    public void deleteObservations(Collection<Observation> observations) {
        final DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();

        for (Observation observation : observations) {
            observation = dao.find(observation);

            if (observation != null) {
                VideoFrame videoFrame = observation.getVideoFrame();
                videoFrame.removeObservation(observation);
                dao.remove(observation);

                if (videoFrame.getObservations().size() == 0) {
                    VideoArchive videoArchive = videoFrame.getVideoArchive();
                    videoArchive.removeVideoFrame(videoFrame);
                    dao.remove(videoFrame);
                }
            }

        }

        dao.endTransaction();
        dao.close();
        updateUI();
    }

    /**
     *
     * @param observations
     * @param associationTemplate
     * @return
     */
    public Collection<Association> insertAssociations(Collection<Observation> observations, ILink associationTemplate) {
        final Collection<Association> associations = new ArrayList<Association>(observations.size());
        final Collection<Observation> uiObservations = new ArrayList<Observation>();
        final Collection<Observation> mergedObservations = new ArrayList<Observation>();
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        final AssociationDAO dao = annotationDAOFactory.newAssociationDAO();

        // DAOTX - Add Association to each observation
        dao.startTransaction();
        for (Observation observation : observations) {
            // Try a merge first to try an update the conceptName incase it's been
            // changed.
            try {
                observation = dao.merge(observation);
            }
            catch (Exception e) {
                observation = dao.find(observation);
            }
            
            if (observation != null) {
                uiObservations.add(observation);
                Association ass = annotationFactory.newAssociation(associationTemplate.getLinkName(),
                    associationTemplate.getToConcept(), associationTemplate.getLinkValue());
                observation.addAssociation(ass);
                dao.persist(ass);
                dao.validateName(ass, conceptDAO);
                associations.add(ass);
            }
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        resetObservationsInDispatcher(uiObservations);
        updateUI(uiObservations);    // update view
        return associations;
    }

    /**
     * If any of the observations provided in the argument match those in those
     * referenced in {@code (Collection<Observation>) Lookup.getSelectedObservationsDispatcher().getValueObject();}
     * then they ones in the dispatcher will be replaced by those you provided.
     * This helps keep observations in sync
     * 
     * @param observations
     */
    private void resetObservationsInDispatcher(Collection<Observation> observations) {

        // ---- Remove overlapping references from the observations in the
        // dispatcher. We'll replace them with the observations in our argument
        // collection.
        Collection<Observation> selectedObservations = (Collection<Observation>) Lookup.getSelectedObservationsDispatcher().getValueObject();
        Function<Observation, Long> f = new Function<Observation, Long>() {
            public Long apply(Observation from) {
                return (Long) from.getPrimaryKey();
            }
        };
        final Collection<Long> pks = Collections2.transform(observations, f);
        final Collection<Long> selectedPks = new ArrayList<Long>(Collections2.transform(selectedObservations, f));
        selectedPks.removeAll(pks);
        selectedObservations = Collections2.filter(selectedObservations, new Predicate<Observation>() {
            public boolean apply(Observation input) {
                return selectedPks.contains((Long) input.getPrimaryKey());
            }
        });

        // ---- Once the overlaps are removed add the replacements
        Collection<Observation> uiObservations = new ArrayList<Observation>(selectedObservations);
        uiObservations.addAll(observations);

        Lookup.getSelectedObservationsDispatcher().setValueObject(uiObservations);
    }

    /**
     *
     * @param videoFrame
     * @param observation
     * @return
     */
    public Observation insertObservation(VideoFrame videoFrame, Observation observation) {
        ObservationDAO dao = annotationDAOFactory.newObservationDAO();
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        Collection<Observation> newObservations = new ArrayList<Observation>();
        dao.startTransaction();
        videoFrame = dao.find(videoFrame);

        if (videoFrame != null) {
            videoFrame.addObservation(observation);
            dao.persist(observation);
            dao.validateName(observation, conceptDAO);
            newObservations.add(observation);
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        updateUI(newObservations);    // update view
        return observation;
    }

    /**
     *
     * @param videoFrame
     * @param observations
     * @return
     */
    public Collection<Observation> insertObservations(VideoFrame videoFrame, Collection<Observation> observations) {
        ObservationDAO dao = annotationDAOFactory.newObservationDAO();
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        dao.startTransaction();
        videoFrame = dao.find(videoFrame);

        for (Observation observation : observations) {
            videoFrame.addObservation(observation);
            dao.persist(observation);
            dao.validateName(observation, conceptDAO);
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        updateUI(observations);    // update view
        return observations;
    }

    /**
     *
     * @param videoArchive
     * @param videoFrame
     * @return
     */
    public VideoFrame insertVideoFrame(VideoArchive videoArchive, VideoFrame videoFrame) {
        DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();
        videoArchive = dao.find(videoArchive);
        videoArchive.addVideoFrame(videoFrame);
        dao.persist(videoFrame);
        dao.endTransaction();
        dao.close();
        return videoFrame;
    }

    /**
     * VideoFrames need to be loaded from the database. Call this method to fetch all
     * of them for a particular {@link VideoArchive}. Be sre to grab the returned reference
     * in order to access them.
     * @param videoArchive
     * @return
     */
    public VideoArchive loadVideoFramesFor(VideoArchive videoArchive) {
        DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();
        videoArchive = dao.find(videoArchive);
        @SuppressWarnings("unused") Collection<VideoFrame> videoFrames = videoArchive.getVideoFrames();
        dao.endTransaction();
        dao.close();
        return videoArchive;
    }

    /**
     * Convenience method very specific to MBARI internal usage and naming
     * conventions. MBARI likes to name video archives so that a tape #3 from
     * dive# 302 (seqNumber)using the ROV Tiburon (platform) would be named
     * T0302-03.
     *
     * @param platform The platform name. THe first character of the name
     *          is used. This is stored in the VideoArchiveSet
     * @param seqNumber In MBARI's case we use dive number. seqNumber is
     *          stored in the CameraPlatformDeployment. Numbers with more than
     *          4 digits are not supported.
     * @param tapeNumber This is an MBARI specific value. It is not stored in
     *          the VARS database. Numbers of more than 2 digits are not supported.
     * @param postfix This is any text to be appended to the end of the {@link VideoArchive}'s name. At MBARI,
     *          we use this to indicate HD tapes by appending 'HD'. If it's null nothing will be
     *          appended
     * @return A string name that is generated from the supplied arguments
     */
    public static String makeVideoArchiveName(final String platform, final int seqNumber, final int tapeNumber,
            final String postfix) {
        StringBuffer sb = new StringBuffer();
        sb.append(platform.charAt(0));
        sb.append(f0123.format((long) seqNumber));
        sb.append("-");
        sb.append(f01.format((long) tapeNumber));

        if (postfix != null) {
            sb.append(postfix);
        }

        return sb.toString();
    }

    /**
     *
     * @param videoArchive
     * @param observations
     */
    public void moveObservationsTo(VideoArchive videoArchive, Collection<Observation> observations) {
        Collection<Observation> updateObservations = new ArrayList<Observation>();
        DAO dao = toolBelt.getAnnotationDAOFactory().newDAO();
        dao.startTransaction();
        videoArchive = dao.find(videoArchive);

        for (Observation observation : updateObservations) {
            observation = dao.find(observation);
            throw new UnsupportedOperationException("Implementation isn't finished yet");
        }
    }

    /**
     *
     * @param platform
     * @param sequenceNumber
     * @param videoArchiveName
     * @return
     */
    public VideoArchive openVideoArchive(String platform, int sequenceNumber, String videoArchiveName) {
        VideoArchiveDAO dao = toolBelt.getAnnotationDAOFactory().newVideoArchiveDAO();
        dao.startTransaction();
        VideoArchive videoArchive = dao.findOrCreateByParameters(platform, sequenceNumber, videoArchiveName);
        @SuppressWarnings("unused") Collection<VideoFrame> videoFrames = videoArchive.getVideoFrames();    // Load the videoFrames
        dao.endTransaction();
        dao.close();
        Lookup.getVideoArchiveDispatcher().setValueObject(videoArchive);

        // TODO Do we need to call updateUI here?
        return videoArchive;
    }


    /**
     * Thread-safe. Updates changes made to the observations in the database. Validates the
     * concept names used by the {@link Observation}s and their child {@link Association}
     * @param observations
     * @return
     */
    public Collection<Observation> updateAndValidate(Collection<Observation> observations) {
        Collection<Observation> updatedObservations = new Vector<Observation>(observations.size());
        ObservationDAO dao = toolBelt.getAnnotationDAOFactory().newObservationDAO();
        AssociationDAO aDao = toolBelt.getAnnotationDAOFactory().newAssociationDAO(dao.getEntityManager());
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        dao.startTransaction();

        for (Observation observation : observations) {
            observation = dao.updateFields(observation);
            if (observation != null) {
                updatedObservations.add(observation);
                dao.validateName(observation, conceptDAO);
                for (Association association : new ArrayList<Association>(observation.getAssociations())) {
                    aDao.validateName(association, conceptDAO);
                }
            }
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        return updatedObservations;
    }

    /**
     *
     * @param associations
     * @return
     */
    public Collection<Association> updateAssociations(Collection<Association> associations) {
        final AssociationDAO dao = annotationDAOFactory.newAssociationDAO();
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        Collection<Association> updatedAssociations = new ArrayList<Association>(associations.size());
        Collection<Observation> uiObservations = new ArrayList<Observation>();
        dao.startTransaction();

        for (Association association : associations) {
            association = dao.merge(association);
            dao.validateName(association, conceptDAO);
            updatedAssociations.add(association);
            uiObservations.add(association.getObservation());
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        updateUI(uiObservations);
        return updatedAssociations;
    }

    /**
     *
     * @param observations
     * @return
     */
    public Collection<Observation> updateObservations(Collection<Observation> observations) {
        Collection<Observation> updatedObservations = updateAndValidate(observations);
        updateUI(updatedObservations);    // update view
        return updatedObservations;
    }

    /**
     * Changes the CameraData URL's that match the currently set local directory to
     * use ther URL (image mapping target) defined in the uses preferences.
     *
     * @param videoArchive
     * @param imageTarget The  directory where the frames are saved into
     * @param imageTargetMapping The URL that maps imageTarget onto a web server
     * @return A Collection of CameraData objects whose URL's have been updated
     *  in the database. (Returns the udpated instance)
     */
    public Collection<CameraData> updateCameraDataUrls(VideoArchive videoArchive, File imageTarget, URL imageTargetMapping) throws MalformedURLException {
        Collection<CameraData> cameraDatas = new ArrayList<CameraData>();
        DAO dao = toolBelt.getAnnotationDAOFactory().newDAO();
        dao.startTransaction();
        videoArchive = dao.find(videoArchive);
        Collection<VideoFrame> videoFrames = videoArchive.getVideoFrames();
        URL imageTargetUrl = imageTarget.toURI().toURL();
        String imageTargetExternalForm = imageTargetUrl.toExternalForm();
        for (VideoFrame videoFrame : videoFrames) {
            CameraData cameraData = videoFrame.getCameraData();
            cameraData = dao.find(cameraData);
            String imageReference = cameraData.getImageReference();
            if (imageReference != null && imageReference.startsWith(imageTargetExternalForm)) {
                URL imageReferenceURL = new URL(imageReference);
                File imageReferenceFile = URLUtilities.toFile(imageReferenceURL);
                URL newUrl = fileToUrl(imageReferenceFile, imageTarget, imageTargetMapping);
                cameraData.setImageReference(newUrl.toExternalForm());
                cameraDatas.add(cameraData);
            }
        }
        dao.endTransaction();
        dao.close();
        return cameraDatas;
    }

    /**
     * Creates a URL of [image.archive.url]/[platform]/images/[dive]/filename from
     * a file of [image.archive.dir]/[platform]/images/[dive]/filename
     *
     * @param  targetFile The File where the image that an image was copied to.
     * @return  The URL that corresponds to the File targetFile.
     * @exception  IllegalArgumentException Description of the Exception
     * @throws  MalformedURLException
     */
    URL fileToUrl(final File targetFile, final File imageTarget, final URL imageTargetMapping) throws IllegalArgumentException, MalformedURLException {

        // ---- Ensure that the file provided is located under the image archive directory
        String targetPath = targetFile.getAbsolutePath();
        final String rootPath = imageTarget.getAbsolutePath();
        if (!targetPath.startsWith(rootPath)) {
            throw new IllegalArgumentException("The file, " + targetPath +
                                               ", is not located in the expected location, " + rootPath);
        }

        // Chop off the part of the path that matches the image target
        // e.g. /Target/MyDir with an image of /Target/MyDir/images/Tiburon/foo.png
        // would yield a postfix of /images/Tiburon/foo.png
        String postfix = targetPath.substring(rootPath.length(), targetPath.length());
        final String[] parts = postfix.split("[\\\\\\\\,/]");
        StringBuffer dstUrl = new StringBuffer(imageTargetMapping.toExternalForm());

        // Make sure the URL ends with "/"
        if (!dstUrl.toString().endsWith("/")) {
            dstUrl.append("/");
        }

        // Chain the parts into a new URL
        boolean b = false; // Don't add "/" on the first loop iteration. It's already in the URL
        for (int i = 0; i < parts.length; i++) {
            if (!"".equals(parts[i])) {
                if (b) {
                    dstUrl.append("/");
                }

                dstUrl.append(parts[i]);
                b = true;
            }
        }

        String dstUrlString = dstUrl.toString().replaceAll(" ", "%20");    // Space break things

        URL out = null;
        try {
            out = new URL(dstUrlString);
        }
        catch (Exception e) {
            if (log.isWarnEnabled()) {
                log.warn("Strings in Java suck!!!", e);
            }
        }

        return out;
    }

    /**
     *
     * @param observations
     */
    public void updateUI(final Collection<Observation> observations) {
        updateUI(observations, true);
    }

    /**
     * Updates the observations in the UI. Uses a flag to indicate if the
     * selected rows should be adjusted.
     * 
     * @param observations
     * @param updateSelection true = reselect rows, false = don't make any adjustments
     *  to selections (useful when you know none of the rows were selected)
     */
    public void updateUI(final Collection<Observation> observations, final boolean updateSelection) {

        Runnable runnable = new Runnable() {

            public void run() {

                // Get the TableModel
                final ObservationTable observationTable = (ObservationTable) Lookup.getObservationTableDispatcher().getValueObject();
                final JTable table = (JTable) observationTable;
                if (observationTable == null) {
                    log.info("No UI is available to update");
                    return;
                }

                final ObservationTableModel model = (ObservationTableModel) table.getModel();
                
                for (Observation observation : observations) {
                    int row = model.getObservationRow(observation);
                    if ((row > -1) && (row < model.getRowCount())) {
                        observationTable.updateObservation(observation);
                    }
                    else {
                        observationTable.addObservation(observation);
                        row = model.getObservationRow(observation);

                        if ((row > -1) && (row < model.getRowCount())) {
                            
                            observationTable.scrollToVisible(row, 0);
                        }
                    }
                }

                /*
                 * We need to keep the RowEditorPanel in sync. Doing this
                 * explicitly is probably best to avoid weird unintended UI
                 * side-effects.
                 */
                AnnotationFrame annotationFrame = (AnnotationFrame) Lookup.getApplicationFrameDispatcher().getValueObject();
                RowEditorPanel rowEditorPanel = annotationFrame.getRowEditorPanel();
                Observation reObservation = rowEditorPanel.getObservation();
                if (reObservation != null) {
                    DAO dao = toolBelt.getAnnotationDAOFactory().newDAO();
                    for (Observation obs : observations) {
                        if (dao.equalInDatastore(reObservation, obs)) {
                            rowEditorPanel.setObservation(obs);
                            break;
                        }
                    }
                    dao.close();
                }

                if (updateSelection) {
                    Collection<Observation> selectedObservations = (Collection<Observation>) Lookup.getSelectedObservationsDispatcher().getValueObject();
                    selectedObservations = new ArrayList<Observation>(selectedObservations);    // Copy to avoid thread issues

                    /*
                     * If we just added one select it in the table
                     */
                    if (observations.size() == 1) {
                        final Observation observation = observations.iterator().next();
                        observationTable.setSelectedObservation(observation);
                    }
                    else {
                        ListSelectionModel lsm = table.getSelectionModel();
                        lsm.clearSelection();

                        for (Observation observation : selectedObservations) {
                            int row = model.getObservationRow(observation);
                            lsm.addSelectionInterval(row, row);
                        }

                    }
                }

            }
        };

        /*
         * Execute on the proper thread.
         */
        if (SwingUtilities.isEventDispatchThread()) {
            runnable.run();
        }
        else {
            try {
                SwingUtilities.invokeAndWait(runnable);
            } catch (Exception ex) {
                log.warn("Failed to excecute updateUI() method on EDT", ex);
            }
        }

    }

    /**
     *
     * @param videoArchive
     */
    public void updateUI(VideoArchive videoArchive) {

        // Get the TableModel
        final ObservationTable observationTable = (ObservationTable) Lookup.getObservationTableDispatcher().getValueObject();
        if (observationTable == null) {
            log.info("No UI is available to update");
            return;
        }

        Runnable runnable = new Runnable() {

            public void run() {
                JTable table = observationTable.getJTable();
                table.getSelectionModel().clearSelection();

                // Remove the current contents of the table
                final ObservationTableModel model = (ObservationTableModel) ((JTable) observationTable).getModel();
                model.clear();

            }
        };

        /*
         * Clear the table on the proper thread
         */
        if (SwingUtilities.isEventDispatchThread()) {
            runnable.run();
        }
        else {
            try {
                SwingUtilities.invokeAndWait(runnable);
            } catch (Exception ex) {
                log.warn("Failed to clear tabel model", ex);
            }
        }


        Collection<Observation> observations = new ArrayList<Observation>();

        // Repopulate it with the contents of the new VideoArchive
        if (videoArchive != null) {

            // DAOTX - Needed to deal with lazy loading
            DAO dao = toolBelt.getAnnotationDAOFactory().newDAO();
            dao.startTransaction();
            videoArchive = dao.find(videoArchive);

            final Collection<VideoFrame> videoFrames = videoArchive.getVideoFrames();
            for (VideoFrame videoFrame : videoFrames) {
                observations.addAll(videoFrame.getObservations());
            }

            dao.endTransaction();
            dao.close();

            updateUI(observations, false);
        }
    }

    /**
     * Bascially a UI refresh using the currently open videoArchive. Scrolls to the currently open
     * visible rectangle.
     */
    public void updateUI() {

         // Get the TableModel
        final ObservationTable observationTable = (ObservationTable) Lookup.getObservationTableDispatcher().getValueObject();
        if (observationTable == null) {
            log.info("No UI is available to update");
            return;
        }
        final JTable table = observationTable.getJTable();
        final Rectangle rect = table.getVisibleRect();
        VideoArchive videoArchive = (VideoArchive) Lookup.getVideoArchiveDispatcher().getValueObject();
        updateUI(videoArchive);
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // When observations are deleted the table would jump to the last row UNLESS
                // we make this call which mostly preserves the current view. Doing this still
                // makes a little visible 'jump' but it takes the user back to about the same
                // position in the table
                table.scrollRectToVisible(rect);
            }
        });
    }

    /**
     *
     * @param videoArchive
     * @return
     */
    public VideoArchive updateVideoArchive(VideoArchive videoArchive) {
        DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();
        videoArchive = dao.merge(videoArchive);
        dao.endTransaction();
        dao.close();
        updateUI();
        return videoArchive;
    }

    /**
     *
     * @param videoArchiveSet
     * @return
     */
    public VideoArchiveSet updateVideoArchiveSet(VideoArchiveSet videoArchiveSet) {
        DAO dao = annotationDAOFactory.newDAO();
        dao.startTransaction();
        videoArchiveSet = dao.merge(videoArchiveSet);
        dao.endTransaction();

        //updateUI(videoArchiveSet);
        return videoArchiveSet;
    }

    /**
     *
     *
     * @param videoFrames
     * @return
     */
    public Collection<VideoFrame> updateVideoFrames(Collection<VideoFrame> videoFrames) {
        ObservationDAO dao = annotationDAOFactory.newObservationDAO();
        final ConceptDAO conceptDAO = toolBelt.getKnowledgebaseDAOFactory().newConceptDAO();
        conceptDAO.startTransaction();
        final Collection<VideoFrame> updatedVideoFrames = new ArrayList<VideoFrame>(videoFrames.size());
        final Collection<Observation> observations = new ArrayList<Observation>();
        dao.startTransaction();

        for (VideoFrame vf : videoFrames) {
            VideoFrame updatedVideoFrame = dao.merge(vf);
            updatedVideoFrames.add(updatedVideoFrame);
            observations.addAll(updatedVideoFrame.getObservations());
        }

        for (Observation observation : observations) {
            dao.validateName(observation, conceptDAO);
        }

        dao.endTransaction();
        dao.close();
        conceptDAO.endTransaction();
        conceptDAO.close();
        updateUI(observations);    // update view
        return updatedVideoFrames;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.