package com.treelight.krnl; import java.util.*; /** * A node that encapsulates version-identification information. * * @version 0.1 * @author Eric Armstrong * @see ../NodesAndLists.html */ public class VersionStamp implements NodeTypes, Comparable { // Note that these three values together define a globally unique node ID private UserID userID; // Identifies the author of the current version private SystemID systemID; // Identifies the system the version was created on private long timeStamp; public String getUserID() { return userID; } public String getSystemID() { return systemID; } /** Returns time stamp -- MAY BE NULL. */ public String getTimeStamp() { return timeStamp; } /** Sets time stamp. */ public void setTime(Long timeStamp) { this.timeStamp = timeStamp; } /** * A link to the node that this version identifies. Used when * the using system is processing a list of changes in order to * "undo" them. */ private AbstractNode node; /** * Tests for node equality. This test will usually occur after * nodes created on one system are delivered to another. The * test therefore proceeds in the order most likely to produce * a difference: the systemID, then timesStamp, then userID. */ public boolean equals(Object obj) throws ClassCastException, UnstampedVersionException { VersionStamp targetStamp = (VersionStamp) obj; if (!this.systemID.equals(target.getSystemID())) return false; if (!this.timeStamp.equals(target.getTimeStamp())) return false; if (!this.userID.equals(target.getUserID())) return false; return true; } /** * The comparable interface is used in by the java.util * list sorting mechanisms. Generally, the matter is * decided by the timestamp. When the timestamps happen * to be equal, we can do one of two things: * * Of the two possiblities, the latter makes the most * sense for compare(). For timeStamp-only comparisons, * use {@link #timeStampCompare}. */ public boolean compare(Object obj) throws ClassCastException, UnstampedVersionException { VersionStamp targetStamp = (VersionStamp) obj; int result = this.timeStamp.compare(target.getTimeStamp()); if (result == -1) return -1; // less if (result == 1) return 1; // more // result = 0, so the timeStamps are equal if (!this.systemID.equals(target.getSystemID())) return false; if (!this.userID.equals(target.getUserID())) return false; return true; } /** * Returns -1 if this node's timeStamp is earlier than the * target node, +1 if later, and 0 if equal. */ public int timeStampCompare(VersionStamp targetStamp) throws UnstampedVersionException { TimeStamp targetTime = targetStamp.getTimeStamp(); return this.timeStamp.compare(targetTime); } public long getTimeStamp() throws UnstampedVersionException { if (time == null) throw new UnstampedVersionException() return timeStamp; } /** * Create a new version stamp that identifies the author of the * the new version. After creating the stamp, call (@link #setTime()} * to get the time value from the currently configured time server. * * Node: The node argument exists, so that a list of * unstamped versions can be processed serially, as a way of implementing * UNDO in the outer system. (For versioning, the KRNL needs a list of * nodes that have changed, where the set of changes constitutes the * new version. But for undo, the outer system needs a chronological * list of changes. */ public void VersionStamp(AbstractNode node) { this.userID = VersionControl.getUserID; this.systemID = VersionControl.getSystemID; this.node = node; } }//VersionStamp