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
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(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);
60
61 Integer subId = new Integer(subscription.getId());
62
63 if (documentIdPredicate.isEmpty()) {
64 if (!dontCareSubscriptions.containsKey(Constants.DOCUMENT_ID_FIELD)) {
65 dontCareSubscriptions.put(Constants.DOCUMENT_ID_FIELD, new TreeSet());
66 }
67 Set list = (Set) dontCareSubscriptions.get(Constants.DOCUMENT_ID_FIELD);
68 list.add(subId);
69 }
70 if (collectionIdPredicate.isEmpty()) {
71 if (!dontCareSubscriptions.containsKey(Constants.COLLECTION_ID_FIELD)) {
72 dontCareSubscriptions.put(Constants.COLLECTION_ID_FIELD, new TreeSet());
73 }
74 Set list = (Set) dontCareSubscriptions.get(Constants.COLLECTION_ID_FIELD);
75 list.add(subId);
76 }
77 if (hostIdPredicate.isEmpty()) {
78 if (!dontCareSubscriptions.containsKey(Constants.HOST_ID_FIELD)) {
79 dontCareSubscriptions.put(Constants.HOST_ID_FIELD, new TreeSet());
80 }
81 Set list = (Set) dontCareSubscriptions.get(Constants.HOST_ID_FIELD);
82 list.add(subId);
83 }
84 if (typePredicate.isEmpty()) {
85 if (!dontCareSubscriptions.containsKey(Constants.TYPE_FIELD)) {
86 dontCareSubscriptions.put(Constants.TYPE_FIELD, new TreeSet());
87 }
88 Set list = (Set) dontCareSubscriptions.get(Constants.TYPE_FIELD);
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(Constants.TYPE_FIELD,
116 (String)event.get(Constants.TYPE_FIELD));
117 if (predicate != null)
118 result.addAll(predicate.getSubscriptionIDs());
119
120 Set docIDSubs = new TreeSet();
121 predicate = PredicateFactory.getIdEqualsPredicate(Constants.DOCUMENT_ID_FIELD,
122 (String)event.get(Constants.DOCUMENT_ID_FIELD));
123 if (predicate != null)
124 docIDSubs.addAll(predicate.getSubscriptionIDs());
125 docIDSubs.addAll(getDontCareSubscriptions(Constants.DOCUMENT_ID_FIELD));
126 result.retainAll(docIDSubs);
127
128 Set collIDSubs = new TreeSet();
129 predicate = PredicateFactory.getIdEqualsPredicate(Constants.COLLECTION_ID_FIELD,
130 (String)event.get(Constants.COLLECTION_ID_FIELD));
131 if (predicate != null)
132 collIDSubs.addAll(predicate.getSubscriptionIDs());
133 collIDSubs.addAll(getDontCareSubscriptions(Constants.COLLECTION_ID_FIELD));
134 result.retainAll(collIDSubs);
135
136 Set hostIDSubs = new TreeSet();
137 predicate = PredicateFactory.getIdEqualsPredicate(Constants.HOST_ID_FIELD,
138 (String)event.get(Constants.HOST_ID_FIELD));
139 if (predicate != null)
140 hostIDSubs.addAll(predicate.getSubscriptionIDs());
141 hostIDSubs.addAll(getDontCareSubscriptions(Constants.HOST_ID_FIELD));
142 result.retainAll(hostIDSubs);
143
144 return result;
145 }
146
147 /**
148 *
149 * @param gsComm
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
160 for (Iterator iter = PredicateFactory.getQueryPredicates(Constants.DOCUMENT_CONTENT_FIELD).iterator(); iter.hasNext();) {
161 Predicate predicate = (Predicate) iter.next();
162 String collection = (String) event.get(Constants.COLLECTION_ID_FIELD);
163 String query = predicate.getValue();
164 Set results;
165 try {
166 results = gsComm.fullTextSearch(collection, query);
167 if (results.contains(event.get(Constants.DOCUMENT_ID_FIELD))) {
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
201 * @param gsComm
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();
215 for (Iterator iterator = pred.getSubscriptionIDs().iterator(); iterator
216 .hasNext();) {
217 Integer subId = (Integer) iterator.next();
218 Subscription sub = (Subscription) subscriptions.get(subId);
219 Integer count = (Integer) numMatchedPredicates.get(subId);
220 int newCountValue = (count == null ? 1 : count.intValue() + 1);
221 numMatchedPredicates.put(subId,
222 new Integer(newCountValue));
223 }
224 }
225
226 Set notUnmatchedSubscriptions = partiallyMatchedSubscriptions;
227 notUnmatchedSubscriptions.addAll(noEqualsSubscriptions);
228 for (Iterator iter = notUnmatchedSubscriptions.iterator(); iter
229 .hasNext();) {
230 Integer subId = (Integer) iter.next();
231 Subscription sub = (Subscription) subscriptions.get(subId);
232 int matchedPredicatesCount = 0;
233 if (numMatchedPredicates.get(subId) != null) {
234 matchedPredicatesCount = ((Integer) numMatchedPredicates.get(subId)).intValue();
235 }
236 if (matchedPredicatesCount == sub.getNumOfNonEqualsPredicates()) {
237 matchedSubscriptions.add(sub);
238 }
239 }
240 return matchedSubscriptions;
241 }
242
243
244 /**
245 * @param arguments
246 * @throws Exception
247 */
248 public void createSubscription(Map arguments) throws Exception {
249 Subscription sub = new Subscription(arguments);
250 addSubscription(sub);
251 }
252
253
254 /**
255 * @param subscriptionID
256 * @throws DatabaseException
257 * @throws SQLException
258 */
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);
279
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
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 }
309
310 /**
311 * @param username
312 * @return
313 * @throws DatabaseException
314 */
315 public Set getAllSubscriptionsFor(String username) throws DatabaseException {
316 Set result = new TreeSet();
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
331 return result;
332 }
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 }
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()) {
374 String type = predicates.getString(Constants.TYPE_FIELD);
375 String field = predicates.getString("field");
376 if (type.equals(SubstringMatchPredicate.class.getName())) {
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;
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 }
408
409}
Note: See TracBrowser for help on using the repository browser.