001: package net.sf.saxon.trace;
002:
003: import net.sf.saxon.expr.XPathContext;
004: import net.sf.saxon.om.Item;
005:
006: import java.util.EventListener;
007:
008: /**
009: * A class which implements efficient and thread-safe multi-cast event
010: * dispatching for the TraceListener evants.
011: *
012: * Grabbed from java.awt.AWTEventMulticaster
013: */
014: public class TraceEventMulticaster implements TraceListener {
015:
016: protected final EventListener a, b;
017:
018: /**
019: * Creates an event multicaster instance which chains listener-a
020: * with listener-b.
021: * @param a listener-a
022: * @param b listener-b
023: */
024: protected TraceEventMulticaster(EventListener a, EventListener b) {
025: this .a = a;
026: this .b = b;
027: }
028:
029: /**
030: * Removes a listener from this multicaster and returns the
031: * resulting multicast listener.
032: * @param oldl the listener to be removed
033: */
034: protected EventListener remove(EventListener oldl) {
035: if (oldl == a)
036: return b;
037: if (oldl == b)
038: return a;
039: EventListener a2 = removeInternal(a, oldl);
040: EventListener b2 = removeInternal(b, oldl);
041: if (a2 == a && b2 == b) {
042: return this ; // it's not here
043: }
044: return addInternal(a2, b2);
045: }
046:
047: /**
048: * Called at start
049: */
050:
051: public void open() {
052: ((TraceListener) a).open();
053: ((TraceListener) b).open();
054: }
055:
056: /**
057: * Called at end
058: */
059:
060: public void close() {
061: ((TraceListener) a).close();
062: ((TraceListener) b).close();
063: }
064:
065: /**
066: * Called when an element of the stylesheet gets processed
067: */
068: public void enter(InstructionInfo element, XPathContext context) {
069: ((TraceListener) a).enter(element, context);
070: ((TraceListener) b).enter(element, context);
071: }
072:
073: /**
074: * Called after an element of the stylesheet got processed
075: */
076: public void leave(InstructionInfo element) {
077: ((TraceListener) a).leave(element);
078: ((TraceListener) b).leave(element);
079: }
080:
081: /**
082: * Called when an item becomes current
083: */
084: public void startCurrentItem(Item item) {
085: ((TraceListener) a).startCurrentItem(item);
086: ((TraceListener) b).startCurrentItem(item);
087: }
088:
089: /**
090: * Called when an item ceases to be the current item
091: */
092: public void endCurrentItem(Item item) {
093: ((TraceListener) a).endCurrentItem(item);
094: ((TraceListener) b).endCurrentItem(item);
095: }
096:
097: /**
098: * Adds trace-listener-a with trace-listener-b and
099: * returns the resulting multicast listener.
100: * @param a trace-listener-a
101: * @param b trace-listener-b
102: */
103: public static TraceListener add(TraceListener a, TraceListener b) {
104: return (TraceListener) addInternal(a, b);
105: }
106:
107: /**
108: * Removes the old trace-listener from trace-listener-l and
109: * returns the resulting multicast listener.
110: * @param l trace-listener-l
111: * @param oldl the trace-listener being removed
112: */
113: public static TraceListener remove(TraceListener l,
114: TraceListener oldl) {
115: return (TraceListener) removeInternal(l, oldl);
116: }
117:
118: /**
119: * Returns the resulting multicast listener from adding listener-a
120: * and listener-b together.
121: * If listener-a is null, it returns listener-b;
122: * If listener-b is null, it returns listener-a
123: * If neither are null, then it creates and returns
124: * a new EventMulticaster instance which chains a with b.
125: * @param a event listener-a
126: * @param b event listener-b
127: */
128: protected static EventListener addInternal(EventListener a,
129: EventListener b) {
130: if (a == null)
131: return b;
132: if (b == null)
133: return a;
134: return new TraceEventMulticaster(a, b);
135: }
136:
137: /**
138: * Returns the resulting multicast listener after removing the
139: * old listener from listener-l.
140: * If listener-l equals the old listener OR listener-l is null,
141: * returns null.
142: * Else if listener-l is an instance of SaxonEventMulticaster,
143: * then it removes the old listener from it.
144: * Else, returns listener l.
145: * @param l the listener being removed from
146: * @param oldl the listener being removed
147: */
148:
149: protected static EventListener removeInternal(EventListener l,
150: EventListener oldl) {
151: if (l == oldl || l == null) {
152: return null;
153: } else if (l instanceof TraceEventMulticaster) {
154: return ((TraceEventMulticaster) l).remove(oldl);
155: } else {
156: return l; // it's not here
157: }
158: }
159:
160: }
161:
162: // Contributor(s):
163: // This module is from Edwin Glaser (edwin@pannenleiter.de)
164: // Modified by MHK for Saxon 6.1 to remove "throws SAXException" from all methods
165: //
|