last hooks for getting default values set
[lwes-java.git] / src / main / java / org / lwes / Event.java
blob50ecd3763d57851f351a89a55b35d796d3ab275e
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);
108 setDefaultValues(eventTemplateDB);
112 * Creates an event by deserializing a raw byte array.
114 * @param bytes the raw bytes to convert
115 * @param eventTemplateDB the EventTemplateDB to use to validate the event
116 * @throws NoSuchEventException
117 * @throws NoSuchAttributeException
118 * @throws NoSuchAttributeTypeException
120 public Event(byte[] bytes, EventTemplateDB eventTemplateDB)
121 throws EventSystemException {
122 this(bytes, true, eventTemplateDB);
127 * Creates an event by deserializing a raw byte array.
129 * @param bytes the raw bytes to convert
130 * @param validate whether or not to validate the event
131 * @param eventTemplateDB the EventTemplateDB to use to validate the event
132 * @throws NoSuchEventException
133 * @throws NoSuchAttributeException
134 * @throws NoSuchAttributeTypeException
136 public Event(byte[] bytes, boolean validate, EventTemplateDB eventTemplateDB)
137 throws EventSystemException {
138 setEventTemplateDB(eventTemplateDB);
139 validating = validate;
140 deserialize(bytes);
141 setDefaultValues(eventTemplateDB);
144 protected void setDefaultValues(EventTemplateDB template) throws EventSystemException {
145 if (template == null) {
146 return;
148 Map<String, BaseType> m = template.getBaseTypesForEvent(getEventName());
149 for (String key : m.keySet()) {
150 BaseType b = m.get(key);
151 if (b.getDefaultValue() != null) {
152 if (Log.isLogDebug()) {
153 Log.debug("Setting default value: "+key+"="+b.getDefaultValue());
155 set(key, b.getDefaultValue());
161 * Returns an enumeration of all the event attribute names
163 * @return an enumeration of attribute strings
165 public Enumeration<String> getEventAttributeNames() {
166 if (attributes == null) {
167 return null;
170 return attributes.keys();
174 * Returns the number of attributes in the event
176 * @return number of attributes in the event
178 public int size() {
179 if (attributes == null) {
180 return 0;
182 return attributes.size();
186 * Returns true if the event validates against the EventTemplateDB before making changes
188 * @return the validating state
190 public boolean isValidating() {
191 return this.validating;
195 * Set to true if the event should validate against the EventTemplateDB before making changes
197 * @param validate the validating value
199 public void setValidating(boolean validate) {
200 this.validating = validate;
204 * Returns the EventTemplateDB for this event, used for validation of types and attributes.
206 * @return the EventTemplateDB
208 public EventTemplateDB getEventTemplateDB() {
209 return this.eventTemplateDB;
213 * Sets the EventTemplateDB for this event, used for validation of types and attributes.
215 * @param eventTemplateDB the EventTemplateDB to be used for validation
217 public void setEventTemplateDB(EventTemplateDB eventTemplateDB) {
218 this.eventTemplateDB = eventTemplateDB;
222 * Returns the name of the event
224 * @return the name of the event
226 public synchronized String getEventName() {
227 return this.name;
231 * Sets the name of the Event
233 * @param name the name of the event
234 * @throws NoSuchEventException if the event is validating and does not exist in the EventTemplateDB
236 public synchronized void setEventName(String name) throws NoSuchEventException {
237 if (isValidating() && getEventTemplateDB() != null) {
238 if (!getEventTemplateDB().checkForEvent(name)) {
239 throw new NoSuchEventException("Event " + name + " does not exist in event definition");
243 /* determine if we already have the name and are just resetting it */
244 if (this.name != null) {
245 bytesStoreSize -= (this.name.length() + 1 + 2);
248 bytesStoreSize += (name.length() + 1 + 2);
250 this.name = name;
254 * Get the character encoding for this event
256 * @return the encoding
258 public short getEncoding() {
259 return this.encoding;
263 * Set the character encoding for event strings
265 * @param encoding the character encoding
266 * @throws NoSuchAttributeTypeException if the type for the encoding attribute does not exist
267 * @throws NoSuchAttributeException if the encoding attribute does not exist
269 public void setEncoding(short encoding) throws EventSystemException {
270 this.encoding = encoding;
271 setInt16(ENCODING, this.encoding);
275 * Generic accessor, checks if an attribute exists and returns its value. The user must do their
276 * own type checking.
278 * @param attributeName name of the attribute to lookup
279 * @return the object poitned to by attributeName
280 * @throws NoSuchAttributeException if the attribute does not exist in this event
282 public Object get(String attributeName) throws NoSuchAttributeException {
283 if (attributes == null) {
284 return null;
287 if (attributes.containsKey(attributeName)) {
288 return attributes.get(attributeName).getTypeObject();
291 if (isValidating() && getEventTemplateDB() != null) {
292 if (getEventTemplateDB().checkForAttribute(name, attributeName)) {
293 return null;
295 else {
296 throw new NoSuchAttributeException("Attribute " + attributeName + " does not exist for event " + name);
300 return null;
303 public short[] getInt16Array(String attributeName)
304 throws NoSuchAttributeException {
305 Object o = get(attributeName);
306 if (o != null && o instanceof short[]) {
307 return (short[]) o;
309 else {
310 return null;
314 public int[] getInt32Array(String attributeName)
315 throws NoSuchAttributeException {
316 Object o = get(attributeName);
317 if (o != null && o instanceof int[]) {
318 return (int[]) o;
320 else {
321 return null;
325 public long[] getInt64Array(String attributeName)
326 throws NoSuchAttributeException {
327 Object o = get(attributeName);
328 if (o != null && o instanceof long[]) {
329 return (long[]) o;
331 else {
332 return null;
336 public int[] getUInt16Array(String attributeName)
337 throws NoSuchAttributeException {
338 Object o = get(attributeName);
339 if (o != null && o instanceof int[]) {
340 return (int[]) o;
342 else {
343 return null;
347 public long[] getUInt32Array(String attributeName)
348 throws NoSuchAttributeException {
349 Object o = get(attributeName);
350 if (o != null && o instanceof long[]) {
351 return (long[]) o;
353 else {
354 return null;
358 public long[] getUInt64Array(String attributeName)
359 throws NoSuchAttributeException {
360 Object o = get(attributeName);
361 if (o != null && o instanceof long[]) {
362 return (long[]) o;
364 else {
365 return null;
369 public String[] getStringArray(String attributeName)
370 throws NoSuchAttributeException {
371 Object o = get(attributeName);
372 if (o != null && o instanceof String[]) {
373 return (String[]) o;
375 else {
376 return null;
380 public boolean[] getBooleanArray(String attributeName) throws NoSuchAttributeException {
381 Object o = get(attributeName);
382 if (o != null && o instanceof boolean[]) {
383 return (boolean[]) o;
385 else {
386 return null;
390 public byte[] getByteArray(String attributeName) throws NoSuchAttributeException {
391 Object o = get(attributeName);
392 if (o != null && o instanceof byte[]) {
393 return (byte[]) o;
395 else {
396 return null;
401 * Method to check if an attribute is set in the event. This method does not throw
402 * NoSuchAttributeException because it shouldn't really care. If it's not there, it's
403 * not there.
405 * @param attributeName The attribute name to check for existance.
406 * @return true if there is a value, false if not.
408 public boolean isSet(String attributeName) {
409 try {
410 return (get(attributeName) != null);
412 catch (NoSuchAttributeException e) {
413 return false;
418 * Accessor that returns a boolean value for attribute <tt>attributeName</tt>
420 * @param attributeName the name of the attribute to fetch
421 * @return the boolean value
422 * @throws NoSuchAttributeException if the attribute does not exist in this event
424 public Boolean getBoolean(String attributeName) throws NoSuchAttributeException {
425 return (Boolean) get(attributeName);
429 * Accessor that returns an <tt>unsigned short</tt>, in the guise of an <tt>int</tt>, for attribute <tt>attributeName</tt>
431 * @param attributeName the name of the attribute to fetch
432 * @return the unsigned short as an int
433 * @throws NoSuchAttributeException if the attribute does not exist in this event
435 public Integer getUInt16(String attributeName) throws NoSuchAttributeException {
436 return (Integer) get(attributeName);
440 * Accessor that returns an <tt>short</tt>, for attribute <tt>attributeName</tt>
442 * @param attributeName the name of the attribute to fetch
443 * @return the short value
444 * @throws NoSuchAttributeException if the attribute does not exist in this event
446 public Short getInt16(String attributeName) throws NoSuchAttributeException {
447 return (Short) get(attributeName);
451 * Accessor that returns an <tt>unsigned int</tt>, in the guise of an <tt>long</tt>, for attribute <tt>attributeName</tt>
453 * @param attributeName the name of the attribute to fetch
454 * @return the unsigned int as a long
455 * @throws NoSuchAttributeException if the attribute does not exist in this event
457 public Long getUInt32(String attributeName) throws NoSuchAttributeException {
458 return (Long) get(attributeName);
462 * Accessor that returns an <tt>int</tt>, for attribute <tt>attributeName</tt>
464 * @param attributeName the name of the attribute to fetch
465 * @return the int value
466 * @throws NoSuchAttributeException if the attribute does not exist in this event
468 public Integer getInt32(String attributeName) throws NoSuchAttributeException {
469 return (Integer) get(attributeName);
473 * Accessor that returns an <tt>unsigned long</tt>, in the guise of an <tt>BigInteger</tt>, for attribute <tt>attributeName</tt>
475 * @param attributeName the name of the attribute to fetch
476 * @return the unsigned long as a BigInteger
477 * @throws NoSuchAttributeException if the attribute does not exist in this event
479 public BigInteger getUInt64(String attributeName) throws NoSuchAttributeException {
480 return (BigInteger) get(attributeName);
485 * Accessor that returns an <tt>long</tt>, for attribute <tt>attributeName</tt>
487 * @param attributeName the name of the attribute to fetch
488 * @return the long value
489 * @throws NoSuchAttributeException if the attribute does not exist in this event
491 public Long getInt64(String attributeName) throws NoSuchAttributeException {
492 return (Long) get(attributeName);
496 * Accessor that returns an <tt>String</tt>, for attribute <tt>attributeName</tt>
498 * @param attributeName the name of the attribute to fetch
499 * @return the String value
500 * @throws NoSuchAttributeException if the attribute does not exist in this event
502 public String getString(String attributeName) throws NoSuchAttributeException {
503 return (String) get(attributeName);
507 * Accessor that returns an <tt>InetAddress</tt>, for attribute <tt>attributeName</tt>
509 * @param attributeName the name of the attribute to fetch
510 * @return the InetAddress value
511 * @throws NoSuchAttributeException if the attribute does not exist in this event
513 public InetAddress getInetAddress(String attributeName) throws NoSuchAttributeException {
514 IPAddress a = (IPAddress) get(attributeName);
515 if (a != null) {
516 return a.toInetAddress();
518 else {
519 return null;
524 * Accessor that returns an IP address in bytes, for attribute <tt>attributeName</tt>
526 * @param attributeName the name of the attribute to fetch
527 * @return the IP address in bytes
528 * @throws NoSuchAttributeException if the attribute does not exist in this event
530 public byte[] getIPAddress(String attributeName) throws NoSuchAttributeException {
531 return ((IPAddress) get(attributeName)).getInetAddressAsBytes();
535 * Accessor that returns the ip addres as an IPAddress object.
537 * @param attributeName name of the attribute to fetch
538 * @return IPAddress
539 * @throws NoSuchAttributeException
541 public IPAddress getIPAddressObj(String attributeName) throws NoSuchAttributeException {
542 return (IPAddress) get(attributeName);
546 * Set the object's attribute <tt>attributeName</tt> with the Object given
548 * @param attributeName the name of the attribute to set
549 * @param attributeValue the object to set the attribute with
550 * @throws NoSuchAttributeException if the attribute does not exist in this event
551 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
553 public void set(String attributeName, Object attributeValue)
554 throws EventSystemException {
555 if (isValidating() && getEventTemplateDB() != null) {
556 if (getEventTemplateDB().checkForAttribute(getEventName(), attributeName)) {
557 BaseType bt = getEventTemplateDB().getBaseTypeForObjectAttribute(getEventName(),
558 attributeName, attributeValue);
559 set(attributeName, bt);
562 else {
563 throw new NoSuchAttributeException("Must be able to check the EventTemplateDB to use set(String,Object)");
568 * Private method to set a BaseType
570 * @param attribute the name of the attribute to set
571 * @param anObject the BaseType to set in the event
572 * @throws NoSuchAttributeException if the attribute does not exist in this event
573 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
575 private void set(String attribute, BaseType anObject)
576 throws EventSystemException {
578 if (isValidating() && getEventTemplateDB() != null) {
579 if (getEventTemplateDB().checkForAttribute(name, attribute)) {
580 if (!getEventTemplateDB().checkTypeForAttribute(name, attribute, anObject)) {
581 throw new NoSuchAttributeTypeException("Wrong type '" + anObject.getTypeName() +
582 "' for " + name + "." + attribute);
585 else {
586 throw new NoSuchAttributeException("Attribute " + attribute + " does not exist for event " + name);
588 getEventTemplateDB().checkForSize(name, attribute, anObject);
591 if (anObject.getTypeObject() != null) {
592 BaseType oldObject = null;
593 int newSize = bytesStoreSize + ((attribute.length() + 1) + anObject.bytesStoreSize(encoding));
594 if (newSize > MAX_MESSAGE_SIZE) {
595 throw new EventSystemException("Event size limit is " + MAX_MESSAGE_SIZE + " bytes.");
597 if ((oldObject = attributes.remove(attribute)) != null) {
598 bytesStoreSize -= (attribute.length() + 1) + oldObject.bytesStoreSize(encoding);
601 bytesStoreSize += (attribute.length() + 1) + anObject.bytesStoreSize(encoding);
602 attributes.put(attribute, anObject);
606 public void setInt16Array(String attributeName, short[] value) throws EventSystemException {
607 set(attributeName, new BaseType(TypeID.INT16_ARRAY_STRING,
608 TypeID.INT16_ARRAY_TOKEN,
609 value));
612 public void setInt32Array(String attributeName, int[] value) throws EventSystemException {
613 set(attributeName, new BaseType(TypeID.INT32_ARRAY_STRING,
614 TypeID.INT32_ARRAY_TOKEN,
615 value));
618 public void setInt64Array(String attributeName, long[] value) throws EventSystemException {
619 set(attributeName, new BaseType(TypeID.INT64_ARRAY_STRING,
620 TypeID.INT64_ARRAY_TOKEN,
621 value));
624 public void setUInt16Array(String attributeName, int[] value) throws EventSystemException {
625 set(attributeName, new BaseType(TypeID.UINT16_ARRAY_STRING,
626 TypeID.UINT16_ARRAY_TOKEN,
627 value));
630 public void setUInt32Array(String attributeName, long[] value) throws EventSystemException {
631 set(attributeName, new BaseType(TypeID.UINT32_ARRAY_STRING,
632 TypeID.UINT32_ARRAY_TOKEN,
633 value));
636 public void setUInt64Array(String attributeName, long[] value) throws EventSystemException {
637 set(attributeName, new BaseType(TypeID.UINT64_ARRAY_STRING,
638 TypeID.UINT64_ARRAY_TOKEN,
639 value));
642 public void setStringArray(String attributeName, String[] value)
643 throws EventSystemException {
644 set(attributeName, new BaseType(TypeID.STRING_ARRAY_STRING,
645 TypeID.STRING_ARRAY_TOKEN,
646 value));
649 public void setBooleanArray(String attributeName, boolean[] value)
650 throws EventSystemException {
651 set(attributeName, new BaseType(TypeID.BOOLEAN_ARRAY_STRING,
652 TypeID.BOOLEAN_ARRAY_TOKEN,
653 value));
656 public void setByteArray(String attributeName, byte[] value)
657 throws EventSystemException {
658 set(attributeName, new BaseType(TypeID.BYTE_ARRAY_STRING,
659 TypeID.BYTE_ARRAY_TOKEN,
660 value));
664 * Sets the given attribute with a <tt>boolean</tt> value given by <tt>aBool</tt>.
666 * @param attributeName the attribute to set
667 * @param aBool the boolean value to set
668 * @throws NoSuchAttributeException if the attribute does not exist in the event
669 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
671 public void setBoolean(String attributeName, boolean aBool)
672 throws EventSystemException {
673 setBoolean(attributeName, Boolean.valueOf(aBool));
677 * Sets the given attribute with a <tt>Boolean</tt> value given by <tt>aBool</tt>.
679 * @param attributeName the attribute to set
680 * @param aBool the boolean value to set
681 * @throws NoSuchAttributeException
682 * @throws NoSuchAttributeTypeException
684 public void setBoolean(String attributeName, Boolean aBool)
685 throws EventSystemException {
686 set(attributeName, new BaseType(TypeID.BOOLEAN_STRING, TypeID.BOOLEAN_TOKEN, aBool));
690 * Set the given attribute with the <tt>unsigned short</tt> value given by <tt>aNumber</tt>.
691 * Because Java does not support unsigned types, we must use a signed int to cover the range of unsigned short.
693 * @param attributeName the attribute to set
694 * @param aNumber the unsigned short value as an integer
695 * @throws NoSuchAttributeException if the attribute does not exist in the event
696 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
698 public void setUInt16(String attributeName, int aNumber)
699 throws EventSystemException {
700 setUInt16(attributeName, Integer.valueOf(aNumber));
704 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
705 * This should be an <tt>unsigned short</tt>, but is an Integer because Java does not support unsigned types,
706 * and a signed integer is needed to cover the range of an unsigned short.
708 * @param attributeName the attribute to set
709 * @param aNumber the value
711 public void setUInt16(String attributeName, Integer aNumber)
712 throws EventSystemException {
713 set(attributeName, new BaseType(TypeID.UINT16_STRING, TypeID.UINT16_TOKEN, aNumber));
717 * Set the given attribute with the <tt>short</tt> value given by <tt>aNumber</tt>.
719 * @param attributeName the attribute to set
720 * @param aNumber the short value to set
721 * @throws NoSuchAttributeException if the attribute does not exist in the event
722 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
724 public void setInt16(String attributeName, short aNumber)
725 throws EventSystemException {
726 setInt16(attributeName, Short.valueOf(aNumber));
730 * Set the given attribute with the <tt>Short</tt> value given by <tt>aNumber</tt>.
732 * @param attributeName the attribute to set
733 * @param aNumber the short value to set
734 * @throws NoSuchAttributeException if the attribute does not exist in the event
735 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
737 public void setInt16(String attributeName, Short aNumber)
738 throws EventSystemException {
739 set(attributeName, new BaseType(TypeID.INT16_STRING, TypeID.INT16_TOKEN, aNumber));
743 * Set the given attribute with the <tt>unsigned int</tt> value given by <tt>aNumber</tt>.
744 * Because Java does not support unsigned types, we must use a signed long to cover the range of an unsigned int.
746 * @param attributeName the attribute to set
747 * @param aNumber the unsigned int value as a long
748 * @throws NoSuchAttributeException if the attribute does not exist in the event
749 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
751 public void setUInt32(String attributeName, long aNumber)
752 throws EventSystemException {
753 setUInt32(attributeName, Long.valueOf(aNumber));
757 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
758 * This should be an <tt>unsigned int</tt>, but is an Long because Java does not support unsigned types,
759 * and a signed long is needed to cover the range of an unsigned int.
761 * @param attributeName the attribute to set
762 * @param aNumber the value
764 public void setUInt32(String attributeName, Long aNumber)
765 throws EventSystemException {
766 set(attributeName, new BaseType(TypeID.UINT32_STRING, TypeID.UINT32_TOKEN, aNumber));
770 * Set the given attribute with the <tt>int</tt> value given by <tt>aNumber</tt>.
772 * @param attributeName the attribute to set
773 * @param aNumber the integer value to set
774 * @throws NoSuchAttributeException if the attribute does not exist in the event
775 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
777 public void setInt32(String attributeName, int aNumber)
778 throws EventSystemException {
779 setInt32(attributeName, Integer.valueOf(aNumber));
783 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
785 * @param attributeName the attribute to set
786 * @param aNumber the Integer value to set
787 * @throws NoSuchAttributeException if the attribute does not exist in the event
788 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
790 public void setInt32(String attributeName, Integer aNumber)
791 throws EventSystemException {
792 set(attributeName, new BaseType(TypeID.INT32_STRING, TypeID.INT32_TOKEN, aNumber));
796 * Set the given attribute with the <tt>unsigned long</tt> value given by <tt>aNumber</tt>.
798 * @param attributeName the attribute to set
799 * @param aNumber the value
800 * @throws NoSuchAttributeException if the attribute does not exist in the event
801 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
803 public void setUInt64(String attributeName, long aNumber)
804 throws EventSystemException {
805 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber)));
809 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
811 * @param attributeName the attribute to set
812 * @param aNumber the value
813 * @throws NoSuchAttributeException if the attribute does not exist in the event
814 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
816 public void setUInt64(String attributeName, Long aNumber)
817 throws EventSystemException {
818 set(attributeName,
819 new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber.longValue())));
823 * Set the given attribute with the <tt>BigInteger</tt> value given by <tt>aNumber</tt>.
824 * This should be an <tt>unsigned long</tt>, but is an BigInteger because Java does not support unsigned types,
825 * and a BigInteger is needed to cover the range of an unsigned long.
827 * @param attributeName the attribute to set
828 * @param aNumber the value
830 public void setUInt64(String attributeName, BigInteger aNumber)
831 throws EventSystemException {
832 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, aNumber));
836 * Set the given attribute with the <tt>long</tt> value given by <tt>aNumber</tt>.
838 * @param attributeName the attribute to set
839 * @param aNumber the long value to set
840 * @throws NoSuchAttributeException if the attribute does not exist in the event
841 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
843 public void setInt64(String attributeName, long aNumber)
844 throws EventSystemException {
845 setInt64(attributeName, Long.valueOf(aNumber));
849 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
851 * @param attributeName the attribute to set
852 * @param aNumber the Long value to set
853 * @throws NoSuchAttributeException if the attribute does not exist in the event
854 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
856 public void setInt64(String attributeName, Long aNumber)
857 throws EventSystemException {
858 set(attributeName, new BaseType(TypeID.INT64_STRING, TypeID.INT64_TOKEN, aNumber));
862 * Set the given attribute with a <tt>String</tt>
864 * @param attributeName the attribute to set
865 * @param aString the String value to set
866 * @throws NoSuchAttributeException if the attribute does not exist in the event
867 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
869 public void setString(String attributeName, String aString)
870 throws EventSystemException {
871 set(attributeName, new BaseType(TypeID.STRING_STRING, TypeID.STRING_TOKEN, aString));
875 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
877 * @param attributeName the attribute to set
878 * @param address the ip address in bytes
879 * @throws NoSuchAttributeException if the attribute does not exist in the event
880 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
882 public void setIPAddress(String attributeName, byte[] address)
883 throws EventSystemException {
884 setIPAddress(attributeName, new IPAddress(address));
888 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
890 * @param attributeName the attribute to set
891 * @param address the ip address in bytes
892 * @throws NoSuchAttributeException if the attribute does not exist in the event
893 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
895 public void setIPAddress(String attributeName, InetAddress address)
896 throws EventSystemException {
897 setIPAddress(attributeName, new IPAddress(address));
901 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
903 * @param attributeName the attribute to set
904 * @param address the ip address in bytes
905 * @throws NoSuchAttributeException if the attribute does not exist in the event
906 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
908 public void setIPAddress(String attributeName, IPAddress address)
909 throws EventSystemException {
910 set(attributeName, new BaseType(TypeID.IPADDR_STRING, TypeID.IPADDR_TOKEN, address));
914 * Serializes the Event into a byte array
916 * @return the serialized byte array
918 public byte[] serialize() {
920 * Serialization uses the following protocol
921 * EVENTWORD,<number of elements>,ATTRIBUTEWORD,TYPETOKEN,
922 * (UINT16|INT16|UINT32|INT32|UINT64|INT64|BOOLEAN|STRING)
923 * ...ATTRIBUTEWORD,TYPETOKEN(UINT16|INT16|UINT32|INT32|
924 * UINT64|INT64|BOOLEAN|STRING)
926 * The first attribute will always be the encoding if present.
928 byte[] bytes = new byte[this.bytesStoreSize];
929 int offset = 0;
930 int attributeCount = 0;
931 short encoding = DEFAULT_ENCODING;
933 if (attributes != null) {
934 attributeCount = attributes.size();
937 offset += Serializer.serializeEVENTWORD(name, bytes, offset);
938 offset += Serializer.serializeUINT16((short) (attributeCount), bytes, offset);
941 * Set the encoding attributes in the event
943 if (attributes != null) {
944 BaseType encodingBase = attributes.get(ENCODING);
945 if (encodingBase != null) {
946 Object encodingObj = encodingBase.getTypeObject();
947 byte encodingType = encodingBase.getTypeToken();
948 if (encodingObj != null) {
949 if (encodingType == TypeID.INT16_TOKEN) {
950 encoding = (Short) encodingObj;
951 Log.trace("Character encoding: " + encoding);
952 offset += Serializer.serializeATTRIBUTEWORD(ENCODING, bytes, offset);
953 offset += Serializer.serializeBYTE(encodingType, bytes, offset);
954 offset += Serializer.serializeUINT16(encoding, bytes, offset);
958 else {
959 Log.warning("Character encoding null in event " + name);
962 Enumeration<String> e = attributes.keys();
963 while (e.hasMoreElements()) {
964 String key = e.nextElement();
965 if (key.equals(ENCODING)) {
966 continue;
969 BaseType value = attributes.get(key);
970 Object data = value.getTypeObject();
971 byte typeToken = value.getTypeToken();
973 /* don't try to serialize nulls */
974 if (data == null) {
975 Log.warning("Attribute " + key + " was null in event " + name);
976 continue;
979 offset += Serializer.serializeATTRIBUTEWORD(key, bytes, offset);
980 offset += Serializer.serializeBYTE(typeToken, bytes, offset);
982 switch (typeToken) {
983 case TypeID.BOOLEAN_TOKEN:
984 offset += Serializer.serializeBOOLEAN((Boolean) data, bytes, offset);
985 break;
986 case TypeID.UINT16_TOKEN:
987 offset += Serializer.serializeUINT16((Integer) data, bytes, offset);
988 break;
989 case TypeID.INT16_TOKEN:
990 offset += Serializer.serializeINT16((Short) data, bytes, offset);
991 break;
992 case TypeID.UINT32_TOKEN:
993 offset += Serializer.serializeUINT32((Long) data, bytes, offset);
994 break;
995 case TypeID.INT32_TOKEN:
996 offset += Serializer.serializeINT32((Integer) data, bytes, offset);
997 break;
998 case TypeID.UINT64_TOKEN:
999 offset += Serializer.serializeUINT64((BigInteger) data, bytes, offset);
1000 break;
1001 case TypeID.INT64_TOKEN:
1002 offset += Serializer.serializeINT64((Long) data, bytes, offset);
1003 break;
1004 case TypeID.STRING_TOKEN:
1005 offset += Serializer.serializeSTRING(((String) data), bytes, offset, encoding);
1006 break;
1007 case TypeID.IPADDR_TOKEN:
1008 offset += Serializer.serializeIPADDR(((IPAddress) data), bytes, offset);
1009 break;
1010 case TypeID.STRING_ARRAY_TOKEN:
1011 offset += Serializer.serializeStringArray
1012 (((String[]) data), bytes, offset, encoding);
1013 break;
1014 case TypeID.INT16_ARRAY_TOKEN:
1015 offset += Serializer.serializeInt16Array((short[]) data, bytes, offset);
1016 break;
1017 case TypeID.INT32_ARRAY_TOKEN:
1018 offset += Serializer.serializeInt32Array((int[]) data, bytes, offset);
1019 break;
1020 case TypeID.INT64_ARRAY_TOKEN:
1021 offset += Serializer.serializeInt64Array((long[]) data, bytes, offset);
1022 break;
1023 case TypeID.UINT16_ARRAY_TOKEN:
1024 offset += Serializer.serializeUInt16Array((int[]) data, bytes, offset);
1025 break;
1026 case TypeID.UINT32_ARRAY_TOKEN:
1027 offset += Serializer.serializeUInt32Array((long[]) data, bytes, offset);
1028 break;
1029 case TypeID.UINT64_ARRAY_TOKEN:
1030 offset += Serializer.serializeUInt64Array((long[]) data, bytes, offset);
1031 break;
1032 case TypeID.BOOLEAN_ARRAY_TOKEN:
1033 offset += Serializer.serializeBooleanArray((boolean[]) data, bytes, offset);
1034 break;
1035 case TypeID.BYTE_ARRAY_TOKEN:
1036 offset += Serializer.serializeByteArray((byte[]) data, bytes, offset);
1037 break;
1038 default:
1039 Log.warning("Unknown BaseType token: " + typeToken);
1040 break;
1041 } // switch(typeToken)
1043 Log.trace("Serialized attribute " + key);
1044 } // while(e.hasMoreElements())
1045 } // if(attributes != null)
1047 return bytes;
1051 * Deserialize the Event from byte array
1053 * @param bytes the byte array containing a serialized Event
1055 public void deserialize(byte[] bytes)
1056 throws EventSystemException {
1057 if (bytes == null) {
1058 return;
1060 if (state == null) {
1061 state = new DeserializerState();
1064 state.reset();
1065 setEventName(Deserializer.deserializeEVENTWORD(state, bytes));
1066 long num = Deserializer.deserializeUINT16(state, bytes);
1067 if (Log.isLogTrace()) {
1068 Log.trace("Event name = " + getEventName());
1069 Log.trace("Number of attribute: " + num);
1071 for (int i = 0; i < num; ++i) {
1072 String attribute = Deserializer.deserializeATTRIBUTEWORD(state, bytes);
1074 byte type = Deserializer.deserializeBYTE(state, bytes);
1075 if (Log.isLogTrace()) {
1076 Log.trace("Attribute: " + attribute);
1077 Log.trace("Type: " + TypeID.byteIDToString(type));
1078 Log.trace("State: " + state);
1080 if (attribute != null) {
1081 if (i == 0 && attribute.equals(ENCODING)) {
1082 if (type == TypeID.INT16_TOKEN) {
1083 setEncoding(Deserializer.deserializeINT16(state, bytes));
1084 continue;
1086 else {
1087 Log.warning("Found encoding, but type was not int16 while deserializing");
1091 switch (type) {
1092 case TypeID.BOOLEAN_TOKEN:
1093 boolean aBool = Deserializer.deserializeBOOLEAN(state, bytes);
1094 setBoolean(attribute, aBool);
1095 break;
1096 case TypeID.UINT16_TOKEN:
1097 int uShort = Deserializer.deserializeUINT16(state, bytes);
1098 setUInt16(attribute, uShort);
1099 break;
1100 case TypeID.INT16_TOKEN:
1101 short aShort = Deserializer.deserializeINT16(state, bytes);
1102 setInt16(attribute, aShort);
1103 break;
1104 case TypeID.UINT32_TOKEN:
1105 long uInt = Deserializer.deserializeUINT32(state, bytes);
1106 setUInt32(attribute, uInt);
1107 break;
1108 case TypeID.INT32_TOKEN:
1109 int aInt = Deserializer.deserializeINT32(state, bytes);
1110 setInt32(attribute, aInt);
1111 break;
1112 case TypeID.UINT64_TOKEN:
1113 long uLong = Deserializer.deserializeUINT64(state, bytes);
1114 setUInt64(attribute, BigInteger.valueOf(uLong));
1115 break;
1116 case TypeID.INT64_TOKEN:
1117 long aLong = Deserializer.deserializeINT64(state, bytes);
1118 setInt64(attribute, aLong);
1119 break;
1120 case TypeID.STRING_TOKEN:
1121 String s = Deserializer.deserializeSTRING(state, bytes, encoding);
1122 setString(attribute, s);
1123 break;
1124 case TypeID.IPADDR_TOKEN:
1125 byte[] inetAddress = Deserializer.deserializeIPADDR(state, bytes);
1126 setIPAddress(attribute, inetAddress);
1127 break;
1128 case TypeID.STRING_ARRAY_TOKEN:
1129 String[] sArray = Deserializer.deserializeStringArray(state, bytes, encoding);
1130 setStringArray(attribute, sArray);
1131 break;
1132 case TypeID.INT16_ARRAY_TOKEN:
1133 short[] as = Deserializer.deserializeInt16Array(state, bytes);
1134 setInt16Array(attribute, as);
1135 break;
1136 case TypeID.INT32_ARRAY_TOKEN:
1137 int[] ai = Deserializer.deserializeInt32Array(state, bytes);
1138 setInt32Array(attribute, ai);
1139 break;
1140 case TypeID.INT64_ARRAY_TOKEN:
1141 long[] al = Deserializer.deserializeInt64Array(state, bytes);
1142 setInt64Array(attribute, al);
1143 break;
1144 case TypeID.UINT16_ARRAY_TOKEN:
1145 int[] uas = Deserializer.deserializeUInt16Array(state, bytes);
1146 setUInt16Array(attribute, uas);
1147 break;
1148 case TypeID.UINT32_ARRAY_TOKEN:
1149 long[] uai = Deserializer.deserializeUInt32Array(state, bytes);
1150 setUInt32Array(attribute, uai);
1151 break;
1152 case TypeID.UINT64_ARRAY_TOKEN:
1153 long[] ual = Deserializer.deserializeUInt64Array(state, bytes);
1154 setUInt64Array(attribute, ual);
1155 break;
1156 case TypeID.BOOLEAN_ARRAY_TOKEN:
1157 boolean[] ba = Deserializer.deserializeBooleanArray(state, bytes);
1158 setBooleanArray(attribute, ba);
1159 break;
1160 case TypeID.BYTE_ARRAY_TOKEN:
1161 byte[] bar = Deserializer.deserializeByteArray(state, bytes);
1162 setByteArray(attribute, bar);
1163 break;
1164 default:
1165 Log.warning("Unknown type " + type + " in deserialization");
1168 } // for (int i =0 ...
1173 * Returns a mutable copy of the event. This is a SLOW operation.
1175 * @return Event the Event object
1176 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
1177 * @throws NoSuchAttributeException if the attribute does not exist in this event
1178 * @throws NoSuchAttributeTypeException if there is an attribute that does not match a type in the EventTemplateDB
1180 public Event copy() throws EventSystemException {
1181 /* match the type-checking of the original event */
1182 Event evt = new Event(name, isValidating(), getEventTemplateDB());
1183 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
1184 String key = e.nextElement();
1185 BaseType value = attributes.get(key);
1186 evt.set(key, value);
1189 return evt;
1193 * Returns a String representation of this event
1195 * @return a String return of this event.
1197 public String toString() {
1198 if (name == null) {
1199 return "";
1202 StringBuffer sb = new StringBuffer();
1203 sb.append(name);
1204 sb.append("\n{\n");
1206 if (attributes != null) {
1207 int i = 0;
1208 String[] keys = new String[attributes.size()];
1209 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
1210 keys[i++] = e.nextElement();
1213 Arrays.sort(keys);
1215 for (i = 0; i < attributes.size(); ++i) {
1216 BaseType value = attributes.get(keys[i]);
1217 if (isValidating() && getEventTemplateDB() != null) {
1218 if (getEventTemplateDB().checkTypeForAttribute(name, keys[i], TypeID.UINT64_STRING)) {
1219 try {
1220 sb.append("\t")
1221 .append(keys[i])
1222 .append(" = ")
1223 .append(NumberCodec.toHexString(getUInt64(keys[i])))
1224 .append(";\n");
1226 catch (EventSystemException exc) {
1227 Log.warning("Event.toString : ", exc);
1230 else {
1231 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1234 else {
1235 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1237 } // for(i = 0; i < attributes.size() ...
1238 } // if(attributes != null)
1240 sb.append("}");
1241 return sb.toString();
1244 @Override
1245 public int hashCode() {
1246 return toString().hashCode();
1249 public boolean equals(Object o) {
1250 if (o == null) {
1251 return false;
1253 if (getClass().getName().equals(o.getClass().getName())) {
1254 return toString().equals(o.toString());
1256 else {
1257 return false;
1262 * This method can be used to validate an event after it has been created.
1264 * @throws ValidationExceptions A list of validation errors
1266 public void validate() throws ValidationExceptions {
1267 ValidationExceptions ve = new ValidationExceptions(name);
1269 EventTemplateDB templ = getEventTemplateDB();
1270 if (templ == null) {
1271 ve.addException(new EventSystemException("No template defined."));
1272 throw ve;
1274 if (!templ.checkForEvent(name)) {
1275 ve.addException(new NoSuchEventException("Event " + name + " does not exist in event definition"));
1276 throw ve;
1278 for (String key : attributes.keySet()) {
1279 if (!templ.checkForAttribute(name, key)) {
1280 ve.addException(new NoSuchAttributeException("Attribute " + key + " does not exist for event " + name));
1281 continue;
1283 Object value;
1284 try {
1285 value = get(key);
1287 catch (NoSuchAttributeException e) {
1288 ve.addException(e);
1289 continue;
1292 BaseType expected = templ.getBaseTypeForObjectAttribute(name, key, value);
1293 BaseType bt = BaseType.baseTypeFromObject(value);
1296 * There are no unsigned values in java so they are kind of a special case
1297 * in that i can't guess which one the person meant. This small hack treats
1298 * similar types the same way.
1300 if ((expected.getTypeToken() == TypeID.UINT16_TOKEN &&
1301 bt.getTypeToken() == TypeID.INT32_TOKEN) ||
1302 (expected.getTypeToken() == TypeID.UINT32_TOKEN &&
1303 bt.getTypeToken() == TypeID.INT64_TOKEN) ||
1304 (expected.getTypeToken() == TypeID.UINT64_TOKEN &&
1305 bt.getTypeToken() == TypeID.INT64_TOKEN)) {
1306 bt = expected;
1308 if (!templ.checkTypeForAttribute(name, key, bt)) {
1309 ve.addException(new NoSuchAttributeTypeException("Wrong type '" + bt.getTypeName() +
1310 "' for " + name + "." + key));
1313 Map<String, BaseType> map = templ.getEvents().get(name);
1314 for (String key : map.keySet()) {
1315 BaseType bt = map.get(key);
1316 if (bt.isRequired()) {
1317 if (!attributes.containsKey(key)) {
1318 ve.addException(new AttributeRequiredException(key));
1323 if (ve.hasExceptions()) {
1324 throw ve;