boolean and byte array support added
[lwes-java.git] / src / main / java / org / lwes / Event.java
blob8b757982857e0b51f997bea8af944641c03730b0
1 package org.lwes;
3 import org.lwes.db.EventTemplateDB;
4 import org.lwes.serializer.Deserializer;
5 import org.lwes.serializer.DeserializerState;
6 import org.lwes.serializer.Serializer;
7 import org.lwes.util.CharacterEncoding;
8 import org.lwes.util.IPAddress;
9 import org.lwes.util.Log;
10 import org.lwes.util.NumberCodec;
12 import java.math.BigInteger;
13 import java.net.InetAddress;
14 import java.util.Arrays;
15 import java.util.Enumeration;
16 import java.util.Map;
17 import java.util.concurrent.ConcurrentHashMap;
19 public class Event {
21 public static final int MAX_MESSAGE_SIZE = 65507;
23 /**
24 * Reserved metadata keywords
26 public static final String ENCODING = "enc";
27 public static final String RECEIPT_TIME = "ReceiptTime";
28 public static final String SENDER_IP = "SenderIP";
29 public static final String SENDER_PORT = "SenderPort";
31 /**
32 * Encoding variables
34 public static final short ISO_8859_1 = 0;
35 public static final short UTF_8 = 1;
36 public static final short DEFAULT_ENCODING = UTF_8;
37 public static final CharacterEncoding[] ENCODING_STRINGS = {
38 CharacterEncoding.ISO_8859_1, CharacterEncoding.UTF_8};
40 /**
41 * Event data
43 private ConcurrentHashMap<String, BaseType> attributes = new ConcurrentHashMap<String, BaseType>();
44 private String name = null;
45 private EventTemplateDB eventTemplateDB = null;
46 private short encoding = DEFAULT_ENCODING;
48 /**
49 * If this is set to true, types and attributes are validated against the EventTemplateDB
51 private boolean validating = true;
53 /**
54 * Internal object for deserialization state
56 private DeserializerState state = null;
58 /**
59 * the size of the event in bytes
61 private int bytesStoreSize = 0;
63 /**
64 * Create an event called <tt>eventName</tt>
66 * @param eventName the name of the event
67 * @param eventTemplateDB the EventTemplateDB to use for validation
68 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
69 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
70 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
72 public Event(String eventName, EventTemplateDB eventTemplateDB)
73 throws EventSystemException {
74 this(eventName, true, eventTemplateDB);
77 /**
78 * Create an event called <tt>eventName</tt>
80 * @param eventName the name of the event
81 * @param validate true if the EventTemplateDB should be checked for types before all mutations
82 * @param eventTemplateDB the EventTemplateDB to use for validation
83 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
84 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
85 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
87 public Event(String eventName, boolean validate, EventTemplateDB eventTemplateDB)
88 throws EventSystemException {
89 this(eventName, validate, eventTemplateDB, DEFAULT_ENCODING);
92 /**
93 * Create an event called <tt>eventName</tt>
95 * @param eventName the name of the event
96 * @param validate true if the EventTemplateDB should be checked for types before all mutations
97 * @param encoding the character encoding used by the event
98 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
99 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
100 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
102 public Event(String eventName, boolean validate, EventTemplateDB eventTemplateDB, short encoding)
103 throws EventSystemException {
104 setEventTemplateDB(eventTemplateDB);
105 validating = validate;
106 setEventName(eventName);
107 setEncoding(encoding);
111 * Creates an event by deserializing a raw byte array.
113 * @param bytes the raw bytes to convert
114 * @param eventTemplateDB the EventTemplateDB to use to validate the event
115 * @throws NoSuchEventException
116 * @throws NoSuchAttributeException
117 * @throws NoSuchAttributeTypeException
119 public Event(byte[] bytes, EventTemplateDB eventTemplateDB)
120 throws EventSystemException {
121 this(bytes, true, eventTemplateDB);
126 * Creates an event by deserializing a raw byte array.
128 * @param bytes the raw bytes to convert
129 * @param validate whether or not to validate the event
130 * @param eventTemplateDB the EventTemplateDB to use to validate the event
131 * @throws NoSuchEventException
132 * @throws NoSuchAttributeException
133 * @throws NoSuchAttributeTypeException
135 public Event(byte[] bytes, boolean validate, EventTemplateDB eventTemplateDB)
136 throws EventSystemException {
137 setEventTemplateDB(eventTemplateDB);
138 validating = validate;
139 deserialize(bytes);
143 * Returns an enumeration of all the event attribute names
145 * @return an enumeration of attribute strings
147 public Enumeration<String> getEventAttributeNames() {
148 if (attributes == null) {
149 return null;
152 return attributes.keys();
156 * Returns the number of attributes in the event
158 * @return number of attributes in the event
160 public int size() {
161 if (attributes == null) {
162 return 0;
164 return attributes.size();
168 * Returns true if the event validates against the EventTemplateDB before making changes
170 * @return the validating state
172 public boolean isValidating() {
173 return this.validating;
177 * Set to true if the event should validate against the EventTemplateDB before making changes
179 * @param validate the validating value
181 public void setValidating(boolean validate) {
182 this.validating = validate;
186 * Returns the EventTemplateDB for this event, used for validation of types and attributes.
188 * @return the EventTemplateDB
190 public EventTemplateDB getEventTemplateDB() {
191 return this.eventTemplateDB;
195 * Sets the EventTemplateDB for this event, used for validation of types and attributes.
197 * @param eventTemplateDB the EventTemplateDB to be used for validation
199 public void setEventTemplateDB(EventTemplateDB eventTemplateDB) {
200 this.eventTemplateDB = eventTemplateDB;
204 * Returns the name of the event
206 * @return the name of the event
208 public synchronized String getEventName() {
209 return this.name;
213 * Sets the name of the Event
215 * @param name the name of the event
216 * @throws NoSuchEventException if the event is validating and does not exist in the EventTemplateDB
218 public synchronized void setEventName(String name) throws NoSuchEventException {
219 if (isValidating() && getEventTemplateDB() != null) {
220 if (!getEventTemplateDB().checkForEvent(name)) {
221 throw new NoSuchEventException("Event " + name + " does not exist in event definition");
225 /* determine if we already have the name and are just resetting it */
226 if (this.name != null) {
227 bytesStoreSize -= (this.name.length() + 1 + 2);
230 bytesStoreSize += (name.length() + 1 + 2);
232 this.name = name;
236 * Get the character encoding for this event
238 * @return the encoding
240 public short getEncoding() {
241 return this.encoding;
245 * Set the character encoding for event strings
247 * @param encoding the character encoding
248 * @throws NoSuchAttributeTypeException if the type for the encoding attribute does not exist
249 * @throws NoSuchAttributeException if the encoding attribute does not exist
251 public void setEncoding(short encoding) throws EventSystemException {
252 this.encoding = encoding;
253 setInt16(ENCODING, this.encoding);
257 * Generic accessor, checks if an attribute exists and returns its value. The user must do their
258 * own type checking.
260 * @param attributeName name of the attribute to lookup
261 * @return the object poitned to by attributeName
262 * @throws NoSuchAttributeException if the attribute does not exist in this event
264 public Object get(String attributeName) throws NoSuchAttributeException {
265 if (attributes == null) {
266 return null;
269 if (attributes.containsKey(attributeName)) {
270 return attributes.get(attributeName).getTypeObject();
273 if (isValidating() && getEventTemplateDB() != null) {
274 if (getEventTemplateDB().checkForAttribute(name, attributeName)) {
275 return null;
277 else {
278 throw new NoSuchAttributeException("Attribute " + attributeName + " does not exist for event " + name);
282 return null;
285 public short[] getInt16Array(String attributeName)
286 throws NoSuchAttributeException {
287 Object o = get(attributeName);
288 if (o != null && o instanceof short[]) {
289 return (short[]) o;
291 else {
292 return null;
296 public int[] getInt32Array(String attributeName)
297 throws NoSuchAttributeException {
298 Object o = get(attributeName);
299 if (o != null && o instanceof int[]) {
300 return (int[]) o;
302 else {
303 return null;
307 public long[] getInt64Array(String attributeName)
308 throws NoSuchAttributeException {
309 Object o = get(attributeName);
310 if (o != null && o instanceof long[]) {
311 return (long[]) o;
313 else {
314 return null;
318 public int[] getUInt16Array(String attributeName)
319 throws NoSuchAttributeException {
320 Object o = get(attributeName);
321 if (o != null && o instanceof int[]) {
322 return (int[]) o;
324 else {
325 return null;
329 public long[] getUInt32Array(String attributeName)
330 throws NoSuchAttributeException {
331 Object o = get(attributeName);
332 if (o != null && o instanceof long[]) {
333 return (long[]) o;
335 else {
336 return null;
340 public long[] getUInt64Array(String attributeName)
341 throws NoSuchAttributeException {
342 Object o = get(attributeName);
343 if (o != null && o instanceof long[]) {
344 return (long[]) o;
346 else {
347 return null;
351 public String[] getStringArray(String attributeName)
352 throws NoSuchAttributeException {
353 Object o = get(attributeName);
354 if (o != null && o instanceof String[]) {
355 return (String[]) o;
357 else {
358 return null;
362 public boolean[] getBooleanArray(String attributeName) throws NoSuchAttributeException {
363 Object o = get(attributeName);
364 if (o != null && o instanceof boolean[]) {
365 return (boolean[]) o;
367 else {
368 return null;
372 public byte[] getByteArray(String attributeName) throws NoSuchAttributeException {
373 Object o = get(attributeName);
374 if (o != null && o instanceof byte[]) {
375 return (byte[]) o;
377 else {
378 return null;
383 * Method to check if an attribute is set in the event. This method does not throw
384 * NoSuchAttributeException because it shouldn't really care. If it's not there, it's
385 * not there.
387 * @param attributeName The attribute name to check for existance.
388 * @return true if there is a value, false if not.
390 public boolean isSet(String attributeName) {
391 try {
392 return (get(attributeName) != null);
394 catch (NoSuchAttributeException e) {
395 return false;
400 * Accessor that returns a boolean value for attribute <tt>attributeName</tt>
402 * @param attributeName the name of the attribute to fetch
403 * @return the boolean value
404 * @throws NoSuchAttributeException if the attribute does not exist in this event
406 public Boolean getBoolean(String attributeName) throws NoSuchAttributeException {
407 return (Boolean) get(attributeName);
411 * Accessor that returns an <tt>unsigned short</tt>, in the guise of an <tt>int</tt>, for attribute <tt>attributeName</tt>
413 * @param attributeName the name of the attribute to fetch
414 * @return the unsigned short as an int
415 * @throws NoSuchAttributeException if the attribute does not exist in this event
417 public Integer getUInt16(String attributeName) throws NoSuchAttributeException {
418 return (Integer) get(attributeName);
422 * Accessor that returns an <tt>short</tt>, for attribute <tt>attributeName</tt>
424 * @param attributeName the name of the attribute to fetch
425 * @return the short value
426 * @throws NoSuchAttributeException if the attribute does not exist in this event
428 public Short getInt16(String attributeName) throws NoSuchAttributeException {
429 return (Short) get(attributeName);
433 * Accessor that returns an <tt>unsigned int</tt>, in the guise of an <tt>long</tt>, for attribute <tt>attributeName</tt>
435 * @param attributeName the name of the attribute to fetch
436 * @return the unsigned int as a long
437 * @throws NoSuchAttributeException if the attribute does not exist in this event
439 public Long getUInt32(String attributeName) throws NoSuchAttributeException {
440 return (Long) get(attributeName);
444 * Accessor that returns an <tt>int</tt>, for attribute <tt>attributeName</tt>
446 * @param attributeName the name of the attribute to fetch
447 * @return the int value
448 * @throws NoSuchAttributeException if the attribute does not exist in this event
450 public Integer getInt32(String attributeName) throws NoSuchAttributeException {
451 return (Integer) get(attributeName);
455 * Accessor that returns an <tt>unsigned long</tt>, in the guise of an <tt>BigInteger</tt>, for attribute <tt>attributeName</tt>
457 * @param attributeName the name of the attribute to fetch
458 * @return the unsigned long as a BigInteger
459 * @throws NoSuchAttributeException if the attribute does not exist in this event
461 public BigInteger getUInt64(String attributeName) throws NoSuchAttributeException {
462 return (BigInteger) get(attributeName);
467 * Accessor that returns an <tt>long</tt>, for attribute <tt>attributeName</tt>
469 * @param attributeName the name of the attribute to fetch
470 * @return the long value
471 * @throws NoSuchAttributeException if the attribute does not exist in this event
473 public Long getInt64(String attributeName) throws NoSuchAttributeException {
474 return (Long) get(attributeName);
478 * Accessor that returns an <tt>String</tt>, for attribute <tt>attributeName</tt>
480 * @param attributeName the name of the attribute to fetch
481 * @return the String value
482 * @throws NoSuchAttributeException if the attribute does not exist in this event
484 public String getString(String attributeName) throws NoSuchAttributeException {
485 return (String) get(attributeName);
489 * Accessor that returns an <tt>InetAddress</tt>, for attribute <tt>attributeName</tt>
491 * @param attributeName the name of the attribute to fetch
492 * @return the InetAddress value
493 * @throws NoSuchAttributeException if the attribute does not exist in this event
495 public InetAddress getInetAddress(String attributeName) throws NoSuchAttributeException {
496 IPAddress a = (IPAddress) get(attributeName);
497 if (a != null) {
498 return a.toInetAddress();
500 else {
501 return null;
506 * Accessor that returns an IP address in bytes, for attribute <tt>attributeName</tt>
508 * @param attributeName the name of the attribute to fetch
509 * @return the IP address in bytes
510 * @throws NoSuchAttributeException if the attribute does not exist in this event
512 public byte[] getIPAddress(String attributeName) throws NoSuchAttributeException {
513 return (byte[]) get(attributeName);
518 * Set the object's attribute <tt>attributeName</tt> with the Object given
520 * @param attributeName the name of the attribute to set
521 * @param attributeValue the object to set the attribute with
522 * @throws NoSuchAttributeException if the attribute does not exist in this event
523 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
525 public void set(String attributeName, Object attributeValue)
526 throws EventSystemException {
527 if (isValidating() && getEventTemplateDB() != null) {
528 if (getEventTemplateDB().checkForAttribute(getEventName(), attributeName)) {
529 BaseType bt = getEventTemplateDB().getBaseTypeForObjectAttribute(getEventName(),
530 attributeName, attributeValue);
531 set(attributeName, bt);
534 else {
535 throw new NoSuchAttributeException("Must be able to check the EventTemplateDB to use set(String,Object)");
540 * Private method to set a BaseType
542 * @param attribute the name of the attribute to set
543 * @param anObject the BaseType to set in the event
544 * @throws NoSuchAttributeException if the attribute does not exist in this event
545 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
547 private void set(String attribute, BaseType anObject)
548 throws EventSystemException {
550 if (isValidating() && getEventTemplateDB() != null) {
551 if (getEventTemplateDB().checkForAttribute(name, attribute)) {
552 if (!getEventTemplateDB().checkTypeForAttribute(name, attribute, anObject)) {
553 throw new NoSuchAttributeTypeException("Wrong type '" + anObject.getTypeName() +
554 "' for " + name + "." + attribute);
557 else {
558 throw new NoSuchAttributeException("Attribute " + attribute + " does not exist for event " + name);
560 getEventTemplateDB().checkForSize(name, attribute, anObject);
563 if (anObject.getTypeObject() != null) {
564 BaseType oldObject = null;
565 int newSize = bytesStoreSize + ((attribute.length() + 1) + anObject.bytesStoreSize(encoding));
566 if (newSize > MAX_MESSAGE_SIZE) {
567 throw new EventSystemException("Event size limit is " + MAX_MESSAGE_SIZE + " bytes.");
569 if ((oldObject = attributes.remove(attribute)) != null) {
570 bytesStoreSize -= (attribute.length() + 1) + oldObject.bytesStoreSize(encoding);
573 bytesStoreSize += (attribute.length() + 1) + anObject.bytesStoreSize(encoding);
574 attributes.put(attribute, anObject);
578 public void setInt16Array(String attributeName, short[] value) throws EventSystemException {
579 set(attributeName, new BaseType(TypeID.INT16_ARRAY_STRING,
580 TypeID.INT16_ARRAY_TOKEN,
581 value));
584 public void setInt32Array(String attributeName, int[] value) throws EventSystemException {
585 set(attributeName, new BaseType(TypeID.INT32_ARRAY_STRING,
586 TypeID.INT32_ARRAY_TOKEN,
587 value));
590 public void setInt64Array(String attributeName, long[] value) throws EventSystemException {
591 set(attributeName, new BaseType(TypeID.INT64_ARRAY_STRING,
592 TypeID.INT64_ARRAY_TOKEN,
593 value));
596 public void setUInt16Array(String attributeName, int[] value) throws EventSystemException {
597 set(attributeName, new BaseType(TypeID.UINT16_ARRAY_STRING,
598 TypeID.UINT16_ARRAY_TOKEN,
599 value));
602 public void setUInt32Array(String attributeName, long[] value) throws EventSystemException {
603 set(attributeName, new BaseType(TypeID.UINT32_ARRAY_STRING,
604 TypeID.UINT32_ARRAY_TOKEN,
605 value));
608 public void setUInt64Array(String attributeName, long[] value) throws EventSystemException {
609 set(attributeName, new BaseType(TypeID.UINT64_ARRAY_STRING,
610 TypeID.UINT64_ARRAY_TOKEN,
611 value));
614 public void setStringArray(String attributeName, String[] value)
615 throws EventSystemException {
616 set(attributeName, new BaseType(TypeID.STRING_ARRAY_STRING,
617 TypeID.STRING_ARRAY_TOKEN,
618 value));
621 public void setBooleanArray(String attributeName, boolean[] value)
622 throws EventSystemException {
623 set(attributeName, new BaseType(TypeID.BOOLEAN_ARRAY_STRING,
624 TypeID.BOOLEAN_ARRAY_TOKEN,
625 value));
628 public void setByteArray(String attributeName, byte[] value)
629 throws EventSystemException {
630 set(attributeName, new BaseType(TypeID.BYTE_ARRAY_STRING,
631 TypeID.BYTE_ARRAY_TOKEN,
632 value));
636 * Sets the given attribute with a <tt>boolean</tt> value given by <tt>aBool</tt>.
638 * @param attributeName the attribute to set
639 * @param aBool the boolean value to set
640 * @throws NoSuchAttributeException if the attribute does not exist in the event
641 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
643 public void setBoolean(String attributeName, boolean aBool)
644 throws EventSystemException {
645 setBoolean(attributeName, Boolean.valueOf(aBool));
649 * Sets the given attribute with a <tt>Boolean</tt> value given by <tt>aBool</tt>.
651 * @param attributeName the attribute to set
652 * @param aBool the boolean value to set
653 * @throws NoSuchAttributeException
654 * @throws NoSuchAttributeTypeException
656 public void setBoolean(String attributeName, Boolean aBool)
657 throws EventSystemException {
658 set(attributeName, new BaseType(TypeID.BOOLEAN_STRING, TypeID.BOOLEAN_TOKEN, aBool));
662 * Set the given attribute with the <tt>unsigned short</tt> value given by <tt>aNumber</tt>.
663 * Because Java does not support unsigned types, we must use a signed int to cover the range of unsigned short.
665 * @param attributeName the attribute to set
666 * @param aNumber the unsigned short value as an integer
667 * @throws NoSuchAttributeException if the attribute does not exist in the event
668 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
670 public void setUInt16(String attributeName, int aNumber)
671 throws EventSystemException {
672 setUInt16(attributeName, Integer.valueOf(aNumber));
676 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
677 * This should be an <tt>unsigned short</tt>, but is an Integer because Java does not support unsigned types,
678 * and a signed integer is needed to cover the range of an unsigned short.
680 * @param attributeName the attribute to set
681 * @param aNumber the value
683 public void setUInt16(String attributeName, Integer aNumber)
684 throws EventSystemException {
685 set(attributeName, new BaseType(TypeID.UINT16_STRING, TypeID.UINT16_TOKEN, aNumber));
689 * Set the given attribute with the <tt>short</tt> value given by <tt>aNumber</tt>.
691 * @param attributeName the attribute to set
692 * @param aNumber the short value to set
693 * @throws NoSuchAttributeException if the attribute does not exist in the event
694 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
696 public void setInt16(String attributeName, short aNumber)
697 throws EventSystemException {
698 setInt16(attributeName, Short.valueOf(aNumber));
702 * Set the given attribute with the <tt>Short</tt> value given by <tt>aNumber</tt>.
704 * @param attributeName the attribute to set
705 * @param aNumber the short value to set
706 * @throws NoSuchAttributeException if the attribute does not exist in the event
707 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
709 public void setInt16(String attributeName, Short aNumber)
710 throws EventSystemException {
711 set(attributeName, new BaseType(TypeID.INT16_STRING, TypeID.INT16_TOKEN, aNumber));
715 * Set the given attribute with the <tt>unsigned int</tt> value given by <tt>aNumber</tt>.
716 * Because Java does not support unsigned types, we must use a signed long to cover the range of an unsigned int.
718 * @param attributeName the attribute to set
719 * @param aNumber the unsigned int value as a long
720 * @throws NoSuchAttributeException if the attribute does not exist in the event
721 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
723 public void setUInt32(String attributeName, long aNumber)
724 throws EventSystemException {
725 setUInt32(attributeName, Long.valueOf(aNumber));
729 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
730 * This should be an <tt>unsigned int</tt>, but is an Long because Java does not support unsigned types,
731 * and a signed long is needed to cover the range of an unsigned int.
733 * @param attributeName the attribute to set
734 * @param aNumber the value
736 public void setUInt32(String attributeName, Long aNumber)
737 throws EventSystemException {
738 set(attributeName, new BaseType(TypeID.UINT32_STRING, TypeID.UINT32_TOKEN, aNumber));
742 * Set the given attribute with the <tt>int</tt> value given by <tt>aNumber</tt>.
744 * @param attributeName the attribute to set
745 * @param aNumber the integer value to set
746 * @throws NoSuchAttributeException if the attribute does not exist in the event
747 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
749 public void setInt32(String attributeName, int aNumber)
750 throws EventSystemException {
751 setInt32(attributeName, Integer.valueOf(aNumber));
755 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
757 * @param attributeName the attribute to set
758 * @param aNumber the Integer value to set
759 * @throws NoSuchAttributeException if the attribute does not exist in the event
760 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
762 public void setInt32(String attributeName, Integer aNumber)
763 throws EventSystemException {
764 set(attributeName, new BaseType(TypeID.INT32_STRING, TypeID.INT32_TOKEN, aNumber));
768 * Set the given attribute with the <tt>unsigned long</tt> value given by <tt>aNumber</tt>.
770 * @param attributeName the attribute to set
771 * @param aNumber the value
772 * @throws NoSuchAttributeException if the attribute does not exist in the event
773 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
775 public void setUInt64(String attributeName, long aNumber)
776 throws EventSystemException {
777 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber)));
781 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
783 * @param attributeName the attribute to set
784 * @param aNumber the value
785 * @throws NoSuchAttributeException if the attribute does not exist in the event
786 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
788 public void setUInt64(String attributeName, Long aNumber)
789 throws EventSystemException {
790 set(attributeName,
791 new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber.longValue())));
795 * Set the given attribute with the <tt>BigInteger</tt> value given by <tt>aNumber</tt>.
796 * This should be an <tt>unsigned long</tt>, but is an BigInteger because Java does not support unsigned types,
797 * and a BigInteger is needed to cover the range of an unsigned long.
799 * @param attributeName the attribute to set
800 * @param aNumber the value
802 public void setUInt64(String attributeName, BigInteger aNumber)
803 throws EventSystemException {
804 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, aNumber));
808 * Set the given attribute with the <tt>long</tt> value given by <tt>aNumber</tt>.
810 * @param attributeName the attribute to set
811 * @param aNumber the long value to set
812 * @throws NoSuchAttributeException if the attribute does not exist in the event
813 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
815 public void setInt64(String attributeName, long aNumber)
816 throws EventSystemException {
817 setInt64(attributeName, Long.valueOf(aNumber));
821 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
823 * @param attributeName the attribute to set
824 * @param aNumber the Long value to set
825 * @throws NoSuchAttributeException if the attribute does not exist in the event
826 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
828 public void setInt64(String attributeName, Long aNumber)
829 throws EventSystemException {
830 set(attributeName, new BaseType(TypeID.INT64_STRING, TypeID.INT64_TOKEN, aNumber));
834 * Set the given attribute with a <tt>String</tt>
836 * @param attributeName the attribute to set
837 * @param aString the String value to set
838 * @throws NoSuchAttributeException if the attribute does not exist in the event
839 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
841 public void setString(String attributeName, String aString)
842 throws EventSystemException {
843 set(attributeName, new BaseType(TypeID.STRING_STRING, TypeID.STRING_TOKEN, aString));
847 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
849 * @param attributeName the attribute to set
850 * @param address the ip address in bytes
851 * @throws NoSuchAttributeException if the attribute does not exist in the event
852 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
854 public void setIPAddress(String attributeName, byte[] address)
855 throws EventSystemException {
856 setIPAddress(attributeName, new IPAddress(address));
860 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
862 * @param attributeName the attribute to set
863 * @param address the ip address in bytes
864 * @throws NoSuchAttributeException if the attribute does not exist in the event
865 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
867 public void setIPAddress(String attributeName, InetAddress address)
868 throws EventSystemException {
869 setIPAddress(attributeName, new IPAddress(address));
873 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
875 * @param attributeName the attribute to set
876 * @param address the ip address in bytes
877 * @throws NoSuchAttributeException if the attribute does not exist in the event
878 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
880 public void setIPAddress(String attributeName, IPAddress address)
881 throws EventSystemException {
882 set(attributeName, new BaseType(TypeID.IPADDR_STRING, TypeID.IPADDR_TOKEN, address));
886 * Serializes the Event into a byte array
888 * @return the serialized byte array
890 public byte[] serialize() {
892 * Serialization uses the following protocol
893 * EVENTWORD,<number of elements>,ATTRIBUTEWORD,TYPETOKEN,
894 * (UINT16|INT16|UINT32|INT32|UINT64|INT64|BOOLEAN|STRING)
895 * ...ATTRIBUTEWORD,TYPETOKEN(UINT16|INT16|UINT32|INT32|
896 * UINT64|INT64|BOOLEAN|STRING)
898 * The first attribute will always be the encoding if present.
900 byte[] bytes = new byte[this.bytesStoreSize];
901 int offset = 0;
902 int attributeCount = 0;
903 short encoding = DEFAULT_ENCODING;
905 if (attributes != null) {
906 attributeCount = attributes.size();
909 offset += Serializer.serializeEVENTWORD(name, bytes, offset);
910 offset += Serializer.serializeUINT16((short) (attributeCount), bytes, offset);
913 * Set the encoding attributes in the event
915 if (attributes != null) {
916 BaseType encodingBase = attributes.get(ENCODING);
917 if (encodingBase != null) {
918 Object encodingObj = encodingBase.getTypeObject();
919 byte encodingType = encodingBase.getTypeToken();
920 if (encodingObj != null) {
921 if (encodingType == TypeID.INT16_TOKEN) {
922 encoding = (Short) encodingObj;
923 Log.trace("Character encoding: " + encoding);
924 offset += Serializer.serializeATTRIBUTEWORD(ENCODING, bytes, offset);
925 offset += Serializer.serializeBYTE(encodingType, bytes, offset);
926 offset += Serializer.serializeUINT16(encoding, bytes, offset);
930 else {
931 Log.warning("Character encoding null in event " + name);
934 Enumeration<String> e = attributes.keys();
935 while (e.hasMoreElements()) {
936 String key = e.nextElement();
937 if (key.equals(ENCODING)) {
938 continue;
941 BaseType value = attributes.get(key);
942 Object data = value.getTypeObject();
943 byte typeToken = value.getTypeToken();
945 /* don't try to serialize nulls */
946 if (data == null) {
947 Log.warning("Attribute " + key + " was null in event " + name);
948 continue;
951 offset += Serializer.serializeATTRIBUTEWORD(key, bytes, offset);
952 offset += Serializer.serializeBYTE(typeToken, bytes, offset);
954 switch (typeToken) {
955 case TypeID.BOOLEAN_TOKEN:
956 offset += Serializer.serializeBOOLEAN((Boolean) data, bytes, offset);
957 break;
958 case TypeID.UINT16_TOKEN:
959 offset += Serializer.serializeUINT16((Integer) data, bytes, offset);
960 break;
961 case TypeID.INT16_TOKEN:
962 offset += Serializer.serializeINT16((Short) data, bytes, offset);
963 break;
964 case TypeID.UINT32_TOKEN:
965 offset += Serializer.serializeUINT32((Long) data, bytes, offset);
966 break;
967 case TypeID.INT32_TOKEN:
968 offset += Serializer.serializeINT32((Integer) data, bytes, offset);
969 break;
970 case TypeID.UINT64_TOKEN:
971 offset += Serializer.serializeUINT64((BigInteger) data, bytes, offset);
972 break;
973 case TypeID.INT64_TOKEN:
974 offset += Serializer.serializeINT64((Long) data, bytes, offset);
975 break;
976 case TypeID.STRING_TOKEN:
977 offset += Serializer.serializeSTRING(((String) data), bytes, offset, encoding);
978 break;
979 case TypeID.IPADDR_TOKEN:
980 offset += Serializer.serializeIPADDR(((IPAddress) data), bytes, offset);
981 break;
982 case TypeID.STRING_ARRAY_TOKEN:
983 offset += Serializer.serializeStringArray
984 (((String[]) data), bytes, offset, encoding);
985 break;
986 case TypeID.INT16_ARRAY_TOKEN:
987 offset += Serializer.serializeInt16Array((short[]) data, bytes, offset);
988 break;
989 case TypeID.INT32_ARRAY_TOKEN:
990 offset += Serializer.serializeInt32Array((int[]) data, bytes, offset);
991 break;
992 case TypeID.INT64_ARRAY_TOKEN:
993 offset += Serializer.serializeInt64Array((long[]) data, bytes, offset);
994 break;
995 case TypeID.UINT16_ARRAY_TOKEN:
996 offset += Serializer.serializeUInt16Array((int[]) data, bytes, offset);
997 break;
998 case TypeID.UINT32_ARRAY_TOKEN:
999 offset += Serializer.serializeUInt32Array((long[]) data, bytes, offset);
1000 break;
1001 case TypeID.UINT64_ARRAY_TOKEN:
1002 offset += Serializer.serializeUInt64Array((long[]) data, bytes, offset);
1003 break;
1004 case TypeID.BOOLEAN_ARRAY_TOKEN:
1005 offset += Serializer.serializeBooleanArray((boolean[]) data, bytes, offset);
1006 break;
1007 case TypeID.BYTE_ARRAY_TOKEN:
1008 offset += Serializer.serializeByteArray((byte[]) data, bytes, offset);
1009 break;
1010 default:
1011 Log.warning("Unknown BaseType token: " + typeToken);
1012 break;
1013 } // switch(typeToken)
1015 Log.trace("Serialized attribute " + key);
1016 } // while(e.hasMoreElements())
1017 } // if(attributes != null)
1019 return bytes;
1023 * Deserialize the Event from byte array
1025 * @param bytes the byte array containing a serialized Event
1027 public void deserialize(byte[] bytes)
1028 throws EventSystemException {
1029 if (bytes == null) {
1030 return;
1032 if (state == null) {
1033 state = new DeserializerState();
1036 state.reset();
1037 setEventName(Deserializer.deserializeEVENTWORD(state, bytes));
1038 long num = Deserializer.deserializeUINT16(state, bytes);
1039 if (Log.isLogTrace()) {
1040 Log.trace("Event name = " + getEventName());
1041 Log.trace("Number of attribute: " + num);
1043 for (int i = 0; i < num; ++i) {
1044 String attribute = Deserializer.deserializeATTRIBUTEWORD(state, bytes);
1046 byte type = Deserializer.deserializeBYTE(state, bytes);
1047 if (Log.isLogTrace()) {
1048 Log.trace("Attribute: " + attribute);
1049 Log.trace("Type: " + TypeID.byteIDToString(type));
1050 Log.trace("State: " + state);
1052 if (attribute != null) {
1053 if (i == 0 && attribute.equals(ENCODING)) {
1054 if (type == TypeID.INT16_TOKEN) {
1055 setEncoding(Deserializer.deserializeINT16(state, bytes));
1056 continue;
1058 else {
1059 Log.warning("Found encoding, but type was not int16 while deserializing");
1063 switch (type) {
1064 case TypeID.BOOLEAN_TOKEN:
1065 boolean aBool = Deserializer.deserializeBOOLEAN(state, bytes);
1066 setBoolean(attribute, aBool);
1067 break;
1068 case TypeID.UINT16_TOKEN:
1069 int uShort = Deserializer.deserializeUINT16(state, bytes);
1070 setUInt16(attribute, uShort);
1071 break;
1072 case TypeID.INT16_TOKEN:
1073 short aShort = Deserializer.deserializeINT16(state, bytes);
1074 setInt16(attribute, aShort);
1075 break;
1076 case TypeID.UINT32_TOKEN:
1077 long uInt = Deserializer.deserializeUINT32(state, bytes);
1078 setUInt32(attribute, uInt);
1079 break;
1080 case TypeID.INT32_TOKEN:
1081 int aInt = Deserializer.deserializeINT32(state, bytes);
1082 setInt32(attribute, aInt);
1083 break;
1084 case TypeID.UINT64_TOKEN:
1085 long uLong = Deserializer.deserializeUINT64(state, bytes);
1086 setUInt64(attribute, BigInteger.valueOf(uLong));
1087 break;
1088 case TypeID.INT64_TOKEN:
1089 long aLong = Deserializer.deserializeINT64(state, bytes);
1090 setInt64(attribute, aLong);
1091 break;
1092 case TypeID.STRING_TOKEN:
1093 String s = Deserializer.deserializeSTRING(state, bytes, encoding);
1094 setString(attribute, s);
1095 break;
1096 case TypeID.IPADDR_TOKEN:
1097 byte[] inetAddress = Deserializer.deserializeIPADDR(state, bytes);
1098 setIPAddress(attribute, inetAddress);
1099 break;
1100 case TypeID.STRING_ARRAY_TOKEN:
1101 String[] sArray = Deserializer.deserializeStringArray(state, bytes, encoding);
1102 setStringArray(attribute, sArray);
1103 break;
1104 case TypeID.INT16_ARRAY_TOKEN:
1105 short[] as = Deserializer.deserializeInt16Array(state, bytes);
1106 setInt16Array(attribute, as);
1107 break;
1108 case TypeID.INT32_ARRAY_TOKEN:
1109 int[] ai = Deserializer.deserializeInt32Array(state, bytes);
1110 setInt32Array(attribute, ai);
1111 break;
1112 case TypeID.INT64_ARRAY_TOKEN:
1113 long[] al = Deserializer.deserializeInt64Array(state, bytes);
1114 setInt64Array(attribute, al);
1115 break;
1116 case TypeID.UINT16_ARRAY_TOKEN:
1117 int[] uas = Deserializer.deserializeUInt16Array(state, bytes);
1118 setUInt16Array(attribute, uas);
1119 break;
1120 case TypeID.UINT32_ARRAY_TOKEN:
1121 long[] uai = Deserializer.deserializeUInt32Array(state, bytes);
1122 setUInt32Array(attribute, uai);
1123 break;
1124 case TypeID.UINT64_ARRAY_TOKEN:
1125 long[] ual = Deserializer.deserializeUInt64Array(state, bytes);
1126 setUInt64Array(attribute, ual);
1127 break;
1128 case TypeID.BOOLEAN_ARRAY_TOKEN:
1129 boolean[] ba = Deserializer.deserializeBooleanArray(state, bytes);
1130 setBooleanArray(attribute, ba);
1131 break;
1132 case TypeID.BYTE_ARRAY_TOKEN:
1133 byte[] bar = Deserializer.deserializeByteArray(state, bytes);
1134 setByteArray(attribute, bar);
1135 break;
1136 default:
1137 Log.warning("Unknown type " + type + " in deserialization");
1140 } // for (int i =0 ...
1145 * Returns a mutable copy of the event. This is a SLOW operation.
1147 * @return Event the Event object
1148 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
1149 * @throws NoSuchAttributeException if the attribute does not exist in this event
1150 * @throws NoSuchAttributeTypeException if there is an attribute that does not match a type in the EventTemplateDB
1152 public Event copy() throws EventSystemException {
1153 /* match the type-checking of the original event */
1154 Event evt = new Event(name, isValidating(), getEventTemplateDB());
1155 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
1156 String key = e.nextElement();
1157 BaseType value = attributes.get(key);
1158 evt.set(key, value);
1161 return evt;
1165 * Returns a String representation of this event
1167 * @return a String return of this event.
1169 public String toString() {
1170 if (name == null) {
1171 return "";
1174 StringBuffer sb = new StringBuffer();
1175 sb.append(name);
1176 sb.append("\n{\n");
1178 if (attributes != null) {
1179 int i = 0;
1180 String[] keys = new String[attributes.size()];
1181 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
1182 keys[i++] = e.nextElement();
1185 Arrays.sort(keys);
1187 for (i = 0; i < attributes.size(); ++i) {
1188 BaseType value = attributes.get(keys[i]);
1189 if (isValidating() && getEventTemplateDB() != null) {
1190 if (getEventTemplateDB().checkTypeForAttribute(name, keys[i], TypeID.UINT64_STRING)) {
1191 try {
1192 sb.append("\t")
1193 .append(keys[i])
1194 .append(" = ")
1195 .append(NumberCodec.toHexString(getUInt64(keys[i])))
1196 .append(";\n");
1198 catch (EventSystemException exc) {
1199 Log.warning("Event.toString : ", exc);
1202 else {
1203 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1206 else {
1207 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1209 } // for(i = 0; i < attributes.size() ...
1210 } // if(attributes != null)
1212 sb.append("}");
1213 return sb.toString();
1216 @Override
1217 public int hashCode() {
1218 return toString().hashCode();
1221 public boolean equals(Object o) {
1222 if (o == null) {
1223 return false;
1225 if (getClass().getName().equals(o.getClass().getName())) {
1226 return toString().equals(o.toString());
1228 else {
1229 return false;
1234 * This method can be used to validate an event after it has been created.
1236 * @throws EventSystemException
1238 public void validate() throws EventSystemException {
1239 EventTemplateDB templ = getEventTemplateDB();
1240 if (templ == null) {
1241 throw new EventSystemException("No template defined.");
1243 if (!templ.checkForEvent(name)) {
1244 throw new NoSuchEventException("Event " + name + " does not exist in event definition");
1246 for (String key : attributes.keySet()) {
1247 if (!templ.checkForAttribute(name, key)) {
1248 throw new NoSuchAttributeException("Attribute " + key + " does not exist for event " + name);
1250 Object value = get(key);
1251 BaseType expected = templ.getBaseTypeForObjectAttribute(name, key, value);
1252 BaseType bt = BaseType.baseTypeFromObject(value);
1255 * There are no unsigned values in java so they are kind of a special case
1256 * in that i can't guess which one the person meant. This small hack treats
1257 * similar types the same way.
1259 if ((expected.getTypeToken() == TypeID.UINT16_TOKEN &&
1260 bt.getTypeToken() == TypeID.INT32_TOKEN) ||
1261 (expected.getTypeToken() == TypeID.UINT32_TOKEN &&
1262 bt.getTypeToken() == TypeID.INT64_TOKEN) ||
1263 (expected.getTypeToken() == TypeID.UINT64_TOKEN &&
1264 bt.getTypeToken() == TypeID.INT64_TOKEN)) {
1265 bt = expected;
1267 if (!templ.checkTypeForAttribute(name, key, bt)) {
1268 throw new NoSuchAttributeTypeException("Wrong type '" + bt.getTypeName() +
1269 "' for " + name + "." + key);
1272 Map<String, BaseType> map = templ.getEvents().get(name);
1273 for (String key : map.keySet()) {
1274 BaseType bt = map.get(key);
1275 if (bt.isRequired()) {
1276 if (!attributes.containsKey(key)) {
1277 throw new AttributeRequiredException(key);