Refactored code packages, com.jdbernard -> com.jdblabs

* Updated contact info, package declarations, and config to match.
* Removed com.jdbernard.timestamper.core, it is becoming a seperate library
  project.
This commit is contained in:
Jonathan Bernard 2011-06-16 12:33:54 -05:00
parent d08d054fbe
commit 98071f270d
30 changed files with 82 additions and 1016 deletions

View File

@ -5,23 +5,23 @@ application {
} }
mvcGroups { mvcGroups {
LogDialog { LogDialog {
model="com.jdbernard.timestamper.LogDialogModel" model="com.jdblabs.timestamper.gui.LogDialogModel"
controller="com.jdbernard.timestamper.LogDialogController" controller="com.jdblabs.timestamper.gui.LogDialogController"
view="com.jdbernard.timestamper.LogDialogView" view="com.jdblabs.timestamper.gui.LogDialogView"
} }
TimeStamperMain { TimeStamperMain {
model="com.jdbernard.timestamper.TimeStamperMainModel" model="com.jdblabs.timestamper.gui.TimeStamperMainModel"
view="com.jdbernard.timestamper.TimeStamperMainView" view="com.jdblabs.timestamper.gui.TimeStamperMainView"
controller="com.jdbernard.timestamper.TimeStamperMainController" controller="com.jdblabs.timestamper.gui.TimeStamperMainController"
} }
PunchcardDialog { PunchcardDialog {
model="com.jdbernard.timestamper.PunchcardDialogModel" model="com.jdblabs.timestamper.gui.PunchcardDialogModel"
view="com.jdbernard.timestamper.PunchcardDialogView" view="com.jdblabs.timestamper.gui.PunchcardDialogView"
controller="com.jdbernard.timestamper.PunchcardDialogController" controller="com.jdblabs.timestamper.gui.PunchcardDialogController"
} }
NotesDialog { NotesDialog {
model="com.jdbernard.timestamper.NotesDialogModel" model="com.jdblabs.timestamper.gui.NotesDialogModel"
view="com.jdbernard.timestamper.NotesDialogView" view="com.jdblabs.timestamper.gui.NotesDialogView"
controller="com.jdbernard.timestamper.NotesDialogController" controller="com.jdblabs.timestamper.gui.NotesDialogController"
} }
} }

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
class LogDialogController { class LogDialogController {
// these will be injected by Griffon // these will be injected by Griffon
@ -13,4 +13,4 @@ class LogDialogController {
def action = { evt = null -> def action = { evt = null ->
} }
*/ */
} }

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import java.awt.Point import java.awt.Point

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import java.awt.Point import java.awt.Point

View File

@ -1,8 +1,8 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import com.jdbernard.util.SmartConfig import com.jdblabs.util.SmartConfig
import com.jdbernard.timestamper.core.TimelineMarker import com.jdblabs.timestamper.core.TimelineMarker
import com.jdbernard.timestamper.core.TimelineProperties import com.jdblabs.timestamper.core.TimelineProperties
class TimeStamperMainController { class TimeStamperMainController {
// these will be injected by Griffon // these will be injected by Griffon

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import groovy.beans.Bindable import groovy.beans.Bindable

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import groovy.beans.Bindable import groovy.beans.Bindable

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import groovy.beans.Bindable import groovy.beans.Bindable

View File

@ -1,13 +1,13 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import groovy.beans.Bindable import groovy.beans.Bindable
import java.awt.Point import java.awt.Point
import java.awt.Rectangle import java.awt.Rectangle
import java.util.Properties import java.util.Properties
import com.jdbernard.util.SmartConfig import com.jdblabs.util.SmartConfig
import com.jdbernard.timestamper.core.Timeline import com.jdblabs.timestamper.core.Timeline
import com.jdbernard.timestamper.core.TimelineMarker import com.jdblabs.timestamper.core.TimelineMarker
import com.jdbernard.timestamper.core.TimelineProperties import com.jdblabs.timestamper.core.TimelineProperties
class TimeStamperMainModel { class TimeStamperMainModel {
@Bindable TimelineMarker currentMarker @Bindable TimelineMarker currentMarker

View File

@ -17,4 +17,4 @@ appender("FILE", FileAppender) {
} }
root(WARN, ["CONSOLE"]) root(WARN, ["CONSOLE"])
logger("com.jdbernard.*", TRACE, ["FILE"], false) logger("com.jdblabs.*", TRACE, ["FILE"], false)

View File

@ -42,32 +42,32 @@ if expand('%') == '' && !&modified && line('$') <= 1 && getline(1) == ''
let s:wipebuf = bufnr('%') let s:wipebuf = bufnr('%')
endif endif
set shortmess=aoO set shortmess=aoO
badd +88 views/com/jdbernard/timestamper/TimeStamperMainView.groovy badd +88 views/com/jdblabs/timestamper/TimeStamperMainView.groovy
badd +24 models/com/jdbernard/timestamper/TimeStamperMainModel.groovy badd +24 models/com/jdblabs/timestamper/TimeStamperMainModel.groovy
badd +64 controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy badd +64 controllers/com/jdblabs/timestamper/TimeStamperMainController.groovy
badd +1 views/com/jdbernard/timestamper/NotesDialogView.groovy badd +1 views/com/jdblabs/timestamper/NotesDialogView.groovy
badd +8 models/com/jdbernard/timestamper/NotesDialogModel.groovy badd +8 models/com/jdblabs/timestamper/NotesDialogModel.groovy
badd +1 controllers/com/jdbernard/timestamper/NotesDialogController.groovy badd +1 controllers/com/jdblabs/timestamper/NotesDialogController.groovy
badd +1 views/com/jdbernard/timestamper/PunchcardDialogView.groovy badd +1 views/com/jdblabs/timestamper/PunchcardDialogView.groovy
badd +7 models/com/jdbernard/timestamper/PunchcardDialogModel.groovy badd +7 models/com/jdblabs/timestamper/PunchcardDialogModel.groovy
badd +1 controllers/com/jdbernard/timestamper/PunchcardDialogController.groovy badd +1 controllers/com/jdblabs/timestamper/PunchcardDialogController.groovy
badd +215 ../src/main/com/jdbernard/timestamper/gui/TimelineDayDisplay.java badd +215 ../src/main/com/jdblabs/timestamper/gui/TimelineDayDisplay.java
badd +8 ../src/main/com/jdbernard/timestamper/gui/WindowInformation.groovy badd +8 ../src/main/com/jdblabs/timestamper/gui/WindowInformation.groovy
badd +28 conf/Application.groovy badd +28 conf/Application.groovy
badd +1 conf/Builder.groovy badd +1 conf/Builder.groovy
badd +1 conf/Config.groovy badd +1 conf/Config.groovy
badd +1 actions/com/jdbernard/timestamper/NotesDialogActions.groovy badd +1 actions/com/jdblabs/timestamper/NotesDialogActions.groovy
badd +1 actions/com/jdbernard/timestamper/TimeStamperMainActions.groovy badd +1 actions/com/jdblabs/timestamper/TimeStamperMainActions.groovy
badd +24 lifecycle/Initialize.groovy badd +24 lifecycle/Initialize.groovy
badd +1 conf/Events.groovy badd +1 conf/Events.groovy
badd +13 resources/log4j.properties badd +13 resources/log4j.properties
badd +1 ../src/main/com/jdbernard/timestamper/GUIUtil.groovy badd +1 ../src/main/com/jdblabs/timestamper/GUIUtil.groovy
badd +1 controllers/com/jdbernard/timestamper/LogDialogController.groovy badd +1 controllers/com/jdblabs/timestamper/LogDialogController.groovy
badd +1 models/com/jdbernard/timestamper/LogDialogModel.groovy badd +1 models/com/jdblabs/timestamper/LogDialogModel.groovy
badd +0 views/com/jdbernard/timestamper/LogDialogView.groovy badd +0 views/com/jdblabs/timestamper/LogDialogView.groovy
badd +0 ../src/main/com/jdbernard/GUIUtil.groovy badd +0 ../src/main/com/jdblabs/GUIUtil.groovy
args views/com/jdbernard/timestamper/TimeStamperMainView.groovy args views/com/jdblabs/timestamper/TimeStamperMainView.groovy
edit views/com/jdbernard/timestamper/TimeStamperMainView.groovy edit views/com/jdblabs/timestamper/TimeStamperMainView.groovy
set splitbelow splitright set splitbelow splitright
wincmd _ | wincmd | wincmd _ | wincmd |
vsplit vsplit
@ -190,7 +190,7 @@ normal! zt
normal! 011l normal! 011l
wincmd w wincmd w
argglobal argglobal
edit models/com/jdbernard/timestamper/TimeStamperMainModel.groovy edit models/com/jdblabs/timestamper/TimeStamperMainModel.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -294,7 +294,7 @@ normal! zt
normal! 0 normal! 0
wincmd w wincmd w
argglobal argglobal
edit controllers/com/jdbernard/timestamper/TimeStamperMainController.groovy edit controllers/com/jdblabs/timestamper/TimeStamperMainController.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -403,7 +403,7 @@ exe '2resize ' . ((&lines * 23 + 40) / 81)
exe 'vert 2resize ' . ((&columns * 91 + 91) / 182) exe 'vert 2resize ' . ((&columns * 91 + 91) / 182)
exe '3resize ' . ((&lines * 54 + 40) / 81) exe '3resize ' . ((&lines * 54 + 40) / 81)
exe 'vert 3resize ' . ((&columns * 91 + 91) / 182) exe 'vert 3resize ' . ((&columns * 91 + 91) / 182)
tabedit views/com/jdbernard/timestamper/NotesDialogView.groovy tabedit views/com/jdblabs/timestamper/NotesDialogView.groovy
set splitbelow splitright set splitbelow splitright
wincmd _ | wincmd | wincmd _ | wincmd |
vsplit vsplit
@ -526,7 +526,7 @@ normal! zt
normal! 025l normal! 025l
wincmd w wincmd w
argglobal argglobal
edit models/com/jdbernard/timestamper/NotesDialogModel.groovy edit models/com/jdblabs/timestamper/NotesDialogModel.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -630,7 +630,7 @@ normal! zt
normal! 0 normal! 0
wincmd w wincmd w
argglobal argglobal
edit controllers/com/jdbernard/timestamper/NotesDialogController.groovy edit controllers/com/jdblabs/timestamper/NotesDialogController.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -739,7 +739,7 @@ exe '2resize ' . ((&lines * 12 + 40) / 81)
exe 'vert 2resize ' . ((&columns * 91 + 91) / 182) exe 'vert 2resize ' . ((&columns * 91 + 91) / 182)
exe '3resize ' . ((&lines * 65 + 40) / 81) exe '3resize ' . ((&lines * 65 + 40) / 81)
exe 'vert 3resize ' . ((&columns * 91 + 91) / 182) exe 'vert 3resize ' . ((&columns * 91 + 91) / 182)
tabedit views/com/jdbernard/timestamper/PunchcardDialogView.groovy tabedit views/com/jdblabs/timestamper/PunchcardDialogView.groovy
set splitbelow splitright set splitbelow splitright
wincmd _ | wincmd | wincmd _ | wincmd |
vsplit vsplit
@ -862,7 +862,7 @@ normal! zt
normal! 011l normal! 011l
wincmd w wincmd w
argglobal argglobal
edit models/com/jdbernard/timestamper/PunchcardDialogModel.groovy edit models/com/jdblabs/timestamper/PunchcardDialogModel.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -966,7 +966,7 @@ normal! zt
normal! 07l normal! 07l
wincmd w wincmd w
argglobal argglobal
edit controllers/com/jdbernard/timestamper/PunchcardDialogController.groovy edit controllers/com/jdblabs/timestamper/PunchcardDialogController.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -1075,7 +1075,7 @@ exe '2resize ' . ((&lines * 12 + 40) / 81)
exe 'vert 2resize ' . ((&columns * 91 + 91) / 182) exe 'vert 2resize ' . ((&columns * 91 + 91) / 182)
exe '3resize ' . ((&lines * 65 + 40) / 81) exe '3resize ' . ((&lines * 65 + 40) / 81)
exe 'vert 3resize ' . ((&columns * 91 + 91) / 182) exe 'vert 3resize ' . ((&columns * 91 + 91) / 182)
tabedit views/com/jdbernard/timestamper/LogDialogView.groovy tabedit views/com/jdblabs/timestamper/LogDialogView.groovy
set splitbelow splitright set splitbelow splitright
wincmd _ | wincmd | wincmd _ | wincmd |
vsplit vsplit
@ -1198,7 +1198,7 @@ normal! zt
normal! 04l normal! 04l
wincmd w wincmd w
argglobal argglobal
edit models/com/jdbernard/timestamper/LogDialogModel.groovy edit models/com/jdblabs/timestamper/LogDialogModel.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -1302,7 +1302,7 @@ normal! zt
normal! 014l normal! 014l
wincmd w wincmd w
argglobal argglobal
edit controllers/com/jdbernard/timestamper/LogDialogController.groovy edit controllers/com/jdblabs/timestamper/LogDialogController.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent
@ -1633,7 +1633,7 @@ wincmd w
3wincmd w 3wincmd w
exe 'vert 1resize ' . ((&columns * 91 + 91) / 182) exe 'vert 1resize ' . ((&columns * 91 + 91) / 182)
exe 'vert 2resize ' . ((&columns * 90 + 91) / 182) exe 'vert 2resize ' . ((&columns * 90 + 91) / 182)
tabedit ../src/main/com/jdbernard/timestamper/gui/TimelineDayDisplay.java tabedit ../src/main/com/jdblabs/timestamper/gui/TimelineDayDisplay.java
set splitbelow splitright set splitbelow splitright
wincmd _ | wincmd | wincmd _ | wincmd |
vsplit vsplit
@ -1758,7 +1758,7 @@ normal! zt
normal! 0 normal! 0
wincmd w wincmd w
argglobal argglobal
edit ../src/main/com/jdbernard/GUIUtil.groovy edit ../src/main/com/jdblabs/GUIUtil.groovy
setlocal keymap= setlocal keymap=
setlocal noarabic setlocal noarabic
setlocal autoindent setlocal autoindent

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import javax.swing.JDialog import javax.swing.JDialog

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import java.awt.Color import java.awt.Color
import java.awt.Point import java.awt.Point
@ -6,7 +6,6 @@ import java.awt.Rectangle
import java.awt.Toolkit import java.awt.Toolkit
import javax.swing.BoxLayout import javax.swing.BoxLayout
import javax.swing.JDialog import javax.swing.JDialog
import com.jdbernard.GUIUtil
import net.miginfocom.swing.MigLayout import net.miginfocom.swing.MigLayout
Point mousePressRelativeToDialog Point mousePressRelativeToDialog

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import java.awt.Color import java.awt.Color
import java.awt.Point import java.awt.Point
@ -8,8 +8,7 @@ import java.text.SimpleDateFormat
import javax.swing.JDialog import javax.swing.JDialog
import java.util.Calendar import java.util.Calendar
import javax.swing.SwingConstants import javax.swing.SwingConstants
import com.jdbernard.GUIUtil import com.jdblabs.timestamper.gui.TimelineDayDisplay
import com.jdbernard.timestamper.gui.TimelineDayDisplay
import com.toedter.calendar.JDateChooser import com.toedter.calendar.JDateChooser
import net.miginfocom.swing.MigLayout import net.miginfocom.swing.MigLayout

View File

@ -1,4 +1,4 @@
package com.jdbernard.timestamper package com.jdblabs.timestamper.gui
import java.awt.Color import java.awt.Color
import java.awt.Font import java.awt.Font
@ -11,8 +11,7 @@ import javax.swing.JDialog
import javax.swing.JFileChooser import javax.swing.JFileChooser
import javax.swing.SwingConstants import javax.swing.SwingConstants
import javax.swing.Timer import javax.swing.Timer
import com.jdbernard.GUIUtil import com.jdblabs.timestamper.core.Timeline
import com.jdbernard.timestamper.core.Timeline
import net.miginfocom.swing.MigLayout import net.miginfocom.swing.MigLayout
/* ========== * /* ========== *
@ -199,7 +198,7 @@ aboutDialog = dialog(new JDialog(frame),
label(text: "version " + app.applicationProperties.'app.version' label(text: "version " + app.applicationProperties.'app.version'
+ " by Jonathan Bernard", constraints: 'growx, wrap', + " by Jonathan Bernard", constraints: 'growx, wrap',
horizontalAlignment: SwingConstants.CENTER) horizontalAlignment: SwingConstants.CENTER)
textField(text: 'http://www.jdbernard.com/timestamper', textField(text: 'http://www.jdb-labs.com/timestamper',
constraints: 'growx', foreground: [0,0,200], editable: false, constraints: 'growx', foreground: [0,0,200], editable: false,
horizontalAlignment: SwingConstants.CENTER) horizontalAlignment: SwingConstants.CENTER)
} }

View File

@ -1,21 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.IOException;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class AuthenticationException extends IOException {
public AuthenticationException() { super(); }
public AuthenticationException(String message) { super(message); }
public AuthenticationException(Throwable t) { super(t); }
public AuthenticationException(String message, Throwable t) {
super(message, t);
}
}

View File

@ -1,64 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class FileTimelineSource extends TimelineSource {
private File file;
public FileTimelineSource(URI uri) {
super(uri);
this.file = new File(uri);
}
/** * {@inheritDoc } */
public Timeline read() throws IOException {
FileInputStream fin = new FileInputStream(file);
Timeline t = StreamBasedTimelineSource.readFromStream(fin);
fin.close();
return t;
}
public Timeline readWithComments(OutputStream commentStream)
throws IOException {
FileInputStream fin = new FileInputStream(file);
Timeline t = StreamBasedTimelineSource.readFromStream(fin, commentStream);
fin.close();
return t;
}
/** * {@inheritDoc } */
public void persist(Timeline t) throws IOException {
FileOutputStream fout = new FileOutputStream(file);
StreamBasedTimelineSource.writeToStream(fout, t);
fout.close();
}
public boolean isAuthenticated() {
File dir = file.getParentFile();
return (dir.canRead() && dir.canWrite());
}
public void authenticate() throws AuthenticationException {
File dir = file.getParentFile();
if (!dir.canRead())
throw new AuthenticationException("This FileTimelineSource does not"
+ " have read access to the parent directory for the "
+ "given file (" + file.getAbsolutePath() + ".");
if (!dir.canWrite())
throw new AuthenticationException("This FileTimelineSource does not"
+ " have write access to the parent directory for the "
+ "given file (" + file.getAbsolutePath() + ".");
}
}

View File

@ -1,203 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.ParseException;
import java.util.Date;
import java.util.Scanner;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class StreamBasedTimelineSource extends TimelineSource {
private static final int lineWrap = 78;
private static enum ReadingState {
NewMarker,
StartMark,
ReadMark,
StartNotes,
ReadNotes,
EndMarker
};
private InputStream in;
private OutputStream out;
private ByteArrayOutputStream comments;
public StreamBasedTimelineSource(InputStream inStream,
OutputStream outStream) {
super(null);
this.in = inStream;
this.out = outStream;
this.comments = new ByteArrayOutputStream();
}
/** {@inheritDoc } */
public Timeline read() throws IOException {
return readFromStream(in, comments);
}
/** {@inheritDoc } */
public void persist(Timeline t) throws IOException {
writeToStream(out, t);
}
public void authenticate() throws AuthenticationException { }
public boolean isAuthenticated() { return true; }
/**
* Allows a user to extract the comments from the last parsed file.
* @return a <code>byte[]</code> representing the portions of the file
* which were comments.
*/
public byte[] getCommentBytes() {
return comments.toByteArray();
}
/**
* Write the a representation of the timeline to a stream. This method
* flushes the stream after it finishes writing but does not close the
* stream.
* @param stream An open stream to write the timeline representation to.
* @param timeline The timeline to write.
* @throws java.io.IOException
*/
public static void writeToStream(OutputStream stream, Timeline timeline)
throws IOException {
Writer out = new OutputStreamWriter(stream);
for (TimelineMarker tm : timeline) {
// write timestamp
out.write(Timeline.longFormat.format(tm.getTimestamp()) + "\n");
// write mark
String mark = tm.getMark().replace('\n', '\u0000');
if (mark.length() < lineWrap) out.write(mark + "\n");
else {
// wrap lines if neccessary
int i;
for (i = 0; (i + lineWrap) < mark.length(); i+=lineWrap)
out.write(mark.substring(i, i+lineWrap) + "\\\n");
if (i < mark.length())
out.write(mark.substring(i, mark.length()) + "\n");
}
// write notes
String notes = tm.getNotes().replace('\n', '\u0000');
if (notes.length() < lineWrap) out.write(notes + "\n");
else {
// wrap lines if neccessary
int i;
for (i = 0; (i + lineWrap) < notes.length(); i+=lineWrap)
out.write(notes.substring(i, i+lineWrap) + "\\\n");
if (i < notes.length())
out.write(notes.substring(i, notes.length()) + "\n");
}
out.write("\n");
}
out.flush();
}
/**
* Create a <b>Timeline</b> instance from a given stream.
* @param stream The stream to read from.
* @return A new <b>Timeline</b> instance specified by the input stream.
* @throws java.io.IOException
* @throws java.io.FileNotFoundException
*/
public static Timeline readFromStream(InputStream stream)
throws IOException {
return readFromStream(stream, null);
}
/**
* Create a <b>Timeline</b> instance from a given stream.
* @param stream The stream to read from.
* @param commentStream A stream to write comments found in the file. This
* parameter may be <b>null</b>, in which case comments are ignored.
* @return A new <b>Timeline</b> instance specified by the input stream.
* @throws java.io.IOException
* @throws java.io.FileNotFoundException
*/
public static Timeline readFromStream(InputStream stream,
OutputStream commentStream) throws IOException {
Scanner in = new Scanner(stream);
Timeline timeline = new Timeline();
PrintWriter commentsWriter = commentStream == null ?
null : new PrintWriter(commentStream);
ReadingState readingState = ReadingState.NewMarker;
Date d = null;
StringBuilder mark = null;
StringBuilder notes = null;
String line;
int lineNumber = 0;
while (in.hasNextLine()) {
line = in.nextLine();
lineNumber++;
// line is a comment
if (line.startsWith("#")) {
if (commentsWriter != null) commentsWriter.println(line);
continue; // don't parse this line as part of the timeline
}
switch (readingState) {
case NewMarker:
try { d = Timeline.longFormat.parse(line); }
catch (ParseException pe) {
throw new IOException("Error parsing timeline file at line "
+ lineNumber + ": expected a new marker date but could not parse"
+ " the date. Error: " + pe.getLocalizedMessage());
}
readingState = ReadingState.StartMark;
break;
case StartMark:
mark = new StringBuilder();
// fall through to ReadMark
case ReadMark:
if (line.endsWith("\\")) {
readingState = ReadingState.ReadMark;
line = line.substring(0, line.length() - 1);
}
else readingState = ReadingState.StartNotes;
mark.append(line);
break;
case StartNotes:
notes = new StringBuilder();
// fall through to ReadNotes
case ReadNotes:
if (line.endsWith("\\")) {
readingState = ReadingState.ReadNotes;
line = line.substring(0, line.length() - 1);
}
else readingState = ReadingState.EndMarker;
notes.append(line);
break;
case EndMarker:
String sMark = mark.toString().replace('\u0000', '\n');
String sNotes = notes.toString().replace('\u0000', '\n');
timeline.addMarker(d, sMark, sNotes);
readingState = ReadingState.NewMarker;
}
}
return timeline;
}
}

View File

@ -1,132 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.IOException;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
/**
* A remote target synchronized against the local timeline.
* @author Jonathan Bernard (jonathan.bernard@gemalto.com)
*/
public class SyncTarget {
protected final TimelineSource source;
protected final Timeline localTimeline;
protected final String name;
protected Timer syncTimer;
protected SyncTask syncTask;
protected long syncInterval= 30 * 60 * 1000; // 30 minutes converted to ms
protected boolean pushEnabled = true;
protected boolean pullEnabled = true;
protected boolean syncOnExit = true;
/**
*
*/
protected class SyncTask extends TimerTask {
@Override public void run() {
synchronized(this) {
try { SyncTarget.this.sync(); }
catch (IOException ioe) { /* TODO */ }
}}}
protected SyncTarget(String name, TimelineSource source,
Timeline localTimeline) {
this.name = name;
this.source = source;
this.localTimeline = localTimeline;
syncTimer = new Timer(source.toString() + " sync-timer");
syncTask = new SyncTask();
syncTimer.schedule(syncTask, syncInterval, syncInterval);
}
/**
* Sync the local timeline with the remote timeline represented by this
* SyncTarget object.
* @return <b>true</b> if the two timelines were out of sync and have
* been put into synch, <b>false</b> if the timelines were already in
* sync and no action was requried.
* @throws IOException if there is an error communicating with the remote
* timeline. This includes AuthenticationException.
*/
protected boolean sync() throws IOException {
assert (pullEnabled || pushEnabled);
Timeline remoteTimeline;
boolean syncPerformed = false;
// make sure we're authenticated to whatever source we're using
if (!SyncTarget.this.source.isAuthenticated()) {
SyncTarget.this.source.authenticate();
}
// try to copy the remote timeline locally
remoteTimeline = SyncTarget.this.source.read();
// if we are pulling markers from the remote line
if (SyncTarget.this.pullEnabled) {
// get all markers in the remote timeline not in the local one
Collection<TimelineMarker> diffFromRemote =
remoteTimeline.difference(localTimeline);
if (diffFromRemote.size() != 0) {
// add all markers in the remote tline to the local one
localTimeline.addAll(diffFromRemote);
syncPerformed = true;
}
}
// if we are pushing markers to the remote timeline
if (SyncTarget.this.pushEnabled) {
// get all markers in the local timeline but not in the remote
Collection<TimelineMarker> diffFromLocal =
localTimeline.difference(remoteTimeline);
if (diffFromLocal.size() != 0) {
// add the difference to the remote timeline
remoteTimeline.addAll(diffFromLocal);
syncPerformed = true;
}
}
return syncPerformed;
}
public String getName() { return name; }
public TimelineSource getSource() { return source; }
public synchronized void setSyncInterval(long syncInterval) {
this.syncInterval= syncInterval;
syncTask.cancel();
syncTask = new SyncTask();
syncTimer.purge();
syncTimer.schedule(syncTask, syncInterval, syncInterval);
}
public long getSyncInterval() { return syncInterval; }
public synchronized void setPushEnabled(boolean pushEnabled) {
this.pullEnabled = pushEnabled;
}
public boolean getPushEnabled() { return pushEnabled; }
public synchronized void setPullEnabled(boolean pullEnabled) {
this.pullEnabled = pullEnabled;
}
public boolean getPullEnabled() { return pullEnabled; }
public synchronized void setSyncOnExit(boolean syncOnExit) {
this.syncOnExit = syncOnExit;
}
public boolean getSyncOnExit() { return syncOnExit; }
}

View File

@ -1,128 +0,0 @@
package com.jdbernard.timestamper.core;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.TreeSet;
/**
* A Timeline object represents a series of markers at specific points in time.
* It represents on logical timeline. The markers have a name or symbol (the
* 'mark') and notes associated with that mark.
* @author Jonathan Bernard {@literal <jdbernard@gmail.com>}
* @see com.jdbernard.timestamper.core.TimelineSource
*/
public class Timeline implements Iterable<TimelineMarker> {
public static SimpleDateFormat shortFormat = new SimpleDateFormat("HH:mm:ss");
public static SimpleDateFormat longFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
private TreeSet<TimelineMarker> timelineList;
/**
* Create a new, empty Timeline.
*/
public Timeline() {
timelineList = new TreeSet<TimelineMarker>();
}
/**
* Add a marker to the timeline.
* @param tm The TimelineMarker to add.
* @return <code>true</code> if this Timeline was modified.
*/
public boolean addMarker(TimelineMarker tm) { return timelineList.add(tm); }
/**
* 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 <code>true</code> 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) {
if (tm.getTimestamp().after(timestamp))
break;
lastMarker = tm;
}
return lastMarker;
}
/**
* Remove a TimelineMarker from this Timelnie.
* @param marker The marker to remove.
* @return <code>true</code> if this Timeline was changed.
*/
public boolean removeMarker(TimelineMarker marker) {
return timelineList.remove(marker);
}
public Iterator<TimelineMarker> iterator() {
return timelineList.iterator();
}
/**
* Return the difference of the this timeline relative to another timeline.
* More specifically, return the set of all
* {@link jdbernard.timestamper.core.TimelineMarker}s that are present in
* the <b>this</b> timeline but not present in the given timeline.
* timeline.
* @param t
* @return A collection representing the TimelineMarkers present in
* <b>this</b> timeline but not in the given timeline.
*/
public Collection<TimelineMarker> difference(Timeline t) {
TreeSet<TimelineMarker> difference = new TreeSet<TimelineMarker>();
for (TimelineMarker tm : timelineList) {
if (!t.timelineList.contains(tm))
difference.add(tm);
}
return difference;
}
/**
* Add all TimelineMarkers from <code>t</code> to <code>this</code>
* Timeline, excluding markers already present in <code>this</code>.
* @param t
* @return <code>true</code> if this Timeline was modified.
*/
public boolean addAll(Timeline t) {
boolean modified = false;
for (TimelineMarker tm : t) {
if (!timelineList.contains(tm)) {
timelineList.add(tm);
modified = true;
}
}
return modified;
}
/**
* Add all TimelineMarkers from <code>c</code> to <code>this</code>
* Timeline, excluding markers already present in <code>this</code>.
* @param c A Collection of TimelineMarkers
* @return <code>true</code> if this TImeline was modified.
*/
public boolean addAll(Collection<TimelineMarker> c) {
return timelineList.addAll(c);
}
}

View File

@ -1,63 +0,0 @@
package com.jdbernard.timestamper.core;
import java.util.Date;
/**
* @author Jonathan Bernard {@literal <jdbernard@gmail.com>}
* This represents a marker on the timeline.
* The date of the marker and the mark cannot be changed once assigned.
*/
public class TimelineMarker implements Comparable<TimelineMarker> {
private final Date timestamp;
private final String mark;
private String notes;
public TimelineMarker(Date timestamp, String mark, String notes) {
if (timestamp == null || mark == null)
throw new IllegalArgumentException("Null timestamp or mark"
+ " is not permitted.");
this.timestamp = timestamp;
this.mark = mark;
this.notes = notes;
}
public Date getTimestamp() { return timestamp; }
public String getMark() { return mark; }
public String getNotes() { return notes; }
public void setNotes(String notes) { this.notes = notes; }
@Override
public int compareTo(TimelineMarker that) {
if (that == null) return Integer.MAX_VALUE;
int val = this.timestamp.compareTo(that.timestamp);
if (val == 0) val = this.mark.compareTo(that.mark);
return val;
}
@Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof TimelineMarker)) return false;
TimelineMarker that = (TimelineMarker) o;
return this.timestamp.equals(that.timestamp) &&
this.mark.equals(that.mark);
}
@Override
public int hashCode() {
int hash = 7;
hash = 61 * hash + (this.timestamp != null ? this.timestamp.hashCode() : 0);
hash = 61 * hash + (this.mark != null ? this.mark.hashCode() : 0);
return hash;
}
}

