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