1 /**
2 * Copyright (c) 2004-2011 QOS.ch
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25 package org.slf4j.ext;
26
27 import java.io.Serializable;
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.util.Date;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.beans.XMLDecoder;
35 import java.beans.XMLEncoder;
36 import java.beans.ExceptionListener;
37
38 /**
39 * Base class for Event Data. Event Data contains data to be logged about an
40 * event. Users may extend this class for each EventType they want to log.
41 *
42 * @author Ralph Goers
43 */
44 public class EventData implements Serializable {
45
46 private static final long serialVersionUID = 153270778642103985L;
47
48 private Map<String, Object> eventData = new HashMap<String, Object>();
49 public static final String EVENT_MESSAGE = "EventMessage";
50 public static final String EVENT_TYPE = "EventType";
51 public static final String EVENT_DATETIME = "EventDateTime";
52 public static final String EVENT_ID = "EventId";
53
54 /**
55 * Default Constructor
56 */
57 public EventData() {
58 }
59
60 /**
61 * Constructor to create event data from a Map.
62 *
63 * @param map
64 * The event data.
65 */
66 public EventData(Map<String, Object> map) {
67 eventData.putAll(map);
68 }
69
70 /**
71 * Construct from a serialized form of the Map containing the RequestInfo
72 * elements
73 *
74 * @param xml
75 * The serialized form of the RequestInfo Map.
76 */
77 @SuppressWarnings("unchecked")
78 public EventData(String xml) {
79 ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
80 try {
81 XMLDecoder decoder = new XMLDecoder(bais);
82 this.eventData = (Map<String, Object>) decoder.readObject();
83 } catch (Exception e) {
84 throw new EventException("Error decoding " + xml, e);
85 }
86 }
87
88 /**
89 * Serialize all the EventData items into an XML representation.
90 *
91 * @return an XML String containing all the EventDAta items.
92 */
93 public String toXML() {
94 return toXML(eventData);
95 }
96
97 /**
98 * Serialize all the EventData items into an XML representation.
99 *
100 * @return an XML String containing all the EventDAta items.
101 */
102 public static String toXML(Map<String, Object> map) {
103 ByteArrayOutputStream baos = new ByteArrayOutputStream();
104 try {
105 XMLEncoder encoder = new XMLEncoder(baos);
106 encoder.setExceptionListener(new ExceptionListener() {
107 public void exceptionThrown(Exception exception) {
108 exception.printStackTrace();
109 }
110 });
111 encoder.writeObject(map);
112 encoder.close();
113 return baos.toString();
114 } catch (Exception e) {
115 e.printStackTrace();
116 return null;
117 }
118 }
119
120 /**
121 * Retrieve the event identifier.
122 *
123 * @return The event identifier
124 */
125 public String getEventId() {
126 return (String) this.eventData.get(EVENT_ID);
127 }
128
129 /**
130 * Set the event identifier.
131 *
132 * @param eventId
133 * The event identifier.
134 */
135 public void setEventId(String eventId) {
136 if (eventId == null) {
137 throw new IllegalArgumentException("eventId cannot be null");
138 }
139 this.eventData.put(EVENT_ID, eventId);
140 }
141
142 /**
143 * Retrieve the message text associated with this event, if any.
144 *
145 * @return The message text associated with this event or null if there is
146 * none.
147 */
148 public String getMessage() {
149 return (String) this.eventData.get(EVENT_MESSAGE);
150 }
151
152 /**
153 * Set the message text associated with this event.
154 *
155 * @param message
156 * The message text.
157 */
158 public void setMessage(String message) {
159 this.eventData.put(EVENT_MESSAGE, message);
160 }
161
162 /**
163 * Retrieve the date and time the event occurred.
164 *
165 * @return The Date associated with the event.
166 */
167 public Date getEventDateTime() {
168 return (Date) this.eventData.get(EVENT_DATETIME);
169 }
170
171 /**
172 * Set the date and time the event occurred in case it is not the same as when
173 * the event was logged.
174 *
175 * @param eventDateTime
176 * The event Date.
177 */
178 public void setEventDateTime(Date eventDateTime) {
179 this.eventData.put(EVENT_DATETIME, eventDateTime);
180 }
181
182 /**
183 * Set the type of event that occurred.
184 *
185 * @param eventType
186 * The type of the event.
187 */
188 public void setEventType(String eventType) {
189 this.eventData.put(EVENT_TYPE, eventType);
190 }
191
192 /**
193 * Retrieve the type of the event.
194 *
195 * @return The event type.
196 */
197 public String getEventType() {
198 return (String) this.eventData.get(EVENT_TYPE);
199 }
200
201 /**
202 * Add arbitrary attributes about the event.
203 *
204 * @param name
205 * The attribute's key.
206 * @param obj
207 * The data associated with the key.
208 */
209 public void put(String name, Serializable obj) {
210 this.eventData.put(name, obj);
211 }
212
213 /**
214 * Retrieve an event attribute.
215 *
216 * @param name
217 * The attribute's key.
218 * @return The value associated with the key or null if the key is not
219 * present.
220 */
221 public Serializable get(String name) {
222 return (Serializable) this.eventData.get(name);
223 }
224
225 /**
226 * Populate the event data from a Map.
227 *
228 * @param data
229 * The Map to copy.
230 */
231 public void putAll(Map<String, Object> data) {
232 this.eventData.putAll(data);
233 }
234
235 /**
236 * Returns the number of attributes in the EventData.
237 *
238 * @return the number of attributes in the EventData.
239 */
240 public int getSize() {
241 return this.eventData.size();
242 }
243
244 /**
245 * Returns an Iterator over all the entries in the EventDAta.
246 *
247 * @return an Iterator that can be used to access all the event attributes.
248 */
249 public Iterator<Map.Entry<String, Object>> getEntrySetIterator() {
250 return this.eventData.entrySet().iterator();
251 }
252
253 /**
254 * Retrieve all the attributes in the EventData as a Map. Changes to this map
255 * will be reflected in the EventData.
256 *
257 * @return The Map of attributes in this EventData instance.
258 */
259 public Map<String, Object> getEventMap() {
260 return this.eventData;
261 }
262
263 /**
264 * Convert the EventData to a String.
265 *
266 * @return The EventData as a String.
267 */
268 @Override
269 public String toString() {
270 return toXML();
271 }
272
273 /**
274 * Compare two EventData objects for equality.
275 *
276 * @param o
277 * The Object to compare.
278 * @return true if the objects are the same instance or contain all the same
279 * keys and their values.
280 */
281 @SuppressWarnings("unchecked")
282 @Override
283 public boolean equals(Object o) {
284 if (this == o) {
285 return true;
286 }
287 if (!(o instanceof EventData || o instanceof Map)) {
288 return false;
289 }
290 Map<String, Object> map = (o instanceof EventData) ? ((EventData) o)
291 .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 }