View File

@ -1,195 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.jdbernard.util.SmartConfig;
/**
* 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.
* <br>
* <table>
* <tr><th>Property</th><th>Description</th></tr>
* <tr><td><code>timeline.uri</code></td><td>The URI of the primary (local)
* timeline</td></tr>
* <tr><td><code>timeline.persistOnUpdate?</code></td><td><code>true</code> to
* persist the local timeline when a new event is entered,
* <code>false</code> to disable.</td></tr>
* <tr><td><code>remote.timeline.</code><i>name</i><code>.uri</code></td>
* <td>The URI for the <i>name</i> remote timeline.</td></tr>
* <tr><td><code>remote.timeline.</code><i>name</i><code>.push?</code></td>
* <td><code>true</code> to enable pushing updates to the <i>name</i>
* remote timeline, <code>false</code> to disable.</td></tr>
* <tr><td><code>remote.timeline.</code><i>name</i><code>.pull?</code></td>
* <td><code>true</code> to enable pulling updates from the <i>name</i>
* remote timeline, <code>false</code> to disable.</td></tr>
* <tr><td><code>remote.timeline.</code><i>name</i><code>.syncOnExit?</code>
* </td><td><code>true</code> to force sync the <i>name</i> remote
* timeline on exit.</td></tr>
* <tr><td><code>remote.timeline.</code><i>name</i>
* <code>.updateInterval</code></td><td>The time in milliseconds between
* synching the <i>name</i> remote timeline.</td></tr></table>
* @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 {
public static final String LOCAL_TIMELINE_URI = "timeline.uri";
public static final String LOCAL_TIMELINE_PERSIST_ON_UPDATE = "timeline.persistOnUpdate?";
public static final String REMOTE_TIMELINE_BASE = "remote.timeline.";
private static final Pattern remoteTimelinePropPattern =
Pattern.compile("\\Q" + REMOTE_TIMELINE_BASE + "\\E([^\\s\\.=]+?)[\\.=].*");
private SmartConfig config;
private Timeline timeline;
private TimelineSource timelineSource;
private LinkedList<SyncTarget> syncTargets = new LinkedList<SyncTarget>();
private boolean persistOnUpdate;
/**
* Create new TimelineProperties, using default values. This will create
* a new configuration using a FileTimelineSource pointed at
* <code>'timeline.default.txt'</code> in the current directory and no
* remote Timelines. It will save this configuration to
* <code>'timeline.default.properties'</code> in the current directory.
*/
public TimelineProperties() {
File propertyFile = new File("timeline.default.properties");
config = new SmartConfig(propertyFile);
File timelineFile = new File("timeline.default.txt");
URI timelineURI = timelineFile.toURI();
timeline = new Timeline();
timelineSource = TimelineSourceFactory.newInstance(timelineURI);
persistOnUpdate = true;
try { timelineSource.persist(timeline); }
catch (IOException ioe) {
// TODO
}
config.setProperty(LOCAL_TIMELINE_URI, timelineURI);
config.setProperty(LOCAL_TIMELINE_PERSIST_ON_UPDATE, persistOnUpdate);
}
/**
* Load TimelineProperties from an InputStream.
* @param is
*/
public TimelineProperties(File propFile) throws IOException {
String strURI;
URI timelineURI;
config = new SmartConfig(propFile);
// load persist on update information
persistOnUpdate = (Boolean) config.getProperty(
LOCAL_TIMELINE_PERSIST_ON_UPDATE, true);
// load local timeline
strURI = (String) config.getProperty(LOCAL_TIMELINE_URI, "");
if ("".equals(strURI)) {
File defaultTimelineFile = new File("timeline.default.txt");
try {
if (!defaultTimelineFile.exists())
defaultTimelineFile.createNewFile();
} catch (IOException ioe) {
// TODO
}
timelineURI = defaultTimelineFile.toURI();
} else {
try { timelineURI = new URI(strURI); }
catch (URISyntaxException urise) {
throw new IOException("Unable to load the timeline: the timeline "
+ "URI is invalid.", urise);
}
}
timelineSource = TimelineSourceFactory.newInstance(timelineURI);
timeline = timelineSource.read();
// search keys for remote timeline entries
// TODO: this code will add a new sync object for every remote target
// property, regardless of whether the SyncTarget for that remote URI
// already exists
for (Object keyObj : config.keySet()) {
if (!(keyObj instanceof String)) continue;
String key = (String) keyObj;
String stName;
String remoteBase;
SyncTarget st;
Matcher m = remoteTimelinePropPattern.matcher(key);
if (!m.matches()) continue;
stName = m.group(1);
remoteBase = REMOTE_TIMELINE_BASE + stName;
strURI = (String) config.getProperty(remoteBase + ".uri", "");
try { timelineURI = new URI(strURI); }
catch (URISyntaxException urise) { /* TODO */ }
// add a new SyncTarget to the list
st = new SyncTarget(stName, TimelineSourceFactory
.newInstance(timelineURI), timeline);
syncTargets.add(st);
// check for synch options
st.setPullEnabled((Boolean)config.getProperty(
remoteBase + ".pull?", true));
st.setPushEnabled((Boolean)config.getProperty(
remoteBase + ".push?", true));
st.setSyncOnExit((Boolean)config.getProperty(
remoteBase + ".syncOnExit?", true));
st.setSyncInterval((Long)config.getProperty(
remoteBase + ".updateInterval", 1800000l)); // thirty minutes
}
}
public void save() throws IOException {
timelineSource.persist(timeline);
config.setProperty(LOCAL_TIMELINE_PERSIST_ON_UPDATE, persistOnUpdate);
config.setProperty(LOCAL_TIMELINE_URI, timelineSource.getURI());
for (SyncTarget st : syncTargets) {
String remoteBase = REMOTE_TIMELINE_BASE + st.getName();
config.setProperty(remoteBase + ".uri", st.getSource().getURI());
config.setProperty(remoteBase + ".pull?", st.getPullEnabled());
config.setProperty(remoteBase + ".push?", st.getPushEnabled());
config.setProperty(remoteBase + ".syncOnExit?", st.getSyncOnExit());
config.setProperty(remoteBase + ".updateInterval",
st.getSyncInterval());
}
}
public Timeline getTimeline() { return timeline; }
public void setTimelineSource(TimelineSource newSource) {
this.timelineSource = newSource;
}
public TimelineSource getTimelineSource() { return timelineSource; }
public Collection<SyncTarget> getSyncTargets() { return syncTargets; }
public boolean getPersistOnUpdate() { return persistOnUpdate; }
public void setPersistOnUpdate(boolean persistOnUpdate) {
this.persistOnUpdate = persistOnUpdate;
if (persistOnUpdate) try { save(); } catch (IOException ioe) {}
}
}

