/******************************************************************************** * * * (c) Copyright 2010 Verizon Communications USA and The Open University UK * * * * This software is freely distributed in accordance with * * the GNU Lesser General Public (LGPL) license, version 3 or later * * as published by the Free Software Foundation. * * For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html * * and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html * * * * This software is provided by the copyright holders and contributors "as is" * * and any express or implied warranties, including, but not limited to, the * * implied warranties of merchantability and fitness for a particular purpose * * are disclaimed. In no event shall the copyright owner or contributors be * * liable for any direct, indirect, incidental, special, exemplary, or * * consequential damages (including, but not limited to, procurement of * * substitute goods or services; loss of use, data, or profits; or business * * interruption) however caused and on any theory of liability, whether in * * contract, strict liability, or tort (including negligence or otherwise) * * arising in any way out of the use of this software, even if advised of the * * possibility of such damage. * * * ********************************************************************************/ package com.compendium.core.datamodel; import java.sql.SQLException; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.compendium.core.datamodel.services.IViewService; /** * The View object is a node that represents a collection of nodes and links with related timespans. * The visual representation of the nodes and links depends on the type of the view. * * @author Michelle Bachler */ public class TimeMapView extends View implements java.io.Serializable { /** * class's own logger */ final Logger log = LoggerFactory.getLogger(getClass()); /** * */ private static final long serialVersionUID = 1L; /** time added property name for use with property change events */ public final static String TIME_ADDED_PROPERTY = "timeadded"; /** time removed property name for use with property change events */ public final static String TIME_REMOVED_PROPERTY = "timeremoved"; /** time changed property name for use with property change events */ public final static String TIME_CHANGED_PROPERTY = "timechanged"; /** A List of all the time spans for this node. */ protected Hashtable htMemberNodeTimes = new Hashtable(51); /** * Constructor, takes in only the id value. * * @param sNodeID String, the id of the view object. */ public TimeMapView(String sNodeID) { super(sNodeID); } /** * Constructor, creates a TimeMapView object. * * @param String sViewID, the id of the view node. * @param nType int, the type of this node. * @param sXNodeType String, the extended node type id of the node - NOT CURRENTLY USED. * @param sOriginalID String, the original id of the node if it was imported. * @param sAuthor String, the author of this node. * @param dCreationDate Date, the creation date of this node. * @param dModificationDate Date, the date the node was last modified. */ protected TimeMapView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail) { super( sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); } /** * Constructor, creates a TimeMapView object. * * @param String sViewID, the id of the view node. * @param int nType, the type of this node. * @param String sXNodeType, the extended node type id of the node - NOT CURRENTLY USED. * @param String sOriginalID, the original id of the node if it was imported. * @param int nPermission, the permissions in this node - NOT CURRENTLY USED. * @param int nState, the state of this node: not read (0) read (1), modified since last read (2). * @param String sAuthor, the author of the node. * @param Date dCreationDate, the creation date of this node. * @param Date dModificationDate, the date the node was last modified. * @param String sLabel, the label of this node. * @param String sDetail, the first page of detail for this node. */ protected TimeMapView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nPermission, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail) { super(sViewID, nType, sXNodeType, sOriginalID, nPermission, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); } /** * Constructor, creates a TimeMapView object. * * @param String sViewID, the id of the view node. * @param nType int, the type of this node. * @param sXNodeType String, the extended node type id of the node - NOT CURRENTLY USED. * @param sOriginalID String, the original id of the node if it was imported. * @param sAuthor String, the author of this node. * @param dCreationDate Date, the creation date of this node. * @param dModificationDate Date, the date the node was last modified. * @param sLastModAuthor the author who last modified this object.* */ protected TimeMapView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail, String sLastModAuthor) { super( sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail, sLastModAuthor); } /** * Constructor, creates a TimeMapView object. * * @param sViewID the id of the view node. * @param nType the type of this node. * @param sXNodeType the extended node type id of the node - NOT CURRENTLY USED. * @param sOriginalID the original id of the node if it was imported. * @param nPermission the permissions in this node - NOT CURRENTLY USED. * @param nState the state of this node: not read (0) read (1), modified since last read (2). * @param sAuthor the author of the node. * @param dCreationDate the creation date of this node. * @param dModificationDate the date the node was last modified. * @param sLabel the label of this node. * @param sDetail the first page of detail for this node. * @param sLastModAuthor the author who last modified this object. */ protected TimeMapView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nPermission, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail, String sLastModAuthor) { super(sViewID, nType, sXNodeType, sOriginalID, nPermission, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail, sLastModAuthor); } /** * Return a TimeMapView object with the given id. * If a view node with the given id has already been created in this session, return that, * else create a new one, and add it to the list. * * @param String id, the id of the node to return/create. * @return View, a view node object with the given id. */ public static TimeMapView getView(String id) { int i = 0; Vector nodeSummaryList = NodeSummary.getNodeSummaryList(); for (i = 0; i < nodeSummaryList.size(); i++) { if (id.equals(((NodeSummary)nodeSummaryList.elementAt(i)).getId())) { break; } } TimeMapView ns = null; if (i == nodeSummaryList.size()) { ns = new TimeMapView(id); nodeSummaryList.addElement(ns); } else { Object obj = nodeSummaryList.elementAt(i); if (obj instanceof TimeMapView) { ns = (TimeMapView)obj; } else { nodeSummaryList.removeElement(obj); ns = new TimeMapView(id); nodeSummaryList.addElement(ns); } } return ns; } /** * Return a TimeMapView object with the given id and details. * If a view node with the given id has already been created in this session, update its data and return that, * else create a new one, and add it to the list. * * @param String sViewID, the id of the view node. * @param int nType, the type of this node. * @param String sXNodeType, the extended node type id of the node - NOT CURRENTLY USED. * @param String sOriginalID, the original id of the node if it was imported. * @param String sAuthor, the author of the node. * @param Date dCreationDate, the creation date of this node. * @param Date dModificationDate, the date the node was last modified. * @param String sLabel, the label of this node. * @param String sDetail, the first page of detail for this node. * @return View, a view node object with the given id. */ public static TimeMapView getView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail) { int i = 0; Vector nodeSummaryList = NodeSummary.getNodeSummaryList(); for (i = 0; i < nodeSummaryList.size(); i++) { if (sViewID.equals(((NodeSummary)nodeSummaryList.elementAt(i)).getId())) { break; } } TimeMapView ns = null; if (i == nodeSummaryList.size()) { ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); nodeSummaryList.addElement(ns); } else { Object obj = nodeSummaryList.elementAt(i); if (obj instanceof TimeMapView) { ns = (TimeMapView)obj; // UPDATE THE DETAILS if (!ns.bLabelDirty) { ns.setLabelLocal(sLabel); } ns.setDetailLocal(sDetail); ns.setTypeLocal(nType); ns.setStateLocal(nState); ns.setAuthorLocal(sAuthor); ns.setCreationDateLocal(dCreationDate); ns.setModificationDateLocal(dModificationDate); ns.setOriginalIdLocal(sOriginalID); ns.setExtendedNodeTypeLocal(sXNodeType); } else { nodeSummaryList.removeElement(obj); ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); nodeSummaryList.addElement(ns); } } return ns; } /** * Return a TimeMapView object with the given id and details. * If a view node with the given id has already been created in this session, update its data and return that, * else create a new one, and add it to the list. * * @param sViewID the id of the view node. * @param nType the type of this node. * @param sXNodeType the extended node type id of the node - NOT CURRENTLY USED. * @param sOriginalID the original id of the node if it was imported. * @param sAuthor the author of the node. * @param dCreationDate the creation date of this node. * @param dModificationDate the date the node was last modified. * @param sLabel the label of this node. * @param sDetail the first page of detail for this node. * @param sLastModAuthor the author who last modified this object. * @return View, a view node object with the given id. */ public static TimeMapView getView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail, String sLastModAuthor) { int i = 0; Vector nodeSummaryList = NodeSummary.getNodeSummaryList(); for (i = 0; i < nodeSummaryList.size(); i++) { if (sViewID.equals(((NodeSummary)nodeSummaryList.elementAt(i)).getId())) { break; } } TimeMapView ns = null; if (i == nodeSummaryList.size()) { ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail, sLastModAuthor); nodeSummaryList.addElement(ns); } else { Object obj = nodeSummaryList.elementAt(i); if (obj instanceof TimeMapView) { ns = (TimeMapView)obj; // UPDATE THE DETAILS if (!ns.bLabelDirty) { ns.setLabelLocal(sLabel); } ns.setDetailLocal(sDetail); ns.setTypeLocal(nType); ns.setStateLocal(nState); ns.setAuthorLocal(sAuthor); ns.setCreationDateLocal(dCreationDate); ns.setModificationDateLocal(dModificationDate); ns.setOriginalIdLocal(sOriginalID); ns.setExtendedNodeTypeLocal(sXNodeType); ns.setLastModificationAuthorLocal(sLastModAuthor); } else { nodeSummaryList.removeElement(obj); ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); nodeSummaryList.addElement(ns); } } return ns; } /** * Return a TimeMapView object with the given id and details. * If a view node with the given id has already been created in this session, update its data and return that, * else create a new one, and add it to the list. * * @param String sViewID, the id of the view node. * @param int nType, the type of this node. * @param String sXNodeType, the extended node type id of the node - NOT CURRENTLY USED. * @param String sOriginalID, the original id of the node if it was imported. * @param int nPermission, the permissions in this node - NOT CURRENTLY USED. * @param int nState, the state of this node: not read (0) read (1), modified since last read (/2). * @param String sAuthor, the author of the node. * @param Date dCreationDate, the creation date of this node. * @param Date dModificationDate, the date the node was last modified. * @param String sLabel, the label of this node. * @param String sDetail, the first page of detail for this node. * @return View, a view node object with the given id. */ public static TimeMapView getView(String sViewID, int nType, String sXNodeType, String sOriginalID, int nPermission, int nState, String sAuthor, Date dCreationDate, Date dModificationDate, String sLabel, String sDetail) { int i = 0; Vector nodeSummaryList = NodeSummary.getNodeSummaryList(); for (i = 0; i < nodeSummaryList.size(); i++) { if (sViewID.equals(((NodeSummary)nodeSummaryList.elementAt(i)).getId())) { break; } } TimeMapView ns = null; if (i == nodeSummaryList.size()) { ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nPermission, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); nodeSummaryList.addElement(ns); } else { Object obj = nodeSummaryList.elementAt(i); if (obj instanceof TimeMapView) { ns = (TimeMapView)obj; // UPDATE THE DETAILS if (!ns.bLabelDirty) { ns.setLabelLocal(sLabel); } ns.setDetailLocal(sDetail); ns.setTypeLocal(nType); ns.setAuthorLocal(sAuthor); ns.setCreationDateLocal(dCreationDate); ns.setModificationDateLocal(dModificationDate); ns.setOriginalIdLocal(sOriginalID); ns.setExtendedNodeTypeLocal(sXNodeType); ns.setPermissionLocal(nPermission); ns.setStateLocal(nState); } else { nodeSummaryList.removeElement(obj); ns = new TimeMapView(sViewID, nType, sXNodeType, sOriginalID, nPermission, nState, sAuthor, dCreationDate, dModificationDate, sLabel, sDetail); nodeSummaryList.addElement(ns); } } return ns; } /** * Override. * Loads all the nodes and node times and links into this view from the DATABASE. * * @exception java.sql.SQLException * @exception ModelSessionException */ public void initializeMembers() throws SQLException, ModelSessionException { if (!bMembersInitialized) { if (oModel == null) throw new ModelSessionException("Model is null in View.initializeMembers"); if (oSession == null) { oSession = oModel.getSession(); if (oSession == null) throw new ModelSessionException("Session is null in View.initializeMembers"); } super.initializeMembers(); bMembersInitialized = false; Vector vtNodeTimes = oModel.getViewService().getNodeTimes(oModel.getSession(), this.getId()); for(Enumeration e = vtNodeTimes.elements(); e.hasMoreElements();) { NodePositionTime nodeTime = (NodePositionTime)e.nextElement(); nodeTime.initialize(oModel.getSession(), oModel); NodeSummary node1 = nodeTime.getNode(); int xPos = nodeTime.getXPos(); int yPos = nodeTime.getYPos(); nodeTime.setView(this); if (htMemberNodeTimes.containsKey(node1.getId())){ Hashtable times = (Hashtable)htMemberNodeTimes.get(node1.getId()); times.put(nodeTime.getId(), nodeTime); htMemberNodeTimes.put(node1.getId(), times); } else { Hashtable times = new Hashtable(); times.put(nodeTime.getId(), nodeTime); htMemberNodeTimes.put(node1.getId(), times); } node1.initialize(oModel.getSession(), oModel); } } bMembersInitialized = true; } /** * Clear all data associated with this View and reloads it from scratch from the database. * * @exception java.sql.SQLException * @exception ModelSessionException * */ public void reloadViewData() throws SQLException, ModelSessionException { this.htMemberNodeTimes.clear(); super.reloadViewData(); } /** * Get the Hashtable of <code>NodePositionTime</code>objects for the given node id * @param sNodeID the node id to return the time points for * @return Hashtable of NodePositionTime objects for the given node id */ public Hashtable<String, NodePositionTime> getTimesForNode(String sNodeID) { if (this.htMemberNodeTimes.containsKey(sNodeID)) { return (Hashtable<String, NodePositionTime>)htMemberNodeTimes.get(sNodeID); } return new Hashtable<String, NodePositionTime>(0); } /** * Adds a new node time span to the given node, both locally and in the DATABASE. * * @param sNodeID the id of the node to add the time record for * @param nShow the time (in milliseconds) to show the node * @param nHide the time (in milliseconds) to hide the node * @param x The X coordinate of the node in the view * @param y The Y coordinate of the node in the view * @return the NodePositionTime object if the node was successfully added, otherwise null. * @exception java.sql.SQLException * @exception ModelSessionException */ public NodePositionTime addNodeTime(String sNodeID, long nShow, long nHide, int x, int y) throws SQLException, ModelSessionException { if (oModel == null) throw new ModelSessionException("Model is null in View.addMemberNode-2"); if (oSession == null) { oSession = oModel.getSession(); if (oSession == null) throw new ModelSessionException("Session is null in View.addMemberNode-2"); } //Create the NodePositionTime in the ViewTimeNode table IViewService vs = getModel().getViewService(); String sViewTimeNodeID = oModel.getUniqueID(); NodePositionTime nodeTime = vs.addNodeTime(oModel.getSession(), sViewTimeNodeID, this, getNode(sNodeID), nShow, nHide, x , y); //Local Hashtable update if (htMemberNodeTimes.containsKey(sNodeID)){ Hashtable times = (Hashtable)htMemberNodeTimes.get(sNodeID); times.put(sViewTimeNodeID, nodeTime); htMemberNodeTimes.put(sNodeID, times); } else { Hashtable<String, NodePositionTime> times = new Hashtable<String, NodePositionTime>(); times.put(sViewTimeNodeID, nodeTime); htMemberNodeTimes.put(sNodeID, times); } firePropertyChange(TIME_ADDED_PROPERTY, nodeTime, nodeTime); return nodeTime; } /** * Update a node time span, both locally and in the DATABASE. * * @param sViewTimeNodeID the id of the time point to update * @param sNodeID the id of the node to add the time record for * @param nShow the time (in milliseconds) to show the node * @param nHide the time (in milliseconds) to hide the node * @param x The X coordinate of the node in the view * @param y The Y coordinate of the node in the view * @return the NodePositionTime object if the node was successfully updated, otherwise null. * @exception java.sql.SQLException * @exception ModelSessionException */ public NodePositionTime updateNodeTime(String sViewTimeNodeID, String sNodeID, long nShow, long nHide, int x, int y) throws SQLException, ModelSessionException { if (oModel == null) throw new ModelSessionException("Model is null in View.addMemberNode-2"); if (oSession == null) { oSession = oModel.getSession(); if (oSession == null) throw new ModelSessionException("Session is null in View.addMemberNode-2"); } //Create the NodePositionTime in the ViewTimeNode table IViewService vs = getModel().getViewService(); NodePositionTime nodeTime = vs.updateNodeTime(oModel.getSession(), sViewTimeNodeID, this, getNode(sNodeID), nShow, nHide, x , y); NodePositionTime oldPos = null; //Replace if (htMemberNodeTimes.containsKey(sNodeID)){ Hashtable times = (Hashtable)htMemberNodeTimes.get(sNodeID); oldPos = (NodePositionTime)times.get(sViewTimeNodeID); times.put(sViewTimeNodeID, nodeTime); htMemberNodeTimes.put(sNodeID, times); } else { Hashtable times = new Hashtable(); times.put(sViewTimeNodeID, nodeTime); htMemberNodeTimes.put(sNodeID, times); } firePropertyChange(TIME_CHANGED_PROPERTY, oldPos, nodeTime); return nodeTime; } /** * Delete a node time span from the given node, both locally and in the DATABASE. * * @param sViewTimeNodeID the id of the time point to delete * @param sNodeID the id of the node to add the time record for * @exception java.sql.SQLException * @exception ModelSessionException */ public void deleteNodeTime(String sViewTimeNodeID, String sNodeID) throws SQLException, ModelSessionException { if (oModel == null) throw new ModelSessionException("Model is null in View.addMemberNode-2"); if (oSession == null) { oSession = oModel.getSession(); if (oSession == null) throw new ModelSessionException("Session is null in View.addMemberNode-2"); } IViewService vs = getModel().getViewService(); vs.deleteNodeTime(oModel.getSession(), sViewTimeNodeID); //Local Hashtable update if (htMemberNodeTimes.containsKey(sNodeID)){ Hashtable times = (Hashtable)htMemberNodeTimes.get(sNodeID); times.remove(sViewTimeNodeID); } firePropertyChange(TIME_REMOVED_PROPERTY, sViewTimeNodeID, sViewTimeNodeID); } /** * Clear all the node time data as well as call super to clear nodes and links etc. * * @exception java.sql.SQLException * @exception ModelSessionException */ public void clearViewForTypeChange() throws SQLException, ModelSessionException { clearTimes(); super.clearViewForTypeChange(); } /** * Clear all the node time data. (used for node type change) * * @exception java.sql.SQLException * @exception ModelSessionException */ public void clearTimes() throws SQLException, ModelSessionException { // delete the associated node times before nodes removed Hashtable<String, NodePositionTime> times = null; NodePositionTime item = null; for (Enumeration e = getPositions(); e.hasMoreElements();) { NodePosition pos = (NodePosition)e.nextElement(); times = getTimesForNode(pos.getNode().getId()); for (Enumeration time = times.elements(); e.hasMoreElements();) { item = (NodePositionTime)time.nextElement(); deleteNodeTime(item.getId(), pos.getNode().getId()); } } } }