KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > event > EventProducer


1 /*
2  * Copyright(C) 2001 Mika Riekkinen, Joni Suominen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or(at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package alt.jiapi.event;
20
21 import alt.jiapi.Rule;
22
23 /**
24  * Base class for event producers.
25  *
26  * @author Mika Riekkinen
27  * @author Joni Suominen
28  * @version $Revision: 1.9 $ $Date: 2004/03/22 09:04:17 $
29  */

30 public class EventProducer {
31     private String JavaDoc[] resolutions;
32     private Rule[] rules;
33
34     /**
35      * IdentityList is used for locks to avoid StackOverflow
36      * in cases where the lock object implements hashCode method
37      * which has been instrumented.
38      */

39     private IdentityList locks = new IdentityList();
40
41     /**
42      * Empty constructor. This constructor will set up resolution
43      * to its default value "*".
44      */

45     public EventProducer() {
46         this(new String JavaDoc[] {"*"});
47     }
48
49     /**
50      * This constructor will set up resolution to given value.
51      *
52      * @param resolution A resolution that is to be used.
53      */

54     public EventProducer(String JavaDoc resolution) {
55         this(new String JavaDoc[] {resolution});
56     }
57
58     /**
59      * This constructor will set up resolution to given values.
60      *
61      * @param resolution A resolutions that is to be used.
62      */

63     public EventProducer(String JavaDoc[] resolutions) {
64         this.resolutions = resolutions;
65         this.rules = new Rule[resolutions.length];
66
67         for (int i = 0; i < rules.length; i++) {
68             try {
69                 rules[i] = new Rule(resolutions[i]);
70             }
71             catch(Exception JavaDoc e) {
72                 System.out.println("Invalid rule: " + e);
73             }
74         }
75     }
76
77
78     /**
79      * Matches a given String into resolution String this EventProducer has.
80      * If at least one resolution matches, a true is returned.
81      */

82     public boolean match(String JavaDoc s) {
83         for (int i = 0; i < rules.length; i++) {
84             if (rules[i].match(s) == true) {
85                 return true;
86             }
87         }
88
89         return false;
90     }
91
92
93     /**
94      * Get the resolutions of this EventProducer.
95      *
96      * @return An array of Strings. Each String represents one
97      * resolution String, that is used in matching.
98      */

99     public String JavaDoc[] getResolutions() {
100         return resolutions;
101     }
102
103     /**
104      * Checks whether a given sourceObject is in protected mode.
105      * if sourceObject is in protected mode, corresponding JiapiEvent
106      * should not be fired.
107      *
108      * @param sourceObject sourceObject to check
109      */

110     public boolean isProtected(Object JavaDoc sourceObject) {
111         return locks.contains(sourceObject);
112     }
113
114     /**
115      * Checks whether a given JiapiEvent is in protected mode.
116      * if JiapiEvent is in protected mode, that event should not
117      * be fired.
118      *
119      * @param je JiapiEvent to check
120      */

121     public boolean isProtected(JiapiEvent je) {
122         Object JavaDoc sourceObject = je.getSourceObject();
123         return locks.contains(sourceObject);
124     }
125
126     /**
127      * This method protects application from entering into
128      * recursive event loop. This situation may occur, if a method
129      * has been instrumented, and instrumentation produces an
130      * event. If that method is called, directly or indirectly,
131      * with the aid of JiapiEvent, application will enter to an
132      * endless event loop, eventually crashing Virtual Machine.<p>
133      *
134      * Calling this method prevents <code>EventProducer</code>
135      * from producing further events for the same sourceObject.
136      * This protection mechanism allows applications to call
137      * methods of sourceObject and targetObject without worrying
138      * about event loops.<p>
139      *
140      * To enable events again, one will have to release
141      * <code>EventProducer</code> with method <code>release</code>.<p>
142      *
143      * @see #release(JiapiEvent)
144      * @see JiapiEvent#protect()
145      */

146     public void protect(JiapiEvent je) {
147         Object JavaDoc sourceObject = je.getSourceObject();
148         locks.add(sourceObject);
149     }
150
151     /**
152      * This method releases <code>EventProducer</code> so, that
153      * it is able to produce more events for the sourceObject.
154      *
155      * @see #protect(JiapiEvent)
156      * @see JiapiEvent#release()
157      */

158     public void release(JiapiEvent je) {
159         Object JavaDoc sourceObject = je.getSourceObject();
160         locks.remove(sourceObject);
161     }
162 }
163
164 /**
165  * A List-like implementation where reference-equality is used instead
166  * of object-equality (i.e. == instead of equals()).
167  * <p>
168  * Since only a partial List functionality is needed it was easier
169  * (and safer) not to implement a List or extend AbstractList. This
170  * way we don't have to care how the unused methods use the
171  * entries in the set.
172  */

173 class IdentityList {
174     private Object JavaDoc []elementData;
175     private int elementCount;
176
177     public IdentityList() {
178         elementData = new Object JavaDoc[10];
179         elementCount = 0;
180     }
181
182     public synchronized void add(Object JavaDoc o) {
183         checkCapacity();
184         elementData[elementCount++] = o;
185     }
186
187     public synchronized void remove(Object JavaDoc o) {
188         int index = indexOf(o);
189
190         if (index != -1) {
191             removeElementAt(index);
192         }
193     }
194
195     public synchronized boolean contains(Object JavaDoc o) {
196         return indexOf(o) >= 0;
197     }
198
199     private int indexOf(Object JavaDoc o) {
200         for (int i = 0; i < elementCount; i++) {
201             if (o == elementData[i]) {
202                 return i;
203             }
204         }
205         
206         return -1;
207     }
208
209     private void removeElementAt(int index) {
210         if (index >= elementCount) {
211             throw new ArrayIndexOutOfBoundsException JavaDoc(index + " >= " +
212                                                      elementCount);
213         }
214         else if (index < 0) {
215             throw new ArrayIndexOutOfBoundsException JavaDoc(index);
216         }
217
218         int j = elementCount - index - 1;
219         if (j > 0) {
220             System.arraycopy(elementData, index + 1, elementData, index, j);
221         }
222
223         elementCount--;
224         elementData[elementCount] = null;
225     }
226
227     private void checkCapacity() {
228         int curCapacity = elementData.length;
229         if (elementCount >= curCapacity) {
230             Object JavaDoc oldData[] = elementData;
231             int newCapacity = curCapacity * 2;
232             elementData = new Object JavaDoc[newCapacity];
233             System.arraycopy(oldData, 0, elementData, 0, elementCount);
234         }
235     }
236 }
237
Popular Tags