View File

@ -1,50 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.IOException;
import java.net.URI;
/**
* A means of loading and persisting a Timeline.
* @author Jonathan Bernard (jonathan.bernard@gemalto.com)
*/
public abstract class TimelineSource {
protected final URI uri;
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 <code>true</code> 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;
}
}

View File

@ -1,38 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.File;
import java.net.URI;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class TimelineSourceFactory {
public static TimelineSource newInstance(URI uri) {
// File based
if ("file".equalsIgnoreCase(uri.getScheme())) {
return new FileTimelineSource(uri);
}
// Twitter
else if ("http".equalsIgnoreCase(uri.getScheme()) &&
("twitter.com".equalsIgnoreCase(uri.getHost())
|| "www.twitter.com".equalsIgnoreCase(uri.getHost()))) {
throw new UnsupportedOperationException("Twitter based timeline "
+ "sources are not yet supported.");
}
// SSH
else if ("ssh".equalsIgnoreCase(uri.getScheme())) {
throw new UnsupportedOperationException("SSH based timeline sources"
+ " are not yet supported.");
}
// unknown
else {
throw new UnsupportedOperationException("Timeline sources for the"
+ " " + uri.getScheme() + " are not currently supported.");
}
}
}

View File

@ -1,34 +0,0 @@
package com.jdbernard.timestamper.core;
import java.io.IOException;
import java.net.URI;
/**
*
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
*/
public class TwitterTimelineSource extends TimelineSource {
private String username;
private char[] password;
public TwitterTimelineSource(URI uri) {
super(uri);
}
public Timeline read() throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public void persist(Timeline t) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public boolean isAuthenticated() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void authenticate() throws AuthenticationException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -1,4 +1,4 @@
package com.jdbernard package com.jdblabs.timestamper.gui
import java.awt.Point import java.awt.Point
import java.awt.Rectangle import java.awt.Rectangle

View File

@ -1,11 +1,9 @@
/* TimelineDayDisplay.java /* TimelineDayDisplay.java */
* Author: Jonathan Bernard - jonathan.bernard@gemalto.com
*/
package com.jdbernard.timestamper.gui; package com.jdblabs.timestamper.gui;
import com.jdbernard.timestamper.core.TimelineMarker; import com.jdblabs.timestamper.core.TimelineMarker;
import com.jdbernard.timestamper.core.Timeline; import com.jdblabs.timestamper.core.Timeline;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
@ -28,8 +26,7 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
/** /**
* * @author Jonathan Bernard (jdbernard@gmail.com)
* @author jbernard
*/ */
public class TimelineDayDisplay extends JComponent implements MouseListener, public class TimelineDayDisplay extends JComponent implements MouseListener,
ChangeListener { ChangeListener {
@ -312,7 +309,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
/** /**
* Set the font used for displaying the name of the entry (more precisely: * Set the font used for displaying the name of the entry (more precisely:
* {@link com.jdbernard.timestamper.core.TimelineMarker#mark}). * {@link com.jdblabs.timestamper.core.TimelineMarker#mark}).
* @param f The font to use. * @param f The font to use.
*/ */
public void setMarkFont(Font f) { public void setMarkFont(Font f) {

View File

@ -1,6 +1,6 @@
package com.jdbernard.timestamper.gui.plugin package com.jdblabs.timestamper.gui.plugin
import com.jdbernard.timestamper.core.TimelineMarker import com.jdblabs.timestamper.core.TimelineMarker
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory

View File

@ -1,8 +1,8 @@
package com.jdbernard.timestamper.gui.plugin; package com.jdblabs.timestamper.gui.plugin;
import java.io.File; import java.io.File;
import java.util.Map; import java.util.Map;
import com.jdbernard.timestamper.core.TimelineMarker; import com.jdblabs.timestamper.core.TimelineMarker;
public interface TimestamperPlugin { public interface TimestamperPlugin {

View File

@ -1,6 +1,6 @@
package com.jdbernard.timestamper.gui.plugin package com.jdblabs.timestamper.gui.plugin
import com.jdbernard.timestamper.core.TimelineMarker import com.jdblabs.timestamper.core.TimelineMarker
import org.jivesoftware.smack.ConnectionConfiguration import org.jivesoftware.smack.ConnectionConfiguration
import org.jivesoftware.smack.XMPPConnection import org.jivesoftware.smack.XMPPConnection
import org.jivesoftware.smack.packet.Presence import org.jivesoftware.smack.packet.Presence