From b02c8359f983ef85e3a9cdcfc76fdd5f32b27b7c Mon Sep 17 00:00:00 2001
From: Mathew McBride
Date: Sun, 18 May 2008 21:48:12 +1000
Subject: [PATCH] Mega experimental fixes; try to stop a new smallsql
connection from being opened if one is already present in the VM (unfinished
sync session).
---
docs/icalsamples/10350.ics | 6 +-
docs/icalsamples/10350_1.ics | 4 +-
.../java/net/bionicmessage/groupdav/groupDAV.java | 111 +++-----
.../MultipleSourceICalendarObjectStore.java | 93 ++++--
...king.java => MultipleSourceObjectTracking.java} | 313 +++++++++++++--------
.../net/bionicmessage/utils/HTMLFormatter.java | 9 +-
.../bionicmessage/utils/JDBCConnectionFactory.java | 67 +++++
.../MultipleSourceICalendarObjectStoreTest.java | 4 +-
8 files changed, 384 insertions(+), 223 deletions(-)
rename src/main/java/net/bionicmessage/objects/{ObjectTracking.java => MultipleSourceObjectTracking.java} (61%)
mode change 100755 => 100644
create mode 100644 src/main/java/net/bionicmessage/utils/JDBCConnectionFactory.java
diff --git a/docs/icalsamples/10350.ics b/docs/icalsamples/10350.ics
index 3ec89aa..53e8958 100755
--- a/docs/icalsamples/10350.ics
+++ b/docs/icalsamples/10350.ics
@@ -7,8 +7,8 @@ CLASS:PUBLIC
LOCATION:changed location
STATUS:CONFIRMED
SUMMARY:Test event
-DTEND:20070227T110000Z
-DTSTART:20070227T100000Z
+DTEND:20080227T110000Z
+DTSTART:20080227T100000Z
TRANSP:OPAQUE
UID:skyrix://ogosync.tietoteema.fi/yritys.template.com/10350
CREATED:20030710T120000Z
@@ -19,6 +19,6 @@ X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
ATTENDEE;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;ROLE=OPT-PARTICIPANT;RSVP=FALSE;CN=Mathew McBride:MAILTO:matt@mcbridematt.dhs.org
-ORGANIZER;CN=Mathew McBride:MAILTO:matt@mcbridematt.dhs.org
+
END:VEVENT
END:VCALENDAR
\ No newline at end of file
diff --git a/docs/icalsamples/10350_1.ics b/docs/icalsamples/10350_1.ics
index ff63976..bd9b210 100644
--- a/docs/icalsamples/10350_1.ics
+++ b/docs/icalsamples/10350_1.ics
@@ -6,8 +6,8 @@ BEGIN:VEVENT
CLASS:PUBLIC
LOCATION:between 11 and 12
SUMMARY:Test event
-DTEND:20070227T110000Z
-DTSTART:20070227T100000Z
+DTEND:20080227T110000Z
+DTSTART:20080227T100000Z
TRANSP:OPAQUE
UID:skyrix://ogosync.tietoteema.fi/yritys.template.com/10350
CREATED:20030710T120000Z
diff --git a/src/main/java/net/bionicmessage/groupdav/groupDAV.java b/src/main/java/net/bionicmessage/groupdav/groupDAV.java
index 72bf9a4..ee62c8c 100755
--- a/src/main/java/net/bionicmessage/groupdav/groupDAV.java
+++ b/src/main/java/net/bionicmessage/groupdav/groupDAV.java
@@ -63,6 +63,8 @@ public class groupDAV {
private String origurl = "";
private entityFinderHandler storeFinderHandler = null;
private entityFinderHandler dirFinderHandler = null;
+
+ private URL serverURL = null;
/** For use in situations where something (i.e in the case of
* Funambol's authentication) has already given us a HTTP Basic Base64
@@ -76,7 +78,7 @@ public class groupDAV {
public groupDAV(String url, String b64cache) {
origurl = url;
try {
- URL serverURL = new URL(url);
+ serverURL = new URL(url);
if (serverURL.getProtocol().contains("https")) {
ssl = true;
}
@@ -110,7 +112,7 @@ public class groupDAV {
public groupDAV(String url, String user, String pass) {
origurl = url;
try {
- URL serverURL = new URL(url);
+ serverURL = new URL(url);
if (serverURL.getProtocol().contains("https")) {
ssl = true;
tok = "https://";
@@ -219,16 +221,25 @@ public class groupDAV {
int clength = findContentLength(output);
if (clength == -1) {
logger.warning("We don't have a Content Length field in listObjects");
- }
+ /* Temporary, ugly workaround for chunked transfer. Only use if
+ * you need to
+ if (output.endsWith("0")) {
+ int startOfXML = output.indexOf(" -1) {
gdir = "";
}
String XMLSTRING = "" +
- "";
+ "";
// String XMLSTRING = "";
String PROPFIND = "PROPFIND " + gdir + subdir + " HTTP/1.1\n" +
"Cache-control: no-cache\nPragma: no-cache\nAccept-Language: en\n" +
base64cache + "\nContent-Length: " +
- XMLSTRING.getBytes().length + "\nHost: " + host + ":" + po + "\n" +
+ XMLSTRING.getBytes().length + "\nHost: " + host + "\n" +
"Depth: 1\nContent-Type: text/xml;charset=utf-8\nAccept: text/*\n\n" +
XMLSTRING;
return PROPFIND.getBytes();
@@ -388,63 +409,6 @@ public class groupDAV {
sparser.parse(new InputSource(new StringReader(xmldata)));
}
- /** Testing method. Edit source and replace with own
- * server settings to test client. */
- public static void main(String args[]) {
- /* Todo: use GUI to ask for info */
- String SERVER = "http://your.server.here:80";
- groupDAV client = new groupDAV(SERVER,
- "",
- "");
- try {
- List calobjects = client.listObjects("/groupdav/Calendar/");
- Map etags = client.getEtags();
- for (int i = 0; i < calobjects.size(); i++) {
- String objectu = (String) calobjects.get(i);
- String eTag = null;
- if (etags.get(objectu) != null) {
- eTag = (String) etags.get(objectu);
- } else {
- eTag = "not found";
- }
- GroupDAVObject gobj = client.getObject(objectu);
- System.err.println(gobj.getContent() + "\n|etag-server=" + eTag);
- System.err.println("|etag-object=" + gobj.getEtag());
- String object = gobj.getContent();
-
- }
- java.util.Random rd = new java.util.Random();
- int uid = rd.nextInt(32);
- String u = "" + uid;
- String object = "BEGIN:VCALENDAR\n" +
- "PRODID:-//BM GroupDAV Client//Test Creation Object/EN\n" +
- "VERSION:2.0\n" +
- "METHOD:REQUEST\n" +
- "BEGIN:VEVENT\n" +
- "SUMMARY:Test object\n" +
- "LOCATION:In dev slash null\n" +
- "DESCRIPTION:Please don't fail me! I'm innocent!\n" +
- "DTSTART:20060408T100059Z\n" +
- "DTEND:20060408T110059Z\n" +
- "TRANSP:OPAQUE\n" +
- "UID:" + u + "\n" +
- "SEQUENCE:1\n" +
- "ORGANIZER:MAILTO:matt@comalies\n" +
- "END:VEVENT\n" +
- "END:VCALENDAR";
-
- // GroupDAVObject gbo = client.postObject(calendarUrl,u,object);
- //System.out.println("Etag for new object= " + gbo.getEtag());
- // Test change operation
- // object.replaceAll("don't","never");
- // GroupDAVObject gboc = client.modifyObject(gbo.getLocation(),object,gbo.getEtag());
- // GroupDAVObject gbod = client.deleteObject(gbo.getLocation(),gbo.getEtag());
- } catch (Exception ex) {
-
- ex.printStackTrace();
- }
- }
-
/** Parses the result of PROPFIND */
private class entityFinderHandler extends DefaultHandler {
@@ -595,7 +559,12 @@ public class groupDAV {
}
return -1;
}
-
+ /** Sends a request to the server, non-keepalive
+ *
+ * @param by A Byte array containing the HTTP request headers and contents
+ * @return A String of the server result
+ * @throws java.lang.Exception Due to network error
+ */
private String sendNonKeepAliveRequest(byte[] by) throws Exception {
String dbugstring = new String(by);
logger.fine(dbugstring);
@@ -675,7 +644,7 @@ public class groupDAV {
query += "\nContent-Length: 0";
}
- query += "\nUser-Agent: " + USER_AGENT + "\nHost: " + host + ":" + po +
+ query += "\nUser-Agent: " + USER_AGENT + "\nHost: " + host +
"\n\n";
// "Host: " + host + "\n\n\n";
if (contents != null) {
diff --git a/src/main/java/net/bionicmessage/objects/MultipleSourceICalendarObjectStore.java b/src/main/java/net/bionicmessage/objects/MultipleSourceICalendarObjectStore.java
index 0ad6aee..faa157b 100644
--- a/src/main/java/net/bionicmessage/objects/MultipleSourceICalendarObjectStore.java
+++ b/src/main/java/net/bionicmessage/objects/MultipleSourceICalendarObjectStore.java
@@ -132,19 +132,6 @@ public class MultipleSourceICalendarObjectStore {
singlelog = true;
}
obtrackdir = storedir + File.separatorChar + "obtrack" + File.separatorChar;
- if (purgemode) {
- File obtrackdirf = new File(obtrackdir);
- String[] files = obtrackdirf.list();
- if (obtrackdirf.exists() && files.length > 0) {
- for (int i = 0; i < files.length; i++) {
- String string = files[i];
- File toDelete = new File(obtrackdir + File.separatorChar + string);
- boolean deleted = toDelete.delete();
- System.out.println("Delete " + toDelete.getAbsolutePath() + "..." + deleted);
- }
- }
- obtrackdirf.delete();
- }
obtrack = new MultipleSourceObjectTracking(obtrackdir);
props = new Properties();
propfile = new File(storedir + File.separatorChar + "vcalstoreprops");
@@ -176,6 +163,7 @@ public class MultipleSourceICalendarObjectStore {
}
}
+ /** Loads a list of data sources from the predefinied properties */
public void loadSourcesFromProps() {
Iterator listOfProps = props.keySet().iterator();
while (listOfProps.hasNext()) {
@@ -227,6 +215,11 @@ public class MultipleSourceICalendarObjectStore {
client.setLogger(log);
}
+ /**
+ * Returns a list of server side data stores discovered by the client
+ * @return A Hashtable of server side data stores discovered (PROPFIND) by the
+ * GroupDAV Client
+ */
public Hashtable getStores() {
return client.getURLLocs();
}
@@ -252,11 +245,18 @@ public class MultipleSourceICalendarObjectStore {
DtStart dts = (DtStart) vcal.getProperty("DTSTART");
DtEnd dte = (DtEnd) vcal.getProperty("DTEND");
java.util.Date dts_date = (java.util.Date) dts.getDate();
- java.util.Date dte_date = (java.util.Date) dte.getDate();
+ java.util.Date dte_date = null;
+ if (dte == null) { // all day event
+ // TODO: handle as dts_date+24h or dts_date?
+ dte_date = dts_date;
+ } else {
+ dte_date = dte.getDate();
+ }
dtstart = dts_date.getTime() / 1000;
dtend = dte_date.getTime() / 1000;
dts = null;
- dte = null;;
+ dte = null;
+ ;
}
obtrack.createObject(storeName, uid.getValue(), url, obj.getEtag(), summ.getValue().trim(), obj.getContent(), dtstart, dtend);
logList.add(uid.getValue());
@@ -285,6 +285,11 @@ public class MultipleSourceICalendarObjectStore {
updatedInStore.add(uid);
}
+ /**
+ * Deletes an object from the store (not from the server)
+ * @param uid The object to delete from the store
+ * @throws java.lang.Exception
+ */
private void deleteFromStore(String uid) throws Exception {
obtrack.deleteObject(uid);
deletedFromStore.add(uid);
@@ -388,9 +393,17 @@ public class MultipleSourceICalendarObjectStore {
return cd;
}
+ /** Starts the synchronisation process. Pulls new and updated
+ * data from the server and deletes any objects as needed
+ * @throws java.lang.Exception
+ */
public void startSync() throws Exception {
log.info("Sync started....");
- obtrack.init();
+ if (!purgemode) {
+ obtrack.init();
+ } else {
+ obtrack.initClean();
+ }
Iterator sourceList = sources.keySet().iterator();
while (sourceList.hasNext()) {
String sourceName = sourceList.next();
@@ -432,34 +445,64 @@ public class MultipleSourceICalendarObjectStore {
}
}
+ /** Returns a list of UIDs that have not been modified in the last
+ * sync cycle
+ * @return An ArrayList of unmodified UIDs
+ */
public ArrayList getUnModifiedUIDS() {
return untouched;
}
+ /** @deprecated */
public ArrayList getAddedToServerUIDS() {
return addedToServer;
}
+ /** Returns a list of UIDs that were added(new) from the server in the last
+ * sync cycle
+ * @return An ArrayList of new UIDs
+ */
public ArrayList getAddedToStoreUIDS() {
return addedToStore;
}
+ /** Returns a list of UIDs that have been deleted by the user of this sink
+ *
+ * @return An ArrayList of UIDs deleted from the server
+ */
public ArrayList getDeletedFromServerUIDS() {
return deletedFromServer;
}
+ /**
+ * Returns a list of UIDs deleted from the server
+ * @return An ArrayList of UIDs deleted on the server
+ */
public ArrayList getDeletedFromStoreUIDS() {
return deletedFromStore;
}
+ /**
+ * Returns a list of UIDs updated on the server
+ * @return An ArrayList of UIDs updated on the server
+ */
public ArrayList getUpdatedInStoreUIDS() {
return updatedInStore;
}
+ /**
+ * Returns a list of UIDs modified by us
+ * @return An ArrayList of UIDs modified by the user
+ */
public ArrayList getUpdatedOnServerUIDS() {
return updatedOnServer;
}
+ /**
+ * Returns a list of UIDs in the database
+ * @return An ArrayList of UIDs in the database
+ * @throws java.sql.SQLException
+ */
public ArrayList getUIDList() throws SQLException {
return obtrack.getUIDList();
}
@@ -527,22 +570,27 @@ public class MultipleSourceICalendarObjectStore {
log.info(sw.toString());
}
+ /** Ends this sink session, shuts down the logger and closes the database
+ * connection
+ * @throws java.lang.Exception
+ */
public void close() throws Exception {
fh.close();
obtrack.terminate();
}
protected void logStart() {
- log.info(this.getClass().getName() + " started in "+obtrackdir);
- log.info("Purge mode="+purgemode);
+ log.info(this.getClass().getName() + " started in " + obtrackdir);
+ log.info("Purge mode=" + purgemode);
Iterator it = props.keySet().iterator();
- while(it.hasNext()) {
- String prop = (String)it.next();
+ while (it.hasNext()) {
+ String prop = (String) it.next();
String key = props.getProperty(prop);
- log.info(prop+"="+key);
+ log.info(prop + "=" + key);
}
-
+
}
+
public static void main(String[] args) {
String storeloc = "";
if (args.length > 0 && args[0] != null) {
@@ -560,5 +608,4 @@ public class MultipleSourceICalendarObjectStore {
ex.printStackTrace();
}
}
-
}
diff --git a/src/main/java/net/bionicmessage/objects/ObjectTracking.java b/src/main/java/net/bionicmessage/objects/MultipleSourceObjectTracking.java
old mode 100755
new mode 100644
similarity index 61%
rename from src/main/java/net/bionicmessage/objects/ObjectTracking.java
rename to src/main/java/net/bionicmessage/objects/MultipleSourceObjectTracking.java
index 1a75021..42d3fed
--- a/src/main/java/net/bionicmessage/objects/ObjectTracking.java
+++ b/src/main/java/net/bionicmessage/objects/MultipleSourceObjectTracking.java
@@ -1,8 +1,8 @@
/*
- * ObjectTracking.java
+ * MultipleSourceObjectTracking.java
*
- * Created on 26 August 2006, 13:24
- * Copyright (c) 2006 Mathew McBride / "BionicMessage.net"
+ * Original file created on 26 August 2006, 13:24
+ * Copyright (c) 2006-2008 Mathew McBride / "BionicMessage.net"
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
@@ -19,17 +19,23 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
- *
+ *
*/
package net.bionicmessage.objects;
+
+import java.io.File;
+import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import net.bionicmessage.extutils.Base64;
+import net.bionicmessage.utils.JDBCConnectionFactory;
+
/**
*
- * @author matt
+ * @ObjMultipleSourceObjectTracking
*/
-public class ObjectTracking {
+public class MultipleSourceObjectTracking {
+
private String dbpath = "";
private Connection conn = null;
private String dburl = "";
@@ -40,19 +46,66 @@ public class ObjectTracking {
private static final String URLLIST = "urllist";
private static final String DATELIST = "datelist";
private static final String NOTWANTLIST = "notwanted";
- /** Creates a new instance of ObjectTracking */
- public ObjectTracking(String dbpath) {
+ private JDBCConnectionFactory jdbcFactory = null;
+
+ /** Creates a newObjMultipleSourceObjectTrackingjectTracking */
+ public MultipleSourceObjectTracking(String dbpath) {
this.dbpath = dbpath;
- dburl = "jdbc:smallsql:"+dbpath+"?create=true";
+ dburl = "jdbc:smallsql:" + dbpath + "?create=true";
+ jdbcFactory = JDBCConnectionFactory.getInstance();
}
+
public void terminate() throws SQLException {
conn.close();
+ JDBCConnectionFactory.removeConnection(dburl);
}
+
public void init() throws Exception {
- Class.forName( "smallsql.database.SSDriver" );
- conn = java.sql.DriverManager.getConnection(dburl);
+ Class.forName("smallsql.database.SSDriver");
+ //conn = java.sql.DriverManager.getConnection(dburl);
+ if (jdbcFactory.doesConnectionExist(dburl)) {
+ initClean();
+ } else {
+ conn = jdbcFactory.getConnection(dburl);
+ if (conn == null) {
+ throw new Exception("Critical error: No SmallSQL connection. DBURL:" + dburl);
+ }
+ createTablesIfNeeded();
+ }
+ }
+
+ /** Function designed for Funambol slow syncs. If an errored instance exists
+ * in the VM, close its connection, purge, and then make ours.
+ * @throws java.sql.SQLException
+ * @throws java.io.IOException
+ */
+ public void initClean() throws SQLException, IOException, ClassNotFoundException {
+ Class.forName("smallsql.database.SSDriver");
+ if (JDBCConnectionFactory.doesConnectionExist(dburl)) {
+ conn = JDBCConnectionFactory.getConnection(dburl);
+ terminate();
+ }
+ File dbDir = new File(dbpath);
+ if (dbDir.exists()) {
+ String[] files = dbDir.list();
+ if (dbDir.exists() && files.length > 0) {
+ for (int i = 0; i < files.length; i++) {
+ String string = files[i];
+ File toDelete = new File(dbDir, string);
+ boolean deleted = toDelete.delete();
+ System.out.println("Delete " + toDelete.getAbsolutePath() + "..." + deleted);
+ }
+ }
+ boolean deleted = dbDir.delete();
+ int one = 2;
+ }
+ conn = JDBCConnectionFactory.getConnection(dburl);
+ if (conn == null) {
+ throw new SQLException("Critical error: No SmallSQL connection. DBURL:" + dburl);
+ }
createTablesIfNeeded();
}
+
public void createTablesIfNeeded() throws SQLException {
boolean create = false;
try {
@@ -70,9 +123,10 @@ public class ObjectTracking {
executeSQL(CREATE_NOTWANTED);
}
}
-
+
/**
* Adds an object to the store
+ * @param sourceName The server source for that object
* @param uid The UID for the object
* @param url The URL from which the server copy of the object can be
* obtained from
@@ -83,78 +137,88 @@ public class ObjectTracking {
* @param dtend The Unix time at which this object ends
* @throws java.sql.SQLException Thrown when the store encounters a problem adding an object to the database
*/
- public void createObject(String uid,
+ public void createObject(String sourceName,
+ String uid,
String url,
String etag,
String name,
String contents,
long dtstart,
long dtend) throws SQLException {
- String newuid = "INSERT INTO " + OBJLIST + "(\"obj_uid\") VALUES ('"+uid+"')";
+ String newuid = String.format("INSERT INTO %s (\"obj_source\", \"obj_uid\") VALUES ('%s','%s')",
+ OBJLIST, sourceName, uid);
executeSQL(newuid);
- String newurl = "INSERT INTO " + URLLIST + "(\"obj_uid\",\"obj_url\") VALUES ('"+uid+"','"+url+"')";
+ String newurl = String.format("INSERT INTO %s (\"obj_source\", \"obj_uid\",\"obj_url\") VALUES ('%s','%s','%s')",
+ URLLIST, sourceName, uid, url);
executeSQL(newurl);
- String newetag = "INSERT INTO " + ETAGLIST + "(\"obj_uid\",\"obj_etag\") VALUES ('"+uid+"','"+etag+"')";
+ String newetag = "INSERT INTO " + ETAGLIST + "(\"obj_uid\",\"obj_etag\") VALUES ('" + uid + "','" + etag + "')";
executeSQL(newetag);
- name = name.replace("'","\"");
- String newname = "INSERT INTO " + NAMELIST + "(\"obj_uid\",\"obj_name\") VALUES ('"+uid+"','"+name+"')";
+ name = name.replace("'", "\"");
+ String newname = "INSERT INTO " + NAMELIST + "(\"obj_uid\",\"obj_name\") VALUES ('" + uid + "','" + name + "')";
executeSQL(newname);
String newobject = "INSERT INTO " + OBJECTS + "(\"obj_uid\",\"obj_contents\") VALUES (?,?)";
PreparedStatement innewobject = conn.prepareStatement(newobject);
innewobject.setString(1, uid);
innewobject.setBytes(2, contents.getBytes());
innewobject.execute();
- String insertdates = "INSERT INTO " + DATELIST + "(\"obj_uid\",\"obj_dtstart\",\"obj_dtend\") VALUES ('"+uid+"','"+dtstart+"','"+dtend+"')";
+ String insertdates = "INSERT INTO " + DATELIST + "(\"obj_uid\",\"obj_dtstart\",\"obj_dtend\") VALUES ('" + uid + "','" + dtstart + "','" + dtend + "')";
executeSQL(insertdates);
}
+
public void deleteObject(String uid) throws SQLException {
- String deleteuid = "DELETE FROM " + OBJLIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteuid = "DELETE FROM " + OBJLIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteuid);
- String deleteetag = "DELETE FROM " + ETAGLIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteetag = "DELETE FROM " + ETAGLIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteetag);
- String deletename = "DELETE FROM " + NAMELIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deletename = "DELETE FROM " + NAMELIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deletename);
- String deleteobject= "DELETE FROM " + OBJECTS + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteobject = "DELETE FROM " + OBJECTS + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteobject);
- String deleteurl = "DELETE FROM " + URLLIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteurl = "DELETE FROM " + URLLIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteurl);
- String deletedate = "DELETE FROM " + DATELIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deletedate = "DELETE FROM " + DATELIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deletedate);
}
+
public boolean doesUidMatchTimes(String uid, long dstime, long detime) throws SQLException {
- String findDate = String.format("SELECT \"obj_uid\" FROM \"%s\" WHERE \"obj_uid\" = '%s' AND \"obj_dtstart\" = %d AND \"obj_dtend\" = %d", DATELIST, uid, dstime, detime );
+ String findDate = String.format("SELECT \"obj_uid\" FROM \"%s\" WHERE \"obj_uid\" = '%s' AND \"obj_dtstart\" = %d AND \"obj_dtend\" = %d", DATELIST, uid, dstime, detime);
String result = get1x1SQL(findDate);
- if (result != null)
+ if (result != null) {
return true;
+ }
return false;
}
+
public String findObjectByURL(String url) throws SQLException {
- String findUid = "SELECT \"obj_uid\" FROM \"" + URLLIST + "\" WHERE \"obj_url\" = '" + url +"'";
+ String findUid = "SELECT \"obj_uid\" FROM \"" + URLLIST + "\" WHERE \"obj_url\" = '" + url + "'";
String result = get1x1SQL(findUid);
return result;
}
+
public String findObjectByName(String name) throws SQLException {
- name = name.replace("'","\"");
- String findUid = "SELECT \"obj_uid\" FROM \"" + NAMELIST + "\" WHERE \"obj_name\" = '" + name +"'";
+ name = name.replace("'", "\"");
+ String findUid = "SELECT \"obj_uid\" FROM \"" + NAMELIST + "\" WHERE \"obj_name\" = '" + name + "'";
String result = get1x1SQL(findUid);
return result;
}
+
public ArrayList findObjectsByName(String name) throws SQLException {
ArrayList results = new ArrayList();
- name = name.replace("'","\"");
- String findUid = "SELECT \"obj_uid\" FROM \"" + NAMELIST + "\" WHERE \"obj_name\" = '" + name +"'";
+ name = name.replace("'", "\"");
+ String findUid = "SELECT \"obj_uid\" FROM \"" + NAMELIST + "\" WHERE \"obj_name\" = '" + name + "'";
String result = get1x1SQL(findUid);
Statement stmt = conn.createStatement();
stmt.execute(findUid);
ResultSet rs = stmt.getResultSet();
- while(rs.next()) {
+ while (rs.next()) {
String id = rs.getString("obj_uid");
results.add(id);
}
return results;
}
+
public String getObjectContents(String uid) throws SQLException {
- String findObject = "SELECT \"obj_contents\" FROM \"" + OBJECTS + "\" WHERE \"obj_uid\" = '"+uid+"'";
+ String findObject = "SELECT \"obj_contents\" FROM \"" + OBJECTS + "\" WHERE \"obj_uid\" = '" + uid + "'";
Statement stmt = conn.createStatement();
stmt.execute(findObject);
ResultSet rs = stmt.getResultSet();
@@ -165,94 +229,115 @@ public class ObjectTracking {
String cn = new String(rs.getBytes("obj_contents"));
return cn;
}
+
public String getObjectEtag(String uid) throws SQLException {
- String findObject = "SELECT \"obj_etag\" FROM \"" + ETAGLIST + "\" WHERE \"obj_uid\" = '"+uid+"'";
- String result = get1x1SQL(findObject);;
+ String findObject = "SELECT obj_etag FROM " + ETAGLIST + " WHERE obj_uid = '" + uid + "'";
+ String result = get1x1SQL(findObject);
+ ;
return result;
}
+
public String getObjectName(String uid) throws SQLException {
- String findObject = "SELECT \"obj_name\" FROM \"" + NAMELIST + "\" WHERE \"obj_uid\" = '"+uid+"'";
- String result = get1x1SQL(findObject);;
+ String findObject = "SELECT \"obj_name\" FROM \"" + NAMELIST + "\" WHERE \"obj_uid\" = '" + uid + "'";
+ String result = get1x1SQL(findObject);
+ ;
return result;
}
+
public String getObjectURL(String uid) throws SQLException {
- String findObject = "SELECT \"obj_url\" FROM \"" + URLLIST + "\" WHERE \"obj_uid\" = '"+uid+"'";
- String result = get1x1SQL(findObject);;
+ String findObject = "SELECT \"obj_url\" FROM \"" + URLLIST + "\" WHERE \"obj_uid\" = '" + uid + "'";
+ String result = get1x1SQL(findObject);
return result;
}
+
+ public String getObjectSource(String uid) throws SQLException {
+ String findObject = String.format("SELECT \"obj_uid\" FROM %s WHERE \"obj_uid\" = '%s'", OBJLIST, uid);
+ String result = get1x1SQL(findObject);
+ return result;
+ }
+
public void updateEtag(String uid, String etag) throws SQLException {
- String deleteetag = "DELETE FROM " + ETAGLIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteetag = "DELETE FROM " + ETAGLIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteetag);
- String newetag = "INSERT INTO " + ETAGLIST + "(\"obj_uid\",\"obj_etag\") VALUES ('"+uid+"','"+etag+"')";
+ String newetag = "INSERT INTO " + ETAGLIST + "(\"obj_uid\",\"obj_etag\") VALUES ('" + uid + "','" + etag + "')";
executeSQL(newetag);
}
+
public void updateName(String uid, String name) throws SQLException {
- name = name.replace("'","\"");
- String deletename = "DELETE FROM " + NAMELIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ name = name.replace("'", "\"");
+ String deletename = "DELETE FROM " + NAMELIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deletename);
- String newname = "INSERT INTO " + NAMELIST + "(\"obj_uid\",\"obj_name\") VALUES ('"+uid+"','"+name+"')";
+ String newname = "INSERT INTO " + NAMELIST + "(\"obj_uid\",\"obj_name\") VALUES ('" + uid + "','" + name + "')";
executeSQL(newname);
}
+
public void updateObject(String uid, String content) throws SQLException {
- String deleteobject= "DELETE FROM " + OBJECTS + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deleteobject = "DELETE FROM " + OBJECTS + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deleteobject);
String objectBase64 = Base64.encodeBytes(content.getBytes());
String newobject = "INSERT INTO " + OBJECTS + "(\"obj_uid\",\"obj_contents\") VALUES (?,?)";
PreparedStatement innewobject = conn.prepareStatement(newobject);
innewobject.setString(1, uid);
innewobject.setBytes(2, content.getBytes());
- innewobject.execute();
+ boolean executed = innewobject.execute();
}
+
public void updateDate(String uid, long dtstart, long dtend) throws SQLException {
- String deletedate = "DELETE FROM " + DATELIST + " WHERE \"obj_uid\" = '"+uid+"'";
+ String deletedate = "DELETE FROM " + DATELIST + " WHERE \"obj_uid\" = '" + uid + "'";
executeSQL(deletedate);
- String newdate = "INSERT INTO " + DATELIST + "(\"obj_uid\",\"obj_dtstart\",\"obj_dtend\") VALUES ('"+uid+"',"+dtstart+","+dtend+")";
+ String newdate = "INSERT INTO " + DATELIST + "(\"obj_uid\",\"obj_dtstart\",\"obj_dtend\") VALUES ('" + uid + "'," + dtstart + "," + dtend + ")";
executeSQL(newdate);
}
+
public boolean doesObjectExist(String uid) throws SQLException {
- String findObject = "SELECT \"obj_uid\" FROM \"" + OBJLIST + "\" WHERE \"obj_uid\" = '"+uid+"'";
+ String findObject = "SELECT \"obj_uid\" FROM \"" + OBJLIST + "\" WHERE \"obj_uid\" = '" + uid + "'";
Statement stmt = conn.createStatement();
stmt.execute(findObject);
ResultSet rs = stmt.getResultSet();
return rs.next();
}
+
public boolean doesURLExist(String url) throws SQLException {
- String findObject = "SELECT \"obj_url\" FROM \"" + URLLIST + "\" WHERE \"obj_url\" = '"+url+"'";
+ String findObject = "SELECT \"obj_url\" FROM \"" + URLLIST + "\" WHERE \"obj_url\" = '" + url + "'";
Statement stmt = conn.createStatement();
stmt.execute(findObject);
ResultSet rs = stmt.getResultSet();
return rs.next();
}
+
public boolean doesObjectApplyAtTime(String uid, int time) throws SQLException {
- String findObject = "SELECT \"obj_uid\" FROM \"" + DATELIST + "\" WHERE \"obj_uid\" = '"+ uid +"' AND WHERE \"obj_dtstart\" <= " + time + " AND \"obj_dtend\" >= " + time;
+ String findObject = "SELECT \"obj_uid\" FROM \"" + DATELIST + "\" WHERE \"obj_uid\" = '" + uid + "' AND WHERE \"obj_dtstart\" <= " + time + " AND \"obj_dtend\" >= " + time;
Statement stmt = conn.createStatement();
stmt.execute(findObject);
ResultSet rs = stmt.getResultSet();
return rs.next();
}
+
public long getDtStartForUid(String uid) throws SQLException {
- String findUid = "SELECT \"obj_dtstart\" FROM \""+ DATELIST + "\" WHERE \"obj_uid\" = '" + uid +"'";
+ String findUid = "SELECT \"obj_dtstart\" FROM \"" + DATELIST + "\" WHERE \"obj_uid\" = '" + uid + "'";
Statement stmt = conn.createStatement();
stmt.execute(findUid);
ResultSet rs = stmt.getResultSet();
rs.next();
return rs.getLong("obj_dtstart");
}
+
public long getDtEndFromUid(String uid) throws SQLException {
- String findUid = "SELECT \"obj_dtend\" FROM \""+ DATELIST + "\" WHERE \"obj_uid\" = '" + uid +"'";
+ String findUid = "SELECT \"obj_dtend\" FROM \"" + DATELIST + "\" WHERE \"obj_uid\" = '" + uid + "'";
Statement stmt = conn.createStatement();
stmt.execute(findUid);
ResultSet rs = stmt.getResultSet();
rs.next();
return rs.getLong("obj_dtend");
}
+
public ArrayList getUIDList() throws SQLException {
String uidList = "SELECT \"obj_uid\" FROM \"" + OBJLIST + "\"";
Statement stmt = conn.createStatement();
stmt.execute(uidList);
ResultSet rs = stmt.getResultSet();
ArrayList uidlist = new ArrayList();
- while(rs.next()) {
+ while (rs.next()) {
String uid = rs.getString("obj_uid");
uidlist.add(uid);
}
@@ -260,13 +345,29 @@ public class ObjectTracking {
rs = null;
return uidlist;
}
+
public ArrayList getURLList() throws SQLException {
- String urlList = "SELECT \"obj_url\" FROM \"" + URLLIST+ "\"";
+ String urlList = "SELECT \"obj_url\" FROM \"" + URLLIST + "\"";
+ Statement stmt = conn.createStatement();
+ stmt.execute(urlList);
+ ResultSet rs = stmt.getResultSet();
+ ArrayList urllist = new ArrayList();
+ while (rs.next()) {
+ String url = rs.getString("obj_url");
+ urllist.add(url);
+ }
+ stmt = null;
+ rs = null;
+ return urllist;
+ }
+
+ public ArrayList getURLListForSource(String sourceName) throws SQLException {
+ String urlList = String.format("SELECT \"obj_url\" FROM %s WHERE \"obj_source\" = '%s'", URLLIST, sourceName);
Statement stmt = conn.createStatement();
stmt.execute(urlList);
ResultSet rs = stmt.getResultSet();
ArrayList urllist = new ArrayList();
- while(rs.next()) {
+ while (rs.next()) {
String url = rs.getString("obj_url");
urllist.add(url);
}
@@ -274,17 +375,19 @@ public class ObjectTracking {
rs = null;
return urllist;
}
- public void addForgottenURL(String url,String etag) throws SQLException {
- String newurl = "INSERT INTO " + NOTWANTLIST + "(\"obj_url\",\"obj_etag\") VALUES ('"+url+"','"+etag+"')";
+
+ public void addForgottenURL(String url, String etag) throws SQLException {
+ String newurl = "INSERT INTO " + NOTWANTLIST + "(\"obj_url\",\"obj_etag\") VALUES ('" + url + "','" + etag + "')";
executeSQL(newurl);
}
+
public ArrayList getForgottenList() throws SQLException {
- String urlList = "SELECT \"obj_url\" FROM \"" + NOTWANTLIST+ "\"";
+ String urlList = "SELECT \"obj_url\" FROM \"" + NOTWANTLIST + "\"";
Statement stmt = conn.createStatement();
stmt.execute(urlList);
ResultSet rs = stmt.getResultSet();
ArrayList urllist = new ArrayList();
- while(rs.next()) {
+ while (rs.next()) {
String url = rs.getString("obj_url");
urllist.add(url);
}
@@ -292,28 +395,33 @@ public class ObjectTracking {
rs = null;
return urllist;
}
+
public void deleteForgottenURL(String url) throws SQLException {
- String deleteurl = "DELETE FROM " + NOTWANTLIST + " WHERE \"obj_url\" = '"+url+"'";
+ String deleteurl = "DELETE FROM " + NOTWANTLIST + " WHERE \"obj_url\" = '" + url + "'";
executeSQL(deleteurl);
}
+
public boolean isURLForgotten(String url) throws SQLException {
- String findObject = "SELECT \"obj_url\" FROM \"" + NOTWANTLIST + "\" WHERE \"obj_url\" = '"+url+"'";
+ String findObject = "SELECT \"obj_url\" FROM \"" + NOTWANTLIST + "\" WHERE \"obj_url\" = '" + url + "'";
Statement stmt = conn.createStatement();
stmt.execute(findObject);
ResultSet rs = stmt.getResultSet();
return rs.next();
}
+
public String getEtagForForgottenURL(String url) throws SQLException {
- String findObject = "SELECT \"obj_etag\" FROM \"" + NOTWANTLIST + "\" WHERE \"obj_url\" = '"+url+"'";
+ String findObject = "SELECT \"obj_etag\" FROM \"" + NOTWANTLIST + "\" WHERE \"obj_url\" = '" + url + "'";
return get1x1SQL(findObject);
-
+
}
/* Execute SQL statement which doesn't need ResultSet etc. */
+
private void executeSQL(String sql) throws SQLException {
Statement stmt = conn.createStatement();
stmt.execute(sql);
stmt = null;
}
+
/**
* Return a result where there is only one row and one column
* @param sql SQL to Execute
@@ -330,43 +438,6 @@ public class ObjectTracking {
}
return rs.getString(1);
}
- public static void main(String args[]) {
- ObjectTracking obtrack = new ObjectTracking("C:\\trackstore");
- try {
- obtrack.init();
- obtrack.deleteObject("testobject1");
- obtrack.createObject("testobject1","http://server/groupdav/object","2222","Test event","BEGIN:VCALENDAR\r\nEND:VCALENDAR",1161250627,1161250646);
- System.out.println(obtrack.doesObjectExist("testobject1"));
- System.out.println(obtrack.doesObjectExist("nonexistent"));
- ArrayList uids = obtrack.getUIDList();
- for (int i = 0; i < uids.size(); i++) {
- String uid = (String)uids.get(i);
- String url = obtrack.getObjectURL(uid);
- String etag = obtrack.getObjectEtag(uid);
- String name = obtrack.getObjectName(uid);
- String data = obtrack.getObjectContents(uid);
- long dtstart = obtrack.getDtStartForUid(uid);
- long dtend = obtrack.getDtEndFromUid(uid);
- System.out.println("----------");
- System.out.println("UID:"+uid);
- System.out.println("URL:"+url);
- System.out.println("ETAG:"+etag);
- System.out.println("NAME:"+name);
- System.out.println("DTSTART:"+dtstart);
- System.out.println("DTEND:"+dtend);
- System.out.println("DATA FOLLOWS:");
- System.out.println(data);
- System.out.println("----------");
- }
- obtrack.updateEtag("testobject1","4444");
- System.out.println("New etag: "+obtrack.getObjectEtag("testobject1"));
- obtrack.updateObject("testobject1","BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VCALENDAR");
- System.out.println(obtrack.getObjectContents("testobject1"));
- obtrack.deleteObject("testobject1");
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
public static final String CREATE_ETAG_LIST =
"CREATE TABLE etaglist\n" +
"(\n" +
@@ -374,33 +445,35 @@ public class ObjectTracking {
"obj_etag VARCHAR(255) not null\n" +
")";
public static final String CREATE_NAME_LIST =
- "CREATE TABLE namelist(\n"+
- "obj_uid VARCHAR(255) not null,\n"+
- "obj_name VARCHAR(255) not null\n"+
+ "CREATE TABLE namelist(\n" +
+ "obj_uid VARCHAR(255) not null,\n" +
+ "obj_name VARCHAR(255) not null\n" +
")";
public static final String CREATE_OBJECT =
- "CREATE TABLE objects(\n"+
- "obj_uid VARCHAR(255) not null,\n"+
- "obj_contents LONGVARBINARY\n"+
+ "CREATE TABLE objects(\n" +
+ "obj_uid VARCHAR(255) not null,\n" +
+ "obj_contents LONGVARBINARY\n" +
")";
public static final String CREATE_OBJLIST =
- "CREATE TABLE objlist(\n"+
- "obj_uid VARCHAR(255) not null\n"+
+ "CREATE TABLE objlist(\n" +
+ "obj_source VARCHAR(255) not null," +
+ "obj_uid VARCHAR(255) not null" +
")";
public static final String CREATE_URLLIST =
- "CREATE TABLE urllist(\n"+
- "obj_uid VARCHAR(255) not null,"+
- "obj_url VARCHAR(2048) not null"+
+ "CREATE TABLE urllist(\n" +
+ "obj_source VARCHAR(255) not null," +
+ "obj_uid VARCHAR(255) not null," +
+ "obj_url VARCHAR(2048) not null" +
")";
public static final String CREATE_DATELIST =
- "CREATE TABLE datelist(\n"+
- "obj_uid VARCHAR(255) not null,"+
- "obj_dtstart INT not null,"+
- "obj_dtend INT not null"+
+ "CREATE TABLE datelist(\n" +
+ "obj_uid VARCHAR(255) not null," +
+ "obj_dtstart INT not null," +
+ "obj_dtend INT not null" +
")";
public static final String CREATE_NOTWANTED =
- "CREATE TABLE notwanted(\n"+
- "obj_url VARCHAR(255) not null,"+
- "obj_etag VARCHAR(255) not null"+
+ "CREATE TABLE notwanted(\n" +
+ "obj_url VARCHAR(255) not null," +
+ "obj_etag VARCHAR(255) not null" +
")";
}
diff --git a/src/main/java/net/bionicmessage/utils/HTMLFormatter.java b/src/main/java/net/bionicmessage/utils/HTMLFormatter.java
index 02f66b1..0da7905 100755
--- a/src/main/java/net/bionicmessage/utils/HTMLFormatter.java
+++ b/src/main/java/net/bionicmessage/utils/HTMLFormatter.java
@@ -38,8 +38,8 @@ public class HTMLFormatter extends Formatter {
String LASTCLASS = "";
String LASTMETHOD = "";
- /** Creates a new instance of HTMLFormatter */
+ /** Creates a new instance of HTMLFormatter */
public HTMLFormatter() {
}
@@ -48,7 +48,7 @@ public class HTMLFormatter extends Formatter {
if (LASTCLASS.equals(record.getSourceClassName())) {
records.append("");
if (LASTMETHOD.equals(record.getSourceMethodName())) {
-
+
records.append(addMessage(record.getMessage()));
if (record.getThrown() != null) {
Throwable throwed = record.getThrown();
@@ -68,6 +68,8 @@ public class HTMLFormatter extends Formatter {
LASTMETHOD = record.getSourceMethodName();
records.append("");
records.append(record.getSourceClassName());
+ records.append(":");
+ records.append(System.currentTimeMillis());
records.append("
");
records.append(addMethodName(record.getSourceMethodName()));
records.append("");
@@ -111,10 +113,13 @@ public class HTMLFormatter extends Formatter {
}
return null;
}
+
private String addMethodName(String msg) {
StringBuffer records = new StringBuffer();
records.append("");
records.append(msg);
+ records.append(":");
+ records.append(System.currentTimeMillis());
records.append("
");
return records.toString();
}
diff --git a/src/main/java/net/bionicmessage/utils/JDBCConnectionFactory.java b/src/main/java/net/bionicmessage/utils/JDBCConnectionFactory.java
new file mode 100644
index 0000000..c4d6d3a
--- /dev/null
+++ b/src/main/java/net/bionicmessage/utils/JDBCConnectionFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+package net.bionicmessage.utils;
+
+import java.util.Hashtable;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * A 'factory' singleton-type thingy that ensures only ONE connection to a JDBC
+ * resource exists
+ * @author matt
+ */
+public class JDBCConnectionFactory {
+
+ private static JDBCConnectionFactory instance =
+ null;
+ private static Hashtable connectionTable = null;
+
+ private JDBCConnectionFactory() {
+ connectionTable = new Hashtable();
+ }
+
+ public static JDBCConnectionFactory getInstance() {
+ if (instance == null) {
+ return new JDBCConnectionFactory();
+ }
+ return instance;
+ }
+
+ public static Connection getConnection(String jdbcID) throws SQLException {
+ if (connectionTable.get(jdbcID) != null) {
+ return connectionTable.get(jdbcID);
+ }
+ // Else, create one
+ Connection conn = java.sql.DriverManager.getConnection(jdbcID);
+ connectionTable.put(jdbcID, conn);
+ return conn;
+ }
+
+ public static void removeConnection(String jdbcID) {
+ connectionTable.remove(jdbcID);
+ }
+
+ public static boolean doesConnectionExist(String jdbcID) {
+ if (connectionTable.get(jdbcID) != null) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/test/java/MultipleSourceICalendarObjectStoreTest.java b/src/test/java/MultipleSourceICalendarObjectStoreTest.java
index 2718509..44f6b91 100644
--- a/src/test/java/MultipleSourceICalendarObjectStoreTest.java
+++ b/src/test/java/MultipleSourceICalendarObjectStoreTest.java
@@ -98,7 +98,7 @@ public class MultipleSourceICalendarObjectStoreTest {
long end = dte.getDate().getTime() / 1000;
String uid = ve.getUid().getValue();
String summary = ve.getSummary().getValue();
- uidadded = ico.addObject("two",uid,summary, sample.toString(), start, end);
+ uidadded = ico.addObject("default",uid,summary, sample.toString(), start, end);
ico.printDebugReport();
ico.close();
// Start again
@@ -123,7 +123,7 @@ public class MultipleSourceICalendarObjectStoreTest {
long end = dte.getDate().getTime() / 1000;
String uid = ve.getUid().getValue();
String summary = ve.getSummary().getValue();
- uidadded = ico.addObject("two",uid,summary, sample.toString(), start, end);
+ uidadded = ico.addObject("default",uid,summary, sample.toString(), start, end);
ico.printDebugReport();
ico.close();
// Start up again
--
2.11.4.GIT