Source Code Cross Referenced for BaseNotificationService.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) 


0001:        /**********************************************************************************
0002:         * $URL: https://source.sakaiproject.org/svn/event/tags/sakai_2-4-1/event-impl/impl/src/java/org/sakaiproject/event/impl/BaseNotificationService.java $
0003:         * $Id: BaseNotificationService.java 13804 2006-08-17 02:47:37Z ggolden@umich.edu $
0004:         ***********************************************************************************
0005:         *
0006:         * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007:         * 
0008:         * Licensed under the Educational Community License, Version 1.0 (the "License"); 
0009:         * you may not use this file except in compliance with the License. 
0010:         * You may obtain a copy of the License at
0011:         * 
0012:         *      http://www.opensource.org/licenses/ecl1.php
0013:         * 
0014:         * Unless required by applicable law or agreed to in writing, software 
0015:         * distributed under the License is distributed on an "AS IS" BASIS, 
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
0017:         * See the License for the specific language governing permissions and 
0018:         * limitations under the License.
0019:         *
0020:         **********************************************************************************/package org.sakaiproject.event.impl;
0021:
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:        import java.util.Observable;
0025:        import java.util.Observer;
0026:        import java.util.Stack;
0027:        import java.util.Vector;
0028:
0029:        import org.apache.commons.logging.Log;
0030:        import org.apache.commons.logging.LogFactory;
0031:        import org.sakaiproject.component.api.ServerConfigurationService;
0032:        import org.sakaiproject.component.cover.ComponentManager;
0033:        import org.sakaiproject.entity.api.Edit;
0034:        import org.sakaiproject.entity.api.Entity;
0035:        import org.sakaiproject.entity.api.ResourceProperties;
0036:        import org.sakaiproject.entity.api.ResourcePropertiesEdit;
0037:        import org.sakaiproject.event.api.Event;
0038:        import org.sakaiproject.event.api.EventTrackingService;
0039:        import org.sakaiproject.event.api.Notification;
0040:        import org.sakaiproject.event.api.NotificationAction;
0041:        import org.sakaiproject.event.api.NotificationEdit;
0042:        import org.sakaiproject.event.api.NotificationLockedException;
0043:        import org.sakaiproject.event.api.NotificationNotDefinedException;
0044:        import org.sakaiproject.event.api.NotificationService;
0045:        import org.sakaiproject.id.api.IdManager;
0046:        import org.sakaiproject.memory.api.CacheRefresher;
0047:        import org.sakaiproject.time.api.Time;
0048:        import org.sakaiproject.util.BaseResourcePropertiesEdit;
0049:        import org.sakaiproject.util.StorageUser;
0050:        import org.sakaiproject.util.StringUtil;
0051:        import org.sakaiproject.tool.api.SessionBindingEvent;
0052:        import org.sakaiproject.tool.api.SessionBindingListener;
0053:        import org.w3c.dom.Document;
0054:        import org.w3c.dom.Element;
0055:        import org.w3c.dom.Node;
0056:        import org.w3c.dom.NodeList;
0057:
0058:        /**
0059:         * <p>
0060:         * BaseNotificationService ...
0061:         * </p>
0062:         */
0063:        public abstract class BaseNotificationService implements 
0064:                NotificationService, Observer, StorageUser, CacheRefresher {
0065:            /** Our logger. */
0066:            private static Log M_log = LogFactory
0067:                    .getLog(BaseNotificationService.class);
0068:
0069:            /** Storage manager for this service. */
0070:            protected Storage m_storage = null;
0071:
0072:            /** A Cache for this service - Notification objects stored by notification reference. */
0073:            protected NotificationCache m_cache = null;
0074:
0075:            /** The initial portion of a relative access point URL. */
0076:            protected String m_relativeAccessPoint = null;
0077:
0078:            /** Transient notifications (NotificationEdit). */
0079:            protected List m_transients = null;
0080:
0081:            /**********************************************************************************************************************************************************************************************************************************************************
0082:             * Abstractions, etc.
0083:             *********************************************************************************************************************************************************************************************************************************************************/
0084:
0085:            /**
0086:             * Construct storage for this service.
0087:             */
0088:            protected abstract Storage newStorage();
0089:
0090:            /**
0091:             * Does the resource reference match the filter?
0092:             * 
0093:             * @param filter
0094:             *        The resource reference filter.
0095:             * @param ref
0096:             *        The resource reference string.
0097:             * @return true if the filter matches the ref, false if not.
0098:             */
0099:            protected boolean match(String filter, String ref) {
0100:                if (filter == null)
0101:                    return true;
0102:                if (filter.length() == 0)
0103:                    return true;
0104:
0105:                if (ref.startsWith(filter))
0106:                    return true;
0107:
0108:                return false;
0109:            }
0110:
0111:            /**
0112:             * Access the partial URL that forms the root of resource URLs.
0113:             * 
0114:             * @param relative
0115:             *        if true, form within the access path only (i.e. starting with /content)
0116:             * @return the partial URL that forms the root of resource URLs.
0117:             */
0118:            protected String getAccessPoint(boolean relative) {
0119:                return (relative ? "" : serverConfigurationService()
0120:                        .getAccessUrl())
0121:                        + m_relativeAccessPoint;
0122:            }
0123:
0124:            /**
0125:             * Access the notification id extracted from a notification reference.
0126:             * 
0127:             * @param ref
0128:             *        The notification reference string.
0129:             * @return The the notification id extracted from a notification reference.
0130:             */
0131:            protected String notificationId(String ref) {
0132:                String start = getAccessPoint(true) + Entity.SEPARATOR;
0133:                int i = ref.indexOf(start);
0134:                if (i == -1)
0135:                    return ref;
0136:                String id = ref.substring(i + start.length());
0137:                return id;
0138:            }
0139:
0140:            /**
0141:             * Access the external URL which can be used to access the resource from outside the system.
0142:             * 
0143:             * @param id
0144:             *        The notification id.
0145:             * @return The the external URL which can be used to access the resource from outside the system.
0146:             */
0147:            protected String notificationUrl(String id) {
0148:                return getAccessPoint(false) + Entity.SEPARATOR + id;
0149:            }
0150:
0151:            /**********************************************************************************************************************************************************************************************************************************************************
0152:             * Dependencies
0153:             *********************************************************************************************************************************************************************************************************************************************************/
0154:
0155:            /**
0156:             * @return the EventTrackingService collaborator.
0157:             */
0158:            protected abstract EventTrackingService eventTrackingService();
0159:
0160:            /**
0161:             * @return the ServerConfigurationService collaborator.
0162:             */
0163:            protected abstract ServerConfigurationService serverConfigurationService();
0164:
0165:            /**
0166:             * @return the IdManager collaborator.
0167:             */
0168:            protected abstract IdManager idManager();
0169:
0170:            /**********************************************************************************************************************************************************************************************************************************************************
0171:             * Configuration
0172:             *********************************************************************************************************************************************************************************************************************************************************/
0173:
0174:            /** Configuration: make the email notifications To: reply-able. */
0175:            protected boolean m_emailsToReplyable = false;
0176:
0177:            /**
0178:             * Configuration: set reply-able status for email notifications in the To:.
0179:             * 
0180:             * @param value
0181:             *        The setting
0182:             */
0183:            public void setEmailToReplyable(boolean value) {
0184:                m_emailsToReplyable = value;
0185:            }
0186:
0187:            /** Configuration: make the email notifications From: reply-able. */
0188:            protected boolean m_emailsFromReplyable = false;
0189:
0190:            /**
0191:             * Configuration: set reply-able status for email notifications in the From:.
0192:             * 
0193:             * @param value
0194:             *        The setting
0195:             */
0196:            public void setEmailFromReplyable(boolean value) {
0197:                m_emailsFromReplyable = value;
0198:            }
0199:
0200:            /**********************************************************************************************************************************************************************************************************************************************************
0201:             * Init and Destroy
0202:             *********************************************************************************************************************************************************************************************************************************************************/
0203:
0204:            /**
0205:             * Final initialization, once all dependencies are set.
0206:             */
0207:            public void init() {
0208:                try {
0209:                    // prepare for transients
0210:                    m_transients = new Vector();
0211:
0212:                    m_relativeAccessPoint = REFERENCE_ROOT;
0213:
0214:                    M_log.info(this  + ".init()");
0215:
0216:                    // construct storage and read
0217:                    m_storage = newStorage();
0218:                    m_storage.open();
0219:
0220:                    // make the cache
0221:                    m_cache = new NotificationCache(this ,
0222:                            notificationReference(""));
0223:
0224:                    // start watching the events - only those generated on this server, not those from elsewhere
0225:                    eventTrackingService().addLocalObserver(this );
0226:
0227:                    M_log.info(this  + ".init()");
0228:                } catch (Throwable t) {
0229:                    M_log.warn(this  + ".init(): ", t);
0230:                }
0231:            }
0232:
0233:            /**
0234:             * Returns to uninitialized state.
0235:             */
0236:            public void destroy() {
0237:                // if we are not in a global shutdown, remove my event notification registration
0238:                if (!ComponentManager.hasBeenClosed()) {
0239:                    eventTrackingService().deleteObserver(this );
0240:                }
0241:
0242:                // clean up cache
0243:                m_cache.clear();
0244:                m_cache = null;
0245:
0246:                // clean up storage
0247:                m_storage.close();
0248:                m_storage = null;
0249:
0250:                // clean up transients
0251:                m_transients.clear();
0252:                m_transients = null;
0253:
0254:                M_log.info(this  + ".destroy()");
0255:            }
0256:
0257:            /**********************************************************************************************************************************************************************************************************************************************************
0258:             * NotificationService implementation
0259:             *********************************************************************************************************************************************************************************************************************************************************/
0260:
0261:            /**
0262:             * @inheritDoc
0263:             */
0264:            public NotificationEdit addNotification() {
0265:                // check security (throws if not permitted)
0266:                // unlock(SECURE_ADD_NOTIFICATION, notificationReference(id));
0267:
0268:                // get a new unique id
0269:                String id = idManager().createUuid();
0270:
0271:                // reserve a notification with this id from the info store - if it's in use, this will return null
0272:                NotificationEdit notification = m_storage.put(id);
0273:                /*
0274:                 * if (notification == null) { throw new IdUsedException(id); }
0275:                 */
0276:
0277:                ((BaseNotificationEdit) notification)
0278:                        .setEvent(SECURE_ADD_NOTIFICATION);
0279:
0280:                return notification;
0281:            }
0282:
0283:            /**
0284:             * @inheritDoc
0285:             */
0286:            public NotificationEdit addTransientNotification() {
0287:                // the id is not unique, and not really used
0288:                String id = "transient";
0289:
0290:                // create an object, not through storage
0291:                NotificationEdit notification = new BaseNotificationEdit(id);
0292:
0293:                // remember it
0294:                m_transients.add(notification);
0295:
0296:                // no event, no other cluster server knows about it - it's transient and local
0297:                return notification;
0298:            }
0299:
0300:            /**
0301:             * @inheritDoc
0302:             */
0303:            public Notification getNotification(String id)
0304:                    throws NotificationNotDefinedException {
0305:                Notification notification = null;
0306:
0307:                // if we have it cached, use it (hit or miss)
0308:                String key = notificationReference(id);
0309:                if (m_cache.containsKey(key)) {
0310:                    notification = (Notification) m_cache.get(key);
0311:                }
0312:
0313:                // if not in the cache, see if we have it in our info store
0314:                else {
0315:                    notification = m_storage.get(id);
0316:
0317:                    // cache it (hit or miss)
0318:                    m_cache.put(notification);
0319:                }
0320:
0321:                // if not found
0322:                if (notification == null)
0323:                    throw new NotificationNotDefinedException(id);
0324:
0325:                return notification;
0326:            }
0327:
0328:            /**
0329:             * @inheritDoc
0330:             */
0331:            public String notificationReference(String id) {
0332:                return getAccessPoint(true) + Entity.SEPARATOR + id;
0333:            }
0334:
0335:            /**
0336:             * @inheritDoc
0337:             */
0338:            public NotificationEdit editNotification(String id)
0339:                    throws NotificationNotDefinedException,
0340:                    NotificationLockedException {
0341:                // check security (throws if not permitted)
0342:                // unlock(SECURE_UPDATE_NOTIFICATION, notificationReference(id));
0343:
0344:                // check for existance
0345:                if ((m_cache.get(notificationReference(id)) == null)
0346:                        && (!m_storage.check(id))) {
0347:                    throw new NotificationNotDefinedException(id);
0348:                }
0349:
0350:                // ignore the cache - get the notification with a lock from the info store
0351:                NotificationEdit notification = m_storage.edit(id);
0352:                if (notification == null)
0353:                    throw new NotificationLockedException(id);
0354:
0355:                ((BaseNotificationEdit) notification)
0356:                        .setEvent(SECURE_UPDATE_NOTIFICATION);
0357:
0358:                return notification;
0359:            }
0360:
0361:            /**
0362:             * @inheritDoc
0363:             */
0364:            public void commitEdit(NotificationEdit notification) {
0365:                // check for closed edit
0366:                if (!notification.isActiveEdit()) {
0367:                    try {
0368:                        throw new Exception();
0369:                    } catch (Exception e) {
0370:                        M_log.warn(this 
0371:                                + ".commitEdit(): closed NotificationEdit", e);
0372:                    }
0373:                    return;
0374:                }
0375:
0376:                // update the properties
0377:                // addLiveUpdateProperties(notification.getPropertiesEdit());
0378:
0379:                // complete the edit
0380:                m_storage.commit(notification);
0381:
0382:                // track it
0383:                eventTrackingService().post(
0384:                        eventTrackingService().newEvent(
0385:                                ((BaseNotificationEdit) notification)
0386:                                        .getEvent(),
0387:                                notification.getReference(), true));
0388:
0389:                // close the edit object
0390:                ((BaseNotificationEdit) notification).closeEdit();
0391:            }
0392:
0393:            /**
0394:             * @inheritDoc
0395:             */
0396:            public void cancelEdit(NotificationEdit notification) {
0397:                // check for closed edit
0398:                if (!notification.isActiveEdit()) {
0399:                    try {
0400:                        throw new Exception();
0401:                    } catch (Exception e) {
0402:                        M_log.warn(this 
0403:                                + ".cancelEdit(): closed NotificationEdit", e);
0404:                    }
0405:                    return;
0406:                }
0407:
0408:                // release the edit lock
0409:                m_storage.cancel(notification);
0410:
0411:                // close the edit object
0412:                ((BaseNotificationEdit) notification).closeEdit();
0413:            }
0414:
0415:            /**
0416:             * @inheritDoc
0417:             */
0418:            public void removeNotification(NotificationEdit notification) {
0419:                // check for closed edit
0420:                if (!notification.isActiveEdit()) {
0421:                    try {
0422:                        throw new Exception();
0423:                    } catch (Exception e) {
0424:                        M_log
0425:                                .warn(
0426:                                        this 
0427:                                                + ".removeNotification(): closed NotificationEdit",
0428:                                        e);
0429:                    }
0430:                    return;
0431:                }
0432:
0433:                // check security (throws if not permitted)
0434:                // unlock(SECURE_REMOVE_NOTIFICATION, notification.getReference());
0435:
0436:                // complete the edit
0437:                m_storage.remove(notification);
0438:
0439:                // track it
0440:                eventTrackingService().post(
0441:                        eventTrackingService().newEvent(
0442:                                SECURE_REMOVE_NOTIFICATION,
0443:                                notification.getReference(), true));
0444:
0445:                // close the edit object
0446:                ((BaseNotificationEdit) notification).closeEdit();
0447:            }
0448:
0449:            /**
0450:             * @inheritDoc
0451:             */
0452:            public List getNotifications(String function) {
0453:                List notifications = null;
0454:
0455:                // if we have disabled the cache, don't use if
0456:                if (m_cache.disabled()) {
0457:                    notifications = m_storage.getAll(function);
0458:                }
0459:
0460:                else {
0461:                    // if the cache is complete, use it
0462:                    if (m_cache.isComplete()) {
0463:                        notifications = m_cache.getAll(function);
0464:                    }
0465:
0466:                    // otherwise get all the notifications from storage
0467:                    else {
0468:                        // Note: while we are getting from storage, storage might change. These can be processed
0469:                        // after we get the storage entries, and put them in the cache, and mark the cache complete.
0470:                        // -ggolden
0471:                        synchronized (m_cache) {
0472:                            // if we were waiting and it's now complete...
0473:                            if (m_cache.isComplete()) {
0474:                                notifications = m_cache.getAll(function);
0475:                            }
0476:
0477:                            else {
0478:                                // save up any events to the cache until we get past this load
0479:                                m_cache.holdEvents();
0480:
0481:                                // get them all for caching
0482:                                List all = m_storage.getAll();
0483:
0484:                                // update the cache, and mark it complete
0485:                                for (int i = 0; i < all.size(); i++) {
0486:                                    Notification notification = (Notification) all
0487:                                            .get(i);
0488:                                    m_cache.put(notification);
0489:                                }
0490:
0491:                                m_cache.setComplete();
0492:
0493:                                // get those for just this function
0494:                                notifications = m_cache.getAll(function);
0495:
0496:                                // now we are complete, process any cached events
0497:                                m_cache.processEvents();
0498:                            }
0499:                        }
0500:                    }
0501:                }
0502:
0503:                // if none found in storage
0504:                if (notifications == null) {
0505:                    notifications = new Vector();
0506:                }
0507:
0508:                // add transients
0509:                for (Iterator it = m_transients.iterator(); it.hasNext();) {
0510:                    Notification notification = (Notification) it.next();
0511:                    if (notification.containsFunction(function)) {
0512:                        notifications.add(notification);
0513:                    }
0514:                }
0515:
0516:                return notifications;
0517:            }
0518:
0519:            /**
0520:             * @inheritDoc
0521:             */
0522:            public Notification findNotification(String function, String filter) {
0523:                // start with all those for this function (just 'cause we have a nice method to get them -ggolden)
0524:                List notifications = getNotifications(function);
0525:                for (Iterator iNotifications = notifications.iterator(); iNotifications
0526:                        .hasNext();) {
0527:                    Notification notification = (Notification) iNotifications
0528:                            .next();
0529:                    if (notification.getResourceFilter().equals(filter)) {
0530:                        return notification;
0531:                    }
0532:                }
0533:
0534:                return null;
0535:            }
0536:
0537:            /**
0538:             * {@inheritDoc}
0539:             */
0540:            public boolean isNotificationToReplyable() {
0541:                return this .m_emailsToReplyable;
0542:            }
0543:
0544:            /**
0545:             * {@inheritDoc}
0546:             */
0547:            public boolean isNotificationFromReplyable() {
0548:                return this .m_emailsFromReplyable;
0549:            }
0550:
0551:            /**********************************************************************************************************************************************************************************************************************************************************
0552:             * Observer implementation
0553:             *********************************************************************************************************************************************************************************************************************************************************/
0554:
0555:            /**
0556:             * 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
0557:             * cause the courier service to deliver to the interface controlled by my controller. Extensions can override.
0558:             * 
0559:             * @param o
0560:             *        the observable object.
0561:             * @param arg
0562:             *        an argument passed to the <code>notifyObservers</code> method.
0563:             */
0564:            public void update(Observable o, Object arg) {
0565:                // arg is Event
0566:                if (!(arg instanceof  Event))
0567:                    return;
0568:                Event event = (Event) arg;
0569:
0570:                // check the event function against the functions we have notifications watching for
0571:                String function = event.getEvent();
0572:
0573:                // for each notification watching for this event
0574:                List notifications = getNotifications(function);
0575:                for (Iterator it = notifications.iterator(); it.hasNext();) {
0576:                    Notification notification = (Notification) it.next();
0577:
0578:                    // if the resource matches the notification's resource filter
0579:                    if (match(notification.getResourceFilter(), event
0580:                            .getResource())) {
0581:                        // cause the notification to run
0582:                        notification.notify(event);
0583:                    }
0584:                }
0585:
0586:            } // update
0587:
0588:            /**********************************************************************************************************************************************************************************************************************************************************
0589:             * Storage
0590:             *********************************************************************************************************************************************************************************************************************************************************/
0591:
0592:            protected interface Storage {
0593:                /**
0594:                 * Open and be ready to read / write.
0595:                 */
0596:                public void open();
0597:
0598:                /**
0599:                 * Close.
0600:                 */
0601:                public void close();
0602:
0603:                /**
0604:                 * Check if a notification by this id exists.
0605:                 * 
0606:                 * @param id
0607:                 *        The notification id.
0608:                 * @return true if a nitificaion by this id exists, false if not.
0609:                 */
0610:                public boolean check(String id);
0611:
0612:                /**
0613:                 * Add a new notification with this id.
0614:                 * 
0615:                 * @param id
0616:                 *        The notification id.
0617:                 * @return The locked notification with this id, or null if in use.
0618:                 */
0619:                public NotificationEdit put(String id);
0620:
0621:                /**
0622:                 * Get the notification with this id, or null if not found.
0623:                 * 
0624:                 * @param id
0625:                 *        The notification id.
0626:                 * @return The notification with this id, or null if not found.
0627:                 */
0628:                public Notification get(String id);
0629:
0630:                /**
0631:                 * Get a List of all the notifications that are interested in this Event function.
0632:                 * 
0633:                 * @param function
0634:                 *        The Event function
0635:                 * @return The List (Notification) of all the notifications that are interested in this Event function.
0636:                 */
0637:                public List getAll(String function);
0638:
0639:                /**
0640:                 * Get a List of all notifications.
0641:                 * 
0642:                 * @return The List (Notification) of all notifications.
0643:                 */
0644:                public List getAll();
0645:
0646:                /**
0647:                 * Get a lock on the notification with this id, or null if a lock cannot be gotten.
0648:                 * 
0649:                 * @param id
0650:                 *        The user id.
0651:                 * @return The locked Notification with this id, or null if this records cannot be locked.
0652:                 */
0653:                public NotificationEdit edit(String id);
0654:
0655:                /**
0656:                 * Commit the changes and release the lock.
0657:                 * 
0658:                 * @param user
0659:                 *        The notification to commit.
0660:                 */
0661:                public void commit(NotificationEdit notification);
0662:
0663:                /**
0664:                 * Cancel the changes and release the lock.
0665:                 * 
0666:                 * @param user
0667:                 *        The notification to commit.
0668:                 */
0669:                public void cancel(NotificationEdit notification);
0670:
0671:                /**
0672:                 * Remove this notification.
0673:                 * 
0674:                 * @param user
0675:                 *        The notification to remove.
0676:                 */
0677:                public void remove(NotificationEdit notification);
0678:
0679:            } // Storage
0680:
0681:            /**********************************************************************************************************************************************************************************************************************************************************
0682:             * StorageUser implementation
0683:             *********************************************************************************************************************************************************************************************************************************************************/
0684:
0685:            /**
0686:             * Construct a new continer given just an id.
0687:             * 
0688:             * @param id
0689:             *        The id for the new object.
0690:             * @return The new containe Resource.
0691:             */
0692:            public Entity newContainer(String ref) {
0693:                return null;
0694:            }
0695:
0696:            /**
0697:             * Construct a new container resource, from an XML element.
0698:             * 
0699:             * @param element
0700:             *        The XML.
0701:             * @return The new container resource.
0702:             */
0703:            public Entity newContainer(Element element) {
0704:                return null;
0705:            }
0706:
0707:            /**
0708:             * Construct a new container resource, as a copy of another
0709:             * 
0710:             * @param other
0711:             *        The other contianer to copy.
0712:             * @return The new container resource.
0713:             */
0714:            public Entity newContainer(Entity other) {
0715:                return null;
0716:            }
0717:
0718:            /**
0719:             * Construct a new rsource given just an id.
0720:             * 
0721:             * @param container
0722:             *        The Resource that is the container for the new resource (may be null).
0723:             * @param id
0724:             *        The id for the new object.
0725:             * @param others
0726:             *        (options) array of objects to load into the Resource's fields.
0727:             * @return The new resource.
0728:             */
0729:            public Entity newResource(Entity container, String id,
0730:                    Object[] others) {
0731:                return new BaseNotification(id);
0732:            }
0733:
0734:            /**
0735:             * Construct a new resource, from an XML element.
0736:             * 
0737:             * @param container
0738:             *        The Resource that is the container for the new resource (may be null).
0739:             * @param element
0740:             *        The XML.
0741:             * @return The new resource from the XML.
0742:             */
0743:            public Entity newResource(Entity container, Element element) {
0744:                return new BaseNotification(element);
0745:            }
0746:
0747:            /**
0748:             * Construct a new resource from another resource of the same type.
0749:             * 
0750:             * @param container
0751:             *        The Resource that is the container for the new resource (may be null).
0752:             * @param other
0753:             *        The other resource.
0754:             * @return The new resource as a copy of the other.
0755:             */
0756:            public Entity newResource(Entity container, Entity other) {
0757:                return new BaseNotification((Notification) other);
0758:            }
0759:
0760:            /**
0761:             * Construct a new continer given just an id.
0762:             * 
0763:             * @param id
0764:             *        The id for the new object.
0765:             * @return The new containe Resource.
0766:             */
0767:            public Edit newContainerEdit(String ref) {
0768:                return null;
0769:            }
0770:
0771:            /**
0772:             * Construct a new container resource, from an XML element.
0773:             * 
0774:             * @param element
0775:             *        The XML.
0776:             * @return The new container resource.
0777:             */
0778:            public Edit newContainerEdit(Element element) {
0779:                return null;
0780:            }
0781:
0782:            /**
0783:             * Construct a new container resource, as a copy of another
0784:             * 
0785:             * @param other
0786:             *        The other contianer to copy.
0787:             * @return The new container resource.
0788:             */
0789:            public Edit newContainerEdit(Entity other) {
0790:                return null;
0791:            }
0792:
0793:            /**
0794:             * Construct a new rsource given just an id.
0795:             * 
0796:             * @param container
0797:             *        The Resource that is the container for the new resource (may be null).
0798:             * @param id
0799:             *        The id for the new object.
0800:             * @param others
0801:             *        (options) array of objects to load into the Resource's fields.
0802:             * @return The new resource.
0803:             */
0804:            public Edit newResourceEdit(Entity container, String id,
0805:                    Object[] others) {
0806:                BaseNotificationEdit e = new BaseNotificationEdit(id);
0807:                e.activate();
0808:                return e;
0809:            }
0810:
0811:            /**
0812:             * Construct a new resource, from an XML element.
0813:             * 
0814:             * @param container
0815:             *        The Resource that is the container for the new resource (may be null).
0816:             * @param element
0817:             *        The XML.
0818:             * @return The new resource from the XML.
0819:             */
0820:            public Edit newResourceEdit(Entity container, Element element) {
0821:                BaseNotificationEdit e = new BaseNotificationEdit(element);
0822:                e.activate();
0823:                return e;
0824:            }
0825:
0826:            /**
0827:             * Construct a new resource from another resource of the same type.
0828:             * 
0829:             * @param container
0830:             *        The Resource that is the container for the new resource (may be null).
0831:             * @param other
0832:             *        The other resource.
0833:             * @return The new resource as a copy of the other.
0834:             */
0835:            public Edit newResourceEdit(Entity container, Entity other) {
0836:                BaseNotificationEdit e = new BaseNotificationEdit(
0837:                        (Notification) other);
0838:                e.activate();
0839:                return e;
0840:            }
0841:
0842:            /**
0843:             * Collect the fields that need to be stored outside the XML (for the resource).
0844:             * 
0845:             * @return An array of field values to store in the record outside the XML (for the resource).
0846:             */
0847:            public Object[] storageFields(Entity r) {
0848:                return null;
0849:            }
0850:
0851:            /**
0852:             * Check if this resource is in draft mode.
0853:             * 
0854:             * @param r
0855:             *        The resource.
0856:             * @return true if the resource is in draft mode, false if not.
0857:             */
0858:            public boolean isDraft(Entity r) {
0859:                return false;
0860:            }
0861:
0862:            /**
0863:             * Access the resource owner user id.
0864:             * 
0865:             * @param r
0866:             *        The resource.
0867:             * @return The resource owner user id.
0868:             */
0869:            public String getOwnerId(Entity r) {
0870:                return null;
0871:            }
0872:
0873:            /**
0874:             * Access the resource date.
0875:             * 
0876:             * @param r
0877:             *        The resource.
0878:             * @return The resource date.
0879:             */
0880:            public Time getDate(Entity r) {
0881:                return null;
0882:            }
0883:
0884:            /**********************************************************************************************************************************************************************************************************************************************************
0885:             * CacheRefresher implementation (no container)
0886:             *********************************************************************************************************************************************************************************************************************************************************/
0887:
0888:            /**
0889:             * Get a new value for this key whose value has already expired in the cache.
0890:             * 
0891:             * @param key
0892:             *        The key whose value has expired and needs to be refreshed.
0893:             * @param oldValue
0894:             *        The old exipred value of the key.
0895:             * @param event
0896:             *        The event which triggered this refresh.
0897:             * @return a new value for use in the cache for this key; if null, the entry will be removed.
0898:             */
0899:            public Object refresh(Object key, Object oldValue, Event event) {
0900:                // key is a reference, but our storage wants an id
0901:                String id = notificationId((String) key);
0902:
0903:                // get this from storage
0904:                Notification notification = m_storage.get(id);
0905:
0906:                if (M_log.isDebugEnabled())
0907:                    M_log.debug(this  + ".refresh(): " + key + " : " + id);
0908:
0909:                return notification;
0910:
0911:            } // refresh
0912:
0913:            /**********************************************************************************************************************************************************************************************************************************************************
0914:             * Notification implementation
0915:             *********************************************************************************************************************************************************************************************************************************************************/
0916:
0917:            public class BaseNotification implements  Notification {
0918:                /** The Event(s) function we are watching for. */
0919:                protected List m_functions = null;
0920:
0921:                /** The resource reference filter. */
0922:                protected String m_filter = null;
0923:
0924:                /** The resource id. */
0925:                protected String m_id = null;
0926:
0927:                /** The resource properties. */
0928:                protected ResourcePropertiesEdit m_properties = null;
0929:
0930:                /** The action helper class. */
0931:                protected NotificationAction m_action = null;
0932:
0933:                /**
0934:                 * Construct.
0935:                 * 
0936:                 * @param id
0937:                 *        The id to use.
0938:                 */
0939:                public BaseNotification(String id) {
0940:                    // generate a new id
0941:                    m_id = id;
0942:
0943:                    // setup for properties
0944:                    m_properties = new BaseResourcePropertiesEdit();
0945:
0946:                    // setup for functions
0947:                    m_functions = new Vector();
0948:                }
0949:
0950:                /**
0951:                 * @inheritDoc
0952:                 */
0953:                public BaseNotification(Notification other) {
0954:                    setAll(other);
0955:                }
0956:
0957:                /**
0958:                 * @inheritDoc
0959:                 */
0960:                public BaseNotification(Element el) {
0961:                    // setup for properties
0962:                    m_properties = new BaseResourcePropertiesEdit();
0963:
0964:                    // setup for functions
0965:                    m_functions = new Vector();
0966:
0967:                    m_id = el.getAttribute("id");
0968:
0969:                    // the first function
0970:                    String func = StringUtil.trimToNull(el
0971:                            .getAttribute("function"));
0972:                    if (func != null) {
0973:                        m_functions.add(func);
0974:                    }
0975:
0976:                    m_filter = StringUtil.trimToNull(el.getAttribute("filter"));
0977:
0978:                    // the children (properties, action helper)
0979:                    NodeList children = el.getChildNodes();
0980:                    final int length = children.getLength();
0981:                    for (int i = 0; i < length; i++) {
0982:                        Node child = children.item(i);
0983:                        if (child.getNodeType() != Node.ELEMENT_NODE)
0984:                            continue;
0985:                        Element element = (Element) child;
0986:
0987:                        // look for properties
0988:                        if (element.getTagName().equals("properties")) {
0989:                            // re-create properties
0990:                            m_properties = new BaseResourcePropertiesEdit(
0991:                                    element);
0992:                        }
0993:
0994:                        // look for the helper element
0995:                        else if (element.getTagName().equals("action")) {
0996:                            // the class name
0997:                            String className = StringUtil.trimToNull(element
0998:                                    .getAttribute("class"));
0999:                            if (className != null) {
1000:                                // create the class
1001:                                try {
1002:                                    m_action = (NotificationAction) Class
1003:                                            .forName(className).newInstance();
1004:
1005:                                    // let it pick up it's settings
1006:                                    m_action.set(element);
1007:                                } catch (Exception e) {
1008:                                    M_log
1009:                                            .warn(this 
1010:                                                    + " exception creating action helper: "
1011:                                                    + e.toString());
1012:                                }
1013:                            }
1014:                        } else if (element.getTagName().equals("function")) {
1015:                            func = StringUtil.trimToNull(element
1016:                                    .getAttribute("id"));
1017:                            m_functions.add(func);
1018:                        }
1019:                    }
1020:                }
1021:
1022:                /**
1023:                 * @inheritDoc
1024:                 */
1025:                protected void setAll(Notification other) {
1026:                    BaseNotification bOther = (BaseNotification) other;
1027:                    m_id = bOther.m_id;
1028:                    m_filter = bOther.m_filter;
1029:
1030:                    m_properties = new BaseResourcePropertiesEdit();
1031:                    m_properties.addAll(bOther.m_properties);
1032:
1033:                    m_functions = new Vector();
1034:                    m_functions.addAll(bOther.m_functions);
1035:
1036:                    if (bOther.m_action != null) {
1037:                        m_action = bOther.m_action.getClone();
1038:                    }
1039:                }
1040:
1041:                /**
1042:                 * @inheritDoc
1043:                 */
1044:                public void notify(Event event) {
1045:                    if (m_action != null) {
1046:                        m_action.notify(this , event);
1047:                    }
1048:                }
1049:
1050:                /**
1051:                 * @inheritDoc
1052:                 */
1053:                public String getFunction() {
1054:                    return (String) m_functions.get(0);
1055:                }
1056:
1057:                /**
1058:                 * @inheritDoc
1059:                 */
1060:                public String getResourceFilter() {
1061:                    return m_filter;
1062:                }
1063:
1064:                /**
1065:                 * @inheritDoc
1066:                 */
1067:                public List getFunctions() {
1068:                    List rv = new Vector();
1069:                    rv.addAll(m_functions);
1070:
1071:                    return rv;
1072:                }
1073:
1074:                /**
1075:                 * @inheritDoc
1076:                 */
1077:                public boolean containsFunction(String function) {
1078:                    return m_functions.contains(function);
1079:                }
1080:
1081:                /**
1082:                 * @inheritDoc
1083:                 */
1084:                public NotificationAction getAction() {
1085:                    return m_action;
1086:                }
1087:
1088:                /**
1089:                 * @inheritDoc
1090:                 */
1091:                public String getUrl() {
1092:                    return notificationUrl(m_id);
1093:                }
1094:
1095:                /**
1096:                 * @inheritDoc
1097:                 */
1098:                public String getReference() {
1099:                    return notificationReference(m_id);
1100:                }
1101:
1102:                /**
1103:                 * @inheritDoc
1104:                 */
1105:                public String getReference(String rootProperty) {
1106:                    return getReference();
1107:                }
1108:
1109:                /**
1110:                 * @inheritDoc
1111:                 */
1112:                public String getUrl(String rootProperty) {
1113:                    return getUrl();
1114:                }
1115:
1116:                /**
1117:                 * Access the id of the resource.
1118:                 * 
1119:                 * @return The id.
1120:                 */
1121:                public String getId() {
1122:                    return m_id;
1123:                }
1124:
1125:                /**
1126:                 * Access the resource's properties.
1127:                 * 
1128:                 * @return The resource's properties.
1129:                 */
1130:                public ResourceProperties getProperties() {
1131:                    return m_properties;
1132:                }
1133:
1134:                /**
1135:                 * Serialize the resource into XML, adding an element to the doc under the top of the stack element.
1136:                 * 
1137:                 * @param doc
1138:                 *        The DOM doc to contain the XML (or null for a string return).
1139:                 * @param stack
1140:                 *        The DOM elements, the top of which is the containing element of the new "resource" element.
1141:                 * @return The newly added element.
1142:                 */
1143:                public Element toXml(Document doc, Stack stack) {
1144:                    Element notification = doc.createElement("notification");
1145:                    if (stack.isEmpty()) {
1146:                        doc.appendChild(notification);
1147:                    } else {
1148:                        ((Element) stack.peek()).appendChild(notification);
1149:                    }
1150:
1151:                    stack.push(notification);
1152:
1153:                    notification.setAttribute("id", getId());
1154:
1155:                    // first function
1156:                    if (m_functions.size() >= 1) {
1157:                        notification.setAttribute("function",
1158:                                (String) m_functions.get(0));
1159:                    }
1160:
1161:                    if (m_filter != null)
1162:                        notification.setAttribute("filter", m_filter);
1163:
1164:                    // properties
1165:                    m_properties.toXml(doc, stack);
1166:
1167:                    // action
1168:                    if (m_action != null) {
1169:                        Element action = doc.createElement("action");
1170:                        notification.appendChild(action);
1171:                        action.setAttribute("class", m_action.getClass()
1172:                                .getName());
1173:                        m_action.toXml(action);
1174:                    }
1175:
1176:                    // more functions
1177:                    if (m_functions.size() > 1) {
1178:                        for (int i = 1; i < m_functions.size(); i++) {
1179:                            String func = (String) m_functions.get(i);
1180:                            Element funcEl = doc.createElement("function");
1181:                            notification.appendChild(funcEl);
1182:                            funcEl.setAttribute("id", func);
1183:                        }
1184:                    }
1185:                    stack.pop();
1186:
1187:                    return notification;
1188:                }
1189:            }
1190:
1191:            /**********************************************************************************************************************************************************************************************************************************************************
1192:             * NotificationEdit implementation
1193:             *********************************************************************************************************************************************************************************************************************************************************/
1194:
1195:            public class BaseNotificationEdit extends BaseNotification
1196:                    implements  NotificationEdit, SessionBindingListener {
1197:                /** The event code for this edit. */
1198:                protected String m_event = null;
1199:
1200:                /** Active flag. */
1201:                protected boolean m_active = false;
1202:
1203:                /**
1204:                 * Construct.
1205:                 * 
1206:                 * @param id
1207:                 *        The notification id.
1208:                 */
1209:                public BaseNotificationEdit(String id) {
1210:                    super (id);
1211:
1212:                } // BaseNotificationEdit
1213:
1214:                /**
1215:                 * Construct from an existing definition, in xml.
1216:                 * 
1217:                 * @param el
1218:                 *        The message in XML in a DOM element.
1219:                 */
1220:                public BaseNotificationEdit(Element el) {
1221:                    super (el);
1222:
1223:                } // BaseNotificationEdit
1224:
1225:                /**
1226:                 * Construct from another Notification.
1227:                 * 
1228:                 * @param notification
1229:                 *        The other notification to copy values from.
1230:                 */
1231:                public BaseNotificationEdit(Notification other) {
1232:                    super (other);
1233:
1234:                } // BaseNotificationEdit
1235:
1236:                /**
1237:                 * Clean up.
1238:                 */
1239:                protected void finalize() {
1240:                    // catch the case where an edit was made but never resolved
1241:                    if (m_active) {
1242:                        cancelEdit(this );
1243:                    }
1244:
1245:                } // finalize
1246:
1247:                /**
1248:                 * Set the Event function, clearing any that have already been set.
1249:                 * 
1250:                 * @param event
1251:                 *        The Event function to watch for.
1252:                 */
1253:                public void setFunction(String function) {
1254:                    m_functions.clear();
1255:                    m_functions.add(function);
1256:
1257:                } // setFunction
1258:
1259:                /**
1260:                 * Add another Event function.
1261:                 * 
1262:                 * @param event
1263:                 *        Another Event function to watch for.
1264:                 */
1265:                public void addFunction(String function) {
1266:                    m_functions.add(function);
1267:
1268:                } // addFunction
1269:
1270:                /**
1271:                 * Set the resource reference filter.
1272:                 * 
1273:                 * @param filter
1274:                 *        The resource reference filter.
1275:                 */
1276:                public void setResourceFilter(String filter) {
1277:                    m_filter = filter;
1278:
1279:                } // setResourceFilter
1280:
1281:                /**
1282:                 * Set the action helper that handles the notify() action.
1283:                 * 
1284:                 * @param action
1285:                 *        The action helper that handles the notify() action.
1286:                 */
1287:                public void setAction(NotificationAction action) {
1288:                    m_action = action;
1289:
1290:                } // setAction
1291:
1292:                /**
1293:                 * Take all values from this object.
1294:                 * 
1295:                 * @param other
1296:                 *        The notification object to take values from.
1297:                 */
1298:                protected void set(Notification other) {
1299:                    setAll(other);
1300:
1301:                } // set
1302:
1303:                /**
1304:                 * Access the event code for this edit.
1305:                 * 
1306:                 * @return The event code for this edit.
1307:                 */
1308:                protected String getEvent() {
1309:                    return m_event;
1310:                }
1311:
1312:                /**
1313:                 * Set the event code for this edit.
1314:                 * 
1315:                 * @param event
1316:                 *        The event code for this edit.
1317:                 */
1318:                protected void setEvent(String event) {
1319:                    m_event = event;
1320:                }
1321:
1322:                /**
1323:                 * Access the resource's properties for modification
1324:                 * 
1325:                 * @return The resource's properties.
1326:                 */
1327:                public ResourcePropertiesEdit getPropertiesEdit() {
1328:                    return m_properties;
1329:
1330:                } // getPropertiesEdit
1331:
1332:                /**
1333:                 * Enable editing.
1334:                 */
1335:                protected void activate() {
1336:                    m_active = true;
1337:
1338:                } // activate
1339:
1340:                /**
1341:                 * Check to see if the edit is still active, or has already been closed.
1342:                 * 
1343:                 * @return true if the edit is active, false if it's been closed.
1344:                 */
1345:                public boolean isActiveEdit() {
1346:                    return m_active;
1347:
1348:                } // isActiveEdit
1349:
1350:                /**
1351:                 * Close the edit object - it cannot be used after this.
1352:                 */
1353:                protected void closeEdit() {
1354:                    m_active = false;
1355:
1356:                } // closeEdit
1357:
1358:                /******************************************************************************************************************************************************************************************************************************************************
1359:                 * SessionBindingListener implementation
1360:                 *****************************************************************************************************************************************************************************************************************************************************/
1361:
1362:                public void valueBound(SessionBindingEvent event) {
1363:                }
1364:
1365:                public void valueUnbound(SessionBindingEvent event) {
1366:                    if (M_log.isDebugEnabled())
1367:                        M_log.debug(this  + ".valueUnbound()");
1368:
1369:                    // catch the case where an edit was made but never resolved
1370:                    if (m_active) {
1371:                        cancelEdit(this );
1372:                    }
1373:
1374:                } // valueUnbound
1375:
1376:            } // BaseNotificationEdit
1377:
1378:        } // BaseNotificationService
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.