last hooks for getting default values set
[lwes-java.git] / src / main / java / org / lwes / db / EventTemplateDB.java
blobd09855bfbb95cd0dbf3dd834b10f0d8b0e574fa4
1 package org.lwes.db;
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;
10 import java.io.File;
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;
16 import java.util.Map;
17 import java.util.TreeMap;
18 import java.util.concurrent.ConcurrentHashMap;
20 /**
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 {
28 /**
29 * the meta event info inherent to every event
31 private static final String META_EVENT_INFO = "MetaEventInfo";
33 /**
34 * esfFile for this event system.
36 private File esfFile = null;
37 private InputStream esfInputStream = null;
39 /**
40 * System Attributes
42 private Map<String, Map<String, BaseType>> events = null;
43 private Map<String, BaseType> knownTypes = null;
44 private Map<String, BaseType> reservedWords = null;
46 /**
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();
56 /**
57 * Sets the Event Specification file for this system
59 * @param anEsfFile the ESF file for this system.
61 public void setESFFile(File anEsfFile) {
62 esfFile = anEsfFile;
65 /**
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() {
71 return esfFile;
74 /**
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;
83 /**
84 * Ges the ESF InputStream
86 * @return the ESF InputStream used in the system
88 public InputStream getESFInputStream() {
89 return esfInputStream;
92 /**
93 * Initializes the EventTemplateDB, assumes that setESFFile() has been
94 * called.
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.
104 ESFParser parser;
105 try {
106 if (getESFInputStream() != null) {
107 parser = new ESFParser(getESFInputStream());
109 else if (getESFFile() != null) {
110 parser = new ESFParser(
111 new java.io.FileInputStream(getESFFile()));
113 else {
114 return false;
117 parser.setEventTemplateDB(this);
118 parser.eventlist();
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
126 * turned off
129 catch (ParseException e) {
130 Log.warning("Parser error in ESF file " + getESFFile(), e);
131 return false;
133 catch (Exception e) {
134 Log.error("Error parsing ESF file " + getESFFile(), e);
135 /* catch IO, NPEs and other exceptions but still continue */
136 return false;
139 return true;
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) {
150 return false;
153 try {
154 if (anEventName.equals(META_EVENT_INFO)) {
155 return true;
158 if (events.containsKey(anEventName)) {
159 Log.info("Event " + anEventName + " already exists in event DB");
160 return false;
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()) {
167 if (key != null) {
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);
179 return true;
182 public synchronized boolean addEventAttribute(String anEventName,
183 String anAttributeName,
184 String anAttributeType) {
185 return addEventAttribute(anEventName,
186 anAttributeName,
187 anAttributeType,
189 false);
192 public synchronized boolean addEventAttribute(String anEventName,
193 String anAttributeName,
194 String anAttributeType,
195 Integer size,
196 boolean required) {
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,
214 Integer size,
215 boolean required,
216 Object defaultValue) {
218 if (anEventName == null || anAttributeName == null || anAttributeType == null) {
219 return false;
222 try {
223 if (anEventName.equals(META_EVENT_INFO)) {
224 if (checkForType(anAttributeType)) {
225 reservedWords.put(anAttributeName, knownTypes.get(anAttributeType));
226 return true;
228 else {
229 Log.info("Meta keyword " + anEventName + "." + anAttributeName +
230 "has unknown type " + anAttributeType + ", skipping");
231 return false;
235 if (reservedWords.containsKey(anEventName)) {
236 Log.warning("Unable to add attribute named " + anAttributeName +
237 "as it is a reserved word, skipping");
238 return false;
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);
251 return true;
253 else {
254 Log.warning("Type " + anAttributeType + " does not exist for " +
255 anAttributeName + ", skipping");
256 return false;
259 else {
260 Log.warning("No such event " + anEventName + ", skipping");
261 return false;
264 catch (Exception e) {
265 Log.error("Error adding attribute " + anAttributeName + " to " + anEventName, e);
266 return false;
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) {
287 return false;
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.");
300 return;
303 Map<String, BaseType> evtMap = events.get(eventName);
304 if (evtMap == null) {
305 Log.error("event definition did not exist");
306 return;
308 BaseType attrBaseType = evtMap.get(attributeName);
309 if (attrBaseType == null) {
310 Log.error("attribute definition did not exist");
311 return;
314 int sizeToCheck = 0;
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;
332 else {
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) {
353 return false;
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
365 * otherwise
367 public boolean checkForAttribute(String anEventName, String anAttributeName) {
368 if (anEventName == null || anAttributeName == null) {
369 return false;
372 if (checkForEvent(anEventName)) {
373 Map<String, BaseType> evtHash = events.get(anEventName);
374 return evtHash.containsKey(anAttributeName);
376 return false;
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) {
395 return false;
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) {
404 return true;
408 return false;
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
414 * given)
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
419 * attribute.
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) {
427 return false;
430 if (checkForAttribute(anEventName, anAttributeName)) {
431 Map<String, BaseType> evtHash = events.get(anEventName);
432 String storedTypeName = evtHash.get(anAttributeName).getTypeName();
433 System.out
434 .println("attr: " +
435 anAttributeName +
436 " stored: " +
437 storedTypeName +
438 " passed in: " +
439 anAttributeType);
440 if (anAttributeType.equals(storedTypeName)) {
441 return true;
445 return false;
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) {
462 return null;
465 Map<String, BaseType> evtHash = events.get(eventName);
466 BaseType tmpBaseType = evtHash.get(attributeName);
467 BaseType retBaseType = tmpBaseType.cloneBaseType();
468 retBaseType.setTypeObject(attributeValue);
469 return retBaseType;
473 * Returns the base types for this event
475 * @param eventName
476 * @return a map of event fields to base types
478 public Map<String, BaseType> getBaseTypesForEvent(String eventName) {
479 if (eventName == null) {
480 return 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
495 * anAttributeName.
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) {
504 return 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);
514 try {
515 BaseType bt = evtHash.get(anAttributeName);
516 if (bt == null) {
517 throw new EventSystemException("Null BaseType for "
518 + anAttributeName);
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);
530 return 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>")
558 .append(type)
559 .append("</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()];
579 int i = 0, j = 0;
581 for (String s1 : reservedWords.keySet()) {
582 reservedKeys[i] = s1;
583 ++i;
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");
592 sb.append("}\n");
594 String[] eventKeys = new String[events.size()];
595 i = 0;
596 for (String s : events.keySet()) {
597 eventKeys[i] = s;
598 ++i;
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]);
606 j = 0;
607 String[] attributeKeys = new String[event.size()];
608 for (Enumeration<String> att = Collections.enumeration(event.keySet());
609 att.hasMoreElements();) {
610 attributeKeys[j] = att.nextElement();
611 ++j;
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");
621 sb.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);
681 return m;
684 public Map<String, Map<String, BaseType>> getEvents() {
685 Map<String, Map<String, BaseType>> cp = new TreeMap<String, Map<String, BaseType>>();
686 cp.putAll(events);
687 return cp;