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

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

started to use constants instead of strings

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