Source Code Cross Referenced for WikiEventManager.java in  » Wiki-Engine » JSPWiki » com » ecyrd » jspwiki » event » 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 » Wiki Engine » JSPWiki » com.ecyrd.jspwiki.event 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:            JSPWiki - a JSP-based WikiWiki clone.
003:
004:            Copyright (C) 2001-2006 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006:            This program is free software; you can redistribute it and/or modify
007:            it under the terms of the GNU Lesser General Public License as published by
008:            the Free Software Foundation; either version 2.1 of the License, or
009:            (at your option) any later version.
010:
011:            This program is distributed in the hope that it will be useful,
012:            but WITHOUT ANY WARRANTY; without even the implied warranty of
013:            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:            GNU Lesser General Public License for more details.
015:
016:            You should have received a copy of the GNU Lesser General Public License
017:            along with this program; if not, write to the Free Software
018:            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:
021:        package com.ecyrd.jspwiki.event;
022:
023:        import java.lang.ref.WeakReference;
024:        import java.util.*;
025:
026:        import org.apache.log4j.Logger;
027:
028:        /**
029:         *  A singleton class that manages the addition and removal of WikiEvent
030:         *  listeners to a event source, as well as the firing of events to those
031:         *  listeners. An "event source" is the object delegating its event
032:         *  handling to an inner delegating class supplied by this manager. The
033:         *  class being serviced is considered a "client" of the delegate. The
034:         *  WikiEventManager operates across any number of simultaneously-existing
035:         *  WikiEngines since it manages all delegation on a per-object basis.
036:         *  Anything that might fire a WikiEvent (or any of its subclasses) can be
037:         *  a client.
038:         *  </p>
039:         *
040:         *  <h3>Using a Delegate for Event Listener Management</h3>
041:         *  <p>
042:         *  Basically, rather than have all manner of client classes maintain their
043:         *  own listener lists, add and remove listener methods, any class wanting
044:         *  to attach listeners can simply request a delegate object to provide that
045:         *  service. The delegate handles the listener list, the add and remove
046:         *  listener methods. Firing events is then a matter of calling the
047:         *  WikiEventManager's {@link #fireEvent(Object,WikiEvent)} method, where
048:         *  the Object is the client. Prior to instantiating the event object, the
049:         *  client can call {@link #isListening(Object)} to see there are any
050:         *  listeners attached to its delegate.
051:         *  </p>
052:         *
053:         *  <h3>Adding Listeners</h3>
054:         *  <p>
055:         *  Adding a WikiEventListener to an object is very simple:
056:         *  </p>
057:         *  <pre>
058:         *      WikiEventManager.addWikiEventListener(object,listener);
059:         *  </pre>
060:         *
061:         *  <h3>Removing Listeners</h3>
062:         *  <p>
063:         *  Removing a WikiEventListener from an object is very simple:
064:         *  </p>
065:         *  <pre>
066:         *      WikiEventManager.removeWikiEventListener(object,listener);
067:         *  </pre>
068:         *  If you only have a reference to the listener, the following method
069:         *  will remove it from any clients managed by the WikiEventManager:
070:         *  <pre>
071:         *      WikiEventManager.removeWikiEventListener(listener);
072:         *  </pre>
073:         *
074:         *  <h3>Backward Compatibility: Replacing Existing <tt>fireEvent()</tt> Methods</h3>
075:         *  <p>
076:         *  Using one manager for all events processing permits consolidation of all event
077:         *  listeners and their associated methods in one place rather than having them
078:         *  attached to specific subcomponents of an application, and avoids a great deal
079:         *  of event-related cut-and-paste code. Convenience methods that call the
080:         *  WikiEventManager for event delegation can be written to maintain existing APIs.
081:         *  </p>
082:         *  <p>
083:         *  For example, an existing <tt>fireEvent()</tt> method might look something like
084:         *  this:
085:         *  </p>
086:         *  <pre>
087:         *    protected final void fireEvent( WikiEvent event )
088:         *    {
089:         *        for ( Iterator it = m_listeners.iterator(); it.hasNext(); )
090:         *        {
091:         *            WikiEventListener listener = (WikiEventListener)it.next();
092:         *            listener.actionPerformed(event);
093:         *        }
094:         *    }
095:         *  </pre>
096:         *  <p>
097:         *  One disadvantage is that the above method is supplied with event objects,
098:         *  which are created even when no listener exists for them. In a busy wiki
099:         *  with many users unused/unnecessary event creation could be considerable.
100:         *  Another advantage is that in addition to the iterator, there must be code
101:         *  to support the addition and remove of listeners. The above could be
102:         *  replaced with the below code (and with no necessary local support for
103:         *  adding and removing listeners):
104:         *  </p>
105:         *  <pre>
106:         *    protected final void fireEvent( int type )
107:         *    {
108:         *        if ( WikiEventManager.isListening(this) )
109:         *        {
110:         *            WikiEventManager.fireEvent(this,new WikiEngineEvent(this,type));
111:         *        }
112:         *    }
113:         *  </pre>
114:         *  <p>
115:         *  This only needs to be customized to supply the specific parameters for
116:         *  whatever WikiEvent you want to create.
117:         *  </p>
118:         *
119:         *  <h3 id="preloading">Preloading Listeners</h3>
120:         *  <p>
121:         *  This may be used to create listeners for objects that don't yet exist,
122:         *  particularly designed for embedded applications that need to be able
123:         *  to listen for the instantiation of an Object, by maintaining a cache
124:         *  of client-less WikiEvent sources that set their client upon being
125:         *  popped from the cache. Each time any of the methods expecting a client
126:         *  parameter is called with a null parameter it will preload an internal
127:         *  cache with a client-less delegate object that will be popped and
128:         *  returned in preference to creating a new object. This can have unwanted
129:         *  side effects if there are multiple clients populating the cache with
130:         *  listeners. The only check is for a Class match, so be aware if others
131:         *  might be populating the client-less cache with listeners.
132:         *  </p>
133:         *  <h3>Listener lifecycle</h3>
134:         *  <p>
135:         *  Note that in most cases it is not necessary to remove a listener.
136:         *  As of 2.4.97, the listeners are stored as WeakReferences, and will be
137:         *  automatically cleaned at the next garbage collection, if you no longer
138:         *  hold a reference to them.  Of course, until the garbage is collected,
139:         *  your object might still be getting events, so if you wish to avoid that,
140:         *  please remove it explicitly as described above.
141:         *  </p>
142:         * @author Murray Altheim
143:         * @since 2.4.20
144:         */
145:        public final class WikiEventManager {
146:            private static final Logger log = Logger
147:                    .getLogger(WikiEventManager.class);
148:
149:            /* If true, permits a WikiEventMonitor to be set. */
150:            private static boolean c_permitMonitor = false;
151:
152:            /* Optional listener to be used as all-event monitor. */
153:            private static WikiEventListener c_monitor = null;
154:
155:            /* The Map of client object to WikiEventDelegate. */
156:            private final Map m_delegates = new HashMap();
157:
158:            /* The Vector containing any preloaded WikiEventDelegates. */
159:            private final Vector m_preloadCache = new Vector();
160:
161:            /* Singleton instance of the WikiEventManager. */
162:            private static WikiEventManager c_instance = null;
163:
164:            // ............
165:
166:            /**
167:             *  Constructor for a WikiEventManager.
168:             */
169:            private WikiEventManager() {
170:                c_instance = this ;
171:                log.debug("instantiated WikiEventManager");
172:            }
173:
174:            /**
175:             *  As this is a singleton class, this returns the single
176:             *  instance of this class provided with the property file
177:             *  filename and bit-wise application settings.
178:             *
179:             *  @return A shared instance of the WikiEventManager
180:             */
181:            public static WikiEventManager getInstance() {
182:                if (c_instance == null) {
183:                    synchronized (WikiEventManager.class) {
184:                        WikiEventManager mgr = new WikiEventManager();
185:                        // start up any post-instantiation services here
186:                        return mgr;
187:                    }
188:                }
189:                return c_instance;
190:            }
191:
192:            // public/API methods ......................................................
193:
194:            /**
195:             *  Registers a WikiEventListener with a WikiEventDelegate for
196:             *  the provided client object.
197:             *
198:             *  <h3>Monitor Listener</h3>
199:             *
200:             *  If <tt>client</tt> is a reference to the WikiEventManager class
201:             *  itself and the compile-time flag {@link #c_permitMonitor} is true,
202:             *  this attaches the listener as an all-event monitor, overwriting
203:             *  any previous listener (hence returning true).
204:             *  <p>
205:             *  You can remove any existing monitor by either calling this method
206:             *  with <tt>client</tt> as a reference to this class and the
207:             *  <tt>listener</tt> parameter as null, or
208:             *  {@link #removeWikiEventListener(Object,WikiEventListener)} with a
209:             *  <tt>client</tt> as a reference to this class. The <tt>listener</tt>
210:             *  parameter in this case is ignored.
211:             *
212:             * @param client   the client of the event source
213:             * @param listener the event listener
214:             * @return true if the listener was added (i.e., it was not already in the list and was added)
215:             */
216:            public static final boolean addWikiEventListener(Object client,
217:                    WikiEventListener listener) {
218:                if (client == WikiEventManager.class) {
219:                    if (c_permitMonitor)
220:                        c_monitor = listener;
221:                    return c_permitMonitor;
222:                }
223:                WikiEventDelegate delegate = getInstance().getDelegateFor(
224:                        client);
225:                return delegate.addWikiEventListener(listener);
226:            }
227:
228:            /**
229:             *  Un-registers a WikiEventListener with the WikiEventDelegate for
230:             *  the provided client object.
231:             *
232:             * @param client   the client of the event source
233:             * @param listener the event listener
234:             * @return true if the listener was found and removed.
235:             */
236:            public static final boolean removeWikiEventListener(Object client,
237:                    WikiEventListener listener) {
238:                if (client == WikiEventManager.class) {
239:                    c_monitor = null;
240:                    return true;
241:                }
242:                WikiEventDelegate delegate = getInstance().getDelegateFor(
243:                        client);
244:                return delegate.removeWikiEventListener(listener);
245:            }
246:
247:            /**
248:             *  Return the Set containing the WikiEventListeners attached to the
249:             *  delegate for the supplied client. If there are no attached listeners,
250:             *  returns an empty Iterator rather than null.  Note that this will
251:             *  create a delegate for the client if it did not exist prior to the call.
252:             *
253:             *  <h3>NOTE</h3>
254:             *  <p>
255:             *  This method returns a Set rather than an Iterator because of the high
256:             *  likelihood of the Set being modified while an Iterator might be active.
257:             *  This returns an unmodifiable reference to the actual Set containing
258:             *  the delegate's listeners. Any attempt to modify the Set will throw an
259:             *  {@link java.lang.UnsupportedOperationException}. This method is not
260:             *  synchronized and it should be understood that the composition of the
261:             *  backing Set may change at any time.
262:             *  </p>
263:             *
264:             * @param client   the client of the event source
265:             * @return an unmodifiable Set containing the WikiEventListeners attached to the client
266:             * @throws java.lang.UnsupportedOperationException  if any attempt is made to modify the Set
267:             */
268:            public static final Set getWikiEventListeners(Object client)
269:                    throws UnsupportedOperationException {
270:                WikiEventDelegate delegate = getInstance().getDelegateFor(
271:                        client);
272:                return delegate.getWikiEventListeners();
273:            }
274:
275:            /**
276:             *  Un-registers a WikiEventListener from any WikiEventDelegate client managed by this
277:             *  WikiEventManager. Since this is a one-to-one relation, the first match will be
278:             *  returned upon removal; a true return value indicates the WikiEventListener was
279:             *  found and removed.
280:             *
281:             * @param listener the event listener
282:             * @return true if the listener was found and removed.
283:             */
284:            public static final boolean removeWikiEventListener(
285:                    WikiEventListener listener) {
286:                // get the Map.entry object for the entire Map, then check match on entry (listener)
287:                WikiEventManager mgr = getInstance();
288:                Map sources = mgr.getDelegates();
289:                synchronized (sources) {
290:                    // get an iterator over the Map.Enty objects in the map
291:                    Iterator it = sources.entrySet().iterator();
292:                    while (it.hasNext()) {
293:                        Map.Entry entry = (Map.Entry) it.next();
294:                        // the entry value is the delegate
295:                        WikiEventDelegate delegate = (WikiEventDelegate) entry
296:                                .getValue();
297:
298:                        // now see if we can remove the listener from the delegate
299:                        // (delegate may be null because this is a weak reference)
300:                        if (delegate != null
301:                                && delegate.removeWikiEventListener(listener)) {
302:                            return true; // was removed
303:                        }
304:                    }
305:                }
306:                return false;
307:            }
308:
309:            /**
310:             *  Returns true if there are one or more listeners registered with
311:             *  the provided client Object (undelegated event source). This locates
312:             *  any delegate and checks to see if it has any listeners attached.
313:             *
314:             *  @param client the client Object
315:             *  @return True, if there is a listener for this client object.
316:             */
317:            public static boolean isListening(Object client) {
318:                WikiEventDelegate source = getInstance().getDelegateFor(client);
319:                return source != null ? source.isListening() : false;
320:            }
321:
322:            /**
323:             *  Notify all listeners of the WikiEventDelegate having a registered
324:             *  interest in change events of the supplied WikiEvent.
325:             *
326:             * @param client the client initiating the event.
327:             * @param event  the WikiEvent to fire.
328:             */
329:            public static void fireEvent(Object client, WikiEvent event) {
330:                WikiEventDelegate source = getInstance().getDelegateFor(client);
331:                if (source != null)
332:                    source.fireEvent(event);
333:                if (c_monitor != null)
334:                    c_monitor.actionPerformed(event);
335:            }
336:
337:            // private and utility methods .............................................
338:
339:            /**
340:             *  Return the client-to-delegate Map.
341:             */
342:            private Map getDelegates() {
343:                return m_delegates;
344:            }
345:
346:            /**
347:             *  Returns a WikiEventDelegate for the provided client Object.
348:             *  If the parameter is a class reference, will generate and return a
349:             *  client-less WikiEventDelegate. If the parameter is not a Class and
350:             *  the delegate cache contains any objects matching the Class of any
351:             *  delegates in the cache, the first Class-matching delegate will be
352:             *  used in preference to creating a new delegate.
353:             *  If a null parameter is supplied, this will create a client-less
354:             *  delegate that will attach to the first incoming client (i.e.,
355:             *  there will be no Class-matching requirement).
356:             *
357:             * @param client   the client Object, or alternately a Class reference
358:             * @return the WikiEventDelegate.
359:             */
360:            private WikiEventDelegate getDelegateFor(Object client) {
361:                synchronized (m_delegates) {
362:                    if (client == null || client instanceof  Class) // then preload the cache
363:                    {
364:                        WikiEventDelegate delegate = new WikiEventDelegate(
365:                                client);
366:                        m_preloadCache.add(delegate);
367:                        m_delegates.put(client, delegate);
368:                        return delegate;
369:                    } else if (!m_preloadCache.isEmpty()) {
370:                        // then see if any of the cached delegates match the class of the incoming client
371:                        for (int i = m_preloadCache.size() - 1; i >= 0; i--) // start with most-recently added
372:                        {
373:                            WikiEventDelegate delegate = (WikiEventDelegate) m_preloadCache
374:                                    .elementAt(i);
375:                            if (delegate.getClientClass() == null
376:                                    || delegate.getClientClass().equals(
377:                                            client.getClass())) {
378:                                // we have a hit, so use it, but only on a client we haven't seen before
379:                                if (!m_delegates.keySet().contains(client)) {
380:                                    m_preloadCache.remove(delegate);
381:                                    m_delegates.put(client, delegate);
382:                                    return delegate;
383:                                }
384:                            }
385:                        }
386:                    }
387:                    // otherwise treat normally...
388:                    WikiEventDelegate delegate = (WikiEventDelegate) m_delegates
389:                            .get(client);
390:                    if (delegate == null) {
391:                        delegate = new WikiEventDelegate(client);
392:                        m_delegates.put(client, delegate);
393:                    }
394:                    return delegate;
395:                }
396:            }
397:
398:            // .........................................................................
399:
400:            /**
401:             *  Inner delegating class that manages event listener addition and
402:             *  removal. Classes that generate events can obtain an instance of
403:             *  this class from the WikiEventManager and delegate responsibility
404:             *  to it. Interaction with this delegating class is done via the
405:             *  methods of the {@link WikiEventDelegate} API.
406:             *
407:             * @author Murray Altheim
408:             * @since 2.4.20
409:             */
410:            private static final class WikiEventDelegate {
411:                /* A list of event listeners for this instance. */
412:
413:                private ArrayList m_listenerList = new ArrayList();
414:
415:                private Class m_class = null;
416:
417:                /**
418:                 *  Constructor for an WikiEventDelegateImpl, provided
419:                 *  with the client Object it will service, or the Class
420:                 *  of client, the latter when used to preload a future
421:                 *  incoming delegate.
422:                 */
423:                protected WikiEventDelegate(Object client) {
424:                    if (client instanceof  Class) {
425:                        m_class = (Class) client;
426:                    }
427:                }
428:
429:                /**
430:                 *  Returns the class of the client-less delegate, null if
431:                 *  this delegate is attached to a client Object.
432:                 */
433:                protected Class getClientClass() {
434:                    return m_class;
435:                }
436:
437:                /**
438:                 *  Return an unmodifiable Set containing the WikiEventListeners of
439:                 *  this WikiEventDelegateImpl. If there are no attached listeners,
440:                 *  returns an empty Set rather than null.
441:                 *
442:                 * @return an unmodifiable Set containing this delegate's WikiEventListeners
443:                 * @throws java.lang.UnsupportedOperationException  if any attempt is made to modify the Set
444:                 */
445:                public Set getWikiEventListeners() {
446:                    synchronized (m_listenerList) {
447:                        TreeSet set = new TreeSet(
448:                                new WikiEventListenerComparator());
449:
450:                        for (Iterator i = m_listenerList.iterator(); i
451:                                .hasNext();) {
452:                            WikiEventListener l = (WikiEventListener) ((WeakReference) i
453:                                    .next()).get();
454:
455:                            if (l != null) {
456:                                set.add(l);
457:                            }
458:                        }
459:
460:                        return Collections.unmodifiableSet(set);
461:                    }
462:                }
463:
464:                /**
465:                 *  Adds <tt>listener</tt> as a listener for events fired by the WikiEventDelegate.
466:                 *
467:                 * @param listener   the WikiEventListener to be added
468:                 * @return true if the listener was added (i.e., it was not already in the list and was added)
469:                 */
470:                public boolean addWikiEventListener(WikiEventListener listener) {
471:                    synchronized (m_listenerList) {
472:                        return m_listenerList.add(new WeakReference(listener));
473:                    }
474:                }
475:
476:                /**
477:                 *  Removes <tt>listener</tt> from the WikiEventDelegate.
478:                 *
479:                 * @param listener   the WikiEventListener to be removed
480:                 * @return true if the listener was removed (i.e., it was actually in the list and was removed)
481:                 */
482:                public boolean removeWikiEventListener(
483:                        WikiEventListener listener) {
484:                    synchronized (m_listenerList) {
485:                        for (Iterator i = m_listenerList.iterator(); i
486:                                .hasNext();) {
487:                            WikiEventListener l = (WikiEventListener) ((WeakReference) i
488:                                    .next()).get();
489:
490:                            if (l == listener) {
491:                                i.remove();
492:                                return true;
493:                            }
494:                        }
495:                    }
496:
497:                    return false;
498:                }
499:
500:                /**
501:                 *  Returns true if there are one or more listeners registered
502:                 *  with this instance.
503:                 */
504:                public boolean isListening() {
505:                    synchronized (m_listenerList) {
506:                        return !m_listenerList.isEmpty();
507:                    }
508:                }
509:
510:                /**
511:                 *  Notify all listeners having a registered interest
512:                 *  in change events of the supplied WikiEvent.
513:                 */
514:                public void fireEvent(WikiEvent event) {
515:                    boolean needsCleanup = false;
516:
517:                    try {
518:                        synchronized (m_listenerList) {
519:                            for (int i = 0; i < m_listenerList.size(); i++) {
520:                                WikiEventListener listener = (WikiEventListener) ((WeakReference) m_listenerList
521:                                        .get(i)).get();
522:
523:                                if (listener != null) {
524:                                    listener.actionPerformed(event);
525:                                } else {
526:                                    needsCleanup = true;
527:                                }
528:                            }
529:
530:                            //
531:                            //  Remove all such listeners which have expired
532:                            //
533:                            if (needsCleanup) {
534:                                for (int i = 0; i < m_listenerList.size(); i++) {
535:                                    WeakReference w = (WeakReference) m_listenerList
536:                                            .get(i);
537:
538:                                    if (w.get() == null)
539:                                        m_listenerList.remove(i--);
540:                                }
541:                            }
542:
543:                        }
544:                    } catch (ConcurrentModificationException e) {
545:                        //
546:                        //  We don't die, we just don't do notifications in that case.
547:                        //
548:                        log
549:                                .info(
550:                                        "Concurrent modification of event list; please report this.",
551:                                        e);
552:                    }
553:
554:                }
555:
556:            } // end inner class WikiEventDelegate
557:
558:            private static class WikiEventListenerComparator implements 
559:                    Comparator {
560:                // TODO: This method is a critical performance bottleneck
561:                public int compare(Object arg0, Object arg1) {
562:                    if (arg0 instanceof  WikiEventListener
563:                            && arg1 instanceof  WikiEventListener) {
564:                        WikiEventListener w0 = (WikiEventListener) arg0;
565:                        WikiEventListener w1 = (WikiEventListener) arg1;
566:
567:                        if (w1 == w0 || w0.equals(w1))
568:                            return 0;
569:
570:                        return w1.hashCode() - w0.hashCode();
571:                    }
572:
573:                    throw new ClassCastException(arg1.getClass().getName()
574:                            + " != " + arg0.getClass().getName());
575:                }
576:            }
577:        } // end com.ecyrd.jspwiki.event.WikiEventManager
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.