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