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
020package org.apache.wiki.event;
021
022import java.util.EventObject;
023import java.util.HashMap;
024import java.util.Map;
025
026/**
027 * Abstract parent class for wiki events.
028 *
029 * @since 2.3.79
030 */
031public abstract class WikiEvent extends EventObject {
032
033    private static final long serialVersionUID = 1829433967558773960L;
034
035    /** Indicates a exception or error state. */
036    public static final int ERROR          = -99;
037
038    /** Indicates an undefined state. */
039    public static final int UNDEFINED      = -98;
040
041    private int m_type = UNDEFINED;
042
043    private final long m_when;
044
045    /** objects associated to src which only make sense in the context of a given WikiEvent */
046    private Object[] args;
047    
048    /** additional attributes, primarily used for the audit logger */
049    private Map<Object,Object> attributes = new HashMap<>();
050
051    /**
052     * gets a live reference to a hash map, primarily used for the audit logger
053     * @since 3.0.0
054     * @return 
055     */
056    public Map<Object, Object> getAttributes() {
057        return attributes;
058    }
059
060    // ............
061
062    /**
063     * Constructs an instance of this event.
064     *
065     * @param src the Object that is the source of the event. Typically, this is the Wiki {@link Engine}
066     * @param type the event type. Typically this is a constant reference to {@link WikiPageEvent}
067     */
068    public WikiEvent( final Object src, final int type ) {
069        super( src );
070        m_when = System.currentTimeMillis();
071        args = new Object[]{};
072        setType( type );
073    }
074
075    /**
076     * Constructs an instance of this event.
077     *
078     * @param src the Object that is the source of the event. Typically, this is the Wiki {@link Engine}
079     * @param type the event type. Typically this is a constant reference to {@link WikiPageEvent}
080     * @param args typically the first arg is the page name that triggered the event.
081     */
082    public WikiEvent( final Object src, final int type, final Object... args ) {
083        this( src, type );
084        this.args = args != null ? args : new Object[]{};
085    }
086    
087    /**
088     * Convenience method that returns the typed object to which the event applied.
089     * 
090     * @return the typed object to which the event applied.
091     */
092    @SuppressWarnings("unchecked")
093    public < T > T getSrc() {
094        return ( T )super.getSource();
095    }
096
097   /**
098    *  Returns the timestamp of when this WikiEvent occurred.
099    *
100    * @return this event's timestamp
101    * @since 2.4.74
102    */
103   public long getWhen() {
104       return m_when;
105   }
106
107    /**
108     * Sets the type of this event. Validation of acceptable type values is the responsibility of each subclass.
109     *
110     * @param type the type of this WikiEvent.
111     */
112    protected void setType( final int type ) {
113        m_type = type;
114    }
115
116    /**
117     * Returns the type of this event.
118     *
119     * @return the type of this WikiEvent. See the enumerated values defined in {@link org.apache.wiki.event.WikiEvent}).
120     */
121    public int getType() {
122        return m_type;
123    }
124
125    /**
126     * Returns the args associated to src, if any.
127     *
128     * @return args associated to src, if any.
129     */
130    public Object[] getArgs() {
131        return args;
132    }
133
134    /**
135     * Returns the requested arg, if any.
136     *
137     * @return requested arg  or null.
138     */
139    public < T > T getArg(final int index, final Class< T > cls ) {
140        if( index >= args.length ) {
141            return null;
142        }
143        return ( T )args[ index ];
144    }
145
146    /**
147     * Returns a String (human-readable) description of an event type. This should be subclassed as necessary.
148     *
149     * @return the String description
150     */
151    public String getTypeDescription() {
152        switch( m_type ) {
153            case ERROR:     return "exception or error event";
154            case UNDEFINED: return "undefined event type";
155            default:        return "unknown event type (" + m_type + ")";
156        }
157    }
158
159    /**
160     * Returns true if the int value is a valid WikiEvent type. Because the WikiEvent class does not itself any event types,
161     * this method returns true if the event type is anything except {@link #ERROR} or {@link #UNDEFINED}. This method is meant to
162     * be subclassed as appropriate.
163     * 
164     * @param type The value to test.
165     * @return true, if the value is a valid WikiEvent type.
166     */
167    public static boolean isValidType( final int type ) {
168        return type != ERROR && type != UNDEFINED;
169    }
170
171
172    /**
173     * Returns a textual representation of an event type.
174     *
175     * @return the String representation
176     */
177    public String eventName() {
178        switch( m_type ) {
179            case ERROR:     return "ERROR";
180            case UNDEFINED: return "UNDEFINED";
181            default:        return "UNKNOWN (" + m_type + ")";
182        }
183    }
184
185    /**
186     * Prints a String (human-readable) representation of this object. This should be subclassed as necessary.
187     *
188     * @see java.lang.Object#toString()
189     * @return the String representation
190     */
191    public String toString() {
192        return "WikiEvent." + eventName() + " [source=" + getSource().toString() + "]";
193    }
194    
195    
196   
197}