source: trunk/greenstone3-extensions/gsdl-as/src/org/greenstone/gsdlas/ProfileStore.java@ 8867

Last change on this file since 8867 was 8867, checked in by schweer, 19 years ago

fixed BTS 12: restore subscriptions/predicates from database

  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1/*
2 * Created on Oct 27, 2004
3 * Copyright (C) Andrea Schweer, 2004
4 *
5 * This file is part of the Greenstone Alerting Service.
6 * Refer to the COPYING file in the base directory of this package
7 * for licensing information.
8 */
9package org.greenstone.gsdlas;
10
11import java.sql.*;
12import java.sql.Connection;
13import java.sql.Statement;
14import java.util.*;
15
16import javax.servlet.http.HttpSession;
17
18import org.greenstone.gsdlas.database.DatabaseException;
19import org.greenstone.gsdlas.database.DatabaseManager;
20import org.greenstone.gsdlas.profiles.*;
21
22/**
23 * Storage for all Profiles. Singleton.
24 *
25 * @author schweer
26 *
27 */
28public class ProfileStore {
29
30 private static ProfileStore instance;
31
32 private Set noEqualsSubscriptions = new TreeSet();
33 private Map dontCareSubscriptions = new TreeMap();
34 private Map subscriptions = new TreeMap();
35
36
37 private ProfileStore() {
38 // TODO restore subscriptions from database
39 }
40
41 /**
42 * @return the one existing instance of this class.
43 */
44 public static ProfileStore getInstance() {
45 if (instance == null) {
46 instance = new ProfileStore();
47 }
48 return instance;
49 }
50
51 /**
52 * @param subscription
53 * the subscription to add to the profile store.
54 */
55 private void addSubscription(Subscription subscription) {
56 List documentIdPredicate = subscription.getPredicateList("documentID");
57 List collectionIdPredicate = subscription.getPredicateList("collectionID");
58 List hostIdPredicate = subscription.getPredicateList("hostID");
59 List typePredicate = subscription.getPredicateList("type");
60
61 Integer subId = new Integer(subscription.getId());
62
63 if (documentIdPredicate.isEmpty()) {
64 if (!dontCareSubscriptions.containsKey("documentID")) {
65 dontCareSubscriptions.put("documentID", new TreeSet());
66 }
67 Set list = (Set) dontCareSubscriptions.get("documentID");
68 list.add(subId);
69 }
70 if (collectionIdPredicate.isEmpty()) {
71 if (!dontCareSubscriptions.containsKey("collectionID")) {
72 dontCareSubscriptions.put("collectionID", new TreeSet());
73 }
74 Set list = (Set) dontCareSubscriptions.get("collectionID");
75 list.add(subId);
76 }
77 if (hostIdPredicate.isEmpty()) {
78 if (!dontCareSubscriptions.containsKey("hostID")) {
79 dontCareSubscriptions.put("hostID", new TreeSet());
80 }
81 Set list = (Set) dontCareSubscriptions.get("hostID");
82 list.add(subId);
83 }
84 if (typePredicate.isEmpty()) {
85 if (!dontCareSubscriptions.containsKey("type")) {
86 dontCareSubscriptions.put("type", new TreeSet());
87 }
88 Set list = (Set) dontCareSubscriptions.get("type");
89 list.add(subId);
90 }
91
92 if (documentIdPredicate.isEmpty() && collectionIdPredicate.isEmpty()
93 && hostIdPredicate.isEmpty() && typePredicate.isEmpty()) {
94 noEqualsSubscriptions.add(subId);
95 }
96 subscriptions.put(subId, subscription);
97 }
98
99 /**
100 * @return
101 */
102 public Set getSubscriptionsWithoutEqualsPredicates() {
103 return Collections.unmodifiableSet(noEqualsSubscriptions);
104 }
105
106 /**
107 * Computes the list of equality subscriptions satisfied by the event.
108 * @param event
109 * @return
110 */
111 public Set getPartiallyMatchedSubscriptions(Map event) {
112 Set result = new TreeSet();
113 // TODO rework algo for getting partially matched subs
114 IdEqualsPredicate predicate;
115 predicate = PredicateFactory.getIdEqualsPredicate("type", (String)event.get("type"));
116 if (predicate != null)
117 result.addAll(predicate.getSubscriptionIDs());
118
119 Set docIDSubs = new TreeSet();
120 predicate = PredicateFactory.getIdEqualsPredicate("documentID", (String)event.get("documentID"));
121 if (predicate != null)
122 docIDSubs.addAll(predicate.getSubscriptionIDs());
123 docIDSubs.addAll(getDontCareSubscriptions("documentID"));
124 result.retainAll(docIDSubs);
125
126 Set collIDSubs = new TreeSet();
127 predicate = PredicateFactory.getIdEqualsPredicate("collectionID", (String)event.get("collectionID"));
128 if (predicate != null)
129 collIDSubs.addAll(predicate.getSubscriptionIDs());
130 collIDSubs.addAll(getDontCareSubscriptions("collectionID"));
131 result.retainAll(collIDSubs);
132
133 Set hostIDSubs = new TreeSet();
134 predicate = PredicateFactory.getIdEqualsPredicate("hostID", (String)event.get("hostID"));
135 if (predicate != null)
136 hostIDSubs.addAll(predicate.getSubscriptionIDs());
137 hostIDSubs.addAll(getDontCareSubscriptions("hostID"));
138 result.retainAll(hostIDSubs);
139
140 return result;
141 }
142
143 /**
144 *
145 * @param gsComm
146 * @return
147 * @throws UnsupportedFieldException
148 */
149 private Set findMatchedQueryPredicates(Map event, GreenstoneCommunicator gsComm) {
150 Set matchedPreds = new TreeSet();
151
152 // iterate through all document content predicates
153 // execute the query stored in the predicate
154 // predicate is matched iff the docID occurs in the query result
155
156 for (Iterator iter = PredicateFactory.getQueryPredicates("document_content").iterator(); iter.hasNext();) {
157 Predicate predicate = (Predicate) iter.next();
158 String collection = (String) event.get("collectionID");
159 String query = predicate.getValue();
160 Set results;
161 try {
162 results = gsComm.fullTextSearch(collection, query);
163 if (results.contains(event.get("documentID"))) {
164 matchedPreds.add(predicate);
165 }
166 } catch (Exception e) {
167 }
168 }
169
170 return matchedPreds;
171 }
172
173 /**
174 * Computes the set of SubstringMatchPredicates satisfied by the event.
175 * @param event
176 *
177 * @return
178 */
179 private Set findMatchedSubstringMatchPredicates(Map event) {
180 Set result = new TreeSet();
181
182 for (Iterator iter = PredicateFactory.getAllSubstringMatchPredicates().iterator(); iter.hasNext();) {
183 Predicate predicate = (Predicate) iter.next();
184 if (predicate.isSatisfied(event)) {
185 result.add(predicate);
186 }
187 }
188 return result;
189 }
190
191 /**
192 * Filters the event against the profiles. It uses the equality-preferred
193 * algorithm as described in Fabret, Llirbat, Pereira and Shasha:
194 * <em>Efficient Matching for Content-based Publish/Subscribe
195 * Systems</em>.
196 * @param event
197 * @param gsComm
198 */
199 public Set filter(Map event, GreenstoneCommunicator gsComm) {
200 Set matchedSubscriptions = new TreeSet();
201
202 Set partiallyMatchedSubscriptions
203 = getPartiallyMatchedSubscriptions(event);
204
205 Set matchedPredicates = findMatchedSubstringMatchPredicates(event);
206 matchedPredicates.addAll(findMatchedQueryPredicates(event, gsComm));
207
208 Map numMatchedPredicates = new TreeMap();
209 for (Iterator iter = matchedPredicates.iterator(); iter.hasNext();) {
210 Predicate pred = (Predicate) iter.next();
211 for (Iterator iterator = pred.getSubscriptionIDs().iterator(); iterator
212 .hasNext();) {
213 Integer subId = (Integer) iterator.next();
214 Subscription sub = (Subscription) subscriptions.get(subId);
215 Integer count = (Integer) numMatchedPredicates.get(subId);
216 int newCountValue = (count == null ? 1 : count.intValue() + 1);
217 numMatchedPredicates.put(subId,
218 new Integer(newCountValue));
219 }
220 }
221
222 Set notUnmatchedSubscriptions = partiallyMatchedSubscriptions;
223 notUnmatchedSubscriptions.addAll(noEqualsSubscriptions);
224 for (Iterator iter = notUnmatchedSubscriptions.iterator(); iter
225 .hasNext();) {
226 Integer subId = (Integer) iter.next();
227 Subscription sub = (Subscription) subscriptions.get(subId);
228 int matchedPredicatesCount = 0;
229 if (numMatchedPredicates.get(subId) != null) {
230 matchedPredicatesCount = ((Integer) numMatchedPredicates.get(subId)).intValue();
231 }
232 if (matchedPredicatesCount == sub.getNumOfNonEqualsPredicates()) {
233 matchedSubscriptions.add(sub);
234 }
235 }
236 return matchedSubscriptions;
237 }
238
239
240 /**
241 * @param arguments
242 * @throws Exception
243 */
244 public void createSubscription(Map arguments) throws Exception {
245 Subscription sub = new Subscription(arguments);
246 addSubscription(sub);
247 }
248
249
250 /**
251 * @param subscriptionID
252 * @throws DatabaseException
253 * @throws SQLException
254 */
255 public void deleteSubscription(String subscriptionID) throws DatabaseException, SQLException {
256 Integer subID = new Integer(subscriptionID);
257 System.out.println("deleting subscription " + subscriptionID);
258 if (!subscriptions.containsKey(subID)) {
259 return;
260 }
261 Subscription sub = (Subscription) subscriptions.get(subID);
262 for (Iterator iter = dontCareSubscriptions.values().iterator(); iter.hasNext();) {
263 Set entry = (Set) iter.next();
264 if (entry.contains(subID))
265 entry.remove(subID);
266 }
267 if (noEqualsSubscriptions.contains(subID))
268 noEqualsSubscriptions.remove(subID);
269 for (Iterator iter = sub.getPredicates().iterator(); iter.hasNext();) {
270 Predicate pred = (Predicate) iter.next();
271 pred.removeSubscription(subID);
272 }
273
274 subscriptions.remove(subID);
275
276
277 Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
278
279 Statement statement = conn.createStatement();
280
281 String sqlString = "DELETE FROM subscriptions WHERE id = " + subscriptionID;
282 statement.executeUpdate(sqlString);
283
284 sqlString = "SELECT predicate FROM subs_to_predicates " +
285 "WHERE subscription = " + subscriptionID;
286 ResultSet predicates = statement.executeQuery(sqlString);
287 while (predicates.next()) {
288 // if there aren't any other subscriptions using this predicate, delete predicate
289 int predicateID = predicates.getInt("predicate");
290
291 }
292
293
294 }
295
296 /**
297 * @param arguments
298 * @param session
299 */
300 public void changeSubscription(Map arguments, HttpSession session) {
301 String subscriptionID = (String) arguments.get("subscriptionID");
302 // TODO Auto-generated method stub
303
304 }
305
306 /**
307 * @param username
308 * @return
309 * @throws DatabaseException
310 */
311 public Set getAllSubscriptionsFor(String username) throws DatabaseException {
312 Set result = new TreeSet();
313 try {
314 Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
315 Statement statement = conn.createStatement();
316 String sqlString = "SELECT id FROM subscriptions " +
317 "WHERE user like '" + username + "';";
318 ResultSet idList = statement.executeQuery(sqlString);
319 while (idList.next()) {
320 int id = idList.getInt("id");
321 result.add(subscriptions.get(new Integer(id)));
322 }
323 } catch (SQLException e) {
324 e.printStackTrace();
325 }
326
327 return result;
328 }
329
330 /**
331 * @param string
332 * @return
333 */
334 private Set getDontCareSubscriptions(String field) {
335 Set result = new TreeSet();
336 if (dontCareSubscriptions.containsKey(field)) {
337 result = (Set) dontCareSubscriptions.get(field);
338 }
339 return result;
340 }
341
342 /**
343 *
344 */
345 public void restoreFromDatabase() {
346 try {
347 Connection conn = DatabaseManager.getInstance().getDatabaseConnection();
348 Statement statement = conn.createStatement();
349 String sqlString = "SELECT * FROM subscriptions";
350 ResultSet subs = statement.executeQuery(sqlString);
351 while (subs.next()) {
352 // construct map for all predicates
353 int id = subs.getInt("id");
354 Map map = new TreeMap();
355 map.put("username", subs.getString("user"));
356 map.put("email", subs.getString("email"));
357 map.put("subscription_name", subs.getString("name"));
358 Vector ways = new Vector();
359 if (subs.getInt("rss") != 0) {
360 ways.add("rss");
361 }
362 if (subs.getInt("page") != 0) {
363 ways.add("page");
364 }
365 map.put("way", ways);
366 Statement stmnt = conn.createStatement();
367 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 + ";";
368 ResultSet predicates = stmnt.executeQuery(sqlString);
369 while (predicates.next()) {
370 String type = predicates.getString("type");
371 String field = predicates.getString("field");
372 if (type.equals(SubstringMatchPredicate.class.getName())) {
373 if (field.equals("colletionID")) {
374 field = "collection_query";
375 } else if (field.equals("hostID")) {
376 field = "host_query";
377 }
378 }
379 String value = predicates.getString("value");
380 if (type.equals(IdEqualsPredicate.class.getName())) {
381 if (!map.containsKey(field)) {
382 map.put(field, new Vector());
383 }
384 ((List) map.get(field)).add(value);
385 } else {
386 map.put(field, value);
387 }
388 }
389 try {
390 createSubscription(map);
391 } catch (Exception e1) {
392 // TODO Auto-generated catch block
393 e1.printStackTrace();
394 }
395 }
396 } catch (SQLException e) {
397 // TODO Auto-generated catch block
398 e.printStackTrace();
399 } catch (DatabaseException e) {
400 // TODO Auto-generated catch block
401 e.printStackTrace();
402 }
403 }
404
405}
Note: See TracBrowser for help on using the repository browser.