3 import org
.lwes
.BaseType
;
4 import org
.lwes
.EventAttributeSizeException
;
5 import org
.lwes
.EventSystemException
;
6 import org
.lwes
.TypeID
;
7 import org
.lwes
.util
.IPAddress
;
8 import org
.lwes
.util
.Log
;
11 import java
.io
.InputStream
;
12 import java
.math
.BigInteger
;
13 import java
.util
.Arrays
;
14 import java
.util
.Collections
;
15 import java
.util
.Enumeration
;
17 import java
.util
.TreeMap
;
18 import java
.util
.concurrent
.ConcurrentHashMap
;
21 * Provides type checking for the event system. Also provides a place for
22 * globally accessible information.
24 * @author Anthony Molinaro
25 * @author Michael P. Lum
27 public class EventTemplateDB
{
29 * the meta event info inherent to every event
31 private static final String META_EVENT_INFO
= "MetaEventInfo";
34 * esfFile for this event system.
36 private File esfFile
= null;
37 private InputStream esfInputStream
= null;
42 private Map
<String
, Map
<String
, BaseType
>> events
= null;
43 private Map
<String
, BaseType
> knownTypes
= null;
44 private Map
<String
, BaseType
> reservedWords
= null;
47 * This is the EventTemplateDB constructor.
49 public EventTemplateDB() {
50 events
= new ConcurrentHashMap
<String
, Map
<String
, BaseType
>>();
51 knownTypes
= new ConcurrentHashMap
<String
, BaseType
>();
52 reservedWords
= new ConcurrentHashMap
<String
, BaseType
>();
53 initializeKnownTypes();
57 * Sets the Event Specification file for this system
59 * @param anEsfFile the ESF file for this system.
61 public void setESFFile(File anEsfFile
) {
66 * Gets the ESF file, in case you want to look at it
68 * @return the ESF file used in this system.
70 public File
getESFFile() {
75 * Sets the Event Specification file as an InputStream
77 * @param esfInputStream the InputStream representing an ESF file
79 public void setESFInputStream(InputStream esfInputStream
) {
80 this.esfInputStream
= esfInputStream
;
84 * Ges the ESF InputStream
86 * @return the ESF InputStream used in the system
88 public InputStream
getESFInputStream() {
89 return esfInputStream
;
93 * Initializes the EventTemplateDB, assumes that setESFFile() has been
96 * @return true if the EventTemplateDB initializes correctly; false if it
97 * does not. false means the event system is unable to perform validation
99 public synchronized boolean initialize() {
101 * Call the parser to parse the file. Any errors cause the
102 * initialization to fail.
106 if (getESFInputStream() != null) {
107 parser
= new ESFParser(getESFInputStream());
109 else if (getESFFile() != null) {
110 parser
= new ESFParser(
111 new java
.io
.FileInputStream(getESFFile()));
117 parser
.setEventTemplateDB(this);
120 catch (java
.io
.FileNotFoundException e
) {
121 Log
.warning("File not found ", e
);
124 * treat this as just a warning and allow things to continue, this
125 * allows an empty EventTemplateDB to work when type checking is
129 catch (ParseException e
) {
130 Log
.warning("Parser error in ESF file " + getESFFile(), e
);
133 catch (Exception e
) {
134 Log
.error("Error parsing ESF file " + getESFFile(), e
);
135 /* catch IO, NPEs and other exceptions but still continue */
143 * Add an Event to the EventTemplateDB
145 * @param anEventName the name of the Event to add
146 * @return true if the event was added, false if it was not
148 public synchronized boolean addEvent(String anEventName
) {
149 if (anEventName
== null) {
154 if (anEventName
.equals(META_EVENT_INFO
)) {
158 if (events
.containsKey(anEventName
)) {
159 Log
.info("Event " + anEventName
+ " already exists in event DB");
163 Map
<String
, BaseType
> evtHash
= new ConcurrentHashMap
<String
, BaseType
>();
164 if (!(reservedWords
.isEmpty())) {
165 /* insert reserved words into new event */
166 for (String key
: reservedWords
.keySet()) {
168 evtHash
.put(key
, reservedWords
.get(key
));
173 events
.put(anEventName
, evtHash
);
175 catch (Exception e
) {
176 Log
.warning("Error adding event to EventTemplateDB", e
);
182 public synchronized boolean addEventAttribute(String anEventName
,
183 String anAttributeName
,
184 String anAttributeType
) {
185 return addEventAttribute(anEventName
,
192 public synchronized boolean addEventAttribute(String anEventName
,
193 String anAttributeName
,
194 String anAttributeType
,
197 return addEventAttribute(anEventName
, anAttributeName
, anAttributeType
, size
, required
, null);
201 * Add an attribute to an Event in the EventTemplateDB
203 * @param anEventName the name of the event to add this attribute to
204 * @param anAttributeName the name of the attribute to add
205 * @param anAttributeType the type of the attribute, should be the name of the type
206 * given in the ESF Specification.
207 * @param size The size restriction for this attribute
208 * @param required Is this attribute required
209 * @return true if the attribute can be added, false if it can not.
211 public synchronized boolean addEventAttribute(String anEventName
,
212 String anAttributeName
,
213 String anAttributeType
,
216 Object defaultValue
) {
218 if (anEventName
== null || anAttributeName
== null || anAttributeType
== null) {
223 if (anEventName
.equals(META_EVENT_INFO
)) {
224 if (checkForType(anAttributeType
)) {
225 reservedWords
.put(anAttributeName
, knownTypes
.get(anAttributeType
));
229 Log
.info("Meta keyword " + anEventName
+ "." + anAttributeName
+
230 "has unknown type " + anAttributeType
+ ", skipping");
235 if (reservedWords
.containsKey(anEventName
)) {
236 Log
.warning("Unable to add attribute named " + anAttributeName
+
237 "as it is a reserved word, skipping");
241 if (events
.containsKey(anEventName
)) {
242 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
243 if (checkForType(anAttributeType
)) {
244 BaseType bt
= knownTypes
.get(anAttributeType
).cloneBaseType();
245 bt
.setRequired(required
);
246 bt
.setSizeRestriction(size
);
247 if (defaultValue
!= null) {
248 bt
.setDefaultValue(defaultValue
);
250 evtHash
.put(anAttributeName
, bt
);
254 Log
.warning("Type " + anAttributeType
+ " does not exist for " +
255 anAttributeName
+ ", skipping");
260 Log
.warning("No such event " + anEventName
+ ", skipping");
264 catch (Exception e
) {
265 Log
.error("Error adding attribute " + anAttributeName
+ " to " + anEventName
, e
);
271 * Returns an enumeration of all defined events
273 * @return an enumeration of all defined events
275 public Enumeration
<String
> getEventNames() {
276 return Collections
.enumeration(this.events
.keySet());
280 * Returns true if the type given by aTypeName is a valid type in the DB.
282 * @param aTypeName a type name according to the ESF Specification
283 * @return true if the type exists in the DB, false otherwise
285 public boolean checkForType(String aTypeName
) {
286 if (aTypeName
== null) {
289 return knownTypes
.containsKey(aTypeName
);
292 public void checkForSize(String eventName
,
293 String attributeName
,
294 BaseType attributeValue
) throws EventAttributeSizeException
{
296 if (!attributeValue
.getTypeName().startsWith("[L")) {
297 if (Log
.isLogDebug()) {
298 Log
.debug("value for attribute " + attributeName
+ " is not an array.");
303 Map
<String
, BaseType
> evtMap
= events
.get(eventName
);
304 if (evtMap
== null) {
305 Log
.error("event definition did not exist");
308 BaseType attrBaseType
= evtMap
.get(attributeName
);
309 if (attrBaseType
== null) {
310 Log
.error("attribute definition did not exist");
315 int size
= attrBaseType
.getSizeRestriction();
316 Object o
= attributeValue
.getTypeObject();
317 if (o
instanceof short[]) {
318 sizeToCheck
= ((short[])o
).length
;
320 else if (o
instanceof int[]) {
321 sizeToCheck
= ((int[])o
).length
;
323 else if (o
instanceof long[]) {
324 sizeToCheck
= ((long[])o
).length
;
326 else if (o
instanceof boolean[]) {
327 sizeToCheck
= ((boolean[])o
).length
;
329 else if (o
instanceof byte[]) {
330 sizeToCheck
= ((byte[])o
).length
;
333 Object
[] arr
= (Object
[]) attributeValue
.getTypeObject();
334 sizeToCheck
= arr
.length
;
336 if (Log
.isLogTrace()) {
337 Log
.trace("sizeToCheck: " + sizeToCheck
+ " size: " + size
);
339 if (size
> 0 && sizeToCheck
> size
) {
340 throw new EventAttributeSizeException(attributeName
, sizeToCheck
, size
);
345 * Checks to see if an Event exists in the EventTemplateDB
347 * @param anEventName the name of the event to check the existence of
348 * @return true if the event with the name <tt>anEventName</tt> exists in
349 * the EventTemplateDB, false otherwise.
351 public boolean checkForEvent(String anEventName
) {
352 if (anEventName
== null) {
355 return events
.containsKey(anEventName
);
359 * Checks to see if an attribute <tt>anAttributeName</tt> exists for the
360 * event <tt>anEventName</tt>
362 * @param anEventName the name of an Event
363 * @param anAttributeName the name of an attribute of Event to check
364 * @return true if the attribute exists as a member of event, false
367 public boolean checkForAttribute(String anEventName
, String anAttributeName
) {
368 if (anEventName
== null || anAttributeName
== null) {
372 if (checkForEvent(anEventName
)) {
373 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
374 return evtHash
.containsKey(anAttributeName
);
380 * Checks to see if the type of an attribute is proper. (i.e. if the given
381 * attribute of the given event has the same type assigned to it as the type
382 * of the given objects value)
384 * @param anEventName the name of an Event.
385 * @param anAttributeName the name of the attribute whose type is being checked
386 * @param anAttributeValue the Object containing the possible value of the attribute.
387 * @return true if the event and attribute exist and if the type of the
388 * attribute matches the type assigned to this attribute in the
389 * EventTemplateDB, false otherwise.
391 public boolean checkTypeForAttribute(String anEventName
,
392 String anAttributeName
,
393 Object anAttributeValue
) {
394 if (anEventName
== null || anAttributeName
== null || anAttributeValue
== null) {
398 if (checkForAttribute(anEventName
, anAttributeName
)) {
399 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
400 Object storedTypeObject
= evtHash
.get(anAttributeName
);
401 byte type1
= ((BaseType
) anAttributeValue
).getTypeToken();
402 byte type2
= ((BaseType
) storedTypeObject
).getTypeToken();
403 if (type1
== type2
) {
412 * Checks to see if the type of an attribute is proper. (i.e. if the given
413 * attribute of the given event has the same type assigned to it as the type
416 * @param anEventName the name of an Event.
417 * @param anAttributeName the name of the attribute whose type is being checked
418 * @param anAttributeType the String containing the possible type value of the
420 * @return true if the event and attribute exist and if the type of the
421 * attribute matches the type assigned to this attribute in the
422 * EventTemplateDB, false otherwise.
424 public boolean checkTypeForAttribute(String anEventName
,
425 String anAttributeName
, String anAttributeType
) {
426 if (anEventName
== null || anAttributeName
== null || anAttributeType
== null) {
430 if (checkForAttribute(anEventName
, anAttributeName
)) {
431 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
432 String storedTypeName
= evtHash
.get(anAttributeName
).getTypeName();
440 if (anAttributeType
.equals(storedTypeName
)) {
449 * Given an Object which is the attribute value of the attribute
450 * <tt>attributeName</tt> of event <tt>eventName</tt>, return the internal
451 * representation (i.e. <tt>BaseType</tt>) of this Object
453 * @param eventName the name of an Event.
454 * @param attributeName the name of an attribute of <tt>eventName</tt>
455 * @param attributeValue the value of the attribute
456 * @return the <tt>BaseType</tt> representation of <tt>attributeValue</tt>
458 public BaseType
getBaseTypeForObjectAttribute(String eventName
,
459 String attributeName
,
460 Object attributeValue
) {
461 if (eventName
== null || attributeName
== null || attributeValue
== null) {
465 Map
<String
, BaseType
> evtHash
= events
.get(eventName
);
466 BaseType tmpBaseType
= evtHash
.get(attributeName
);
467 BaseType retBaseType
= tmpBaseType
.cloneBaseType();
468 retBaseType
.setTypeObject(attributeValue
);
473 * Returns the base types for this event
476 * @return a map of event fields to base types
478 public Map
<String
, BaseType
> getBaseTypesForEvent(String eventName
) {
479 if (eventName
== null) {
483 Map
<String
, BaseType
> map
= events
.get(eventName
);
485 return map
== null ?
new ConcurrentHashMap
<String
, BaseType
>() : map
;
489 * Parses the string representation of an event attribute into the
490 * appropriate objectt.
492 * @param anEventName the name of an Event.
493 * @param anAttributeName the name of the attribute we are parsing
494 * @param stringAttributeValue a string representation of the value of the attribute given by
496 * @return the object represented by the string
497 * <tt>stringAttributeValue</tt>
499 public Object
parseAttribute(String anEventName
, String anAttributeName
,
500 String stringAttributeValue
) {
501 Object retObject
= null;
503 if (anEventName
== null || anAttributeName
== null || stringAttributeValue
== null) {
507 Log
.trace("parseAttribute: " + anEventName
+ "." + anAttributeName
+ "=" +
508 stringAttributeValue
);
510 if (checkForAttribute(anEventName
, anAttributeName
)) {
511 Log
.trace("parseAttribute: passed first if attribute exists");
513 Map
<String
, BaseType
> evtHash
= events
.get(anEventName
);
515 BaseType bt
= evtHash
.get(anAttributeName
);
517 throw new EventSystemException("Null BaseType for "
521 retObject
= bt
.parseFromString(stringAttributeValue
);
522 Log
.trace("parseAttribute: parsed " + retObject
);
524 catch (EventSystemException btpe
) {
525 Log
.error("Unable to parseAttribute", btpe
);
529 Log
.trace("parseAttribute: returning " + retObject
);
534 * Returns a HTML rendering of the EventTemplateDB
536 * @return HTML string of the EventTemplateDB
538 public String
toHtmlString() {
539 StringBuffer sb
= new StringBuffer();
540 sb
.append("<table>\n");
541 sb
.append("<tr><th>" + META_EVENT_INFO
542 + "</th><th>Type</th><th>Name</th></tr>\n");
543 for (String key
: reservedWords
.keySet()) {
544 BaseType tv
= reservedWords
.get(key
);
545 String type
= tv
.getTypeName();
546 sb
.append("<tr><td></td><td>").append(type
).append("</td><td>").append(key
).append("</td></tr>\n");
548 for (String EventKey
: events
.keySet()) {
549 sb
.append("<tr><th>").append(EventKey
).append("</th><th>Type</th><th>Name</th></tr>\n");
550 if (EventKey
!= null) {
551 Map
<String
, BaseType
> event
= events
.get(EventKey
);
552 for (Enumeration
<String
> att
= Collections
.enumeration(event
.keySet()); att
553 .hasMoreElements();) {
554 String key
= att
.nextElement();
555 BaseType tv
= event
.get(key
);
556 String type
= tv
.getTypeName();
557 sb
.append("<tr><td></td><td>")
560 .append(key
).append("</td></tr>\n");
565 sb
.append("</table>\n");
566 return sb
.toString();
571 * Returns a rather long string Representation of the EventTemplateDB
573 * @return a string Representation of the EventTemplateDB
575 public String
toString() {
576 StringBuffer sb
= new StringBuffer();
577 sb
.append("\n" + META_EVENT_INFO
+ "\n{\n");
578 String
[] reservedKeys
= new String
[reservedWords
.size()];
581 for (String s1
: reservedWords
.keySet()) {
582 reservedKeys
[i
] = s1
;
585 Arrays
.sort(reservedKeys
);
587 for (i
= 0; i
< reservedKeys
.length
; ++i
) {
588 BaseType tv
= reservedWords
.get(reservedKeys
[i
]);
589 String type
= tv
.getTypeName();
590 sb
.append("\t").append(type
).append(" ").append(reservedKeys
[i
]).append(";\n");
594 String
[] eventKeys
= new String
[events
.size()];
596 for (String s
: events
.keySet()) {
600 Arrays
.sort(eventKeys
);
602 for (i
= 0; i
< eventKeys
.length
; ++i
) {
603 sb
.append(eventKeys
[i
]).append("\n{\n");
604 if (eventKeys
[i
] != null) {
605 Map
<String
, BaseType
> event
= events
.get(eventKeys
[i
]);
607 String
[] attributeKeys
= new String
[event
.size()];
608 for (Enumeration
<String
> att
= Collections
.enumeration(event
.keySet());
609 att
.hasMoreElements();) {
610 attributeKeys
[j
] = att
.nextElement();
613 Arrays
.sort(attributeKeys
);
615 for (j
= 0; j
< attributeKeys
.length
; ++j
) {
616 BaseType tv
= event
.get(attributeKeys
[j
]);
617 String type
= tv
.getTypeName();
618 sb
.append("\t").append(type
).append(" ").append(attributeKeys
[j
]).append(";\n");
623 return sb
.toString();
627 * Creates a map of known types
629 private void initializeKnownTypes() {
630 /* initialize the list of known types */
631 knownTypes
.put(TypeID
.UINT16_STRING
, new BaseType(TypeID
.UINT16_STRING
,
632 TypeID
.UINT16_TOKEN
, 0));
633 knownTypes
.put(TypeID
.INT16_STRING
, new BaseType(TypeID
.INT16_STRING
,
634 TypeID
.INT16_TOKEN
, (short) 0));
635 knownTypes
.put(TypeID
.UINT32_STRING
, new BaseType(TypeID
.UINT32_STRING
,
636 TypeID
.UINT32_TOKEN
, (long) 0));
637 knownTypes
.put(TypeID
.INT32_STRING
, new BaseType(TypeID
.INT32_STRING
,
638 TypeID
.INT32_TOKEN
, 0));
639 knownTypes
.put(TypeID
.STRING_STRING
, new BaseType(TypeID
.STRING_STRING
,
640 TypeID
.STRING_TOKEN
, ""));
641 knownTypes
.put(TypeID
.IPADDR_STRING
, new BaseType(TypeID
.IPADDR_STRING
,
642 TypeID
.IPADDR_TOKEN
, new IPAddress()));
643 knownTypes
.put(TypeID
.INT64_STRING
, new BaseType(TypeID
.INT64_STRING
,
644 TypeID
.INT64_TOKEN
, (long) 0));
645 knownTypes
.put(TypeID
.UINT64_STRING
, new BaseType(TypeID
.UINT64_STRING
,
646 TypeID
.UINT64_TOKEN
, BigInteger
.ZERO
));
647 knownTypes
.put(TypeID
.BOOLEAN_STRING
, new BaseType(TypeID
.BOOLEAN_STRING
,
648 TypeID
.BOOLEAN_TOKEN
, true));
649 knownTypes
.put(TypeID
.STRING_ARRAY_STRING
,
650 new BaseType(TypeID
.STRING_ARRAY_STRING
,
651 TypeID
.STRING_ARRAY_TOKEN
, null));
652 knownTypes
.put(TypeID
.INT16_ARRAY_STRING
,
653 new BaseType(TypeID
.INT16_ARRAY_STRING
,
654 TypeID
.INT16_ARRAY_TOKEN
, null));
655 knownTypes
.put(TypeID
.INT32_ARRAY_STRING
,
656 new BaseType(TypeID
.INT32_ARRAY_STRING
,
657 TypeID
.INT32_ARRAY_TOKEN
, null));
658 knownTypes
.put(TypeID
.INT64_ARRAY_STRING
,
659 new BaseType(TypeID
.INT64_ARRAY_STRING
,
660 TypeID
.INT64_ARRAY_TOKEN
, null));
661 knownTypes
.put(TypeID
.UINT16_ARRAY_STRING
,
662 new BaseType(TypeID
.UINT16_ARRAY_STRING
,
663 TypeID
.UINT16_ARRAY_TOKEN
, null));
664 knownTypes
.put(TypeID
.UINT32_ARRAY_STRING
,
665 new BaseType(TypeID
.UINT32_ARRAY_STRING
,
666 TypeID
.UINT32_ARRAY_TOKEN
, null));
667 knownTypes
.put(TypeID
.UINT64_ARRAY_STRING
,
668 new BaseType(TypeID
.UINT64_ARRAY_STRING
,
669 TypeID
.UINT64_ARRAY_TOKEN
, null));
670 knownTypes
.put(TypeID
.BOOLEAN_ARRAY_STRING
,
671 new BaseType(TypeID
.BOOLEAN_ARRAY_STRING
,
672 TypeID
.BOOLEAN_ARRAY_TOKEN
, null));
673 knownTypes
.put(TypeID
.BYTE_ARRAY_STRING
,
674 new BaseType(TypeID
.BYTE_ARRAY_STRING
,
675 TypeID
.BYTE_ARRAY_TOKEN
, null));
678 public Map
<String
, BaseType
> getMetaFields() {
679 Map
<String
, BaseType
> m
= new TreeMap
<String
, BaseType
>();
680 m
.putAll(reservedWords
);
684 public Map
<String
, Map
<String
, BaseType
>> getEvents() {
685 Map
<String
, Map
<String
, BaseType
>> cp
= new TreeMap
<String
, Map
<String
, BaseType
>>();