1   package org.slf4j.ext;
2   
3   import java.io.Serializable;
4   import java.io.ByteArrayInputStream;
5   import java.io.ByteArrayOutputStream;
6   import java.util.Date;
7   import java.util.HashMap;
8   import java.util.Iterator;
9   import java.util.Map;
10  import java.beans.XMLDecoder;
11  import java.beans.XMLEncoder;
12  import java.beans.ExceptionListener;
13  
14  /**
15   * Base class for Event Data. Event Data contains data to be logged about an
16   * event. Users may extend this class for each EventType they want to log.
17   * 
18   * @author Ralph Goers
19   */
20  public class EventData implements Serializable {
21    private Map<String, Object> eventData = new HashMap<String, Object>();
22    public static final String EVENT_MESSAGE = "EventMessage";
23    public static final String EVENT_TYPE = "EventType";
24    public static final String EVENT_DATETIME = "EventDateTime";
25    public static final String EVENT_ID = "EventId";
26  
27    /**
28     * Default Constructor
29     */
30    public EventData() {
31    }
32  
33    /**
34     * Constructor to create event data from a Map.
35     * 
36     * @param map
37     *          The event data.
38     */
39    public EventData(Map<String, Object> map) {
40      eventData.putAll(map);
41    }
42  
43    /**
44     * Construct from a serialized form of the Map containing the RequestInfo
45     * elements
46     * 
47     * @param xml
48     *          The serialized form of the RequestInfo Map.
49     */
50    public EventData(String xml) {
51      ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
52      try {
53        XMLDecoder decoder = new XMLDecoder(bais);
54        this.eventData = (Map<String, Object>) decoder.readObject();
55      } catch (Exception e) {
56        throw new EventException("Error decoding " + xml, e);
57      }
58    }
59  
60    /**
61     * Serialize all the EventData items into an XML representation.
62     * 
63     * @return an XML String containing all the EventDAta items.
64     */
65    public String toXML() {
66      return toXML(eventData);
67    }
68  
69    /**
70     * Serialize all the EventData items into an XML representation.
71     * 
72     * @return an XML String containing all the EventDAta items.
73     */
74    public static String toXML(Map<String, Object> map) {
75      ByteArrayOutputStream baos = new ByteArrayOutputStream();
76      try {
77        XMLEncoder encoder = new XMLEncoder(baos);
78        encoder.setExceptionListener(new ExceptionListener() {
79          public void exceptionThrown(Exception exception) {
80            exception.printStackTrace();
81          }
82        });
83        encoder.writeObject(map);
84        encoder.close();
85        return baos.toString();
86      } catch (Exception e) {
87        e.printStackTrace();
88        return null;
89      }
90    }
91  
92    /**
93     * Retrieve the event identifier.
94     * 
95     * @return The event identifier
96     */
97    public String getEventId() {
98      return (String) this.eventData.get(EVENT_ID);
99    }
100 
101   /**
102    * Set the event identifier.
103    * 
104    * @param eventId
105    *          The event identifier.
106    */
107   public void setEventId(String eventId) {
108     if (eventId == null) {
109       throw new IllegalArgumentException("eventId cannot be null");
110     }
111     this.eventData.put(EVENT_ID, eventId);
112   }
113 
114   /**
115    * Retrieve the message text associated with this event, if any.
116    * 
117    * @return The message text associated with this event or null if there is
118    *         none.
119    */
120   public String getMessage() {
121     return (String) this.eventData.get(EVENT_MESSAGE);
122   }
123 
124   /**
125    * Set the message text associated with this event.
126    * 
127    * @param message
128    *          The message text.
129    */
130   public void setMessage(String message) {
131     this.eventData.put(EVENT_MESSAGE, message);
132   }
133 
134   /**
135    * Retrieve the date and time the event occurred.
136    * 
137    * @return The Date associated with the event.
138    */
139   public Date getEventDateTime() {
140     return (Date) this.eventData.get(EVENT_DATETIME);
141   }
142 
143   /**
144    * Set the date and time the event occurred in case it is not the same as when
145    * the event was logged.
146    * 
147    * @param eventDateTime
148    *          The event Date.
149    */
150   public void setEventDateTime(Date eventDateTime) {
151     this.eventData.put(EVENT_DATETIME, eventDateTime);
152   }
153 
154   /**
155    * Set the type of event that occurred.
156    * 
157    * @param eventType
158    *          The type of the event.
159    */
160   public void setEventType(String eventType) {
161     this.eventData.put(EVENT_TYPE, eventType);
162   }
163 
164   /**
165    * Retrieve the type of the event.
166    * 
167    * @return The event type.
168    */
169   public String getEventType() {
170     return (String) this.eventData.get(EVENT_TYPE);
171   }
172 
173   /**
174    * Add arbitrary attributes about the event.
175    * 
176    * @param name
177    *          The attribute's key.
178    * @param obj
179    *          The data associated with the key.
180    */
181   public void put(String name, Serializable obj) {
182     this.eventData.put(name, obj);
183   }
184 
185   /**
186    * Retrieve an event attribute.
187    * 
188    * @param name
189    *          The attribute's key.
190    * @return The value associated with the key or null if the key is not
191    *         present.
192    */
193   public Serializable get(String name) {
194     return (Serializable) this.eventData.get(name);
195   }
196 
197   /**
198    * Populate the event data from a Map.
199    * 
200    * @param data
201    *          The Map to copy.
202    */
203   public void putAll(Map<String, Object> data) {
204     this.eventData.putAll(data);
205   }
206 
207   /**
208    * Returns the number of attributes in the EventData.
209    * 
210    * @return the number of attributes in the EventData.
211    */
212   public int getSize() {
213     return this.eventData.size();
214   }
215 
216   /**
217    * Returns an Iterator over all the entries in the EventDAta.
218    * 
219    * @return an Iterator that can be used to access all the event attributes.
220    */
221   public Iterator<Map.Entry<String, Object>> getEntrySetIterator() {
222     return this.eventData.entrySet().iterator();
223   }
224 
225   /**
226    * Retrieve all the attributes in the EventData as a Map. Changes to this map
227    * will be reflected in the EventData.
228    * 
229    * @return The Map of attributes in this EventData instance.
230    */
231   public Map<String, Object> getEventMap() {
232     return this.eventData;
233   }
234 
235   /**
236    * Convert the EventData to a String.
237    * 
238    * @return The EventData as a String.
239    */
240   @Override
241   public String toString() {
242     return toXML();
243   }
244 
245   /**
246    * Compare two EventData objects for equality.
247    * 
248    * @param o
249    *          The Object to compare.
250    * @return true if the objects are the same instance or contain all the same
251    *         keys and their values.
252    */
253   @Override
254   public boolean equals(Object o) {
255     if (this == o) {
256       return true;
257     }
258     if (!(o instanceof EventData || o instanceof Map)) {
259       return false;
260     }
261     Map<String, Object> map = (o instanceof EventData) ? ((EventData) o)
262         .getEventMap() : (Map<String, Object>) o;
263 
264     return this.eventData.equals(map);
265   }
266 
267   /**
268    * Compute the hashCode for this EventData instance.
269    * 
270    * @return The hashcode for this EventData instance.
271    */
272   @Override
273   public int hashCode() {
274     return this.eventData.hashCode();
275   }
276 }