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}