MVCHandler.java
001 /*
002  * Copyright 2008-2014 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.core.mvc;
017 
018 import griffon.core.artifact.GriffonController;
019 import griffon.core.artifact.GriffonModel;
020 import griffon.core.artifact.GriffonMvcArtifact;
021 import griffon.core.artifact.GriffonView;
022 
023 import javax.annotation.Nonnull;
024 import java.util.List;
025 import java.util.Map;
026 
027 /**
028  * Base contract for classes that can manipulate MVC groups.
029  * There are 3 types of methods used for instantiating a group:
030  * <ul>
031  * <ol>{@code buildMVCGroup()} - creates a new group instance returning all members.</ol>
032  * <ol>{@code createMVCGroup()} - creates a new group instance returning only Model, View and Controller members.</ol>
033  * <ol>{@code withMVCGroup()} - creates a new group instance and  destroys it immediately after it has been processed by the callback.</ol>
034  * </ul>
035  * <p/>
036  * It's worth mentioning that the value of the {@code mvcId} parameter must be unique otherwise a collision will occur.
037  * When that happens the application will report and exception and terminate. This behavior can be configured to be more
038  * lenient, by defining a configuration flag {@code griffon.mvcid.collision} in {@code Config}. <br/>
039  * Accepted values are
040  * <ul>
041  * <ol>warning - reports the error but allows the application to continue. Destroys the existing group before continuing.</ol>
042  * <ol>exception - reports the error and terminates the application. this is the default behavior.</ol>
043  * </ul>
044  *
045  * @author Andres Almiray
046  * @since 2.0.0
047  */
048 public interface MVCHandler {
049     /**
050      * Instantiates an MVC group of the specified type.<p>
051      * MVC Groups must be previously configured with the application's metadata
052      * before they can be used. This registration process usually takes place automatically
053      * at boot time. The type of the group can be normally found in the application's
054      * configuration file.<p>
055      * For example, with the following entry available in {@code Application.groovy}
056      * <p/>
057      * <pre>
058      * mvcGroups {
059      *     'foo' {
060      *         model      = 'com.acme.FooModel'
061      *         view       = 'com.acme.FooView'
062      *         controller = 'com.acme.FooController'
063      *     }
064      * }
065      * </pre>
066      * <p/>
067      * An instance of the "foo" group can be created as follows
068      * <p/>
069      * <pre>
070      * Map<String, Object> fooGroup = buildMVCGroup('foo')
071      * assert (fooGroup.controller instanceof FooController)
072      * </pre>
073      *
074      * @param mvcType the type of group to build.
075      * @return an MVCGroup instance of the desired type
076      * @throws griffon.exceptions.MVCGroupInstantiationException
077      *          - if the type specified is not found in the application's
078      *          configuration or if a group with the same mvcId exists already.
079      */
080     @Nonnull
081     MVCGroup buildMVCGroup(@Nonnull String mvcType);
082 
083     /**
084      * Instantiates an MVC group of the specified type with a particular name.<p>
085      * MVC Groups must be previously configured with the application's metadata
086      * before they can be used. This registration process usually takes place automatically
087      * at boot time. The type of the group can be normally found in the application's
088      * configuration file.<p>
089      * For example, with the following entry available in {@code Application.groovy}
090      * <p/>
091      * <pre>
092      * mvcGroups {
093      *     'foo' {
094      *         model      = 'com.acme.FooModel'
095      *         view       = 'com.acme.FooView'
096      *         controller = 'com.acme.FooController'
097      *     }
098      * }
099      * </pre>
100      * <p/>
101      * An instance of the "foo" group can be created as follows
102      * <p/>
103      * <pre>
104      * Map<String, Object> fooGroup = buildMVCGroup('foo', 'foo' + System.currentTimeMillis())
105      * assert (fooGroup.controller instanceof FooController)
106      * </pre>
107      * <p/>
108      * MVC groups must have an unique name.
109      *
110      * @param mvcType the type of group to build.
111      * @param mvcId the name to assign to the built group.
112      * @return an MVCGroup instance of the desired type
113      * @throws griffon.exceptions.MVCGroupInstantiationException
114      *          - if the type specified is not found in the application's
115      *          configuration or if a group with the same mvcId exists already.
116      */
117     @Nonnull
118     MVCGroup buildMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId);
119 
120     /**
121      * Instantiates an MVC group of the specified type with additional variables.<p>
122      * MVC Groups must be previously configured with the application's metadata
123      * before they can be used. This registration process usually takes place automatically
124      * at boot time. The type of the group can be normally found in the application's
125      * configuration file.<p>
126      * The <tt>args</tt> Map can contain any value that will be used in one of the following
127      * scenarios <ul>
128      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
129      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
130      * on any MVC member of the group.</li>
131      * </ul>
132      * <p/>
133      * For example, with the following entry available in {@code Application.groovy}
134      * <p/>
135      * <pre>
136      * mvcGroups {
137      *     'foo' {
138      *         model      = 'com.acme.FooModel'
139      *         view       = 'com.acme.FooView'
140      *         controller = 'com.acme.FooController'
141      *     }
142      *     'bar' {
143      *         model      = 'com.acme.FooModel'
144      *         view       = 'com.acme.BarView'
145      *         controller = 'com.acme.BarController'
146      *     }
147      * }
148      * </pre>
149      * <p/>
150      * Notice that groups "foo" and "bar share the same model type, We can make them share the same model
151      * instance by creating the groups in the following way:
152      * <p/>
153      * <pre>
154      * Map<String, Object> fooGroup = buildMVCGroup('foo')
155      * Map<String, Object> barGroup = buildMVCGroup('bar', model: fooGroup.model)
156      * assert fooGroup.model == barGroup.model
157      * </pre>
158      *
159      * @param args    any useful values that can be set as properties on each MVC member or that
160      *                identify a member that can be shared with other groups.
161      * @param mvcType the type of group to build.
162      * @return an MVCGroup instance of the desired type
163      * @throws griffon.exceptions.MVCGroupInstantiationException
164      *          - if the type specified is not found in the application's
165      *          configuration or if a group with the same mvcId exists already.
166      */
167     @Nonnull
168     MVCGroup buildMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType);
169 
170     /**
171      * Instantiates an MVC group of the specified type with additional variables.<p>
172      * MVC Groups must be previously configured with the application's metadata
173      * before they can be used. This registration process usually takes place automatically
174      * at boot time. The type of the group can be normally found in the application's
175      * configuration file.<p>
176      * The <tt>args</tt> Map can contain any value that will be used in one of the following
177      * scenarios <ul>
178      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
179      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
180      * on any MVC member of the group.</li>
181      * </ul>
182      * <p/>
183      * For example, with the following entry available in {@code Application.groovy}
184      * <p/>
185      * <pre>
186      * mvcGroups {
187      *     'foo' {
188      *         model      = 'com.acme.FooModel'
189      *         view       = 'com.acme.FooView'
190      *         controller = 'com.acme.FooController'
191      *     }
192      *     'bar' {
193      *         model      = 'com.acme.FooModel'
194      *         view       = 'com.acme.BarView'
195      *         controller = 'com.acme.BarController'
196      *     }
197      * }
198      * </pre>
199      * <p/>
200      * Notice that groups "foo" and "bar share the same model type, We can make them share the same model
201      * instance by creating the groups in the following way:
202      * <p/>
203      * <pre>
204      * Map<String, Object> fooGroup = buildMVCGroup('foo')
205      * Map<String, Object> barGroup = buildMVCGroup('bar', model: fooGroup.model)
206      * assert fooGroup.model == barGroup.model
207      * </pre>
208      *
209      * @param mvcType the type of group to build.
210      * @param args    any useful values that can be set as properties on each MVC member or that
211      *                identify a member that can be shared with other groups.
212      * @return an MVCGroup instance of the desired type
213      * @throws griffon.exceptions.MVCGroupInstantiationException
214      *          - if the type specified is not found in the application's
215      *          configuration or if a group with the same mvcId exists already.
216      */
217     @Nonnull
218     MVCGroup buildMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args);
219 
220     /**
221      * Instantiates an MVC group of the specified type with a particular name.<p>
222      * MVC Groups must be previously configured with the application's metadata
223      * before they can be used. This registration process usually takes place automatically
224      * at boot time. The type of the group can be normally found in the application's
225      * configuration file.<p>
226      * The <tt>args</tt> Map can contain any value that will be used in one of the following
227      * scenarios <ul>
228      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
229      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
230      * on any MVC member of the group.</li>
231      * </ul>
232      * <p/>
233      * For example, with the following entry available in {@code Application.groovy}
234      * <p/>
235      * <pre>
236      * mvcGroups {
237      *     'foo' {
238      *         model      = 'com.acme.FooModel'
239      *         view       = 'com.acme.FooView'
240      *         controller = 'com.acme.FooController'
241      *     }
242      * }
243      * </pre>
244      * <p/>
245      * We can create two instances of the same group that share the same model instance in the following way:
246      * <p/>
247      * <pre>
248      * Map<String, Object> fooGroup1 = buildMVCGroup('foo', 'foo1')
249      * Map<String, Object> fooGroup2 = buildMVCGroup('bar', 'foo2', model: fooGroup1.model)
250      * assert fooGroup1.model == fooGroup2.model
251      * </pre>
252      * <p/>
253      * MVC groups must have an unique name.
254      *
255      * @param args    any useful values that can be set as properties on each MVC member or that
256      *                identify a member that can be shared with other groups.
257      * @param mvcType the type of group to build.
258      * @param mvcId the name to assign to the built group.
259      * @return an MVCGroup instance of the desired type
260      * @throws griffon.exceptions.MVCGroupInstantiationException
261      *          - if the type specified is not found in the application's
262      *          configuration or if a group with the same mvcId exists already.
263      */
264     @Nonnull
265     MVCGroup buildMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId);
266 
267     /**
268      * Instantiates an MVC group of the specified type with a particular name.<p>
269      * MVC Groups must be previously configured with the application's metadata
270      * before they can be used. This registration process usually takes place automatically
271      * at boot time. The type of the group can be normally found in the application's
272      * configuration file.<p>
273      * The <tt>args</tt> Map can contain any value that will be used in one of the following
274      * scenarios <ul>
275      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
276      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
277      * on any MVC member of the group.</li>
278      * </ul>
279      * <p/>
280      * For example, with the following entry available in {@code Application.groovy}
281      * <p/>
282      * <pre>
283      * mvcGroups {
284      *     'foo' {
285      *         model      = 'com.acme.FooModel'
286      *         view       = 'com.acme.FooView'
287      *         controller = 'com.acme.FooController'
288      *     }
289      * }
290      * </pre>
291      * <p/>
292      * We can create two instances of the same group that share the same model instance in the following way:
293      * <p/>
294      * <pre>
295      * Map<String, Object> fooGroup1 = buildMVCGroup('foo', 'foo1')
296      * Map<String, Object> fooGroup2 = buildMVCGroup('bar', 'foo2', model: fooGroup1.model)
297      * assert fooGroup1.model == fooGroup2.model
298      * </pre>
299      * <p/>
300      * MVC groups must have an unique name.
301      *
302      * @param mvcType the type of group to build.
303      * @param mvcId the name to assign to the built group.
304      * @param args    any useful values that can be set as properties on each MVC member or that
305      *                identify a member that can be shared with other groups.
306      * @return an MVCGroup instance of the desired type
307      * @throws griffon.exceptions.MVCGroupInstantiationException
308      *          - if the type specified is not found in the application's
309      *          configuration or if a group with the same mvcId exists already.
310      */
311     @Nonnull
312     MVCGroup buildMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args);
313 
314     /**
315      * Instantiates an MVC group of the specified type returning only the MVC parts.<p>
316      * MVC Groups must be previously configured with the application's metadata
317      * before they can be used. This registration process usually takes place automatically
318      * at boot time. The type of the group can be normally found in the application's
319      * configuration file.<p>
320      * For example, with the following entry available in {@code Application.groovy}
321      * <p/>
322      * <pre>
323      * mvcGroups {
324      *     'foo' {
325      *         model      = 'com.acme.FooModel'
326      *         view       = 'com.acme.FooView'
327      *         controller = 'com.acme.FooController'
328      *     }
329      * }
330      * </pre>
331      * <p/>
332      * An instance of the "foo" group can be created as follows
333      * <p/>
334      * <pre>
335      * def (m, v, c) = createMVCGroup('foo')
336      * assert (c instanceof FooController)
337      * </pre>
338      *
339      * @param mvcType the type of group to build.
340      * @return a List with the canonical MVC members of the group
341      * @throws griffon.exceptions.MVCGroupInstantiationException
342      *          - if the type specified is not found in the application's
343      *          configuration or if a group with the same mvcId exists already.
344      */
345     @Nonnull
346     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull String mvcType);
347 
348     /**
349      * Instantiates an MVC group of the specified type with additional variables.<p>
350      * MVC Groups must be previously configured with the application's metadata
351      * before they can be used. This registration process usually takes place automatically
352      * at boot time. The type of the group can be normally found in the application's
353      * configuration file.<p>
354      * The <tt>args</tt> Map can contain any value that will be used in one of the following
355      * scenarios <ul>
356      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
357      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
358      * on any MVC member of the group.</li>
359      * </ul>
360      * <p/>
361      * For example, with the following entry available in {@code Application.groovy}
362      * <p/>
363      * <pre>
364      * mvcGroups {
365      *     'foo' {
366      *         model      = 'com.acme.FooModel'
367      *         view       = 'com.acme.FooView'
368      *         controller = 'com.acme.FooController'
369      *     }
370      *     'bar' {
371      *         model      = 'com.acme.FooModel'
372      *         view       = 'com.acme.BarView'
373      *         controller = 'com.acme.BarController'
374      *     }
375      * }
376      * </pre>
377      * <p/>
378      * Notice that groups "foo" and "bar share the same model type, We can make them share the same model
379      * instance by creating the groups in the following way:
380      * <p/>
381      * <pre>
382      * def (m1, v1, c1) = createMVCGroup('foo')
383      * def (m2, v2, c2) = createMVCGroup('bar', model: m1)
384      * assert fm1 == m2
385      * </pre>
386      *
387      * @param args    any useful values that can be set as properties on each MVC member or that
388      *                identify a member that can be shared with other groups.
389      * @param mvcType the type of group to build.
390      * @return a List with the canonical MVC members of the group
391      * @throws griffon.exceptions.MVCGroupInstantiationException
392      *          - if the type specified is not found in the application's
393      *          configuration or if a group with the same mvcId exists already.
394      */
395     @Nonnull
396     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType);
397 
398     /**
399      * Instantiates an MVC group of the specified type with additional variables.<p>
400      * MVC Groups must be previously configured with the application's metadata
401      * before they can be used. This registration process usually takes place automatically
402      * at boot time. The type of the group can be normally found in the application's
403      * configuration file.<p>
404      * The <tt>args</tt> Map can contain any value that will be used in one of the following
405      * scenarios <ul>
406      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
407      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
408      * on any MVC member of the group.</li>
409      * </ul>
410      * <p/>
411      * For example, with the following entry available in {@code Application.groovy}
412      * <p/>
413      * <pre>
414      * mvcGroups {
415      *     'foo' {
416      *         model      = 'com.acme.FooModel'
417      *         view       = 'com.acme.FooView'
418      *         controller = 'com.acme.FooController'
419      *     }
420      *     'bar' {
421      *         model      = 'com.acme.FooModel'
422      *         view       = 'com.acme.BarView'
423      *         controller = 'com.acme.BarController'
424      *     }
425      * }
426      * </pre>
427      * <p/>
428      * Notice that groups "foo" and "bar share the same model type, We can make them share the same model
429      * instance by creating the groups in the following way:
430      * <p/>
431      * <pre>
432      * def (m1, v1, c1) = createMVCGroup('foo')
433      * def (m2, v2, c2) = createMVCGroup('bar', model: m1)
434      * assert fm1 == m2
435      * </pre>
436      *
437      * @param mvcType the type of group to build.
438      * @param args    any useful values that can be set as properties on each MVC member or that
439      *                identify a member that can be shared with other groups.
440      * @return a List with the canonical MVC members of the group
441      * @throws griffon.exceptions.MVCGroupInstantiationException
442      *          - if the type specified is not found in the application's
443      *          configuration or if a group with the same mvcId exists already.
444      */
445     @Nonnull
446     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args);
447 
448     /**
449      * Instantiates an MVC group of the specified type with a particular name.<p>
450      * MVC Groups must be previously configured with the application's metadata
451      * before they can be used. This registration process usually takes place automatically
452      * at boot time. The type of the group can be normally found in the application's
453      * configuration file.<p>
454      * For example, with the following entry available in {@code Application.groovy}
455      * <p/>
456      * <pre>
457      * mvcGroups {
458      *     'foo' {
459      *         model      = 'com.acme.FooModel'
460      *         view       = 'com.acme.FooView'
461      *         controller = 'com.acme.FooController'
462      *      }
463      * }
464      * </pre>
465      * <p/>
466      * An instance of the "foo" group can be created as follows
467      * <p/>
468      * <pre>
469      * def (m, v, c) = createMVCGroup('foo', 'foo' + System.currenttimeMillis())
470      * assert (c instanceof FooController)
471      * </pre>
472      * <p/>
473      * MVC groups must have an unique name.
474      *
475      * @param mvcType the type of group to build.
476      * @param mvcId the name to assign to the built group.
477      * @return a List with the canonical MVC members of the group
478      * @throws griffon.exceptions.MVCGroupInstantiationException
479      *          - if the type specified is not found in the application's
480      *          configuration or if a group with the same mvcId exists already.
481      */
482     @Nonnull
483     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId);
484 
485     /**
486      * Instantiates an MVC group of the specified type with a particular name.<p>
487      * MVC Groups must be previously configured with the application's metadata
488      * before they can be used. This registration process usually takes place automatically
489      * at boot time. The type of the group can be normally found in the application's
490      * configuration file.<p>
491      * The <tt>args</tt> Map can contain any value that will be used in one of the following
492      * scenarios <ul>
493      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
494      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
495      * on any MVC member of the group.</li>
496      * </ul>
497      * <p/>
498      * For example, with the following entry available in {@code Application.groovy}
499      * <p/>
500      * <pre>
501      * mvcGroups {
502      *     'foo' {
503      *         model      = 'com.acme.FooModel'
504      *         view       = 'com.acme.FooView'
505      *         controller = 'com.acme.FooController'
506      *     }
507      * }
508      * </pre>
509      * <p/>
510      * We can create two instances of the same group that share the same model instance in the following way:
511      * <p/>
512      * <pre>
513      * def (m1, v1, c1) = createMVCGroup('foo', 'foo1')
514      * def (m2, v2, c2) = createMVCGroup('foo', 'foo2', model: m1)
515      * assert fm1 == m2
516      * </pre>
517      * <p/>
518      * MVC groups must have an unique name.
519      *
520      * @param args    any useful values that can be set as properties on each MVC member or that
521      *                identify a member that can be shared with other groups.
522      * @param mvcType the type of group to build.
523      * @param mvcId the name to assign to the built group.
524      * @return a List with the canonical MVC members of the group
525      * @throws griffon.exceptions.MVCGroupInstantiationException
526      *          - if the type specified is not found in the application's
527      *          configuration or if a group with the same mvcId exists already.
528      */
529     @Nonnull
530     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId);
531 
532     /**
533      * Instantiates an MVC group of the specified type with a particular name.<p>
534      * MVC Groups must be previously configured with the application's metadata
535      * before they can be used. This registration process usually takes place automatically
536      * at boot time. The type of the group can be normally found in the application's
537      * configuration file.<p>
538      * The <tt>args</tt> Map can contain any value that will be used in one of the following
539      * scenarios <ul>
540      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
541      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
542      * on any MVC member of the group.</li>
543      * </ul>
544      * <p/>
545      * For example, with the following entry available in {@code Application.groovy}
546      * <p/>
547      * <pre>
548      * mvcGroups {
549      *     'foo' {
550      *         model      = 'com.acme.FooModel'
551      *         view       = 'com.acme.FooView'
552      *         controller = 'com.acme.FooController'
553      *     }
554      * }
555      * </pre>
556      * <p/>
557      * We can create two instances of the same group that share the same model instance in the following way:
558      * <p/>
559      * <pre>
560      * def (m1, v1, c1) = createMVCGroup('foo', 'foo1')
561      * def (m2, v2, c2) = createMVCGroup('foo', 'foo2', model: m1)
562      * assert fm1 == m2
563      * </pre>
564      * <p/>
565      * MVC groups must have an unique name.
566      *
567      * @param mvcType the type of group to build.
568      * @param mvcId the name to assign to the built group.
569      * @param args    any useful values that can be set as properties on each MVC member or that
570      *                identify a member that can be shared with other groups.
571      * @return a List with the canonical MVC members of the group
572      * @throws griffon.exceptions.MVCGroupInstantiationException
573      *          - if the type specified is not found in the application's
574      *          configuration or if a group with the same mvcId exists already.
575      */
576     @Nonnull
577     List<? extends GriffonMvcArtifact> createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args);
578 
579     /**
580      * Destroys an MVC group identified by a particular name.<p>
581      * <b>ATTENTION:</b> make sure to call the super implementation if you override this method
582      * otherwise group references will not be kept up to date.
583      *
584      * @param mvcId the name of the group to destroy and dispose.
585      */
586     void destroyMVCGroup(@Nonnull String mvcId);
587 
588     /**
589      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
590      * <p>This method is of particular interest when working with short lived MVC groups such as
591      * those used to build dialogs.<p/>
592      * <p>MVC Groups must be previously configured with the application's metadata
593      * before they can be used. This registration process usually takes place automatically
594      * at boot time. The type of the group can be normally found in the application's
595      * configuration file.</p>
596      * For example, with the following entry available in {@code Application.groovy}
597      * <p/>
598      * <pre>
599      * mvcGroups {
600      *     'foo' {
601      *         model      = 'com.acme.FooModel'
602      *         view       = 'com.acme.FooView'
603      *         controller = 'com.acme.FooController'
604      *    }
605      * }
606      * </pre>
607      * <p/>
608      * An instance of the "foo" group can be used as follows
609      * <p/>
610      * <pre>
611      * withMVCGroup("foo", new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
612      *     public void call(FooModel m, FooView v, FooController c) {
613      *         m.setSomeProperty(someValue);
614      *         c.invokeAnAction();
615      *     }
616      * });
617      * </pre>
618      *
619      * @param mvcType the type of group to build.
620      * @param handler a code block used to configure and manage the instantiated group
621      * @throws griffon.exceptions.MVCGroupInstantiationException
622      *          - if the type specified is not found in the application's
623      *          configuration
624      */
625     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull String mvcType, @Nonnull MVCCallable<M, V, C> handler);
626 
627     /**
628      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
629      * <p>This method is of particular interest when working with short lived MVC groups such as
630      * those used to build dialogs.<p/>
631      * <p>MVC Groups must be previously configured with the application's metadata
632      * before they can be used. This registration process usually takes place automatically
633      * at boot time. The type of the group can be normally found in the application's
634      * configuration file.</p>
635      * For example, with the following entry available in {@code Application.groovy}
636      * <p/>
637      * <pre>
638      * mvcGroups {
639      *     'foo' {
640      *         model      = 'com.acme.FooModel'
641      *         view       = 'com.acme.FooView'
642      *         controller = 'com.acme.FooController'
643      *     }
644      * }
645      * </pre>
646      * <p/>
647      * An instance of the "foo" group can be used as follows
648      * <p/>
649      * <pre>
650      * withMVCGroup("foo", "foo1", new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
651      *     public void call(FooModel m, FooView v, FooController c) {
652      *         m.setSomeProperty(someValue);
653      *         c.invokeAnAction();
654      *     }
655      * });
656      * </pre>
657      * <p/>
658      * MVC groups must have an unique name.
659      *
660      * @param mvcType the type of group to build.
661      * @param mvcId the name to assign to the built group.
662      * @param handler a code block used to configure and manage the instantiated group
663      * @throws griffon.exceptions.MVCGroupInstantiationException
664      *          - if the type specified is not found in the application's
665      *          configuration
666      */
667     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCCallable<M, V, C> handler);
668 
669     /**
670      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
671      * <p>This method is of particular interest when working with short lived MVC groups such as
672      * those used to build dialogs.<p/>
673      * <p>MVC Groups must be previously configured with the application's metadata
674      * before they can be used. This registration process usually takes place automatically
675      * at boot time. The type of the group can be normally found in the application's
676      * configuration file.</p>
677      * The <tt>args</tt> Map can contain any value that will be used in one of the following
678      * scenarios <ul>
679      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
680      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
681      * on any MVC member of the group.</li>
682      * For example, with the following entry available in {@code Application.groovy}
683      * <p/>
684      * <pre>
685      * mvcGroups {
686      *     'foo' {
687      *         model      = 'com.acme.FooModel'
688      *         view       = 'com.acme.FooView'
689      *         controller = 'com.acme.FooController'
690      *     }
691      * }
692      * </pre>
693      * <p/>
694      * An instance of the "foo" group can be used as follows
695      * <p/>
696      * <pre>
697      * Map<String, Object> map = ... // initialized elsewhere
698      * withMVCGroup("foo", "foo1", map, new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
699      *    public void call(FooModel m, FooView v, FooController c) {
700      *        m.setSomeProperty(someValue);
701      *        c.invokeAnAction();
702      *    }
703      * });
704      * </pre>
705      * <p/>
706      * MVC groups must have an unique name.
707      *
708      * @param mvcType the type of group to build.
709      * @param mvcId the name to assign to the built group.
710      * @param args    any useful values that can be set as properties on each MVC member or that
711      *                identify a member that can be shared with other groups.
712      * @param handler a code block used to configure and manage the instantiated group
713      * @throws griffon.exceptions.MVCGroupInstantiationException
714      *          - if the type specified is not found in the application's
715      *          configuration
716      */
717     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCCallable<M, V, C> handler);
718 
719     /**
720      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
721      * <p>This method is of particular interest when working with short lived MVC groups such as
722      * those used to build dialogs.<p/>
723      * <p>MVC Groups must be previously configured with the application's metadata
724      * before they can be used. This registration process usually takes place automatically
725      * at boot time. The type of the group can be normally found in the application's
726      * configuration file.</p>
727      * The <tt>args</tt> Map can contain any value that will be used in one of the following
728      * scenarios <ul>
729      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
730      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
731      * on any MVC member of the group.</li>
732      * For example, with the following entry available in {@code Application.groovy}
733      * <p/>
734      * <pre>
735      * mvcGroups {
736      *     'foo' {
737      *         model      = 'com.acme.FooModel'
738      *         view       = 'com.acme.FooView'
739      *         controller = 'com.acme.FooController'
740      *     }
741      * }
742      * </pre>
743      * <p/>
744      * An instance of the "foo" group can be used as follows
745      * <p/>
746      * <pre>
747      * Map<String, Object> map = ... // initialized elsewhere
748      * withMVCGroup("foo", "foo1", map, new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
749      *    public void call(FooModel m, FooView v, FooController c) {
750      *        m.setSomeProperty(someValue);
751      *        c.invokeAnAction();
752      *    }
753      * });
754      * </pre>
755      * <p/>
756      * MVC groups must have an unique name.
757      *
758      * @param args    any useful values that can be set as properties on each MVC member or that
759      *                identify a member that can be shared with other groups.
760      * @param mvcType the type of group to build.
761      * @param mvcId the name to assign to the built group.
762      * @param handler a code block used to configure and manage the instantiated group
763      * @throws griffon.exceptions.MVCGroupInstantiationException
764      *          - if the type specified is not found in the application's
765      *          configuration
766      */
767     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCCallable<M, V, C> handler);
768 
769     /**
770      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
771      * <p>This method is of particular interest when working with short lived MVC groups such as
772      * those used to build dialogs.<p/>
773      * <p>MVC Groups must be previously configured with the application's metadata
774      * before they can be used. This registration process usually takes place automatically
775      * at boot time. The type of the group can be normally found in the application's
776      * configuration file.</p>
777      * The <tt>args</tt> Map can contain any value that will be used in one of the following
778      * scenarios <ul>
779      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
780      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
781      * on any MVC member of the group.</li>
782      * For example, with the following entry available in {@code Application.groovy}
783      * <p/>
784      * <pre>
785      * mvcGroups {
786      *     'foo' {
787      *         model      = 'com.acme.FooModel'
788      *         view       = 'com.acme.FooView'
789      *         controller = 'com.acme.FooController'
790      *    }
791      * }
792      * </pre>
793      * <p/>
794      * An instance of the "foo" group can be used as follows
795      * <p/>
796      * <pre>
797      * Map<String, Object> map = ... // initialized elsewhere
798      * withMVCGroup("foo", map, new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
799      *    public void call(FooModel m, FooView v, FooController c) {
800      *        m.setSomeProperty(someValue);
801      *        c.invokeAnAction();
802      *    }
803      * });
804      * </pre>
805      *
806      * @param mvcType the type of group to build.
807      * @param args    any useful values that can be set as properties on each MVC member or that
808      *                identify a member that can be shared with other groups.
809      * @param handler a code block used to configure and manage the instantiated group
810      * @throws griffon.exceptions.MVCGroupInstantiationException
811      *          - if the type specified is not found in the application's
812      *          configuration
813      */
814     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCCallable<M, V, C> handler);
815 
816     /**
817      * Instantiates an MVC group of the specified type then destroys it after it has been handled.<p>
818      * <p>This method is of particular interest when working with short lived MVC groups such as
819      * those used to build dialogs.<p/>
820      * <p>MVC Groups must be previously configured with the application's metadata
821      * before they can be used. This registration process usually takes place automatically
822      * at boot time. The type of the group can be normally found in the application's
823      * configuration file.</p>
824      * The <tt>args</tt> Map can contain any value that will be used in one of the following
825      * scenarios <ul>
826      * <li>The key matches a member definition; the value will be used as the instance of such member.</li>
827      * <li>The key does not match a member definition, the value is assumed to be a property that can be set
828      * on any MVC member of the group.</li>
829      * For example, with the following entry available in {@code Application.groovy}
830      * <p/>
831      * <pre>
832      * mvcGroups {
833      *     'foo' {
834      *         model      = 'com.acme.FooModel'
835      *         view       = 'com.acme.FooView'
836      *         controller = 'com.acme.FooController'
837      *    }
838      * }
839      * </pre>
840      * <p/>
841      * An instance of the "foo" group can be used as follows
842      * <p/>
843      * <pre>
844      * Map<String, Object> map = ... // initialized elsewhere
845      * withMVCGroup("foo", map, new MVCCallable&lt;FooModel, FooView, FooController&gt;() {
846      *    public void call(FooModel m, FooView v, FooController c) {
847      *        m.setSomeProperty(someValue);
848      *        c.invokeAnAction();
849      *    }
850      * });
851      * </pre>
852      *
853      * @param args    any useful values that can be set as properties on each MVC member or that
854      *                identify a member that can be shared with other groups.
855      * @param mvcType the type of group to build.
856      * @param handler a code block used to configure and manage the instantiated group
857      * @throws griffon.exceptions.MVCGroupInstantiationException
858      *          - if the type specified is not found in the application's
859      *          configuration
860      */
861     <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull MVCCallable<M, V, C> handler);
862 }