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 * @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)
292 .getEventMap() : (Map<String, Object>) o;
293
294 return this.eventData.equals(map);
295 }
296
297 /**
298 * Compute the hashCode for this EventData instance.
299 *
300 * @return The hashcode for this EventData instance.
301 */
302 @Override
303 public int hashCode() {
304 return this.eventData.hashCode();
305 }
306 }