3 import org
.apache
.commons
.logging
.Log
;
4 import org
.apache
.commons
.logging
.LogFactory
;
5 import org
.lwes
.BaseType
;
6 import org
.lwes
.EventAttributeSizeException
;
7 import org
.lwes
.EventSystemException
;
8 import org
.lwes
.TypeID
;
9 import org
.lwes
.util
.IPAddress
;
12 import java
.io
.InputStream
;
13 import java
.math
.BigInteger
;
14 import java
.util
.Arrays
;
15 import java
.util
.Collections
;
16 import java
.util
.Enumeration
;
17 import java
.util
.List
;
19 import java
.util
.TreeMap
;
20 import java
.util
.concurrent
.ConcurrentHashMap
;
23 * Provides type checking for the event system. Also provides a place for
24 * globally accessible information.
26 * @author Anthony Molinaro
27 * @author Michael P. Lum
28 * @author Frank Maritato
30 public class EventTemplateDB
{
32 private static transient Log log
= LogFactory
.getLog(EventTemplateDB
.class);
34 * the meta event info inherent to every event
36 private static final String META_EVENT_INFO
= "MetaEventInfo";
39 * esfFile for this event system.
41 private File esfFile
= null;
42 private InputStream esfInputStream
= null;
47 private Map
<String
, Map
<String
, BaseType
>> events
= null;
48 private Map
<String
, BaseType
> knownTypes
= null;
49 private Map
<String
, BaseType
> reservedWords
= null;
52 * This is the EventTemplateDB constructor.
54 public EventTemplateDB() {
55 events
= new ConcurrentHashMap
<String
, Map
<String
, BaseType
>>();
56 knownTypes
= new ConcurrentHashMap
<String
, BaseType
>();
57 reservedWords
= new ConcurrentHashMap
<String
, BaseType
>();
58 initializeKnownTypes();
62 * Sets the Event Specification file for this system
64 * @param anEsfFile the ESF file for this system.
66 public void setESFFile(File anEsfFile
) {
71 * Gets the ESF file, in case you want to look at it
73 * @return the ESF file used in this system.
75 public File
getESFFile() {
80 * Sets the Event Specification file as an InputStream
82 * @param esfInputStream the InputStream representing an ESF file
84 public void setESFInputStream(InputStream esfInputStream
) {
85 this.esfInputStream
= esfInputStream
;
89 * Ges the ESF InputStream
91 * @return the ESF InputStream used in the system
93 public InputStream
getESFInputStream() {
94 return esfInputStream
;
98 * Initializes the EventTemplateDB, assumes that setESFFile() has been
101 * @return true if the EventTemplateDB initializes correctly; false if it
102 * does not. false means the event system is unable to perform validation
104 public synchronized boolean initialize() {
106 * Call the parser to parse the file. Any errors cause the
107 * initialization to fail.
111 if (getESFInputStream() != null) {
112 parser
= new ESFParser(getESFInputStream());
114 else if (getESFFile() != null) {
115 parser
= new ESFParser(
116 new java
.io
.FileInputStream(getESFFile()));
122 parser
.setEventTemplateDB(this);
125 catch (java
.io
.FileNotFoundException e
) {
126 log
.warn("File not found ", e
);
129 * treat this as just a warning and allow things to continue, this
130 * allows an empty EventTemplateDB to work when type checking is
134 catch (ParseException e
) {
135 log
.warn("Parser error in ESF file " + getESFFile(), e
);
138 catch (Exception e
) {
139 log
.error("Error parsing ESF file " + getESFFile(), e
);
140 /* catch IO, NPEs and other exceptions but still continue */
148 * Add an Event to the EventTemplateDB
150 * @param anEventName the name of the Event to add
151 * @return true if the event was added, false if it was not
153 public synchronized boolean addEvent(String anEventName
) {
154 if (anEventName
== null) {
159 if (anEventName
.equals(META_EVENT_INFO
)) {
163 if (events
.containsKey(anEventName
)) {
164 if (log
.isInfoEnabled()) {
165 log
.info("Event " + anEventName
+ " already exists in event DB");
170 Map
<String
, BaseType
> evtHash
= new ConcurrentHashMap
<String
, BaseType
>();
171 if (!(reservedWords
.isEmpty())) {
172 /* insert reserved words into new event */
173 for (String key
: reservedWords
.keySet()) {
175 evtHash
.put(key
, reservedWords
.get(key
));
180 events
.put(anEventName
, evtHash
);
182 catch (Exception e
) {
183 log
.warn("Error adding event to EventTemplateDB", e
);
189 public synchronized boolean addEventAttribute(String anEventName
,
190 String anAttributeName
,
191 String anAttributeType
) {
192 return addEventAttribute(anEventName
,
199 public synchronized boolean addEventAttribute(String anEventName
,
200 String anAttributeName
,
201 String anAttributeType
,
204 return addEventAttribute(anEventName
, anAttributeName
, anAttributeType
, size
, required
, null);
208 * Add an attribute to an Event in the EventTemplateDB
210 * @param anEventName the name of the event to add this attribute to
211 * @param anAttributeName the name of the attribute to add
212 * @param anAttributeType the type of the attribute, should be the name of the type
213 * given in the ESF Specification.
214 * @param size The size restriction for this attribute
215 * @param required Is this attribute required
216 * @return true if the attribute can be added, false if it can not.
218 public synchronized boolean addEventAttribute(String anEventName
,
219 String anAttributeName
,
220 String anAttributeType
,
223 Object defaultValue
) {
225 if (anEventName
== null || anAttributeName
== null || anAttributeType
== null) {
230 if (anEventName
.equals(META_EVENT_INFO
)) {
231 if (checkForType(anAttributeType
)) {
232 BaseType bt
= knownTypes
.get(anAttributeType
).cloneBaseType();
233 bt
.setRequired(required
);
234 bt
.setSizeRestriction(size
);
235 if (defaultValue
!= null) {
236 bt
.setDefaultValue(defaultValue
);
238 reservedWords
.put(anAttributeName
, bt
);
242 if (log
.isInfoEnabled()) {
243 log
.info("Meta keyword " + anEventName
+ "." + anAttributeName
+
244 "has unknown type " + anAttributeType
+ ", skipping");
250 if (reservedWords
.containsKey(anEventName
)) {
251 if (log
.isWarnEnabled()) {
252 log
.warn("Unable to add attribute named " + anAttributeName
+
253 "as it is a reserved word, skipping");
258 if (events
.containsKey(anEventName
)) {
259 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
260 if (checkForType(anAttributeType
)) {
261 BaseType bt
= knownTypes
.get(anAttributeType
).cloneBaseType();
262 bt
.setRequired(required
);
263 bt
.setSizeRestriction(size
);
264 if (defaultValue
!= null) {
265 bt
.setDefaultValue(defaultValue
);
267 evtHash
.put(anAttributeName
, bt
);
271 if (log
.isWarnEnabled()) {
272 log
.warn("Type " + anAttributeType
+ " does not exist for " +
273 anAttributeName
+ ", skipping");
279 if (log
.isWarnEnabled()) {
280 log
.warn("No such event " + anEventName
+ ", skipping");
285 catch (Exception e
) {
286 log
.error("Error adding attribute " + anAttributeName
+ " to " + anEventName
, e
);
292 * Returns an enumeration of all defined events
294 * @return an enumeration of all defined events
296 public Enumeration
<String
> getEventNames() {
297 return Collections
.enumeration(this.events
.keySet());
301 * Returns true if the type given by aTypeName is a valid type in the DB.
303 * @param aTypeName a type name according to the ESF Specification
304 * @return true if the type exists in the DB, false otherwise
306 public boolean checkForType(String aTypeName
) {
307 if (aTypeName
== null) {
310 return knownTypes
.containsKey(aTypeName
);
313 public void checkForSize(String eventName
,
314 String attributeName
,
315 BaseType attributeValue
) throws EventAttributeSizeException
{
317 if (!attributeValue
.getTypeName().startsWith("[L")) {
318 if (log
.isDebugEnabled()) {
319 log
.debug("value for attribute " + attributeName
+ " is not an array.");
324 Map
<String
, BaseType
> evtMap
= events
.get(eventName
);
325 if (evtMap
== null) {
326 log
.error("event definition did not exist");
329 BaseType attrBaseType
= evtMap
.get(attributeName
);
330 if (attrBaseType
== null) {
331 log
.error("attribute definition did not exist");
336 int size
= attrBaseType
.getSizeRestriction();
337 Object o
= attributeValue
.getTypeObject();
338 if (o
instanceof short[]) {
339 sizeToCheck
= ((short[]) o
).length
;
341 else if (o
instanceof int[]) {
342 sizeToCheck
= ((int[]) o
).length
;
344 else if (o
instanceof long[]) {
345 sizeToCheck
= ((long[]) o
).length
;
347 else if (o
instanceof boolean[]) {
348 sizeToCheck
= ((boolean[]) o
).length
;
350 else if (o
instanceof byte[]) {
351 sizeToCheck
= ((byte[]) o
).length
;
353 else if (o
instanceof double[]) {
354 sizeToCheck
= ((double[]) o
).length
;
356 else if (o
instanceof float[]) {
357 sizeToCheck
= ((float[]) o
).length
;
359 else if (o
instanceof List
) {
360 List arr
= (List
) attributeValue
.getTypeObject();
361 sizeToCheck
= arr
.size();
364 throw new EventAttributeSizeException("Cannot determine size for "+attributeName
);
366 if (log
.isTraceEnabled()) {
367 log
.trace("sizeToCheck: " + sizeToCheck
+ " size: " + size
);
369 if (size
> 0 && sizeToCheck
> size
) {
370 throw new EventAttributeSizeException(attributeName
, sizeToCheck
, size
);
375 * Checks to see if an Event exists in the EventTemplateDB
377 * @param anEventName the name of the event to check the existence of
378 * @return true if the event with the name <tt>anEventName</tt> exists in
379 * the EventTemplateDB, false otherwise.
381 public boolean checkForEvent(String anEventName
) {
382 if (anEventName
== null) {
385 return events
.containsKey(anEventName
);
389 * Checks to see if an attribute <tt>anAttributeName</tt> exists for the
390 * event <tt>anEventName</tt>
392 * @param anEventName the name of an Event
393 * @param anAttributeName the name of an attribute of Event to check
394 * @return true if the attribute exists as a member of event, false
397 public boolean checkForAttribute(String anEventName
, String anAttributeName
) {
398 if (anEventName
== null || anAttributeName
== null) {
402 if (checkForEvent(anEventName
)) {
403 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
404 return evtHash
.containsKey(anAttributeName
);
410 * Checks to see if the type of an attribute is proper. (i.e. if the given
411 * attribute of the given event has the same type assigned to it as the type
412 * of the given objects value)
414 * @param anEventName the name of an Event.
415 * @param anAttributeName the name of the attribute whose type is being checked
416 * @param anAttributeValue the Object containing the possible value of the attribute.
417 * @return true if the event and attribute exist and if the type of the
418 * attribute matches the type assigned to this attribute in the
419 * EventTemplateDB, false otherwise.
421 public boolean checkTypeForAttribute(String anEventName
,
422 String anAttributeName
,
423 Object anAttributeValue
) {
424 if (anEventName
== null || anAttributeName
== null || anAttributeValue
== null) {
428 if (checkForAttribute(anEventName
, anAttributeName
)) {
429 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
430 Object storedTypeObject
= evtHash
.get(anAttributeName
);
431 byte type1
= ((BaseType
) anAttributeValue
).getTypeToken();
432 byte type2
= ((BaseType
) storedTypeObject
).getTypeToken();
433 if (type1
== type2
) {
442 * Checks to see if the type of an attribute is proper. (i.e. if the given
443 * attribute of the given event has the same type assigned to it as the type
446 * @param anEventName the name of an Event.
447 * @param anAttributeName the name of the attribute whose type is being checked
448 * @param anAttributeType the String containing the possible type value of the
450 * @return true if the event and attribute exist and if the type of the
451 * attribute matches the type assigned to this attribute in the
452 * EventTemplateDB, false otherwise.
454 public boolean checkTypeForAttribute(String anEventName
,
455 String anAttributeName
, String anAttributeType
) {
456 if (anEventName
== null || anAttributeName
== null || anAttributeType
== null) {
460 if (checkForAttribute(anEventName
, anAttributeName
)) {
461 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
462 String storedTypeName
= evtHash
.get(anAttributeName
).getTypeName();
463 if (log
.isDebugEnabled()) {
471 if (anAttributeType
.equals(storedTypeName
)) {
480 * Given an Object which is the attribute value of the attribute
481 * <tt>attributeName</tt> of event <tt>eventName</tt>, return the internal
482 * representation (i.e. <tt>BaseType</tt>) of this Object
484 * @param eventName the name of an Event.
485 * @param attributeName the name of an attribute of <tt>eventName</tt>
486 * @param attributeValue the value of the attribute
487 * @return the <tt>BaseType</tt> representation of <tt>attributeValue</tt>
489 public BaseType
getBaseTypeForObjectAttribute(String eventName
,
490 String attributeName
,
491 Object attributeValue
) {
492 if (eventName
== null || attributeName
== null || attributeValue
== null) {
496 Map
<String
, BaseType
> evtHash
= events
.get(eventName
);
497 BaseType tmpBaseType
= evtHash
.get(attributeName
);
498 BaseType retBaseType
= tmpBaseType
.cloneBaseType();
499 retBaseType
.setTypeObject(attributeValue
);
504 * Returns the base types for this event
507 * @return a map of event fields to base types
509 public Map
<String
, BaseType
> getBaseTypesForEvent(String eventName
) {
510 if (eventName
== null) {
514 Map
<String
, BaseType
> map
= events
.get(eventName
);
516 return map
== null ?
new ConcurrentHashMap
<String
, BaseType
>() : map
;
520 * Parses the string representation of an event attribute into the
521 * appropriate objectt.
523 * @param anEventName the name of an Event.
524 * @param anAttributeName the name of the attribute we are parsing
525 * @param stringAttributeValue a string representation of the value of the attribute given by
527 * @return the object represented by the string
528 * <tt>stringAttributeValue</tt>
530 public Object
parseAttribute(String anEventName
, String anAttributeName
,
531 String stringAttributeValue
) {
532 Object retObject
= null;
534 if (anEventName
== null || anAttributeName
== null || stringAttributeValue
== null) {
538 if (log
.isTraceEnabled()) {
539 log
.trace("parseAttribute: " + anEventName
+ "." + anAttributeName
+ "=" +
540 stringAttributeValue
);
543 if (checkForAttribute(anEventName
, anAttributeName
)) {
544 if (log
.isTraceEnabled()) {
545 log
.trace("parseAttribute: passed first if attribute exists");
548 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
550 BaseType bt
= evtHash
.get(anAttributeName
);
552 throw new EventSystemException("Null BaseType for "
556 retObject
= bt
.parseFromString(stringAttributeValue
);
557 if (log
.isTraceEnabled()) {
558 log
.trace("parseAttribute: parsed " + retObject
);
561 catch (EventSystemException btpe
) {
562 log
.error("Unable to parseAttribute", btpe
);
566 if (log
.isTraceEnabled()) {
567 log
.trace("parseAttribute: returning " + retObject
);
573 * Returns a HTML rendering of the EventTemplateDB
575 * @return HTML string of the EventTemplateDB
577 public String
toHtmlString() {
578 StringBuffer sb
= new StringBuffer();
579 sb
.append("<table>\n");
580 sb
.append("<tr><th>" + META_EVENT_INFO
581 + "</th><th>Type</th><th>Name</th></tr>\n");
582 for (String key
: reservedWords
.keySet()) {
583 BaseType tv
= reservedWords
.get(key
);
584 String type
= tv
.getTypeName();
585 sb
.append("<tr><td></td><td>").append(type
).append("</td><td>").append(key
).append("</td></tr>\n");
587 for (String EventKey
: events
.keySet()) {
588 sb
.append("<tr><th>").append(EventKey
).append("</th><th>Type</th><th>Name</th></tr>\n");
589 if (EventKey
!= null) {
590 Map
<String
, BaseType
> event
= events
.get(EventKey
);
591 for (Enumeration
<String
> att
= Collections
.enumeration(event
.keySet()); att
592 .hasMoreElements();) {
593 String key
= att
.nextElement();
594 BaseType tv
= event
.get(key
);
595 String type
= tv
.getTypeName();
596 sb
.append("<tr><td></td><td>")
599 .append(key
).append("</td></tr>\n");
604 sb
.append("</table>\n");
605 return sb
.toString();
610 * Returns a rather long string Representation of the EventTemplateDB
612 * @return a string Representation of the EventTemplateDB
614 public String
toString() {
615 StringBuffer sb
= new StringBuffer();
616 sb
.append("\n").append(META_EVENT_INFO
).append("\n{\n");
617 String
[] reservedKeys
= new String
[reservedWords
.size()];
620 for (String s1
: reservedWords
.keySet()) {
621 reservedKeys
[i
] = s1
;
624 Arrays
.sort(reservedKeys
);
626 for (i
= 0; i
< reservedKeys
.length
; ++i
) {
627 BaseType tv
= reservedWords
.get(reservedKeys
[i
]);
628 String type
= tv
.getTypeName();
629 sb
.append("\t").append(type
).append(" ").append(reservedKeys
[i
]).append(";\n");
633 String
[] eventKeys
= new String
[events
.size()];
635 for (String s
: events
.keySet()) {
639 Arrays
.sort(eventKeys
);
641 for (i
= 0; i
< eventKeys
.length
; ++i
) {
642 sb
.append(eventKeys
[i
]).append("\n{\n");
643 if (eventKeys
[i
] != null) {
644 Map
<String
, BaseType
> event
= events
.get(eventKeys
[i
]);
646 String
[] attributeKeys
= new String
[event
.size()];
647 for (Enumeration
<String
> att
= Collections
.enumeration(event
.keySet());
648 att
.hasMoreElements();) {
649 attributeKeys
[j
] = att
.nextElement();
652 Arrays
.sort(attributeKeys
);
654 for (j
= 0; j
< attributeKeys
.length
; ++j
) {
655 BaseType tv
= event
.get(attributeKeys
[j
]);
656 String type
= tv
.getTypeName();
657 sb
.append("\t").append(type
).append(" ").append(attributeKeys
[j
]).append(";\n");
662 return sb
.toString();
665 public String
toStringOneLine() {
666 return toString().replace("\n", " ");
670 * Creates a map of known types
672 private void initializeKnownTypes() {
673 /* initialize the list of known types */
674 knownTypes
.put(TypeID
.UINT16_STRING
, new BaseType(TypeID
.UINT16_STRING
,
675 TypeID
.UINT16_TOKEN
, 0));
676 knownTypes
.put(TypeID
.INT16_STRING
, new BaseType(TypeID
.INT16_STRING
,
677 TypeID
.INT16_TOKEN
, (short) 0));
678 knownTypes
.put(TypeID
.UINT32_STRING
, new BaseType(TypeID
.UINT32_STRING
,
679 TypeID
.UINT32_TOKEN
, (long) 0));
680 knownTypes
.put(TypeID
.INT32_STRING
, new BaseType(TypeID
.INT32_STRING
,
681 TypeID
.INT32_TOKEN
, 0));
682 knownTypes
.put(TypeID
.STRING_STRING
, new BaseType(TypeID
.STRING_STRING
,
683 TypeID
.STRING_TOKEN
, ""));
684 knownTypes
.put(TypeID
.IPADDR_STRING
, new BaseType(TypeID
.IPADDR_STRING
,
685 TypeID
.IPADDR_TOKEN
, new IPAddress()));
686 knownTypes
.put(TypeID
.INT64_STRING
, new BaseType(TypeID
.INT64_STRING
,
687 TypeID
.INT64_TOKEN
, (long) 0));
688 knownTypes
.put(TypeID
.UINT64_STRING
, new BaseType(TypeID
.UINT64_STRING
,
689 TypeID
.UINT64_TOKEN
, BigInteger
.ZERO
));
690 knownTypes
.put(TypeID
.BOOLEAN_STRING
, new BaseType(TypeID
.BOOLEAN_STRING
,
691 TypeID
.BOOLEAN_TOKEN
, true));
692 knownTypes
.put(TypeID
.STRING_ARRAY_STRING
,
693 new BaseType(TypeID
.STRING_ARRAY_STRING
,
694 TypeID
.STRING_ARRAY_TOKEN
, null));
695 knownTypes
.put(TypeID
.INT16_ARRAY_STRING
,
696 new BaseType(TypeID
.INT16_ARRAY_STRING
,
697 TypeID
.INT16_ARRAY_TOKEN
, null));
698 knownTypes
.put(TypeID
.INT32_ARRAY_STRING
,
699 new BaseType(TypeID
.INT32_ARRAY_STRING
,
700 TypeID
.INT32_ARRAY_TOKEN
, null));
701 knownTypes
.put(TypeID
.INT64_ARRAY_STRING
,
702 new BaseType(TypeID
.INT64_ARRAY_STRING
,
703 TypeID
.INT64_ARRAY_TOKEN
, null));
704 knownTypes
.put(TypeID
.UINT16_ARRAY_STRING
,
705 new BaseType(TypeID
.UINT16_ARRAY_STRING
,
706 TypeID
.UINT16_ARRAY_TOKEN
, null));
707 knownTypes
.put(TypeID
.UINT32_ARRAY_STRING
,
708 new BaseType(TypeID
.UINT32_ARRAY_STRING
,
709 TypeID
.UINT32_ARRAY_TOKEN
, null));
710 knownTypes
.put(TypeID
.UINT64_ARRAY_STRING
,
711 new BaseType(TypeID
.UINT64_ARRAY_STRING
,
712 TypeID
.UINT64_ARRAY_TOKEN
, null));
713 knownTypes
.put(TypeID
.BOOLEAN_ARRAY_STRING
,
714 new BaseType(TypeID
.BOOLEAN_ARRAY_STRING
,
715 TypeID
.BOOLEAN_ARRAY_TOKEN
, null));
716 knownTypes
.put(TypeID
.BYTE_ARRAY_STRING
,
717 new BaseType(TypeID
.BYTE_ARRAY_STRING
,
718 TypeID
.BYTE_ARRAY_TOKEN
, null));
719 knownTypes
.put(TypeID
.DOUBLE_ARRAY_STRING
,
720 new BaseType(TypeID
.DOUBLE_ARRAY_STRING
,
721 TypeID
.DOUBLE_ARRAY_TOKEN
, null));
722 knownTypes
.put(TypeID
.FLOAT_ARRAY_STRING
,
723 new BaseType(TypeID
.FLOAT_ARRAY_STRING
,
724 TypeID
.FLOAT_ARRAY_TOKEN
, null));
725 knownTypes
.put(TypeID
.DOUBLE_STRING
,
726 new BaseType(TypeID
.DOUBLE_STRING
,
727 TypeID
.DOUBLE_TOKEN
, null));
728 knownTypes
.put(TypeID
.FLOAT_STRING
,
729 new BaseType(TypeID
.FLOAT_STRING
,
730 TypeID
.FLOAT_TOKEN
, null));
733 public Map
<String
, BaseType
> getMetaFields() {
734 Map
<String
, BaseType
> m
= new TreeMap
<String
, BaseType
>();
735 m
.putAll(reservedWords
);
739 public Map
<String
, Map
<String
, BaseType
>> getEvents() {
740 Map
<String
, Map
<String
, BaseType
>> cp
= new TreeMap
<String
, Map
<String
, BaseType
>>();