Index: trunk/greenstone3-extensions/gsdl-as/create-tables.sql
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/create-tables.sql	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/create-tables.sql	(revision 8867)
@@ -19,6 +19,7 @@
 	field varchar(128) not null, 
 	value varchar(255), 
+	type enum("org.greenstone.gsdlas.profiles.IdEqualsPredicate", "org.greenstone.gsdlas.profiles.SubstringMatchPredicate", "org.greenstone.gsdlas.profiles.QueryPredicate") not null,
 	
-	unique(field,value)
+	unique(field,type,value)
 );
 
Index: trunk/greenstone3-extensions/gsdl-as/lib/templates/list.vm
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/lib/templates/list.vm	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/lib/templates/list.vm	(revision 8867)
@@ -14,5 +14,5 @@
 	<div class="subscription">
 		<p><span class="sub_id">Subscription $sub.Id</span><br/>
-		<a href="service?action=showFeed&subscriptionID=$sub.Id">show matching events</a> | <a href="service?action=editSubscription&subscriptionID=$sub.Id">edit subscription</a></p>
+		<a href="service?action=showFeed&subscriptionID=$sub.Id">show matching events</a> | <a href="service?action=editSubscription&subscriptionID=$sub.Id">edit subscription</a> | <a href="service?action=deleteSubscription&subscriptionID=$sub.Id">delete subscription</a></p>
 		<table class="subscription">
 			<thead>
Index: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/AlertingService.java
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/AlertingService.java	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/AlertingService.java	(revision 8867)
@@ -12,6 +12,9 @@
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.sql.SQLException;
 import java.util.*;
 
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
 import javax.servlet.http.*;
 
