From 7f2c1a6d53b51d2975a43155450358cde581eedc Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Wed, 6 Jan 2010 09:57:17 -0600 Subject: [PATCH] Added documentation, fleshed out accessors for class Timeline. --- .hgignore | 1 + CHANGE ME | Bin 0 -> 1241 bytes doc/uml.tsm | Bin 0 -> 19831 bytes .../TimeStamperMainController.groovy | 17 ++-- .../timestamper/TimeStamperMainModel.groovy | 2 +- .../timestamper/core/SyncTarget.java | 23 ++--- .../jdbernard/timestamper/core/Timeline.java | 85 ++++++++++++------ .../timestamper/core/TimelineProperties.java | 68 ++++++++++---- .../timestamper/core/TimelineSource.java | 29 +++++- 9 files changed, 160 insertions(+), 65 deletions(-) create mode 100644 CHANGE ME create mode 100644 doc/uml.tsm diff --git a/.hgignore b/.hgignore index bdc021c..390fc33 100755 --- a/.hgignore +++ b/.hgignore @@ -1,3 +1,4 @@ .*.swp .*.swo staging +dist diff --git a/CHANGE ME b/CHANGE ME new file mode 100644 index 0000000000000000000000000000000000000000..325d8bdd3e4b826a2e2c09f2e30d15900f112235 GIT binary patch literal 1241 zcmezO_TO6u1_mY|W&~r-i%F1? zk(Gg^iLpF0{KJQ7P8#aJRhayFYP8iOoy!9)W>a~@=vu-%P z^lfk1M>o;#??2iMUq0{bXiAghSp8{s&5yb7E`LhsPr817``e%w1(#00T=mo=t5u`= z&5VE@7eD2;b~MWd%uN-avdwClt-sG*pKqa(kM7O474kd%?D(CScX|^}O)6x36j`?S z+cVRrYT%(S%pJVOx! zA&>~SFt zSHUm8L?JD|NFksoKczIeBr`wHKu(<3z|zpj$kNcv$k@;*N}Siwz`z*JrH2!m7N2*-|0Rp!;5P^xiyq{!MUukj;A+hQo694ch|MGF@XGlmdT8 z+V)2L+JE%xE`x8UXNTroZ?tZZHOc>!masj0X28-V^XI={sTNQ=zp_2;W&bW&Q47RfIql8MN+;$m zuIK)xXqxo#cTyFjiuIW#ANQ>YoY1+V`ToPGr}Nn+b*IHOREMgjF#1^kJMXE*+}O$h za>s&)KR2E`8j!cIN8{qMIcr~v+kZX$zIf*YuD4##7N(q+vvht}zS~btGS^Hdan--I z0qt+LZN4k{w()uB+1;GyUR(S)-1>J~tB{Y}eZIyeXWZ*LPCZgIO~}8bGw(y>)WgrK zuJ7Ng+*9l*5wdlnGzVAf!}Iy?OucpoMLsQGv{(B7)!8V?m06#`K!-_$n~6_3@Z60k z2Ze2uJFcr<%+T8|%Ov9dy<=+CA=eu(EjP+>ihFXk&Xrb-30}LRlhapJ@}1Z>Hbtkr IJ5~G30nh#gv;Y7A literal 0 HcmV?d00001 diff --git a/doc/uml.tsm b/doc/uml.tsm new file mode 100644 index 0000000000000000000000000000000000000000..a725ebdbb3e8164d34d4741c75ef3bbe5b31396a GIT binary patch literal 19831 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 LONB^Zf-CU<9u~}3 literal 0 HcmV?d00001 diff --git a/griffon-app/controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy b/griffon-app/controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy index 7cd5c83..149654b 100644 --- a/griffon-app/controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy +++ b/griffon-app/controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy @@ -8,8 +8,12 @@ class TimeStamperMainController { def model def view + def syncTimers = [:] + void mvcGroupInit(Map args) { + def configFile + logger.traceIfEnabled("Initializing TimeStamperMain MVC...") def thisMVC = ['model': model, 'view': view, 'controller': this] @@ -23,13 +27,13 @@ class TimeStamperMainController { // load application properties Properties prop = new Properties() String userHomeDir = System.getProperty('user.home') - model.configFile = new File(userHomeDir, ".timestamperrc") - if (!model.configFile.exists()) model.configFile.createNewFile() + configFile = new File(userHomeDir, ".timestamperrc") + if (!configFile.exists()) configFile.createNewFile() logger.traceIfEnabled("Reading configuration from " - + "'${model.configFile.name}'") + + "'${configFile.name}'") - try { model.configFile.withInputStream { prop.load(it) } } + try { configFile.withInputStream { prop.load(it) } } catch (IOException ioe) { logger.error('Unable to load configuration', ioe) } @@ -45,8 +49,9 @@ class TimeStamperMainController { logger.traceIfEnabled("Reading Timeline properties from '${lastUsed}'") - File propertyFile = new File(lastUsed) - if (!propertyFile.exists()) propertyFile.createNewFile() + model.timelinePropertiesFile = new File(lastUsed) + if (!model.timelinePropertiesFile.exists()) + model.timelinePropertiesFile.createNewFile() load(propertyFile) } diff --git a/griffon-app/models/com/jdbernard/timestamper/TimeStamperMainModel.groovy b/griffon-app/models/com/jdbernard/timestamper/TimeStamperMainModel.groovy index 68eb731..b3a2f84 100644 --- a/griffon-app/models/com/jdbernard/timestamper/TimeStamperMainModel.groovy +++ b/griffon-app/models/com/jdbernard/timestamper/TimeStamperMainModel.groovy @@ -13,7 +13,7 @@ class TimeStamperMainModel { @Bindable Timeline timeline @Bindable TimelineProperties timelineProperties Properties config - File configFile + File timelinePropertiesFile def notesDialogMVC def punchcardDialogMVC diff --git a/src/main/com/jdbernard/timestamper/core/SyncTarget.java b/src/main/com/jdbernard/timestamper/core/SyncTarget.java index 5489545..b7b07c8 100755 --- a/src/main/com/jdbernard/timestamper/core/SyncTarget.java +++ b/src/main/com/jdbernard/timestamper/core/SyncTarget.java @@ -6,8 +6,8 @@ import java.util.Timer; import java.util.TimerTask; /** - * - * @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com}) + * A remote target synchronized against the local timeline. + * @author Jonathan Bernard (jonathan.bernard@gemalto.com) */ public class SyncTarget { @@ -23,6 +23,9 @@ public class SyncTarget { protected boolean pullEnabled = true; protected boolean syncOnExit = true; + /** + * + */ protected class SyncTask extends TimerTask { @Override public void run() { synchronized(this) { @@ -109,21 +112,21 @@ public class SyncTarget { public long getSyncInterval() { return syncInterval; } - public synchronized void enablePush(boolean enablePush) { - this.pullEnabled = enablePush; + public synchronized void setPushEnabled(boolean pushEnabled) { + this.pullEnabled = pushEnabled; } - public boolean isPushEnabled() { return pushEnabled; } + public boolean getPushEnabled() { return pushEnabled; } - public synchronized void enablePull(boolean enablePull) { - this.pullEnabled = enablePull; + public synchronized void setPullEnabled(boolean pullEnabled) { + this.pullEnabled = pullEnabled; } - public boolean isPullEnabled() { return pullEnabled; } + public boolean getPullEnabled() { return pullEnabled; } - public synchronized void enableSyncOnExit(boolean syncOnExit) { + public synchronized void setSyncOnExit(boolean syncOnExit) { this.syncOnExit = syncOnExit; } - public boolean isSyncOnExitEnabled() { return syncOnExit; } + public boolean getSyncOnExit() { return syncOnExit; } } diff --git a/src/main/com/jdbernard/timestamper/core/Timeline.java b/src/main/com/jdbernard/timestamper/core/Timeline.java index 17c828f..4fd6c93 100755 --- a/src/main/com/jdbernard/timestamper/core/Timeline.java +++ b/src/main/com/jdbernard/timestamper/core/Timeline.java @@ -8,10 +8,11 @@ import java.util.Iterator; import java.util.TreeSet; /** - * @author Jonathan Bernard {@literal } * A Timeline object represents a series of markers at specific points in time. - * The markers have a name or symbol (the 'mark') and notes associated with that - * mark. + * It represents on logical timeline. The markers have a name or symbol (the + * 'mark') and notes associated with that mark. + * @author Jonathan Bernard {@literal } + * @see com.jdbernard.timestamper.core.TimelineSource */ public class Timeline implements Iterable { @@ -19,31 +20,39 @@ public class Timeline implements Iterable { public static SimpleDateFormat longFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); private TreeSet timelineList; + /** + * Create a new, empty Timeline. + */ public Timeline() { timelineList = new TreeSet(); } - public void addMarker(TimelineMarker tm) { timelineList.add(tm); } + /** + * Add a marker to the timeline. + * @param tm The TimelineMarker to add. + * @return true if this Timeline was modified. + */ + public boolean addMarker(TimelineMarker tm) { return timelineList.add(tm); } - public void addMarker(Date timestamp, String name, String notes) { - timelineList.add(new TimelineMarker(timestamp, name, notes)); - } - - public String getLastName(Date timestamp) { - TimelineMarker lastMarker = getLastMarker(timestamp); - return (lastMarker == null ? - "No previous marker." : - lastMarker.getMark()); - - } - - public String getLastNotes(Date timestamp) { - TimelineMarker lastMarker = getLastMarker(timestamp); - return (lastMarker == null ? - "No previous marker." : - lastMarker.getNotes()); + /** + * Add a marker to the timeline. + * @param timestamp The date and time of the marker. + * @param name The name of the marker (activity, project, etc) + * @param notes Additional notes about this marker. + * @return true if this Timeline was modified. + */ + public boolean addMarker(Date timestamp, String name, String notes) { + return timelineList.add(new TimelineMarker(timestamp, name, notes)); } + /** + * Get the last marker placed before or on the given timestamp. If you + * think of the markers as demarcating time, then this is effectivly, + * "get the current task." + * @param timestamp The cut-off point for the query. + * @return The latest TimelineMarker placed on or before the given + * timestamp. + */ public TimelineMarker getLastMarker(Date timestamp) { TimelineMarker lastMarker = null; for (TimelineMarker tm : timelineList) { @@ -55,8 +64,13 @@ public class Timeline implements Iterable { return lastMarker; } - public void removeMarker(TimelineMarker marker) { - timelineList.remove(marker); + /** + * Remove a TimelineMarker from this Timelnie. + * @param marker The marker to remove. + * @return true if this Timeline was changed. + */ + public boolean removeMarker(TimelineMarker marker) { + return timelineList.remove(marker); } public Iterator iterator() { @@ -84,14 +98,31 @@ public class Timeline implements Iterable { return difference; } - public void addAll(Timeline t) { + /** + * Add all TimelineMarkers from t to this + * Timeline, excluding markers already present in this. + * @param t + * @return true if this Timeline was modified. + */ + public boolean addAll(Timeline t) { + boolean modified = false; for (TimelineMarker tm : t) { - if (!timelineList.contains(tm)) + if (!timelineList.contains(tm)) { timelineList.add(tm); + modified = true; + } } + + return modified; } - public void addAll(Collection c) { - timelineList.addAll(c); + /** + * Add all TimelineMarkers from c to this + * Timeline, excluding markers already present in this. + * @param c A Collection of TimelineMarkers + * @return true if this TImeline was modified. + */ + public boolean addAll(Collection c) { + return timelineList.addAll(c); } } diff --git a/src/main/com/jdbernard/timestamper/core/TimelineProperties.java b/src/main/com/jdbernard/timestamper/core/TimelineProperties.java index bcbd57d..f396394 100755 --- a/src/main/com/jdbernard/timestamper/core/TimelineProperties.java +++ b/src/main/com/jdbernard/timestamper/core/TimelineProperties.java @@ -4,7 +4,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.Collection; @@ -15,8 +17,32 @@ import java.util.regex.Pattern; /** - * + * Represents a Timeline configuration. A configuration has one primary, or + * local, Timeline with an associated TimelineSource, and a list of remote + * Timelines synched to the local Timeline. + *
+ * + * + * + * + * + * + * + * + * + * + *
PropertyDescription
timeline.uriThe URI of the primary (local) + * timeline
remote.timeline.name.uriThe URI for the name remote timeline.
remote.timeline.name.pushtrue to enable pushing updates to the name + * remote timeline, false to disable.
remote.timeline.name.pulltrue to enable pulling updates from the name + * remote timeline, false to disable.
remote.timeline.name.save-on-exit + * true to force sync the name remote + * timeline on exit.
remote.timeline.name + * .update-intervalThe time in milliseconds between + * synching the name remote timeline.
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com}) + * @see com.jdbernard.timestamper.core.Timeline + * @see com.jdbernard.timestamper.core.TimelineSource + * @see com.jdbernard.timestamper.core.SyncTarget */ public class TimelineProperties { @@ -26,13 +52,19 @@ public class TimelineProperties { private static final Pattern remoteTimelinePropPattern = Pattern.compile("\\Q" + REMOTE_TIMELINE_BASE + "\\E([^\\s\\.=]+?)[\\.=].*"); - private File propertyFile; private Timeline timeline; private TimelineSource timelineSource; private LinkedList syncTargets = new LinkedList(); + /** + * Create new TimelineProperties, using default values. This will create + * a new configuration using a FileTimelineSource pointed at + * 'timeline.default.txt' in the current directory and no + * remote Timelines. It will save this configuration to + * 'timeline.default.properties' in the current directory. + */ public TimelineProperties() { - this.propertyFile = new File("timeline.default.properties"); + File propertyFile = new File("timeline.default.properties"); Properties config = new Properties(); File timelineFile = new File("timeline.default.txt"); @@ -53,14 +85,17 @@ public class TimelineProperties { } } - public TimelineProperties(File propertyFile) throws IOException { + /** + * Load TimelineProperties from an InputStream. + * @param is + */ + public TimelineProperties(InputStream is) throws IOException { String strURI; URI timelineURI; - this.propertyFile = propertyFile; Properties config = new Properties(); try { - config.load(new InputStreamReader(new FileInputStream(propertyFile))); + config.load(new InputStreamReader(is)); } catch (IOException ioe) { // TODO } @@ -112,11 +147,11 @@ public class TimelineProperties { syncTargets.add(st); // check for synch options - st.enablePull(Boolean.parseBoolean( + st.setPullEnabled(Boolean.parseBoolean( config.getProperty(remoteBase + ".pull", "true"))); - st.enablePush(Boolean.parseBoolean( + st.setPushEnabled(Boolean.parseBoolean( config.getProperty(remoteBase + ".push", "true"))); - st.enableSyncOnExit(Boolean.parseBoolean( + st.setSyncOnExit(Boolean.parseBoolean( config.getProperty(remoteBase + ".sync-on-exit", "true"))); st.setSyncInterval(Long.parseLong( config.getProperty(remoteBase + ".update-interval", @@ -125,7 +160,7 @@ public class TimelineProperties { } } - public void save() throws IOException { + public void save(OutputStream os) throws IOException { Properties config = new Properties(); timelineSource.persist(timeline); @@ -137,27 +172,22 @@ public class TimelineProperties { config.setProperty(remoteBase + ".uri", st.getSource().getURI().toString()); config.setProperty(remoteBase + ".pull", - Boolean.toString(st.isPullEnabled())); + Boolean.toString(st.getPullEnabled())); config.setProperty(remoteBase + ".push", - Boolean.toString(st.isPushEnabled())); + Boolean.toString(st.getPushEnabled())); config.setProperty(remoteBase + ".sync-on-exit", - Boolean.toString(st.isSyncOnExitEnabled())); + Boolean.toString(st.getSyncOnExit())); config.setProperty(remoteBase + ".update-interval", Long.toString(st.getSyncInterval())); } try { - config.store(new FileOutputStream(propertyFile), ""); + config.store(os, ""); } catch (IOException ioe) { // TODO } } - public void save(File newFile) throws IOException { - propertyFile = newFile; - save(); - } - public Timeline getTimeline() { return timeline; } public void setTimelineSource(TimelineSource newSource) { diff --git a/src/main/com/jdbernard/timestamper/core/TimelineSource.java b/src/main/com/jdbernard/timestamper/core/TimelineSource.java index 136a632..de85445 100755 --- a/src/main/com/jdbernard/timestamper/core/TimelineSource.java +++ b/src/main/com/jdbernard/timestamper/core/TimelineSource.java @@ -4,8 +4,8 @@ import java.io.IOException; import java.net.URI; /** - * - * @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com}) + * A means of loading and persisting a Timeline. + * @author Jonathan Bernard (jonathan.bernard@gemalto.com) */ public abstract class TimelineSource { @@ -13,11 +13,36 @@ public abstract class TimelineSource { public TimelineSource(URI uri) { this.uri = uri; } + /** + * Read the Timeline from the source. + * @throws IOException + */ public abstract Timeline read() throws IOException; + + /** + * Persist a give timeline to this source. + * @param t + * @throws IOException + */ public abstract void persist(Timeline t) throws IOException; + + /** + * Is this source authenticated and ready for IO. + * @return true if the source is authenticated (or if no + * authentication is required). + */ public abstract boolean isAuthenticated(); + + /** + * Authenticate the client to this source. + * @throws AuthenticationException + */ public abstract void authenticate() throws AuthenticationException; + /** + * Get the URI representing this source. + * @return The {@link java.net.URI} representing this source. + */ public URI getURI() { return uri; }