KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > aspects > gui > ViewControlWrapper


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

18
19 package org.objectweb.jac.aspects.gui;
20
21 import java.util.Arrays JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29 import java.util.WeakHashMap JavaDoc;
30 import org.aopalliance.intercept.ConstructorInvocation;
31 import org.aopalliance.intercept.MethodInvocation;
32 import org.apache.log4j.Logger;
33 import org.objectweb.jac.core.AspectComponent;
34 import org.objectweb.jac.core.Interaction;
35 import org.objectweb.jac.core.Wrappee;
36 import org.objectweb.jac.core.Wrapper;
37 import org.objectweb.jac.core.Wrapping;
38 import org.objectweb.jac.core.rtti.CollectionItem;
39 import org.objectweb.jac.core.rtti.FieldItem;
40 import org.objectweb.jac.core.rtti.MemberItem;
41 import org.objectweb.jac.core.rtti.MethodItem;
42 import org.objectweb.jac.util.Strings;
43
44 /**
45  * This wrapper updates the views of a given object when its state
46  * changes, that is to say when a write method is called on the
47  * wrappee.<p>
48  *
49  * A view controller can control several views of the same wrappee at
50  * the same time.<p>
51  *
52  * This mecanism is similar to the famous MVC design pattern. The
53  * model is the wrappee and the controller is the wrapper.<p>
54  *
55  * @see View
56  * @see #registerObject(Wrappee,ObjectUpdate,Object)
57  * @see #registerField(Wrappee,FieldItem,FieldUpdate,Object)
58  * @see #registerCollection(Wrappee,CollectionItem,CollectionUpdate,Object)
59  * @see #unregisterObject(Wrappee,ObjectUpdate)
60  * @see #unregisterField(Wrappee,FieldItem,FieldUpdate)
61  * @see #unregisterCollection(Wrappee,CollectionItem,CollectionUpdate)
62  */

