Source Code Cross Referenced for PubSubHub.java in  » Ajax » dwr » org » directwebremoting » proxy » openajax » 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 » Ajax » dwr » org.directwebremoting.proxy.openajax 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.directwebremoting.proxy.openajax;
002:
003:        import java.util.ArrayList;
004:        import java.util.Collections;
005:        import java.util.HashMap;
006:        import java.util.List;
007:        import java.util.Map;
008:        import java.util.Set;
009:
010:        import javax.servlet.http.HttpSession;
011:        import javax.swing.event.EventListenerList;
012:
013:        import org.directwebremoting.ScriptSession;
014:        import org.directwebremoting.event.PublishEvent;
015:        import org.directwebremoting.event.PublishListener;
016:        import org.directwebremoting.event.SubscriptionEvent;
017:        import org.directwebremoting.event.SubscriptionListener;
018:
019:        /**
020:         * A Server-side hub to manage subscriptions
021:         * @author Joe Walker [joe at getahead dot ltd dot uk]
022:         */
023:        public class PubSubHub {
024:            /**
025:             * Publishes (broadcasts) an event based on a library-specific prefix and
026:             * event name.
027:             * @param prefix The prefix that corresponds to this event. This must be a
028:             * prefix that has been registered via OpenAjax.registerLibrary().
029:             * @param name The name of the event to listen for. Names can be any string
030:             */
031:            public void publish(String prefix, String name) {
032:                publish(ANY_HTTP_SESSION, ANY_SCRIPT_SESSION, prefix, name,
033:                        null, null);
034:            }
035:
036:            /**
037:             * Publishes (broadcasts) an event based on a library-specific prefix and
038:             * event name.
039:             * @param prefix The prefix that corresponds to this event. This must be a
040:             * prefix that has been registered via OpenAjax.registerLibrary().
041:             * @param name The name of the event to listen for. Names can be any string
042:             * @param publisherData Data to be sent to the Listener along with the
043:             * eventHappened message
044:             */
045:            public void publish(String prefix, String name, Object publisherData) {
046:                publish(ANY_HTTP_SESSION, ANY_SCRIPT_SESSION, prefix, name,
047:                        publisherData, null);
048:            }
049:
050:            /**
051:             * Publishes (broadcasts) an event based on a library-specific prefix and
052:             * event name.
053:             * @param httpSessionId An HttpSession that we are publishing to. The value
054:             * should not be <code>null</code>, but can be {@link #ANY_HTTP_SESSION} to
055:             * denote a match for all {@link HttpSession}s.
056:             * @param scriptSessionId A ScriptSession that we are publishing to. The value
057:             * should not be <code>null</code>, but can be {@link #ANY_SCRIPT_SESSION}
058:             * to denote a match for all {@link ScriptSession}s.
059:             * @param prefix The prefix that corresponds to this event. This must be a
060:             * prefix that has been registered via OpenAjax.registerLibrary().
061:             * @param name The name of the event to listen for. Names can be any string
062:             */
063:            public void publish(String httpSessionId, String scriptSessionId,
064:                    String prefix, String name) {
065:                publish(httpSessionId, scriptSessionId, prefix, name, null,
066:                        null);
067:            }
068:
069:            /**
070:             * Publishes (broadcasts) an event based on a library-specific prefix and
071:             * event name.
072:             * @param httpSessionId An HttpSession that we are publishing to. The value
073:             * should not be <code>null</code>, but can be {@link #ANY_HTTP_SESSION} to
074:             * denote a match for all {@link HttpSession}s.
075:             * @param scriptSessionId A ScriptSession that we are publishing to. The value
076:             * should not be <code>null</code>, but can be {@link #ANY_SCRIPT_SESSION}
077:             * to denote a match for all {@link ScriptSession}s.
078:             * @param prefix The prefix that corresponds to this event. This must be a
079:             * prefix that has been registered via OpenAjax.registerLibrary().
080:             * @param name The name of the event to listen for. Names can be any string
081:             * @param publisherData Data to be sent to the Listener along with the
082:             * eventHappened message
083:             */
084:            public void publish(String httpSessionId, String scriptSessionId,
085:                    String prefix, String name, Object publisherData) {
086:                publish(httpSessionId, scriptSessionId, prefix, name,
087:                        publisherData, null);
088:            }
089:
090:            /**
091:             * Publishes (broadcasts) an event based on a library-specific prefix and
092:             * event name.
093:             * @param httpSessionId An HttpSession that we are publishing to. The value
094:             * should not be <code>null</code>, but can be {@link #ANY_HTTP_SESSION} to
095:             * denote a match for all {@link HttpSession}s.
096:             * @param scriptSessionId A ScriptSession that we are publishing to. The value
097:             * should not be <code>null</code>, but can be {@link #ANY_SCRIPT_SESSION}
098:             * to denote a match for all {@link ScriptSession}s.
099:             * @param prefix The prefix that corresponds to this event. This must be a
100:             * prefix that has been registered via OpenAjax.registerLibrary().
101:             * @param name The name of the event to listen for. Names can be any string
102:             * @param publisherData Data to be sent to the Listener along with the
103:             * eventHappened message
104:             * @param hubsVisited A list of the hubs that the message has passed through
105:             */
106:            public void publish(String httpSessionId, String scriptSessionId,
107:                    String prefix, String name, Object publisherData,
108:                    List<String> hubsVisited) {
109:                checkNulls(httpSessionId, scriptSessionId, prefix, name);
110:
111:                if (hubsVisited == null) {
112:                    hubsVisited = new ArrayList<String>();
113:                } else {
114:                    if (hubsVisited.contains(getHubId())) {
115:                        return;
116:                    }
117:                }
118:                hubsVisited.add(getHubId());
119:
120:                List<PublishListener> matches = new ArrayList<PublishListener>();
121:                matches.addAll(allListeners.keySet());
122:
123:                if (matches.size() != 0
124:                        && !httpSessionId.equals(ANY_HTTP_SESSION)) {
125:                    List<PublishListener> httpSessionMatches = httpSessions
126:                            .get(httpSessionId);
127:                    if (httpSessionMatches != null) {
128:                        matches.retainAll(httpSessionMatches);
129:                    } else {
130:                        matches.clear();
131:                    }
132:                }
133:
134:                if (matches.size() != 0
135:                        && !scriptSessionId.equals(ANY_SCRIPT_SESSION)) {
136:                    List<PublishListener> scriptSessionMatches = scriptSessions
137:                            .get(scriptSessionId);
138:                    if (scriptSessionMatches != null) {
139:                        matches.retainAll(scriptSessionMatches);
140:                    } else {
141:                        matches.clear();
142:                    }
143:                }
144:
145:                if (matches.size() != 0 && !prefix.equals(ANY_PREFIX)) {
146:                    List<PublishListener> prefixMatches = prefixes.get(prefix);
147:                    if (prefixMatches != null) {
148:                        matches.retainAll(prefixMatches);
149:                    } else {
150:                        matches.clear();
151:                    }
152:                }
153:
154:                if (matches.size() != 0 && !name.equals(ANY_NAME)) {
155:                    List<PublishListener> nameMatches = names.get(name);
156:                    if (nameMatches != null) {
157:                        matches.retainAll(nameMatches);
158:                    } else {
159:                        matches.clear();
160:                    }
161:                }
162:
163:                for (PublishListener listener : matches) {
164:                    Object subscriberData = allListeners.get(listener);
165:                    PublishEvent event = new PublishEvent(this , httpSessionId,
166:                            scriptSessionId, prefix, name, publisherData,
167:                            subscriberData, hubsVisited);
168:                    listener.publishHappened(event);
169:                }
170:            }
171:
172:            /**
173:             * @see #subscribe(String, String, String, String, PublishListener, Object)
174:             */
175:            public void subscribe(String prefix, String name,
176:                    PublishListener listener) {
177:                subscribe(ANY_HTTP_SESSION, ANY_SCRIPT_SESSION, prefix, name,
178:                        listener, null);
179:            }
180:
181:            /**
182:             * @see #subscribe(String, String, String, String, PublishListener, Object)
183:             */
184:            public void subscribe(String prefix, String name,
185:                    PublishListener listener, Object subscriberData) {
186:                subscribe(ANY_HTTP_SESSION, ANY_SCRIPT_SESSION, prefix, name,
187:                        listener, subscriberData);
188:            }
189:
190:            /**
191:             * @see #subscribe(String, String, String, String, PublishListener, Object)
192:             */
193:            public void subscribe(String httpSessionId, String scriptSessionId,
194:                    String prefix, String name, PublishListener listener) {
195:                subscribe(httpSessionId, scriptSessionId, prefix, name,
196:                        listener, null);
197:            }
198:
199:            /**
200:             * Allows registration of interest in named events based on library-specific
201:             * prefix and event name. Global event matching is provided by passing "*"
202:             * in the prefix and/or name arguments. Optional arguments may be specified
203:             * for executing the specified handler function in a provided scope and for
204:             * further filtering events prior to application.
205:             * <p>
206:             * The callback function will receive the following parameters
207:             * (see OpenAjax.publish() for description of publisherData):
208:             * <pre>
209:             * function(prefix, name, subscriberData, publisherData){ ... }
210:             * </pre>
211:             * @param httpSessionId An HttpSession that we are subscribing to. The value
212:             * should not be <code>null</code>, but can be {@link #ANY_HTTP_SESSION} to
213:             * denote a match for all {@link HttpSession}s.
214:             * @param scriptSessionId A ScriptSession that we are subscribing to. The value
215:             * should not be <code>null</code>, but can be {@link #ANY_SCRIPT_SESSION}
216:             * to denote a match for all {@link ScriptSession}s.
217:             * @param prefix The prefix that corresponds to this library. This is the
218:             * same value that was previously passed to registerLibrary(). Can be "*" to
219:             * match the provided event name across all libraries.
220:             * @param name The name of the event to listen for. Names can be any string.
221:             * Can be "*" to match all events in the specified toolkit (see prefix). If
222:             * both name and prefix specify "*", all events in the system will be routed
223:             * to the registered handler (modulo any filtering provided by filter).
224:             * @param listener The object to deliver messages to
225:             * @param subscriberData Data to be send to the Listener along with the
226:             * eventHappened message
227:             */
228:            public void subscribe(String httpSessionId, String scriptSessionId,
229:                    String prefix, String name, PublishListener listener,
230:                    Object subscriberData) {
231:                checkNulls(httpSessionId, scriptSessionId, prefix, name);
232:
233:                if (httpSessionId != null && httpSessionId != ANY_HTTP_SESSION) {
234:                    List<PublishListener> listeners = httpSessions
235:                            .get(httpSessionId);
236:                    if (listeners == null) {
237:                        listeners = new ArrayList<PublishListener>();
238:                        httpSessions.put(httpSessionId, listeners);
239:                    }
240:                    listeners.add(listener);
241:                }
242:
243:                if (scriptSessionId != null
244:                        && scriptSessionId != ANY_SCRIPT_SESSION) {
245:                    List<PublishListener> listeners = scriptSessions
246:                            .get(scriptSessionId);
247:                    if (listeners == null) {
248:                        listeners = new ArrayList<PublishListener>();
249:                        scriptSessions.put(scriptSessionId, listeners);
250:                    }
251:                    listeners.add(listener);
252:                }
253:
254:                if (prefix != null && prefix != ANY_PREFIX) {
255:                    List<PublishListener> listeners = prefixes.get(prefix);
256:                    if (listeners == null) {
257:                        listeners = new ArrayList<PublishListener>();
258:                        prefixes.put(prefix, listeners);
259:                    }
260:                    listeners.add(listener);
261:                }
262:
263:                if (name != null && name != ANY_NAME) {
264:                    List<PublishListener> listeners = names.get(name);
265:                    if (listeners == null) {
266:                        listeners = new ArrayList<PublishListener>();
267:                        names.put(name, listeners);
268:                    }
269:                    listeners.add(listener);
270:                }
271:
272:                allListeners.put(listener, subscriberData);
273:                fireSubscribeHappenedEvent(httpSessionId, scriptSessionId,
274:                        prefix, name, listener);
275:            }
276:
277:            /**
278:             * @see #unsubscribe(String, String, String, String, PublishListener)
279:             */
280:            public void unsubscribe(String prefix, String name,
281:                    PublishListener listener) {
282:                unsubscribe(ANY_HTTP_SESSION, ANY_SCRIPT_SESSION, prefix, name,
283:                        listener);
284:            }
285:
286:            /**
287:             * Removes a subscription to an event. In order for a subscription to be
288:             * removed, the values of the parameters supplied to OpenAjax.unsubscribe()
289:             * must exactly match the values of the parameters supplied to a previous
290:             * call to OpenAjax.subscribe(). Note that it is possible that one
291:             * invocation of OpenAjax.unsubscribe() might result in removal of multiple
292:             * subscriptions.
293:             * @param prefix The prefix that corresponds to this library. This is the
294:             * same value that was previously passed to registerLibrary(). Can be "*" to
295:             * match the provided event name across all libraries.
296:             * @param name The name of the event to listen for. Names can be any string.
297:             * Can be "*" to match all events in the specified toolkit (see prefix). If
298:             * both name and prefix specify "*", all events in the system will be routed
299:             * to the registered handler (modulo any filtering provided by filter).
300:             * @param listener The object to deliver messages to
301:             */
302:            public void unsubscribe(String httpSessionId,
303:                    String scriptSessionId, String prefix, String name,
304:                    PublishListener listener) {
305:                checkNulls(httpSessionId, scriptSessionId, prefix, name);
306:
307:                if (httpSessionId != null && httpSessionId != ANY_HTTP_SESSION) {
308:                    List<PublishListener> listeners = httpSessions
309:                            .get(httpSessionId);
310:                    if (listeners != null) {
311:                        listeners.remove(listener);
312:                        if (listeners.size() == 0) {
313:                            httpSessions.remove(httpSessionId);
314:                        }
315:                    }
316:                }
317:
318:                if (scriptSessionId != null
319:                        && scriptSessionId != ANY_SCRIPT_SESSION) {
320:                    List<PublishListener> listeners = scriptSessions
321:                            .get(scriptSessionId);
322:                    if (listeners != null) {
323:                        listeners.remove(listener);
324:                        if (listeners.size() == 0) {
325:                            scriptSessions.remove(scriptSessionId);
326:                        }
327:                    }
328:                }
329:
330:                if (prefix != null && prefix != ANY_PREFIX) {
331:                    List<PublishListener> listeners = prefixes.get(prefix);
332:                    if (listeners != null) {
333:                        listeners.remove(listener);
334:                        if (listeners.size() == 0) {
335:                            prefixes.remove(prefix);
336:                        }
337:                    }
338:                }
339:
340:                if (name != null && name != ANY_NAME) {
341:                    List<PublishListener> listeners = names.get(name);
342:                    if (listeners != null) {
343:                        listeners.remove(listener);
344:                        if (listeners.size() == 0) {
345:                            names.remove(name);
346:                        }
347:                    }
348:                }
349:
350:                allListeners.remove(listener);
351:                fireUnsubscribeHappenedEvent(httpSessionId, scriptSessionId,
352:                        prefix, name, listener);
353:            }
354:
355:            /**
356:             * Maintain the list of {@link SubscriptionListener}s
357:             * @param li the SubscriptionListener to add
358:             */
359:            public void addSubscriptionListener(SubscriptionListener li) {
360:                subscriptionListeners.add(SubscriptionListener.class, li);
361:            }
362:
363:            /**
364:             * Maintain the list of {@link SubscriptionListener}s
365:             * @param li the ScriptSessionListener to remove
366:             */
367:            public void removeSubscriptionListener(SubscriptionListener li) {
368:                subscriptionListeners.remove(SubscriptionListener.class, li);
369:            }
370:
371:            /**
372:             * If other hubs wish to synchronize with the messages passed through this
373:             * hub they need to be able to filter to keep the message storm down.
374:             * @return A set of the names that this hub is interested in.
375:             */
376:            public Set<String> getSubscribedNames() {
377:                return Collections.unmodifiableSet(names.keySet());
378:            }
379:
380:            /**
381:             * If other hubs wish to synchronize with the messages passed through this
382:             * hub they need to be able to filter to keep the message storm down.
383:             * @return A set of the prefixes that this hub is interested in.
384:             */
385:            public Set<String> getSubscribedPrefixes() {
386:                return Collections.unmodifiableSet(prefixes.keySet());
387:            }
388:
389:            /**
390:             * To allow hubs to not create publish loops we need to know what 
391:             * @return The ID of this Hub
392:             */
393:            public String getHubId() {
394:                if (hubId == null) {
395:                    hubId = "org.directwebremoting.proxy.openajax.PubSubHub."
396:                            + hashCode();
397:                }
398:
399:                return hubId;
400:            }
401:
402:            /* (non-Javadoc)
403:             * @see java.lang.Object#toString()
404:             */
405:            @Override
406:            public String toString() {
407:                return getHubId();
408:            }
409:
410:            /**
411:             * This should be called whenever a {@link ScriptSession} is destroyed
412:             * @param httpSessionId The ID match of the {@link HttpSession} that was subscribed to
413:             * @param scriptSessionId The ID match of the {@link ScriptSession} that was subscribed to
414:             * @param prefix The prefix match that was subscribed to
415:             * @param name The name match that was subscripbed to
416:             * @param listener The subscribed object
417:             */
418:            protected void fireSubscribeHappenedEvent(String httpSessionId,
419:                    String scriptSessionId, String prefix, String name,
420:                    PublishListener listener) {
421:                SubscriptionEvent ev = new SubscriptionEvent(this ,
422:                        httpSessionId, scriptSessionId, prefix, name, listener);
423:                Object[] listeners = subscriptionListeners.getListenerList();
424:                for (int i = 0; i < listeners.length - 2; i += 2) {
425:                    if (listeners[i] == SubscriptionListener.class) {
426:                        ((SubscriptionListener) listeners[i + 1])
427:                                .subscribeHappened(ev);
428:                    }
429:                }
430:            }
431:
432:            /**
433:             * This should be called whenever a {@link ScriptSession} is created
434:             * @param httpSessionId The ID match of the {@link HttpSession} that was subscribed to
435:             * @param scriptSessionId The ID match of the {@link ScriptSession} that was subscribed to
436:             * @param prefix The prefix match that was subscribed to
437:             * @param name The name match that was subscripbed to
438:             * @param listener The subscribed object
439:             */
440:            protected void fireUnsubscribeHappenedEvent(String httpSessionId,
441:                    String scriptSessionId, String prefix, String name,
442:                    PublishListener listener) {
443:                SubscriptionEvent ev = new SubscriptionEvent(this ,
444:                        httpSessionId, scriptSessionId, prefix, name, listener);
445:                Object[] listeners = subscriptionListeners.getListenerList();
446:                for (int i = 0; i < listeners.length - 2; i += 2) {
447:                    if (listeners[i] == SubscriptionListener.class) {
448:                        ((SubscriptionListener) listeners[i + 1])
449:                                .unsubscribeHappened(ev);
450:                    }
451:                }
452:            }
453:
454:            /**
455:             * The list of current {@link SubscriptionListener}s
456:             */
457:            protected EventListenerList subscriptionListeners = new EventListenerList();
458:
459:            /**
460:             * A constant to denote a match to any <code>prefix</code>.
461:             */
462:            public static final String ANY_PREFIX = "*";
463:
464:            /**
465:             * A constant to denote a match to any <code>name</code>.
466:             */
467:            public static final String ANY_NAME = "*";
468:
469:            /**
470:             * A constant to denote a match to any {@link HttpSession}.
471:             */
472:            public static final String ANY_HTTP_SESSION = "*";
473:
474:            /**
475:             * A constant to denote a match to any {@link ScriptSession}.
476:             */
477:            public static final String ANY_SCRIPT_SESSION = "*";
478:
479:            /**
480:             * Throw if any of the parameters are null
481:             */
482:            private void checkNulls(String httpSessionId,
483:                    String scriptSessionId, String prefix, String name) {
484:                if (httpSessionId == null) {
485:                    throw new NullPointerException(
486:                            "httpSessionId may not be null. Use PubSubHub.ANY_HTTP_SESSION for broad matching");
487:                }
488:
489:                if (scriptSessionId == null) {
490:                    throw new NullPointerException(
491:                            "scriptSession may not be null. Use PubSubHub.ANY_SCRIPT_SESSION for broad matching");
492:                }
493:
494:                if (prefix == null) {
495:                    throw new NullPointerException(
496:                            "prefix may not be null. Use PubSubHub.ANY_PREFIX or \"*\" for broad matching");
497:                }
498:
499:                if (name == null) {
500:                    throw new NullPointerException(
501:                            "name may not be null. Use PubSubHub.ANY_NAME or \"*\" for broad matching");
502:                }
503:            }
504:
505:            private String hubId = null;
506:
507:            private Map<PublishListener, Object> allListeners = new HashMap<PublishListener, Object>();
508:
509:            private Map<String, List<PublishListener>> names = new HashMap<String, List<PublishListener>>();
510:
511:            private Map<String, List<PublishListener>> prefixes = new HashMap<String, List<PublishListener>>();
512:
513:            private Map<String, List<PublishListener>> httpSessions = new HashMap<String, List<PublishListener>>();
514:
515:            private Map<String, List<PublishListener>> scriptSessions = new HashMap<String, List<PublishListener>>();
516:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.