KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > controls > runtime > generator > AptEventSet


1 package org.apache.beehive.controls.runtime.generator;
2 /*
3  * Copyright 2004 The Apache Software Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * $Header:$
18  */

19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.HashSet JavaDoc;
23
24 import com.sun.mirror.declaration.InterfaceDeclaration;
25 import com.sun.mirror.declaration.MethodDeclaration;
26 import com.sun.mirror.declaration.TypeDeclaration;
27 import com.sun.mirror.declaration.TypeParameterDeclaration;
28 import com.sun.mirror.type.InterfaceType;
29
30 import org.apache.beehive.controls.api.events.EventSet;
31 import org.apache.beehive.controls.api.packaging.EventSetInfo;
32
33 import org.apache.beehive.controls.runtime.generator.apt.*;
34
35 /**
36  * The AptEventSet class represents a control EventSet where the events
37  * are derived using APT metadata.
38  */

39 public class AptEventSet extends AptType
40 {
41     /**
42      * Constructs a new AptEventSet instance from APT metadata
43      * @param controlIntf the declaring control interface
44      * @param eventSet the EventSet class
45      * @param ap the associated AnnotationProcessor
46      */

47     public AptEventSet(AptControlInterface controlIntf, InterfaceDeclaration eventSet,
48                        TwoPhaseAnnotationProcessor ap)
49     {
50         _controlIntf = controlIntf;
51         _eventSet = eventSet;
52         _ap = ap;
53         setDeclaration(eventSet);
54
55         EventSet eventSetAnnot = eventSet.getAnnotation(EventSet.class);
56         if (eventSetAnnot != null)
57             _unicast = eventSetAnnot.unicast();
58
59         //
60
// If an EventSet interface has formal type parameters, they must be a subset of
61
// the original formal type parameters declared on the original control interface.
62
// This is required because it must be possible to bind the types of events immediately
63
// upon construction of the bean... there is no opportunity to separately specify
64
// parameterization for the event set for the purpose of creating listeners, client
65
// notifiers, etc.
66
//
67
TypeDeclaration intfDecl = controlIntf.getTypeDeclaration();
68         for (TypeParameterDeclaration estpd : _eventSet.getFormalTypeParameters())
69         {
70             boolean found = false;
71             for (TypeParameterDeclaration citpd : intfDecl.getFormalTypeParameters())
72             {
73                 if (estpd.getSimpleName().equals(citpd.getSimpleName()))
74                 {
75                     found = true;
76                     break;
77                 }
78             }
79             if (! found)
80             {
81                 //
82
// BUGBUG: Ideally, this would be estpd.getPosition, but this seems to return
83
// 0,0 for the current APT implementation, so we use the event set position
84
// instead.
85
// Once this work, the 'break' below can also be removed to present errors
86
// for multiple invalid parameters
87
//
88

89                 _ap.printError( eventSet, "eventset.formal.parameter.mismatch" );
90                 break;
91             }
92         }
93          
94         _superEventSet = initSuperEventSet();
95
96         _events = initEvents();
97     }
98
99     /**
100      * Checks to see if this EventSet extends on declared on a parent control interface. If
101      * found it will return the parent EventSet, or return null if not found.
102      */

103     public AptEventSet initSuperEventSet()
104     {
105         // This will be common, so short circuit quickly
106
AptControlInterface superControl = _controlIntf.getSuperClass();
107         if (superControl == null)
108             return null;
109
110         // Compute a hash set containing the qualified names of all super interfaces
111
HashSet JavaDoc<String JavaDoc> extendNames = new HashSet JavaDoc<String JavaDoc>();
112         for (InterfaceType superType: _eventSet.getSuperinterfaces())
113         {
114             InterfaceDeclaration superDecl = superType.getDeclaration();
115             if (superDecl != null)
116                 extendNames.add(superDecl.getQualifiedName());
117         }
118
119         // Starting with the parent of the ControlInterface declaring this EventSet, look
120
// for a parent interface that declares ones of these super interfaces as an event
121
// set
122
while (superControl != null)
123         {
124             Collection JavaDoc<AptEventSet> superEventSets = superControl.getEventSets();
125             for (AptEventSet superEventSet : superEventSets)
126             {
127                 if (extendNames.contains(superEventSet.getClassName()))
128                     return superEventSet;
129             }
130
131             superControl = superControl.getSuperClass();
132         }
133
134         // Nothing found, so no super event set
135
return null;
136     }
137
138     /**
139      * Returns any EventSet from which this event set derives (or null if none)
140      */

141     public AptEventSet getSuperEventSet() { return _superEventSet; }
142
143     /**
144      * Initializes the list of Events associated with this EventSet
145      */

146     protected AptMethodSet<AptEvent> initEvents()
147     {
148         AptMethodSet<AptEvent> events = new AptMethodSet<AptEvent>();
149         if ( _eventSet == null || _eventSet.getMethods() == null )
150             return events;
151
152         //
153
// Add all of the public methods directly declared and inherited from extended
154
// interfaces, except for the EventSet super interface (if any)
155
//
156
ArrayList JavaDoc<InterfaceDeclaration> intfList = new ArrayList JavaDoc<InterfaceDeclaration>();
157         intfList.add(_eventSet);
158         for (int i = 0; i < intfList.size(); i++)
159         {
160             InterfaceDeclaration intfDecl = intfList.get(i);
161
162             //
163
// Don't add events that are derived from a super event set.
164
//
165
if (_superEventSet != null &&
166                 _superEventSet.getClassName().equals(intfDecl.getQualifiedName()))
167                 continue;
168
169             // Add all declared methods, but ignore the mystery <clinit> methods
170
for (MethodDeclaration methodDecl : intfDecl.getMethods())
171                 if (!methodDecl.toString().equals("<clinit>()"))
172                     events.add(new AptEvent(this, methodDecl, _ap));
173
174             //
175
// Add all superinterfaces of the target interface to the list
176
//
177
for (InterfaceType superType: intfDecl.getSuperinterfaces())
178             {
179                 InterfaceDeclaration superDecl = superType.getDeclaration();
180                 if (superDecl != null && !intfList.contains(superDecl))
181                     intfList.add(superDecl);
182             }
183         }
184
185         return events;
186     }
187
188     /**
189      * Returns the list of Events associated with this EventSet
190      */

191     public Collection JavaDoc<AptEvent> getEvents() { return _events.getMethods(); }
192
193     /**
194      * Returns 'true' if the event set support only unicast (single listener) events,
195      * false otherwise.
196      */

197     public boolean isUnicast()
198     {
199         return _unicast;
200     }
201
202     /**
203      * Returns the number of Events for this EventSet and any super event set
204      */

205     public int getEventCount()
206     {
207         int count = _events.size();
208         if (_superEventSet != null)
209             count += _superEventSet.getEventCount();
210         return count;
211     }
212
213     /**
214      * Returns the programmatic descriptor name to be returned by the EventDescriptor
215      * for the event set.
216      */

217     public String JavaDoc getDescriptorName()
218     {
219         //
220
// The javadocs for java.beans.EventSetDescriptor suggest that the programmatic name
221
// should start w/ a lowercase letter. So we use the unqualified event set interface
222
// name w/ the first character lowercased.
223
//
224
String JavaDoc name = getShortName();
225         return Character.toLowerCase(name.charAt(0)) + name.substring(1);
226     }
227
228     /**
229      * Returns the name of the generated notifier class for this ControlEventSet
230      */

231     public String JavaDoc getNotifierClass()
232     {
233         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(getShortName());
234         sb.append("Notifier");
235
236         //
237
// If the event set declaration has any parameterized types, then include them on
238
// the notifier class as well. Currently, these can only be parameterized types
239
// from the outer (control interface), since there is no other mechanism for specifying
240
// type values at notifier construction (other than propagation from the outer type).
241
//
242
sb.append(getFormalTypeParameterNames());
243         return sb.toString();
244     }
245
246     /**
247      * Returns any 'extends' clause that should be placed on the generated notifier class
248      */

249     public String JavaDoc getNotifierExtends()
250     {
251         //
252
// All EventNotifiers are rooted from a common utility class, so if there is no
253
// super event set, then extend the utility notifier class.
254
//
255
if (_superEventSet == null)
256         {
257             if (_unicast)
258                 return "org.apache.beehive.controls.runtime.bean.UnicastEventNotifier";
259             else
260                 return "org.apache.beehive.controls.runtime.bean.EventNotifier";
261         }
262
263         //
264
// Otherwise, a generated notifier will extend the notifier of any parent event set
265
//
266
return _superEventSet.getNotifierClass();
267     }
268
269     /**
270      * Returns the name of the method used to register a new EventSet listener
271      */

272     public String JavaDoc getAddListenerMethod()
273     {
274         return "add" + getShortName() + "Listener";
275     }
276
277     /**
278      * Returns the name of the method used to register a new EventSet listener
279      */

280     public String JavaDoc getRemoveListenerMethod()
281     {
282         return "remove" + getShortName() + "Listener";
283     }
284
285     /**
286      * Returns the name of the method used to retrieve the (unicast) EventSet listener
287      */

288     public String JavaDoc getGetListenersMethod()
289     {
290         return "get" + getShortName() + "Listeners";
291     }
292
293     /**
294      * Returns the name of a custom-generated method to initialize MethodDescriptor bean
295      * info for the events in this EventSet
296      */

297     public String JavaDoc getInfoInitializer()
298     {
299        return "init" + getShortName() + "Events";
300     }
301
302     /**
303      * Returns any EventSetInfo associated with the event set (or null if none)
304      */

305     public EventSetInfo getEventSetInfo()
306     {
307         if ( _eventSet == null )
308             return null;
309         
310         return _eventSet.getAnnotation(EventSetInfo.class);
311     }
312
313     /**
314      * Returns the underlying APT InterfaceDeclaration associated with this event set
315      */

316     public InterfaceDeclaration getDeclaration()
317     {
318         return _eventSet;
319     }
320
321     private TwoPhaseAnnotationProcessor _ap;
322     private InterfaceDeclaration _eventSet;
323     private AptEventSet _superEventSet;
324     private AptControlInterface _controlIntf;
325     private AptMethodSet<AptEvent> _events;
326     private boolean _unicast;
327 }
328
Popular Tags