KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2   Copyright (C) 2001-2004 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, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18   USA */

19
20 package org.objectweb.jac.aspects.gui;
21
22 import java.lang.reflect.Modifier JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import org.aopalliance.intercept.ConstructorInvocation;
27 import org.aopalliance.intercept.MethodInvocation;
28 import org.apache.log4j.Logger;
29 import org.objectweb.jac.core.ACManager;
30 import org.objectweb.jac.core.AspectComponent;
31 import org.objectweb.jac.core.Collaboration;
32 import org.objectweb.jac.core.Display;
33 import org.objectweb.jac.core.Interaction;
34 import org.objectweb.jac.core.Wrappee;
35 import org.objectweb.jac.core.Wrapper;
36 import org.objectweb.jac.core.rtti.AbstractMethodItem;
37 import org.objectweb.jac.core.rtti.ClassItem;
38 import org.objectweb.jac.core.rtti.ClassRepository;
39 import org.objectweb.jac.core.rtti.ConstructorItem;
40 import org.objectweb.jac.core.rtti.FieldItem;
41 import org.objectweb.jac.core.rtti.MethodItem;
42 import org.objectweb.jac.core.rtti.NamingConventions;
43 import org.objectweb.jac.util.VoidException;
44
45 /**
46  * This wrapper asks the user the parameters of the invoked method if
47  * the attribute <code>Gui.askForParameters</code> is defined in the
48  * current collaboration.
49  *
50  * @see org.objectweb.jac.core.Display#showInput(Object,AbstractMethodItem,Object[])
51  * @see InputSequence
52  */