@@ -33,4 +36,22 @@
 public class AlertingService extends VelocityServlet {
     
+    /* (non-Javadoc)
+     * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
+     */
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        System.out.println("reloading subs");
+        ProfileStore.getInstance().restoreFromDatabase();
+        try {
+            Set subs = ProfileStore.getInstance().getAllSubscriptionsFor("andrea");
+            System.out.println("reloaded " + subs.size() + " subs for andrea: ");
+            for (Iterator iter = subs.iterator(); iter.hasNext();) {
+                System.out.println(iter.next());
+            }
+        } catch (DatabaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
     public static final String[] actions = new String[] {
             "createSubscription",
@@ -129,5 +150,13 @@
         }
         String subscriptionID = (String) arguments.get("subscriptionID");
-        ProfileStore.getInstance().deleteSubscription(subscriptionID);
+        try {
+            ProfileStore.getInstance().deleteSubscription(subscriptionID);
+        } catch (DatabaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
         return listSubscriptions(arguments, context);
     }
Index: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/ProfileStore.java
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/ProfileStore.java	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/ProfileStore.java	(revision 8867)
@@ -54,5 +54,4 @@
      */
     private void addSubscription(Subscription subscription) {
-        // TODO change to lists
         List documentIdPredicate = subscription.getPredicateList("documentID");
         List collectionIdPredicate = subscription.getPredicateList("collectionID");
@@ -237,42 +236,4 @@
         return matchedSubscriptions;
     }
-//
-//    public String toString() {
-//        Set allSubscriptions = getAllSubscriptions();
-//        
-//        StringBuffer buffer = new StringBuffer();
-//        
-//        for (Iterator iter = allSubscriptions.iterator(); iter.hasNext();) {
-//            Subscription sub = (Subscription) iter.next();
-//            buffer.append(sub);
-//            buffer.append("\n");
-//        }
-//        
-//        return buffer.toString();
-//    }
-//
-//    /**
-//     * @return
-//     */
-//    public Set getAllSubscriptions() {
-//        Set allSubscriptions = new TreeSet();
-//        allSubscriptions.addAll(noEqualsSubscriptions);
-//        
-//        for(Iterator iter = docIdEqualsSubscriptions.values().iterator(); iter.hasNext();) {
-//            Set values = (Set) iter.next();
-//            allSubscriptions.addAll(values);
-//        }
-//        
-//        for(Iterator iter = docCollectionIdEqualsSubscriptions.values().iterator(); iter.hasNext();) {
-//            Set values = (Set) iter.next();
-//            allSubscriptions.addAll(values);
-//        }
-//        
-//        for(Iterator iter = collectionIdEqualsSubscriptions.values().iterator(); iter.hasNext();) {
-//            Set values = (Set) iter.next();
-//            allSubscriptions.addAll(values);
-//        }
-//        return Collections.unmodifiableSet(allSubscriptions);
-//    }
 
 
@@ -289,11 +250,45 @@
     /**
      * @param subscriptionID
-     */
-    public void deleteSubscription(String subscriptionID) {
-        // delete row from subscriptions table 
-        // for each predicate:
-        // delete row from subs_to_predicates
-        // if there aren't any other subscriptions using this predicate, delete predicate
-        // TODO Auto-generated method stub
+     * @throws DatabaseException
+     * @throws SQLException
+     */
+    public void deleteSubscription(String subscriptionID) throws DatabaseException, SQLException {
+        Integer subID = new Integer(subscriptionID);
+        System.out.println("deleting subscription " + subscriptionID);
+        if (!subscriptions.containsKey(subID)) {
+            return;
+        }
+        Subscription sub = (Subscription) subscriptions.get(subID);
+        for (Iterator iter = dontCareSubscriptions.values().iterator(); iter.hasNext();) {
+            Set entry = (Set) iter.next();
+            if (entry.contains(subID))
+                entry.remove(subID);
+        }
+        if (noEqualsSubscriptions.contains(subID))
+            noEqualsSubscriptions.remove(subID);
+        for (Iterator iter = sub.getPredicates().iterator(); iter.hasNext();) {
+            Predicate pred = (Predicate) iter.next();
+            pred.removeSubscription(subID);
+        }
+
+        subscriptions.remove(subID);
+        
+        
+        Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
+        
+        Statement statement = conn.createStatement();
+        
+        String sqlString = "DELETE FROM subscriptions WHERE id = " + subscriptionID;
+        statement.executeUpdate(sqlString);
+        
+        sqlString = "SELECT predicate FROM subs_to_predicates " +
+        		"WHERE subscription = " + subscriptionID;
+        ResultSet predicates = statement.executeQuery(sqlString);
+        while (predicates.next()) {
+            // if there aren't any other subscriptions using this predicate, delete predicate
+            int predicateID = predicates.getInt("predicate");
+            
+        }
+        
         
     }
@@ -344,4 +339,67 @@
         return result;
     }
+
+    /**
+     * 
+     */
+    public void restoreFromDatabase() {
+        try {
+            Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
+            Statement statement = conn.createStatement();
+            String sqlString = "SELECT * FROM subscriptions";
+            ResultSet subs = statement.executeQuery(sqlString);
+            while (subs.next()) {
+                // construct map for all predicates
+                int id = subs.getInt("id");
+                Map map = new TreeMap();
+                map.put("username", subs.getString("user"));
+                map.put("email", subs.getString("email"));
+                map.put("subscription_name", subs.getString("name"));
+                Vector ways = new Vector();
+                if (subs.getInt("rss") != 0) {
+                    ways.add("rss");
+                }
+                if (subs.getInt("page") != 0) {
+                    ways.add("page");
+                }
+                map.put("way", ways);
+                Statement stmnt = conn.createStatement();
+                sqlString = "SELECT p.type, p.field, p.value from subs_to_predicates stp join predicates p on(stp.predicate = p.id) where stp.subscription = " + id + ";";
+                ResultSet predicates = stmnt.executeQuery(sqlString);
+                while (predicates.next()) {
+                    String type = predicates.getString("type");
+                    String field = predicates.getString("field");
+                    if (type.equals(SubstringMatchPredicate.class.getName())) {
+                        if (field.equals("colletionID")) {
+                            field = "collection_query";
+                        } else if (field.equals("hostID")) {
+                            field = "host_query";
+                        }
+                    }
+                    String value = predicates.getString("value");
+                    if (type.equals(IdEqualsPredicate.class.getName())) {
+                        if (!map.containsKey(field)) {
+                            map.put(field, new Vector());
+                        }
+                        ((List) map.get(field)).add(value);
+                    } else {
+                        map.put(field, value);
+                    }
+                }
+                try {
+                    createSubscription(map);
+                } catch (Exception e1) {
+                    // TODO Auto-generated catch block
+                    e1.printStackTrace();
+                }
+            }
+        } catch (SQLException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (DatabaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
     
 }
Index: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Predicate.java
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Predicate.java	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Predicate.java	(revision 8867)
@@ -119,15 +119,17 @@
         String query = "SELECT id FROM predicates " +
         		"WHERE field = '" + field + 
-        		"' AND value = '" + value + "';";
+        		"' AND value = '" + value + 
+        		"' AND type = '" + this.getClass().getName() + "';";
         Statement statement = DatabaseManager.getInstance().getDatabaseConnection().createStatement();
         System.out.println(query);
         ResultSet result = statement.executeQuery(query);
         if (result.next()) { // predicate already exists in database
-            System.out.println("predicate " + id + " already exists");
-            return result.getInt("id");
+            int id = result.getInt("id"); 
+            System.out.println("predicate already exists with id " + id);
+            return id;
         }
         // predicate has been newly created
-        String insert = "INSERT INTO predicates (field, value) " +
-        "VALUES ('" + field + "', '" + value + "');";
+        String insert = "INSERT INTO predicates (field, type, value) " +
+        "VALUES ('" + field + "', '" + this.getClass().getName() + "', '" + value + "');";
         System.out.println(insert);
         statement.execute(insert);
@@ -141,11 +143,4 @@
 
     /**
-     * @return
-     */
-    public List getValueList() {
-        throw new UnsupportedOperationException("you can only call this method for multi-valued predicates");
-    }
-
-    /**
      * @param key
      * @return
@@ -154,4 +149,25 @@
         return ArrayHelper.contains(singleValueFields, key) || ArrayHelper.contains(multiValueFields, key);
     }
+
+    /**
+     * @param subID
+     * @throws DatabaseException
+     * @throws SQLException
+     */
+    public void removeSubscription(Integer subID) throws SQLException, DatabaseException {
+        subscriptions.remove(subID);
+
+        Statement statement = DatabaseManager.getInstance().getDatabaseConnection().createStatement();
+        String sqlString = "DELETE FROM subs_to_predicates " +
+        	"WHERE subscription = " + subID + 
+        	" AND predicate = " + id;
+        statement.executeUpdate(sqlString);
+        
+        if (subscriptions.isEmpty()) {
+            PredicateFactory.deletePredicate(this);
+            sqlString = "DELETE FROM predicates WHERE id = " + id;
+            statement.executeUpdate(sqlString);
+        }
+    }
     
 }
Index: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/PredicateFactory.java
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/PredicateFactory.java	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/PredicateFactory.java	(revision 8867)
@@ -208,4 +208,37 @@
         return result;
     }
+
+    /**
+     * @param predicate
+     */
+    public static void deletePredicate(Predicate predicate) {
+        String field = predicate.getField();
+        String value = predicate.getValue();
+        
+        if (predicate instanceof IdEqualsPredicate) {
+            Map map = (Map) idEqualsPredicates.get(field);
+            if (map.containsKey(value)) {
+                map.remove(value);
+            }
+        } else if (predicate instanceof QueryPredicate) {
+            if (field.equals("document_title")) {
+                documentTitleQueryPredicates.remove(value);
+            } else if (field.equals("document_content")) {
+                documentContentQueryPredicates.remove(value);
+            } else {
+                System.err.println("problem while removing: unknown field " + field);
+            }
+        } else if (predicate instanceof SubstringMatchPredicate) {
+            if (field.equals("hostID")) {
+                hostNameMatchPredicates.remove(value);
+            } else if (field.equals("collectionID")) {
+                collectionNameMatchPredicates.remove(value);
+            } else {
+                System.err.println("problem while removing: unknown field " + field);
+            }
+        } else {
+            System.err.println("problem while removing: unknown class " + predicate.getClass().getName());
+        }
+    }
     
 }
Index: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Subscription.java
===================================================================
--- trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Subscription.java	(revision 8847)
+++ trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/profiles/Subscription.java	(revision 8867)
@@ -78,5 +78,5 @@
         rssNotification = valueMap.containsKey("way") && ((List)valueMap.get("way")).contains("rss");
         eventsSincePageNotification = valueMap.containsKey("way") && ((List)valueMap.get("way")).contains("page");
-        id = saveToDatabase(true);
+        id = saveToDatabase();
         
         for (Iterator iter = getPredicates().iterator(); iter.hasNext();) {
@@ -157,8 +157,20 @@
     }
     
-    private int saveToDatabase(boolean initial) throws DatabaseException, SQLException {
+    private int saveToDatabase() throws DatabaseException, SQLException {
         Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
         Statement statement = conn.createStatement();
         String sqlString;
+        boolean initial = true;
+        
+        sqlString = "SELECT id FROM subscriptions WHERE name like '" + name + 
+        			"' AND email like '" + email + "' AND rss=" + (rssNotification ? 1 : 0) 
+        			+ " AND page=" + (eventsSincePageNotification ? 1 : 0) + " AND user like '" +
+        			username + "';";
+        ResultSet result = statement.executeQuery(sqlString);
+        if (result.next()) {
+            initial = false;
+            this.id = result.getInt("id");
+        }
+        
         if (initial) {
             sqlString = "INSERT INTO subscriptions (name, email, rss, page, user) " +
@@ -168,5 +180,5 @@
             sqlString = "UPDATE subscriptions SET name='" + name + "', email='" +
             		email + "', rss=" + (rssNotification ? 1 : 0) + ",page=" + 
-            		(eventsSincePageNotification ? 1 : 0)+ "WHERE id=" + id + ";";
+            		(eventsSincePageNotification ? 1 : 0)+ " WHERE id=" + this.id + ";";
             // cannot change user
         }
@@ -178,6 +190,6 @@
         			username + "';";
         System.out.println(sqlString);
-        ResultSet result = statement.executeQuery(sqlString);
-        int id;
+        result = statement.executeQuery(sqlString);
+        
         if (result.next()) {
             id = result.getInt("id");
