changes for arrays
[lwes-java.git] / src / main / java / org / lwes / Event.java
blob182c4237121df0b692cca958ed8598c5b744025a
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.concurrent.ConcurrentHashMap;
18 public class Event {
20 public static final int MAX_MESSAGE_SIZE = 65507;
22 /**
23 * Reserved metadata keywords
25 public static final String ENCODING = "enc";
26 public static final String RECEIPT_TIME = "ReceiptTime";
27 public static final String SENDER_IP = "SenderIP";
28 public static final String SENDER_PORT = "SenderPort";
30 /**
31 * Encoding variables
33 public static final short ISO_8859_1 = 0;
34 public static final short UTF_8 = 1;
35 public static final short DEFAULT_ENCODING = UTF_8;
36 public static final CharacterEncoding[] ENCODING_STRINGS = {
37 CharacterEncoding.ISO_8859_1, CharacterEncoding.UTF_8};
39 /**
40 * Event data
42 private ConcurrentHashMap<String, BaseType> attributes = new ConcurrentHashMap<String, BaseType>();
43 private String name = null;
44 private EventTemplateDB eventTemplateDB = null;
45 private short encoding = DEFAULT_ENCODING;
47 /**
48 * If this is set to true, types and attributes are validated against the EventTemplateDB
50 private boolean validating = true;
52 /**
53 * Internal object for deserialization state
55 private DeserializerState state = null;
57 /**
58 * the size of the event in bytes
60 private int bytesStoreSize = 0;
62 /**
63 * Create an event called <tt>eventName</tt>
65 * @param eventName the name of the event
66 * @param eventTemplateDB the EventTemplateDB to use for validation
67 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
68 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
69 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
71 public Event(String eventName, EventTemplateDB eventTemplateDB)
72 throws EventSystemException {
73 this(eventName, true, eventTemplateDB);
76 /**
77 * Create an event called <tt>eventName</tt>
79 * @param eventName the name of the event
80 * @param validate true if the EventTemplateDB should be checked for types before all mutations
81 * @param eventTemplateDB the EventTemplateDB to use for validation
82 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
83 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
84 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
86 public Event(String eventName, boolean validate, EventTemplateDB eventTemplateDB)
87 throws EventSystemException {
88 this(eventName, validate, eventTemplateDB, DEFAULT_ENCODING);
91 /**
92 * Create an event called <tt>eventName</tt>
94 * @param eventName the name of the event
95 * @param validate true if the EventTemplateDB should be checked for types before all mutations
96 * @param encoding the character encoding used by the event
97 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
98 * @throws NoSuchAttributeException if an attribute does not exist in the EventTemplateDB
99 * @throws NoSuchAttributeTypeException if an attribute type does not exist in the EventTemplateDB
101 public Event(String eventName, boolean validate, EventTemplateDB eventTemplateDB, short encoding)
102 throws EventSystemException {
103 setEventTemplateDB(eventTemplateDB);
104 validating = validate;
105 setEventName(eventName);
106 setEncoding(encoding);
110 * Creates an event by deserializing a raw byte array.
112 * @param bytes the raw bytes to convert
113 * @param eventTemplateDB the EventTemplateDB to use to validate the event
114 * @throws NoSuchEventException
115 * @throws NoSuchAttributeException
116 * @throws NoSuchAttributeTypeException
118 public Event(byte[] bytes, EventTemplateDB eventTemplateDB)
119 throws EventSystemException {
120 this(bytes, true, eventTemplateDB);
125 * Creates an event by deserializing a raw byte array.
127 * @param bytes the raw bytes to convert
128 * @param validate whether or not to validate the event
129 * @param eventTemplateDB the EventTemplateDB to use to validate the event
130 * @throws NoSuchEventException
131 * @throws NoSuchAttributeException
132 * @throws NoSuchAttributeTypeException
134 public Event(byte[] bytes, boolean validate, EventTemplateDB eventTemplateDB)
135 throws EventSystemException {
136 setEventTemplateDB(eventTemplateDB);
137 validating = validate;
138 deserialize(bytes);
142 * Returns an enumeration of all the event attribute names
144 * @return an enumeration of attribute strings
146 public Enumeration<String> getEventAttributeNames() {
147 if (attributes == null) {
148 return null;
151 return attributes.keys();
155 * Returns the number of attributes in the event
157 * @return number of attributes in the event
159 public int size() {
160 if (attributes == null) {
161 return 0;
163 return attributes.size();
167 * Returns true if the event validates against the EventTemplateDB before making changes
169 * @return the validating state
171 public boolean isValidating() {
172 return this.validating;
176 * Set to true if the event should validate against the EventTemplateDB before making changes
178 * @param validate the validating value
180 public void setValidating(boolean validate) {
181 this.validating = validate;
185 * Returns the EventTemplateDB for this event, used for validation of types and attributes.
187 * @return the EventTemplateDB
189 public EventTemplateDB getEventTemplateDB() {
190 return this.eventTemplateDB;
194 * Sets the EventTemplateDB for this event, used for validation of types and attributes.
196 * @param eventTemplateDB the EventTemplateDB to be used for validation
198 public void setEventTemplateDB(EventTemplateDB eventTemplateDB) {
199 this.eventTemplateDB = eventTemplateDB;
203 * Returns the name of the event
205 * @return the name of the event
207 public synchronized String getEventName() {
208 return this.name;
212 * Sets the name of the Event
214 * @param name the name of the event
215 * @throws NoSuchEventException if the event is validating and does not exist in the EventTemplateDB
217 public synchronized void setEventName(String name) throws NoSuchEventException {
218 if (isValidating() && getEventTemplateDB() != null) {
219 if (!getEventTemplateDB().checkForEvent(name)) {
220 throw new NoSuchEventException("Event " + name + " does not exist in event definition");
224 /* determine if we already have the name and are just resetting it */
225 if (this.name != null) {
226 bytesStoreSize -= (this.name.length() + 1 + 2);
229 bytesStoreSize += (name.length() + 1 + 2);
231 this.name = name;
235 * Get the character encoding for this event
237 * @return the encoding
239 public short getEncoding() {
240 return this.encoding;
244 * Set the character encoding for event strings
246 * @param encoding the character encoding
247 * @throws NoSuchAttributeTypeException if the type for the encoding attribute does not exist
248 * @throws NoSuchAttributeException if the encoding attribute does not exist
250 public void setEncoding(short encoding) throws EventSystemException {
251 this.encoding = encoding;
252 setInt16(ENCODING, this.encoding);
256 * Generic accessor, checks if an attribute exists and returns its value. The user must do their
257 * own type checking.
259 * @param attributeName name of the attribute to lookup
260 * @return the object poitned to by attributeName
261 * @throws NoSuchAttributeException if the attribute does not exist in this event
263 public Object get(String attributeName) throws NoSuchAttributeException {
264 if (attributes == null) {
265 return null;
268 if (attributes.containsKey(attributeName)) {
269 return attributes.get(attributeName).getTypeObject();
272 if (isValidating() && getEventTemplateDB() != null) {
273 if (getEventTemplateDB().checkForAttribute(name, attributeName)) {
274 return null;
276 else {
277 throw new NoSuchAttributeException("Attribute " + attributeName + " does not exist for event " + name);
281 return null;
285 public String[] getStringArray(String attributeName)
286 throws NoSuchAttributeException {
287 Object o = get(attributeName);
288 if (o != null && o instanceof String[]) {
289 return (String[]) o;
291 else {
292 return null;
297 * Method to check if an attribute is set in the event. This method does not throw
298 * NoSuchAttributeException because it shouldn't really care. If it's not there, it's
299 * not there.
301 * @param attributeName The attribute name to check for existance.
302 * @return true if there is a value, false if not.
304 public boolean isSet(String attributeName) {
305 try {
306 return (get(attributeName) != null);
308 catch (NoSuchAttributeException e) {
309 return false;
314 * Accessor that returns a boolean value for attribute <tt>attributeName</tt>
316 * @param attributeName the name of the attribute to fetch
317 * @return the boolean value
318 * @throws NoSuchAttributeException if the attribute does not exist in this event
320 public Boolean getBoolean(String attributeName) throws NoSuchAttributeException {
321 return (Boolean) get(attributeName);
325 * Accessor that returns an <tt>unsigned short</tt>, in the guise of an <tt>int</tt>, for attribute <tt>attributeName</tt>
327 * @param attributeName the name of the attribute to fetch
328 * @return the unsigned short as an int
329 * @throws NoSuchAttributeException if the attribute does not exist in this event
331 public Integer getUInt16(String attributeName) throws NoSuchAttributeException {
332 return (Integer) get(attributeName);
336 * Accessor that returns an <tt>short</tt>, for attribute <tt>attributeName</tt>
338 * @param attributeName the name of the attribute to fetch
339 * @return the short value
340 * @throws NoSuchAttributeException if the attribute does not exist in this event
342 public Short getInt16(String attributeName) throws NoSuchAttributeException {
343 return (Short) get(attributeName);
347 * Accessor that returns an <tt>unsigned int</tt>, in the guise of an <tt>long</tt>, for attribute <tt>attributeName</tt>
349 * @param attributeName the name of the attribute to fetch
350 * @return the unsigned int as a long
351 * @throws NoSuchAttributeException if the attribute does not exist in this event
353 public Long getUInt32(String attributeName) throws NoSuchAttributeException {
354 return (Long) get(attributeName);
358 * Accessor that returns an <tt>int</tt>, for attribute <tt>attributeName</tt>
360 * @param attributeName the name of the attribute to fetch
361 * @return the int value
362 * @throws NoSuchAttributeException if the attribute does not exist in this event
364 public Integer getInt32(String attributeName) throws NoSuchAttributeException {
365 return (Integer) get(attributeName);
369 * Accessor that returns an <tt>unsigned long</tt>, in the guise of an <tt>BigInteger</tt>, for attribute <tt>attributeName</tt>
371 * @param attributeName the name of the attribute to fetch
372 * @return the unsigned long as a BigInteger
373 * @throws NoSuchAttributeException if the attribute does not exist in this event
375 public BigInteger getUInt64(String attributeName) throws NoSuchAttributeException {
376 return (BigInteger) get(attributeName);
381 * Accessor that returns an <tt>long</tt>, for attribute <tt>attributeName</tt>
383 * @param attributeName the name of the attribute to fetch
384 * @return the long value
385 * @throws NoSuchAttributeException if the attribute does not exist in this event
387 public Long getInt64(String attributeName) throws NoSuchAttributeException {
388 return (Long) get(attributeName);
392 * Accessor that returns an <tt>String</tt>, for attribute <tt>attributeName</tt>
394 * @param attributeName the name of the attribute to fetch
395 * @return the String value
396 * @throws NoSuchAttributeException if the attribute does not exist in this event
398 public String getString(String attributeName) throws NoSuchAttributeException {
399 return (String) get(attributeName);
403 * Accessor that returns an <tt>InetAddress</tt>, for attribute <tt>attributeName</tt>
405 * @param attributeName the name of the attribute to fetch
406 * @return the InetAddress value
407 * @throws NoSuchAttributeException if the attribute does not exist in this event
409 public InetAddress getInetAddress(String attributeName) throws NoSuchAttributeException {
410 IPAddress a = (IPAddress) get(attributeName);
411 if (a != null) {
412 return a.toInetAddress();
414 else {
415 return null;
420 * Accessor that returns an IP address in bytes, for attribute <tt>attributeName</tt>
422 * @param attributeName the name of the attribute to fetch
423 * @return the IP address in bytes
424 * @throws NoSuchAttributeException if the attribute does not exist in this event
426 public byte[] getIPAddress(String attributeName) throws NoSuchAttributeException {
427 return (byte[]) get(attributeName);
432 * Set the object's attribute <tt>attributeName</tt> with the Object given
434 * @param attributeName the name of the attribute to set
435 * @param attributeValue the object to set the attribute with
436 * @throws NoSuchAttributeException if the attribute does not exist in this event
437 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
439 public void set(String attributeName, Object attributeValue)
440 throws EventSystemException {
441 if (isValidating() && getEventTemplateDB() != null) {
442 if (getEventTemplateDB().checkForAttribute(getEventName(), attributeName)) {
443 BaseType bt = getEventTemplateDB().getBaseTypeForObjectAttribute(getEventName(),
444 attributeName, attributeValue);
445 set(attributeName, bt);
448 else {
449 throw new NoSuchAttributeException("Must be able to check the EventTemplateDB to use set(String,Object)");
454 * Private method to set a BaseType
456 * @param attribute the name of the attribute to set
457 * @param anObject the BaseType to set in the event
458 * @throws NoSuchAttributeException if the attribute does not exist in this event
459 * @throws NoSuchAttributeTypeException if there is an attribute with an undefined type
461 private void set(String attribute, BaseType anObject)
462 throws EventSystemException {
464 if (isValidating() && getEventTemplateDB() != null) {
465 if (getEventTemplateDB().checkForAttribute(name, attribute)) {
466 if (!getEventTemplateDB().checkTypeForAttribute(name, attribute, anObject)) {
467 throw new NoSuchAttributeTypeException("Wrong type '" + anObject.getTypeName() +
468 "' for " + name + "." + attribute);
471 else {
472 throw new NoSuchAttributeException("Attribute " + attribute + " does not exist for event " + name);
474 getEventTemplateDB().checkForSize(name, attribute, anObject);
477 if (anObject.getTypeObject() != null) {
478 BaseType oldObject = null;
479 int newSize = bytesStoreSize + ((attribute.length() + 1) + anObject.bytesStoreSize(encoding));
480 if (newSize > MAX_MESSAGE_SIZE) {
481 throw new EventSystemException("Event size limit is " + MAX_MESSAGE_SIZE + " bytes.");
483 if ((oldObject = attributes.remove(attribute)) != null) {
484 bytesStoreSize -= (attribute.length() + 1) + oldObject.bytesStoreSize(encoding);
487 bytesStoreSize += (attribute.length() + 1) + anObject.bytesStoreSize(encoding);
488 attributes.put(attribute, anObject);
492 public void setStringArray(String attributeName, String[] value)
493 throws EventSystemException {
494 set(attributeName, new BaseType(TypeID.STRING_ARRAY_STRING,
495 TypeID.STRING_ARRAY_TOKEN,
496 value));
500 * Sets the given attribute with a <tt>boolean</tt> value given by <tt>aBool</tt>.
502 * @param attributeName the attribute to set
503 * @param aBool the boolean value to set
504 * @throws NoSuchAttributeException if the attribute does not exist in the event
505 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
507 public void setBoolean(String attributeName, boolean aBool)
508 throws EventSystemException {
509 setBoolean(attributeName, Boolean.valueOf(aBool));
513 * Sets the given attribute with a <tt>Boolean</tt> value given by <tt>aBool</tt>.
515 * @param attributeName the attribute to set
516 * @param aBool the boolean value to set
517 * @throws NoSuchAttributeException
518 * @throws NoSuchAttributeTypeException
520 public void setBoolean(String attributeName, Boolean aBool)
521 throws EventSystemException {
522 set(attributeName, new BaseType(TypeID.BOOLEAN_STRING, TypeID.BOOLEAN_TOKEN, aBool));
526 * Set the given attribute with the <tt>unsigned short</tt> value given by <tt>aNumber</tt>.
527 * Because Java does not support unsigned types, we must use a signed int to cover the range of unsigned short.
529 * @param attributeName the attribute to set
530 * @param aNumber the unsigned short value as an integer
531 * @throws NoSuchAttributeException if the attribute does not exist in the event
532 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
534 public void setUInt16(String attributeName, int aNumber)
535 throws EventSystemException {
536 setUInt16(attributeName, Integer.valueOf(aNumber));
540 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
541 * This should be an <tt>unsigned short</tt>, but is an Integer because Java does not support unsigned types,
542 * and a signed integer is needed to cover the range of an unsigned short.
544 * @param attributeName the attribute to set
545 * @param aNumber the value
547 public void setUInt16(String attributeName, Integer aNumber)
548 throws EventSystemException {
549 set(attributeName, new BaseType(TypeID.UINT16_STRING, TypeID.UINT16_TOKEN, aNumber));
553 * Set the given attribute with the <tt>short</tt> value given by <tt>aNumber</tt>.
555 * @param attributeName the attribute to set
556 * @param aNumber the short value to set
557 * @throws NoSuchAttributeException if the attribute does not exist in the event
558 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
560 public void setInt16(String attributeName, short aNumber)
561 throws EventSystemException {
562 setInt16(attributeName, Short.valueOf(aNumber));
566 * Set the given attribute with the <tt>Short</tt> value given by <tt>aNumber</tt>.
568 * @param attributeName the attribute to set
569 * @param aNumber the short value to set
570 * @throws NoSuchAttributeException if the attribute does not exist in the event
571 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
573 public void setInt16(String attributeName, Short aNumber)
574 throws EventSystemException {
575 set(attributeName, new BaseType(TypeID.INT16_STRING, TypeID.INT16_TOKEN, aNumber));
579 * Set the given attribute with the <tt>unsigned int</tt> value given by <tt>aNumber</tt>.
580 * Because Java does not support unsigned types, we must use a signed long to cover the range of an unsigned int.
582 * @param attributeName the attribute to set
583 * @param aNumber the unsigned int value as a long
584 * @throws NoSuchAttributeException if the attribute does not exist in the event
585 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
587 public void setUInt32(String attributeName, long aNumber)
588 throws EventSystemException {
589 setUInt32(attributeName, Long.valueOf(aNumber));
593 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
594 * This should be an <tt>unsigned int</tt>, but is an Long because Java does not support unsigned types,
595 * and a signed long is needed to cover the range of an unsigned int.
597 * @param attributeName the attribute to set
598 * @param aNumber the value
600 public void setUInt32(String attributeName, Long aNumber)
601 throws EventSystemException {
602 set(attributeName, new BaseType(TypeID.UINT32_STRING, TypeID.UINT32_TOKEN, aNumber));
606 * Set the given attribute with the <tt>int</tt> value given by <tt>aNumber</tt>.
608 * @param attributeName the attribute to set
609 * @param aNumber the integer value to set
610 * @throws NoSuchAttributeException if the attribute does not exist in the event
611 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
613 public void setInt32(String attributeName, int aNumber)
614 throws EventSystemException {
615 setInt32(attributeName, Integer.valueOf(aNumber));
619 * Set the given attribute with the <tt>Integer</tt> value given by <tt>aNumber</tt>.
621 * @param attributeName the attribute to set
622 * @param aNumber the Integer value to set
623 * @throws NoSuchAttributeException if the attribute does not exist in the event
624 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
626 public void setInt32(String attributeName, Integer aNumber)
627 throws EventSystemException {
628 set(attributeName, new BaseType(TypeID.INT32_STRING, TypeID.INT32_TOKEN, aNumber));
632 * Set the given attribute with the <tt>unsigned long</tt> value given by <tt>aNumber</tt>.
634 * @param attributeName the attribute to set
635 * @param aNumber the value
636 * @throws NoSuchAttributeException if the attribute does not exist in the event
637 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
639 public void setUInt64(String attributeName, long aNumber)
640 throws EventSystemException {
641 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber)));
645 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
647 * @param attributeName the attribute to set
648 * @param aNumber the value
649 * @throws NoSuchAttributeException if the attribute does not exist in the event
650 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
652 public void setUInt64(String attributeName, Long aNumber)
653 throws EventSystemException {
654 set(attributeName,
655 new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, BigInteger.valueOf(aNumber.longValue())));
659 * Set the given attribute with the <tt>BigInteger</tt> value given by <tt>aNumber</tt>.
660 * This should be an <tt>unsigned long</tt>, but is an BigInteger because Java does not support unsigned types,
661 * and a BigInteger is needed to cover the range of an unsigned long.
663 * @param attributeName the attribute to set
664 * @param aNumber the value
666 public void setUInt64(String attributeName, BigInteger aNumber)
667 throws EventSystemException {
668 set(attributeName, new BaseType(TypeID.UINT64_STRING, TypeID.UINT64_TOKEN, aNumber));
672 * Set the given attribute with the <tt>long</tt> value given by <tt>aNumber</tt>.
674 * @param attributeName the attribute to set
675 * @param aNumber the long value to set
676 * @throws NoSuchAttributeException if the attribute does not exist in the event
677 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
679 public void setInt64(String attributeName, long aNumber)
680 throws EventSystemException {
681 setInt64(attributeName, Long.valueOf(aNumber));
685 * Set the given attribute with the <tt>Long</tt> value given by <tt>aNumber</tt>.
687 * @param attributeName the attribute to set
688 * @param aNumber the Long value to set
689 * @throws NoSuchAttributeException if the attribute does not exist in the event
690 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
692 public void setInt64(String attributeName, Long aNumber)
693 throws EventSystemException {
694 set(attributeName, new BaseType(TypeID.INT64_STRING, TypeID.INT64_TOKEN, aNumber));
698 * Set the given attribute with a <tt>String</tt>
700 * @param attributeName the attribute to set
701 * @param aString the String value to set
702 * @throws NoSuchAttributeException if the attribute does not exist in the event
703 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
705 public void setString(String attributeName, String aString)
706 throws EventSystemException {
707 set(attributeName, new BaseType(TypeID.STRING_STRING, TypeID.STRING_TOKEN, aString));
711 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
713 * @param attributeName the attribute to set
714 * @param address the ip address in bytes
715 * @throws NoSuchAttributeException if the attribute does not exist in the event
716 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
718 public void setIPAddress(String attributeName, byte[] address)
719 throws EventSystemException {
720 setIPAddress(attributeName, new IPAddress(address));
724 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
726 * @param attributeName the attribute to set
727 * @param address the ip address in bytes
728 * @throws NoSuchAttributeException if the attribute does not exist in the event
729 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
731 public void setIPAddress(String attributeName, InetAddress address)
732 throws EventSystemException {
733 setIPAddress(attributeName, new IPAddress(address));
737 * Set the given attribute with the <tt>ip address</tt> value given by <tt>address</tt>
739 * @param attributeName the attribute to set
740 * @param address the ip address in bytes
741 * @throws NoSuchAttributeException if the attribute does not exist in the event
742 * @throws NoSuchAttributeTypeException if the attribute type does not match the EventTemplateDB
744 public void setIPAddress(String attributeName, IPAddress address)
745 throws EventSystemException {
746 set(attributeName, new BaseType(TypeID.IPADDR_STRING, TypeID.IPADDR_TOKEN, address));
750 * Serializes the Event into a byte array
752 * @return the serialized byte array
754 public byte[] serialize() {
756 * Serialization uses the following protocol
757 * EVENTWORD,<number of elements>,ATTRIBUTEWORD,TYPETOKEN,
758 * (UINT16|INT16|UINT32|INT32|UINT64|INT64|BOOLEAN|STRING)
759 * ...ATTRIBUTEWORD,TYPETOKEN(UINT16|INT16|UINT32|INT32|
760 * UINT64|INT64|BOOLEAN|STRING)
762 * The first attribute will always be the encoding if present.
764 byte[] bytes = new byte[this.bytesStoreSize];
765 int offset = 0;
766 int attributeCount = 0;
767 short encoding = DEFAULT_ENCODING;
769 if (attributes != null) {
770 attributeCount = attributes.size();
773 offset += Serializer.serializeEVENTWORD(name, bytes, offset);
774 offset += Serializer.serializeUINT16((short) (attributeCount), bytes, offset);
777 * Set the encoding attributes in the event
779 if (attributes != null) {
780 BaseType encodingBase = attributes.get(ENCODING);
781 if (encodingBase != null) {
782 Object encodingObj = encodingBase.getTypeObject();
783 byte encodingType = encodingBase.getTypeToken();
784 if (encodingObj != null) {
785 if (encodingType == TypeID.INT16_TOKEN) {
786 encoding = (Short) encodingObj;
787 Log.trace("Character encoding: " + encoding);
788 offset += Serializer.serializeATTRIBUTEWORD(ENCODING, bytes, offset);
789 offset += Serializer.serializeBYTE(encodingType, bytes, offset);
790 offset += Serializer.serializeUINT16(encoding, bytes, offset);
794 else {
795 Log.warning("Character encoding null in event " + name);
798 Enumeration<String> e = attributes.keys();
799 while (e.hasMoreElements()) {
800 String key = e.nextElement();
801 if (key.equals(ENCODING)) {
802 continue;
805 BaseType value = attributes.get(key);
806 Object data = value.getTypeObject();
807 byte typeToken = value.getTypeToken();
809 /* don't try to serialize nulls */
810 if (data == null) {
811 Log.warning("Attribute " + key + " was null in event " + name);
812 continue;
815 offset += Serializer.serializeATTRIBUTEWORD(key, bytes, offset);
816 offset += Serializer.serializeBYTE(typeToken, bytes, offset);
818 switch (typeToken) {
819 case TypeID.BOOLEAN_TOKEN:
820 offset += Serializer.serializeBOOLEAN((Boolean) data, bytes, offset);
821 break;
822 case TypeID.UINT16_TOKEN:
823 offset += Serializer.serializeUINT16((Integer) data, bytes, offset);
824 break;
825 case TypeID.INT16_TOKEN:
826 offset += Serializer.serializeINT16((Short) data, bytes, offset);
827 break;
828 case TypeID.UINT32_TOKEN:
829 offset += Serializer.serializeUINT32((Long) data, bytes, offset);
830 break;
831 case TypeID.INT32_TOKEN:
832 offset += Serializer.serializeINT32((Integer) data, bytes, offset);
833 break;
834 case TypeID.UINT64_TOKEN:
835 offset += Serializer.serializeUINT64((BigInteger) data, bytes, offset);
836 break;
837 case TypeID.INT64_TOKEN:
838 offset += Serializer.serializeINT64((Long) data, bytes, offset);
839 break;
840 case TypeID.STRING_TOKEN:
841 offset += Serializer.serializeSTRING(((String) data), bytes, offset, encoding);
842 break;
843 case TypeID.IPADDR_TOKEN:
844 offset += Serializer.serializeIPADDR(((IPAddress) data), bytes, offset);
845 break;
846 case TypeID.STRING_ARRAY_TOKEN:
847 offset += Serializer.serializeStringArray
848 (((String[]) data), bytes, offset, encoding);
849 break;
850 default:
851 Log.warning("Unknown BaseType token: " + typeToken);
852 break;
853 } // switch(typeToken)
855 Log.trace("Serialized attribute " + key);
856 } // while(e.hasMoreElements())
857 } // if(attributes != null)
859 return bytes;
863 * Deserialize the Event from byte array
865 * @param bytes the byte array containing a serialized Event
867 public void deserialize(byte[] bytes)
868 throws EventSystemException {
869 if (bytes == null) {
870 return;
872 if (state == null) {
873 state = new DeserializerState();
876 state.reset();
877 setEventName(Deserializer.deserializeEVENTWORD(state, bytes));
878 long num = Deserializer.deserializeUINT16(state, bytes);
879 if (Log.isLogTrace()) {
880 Log.trace("Event name = " + getEventName());
881 Log.trace("Number of attribute: " + num);
883 for (int i = 0; i < num; ++i) {
884 String attribute = Deserializer.deserializeATTRIBUTEWORD(state, bytes);
886 byte type = Deserializer.deserializeBYTE(state, bytes);
887 if (Log.isLogTrace()) {
888 Log.trace("Attribute: " + attribute);
889 Log.trace("Type: " + TypeID.byteIDToString(type));
890 Log.trace("State: " + state);
892 if (attribute != null) {
893 if (i == 0 && attribute.equals(ENCODING)) {
894 if (type == TypeID.INT16_TOKEN) {
895 setEncoding(Deserializer.deserializeINT16(state, bytes));
896 continue;
898 else {
899 Log.warning("Found encoding, but type was not int16 while deserializing");
903 switch (type) {
904 case TypeID.BOOLEAN_TOKEN:
905 boolean aBool = Deserializer.deserializeBOOLEAN(state, bytes);
906 setBoolean(attribute, aBool);
907 break;
908 case TypeID.UINT16_TOKEN:
909 int uShort = Deserializer.deserializeUINT16(state, bytes);
910 setUInt16(attribute, uShort);
911 break;
912 case TypeID.INT16_TOKEN:
913 short aShort = Deserializer.deserializeINT16(state, bytes);
914 setInt16(attribute, aShort);
915 break;
916 case TypeID.UINT32_TOKEN:
917 long uInt = Deserializer.deserializeUINT32(state, bytes);
918 setUInt32(attribute, uInt);
919 break;
920 case TypeID.INT32_TOKEN:
921 int aInt = Deserializer.deserializeINT32(state, bytes);
922 setInt32(attribute, aInt);
923 break;
924 case TypeID.UINT64_TOKEN:
925 long uLong = Deserializer.deserializeUINT64(state, bytes);
926 setUInt64(attribute, BigInteger.valueOf(uLong));
927 break;
928 case TypeID.INT64_TOKEN:
929 long aLong = Deserializer.deserializeINT64(state, bytes);
930 setInt64(attribute, aLong);
931 break;
932 case TypeID.STRING_TOKEN:
933 String s = Deserializer.deserializeSTRING(state, bytes, encoding);
934 setString(attribute, s);
935 break;
936 case TypeID.IPADDR_TOKEN:
937 byte[] inetAddress = Deserializer.deserializeIPADDR(state, bytes);
938 setIPAddress(attribute, inetAddress);
939 break;
940 case TypeID.STRING_ARRAY_TOKEN:
941 String[] sArray = Deserializer.deserializeStringArray(state, bytes, encoding);
942 setStringArray(attribute, sArray);
943 break;
944 default:
945 Log.warning("Unknown type " + type + " in deserialization");
948 } // for (int i =0 ...
953 * Returns a mutable copy of the event. This is a SLOW operation.
955 * @return Event the Event object
956 * @throws NoSuchEventException if the Event does not exist in the EventTemplateDB
957 * @throws NoSuchAttributeException if the attribute does not exist in this event
958 * @throws NoSuchAttributeTypeException if there is an attribute that does not match a type in the EventTemplateDB
960 public Event copy() throws EventSystemException {
961 /* match the type-checking of the original event */
962 Event evt = new Event(name, isValidating(), getEventTemplateDB());
963 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
964 String key = e.nextElement();
965 BaseType value = attributes.get(key);
966 evt.set(key, value);
969 return evt;
973 * Returns a String representation of this event
975 * @return a String return of this event.
977 public String toString() {
978 if (name == null) {
979 return "";
982 StringBuffer sb = new StringBuffer();
983 sb.append(name);
984 sb.append("\n{\n");
986 if (attributes != null) {
987 int i = 0;
988 String[] keys = new String[attributes.size()];
989 for (Enumeration<String> e = attributes.keys(); e.hasMoreElements();) {
990 keys[i++] = e.nextElement();
993 Arrays.sort(keys);
995 for (i = 0; i < attributes.size(); ++i) {
996 BaseType value = attributes.get(keys[i]);
997 if (isValidating() && getEventTemplateDB() != null) {
998 if (getEventTemplateDB().checkTypeForAttribute(name, keys[i], TypeID.UINT64_STRING)) {
999 try {
1000 sb.append("\t")
1001 .append(keys[i])
1002 .append(" = ")
1003 .append(NumberCodec.toHexString(getUInt64(keys[i])))
1004 .append(";\n");
1006 catch (EventSystemException exc) {
1007 Log.warning("Event.toString : ", exc);
1010 else {
1011 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1014 else {
1015 sb.append("\t").append(keys[i]).append(" = ").append(value).append(";\n");
1017 } // for(i = 0; i < attributes.size() ...
1018 } // if(attributes != null)
1020 sb.append("}");
1021 return sb.toString();
1024 @Override
1025 public int hashCode() {
1026 return toString().hashCode();
1029 public boolean equals(Object o) {
1030 if (o == null) {
1031 return false;
1033 if (getClass().getName().equals(o.getClass().getName())) {
1034 return toString().equals(o.toString());
1036 else {
1037 return false;
1042 * This method can be used to validate an event after it has been created.
1044 * @throws EventSystemException
1046 public void validate() throws EventSystemException {
1047 EventTemplateDB templ = getEventTemplateDB();
1048 if (templ == null) {
1049 throw new EventSystemException("No template defined.");
1051 if (!templ.checkForEvent(name)) {
1052 throw new NoSuchEventException("Event " + name + " does not exist in event definition");
1054 for (String key : attributes.keySet()) {
1055 if (!templ.checkForAttribute(name, key)) {
1056 throw new NoSuchAttributeException("Attribute " + key + " does not exist for event " + name);
1058 Object value = get(key);
1059 BaseType expected = templ.getBaseTypeForObjectAttribute(name, key, value);
1060 BaseType bt = BaseType.baseTypeFromObject(value);
1062 * There are no unsigned values in java so they are kind of a special case
1063 * in that i can't guess which one the person meant. This small hack treats
1064 * similar types the same way.
1066 if ((expected.getTypeToken() == TypeID.UINT16_TOKEN &&
1067 bt.getTypeToken() == TypeID.INT32_TOKEN) ||
1068 (expected.getTypeToken() == TypeID.UINT32_TOKEN &&
1069 bt.getTypeToken() == TypeID.INT64_TOKEN) ||
1070 (expected.getTypeToken() == TypeID.UINT64_TOKEN &&
1071 bt.getTypeToken() == TypeID.INT64_TOKEN) ) {
1072 bt = expected;
1074 if (!templ.checkTypeForAttribute(name, key, bt)) {
1075 throw new NoSuchAttributeTypeException("Wrong type '" + bt.getTypeName() +
1076 "' for " + name + "." + key);