53
54 public class InputWrapper extends Wrapper {
55     static Logger logger = Logger.getLogger("gui.input");
56
57     public InputWrapper(AspectComponent ac) {
58         super(ac);
59     }
60
61     /**
62      * Returns true if all classe of an array are Wrappee classes.
63      */

64     boolean areAllWrappees(Class JavaDoc[] types) {
65         for (int i=0; i<types.length; i++) {
66             if (!Wrappee.class.isAssignableFrom(types[i])) {
67                 return false;
68             }
69         }
70         return true;
71     }
72
73     /**
74      * Calls the <code>Display.showInput</code> method on the current
75      * display.
76      *
77      * @return the value returned by the wrapped method
78      * @see org.objectweb.jac.core.Display#showInput(Object,AbstractMethodItem,Object[])
79      */

80     public Object JavaDoc askForParameters(Interaction interaction)
81         throws InputFailedException, InputCanceledException
82     {
83         boolean proceed = true;
84
85         AbstractMethodItem m =
86             (AbstractMethodItem) attr(GuiAC.ASK_FOR_PARAMETERS);
87         AbstractMethodItem method = (AbstractMethodItem) interaction.method;
88
89         logger.debug("Gui.askForParameters=" + (m!=null ? m.getLongName() : "null"));
90         logger.debug("current method=" + (method!=null ? method.getLongName(): "null"));
91
92         if (m != null && method != null) {
93             logger.debug("actual classes: "
94                     + ((ClassItem) m.getParent()).getActualClass() + ","
95                     + ((ClassItem) method.getParent()).getActualClass());
96         }
97         Display display = null;
98         // DIRTY HACK
99
if (m != null && m.getLongName().equals(method.getLongName())) {
100             logger.debug("Entering parameters asking for "
101                          + interaction.wrappee + " : " + method.getLongName()
102                          + " askForParameters = " + m.getLongName()
103                          + " autoCreate=" + attr(GuiAC.AUTO_CREATE)
104                          + " view=" + attr(GuiAC.VIEW));
105
106             AbstractMethodItem invoked = (AbstractMethodItem)attr(GuiAC.INVOKED_METHOD);
107             if (invoked!=null)
108                 method = invoked;
109             DisplayContext context =
110                 (DisplayContext) attr(GuiAC.DISPLAY_CONTEXT);
111             display = context.getDisplay();
112
113             attrdef(GuiAC.ASK_FOR_PARAMETERS, null);
114
115             if (display != null) {
116                 MethodItem interactionHandler =
117                     GuiAC.getInteractionHandler(method);
118                 if (interactionHandler != null) {
119                     logger.debug("invoking interactionHandler " + interactionHandler);
120                     proceed =
121                         ((Boolean JavaDoc) interactionHandler
122                             .invokeStatic(
123                                 new Object JavaDoc[] { interaction, context }))
124                             .booleanValue();
125                 } else {
126
127                     Class JavaDoc[] paramTypes = method.getParameterTypes();
128                     // automatic created parameter handling
129
if (attr(GuiAC.NO_AUTO_CREATE) == null
130                         && (GuiAC.isAutoCreateParameters(method)
131                             || attr(GuiAC.AUTO_CREATE) != null
132                             || (method.isAdder()
133                                 && GuiAC.isAutoCreate(
134                                     method.getAddedCollection()))
135                             || (method.isSetter()
136                                 && GuiAC.isAutoCreate(
137                                     method.getSetField())))
138                         && areAllWrappees(paramTypes)) {
139                         proceed =
140                             autoCreate(
141                                 display,
142                                 context,
143                                 method,
144                                 interaction,
145                                 paramTypes);
146                     } else {
147                         proceed =
148                             askingSequence(
149                                 display,
150                                 context,
151                                 method,
152                                 interaction,
153                                 paramTypes);
154                     }
155                 }
156             } else {
157                 logger.debug("No display available");
158                 throw new InputFailedException("No display available");
159             }
160             logger.debug("proceed = " + proceed);
161             logger.debug("args=" + Arrays.asList(interaction.args));
162         }
163
164         if (proceed) {
165             Object JavaDoc result = proceed(interaction);
166             return result;
167         } else {
168             throw new InputCanceledException(method);
169         }
170
171     }
172
173     protected boolean autoCreate(
174         Display display,
175         DisplayContext context,
176         AbstractMethodItem method,
177         Interaction interaction,
178         Class JavaDoc[] paramTypes)
179     {
180         logger.debug("in parameter autoCreation");
181         if (method.isAdder()
182              && GuiAC.isAutoCreate(
183                  method.getAddedCollection())) {
184             EventHandler.setOppositeRole(method.getAddedCollection());
185         } else if (method.isSetter()
186                    && GuiAC.isAutoCreate(
187                        method.getSetField())) {
188             EventHandler.setOppositeRole(method.getSetField());
189         }
190         attrdef(GuiAC.AUTO_CREATION, Boolean.TRUE);
191         //attrdef(GuiAC.EMBEDDED_EDITORS, Boolean.TRUE);
192
ACManager.getACM().beforeWrappeeInit(null);
193         boolean proceed = true;
194         try {
195             boolean ok = true;
196             for (int i=0; i<paramTypes.length; i++) {
197
198                 // do not create if already filled in!
199
Object JavaDoc arg = method.getParameter(interaction.args,i);
200                 if (arg != null)
201                     continue;
202
203                 //if( paramTypes[i] instanceof Wrappee ) {
204
if (!Modifier.isPublic(paramTypes[i].getModifiers())) {
205                     logger.error(
206                         "cannot instantiate non public class "
207                             + paramTypes[i].getName());
208                 }
209                 Collaboration collab = Collaboration.get();
210                 collab.addAttribute(GuiAC.AUTOCREATE_REASON, interaction);
211                 try {
212                     method.setParameter(interaction.args,i,newInstance(paramTypes[i], display));
213                     arg = method.getParameter(interaction.args,i);
214                 } catch (Exception JavaDoc e) {
215                     e.printStackTrace();
216                 } finally {
217                     collab.removeAttribute(GuiAC.AUTOCREATE_REASON);
218                 }
219
220                 if (arg != null) {
221                     // Use initializer if any
222
MethodItem init = null;
223                     if (method.isAdder()) {
224                         init =
225                             GuiAC.getInitiliazer(
226                                 method.getAddedCollections()[0]);
227                     } else if (method.isSetter()) {
228                         init = GuiAC.getInitiliazer(method.getSetField());
229                     }
230                     if (init != null) {
231                         logger.debug("Initializing new instance of "
232                                 + paramTypes[i].getName()
233                                 + " with "
234                                 + init.getFullName());
235                         init.invoke(
236                             interaction.wrappee,
237                             new Object JavaDoc[] { arg });
238                     }
239
240                     ok =
241                         display.showModal(
242                             arg,
243                             "Object",
244                             new String JavaDoc[] { GuiAC.AUTOCREATE_VIEW },
245                             interaction.args.length > 1
246                                 ? GuiAC.getLabel(method)
247                                     + " ("
248                                     + NamingConventions.getShortClassName(
249                                         arg.getClass())
250                                     + ")"
251                                 : GuiAC.getLabel(method),
252                             "Fill the needed information and validate.",
253                             context.getWindow(),
254                             true,
255                             true,
256                             false);
257                 } else {
258                     ok = false;
259                 }
260                 if (!ok) {
261                     logger.debug("Input cancelled for " + interaction.method);
262                     proceed = false;
263                     break;
264                 } else {
265                     if (attr(GuiAC.VIEW) != null) {
266                         /* What was this supposed to do ???
267                            Wrapping.invokeRoleMethod(
268                            ((Wrappee)interaction.args[i]),"addView",
269                            new Object[] {attr(GuiAC.VIEW)});
270                         */

271                     }
272                     // if some field must be autocreated, we ask the user
273
// to input them (except if already filled)
274
// this should be reccursive but it is not implemented
275
// for the moment
276
ClassItem parameterClass =
277                         ClassRepository.get().getClass(paramTypes[i]);
278                     String JavaDoc[] autoCreatedFields =
279                         (String JavaDoc[]) parameterClass.getAttribute(
280                             GuiAC.AUTO_CREATED_STATE);
281                     if (autoCreatedFields != null) {
282                         for (int j=0; j<autoCreatedFields.length; j++) {
283                             FieldItem f =
284                                 parameterClass.getField(autoCreatedFields[j]);
285                             if (f != null
286                                 && f.getThroughAccessor(arg) == null) {
287                                 Object JavaDoc newInstance = null;
288                                 try {
289                                     newInstance = f.getType().newInstance();
290                                     ok =
291                                         display.showModal(
292                                             newInstance,
293                                             "Object",
294                                             new String JavaDoc[] {
295                                                  GuiAC.AUTOCREATE_VIEW },
296                                             "Creation of a new "
297                                                 + NamingConventions
298                                                     .getShortClassName(
299                                                     newInstance.getClass()),
300                                             "You did not fill any "
301                                                 + f.getName()
302                                                 + ". "
303                                                 + "Fill the needed informations and validate.",
304                                             context.getWindow(),
305                                             true,
306                                             true,
307                                             false);
308                                     if (ok) {
309                                         f.setThroughWriter(
310                                             arg,
311                                             newInstance);
312                                     }
313                                 } catch (Exception JavaDoc e) {
314                                     e.printStackTrace();
315                                 }
316                             }
317                         }
318                     }
319                 }
320             }
321         } finally {
322             attrdef(GuiAC.AUTO_CREATION, null);
323             //attrdef(GuiAC.EMBEDDED_EDITORS, null);
324
ACManager.getACM().afterWrappeeInit(null);
325         }
326         return proceed;
327     }
328
329     protected boolean askingSequence(
330         Display display,
331         DisplayContext context,
332         AbstractMethodItem method,
333         Interaction interaction,
334         Class JavaDoc[] paramTypes)
335         throws InputFailedException, InputCanceledException
336     {
337         boolean proceed = true;
338         Object JavaDoc[] askingSequence =
339             (Object JavaDoc[]) method.getAttribute(GuiAC.ASKING_SEQUENCE);
340         boolean allCreated = false;
341         if (paramTypes.length > 0) {
342             if (askingSequence != null) {
343                 logger.debug("input sequence found");
344                 allCreated = true;
345                 for (int i=0; i<paramTypes.length; i++) {
346                     if (askingSequence[i].equals("autoCreate")) {
347                         method.setParameter(
348                             interaction.args,
349                             i,
350                             create(
351                                 ClassRepository.get().getClass(paramTypes[i]),
352                                 display));
353                     } else {
354                         allCreated = false;
355                     }
356                 }
357             }
358             if (!allCreated) {
359                 if (!display.fillParameters(method, interaction.args)) {
360                     logger.debug("asking for parameters");
361                     GuiAC.pushGraphicContext(method);
362                     try {
363                         proceed =
364                             display.showInput(
365                                 interaction.wrappee,
366                                 method,
367                                 interaction.args);
368                     } finally {
369                         GuiAC.popGraphicContext();
370                     }
371                     logger.debug("args=" + Arrays.asList(interaction.args));
372                 }
373             } else {
374                 logger.debug("skipping asking for parameters");
375                 proceed = true;
376             }
377         }
378         return proceed;
379     }
380
381     /**
382      * This method performs all the inputs operations for an instance creation.
383      *
384      * @param classItem the class to instantiate
385      * @param display the display to use
386      */

387     public Object JavaDoc create(ClassItem classItem, Display display)
388         throws InputFailedException, InputCanceledException
389     {
390         Object JavaDoc newInstance = null;
391         Collection JavaDoc constructors = classItem.getConstructors();
392         Iterator JavaDoc it = constructors.iterator();
393         ConstructorItem c;
394         c = (ConstructorItem) it.next();
395         if (it.hasNext()) {
396             c = (ConstructorItem) it.next();
397         }
398         if (c.getParameterTypes().length > 0) {
399             Object JavaDoc[] parameters = new Object JavaDoc[c.getParameterTypes().length];
400
401             String JavaDoc inputSequenceName =
402                 (String JavaDoc) c.getAttribute("Gui.inputSequence");
403             logger.debug("input sequence name = " + inputSequenceName);
404             if (inputSequenceName == null) {
405                 display.showInput(null, c, parameters);
406             } else {
407                 org.objectweb.jac.aspects.gui.InputSequence inputSeq = null;
408                 try {
409                     inputSeq =
410                         (org.objectweb.jac.aspects.gui.InputSequence) Class
411                             .forName(inputSequenceName)
412                             .getConstructor(
413                                 new Class JavaDoc[] {
414                                     Display.class,
415                                     AbstractMethodItem.class,
416                                     Object JavaDoc[].class })
417                             .newInstance(
418                                 new Object JavaDoc[] { display, c, parameters });
419                 } catch (Exception JavaDoc e) {
420                     throw new InputFailedException("unabled to create input sequence");
421                 }
422                 if (!inputSeq.proceedInputs()) {
423                     throw new InputCanceledException(c);
424                 }
425             }
426
427             try {
428                 newInstance = c.newInstance(parameters);
429             } catch (Exception JavaDoc e) {
430                 e.printStackTrace();
431             }
432
433         } else {
434             try {
435                 newInstance = c.newInstance();
436             } catch (Exception JavaDoc e) {
437                 e.printStackTrace();
438             }
439         }
440         return newInstance;
441     }
442
443     /**
444      * Create a new instance of a class. If the class has known
445      * subclasses, the user will be given the choice of the actual
446      * class to instantiate.
447      * @param cl the class to instantiate
448      * @param display display to use for user interaction
449      * @return a new instance of the class
450      */

451     public static Object JavaDoc newInstance(Class JavaDoc cl, Display display)
452         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc
453     {
454         ClassItem cli = ClassRepository.get().getClass(cl);
455         Collection JavaDoc subClasses = cli.getChildren();
456         if (!subClasses.isEmpty() && Modifier.isAbstract(cl.getModifiers())) {
457             ClassChooser chooser = new ClassChooser(cli);
458             ClassItem classChooserClass =
459                 ClassRepository.get().getClass(ClassChooser.class);
460             ClassItem[] choice = new ClassItem[1];
461             boolean ok =
462                 display.showInput(
463                     chooser,
464                     classChooserClass.getMethod("setChoice"),
465                     choice);
466             if (!ok) {
467                 return null;
468             } else {
469                 return choice[0].newInstance();
470             }
471         } else {
472             return cl.newInstance();
473         }
474     }
475
476     public void catchInputCanceled(InputCanceledException e) {
477         logger.debug("catching exception: " + e.toString());
478         attrdef(GuiAC.AUTO_CREATE, null);
479         throw new VoidException();
480     }
481
482     public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
483         return askForParameters((Interaction) invocation);
484     }
485
486     public Object JavaDoc construct(ConstructorInvocation invocation)
487         throws Throwable JavaDoc {
488         return askForParameters((Interaction) invocation);
489     }
490 }
491
492 class InputFailedException extends Exception JavaDoc {
493     public InputFailedException() {
494     }
495     public InputFailedException(String JavaDoc msg) {
496         super(msg);
497     }
498 }
499
Popular Tags