Source Code Cross Referenced for NotificationCache.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » event » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » sakai » org.sakaiproject.event.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**********************************************************************************
002:         * $URL: https://source.sakaiproject.org/svn/event/tags/sakai_2-4-1/event-impl/impl/src/java/org/sakaiproject/event/impl/NotificationCache.java $
003:         * $Id: NotificationCache.java 7088 2006-03-28 02:35:22Z ggolden@umich.edu $
004:         ***********************************************************************************
005:         *
006:         * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007:         * 
008:         * Licensed under the Educational Community License, Version 1.0 (the "License"); 
009:         * you may not use this file except in compliance with the License. 
010:         * You may obtain a copy of the License at
011:         * 
012:         *      http://www.opensource.org/licenses/ecl1.php
013:         * 
014:         * Unless required by applicable law or agreed to in writing, software 
015:         * distributed under the License is distributed on an "AS IS" BASIS, 
016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
017:         * See the License for the specific language governing permissions and 
018:         * limitations under the License.
019:         *
020:         **********************************************************************************/package org.sakaiproject.event.impl;
021:
022:        import java.util.HashMap;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:        import java.util.Observable;
027:        import java.util.Observer;
028:        import java.util.Vector;
029:
030:        import org.apache.commons.logging.Log;
031:        import org.apache.commons.logging.LogFactory;
032:        import org.sakaiproject.event.api.Event;
033:        import org.sakaiproject.event.api.Notification;
034:        import org.sakaiproject.event.cover.EventTrackingService;
035:        import org.sakaiproject.memory.api.CacheRefresher;
036:        import org.sakaiproject.memory.api.Cacher;
037:        import org.sakaiproject.memory.cover.MemoryService;
038:
039:        /**
040:         * <p>
041:         * A Cache of objects with keys with a limited lifespan.
042:         * </p>
043:         * <p>
044:         * When the object expires, the cache calls upon a CacheRefresher to update the key's value. The update is done in a separate thread.
045:         * </p>
046:         */
047:        public class NotificationCache implements  Cacher, Observer {
048:            /** Our logger. */
049:            private static Log M_log = LogFactory
050:                    .getLog(NotificationCache.class);
051:
052:            /** Map holding cached entries (by reference). */
053:            protected Map m_map = null;
054:
055:            /** Map of notification function to Set of notifications - same objects as in m_map. */
056:            protected Map m_functionMap = null;
057:
058:            /** The object that will deal with expired entries. */
059:            protected CacheRefresher m_refresher = null;
060:
061:            /** The string that all resources in this cache will start with. */
062:            protected String m_resourcePattern = null;
063:
064:            /** If true, we are disabled. */
065:            protected boolean m_disabled = false;
066:
067:            /** If true, we have all the entries that there are in the cache. */
068:            protected boolean m_complete = false;
069:
070:            /** If true, we are going to hold any events we see in the m_heldEvents list for later processing. */
071:            protected boolean m_holdEventProcessing = false;
072:
073:            /** The events we are holding for later processing. */
074:            protected List m_heldEvents = new Vector();
075:
076:            /**
077:             * Construct the Cache. Attempts to keep complete on Event notification by calling the refresher.
078:             * 
079:             * @param refresher
080:             *        The object that will handle refreshing of event notified modified or added entries.
081:             * @param pattern
082:             *        The "startsWith()" string for all resources that may be in this cache.
083:             */
084:            public NotificationCache(CacheRefresher refresher, String pattern) {
085:                m_map = new HashMap();
086:                m_functionMap = new HashMap();
087:
088:                // register as a cacher
089:                MemoryService.registerCacher(this );
090:
091:                m_refresher = refresher;
092:                m_resourcePattern = pattern;
093:
094:                // register to get events - first, before others
095:                EventTrackingService.addPriorityObserver(this );
096:
097:            } // NotificationCache
098:
099:            /**
100:             * Clean up.
101:             */
102:            protected void finalize() {
103:                // unregister as a cacher
104:                MemoryService.unregisterCacher(this );
105:
106:                // ungister to get events
107:                EventTrackingService.deleteObserver(this );
108:
109:            } // finalize
110:
111:            /**
112:             * Cache an object.
113:             * 
114:             * @param key
115:             *        The key with which to find the object.
116:             * @param payload
117:             *        The object to cache.
118:             * @param duration
119:             *        The time to cache the object (seconds).
120:             */
121:            public synchronized void put(Notification payload) {
122:                if (disabled())
123:                    return;
124:
125:                m_map.put(payload.getReference(), payload);
126:
127:                // put in m_functionMap, too, for each function of the notification
128:                List funcs = payload.getFunctions();
129:                for (Iterator iFuncs = funcs.iterator(); iFuncs.hasNext();) {
130:                    String func = (String) iFuncs.next();
131:
132:                    List notifications = (List) m_functionMap.get(func);
133:                    if (notifications == null) {
134:                        notifications = new Vector();
135:                        m_functionMap.put(func, notifications);
136:                    }
137:
138:                    if (!notifications.contains(payload))
139:                        notifications.add(payload);
140:                }
141:
142:            } // cache
143:
144:            /**
145:             * Test for an entry in the cache.
146:             * 
147:             * @param key
148:             *        The cache key.
149:             * @return true if the key maps to an entry, false if not.
150:             */
151:            public synchronized boolean containsKey(Object key) {
152:                if (disabled())
153:                    return false;
154:
155:                // is it there?
156:                if (m_map.containsKey(key)) {
157:                    return true;
158:                }
159:
160:                return false;
161:
162:            } // containsKey
163:
164:            /**
165:             * Get the entry associated with the key, or null if not there
166:             * 
167:             * @param key
168:             *        The cache key.
169:             * @return The entry associated with the key, or null if the a null is cached, or the key is not found (Note: use containsKey() to remove this ambiguity).
170:             */
171:            public synchronized Notification get(Object key) {
172:                if (disabled())
173:                    return null;
174:
175:                return (Notification) m_map.get(key);
176:
177:            } // get
178:
179:            /**
180:             * Get all the non-null entries.
181:             * 
182:             * @return all the non-null entries, or an empty list if none.
183:             */
184:            public List getAll() {
185:                List rv = new Vector();
186:
187:                if (disabled())
188:                    return rv;
189:                if (m_map.isEmpty())
190:                    return rv;
191:
192:                // get the keys as of now
193:                Object[] keys = m_map.keySet().toArray();
194:
195:                // for each entry in the cache
196:                for (int i = 0; i < keys.length; i++) {
197:                    Object payload = m_map.get(keys[i]);
198:
199:                    // skip nulls
200:                    if (payload == null)
201:                        continue;
202:
203:                    // we'll take it
204:                    rv.add(payload);
205:                }
206:
207:                return rv;
208:
209:            } // getAll
210:
211:            /**
212:             * Get all the Notification entries that are watching this Event function.
213:             * 
214:             * @param function
215:             *        The function to use to select Notifications.
216:             * @return all the Notification entries that are watching this Event function.
217:             */
218:            public List getAll(String function) {
219:                return (List) m_functionMap.get(function);
220:
221:            } // getAll
222:
223:            /**
224:             * Get all the keys
225:             * 
226:             * @return The List of key values (Object).
227:             */
228:            public List getKeys() {
229:                List rv = new Vector();
230:                rv.addAll(m_map.keySet());
231:                return rv;
232:
233:            } // getKeys
234:
235:            /**
236:             * Get all the keys, eache modified to remove the resourcePattern prefix. Note: only works with String keys.
237:             * 
238:             * @return The List of keys converted from references to ids (String).
239:             */
240:            public List getIds() {
241:                List rv = new Vector();
242:
243:                List keys = new Vector();
244:                keys.addAll(m_map.keySet());
245:
246:                Iterator it = keys.iterator();
247:                while (it.hasNext()) {
248:                    String key = (String) it.next();
249:                    int i = key.indexOf(m_resourcePattern);
250:                    if (i != -1)
251:                        key = key.substring(i + m_resourcePattern.length());
252:                    rv.add(key);
253:                }
254:
255:                return rv;
256:
257:            } // getKeys
258:
259:            /**
260:             * Clear all entries.
261:             */
262:            public synchronized void clear() {
263:                m_map.clear();
264:                m_functionMap.clear();
265:                m_complete = false;
266:
267:            } // clear
268:
269:            /**
270:             * Remove this entry from the cache.
271:             * 
272:             * @param key
273:             *        The cache key.
274:             */
275:            public synchronized void remove(Object key) {
276:                if (disabled())
277:                    return;
278:
279:                Notification payload = (Notification) m_map.get(key);
280:                m_map.remove(key);
281:
282:                if (payload == null)
283:                    return;
284:
285:                // remove it from the function map for each function
286:                List funcs = payload.getFunctions();
287:                for (Iterator iFuncs = funcs.iterator(); iFuncs.hasNext();) {
288:                    String func = (String) iFuncs.next();
289:
290:                    List notifications = (List) m_functionMap.get(func);
291:                    if (notifications != null) {
292:                        notifications.remove(payload);
293:                        if (notifications.isEmpty()) {
294:                            m_functionMap.remove(func);
295:                        }
296:                    }
297:                }
298:
299:            } // remove
300:
301:            /**
302:             * Disable the cache.
303:             */
304:            public void disable() {
305:                m_disabled = true;
306:                EventTrackingService.deleteObserver(this );
307:                clear();
308:
309:            } // disable
310:
311:            /**
312:             * Enable the cache.
313:             */
314:            public void enable() {
315:                m_disabled = false;
316:                EventTrackingService.addPriorityObserver(this );
317:
318:            } // enable
319:
320:            /**
321:             * Is the cache disabled?
322:             * 
323:             * @return true if the cache is disabled, false if it is enabled.
324:             */
325:            public boolean disabled() {
326:                return m_disabled;
327:
328:            } // disabled
329:
330:            /**
331:             * Are we complete?
332:             * 
333:             * @return true if we have all the possible entries cached, false if not.
334:             */
335:            public boolean isComplete() {
336:                if (disabled())
337:                    return false;
338:
339:                return m_complete;
340:
341:            } // isComplete
342:
343:            /**
344:             * Set the cache to be complete, containing all possible entries.
345:             */
346:            public void setComplete() {
347:                if (disabled())
348:                    return;
349:
350:                m_complete = true;
351:
352:            } // isComplete
353:
354:            /**
355:             * Set the cache to hold events for later processing to assure an atomic "complete" load.
356:             */
357:            public synchronized void holdEvents() {
358:                m_holdEventProcessing = true;
359:
360:            } // holdEvents
361:
362:            /**
363:             * Restore normal event processing in the cache, and process any held events now.
364:             */
365:            public synchronized void processEvents() {
366:                m_holdEventProcessing = false;
367:
368:                for (int i = 0; i < m_heldEvents.size(); i++) {
369:                    Event event = (Event) m_heldEvents.get(i);
370:                    continueUpdate(event);
371:                }
372:
373:                m_heldEvents.clear();
374:
375:            } // holdEvents
376:
377:            /**********************************************************************************************************************************************************************************************************************************************************
378:             * Cacher implementation
379:             *********************************************************************************************************************************************************************************************************************************************************/
380:
381:            /**
382:             * Clear out as much as possible anything cached; re-sync any cache that is needed to be kept.
383:             */
384:            public void resetCache() {
385:                clear();
386:
387:            } // resetCache
388:
389:            /**
390:             * Return the size of the cacher - indicating how much memory in use.
391:             * 
392:             * @return The size of the cacher.
393:             */
394:            public long getSize() {
395:                return m_map.size();
396:            }
397:
398:            /**
399:             * Return a description of the cacher.
400:             * 
401:             * @return The cacher's description.
402:             */
403:            public String getDescription() {
404:                StringBuffer buf = new StringBuffer();
405:                buf.append("NotificationCache:");
406:                if (m_disabled) {
407:                    buf.append(" disabled:");
408:                }
409:                if (m_complete) {
410:                    buf.append(" complete:");
411:                }
412:                if (m_resourcePattern != null) {
413:                    buf.append(" pattern: " + m_resourcePattern);
414:                }
415:                if (m_refresher != null) {
416:                    buf.append(" refresher: " + m_refresher.toString());
417:                }
418:
419:                return buf.toString();
420:            }
421:
422:            /**********************************************************************************************************************************************************************************************************************************************************
423:             * Observer implementation
424:             *********************************************************************************************************************************************************************************************************************************************************/
425:
426:            /**
427:             * This method is called whenever the observed object is changed. An application calls an <tt>Observable</tt> object's <code>notifyObservers</code> method to have all the object's observers notified of the change. default implementation is to
428:             * cause the courier service to deliver to the interface controlled by my controller. Extensions can override.
429:             * 
430:             * @param o
431:             *        the observable object.
432:             * @param arg
433:             *        an argument passed to the <code>notifyObservers</code> method.
434:             */
435:            public void update(Observable o, Object arg) {
436:                if (disabled())
437:                    return;
438:
439:                // arg is Event
440:                if (!(arg instanceof  Event))
441:                    return;
442:                Event event = (Event) arg;
443:
444:                // if this is just a read, not a modify event, we can ignore it
445:                if (!event.getModify())
446:                    return;
447:
448:                String key = event.getResource();
449:
450:                // if this resource is not in my pattern of resources, we can ignore it
451:                if (key != null && !key.startsWith(m_resourcePattern))
452:                    return;
453:
454:                // if we are holding event processing
455:                if (m_holdEventProcessing) {
456:                    m_heldEvents.add(event);
457:                    return;
458:                }
459:
460:                continueUpdate(event);
461:
462:            } // update
463:
464:            /**
465:             * Complete the update, given an event that we know we need to act upon.
466:             * 
467:             * @param event
468:             *        The event to process.
469:             */
470:            private void continueUpdate(Event event) {
471:                String key = event.getResource();
472:
473:                if (M_log.isDebugEnabled())
474:                    M_log.debug("update() [" + m_resourcePattern
475:                            + "] resource: " + key + " event: "
476:                            + event.getEvent());
477:
478:                // do we have this in our cache?
479:                Object oldValue = get(key);
480:                if (m_map.containsKey(key)) {
481:                    // invalidate our copy
482:                    remove(key);
483:                }
484:
485:                // if we are being complete, we need to get this cached.
486:                if (m_complete) {
487:                    // we can only get it cached if we have a refresher
488:                    if (m_refresher != null) {
489:                        // ask the refresher for the value
490:                        Notification value = (Notification) m_refresher
491:                                .refresh(key, oldValue, event);
492:                        if (value != null) {
493:                            put(value);
494:                        }
495:                    } else {
496:                        // we can no longer claim to be complete
497:                        m_complete = false;
498:                    }
499:                }
500:
501:            } // continueUpdate
502:
503:        } // Cache
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.