    001/**
    002 * Copyright (c) 2004-2011 QOS.ch
    003 * All rights reserved.
    004 *
    005 * Permission is hereby granted, free  of charge, to any person obtaining
    006 * a  copy  of this  software  and  associated  documentation files  (the
    007 * "Software"), to  deal in  the Software without  restriction, including
    008 * without limitation  the rights to  use, copy, modify,  merge, publish,
    009 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
    010 * permit persons to whom the Software  is furnished to do so, subject to
    011 * the following conditions:
    012 *
    013 * The  above  copyright  notice  and  this permission  notice  shall  be
    014 * included in all copies or substantial portions of the Software.
    015 *
    016 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
    017 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
    018 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
    019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    021 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
    022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    023 *
    024 */
    025package org.slf4j.ext;
    026
    027import java.io.Serializable;
    028import java.io.ByteArrayInputStream;
    029import java.io.ByteArrayOutputStream;
    030import java.util.Date;
    031import java.util.HashMap;
    032import java.util.Iterator;
    033import java.util.Map;
    034import java.beans.XMLDecoder;
    035import java.beans.XMLEncoder;
    036import java.beans.ExceptionListener;
    037
    038/**
    039 * Base class for Event Data. Event Data contains data to be logged about an
    040 * event. Users may extend this class for each EventType they want to log.
    041 *
    042 * @author Ralph Goers
    043 */
    044public class EventData implements Serializable {
    045
    046    private static final long serialVersionUID = 153270778642103985L;
    047
    048    private Map<String, Object> eventData = new HashMap<String, Object>();
    049    public static final String EVENT_MESSAGE = "EventMessage";
    050    public static final String EVENT_TYPE = "EventType";
    051    public static final String EVENT_DATETIME = "EventDateTime";
    052    public static final String EVENT_ID = "EventId";
    053
    054    /**
    055     * Default Constructor
    056     */
    057    public EventData() {
    058    }
    059
    060    /**
    061     * Constructor to create event data from a Map.
    062     *
    063     * @param map
    064     *          The event data.
    065     */
    066    public EventData(Map<String, Object> map) {
    067        eventData.putAll(map);
    068    }
    069
    070    /**
    071     * Construct from a serialized form of the Map containing the RequestInfo
    072     * elements
    073     *
    074     * @param xml
    075     *          The serialized form of the RequestInfo Map.
    076     */
    077    @SuppressWarnings("unchecked")
    078    public EventData(String xml) {
    079        ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
    080        try {
    081            XMLDecoder decoder = new XMLDecoder(bais);
    082            this.eventData = (Map<String, Object>) decoder.readObject();
    083        } catch (Exception e) {
    084            throw new EventException("Error decoding " + xml, e);
    085        }
    086    }
    087
    088    /**
    089     * Serialize all the EventData items into an XML representation.
    090     *
    091     * @return an XML String containing all the EventData items.
    092     */
    093    public String toXML() {
    094        return toXML(eventData);
    095    }
    096
    097    /**
    098     * Serialize all the EventData items into an XML representation.
    099     *
    100     * @param map the Map to transform
    101     * @return an XML String containing all the EventData items.
    102     */
    103    public static String toXML(Map<String, Object> map) {
    104        ByteArrayOutputStream baos = new ByteArrayOutputStream();
    105        try {
    106            XMLEncoder encoder = new XMLEncoder(baos);
    107            encoder.setExceptionListener(new ExceptionListener() {
    108                public void exceptionThrown(Exception exception) {
    109                    exception.printStackTrace();
    110                }
    111            });
    112            encoder.writeObject(map);
    113            encoder.close();
    114            return baos.toString();
    115        } catch (Exception e) {
    116            e.printStackTrace();
    117            return null;
    118        }
    119    }
    120
    121    /**
    122     * Retrieve the event identifier.
    123     *
    124     * @return The event identifier
    125     */
    126    public String getEventId() {
    127        return (String) this.eventData.get(EVENT_ID);
    128    }
    129
    130    /**
    131     * Set the event identifier.
    132     *
    133     * @param eventId
    134     *          The event identifier.
    135     */
    136    public void setEventId(String eventId) {
    137        if (eventId == null) {
    138            throw new IllegalArgumentException("eventId cannot be null");
    139        }
    140        this.eventData.put(EVENT_ID, eventId);
    141    }
    142
    143    /**
    144     * Retrieve the message text associated with this event, if any.
    145     *
    146     * @return The message text associated with this event or null if there is
    147     *         none.
    148     */
    149    public String getMessage() {
    150        return (String) this.eventData.get(EVENT_MESSAGE);
    151    }
    152
    153    /**
    154     * Set the message text associated with this event.
    155     *
    156     * @param message
    157     *          The message text.
    158     */
    159    public void setMessage(String message) {
    160        this.eventData.put(EVENT_MESSAGE, message);
    161    }
    162
    163    /**
    164     * Retrieve the date and time the event occurred.
    165     *
    166     * @return The Date associated with the event.
    167     */
    168    public Date getEventDateTime() {
    169        return (Date) this.eventData.get(EVENT_DATETIME);
    170    }
    171
    172    /**
    173     * Set the date and time the event occurred in case it is not the same as when
    174     * the event was logged.
    175     *
    176     * @param eventDateTime
    177     *          The event Date.
    178     */
    179    public void setEventDateTime(Date eventDateTime) {
    180        this.eventData.put(EVENT_DATETIME, eventDateTime);
    181    }
    182
    183    /**
    184     * Set the type of event that occurred.
    185     *
    186     * @param eventType
    187     *          The type of the event.
    188     */
    189    public void setEventType(String eventType) {
    190        this.eventData.put(EVENT_TYPE, eventType);
    191    }
    192
    193    /**
    194     * Retrieve the type of the event.
    195     *
    196     * @return The event type.
    197     */
    198    public String getEventType() {
    199        return (String) this.eventData.get(EVENT_TYPE);
    200    }
    201
    202    /**
    203     * Add arbitrary attributes about the event.
    204     *
    205     * @param name
    206     *          The attribute's key.
    207     * @param obj
    208     *          The data associated with the key.
    209     */
    210    public void put(String name, Serializable obj) {
    211        this.eventData.put(name, obj);
    212    }
    213
    214    /**
    215     * Retrieve an event attribute.
    216     *
    217     * @param name
    218     *          The attribute's key.
    219     * @return The value associated with the key or null if the key is not
    220     *         present.
    221     */
    222    public Serializable get(String name) {
    223        return (Serializable) this.eventData.get(name);
    224    }
    225
    226    /**
    227     * Populate the event data from a Map.
    228     *
    229     * @param data
    230     *          The Map to copy.
    231     */
    232    public void putAll(Map<String, Object> data) {
    233        this.eventData.putAll(data);
    234    }
    235
    236    /**
    237     * Returns the number of attributes in the EventData.
    238     *
    239     * @return the number of attributes in the EventData.
    240     */
    241    public int getSize() {
    242        return this.eventData.size();
    243    }
    244
    245    /**
    246     * Returns an Iterator over all the entries in the EventData.
    247     *
    248     * @return an Iterator that can be used to access all the event attributes.
    249     */
    250    public Iterator<Map.Entry<String, Object>> getEntrySetIterator() {
    251        return this.eventData.entrySet().iterator();
    252    }
    253
    254    /**
    255     * Retrieve all the attributes in the EventData as a Map. Changes to this map
    256     * will be reflected in the EventData.
    257     *
    258     * @return The Map of attributes in this EventData instance.
    259     */
    260    public Map<String, Object> getEventMap() {
    261        return this.eventData;
    262    }
    263
    264    /**
    265     * Convert the EventData to a String.
    266     *
    267     * @return The EventData as a String.
    268     */
    269    @Override
    270    public String toString() {
    271        return toXML();
    272    }
    273
    274    /**
    275     * Compare two EventData objects for equality.
    276     *
    277     * @param o
    278     *          The Object to compare.
    279     * @return true if the objects are the same instance or contain all the same
    280     *         keys and their values.
    281     */
    282    @SuppressWarnings("unchecked")
    283    @Override
    284    public boolean equals(Object o) {
    285        if (this == o) {
    286            return true;
    287        }
    288        if (!(o instanceof EventData || o instanceof Map)) {
    289            return false;
    290        }
    291        Map<String, Object> map = (o instanceof EventData) ? ((EventData) o).getEventMap() : (Map<String, Object>) o;
    292
    293        return this.eventData.equals(map);
    294    }
    295
    296    /**
    297     * Compute the hashCode for this EventData instance.
    298     *
    299     * @return The hashcode for this EventData instance.
    300     */
    301    @Override
    302    public int hashCode() {
    303        return this.eventData.hashCode();
    304    }
    305}