001    /*
002        Licensed to the Apache Software Foundation (ASF) under one
003        or more contributor license agreements.  See the NOTICE file
004        distributed with this work for additional information
005        regarding copyright ownership.  The ASF licenses this file
006        to you under the Apache License, Version 2.0 (the
007        "License"); you may not use this file except in compliance
008        with the License.  You may obtain a copy of the License at
009    
010           http://www.apache.org/licenses/LICENSE-2.0
011    
012        Unless required by applicable law or agreed to in writing,
013        software distributed under the License is distributed on an
014        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015        KIND, either express or implied.  See the License for the
016        specific language governing permissions and limitations
017        under the License.  
018     */
019    
020    package org.apache.wiki.event;
021    
022    import org.apache.wiki.WikiEngine;
023    import org.apache.wiki.api.engine.FilterManager;
024    
025    /**
026     *  A utility class that adds some JSPWiki-specific functionality to the
027     *  WikiEventManager (which is really a general-purpose event manager).
028     *
029     * @since 2.4.20
030     */
031    public class WikiEventUtils
032    {
033        /**
034         *  This ungainly convenience method adds a WikiEventListener to the
035         *  appropriate component of the provided client Object, to listen
036         *  for events of the provided type (or related types, see the table
037         *  below).
038         *  <p>
039         *  If the type value is valid but does not match any WikiEvent type
040         *  known to this method, this will just attach the listener to the
041         *  client Object. This may mean that the Object never fires events
042         *  of the desired type; type-to-client matching is left to you to
043         *  guarantee. Silence is golden, but not if you want those events.
044         *  </p>
045         *  <p>
046         *  Most event types expect a WikiEngine as the client, with the rest
047         *  attaching the listener directly to the supplied source object, as
048         *  described below:
049         *  </p>
050         *  <table border="1" cellpadding="4">
051         *    <tr><th>WikiEvent Type(s) </th><th>Required Source Object </th><th>Actually Attached To </th>
052         *    </tr>
053         *    <tr><td>any WikiEngineEvent       </td><td>WikiEngine  </td><td>WikiEngine        </td></tr>
054         *    <tr><td>WikiPageEvent.PAGE_LOCK,
055         *            WikiPageEvent.PAGE_UNLOCK </td><td>WikiEngine or
056         *                                               PageManager </td><td>PageManager       </td></tr>
057         *    <tr><td>WikiPageEvent.PAGE_REQUESTED,
058         *            WikiPageEvent.PAGE_DELIVERED </td>
059         *                                           <td>WikiServletFilter </td>
060         *                                                                <td>WikiServletFilter </td></tr>
061         *    <tr><td>WikiPageEvent (<a href="#pbeTypes">phase boundary event</a>)</td>
062         *                                           <td>WikiEngine  </td><td>FilterManager     </td></tr>
063         *    <tr><td>WikiPageEvent (<a href="#ipeTypes">in-phase event</a>)</td>
064         *    <tr><td>WikiPageEvent (in-phase event)</td>
065         *                                           <td>any         </td><td>source object     </td></tr>
066         *    <tr><td>WikiSecurityEvent         </td><td>any         </td><td>source object     </td></tr>
067         *    <tr><td>any other valid type      </td><td>any         </td><td>source object     </td></tr>
068         *    <tr><td>any invalid type          </td><td>any         </td><td>nothing           </td></tr>
069         *  </table>
070         *
071         * <p id="pbeTypes"><small><b>phase boundary event types:</b>
072         * <tt>WikiPageEvent.PRE_TRANSLATE_BEGIN</tt>, <tt>WikiPageEvent.PRE_TRANSLATE_END</tt>,
073         * <tt>WikiPageEvent.POST_TRANSLATE_BEGIN</tt>, <tt>WikiPageEvent.POST_TRANSLATE_END</tt>,
074         * <tt>WikiPageEvent.PRE_SAVE_BEGIN</tt>, <tt>WikiPageEvent.PRE_SAVE_END</tt>,
075         * <tt>WikiPageEvent.POST_SAVE_BEGIN</tt>, and <tt>WikiPageEvent.POST_SAVE_END</tt>.
076         * </small></p>
077         * <p id="ipeTypes"><small><b>in-phase event types:</b>
078         * <tt>WikiPageEvent.PRE_TRANSLATE</tt>, <tt>WikiPageEvent.POST_TRANSLATE</tt>,
079         * <tt>WikiPageEvent.PRE_SAVE</tt>, and <tt>WikiPageEvent.POST_SAVE</tt>.
080         * </small></p>
081         *
082         * <p>
083         * <b>Note:</b> The <i>Actually Attached To</i> column may also be considered as the
084         * class(es) that fire events of the type(s) shown in the <i>WikiEvent Type</i> column.
085         * </p>
086         *
087         * @see org.apache.wiki.event.WikiEvent
088         * @see org.apache.wiki.event.WikiEngineEvent
089         * @see org.apache.wiki.event.WikiPageEvent
090         * @see org.apache.wiki.event.WikiSecurityEvent
091         * @throws ClassCastException if there is a type mismatch between certain event types and the client Object
092         */
093        public static synchronized void addWikiEventListener(
094                Object client, int type, WikiEventListener listener )
095        {
096            // Make sure WikiEventManager exists
097            WikiEventManager.getInstance();
098            
099            // first, figure out what kind of event is expected to be generated this does
100            // tie us into known types, but WikiEvent.isValidType() will return true so
101            // long as the type was set to any non-ERROR or non-UNKNOWN value
102    
103            if ( WikiEngineEvent.isValidType(type) )
104            {
105                // add listener directly to WikiEngine
106                WikiEventManager.addWikiEventListener( client, listener );
107            }
108            else if ( WikiPageEvent.isValidType(type) )
109            {
110                // add listener to one of several options
111                if(  type == WikiPageEvent.PAGE_LOCK
112                  || type == WikiPageEvent.PAGE_UNLOCK )
113                {
114                    // attach to PageManager
115                    if( client instanceof WikiEngine )
116                    {
117                        WikiEventManager.addWikiEventListener( ((WikiEngine)client).getPageManager(), listener );
118                    }
119                    else
120                    {
121                        // client instanceof PageManager
122                        WikiEventManager.addWikiEventListener( client, listener );
123                    }
124                }
125                else if(  type == WikiPageEvent.PAGE_REQUESTED
126                       || type == WikiPageEvent.PAGE_DELIVERED )
127                {
128                    // attach directly to WikiServletFilter
129                    WikiEventManager.addWikiEventListener( client, listener );
130                }
131                else if(  type == WikiPageEvent.PRE_TRANSLATE_BEGIN
132                       || type == WikiPageEvent.PRE_TRANSLATE_END
133                       || type == WikiPageEvent.POST_TRANSLATE_BEGIN
134                       || type == WikiPageEvent.POST_TRANSLATE_END
135                       || type == WikiPageEvent.PRE_SAVE_BEGIN
136                       || type == WikiPageEvent.PRE_SAVE_END
137                       || type == WikiPageEvent.POST_SAVE_BEGIN
138                       || type == WikiPageEvent.POST_SAVE_END )
139                {
140                    // attach to FilterManager
141                    FilterManager fm = ((WikiEngine)client).getFilterManager();
142                    WikiEventManager.addWikiEventListener( fm, listener );
143                }
144                else //if (  type == WikiPageEvent.PRE_TRANSLATE
145                     // || type == WikiPageEvent.POST_TRANSLATE
146                     // || type == WikiPageEvent.PRE_SAVE
147                     // || type == WikiPageEvent.POST_SAVE ) // attach to client
148                {
149                    WikiEventManager.addWikiEventListener( client, listener );
150                }
151            }
152            else if( WikiSecurityEvent.isValidType(type) )
153            {
154                // currently just attach it to the client (we are ignorant of other options)
155                WikiEventManager.addWikiEventListener( client, listener );
156            }
157            else if( WikiEvent.isValidType(type) )
158            {
159                // we don't know what to do
160                WikiEventManager.addWikiEventListener( client, listener );
161            }
162            else
163            {
164                // is error or unknown
165                // why are we being called with this?
166            }
167        }
168    
169    } // end org.apache.wiki.event.WikiEventUtils