63
64 public class ViewControlWrapper extends Wrapper {
65     static Logger logger = Logger.getLogger("gui.viewcontrol");
66     static Logger loggerReg = Logger.getLogger("gui.register");
67
68     // FieldItem -> (FieldUpdate -> param) (clients to notify for each field)
69
WeakHashMap JavaDoc fieldClients = new WeakHashMap JavaDoc();
70     // MethodItem -> (MethodUpdate -> param) (clients to notify for each method)
71
WeakHashMap JavaDoc methodClients = new WeakHashMap JavaDoc();
72     // FieldItem -> (CollectionUpdate -> param) (clients to notify for each collection)
73
WeakHashMap JavaDoc collectionClients = new WeakHashMap JavaDoc();
74     // ObjectUpdate -> param (clients to notify when the wrappee's state is modified)
75
WeakHashMap JavaDoc objectClients = new WeakHashMap JavaDoc();
76
77     // FieldItem -> (FieldUpdate -> param) (clients to notify for each field)
78
//Hashtable allFieldClients = new Hashtable();
79
// MethodItem -> (MethodUpdate -> param) (clients to notify for each method)
80
static Hashtable JavaDoc allMethodClients = new Hashtable JavaDoc();
81     // FieldItem -> (CollectionUpdate -> param) (clients to notify for each collection)
82
//Hashtable allCollectionClients = new Hashtable();
83
// ObjectUpdate -> param (clients to notify when the wrappee's state is modified)
84
//HashMap allObjectClients = new HashMap();
85

86     /**
87      * Creates an empty view control wrapper.<p>
88      */

89     public ViewControlWrapper(AspectComponent ac) {
90         super(ac);
91     }
92
93     /**
94      * Register for a fieldUpdated event.<p>
95      *
96      * @param wrappee
97      * @param field the field whose updates must be notified
98      * @param client the object to notify when the field is updated
99      * @param param
100      * @see #unregisterField(Wrappee,FieldItem,FieldUpdate)
101      */

102     public void registerField(
103         Wrappee wrappee,
104         FieldItem field,
105         FieldUpdate client,
106         Object JavaDoc param) {
107         Map JavaDoc clients = (Map JavaDoc) fieldClients.get(field.getName());
108         if (clients == null) {
109             clients = new HashMap JavaDoc();
110             fieldClients.put(field.getName(), clients);
111         }
112         clients.put(client, param);
113         loggerReg.debug(
114             "registerField(" + Strings.hex(client)
115             + ") on " + Strings.hex(wrappee) + "." + field.getName());
116     }
117
118     /**
119      * Unregister from a fieldUpdated event.<p>
120      *
121      * @param field the field whose updates must not be notified anymore
122      * @param client the object not to notify anymore
123      * @see #registerField(Wrappee,FieldItem,FieldUpdate,Object)
124      */

125     public void unregisterField(
126         Wrappee wrappee,
127         FieldItem field,
128         FieldUpdate client) {
129         Map JavaDoc clients = (Map JavaDoc) fieldClients.get(field.getName());
130         if (clients != null) {
131             loggerReg.debug("unregisterField("
132                     + Strings.hex(client)
133                     + ") on "
134                     + Strings.hex(wrappee)
135                     + "."
136                     + field.getName());
137             clients.remove(client);
138         }
139     }
140
141     /**
142      * Register for a collectionUpdated event.<p>
143      *
144      * @param collection the collection whose updates must be notified
145      * @param client the object to notify when the field is updated
146      * @see #unregisterCollection(Wrappee,CollectionItem,CollectionUpdate)
147      */

148     public void registerCollection(
149         Wrappee wrappee,
150         CollectionItem collection,
151         CollectionUpdate client,
152         Object JavaDoc param) {
153         Map JavaDoc clients = (Map JavaDoc) collectionClients.get(collection.getName());
154         if (clients == null) {
155             clients = new HashMap JavaDoc();
156             collectionClients.put(collection.getName(), clients);
157         }
158         clients.put(client, param);
159         loggerReg.debug("registerCollection("
160                 + Strings.hex(client)
161                 + ") on "
162                 + Strings.hex(wrappee)
163                 + "."
164                 + collection.getName());
165     }
166
167     /**
168      * Unregister from a collectionUpdated event.<p>
169      *
170      * @param collection the collection whose updates must not be notified anymore
171      * @param client the object not to notify anymore
172      * @see #registerCollection(Wrappee,CollectionItem,CollectionUpdate,Object)
173      */

174
175     public void unregisterCollection(
176         Wrappee wrappee,
177         CollectionItem collection,
178         CollectionUpdate client) {
179         Map JavaDoc clients = (Map JavaDoc) collectionClients.get(collection.getName());
180         if (clients != null) {
181             loggerReg.debug("unregisterCollection("
182                     + Strings.hex(client)
183                     + ") on "
184                     + Strings.hex(wrappee)
185                     + "."
186                     + collection.getName());
187             clients.remove(client);
188         }
189     }
190
191     /**
192      * Register for a fieldUpdated event.<p>
193      *
194      * @param wrappee
195      * @param method the method whose updates must be notified
196      * @param client the object to notify when the field is updated
197      * @param param
198      * @see #unregisterField(Wrappee,FieldItem,FieldUpdate)
199      */

200     public void registerMethod(
201         Wrappee wrappee,
202         MethodItem method,
203         MethodUpdate client,
204         Object JavaDoc param) {
205         String JavaDoc key = method.getFullName();
206         Map JavaDoc clients = (Map JavaDoc) methodClients.get(key);
207         if (clients == null) {
208             clients = new HashMap JavaDoc();
209             methodClients.put(key, clients);
210         }
211         clients.put(client, param);
212
213         clients = (Map JavaDoc) allMethodClients.get(key);
214         if (clients == null) {
215             clients = new HashMap JavaDoc();
216             allMethodClients.put(key, clients);
217         }
218         clients.put(client, param);
219
220         loggerReg.debug("registerMethod("
221                 + Strings.hex(client)
222                 + ") on "
223                 + Strings.hex(wrappee)
224                 + "."
225                 + key);
226     }
227
228     public void unregisterMethod(
229         Wrappee wrappee,
230         MethodItem method,
231         MethodUpdate client) {
232         String JavaDoc key = method.getFullName();
233         Map JavaDoc clients = (Map JavaDoc) methodClients.get(key);
234         if (clients != null) {
235             loggerReg.debug("unregisterMethod("
236                     + Strings.hex(client)
237                     + ") on "
238                     + Strings.hex(wrappee)
239                     + "."
240                     + method.getName());
241             clients.remove(client);
242         }
243         clients = (Map JavaDoc) allMethodClients.get(key);
244         if (clients != null) {
245             clients.remove(client);
246         }
247     }
248
249     /**
250      * Register for an objectUpdated event.
251      *
252      * @param client whom to notify when the wrappee is updated
253      * @param param an object that will be passed back to client on
254      * each notification event.
255      */

256     public void registerObject(
257         Wrappee wrappee,
258         ObjectUpdate client,
259         Object JavaDoc param) {
260         loggerReg.debug(
261             "registerObject " + Strings.hex(client) +
262             " on " + Strings.hex(wrappee));
263         objectClients.put(client, param);
264     }
265
266     /**
267      * Unregister from an objectUpdated event.
268      *
269      * @param client whom not to notify anymore
270      */

271     public void unregisterObject(Wrappee wrappee, ObjectUpdate client) {
272         loggerReg.debug(
273             "unregisterObject(" + Strings.hex(client)
274             + ") on " + Strings.hex(wrappee));
275         objectClients.remove(client);
276     }
277
278     /**
279      * Unregister a client from all update events
280      * @param wrappee the object to unregister from
281      * @param client the client to unregister
282      */

283     public void unregister(Wrappee wrappee, Object JavaDoc client) {
284         loggerReg.debug("unregister(" + Strings.hex(client)
285                         + ") on " + Strings.hex(wrappee));
286         objectClients.remove(client);
287         Iterator JavaDoc i;
288         i = fieldClients.values().iterator();
289         while (i.hasNext()) {
290             Map JavaDoc clients = (Map JavaDoc) i.next();
291             clients.remove(client);
292         }
293
294         i = collectionClients.values().iterator();
295         while (i.hasNext()) {
296             Map JavaDoc clients = (Map JavaDoc) i.next();
297             clients.remove(client);
298         }
299     }
300
301     /**
302      * Get the views controlled by this wrapper.<p>
303      *
304      * @return the set of controlled views
305      */

306
307     /*
308     public Vector getViews() {
309        return controlledViews;
310     }
311     */

312
313     /**
314      * A wrapping method that updates the views of the objects.<p>
315      *
316      * It uses the RTTI aspect to know the fields and the collections
317      * that are written, added, or removed by the currently wrapped
318      * method. Then it upcall the <code>refreshStateComponent</code> of
319      * all the controlled views to refresh the implied GUI
320      * components.<p>
321      *
322      * @see org.objectweb.jac.core.rtti
323      * @see ObjectUpdate
324      * @see FieldUpdate
325      * @see CollectionUpdate
326      */

327
328     public Object JavaDoc updateView(Interaction interaction) {
329
330         Object JavaDoc ret = proceed(interaction);
331
332         logger.debug(this
333                 + " checking view updating for method "
334                 + Strings.hex(interaction.wrappee)
335                 + "."
336                 + interaction.method.getName());
337
338         MethodItem method = (MethodItem) interaction.method;
339
340         /*
341         JTextArea console = (JTextArea) method.getAttribute("Gui.loggingMethod");
342         if( console != null ) {
343            console.append( (String)arg(0) );
344            console.setCaretPosition( console.getText().length() );
345         }
346         */

347
348         // notify registered clients for fieldUpdated
349
FieldItem[] writtenFields = method.getWrittenFields();
350         if (writtenFields != null) {
351             Class JavaDoc cl = interaction.getActualClass();
352             for (int i = 0; i < writtenFields.length; i++) {
353                 if (writtenFields[i].getGetter() == interaction.method) {
354                     logger.warn(
355                         "Skipping " + interaction.method
356                             + " since it's the getter of " + writtenFields[i]);
357                     continue;
358                 }
359                 logger.debug(method.getClassItem() + "." + method.getFullName()
360                         + " writes " + writtenFields[i].getLongName());
361                 onFieldWrite(interaction.wrappee,cl,writtenFields[i]);
362
363             }
364         }
365
366         // notify registered clients for collectionUpdated
367
CollectionItem[] addedCollections = method.getAddedCollections();
368         CollectionItem[] removedCollections = method.getRemovedCollections();
369         CollectionItem[] modifiedCollections = method.getModifiedCollections();
370         HashSet JavaDoc clientCollections = new HashSet JavaDoc();
371         if (addedCollections != null) {
372             clientCollections.addAll(Arrays.asList(addedCollections));
373         }
374         if (removedCollections != null) {
375             clientCollections.addAll(Arrays.asList(removedCollections));
376         }
377         if (modifiedCollections != null) {
378             clientCollections.addAll(Arrays.asList(modifiedCollections));
379         }
380         Iterator JavaDoc i = clientCollections.iterator();
381         while (i.hasNext()) {
382             CollectionItem collection = (CollectionItem) i.next();
383             HashMap JavaDoc clients =
384                 (HashMap JavaDoc) collectionClients.get(collection.getName());
385             if (clients != null) {
386                 Iterator JavaDoc it = ((Map JavaDoc) clients.clone()).keySet().iterator();
387                 Object JavaDoc value =
388                     collection.getThroughAccessor(interaction.wrappee);
389                 while (it.hasNext()) {
390                     CollectionUpdate client = (CollectionUpdate) it.next();
391                     logger.debug("collectionUpdated("
392                             + collection.getLongName()
393                             + ") on "
394                             + Strings.hex(client));
395                     try {
396                         if (method.isAdder())
397                             client.onAdd(
398                                 interaction.wrappee,
399                                 collection,
400                                 value,
401                                 interaction.args[0],
402                                 clients.get(client));
403                         else if (method.isRemover())
404                             client.onRemove(
405                                 interaction.wrappee,
406                                 collection,
407                                 value,
408                                 interaction.args[0],
409                                 clients.get(client));
410                         else
411                             client.onChange(
412                                 interaction.wrappee,
413                                 collection,
414                                 value,
415                                 clients.get(client));
416                     } catch (Exception JavaDoc e) {
417                         logger.error(
418                             "Caught exception in collectionUpdated("
419                                 + collection.getLongName()
420                                 + ") on "
421                                 + Strings.hex(client),
422                             e);
423                     }
424                 }
425             }
426             notifyDependentCollections(
427                 collection,
428                 interaction.wrappee,
429                 method,
430                 interaction.args);
431         }
432
433         // notify registered clients for objectUpdated
434
if (method.isModifier()) {
435             logger.debug(method + " is a modifier");
436             onObjectModified(interaction.wrappee);
437         }
438
439         return ret;
440     }
441
442     public void onObjectModified(Object JavaDoc substance) {
443         Iterator JavaDoc it = (new HashMap JavaDoc(objectClients)).keySet().iterator();
444         while (it.hasNext()) {
445             ObjectUpdate client = (ObjectUpdate) it.next();
446             logger.debug("objectUpdated("
447                 + Strings.hex(substance)
448                 + ") on "
449                 + Strings.hex(client));
450             try {
451                 client.objectUpdated(
452                     substance,
453                     objectClients.get(client));
454             } catch (Exception JavaDoc e) {
455                 logger.error(
456                     "Caught exception in objectUpdated("
457                     + Strings.hex(substance)
458                     + ") on "
459                     + Strings.hex(client),
460                     e);
461             }
462         }
463     }
464
465     /**
466      * @param substance the object whose field is written
467      * @param cl the class of substance
468      * @param writtenField the field which is written
469      */

470     public void onFieldWrite(Object JavaDoc substance, Class JavaDoc cl, FieldItem writtenField) {
471         logger.debug("onFieldWrite "+substance+"."+writtenField);
472
473         HashMap JavaDoc clients =
474             (HashMap JavaDoc) fieldClients.get(writtenField.getName());
475         if (clients != null) {
476             Iterator JavaDoc it = ((Map JavaDoc) clients.clone()).entrySet().iterator();
477             Object JavaDoc value =
478                 writtenField.getThroughAccessor(substance);
479             while (it.hasNext()) {
480                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
481                 FieldUpdate client = (FieldUpdate) entry.getKey();
482                 logger.debug(" fieldUpdated("
483                     + writtenField.getLongName()
484                     + ") on "
485                     + Strings.hex(client));
486                 try {
487                     client.fieldUpdated(
488                         substance,
489                         writtenField,
490                         value,
491                         entry.getValue());
492                 } catch (Exception JavaDoc e) {
493                     logger.error(
494                         "Caught exception in fieldUpdated("
495                         + writtenField.getLongName()
496                         + ") on "
497                         + Strings.hex(client), e);
498                 }
499             }
500         }
501
502         // Notify dependent fields
503
FieldItem[] dependentFields =
504             writtenField.getDependentFields();
505         for (int j = 0; j < dependentFields.length; j++) {
506             if (!dependentFields[j]
507                 .getClassItem()
508                 .getActualClass()
509                 .isAssignableFrom(cl)) {
510                 logger.debug(" Skipping dependentField "
511                     + dependentFields[j]
512                     + " (class=" + cl.getName() + ")");
513                 continue;
514             }
515
516             logger.debug(" dependent field " + dependentFields[j].getLongName());
517             List JavaDoc depSubstances = (List JavaDoc)dependentFields[j].getSubstances(substance);
518             Iterator JavaDoc sit = depSubstances.iterator();
519             while(sit.hasNext()) {
520                 Wrappee depSubstance = (Wrappee)sit.next();
521                 logger.debug(" iterating on " + depSubstance);
522                 if (depSubstance!=null && depSubstance!=substance) {
523                     Wrapping.invokeRoleMethod(
524                         depSubstance,
525                         ViewControlWrapper.class,
526                         "onFieldWrite",
527                         new Object JavaDoc[] {depSubstance,depSubstance.getClass(),dependentFields[j].getField()}
528                     );
529                     Wrapping.invokeRoleMethod(
530                         depSubstance,
531                         ViewControlWrapper.class,
532                         "onObjectModified",
533                         new Object JavaDoc[] {depSubstance}
534                     );
535                 }
536             }
537             clients =
538                 (HashMap JavaDoc) fieldClients.get(
539                     dependentFields[j].getName());
540             if (clients != null) {
541                 Iterator JavaDoc it =
542                     ((Map JavaDoc) clients.clone()).entrySet().iterator();
543                 Object JavaDoc value =
544                     dependentFields[j].getThroughAccessor(
545                         substance);
546                 while (it.hasNext()) {
547                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
548                     FieldUpdate client = (FieldUpdate) entry.getKey();
549                     logger.debug(" fieldUpdated("
550                         + dependentFields[j].getLongName()
551                         + ") on " + Strings.hex(client));
552                     try {
553                         client.fieldUpdated(
554                             substance,
555                             dependentFields[j],
556                             value,
557                             entry.getValue());
558                     } catch (Exception JavaDoc e) {
559                         logger.error(
560                             "Caught exception in fieldUpdated("
561                             + dependentFields[j].getLongName()
562                             + ") on " + Strings.hex(client),
563                             e);
564                     }
565                 }
566             }
567         }
568
569         notifyDependentMethods(
570             methodClients,
571             writtenField,
572             substance,
573             cl,
574             new HashSet JavaDoc());
575
576     }
577
578
579     /**
580      * @param methodClients the clients to notify
581      * @param member member item which caused the notification
582      * @param wrappee object which caused the notification
583      * @param cl class of wrappee or null
584      * @param alreadyNotified already notified clients, so that we can
585      * avoid infinite loops and notifying a client several times
586      */

587     void notifyDependentMethods(
588         Map JavaDoc methodClients,
589         MemberItem member,
590         Object JavaDoc wrappee,
591         Class JavaDoc cl,
592         Set JavaDoc alreadyNotified) {
593         logger.debug("notifyDependentMethods for " + member + " / " + wrappee);
594         // Notify dependent methods
595
MethodItem[] dependentMethods = member.getDependentMethods();
596         for (int i = 0; i < dependentMethods.length; i++) {
597             // the class of the dependent method
598
Class JavaDoc depClass =
599                 dependentMethods[i].getClassItem().getActualClass();
600             if ((cl != null && !depClass.isAssignableFrom(cl))
601                 || alreadyNotified.contains(dependentMethods[i])) {
602                 logger.debug(" skipping " + dependentMethods[i].getLongName());
603                 continue;
604             }
605             logger.debug("dependent method "
606                     + dependentMethods[i].getClassItem()
607                     + "."
608                     + dependentMethods[i].getFullName());
609             alreadyNotified.add(dependentMethods[i]);
610             HashMap JavaDoc clients =
611                 (HashMap JavaDoc) methodClients.get(dependentMethods[i].getFullName());
612             if (clients != null) {
613                 Iterator JavaDoc it = ((Map JavaDoc) clients.clone()).entrySet().iterator();
614                 while (it.hasNext()) {
615                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
616                     MethodUpdate client = (MethodUpdate) entry.getKey();
617                     logger.debug("MethodUpdated("
618                             + dependentMethods[i].getLongName()
619                             + ") on "
620                             + Strings.hex(client));
621                     try {
622                         client.methodUpdated(
623                             wrappee,
624                             dependentMethods[i],
625                             entry.getValue());
626                     } catch (Exception JavaDoc e) {
627                         logger.error(
628                             "Caught exception in methodUpdated("
629                                 + dependentMethods[i].getLongName()
630                                 + ") on " + Strings.hex(client),
631                             e);
632                     }
633                 }
634             }
635             if (member != dependentMethods[i])
636                 notifyDependentMethods(
637                     allMethodClients,
638                     dependentMethods[i],
639                     wrappee,
640                     null,
641                     alreadyNotified);
642         }
643     }
644
645     void notifyDependentCollections(
646         CollectionItem collection,
647         Wrappee wrappee,
648         MethodItem method,
649         Object JavaDoc[] args) {
650         // Notify dependent fields
651
FieldItem[] dependentFields = collection.getDependentFields();
652         for (int j = 0; j < dependentFields.length; j++) {
653             logger.debug("dependent field "
654                     + dependentFields[j].getName()
655                     + " for "
656                     + collection.getName());
657             HashMap JavaDoc clients =
658                 (HashMap JavaDoc) collectionClients.get(dependentFields[j].getName());
659             if (clients != null) {
660                 Iterator JavaDoc it2 = ((Map JavaDoc) clients.clone()).entrySet().iterator();
661                 Object JavaDoc value = dependentFields[j].getThroughAccessor(wrappee);
662                 while (it2.hasNext()) {
663                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it2.next();
664                     CollectionUpdate client = (CollectionUpdate) entry.getKey();
665                     logger.debug(
666                         "collectionUpdated(" + dependentFields[j].getLongName()
667                         + ") on " + Strings.hex(client));
668                     try {
669                         client.onChange(
670                             wrappee,
671                             (CollectionItem) dependentFields[j],
672                             value,
673                             entry.getValue());
674                     } catch (Exception JavaDoc e) {
675                         logger.error(
676                             "Caught exception in collectionUpdated("
677                                 + dependentFields[j].getLongName()
678                                 + ") on " + Strings.hex(client),
679                             e);
680                     }
681                 }
682             }
683         }
684     }
685
686     public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
687         return updateView((Interaction) invocation);
688     }
689
690     public Object JavaDoc construct(ConstructorInvocation invocation)
691         throws Throwable JavaDoc {
692         throw new Exception JavaDoc("This wrapper does not support constructor wrapping");
693     }
694
695 }
696
Popular Tags