AbstractGriffonApplication.java
001 /*
002  * Copyright 2008-2013 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 
017 package org.codehaus.griffon.runtime.core;
018 
019 import griffon.core.*;
020 import griffon.core.controller.GriffonControllerActionManager;
021 import griffon.core.i18n.MessageSource;
022 import griffon.core.i18n.NoSuchMessageException;
023 import griffon.core.resources.NoSuchResourceException;
024 import griffon.core.resources.ResourceResolver;
025 import griffon.exceptions.GriffonException;
026 import griffon.util.*;
027 import groovy.lang.Binding;
028 import groovy.lang.Closure;
029 import groovy.util.ConfigObject;
030 import groovy.util.FactoryBuilderSupport;
031 import org.codehaus.griffon.runtime.util.ExecutorServiceHolder;
032 import org.codehaus.griffon.runtime.util.GriffonApplicationHelper;
033 import org.codehaus.griffon.runtime.util.MVCGroupExceptionHandler;
034 import org.slf4j.Logger;
035 import org.slf4j.LoggerFactory;
036 
037 import java.io.InputStream;
038 import java.net.URL;
039 import java.util.*;
040 import java.util.concurrent.Callable;
041 import java.util.concurrent.CountDownLatch;
042 import java.util.concurrent.ExecutorService;
043 import java.util.concurrent.Future;
044 
045 import static java.util.Arrays.asList;
046 
047 /**
048  * Implements the basics for a skeleton GriffonApplication.<p>
049  *
050  @author Danno Ferrin
051  @author Andres Almiray
052  */
053 public abstract class AbstractGriffonApplication extends AbstractObservable implements GriffonApplication {
054     private Binding bindings = new Binding();
055     private ConfigObject config;
056     private ConfigObject builderConfig;
057     private Object eventsConfig;
058     private AddonManager addonManager;
059     private ArtifactManager artifactManager;
060     private MVCGroupManager mvcGroupManager;
061     private ServiceManager serviceManager;
062     private MessageSource messageSource;
063     private ResourceResolver resourceResolver;
064     private GriffonControllerActionManager actionManager;
065 
066     private Locale locale = Locale.getDefault();
067     public static final String[] EMPTY_ARGS = new String[0];
068     protected final Object[] lock = new Object[0];
069     private ApplicationPhase phase = ApplicationPhase.INITIALIZE;
070 
071     private EventRouter eventRouter = new NoopEventRouter();
072     private final ResourceLocator resourceLocator = new ResourceLocator();
073     private final List<ShutdownHandler> shutdownHandlers = new ArrayList<ShutdownHandler>();
074     private final String[] startupArgs;
075     private final Object shutdownLock = new Object();
076     private final Logger log;
077 
078     public AbstractGriffonApplication() {
079         this(EMPTY_ARGS);
080     }
081 
082     public AbstractGriffonApplication(String[] args) {
083         startupArgs = new String[args.length];
084         System.arraycopy(args, 0, startupArgs, 0, args.length);
085         ApplicationHolder.setApplication(this);
086         log = LoggerFactory.getLogger(getClass());
087         MVCGroupExceptionHandler.registerWith(this);
088     }
089 
090     public EventRouter getEventRouter() {
091         return eventRouter;
092     }
093 
094     public void setEventRouter(EventRouter eventRouter) {
095         this.eventRouter = eventRouter;
096     }
097 
098     public Binding getBindings() {
099         return bindings;
100     }
101 
102     public void setBindings(Binding bindings) {
103         this.bindings = bindings;
104     }
105 
106     public ConfigObject getConfig() {
107         return config;
108     }
109 
110     public void setConfig(ConfigObject config) {
111         this.config = config;
112     }
113 
114     public ConfigObject getBuilderConfig() {
115         return builderConfig;
116     }
117 
118     public void setBuilderConfig(ConfigObject builderConfig) {
119         this.builderConfig = builderConfig;
120     }
121 
122     public Object getEventsConfig() {
123         return eventsConfig;
124     }
125 
126     public void setEventsConfig(Object eventsConfig) {
127         this.eventsConfig = eventsConfig;
128     }
129 
130     public Map<String, ? extends GriffonModel> getModels() {
131         return getMvcGroupManager().getModels();
132     }
133 
134     public Map<String, ? extends GriffonView> getViews() {
135         return getMvcGroupManager().getViews();
136     }
137 
138     public Map<String, ? extends GriffonController> getControllers() {
139         return getMvcGroupManager().getControllers();
140     }
141 
142     public Map<String, ? extends FactoryBuilderSupport> getBuilders() {
143         return getMvcGroupManager().getBuilders();
144     }
145 
146     public Map<String, MVCGroup> getGroups() {
147         return getMvcGroupManager().getGroups();
148     }
149 
150     public AddonManager getAddonManager() {
151         return addonManager;
152     }
153 
154     public void setAddonManager(AddonManager addonManager) {
155         this.addonManager = addonManager;
156     }
157 
158     public ArtifactManager getArtifactManager() {
159         return artifactManager;
160     }
161 
162     public void setArtifactManager(ArtifactManager artifactManager) {
163         this.artifactManager = artifactManager;
164     }
165 
166     public MVCGroupManager getMvcGroupManager() {
167         return mvcGroupManager;
168     }
169 
170     public void setMvcGroupManager(MVCGroupManager mvcGroupManager) {
171         this.mvcGroupManager = mvcGroupManager;
172     }
173 
174     public ServiceManager getServiceManager() {
175         return serviceManager;
176     }
177 
178     public void setServiceManager(ServiceManager serviceManager) {
179         this.serviceManager = serviceManager;
180     }
181 
182     public Map<String, ? extends GriffonService> getServices() {
183         return serviceManager.getServices();
184     }
185 
186     public Locale getLocale() {
187         return locale;
188     }
189 
190     public String[] getStartupArgs() {
191         return startupArgs;
192     }
193 
194     public Logger getLog() {
195         return log;
196     }
197 
198     public void setLocaleAsString(String locale) {
199         setLocale(GriffonApplicationHelper.parseLocale(locale));
200     }
201 
202     public void setLocale(Locale locale) {
203         Locale oldValue = this.locale;
204         this.locale = locale;
205         Locale.setDefault(locale);
206         firePropertyChange("locale", oldValue, locale);
207     }
208 
209     public Metadata getMetadata() {
210         return Metadata.getCurrent();
211     }
212 
213     public Class getAppConfigClass() {
214         return loadConfigurationalClass(GriffonApplication.Configuration.APPLICATION.getName());
215     }
216 
217     public Class getConfigClass() {
218         return loadConfigurationalClass(GriffonApplication.Configuration.CONFIG.getName());
219     }
220 
221     public Class getBuilderClass() {
222         return loadConfigurationalClass(GriffonApplication.Configuration.BUILDER.getName());
223     }
224 
225     public Class getEventsClass() {
226         return loadConfigurationalClass(GriffonApplication.Configuration.EVENTS.getName());
227     }
228 
229     public void initialize() {
230         if (phase == ApplicationPhase.INITIALIZE) {
231             GriffonApplicationHelper.prepare(this);
232         }
233     }
234 
235     public void ready() {
236         if (phase != ApplicationPhase.STARTUPreturn;
237 
238         phase = ApplicationPhase.READY;
239         event(GriffonApplication.Event.READY_START.getName(), asList(this));
240         GriffonApplicationHelper.runLifecycleHandler(GriffonApplication.Lifecycle.READY.getName()this);
241         event(GriffonApplication.Event.READY_END.getName(), asList(this));
242         phase = ApplicationPhase.MAIN;
243     }
244 
245     public boolean canShutdown() {
246         event(GriffonApplication.Event.SHUTDOWN_REQUESTED.getName(), asList(this));
247         synchronized (shutdownLock) {
248             for (ShutdownHandler handler : shutdownHandlers) {
249                 if (!handler.canShutdown(this)) {
250                     event(GriffonApplication.Event.SHUTDOWN_ABORTED.getName(), asList(this));
251                     if (log.isDebugEnabled()) {
252                         try {
253                             log.debug("Shutdown aborted by " + handler);
254                         catch (UnsupportedOperationException uoe) {
255                             log.debug("Shutdown aborted by a handler");
256                         }
257                     }
258                     return false;
259                 }
260             }
261         }
262         return true;
263     }
264 
265     public boolean shutdown() {
266         // avoids reentrant calls to shutdown()
267         // once permission to quit has been granted
268         if (phase == ApplicationPhase.SHUTDOWNreturn false;
269 
270         if (!canShutdown()) return false;
271         log.info("Shutdown is in process");
272 
273         // signal that shutdown is in process
274         phase = ApplicationPhase.SHUTDOWN;
275 
276         // stage 1 - alert all app event handlers
277         // wait for all handlers to complete before proceeding
278         // with stage #2 if and only if the current thread is
279         // the ui thread
280         log.debug("Shutdown stage 1: notify all event listeners");
281         if (isEventPublishingEnabled()) {
282             final CountDownLatch latch = new CountDownLatch(isUIThread() 0);
283             addApplicationEventListener(GriffonApplication.Event.SHUTDOWN_START.getName()new RunnableWithArgs() {
284                 @Override
285                 public void run(Object[] args) {
286                     latch.countDown();
287                 }
288             });
289             event(GriffonApplication.Event.SHUTDOWN_START.getName(), asList(this));
290             try {
291                 latch.await();
292             catch (InterruptedException e) {
293                 // ignore
294             }
295         }
296 
297         // stage 2 - alert all shutdown handlers
298         log.debug("Shutdown stage 2: notify all shutdown handlers");
299         synchronized (shutdownLock) {
300             for (ShutdownHandler handler : shutdownHandlers) {
301                 handler.onShutdown(this);
302             }
303         }
304 
305         // stage 3 - destroy all mvc groups
306         log.debug("Shutdown stage 3: destroy all MVC groups");
307         List<String> mvcNames = new ArrayList<String>();
308         if (getMvcGroupManager() != null) {
309             mvcNames.addAll(getMvcGroupManager().getGroups().keySet());
310             for (String name : mvcNames) {
311                 destroyMVCGroup(name);
312             }
313         }
314 
315         // stage 4 - call shutdown script
316         log.debug("Shutdown stage 4: execute Shutdown script");
317         GriffonApplicationHelper.runLifecycleHandler(GriffonApplication.Lifecycle.SHUTDOWN.getName()this);
318 
319         ExecutorServiceHolder.shutdownAll();
320 
321         return true;
322     }
323 
324     public void startup() {
325         if (phase != ApplicationPhase.INITIALIZEreturn;
326 
327         phase = ApplicationPhase.STARTUP;
328         event(GriffonApplication.Event.STARTUP_START.getName(), asList(this));
329 
330         Object startupGroups = ConfigUtils.getConfigValue(getConfig()"application.startupGroups");
331         if (startupGroups instanceof List) {
332             if (log.isInfoEnabled()) {
333                 log.info("Initializing all startup groups: " + startupGroups);
334             }
335 
336             for (String groupName : (List<String>startupGroups) {
337                 createMVCGroup(groupName);
338             }
339         else if (startupGroups != null && startupGroups.getClass().isArray()) {
340             Object[] groups = (Object[]) startupGroups;
341             if (log.isInfoEnabled()) {
342                 log.info("Initializing all startup groups: " + Arrays.toString(groups));
343             }
344 
345             for (Object groupName : groups) {
346                 createMVCGroup(String.valueOf(groupName));
347             }
348         }
349 
350         GriffonApplicationHelper.runLifecycleHandler(GriffonApplication.Lifecycle.STARTUP.getName()this);
351 
352         event(GriffonApplication.Event.STARTUP_END.getName(), asList(this));
353     }
354 
355     public void event(String eventName) {
356         eventRouter.publish(eventName, Collections.emptyList());
357     }
358 
359     public void event(String eventName, List params) {
360         eventRouter.publish(eventName, params);
361     }
362 
363     public void eventOutsideUI(String eventName) {
364         eventRouter.publishOutsideUI(eventName, Collections.emptyList());
365     }
366 
367     public void eventOutsideUI(String eventName, List params) {
368         eventRouter.publishOutsideUI(eventName, params);
369     }
370 
371     public void eventAsync(String eventName) {
372         eventRouter.publishAsync(eventName, Collections.emptyList());
373     }
374 
375     public void eventAsync(String eventName, List params) {
376         eventRouter.publishAsync(eventName, params);
377     }
378 
379     public void addApplicationEventListener(Object listener) {
380         eventRouter.addEventListener(listener);
381     }
382 
383     public void removeApplicationEventListener(Object listener) {
384         eventRouter.removeEventListener(listener);
385     }
386 
387     public void addApplicationEventListener(String eventName, Closure listener) {
388         eventRouter.addEventListener(eventName, listener);
389     }
390 
391     public void removeApplicationEventListener(String eventName, Closure listener) {
392         eventRouter.removeEventListener(eventName, listener);
393     }
394 
395     public void addApplicationEventListener(String eventName, RunnableWithArgs listener) {
396         eventRouter.addEventListener(eventName, listener);
397     }
398 
399     public void removeApplicationEventListener(String eventName, RunnableWithArgs listener) {
400         eventRouter.removeEventListener(eventName, listener);
401     }
402 
403     public boolean isEventPublishingEnabled() {
404         return eventRouter.isEnabled();
405     }
406 
407     public void setEventPublishingEnabled(boolean enabled) {
408         eventRouter.setEnabled(enabled);
409     }
410 
411     public Object createApplicationContainer() {
412         return null;
413     }
414 
415     public void addShutdownHandler(ShutdownHandler handler) {
416         if (handler != null && !shutdownHandlers.contains(handler)) shutdownHandlers.add(handler);
417     }
418 
419     public void removeShutdownHandler(ShutdownHandler handler) {
420         if (handler != nullshutdownHandlers.remove(handler);
421     }
422 
423     public ApplicationPhase getPhase() {
424         synchronized (lock) {
425             return this.phase;
426         }
427     }
428 
429     protected void setPhase(ApplicationPhase phase) {
430         synchronized (lock) {
431             this.phase = phase;
432         }
433     }
434 
435     // -----------------------
436 
437     public boolean isUIThread() {
438         return UIThreadManager.getInstance().isUIThread();
439     }
440 
441     public void execInsideUIAsync(Runnable runnable) {
442         UIThreadManager.getInstance().executeAsync(runnable);
443     }
444 
445     public void execInsideUISync(Runnable runnable) {
446         UIThreadManager.getInstance().executeSync(runnable);
447     }
448 
449     public void execOutsideUI(Runnable runnable) {
450         UIThreadManager.getInstance().executeOutside(runnable);
451     }
452 
453     public <R> Future<R> execFuture(ExecutorService executorService, Closure<R> closure) {
454         return UIThreadManager.getInstance().executeFuture(executorService, closure);
455     }
456 
457     public <R> Future<R> execFuture(Closure<R> closure) {
458         return UIThreadManager.getInstance().executeFuture(closure);
459     }
460 
461     public <R> Future<R> execFuture(ExecutorService executorService, Callable<R> callable) {
462         return UIThreadManager.getInstance().executeFuture(executorService, callable);
463     }
464 
465     public <R> Future<R> execFuture(Callable<R> callable) {
466         return UIThreadManager.getInstance().executeFuture(callable);
467     }
468 
469     public Object newInstance(Class clazz, String type) {
470         return GriffonApplicationHelper.newInstance(this, clazz, type);
471     }
472 
473     public MVCGroup buildMVCGroup(String mvcType) {
474         return getMvcGroupManager().buildMVCGroup(mvcType, null, Collections.<String, Object>emptyMap());
475     }
476 
477     public MVCGroup buildMVCGroup(String mvcType, String mvcName) {
478         return getMvcGroupManager().buildMVCGroup(mvcType, mvcName, Collections.<String, Object>emptyMap());
479     }
480 
481     public MVCGroup buildMVCGroup(Map<String, Object> args, String mvcType) {
482         return getMvcGroupManager().buildMVCGroup(mvcType, null, args);
483     }
484 
485     public MVCGroup buildMVCGroup(String mvcType, Map<String, Object> args) {
486         return getMvcGroupManager().buildMVCGroup(mvcType, null, args);
487     }
488 
489     public MVCGroup buildMVCGroup(Map<String, Object> args, String mvcType, String mvcName) {
490         return getMvcGroupManager().buildMVCGroup(mvcType, mvcName, args);
491     }
492 
493     public MVCGroup buildMVCGroup(String mvcType, String mvcName, Map<String, Object> args) {
494         return getMvcGroupManager().buildMVCGroup(mvcType, mvcName, args);
495     }
496 
497     public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType) {
498         return getMvcGroupManager().createMVCGroup(mvcType, null, Collections.<String, Object>emptyMap());
499     }
500 
501     public List<? extends GriffonMvcArtifact> createMVCGroup(Map<String, Object> args, String mvcType) {
502         return getMvcGroupManager().createMVCGroup(mvcType, null, args);
503     }
504 
505     public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, Map<String, Object> args) {
506         return getMvcGroupManager().createMVCGroup(mvcType, null, args);
507     }
508 
509     public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, String mvcName) {
510         return getMvcGroupManager().createMVCGroup(mvcType, mvcName, Collections.<String, Object>emptyMap());
511     }
512 
513     public List<? extends GriffonMvcArtifact> createMVCGroup(Map<String, Object> args, String mvcType, String mvcName) {
514         return getMvcGroupManager().createMVCGroup(mvcType, mvcName, args);
515     }
516 
517     public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, String mvcName, Map<String, Object> args) {
518         return getMvcGroupManager().createMVCGroup(mvcType, mvcName, args);
519     }
520 
521     public void destroyMVCGroup(String mvcName) {
522         getMvcGroupManager().destroyMVCGroup(mvcName);
523     }
524 
525     public void withMVCGroup(String mvcType, Closure handler) {
526         getMvcGroupManager().withMVCGroup(mvcType, null, Collections.<String, Object>emptyMap(), handler);
527     }
528 
529     public void withMVCGroup(String mvcType, String mvcName, Closure handler) {
530         getMvcGroupManager().withMVCGroup(mvcType, mvcName, Collections.<String, Object>emptyMap(), handler);
531     }
532 
533     public void withMVCGroup(String mvcType, Map<String, Object> args, Closure handler) {
534         getMvcGroupManager().withMVCGroup(mvcType, null, args, handler);
535     }
536 
537     public void withMVCGroup(Map<String, Object> args, String mvcType, Closure handler) {
538         getMvcGroupManager().withMVCGroup(mvcType, null, args, handler);
539     }
540 
541     public void withMVCGroup(String mvcType, String mvcName, Map<String, Object> args, Closure handler) {
542         getMvcGroupManager().withMVCGroup(mvcType, mvcName, args, handler);
543     }
544 
545     public void withMVCGroup(Map<String, Object> args, String mvcType, String mvcName, Closure handler) {
546         getMvcGroupManager().withMVCGroup(mvcType, mvcName, args, handler);
547     }
548 
549     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, MVCClosure<M, V, C> handler) {
550         getMvcGroupManager().withMVCGroup(mvcType, null, Collections.<String, Object>emptyMap(), handler);
551     }
552 
553     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, String mvcName, MVCClosure<M, V, C> handler) {
554         getMvcGroupManager().withMVCGroup(mvcType, mvcName, Collections.<String, Object>emptyMap(), handler);
555     }
556 
557     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, Map<String, Object> args, MVCClosure<M, V, C> handler) {
558         getMvcGroupManager().withMVCGroup(mvcType, null, args, handler);
559     }
560 
561     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(Map<String, Object> args, String mvcType, MVCClosure<M, V, C> handler) {
562         getMvcGroupManager().withMVCGroup(mvcType, null, args, handler);
563     }
564 
565     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, String mvcName, Map<String, Object> args, MVCClosure<M, V, C> handler) {
566         getMvcGroupManager().withMVCGroup(mvcType, mvcName, args, handler);
567     }
568 
569     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(Map<String, Object> args, String mvcType, String mvcName, MVCClosure<M, V, C> handler) {
570         getMvcGroupManager().withMVCGroup(mvcType, mvcName, args, handler);
571     }
572 
573     private Class<?> loadClass(String className) {
574         try {
575             return ApplicationClassLoader.get().loadClass(className);
576         catch (ClassNotFoundException e) {
577             // ignored
578         }
579         return null;
580     }
581 
582     private Class<?> loadConfigurationalClass(String className) {
583         if (!className.contains(".")) {
584             String fixedClassName = "config." + className;
585             try {
586                 return ApplicationClassLoader.get().loadClass(fixedClassName);
587             catch (ClassNotFoundException cnfe) {
588                 if (cnfe.getMessage().equals(fixedClassName)) {
589                     return loadClass(className);
590                 else {
591                     throw new GriffonException(cnfe);
592                 }
593             }
594         }
595         return loadClass(className);
596     }
597 
598     public InputStream getResourceAsStream(String name) {
599         return resourceLocator.getResourceAsStream(name);
600     }
601 
602     public URL getResourceAsURL(String name) {
603         return resourceLocator.getResourceAsURL(name);
604     }
605 
606     public List<URL> getResources(String name) {
607         return resourceLocator.getResources(name);
608     }
609 
610     public MessageSource getMessageSource() {
611         return messageSource;
612     }
613 
614     public void setMessageSource(MessageSource messageSource) {
615         this.messageSource = messageSource;
616     }
617 
618     public String getMessage(String keythrows NoSuchMessageException {
619         return messageSource.getMessage(key);
620     }
621 
622     public String getMessage(String key, Locale localethrows NoSuchMessageException {
623         return messageSource.getMessage(key, locale);
624     }
625 
626     public String getMessage(String key, Object[] argsthrows NoSuchMessageException {
627         return messageSource.getMessage(key, args);
628     }
629 
630     public String getMessage(String key, Object[] args, Locale localethrows NoSuchMessageException {
631         return messageSource.getMessage(key, args, locale);
632     }
633 
634     public String getMessage(String key, List argsthrows NoSuchMessageException {
635         return messageSource.getMessage(key, args);
636     }
637 
638     public String getMessage(String key, List args, Locale localethrows NoSuchMessageException {
639         return messageSource.getMessage(key, args, locale);
640     }
641 
642     public String getMessage(String key, String defaultMessage) {
643         return messageSource.getMessage(key, defaultMessage);
644     }
645 
646     public String getMessage(String key, String defaultMessage, Locale locale) {
647         return messageSource.getMessage(key, defaultMessage, locale);
648     }
649 
650     public String getMessage(String key, Object[] args, String defaultMessage) {
651         return messageSource.getMessage(key, args, defaultMessage);
652     }
653 
654     public String getMessage(String key, Object[] args, String defaultMessage, Locale locale) {
655         return messageSource.getMessage(key, args, defaultMessage, locale);
656     }
657 
658     public String getMessage(String key, List args, String defaultMessage) {
659         return messageSource.getMessage(key, args, defaultMessage);
660     }
661 
662     public String getMessage(String key, List args, String defaultMessage, Locale locale) {
663         return messageSource.getMessage(key, args, defaultMessage, locale);
664     }
665 
666     public String getMessage(String key, Map<String, Object> argsthrows NoSuchMessageException {
667         return messageSource.getMessage(key, args);
668     }
669 
670     public String getMessage(String key, Map<String, Object> args, Locale localethrows NoSuchMessageException {
671         return messageSource.getMessage(key, args, locale);
672     }
673 
674     public String getMessage(String key, Map<String, Object> args, String defaultMessage) {
675         return messageSource.getMessage(key, args, defaultMessage);
676     }
677 
678     public String getMessage(String key, Map<String, Object> args, String defaultMessage, Locale locale) {
679         return messageSource.getMessage(key, args, defaultMessage, locale);
680     }
681 
682     public ResourceResolver resolveResourceResolver() {
683         return resourceResolver;
684     }
685 
686     public void setResourceResolver(ResourceResolver resourceResolver) {
687         this.resourceResolver = resourceResolver;
688     }
689 
690     public Object resolveResource(String keythrows NoSuchResourceException {
691         return resourceResolver.resolveResource(key);
692     }
693 
694     public Object resolveResource(String key, Locale localethrows NoSuchResourceException {
695         return resourceResolver.resolveResource(key, locale);
696     }
697 
698     public Object resolveResource(String key, Object[] argsthrows NoSuchResourceException {
699         return resourceResolver.resolveResource(key, args);
700     }
701 
702     public Object resolveResource(String key, Object[] args, Locale localethrows NoSuchResourceException {
703         return resourceResolver.resolveResource(key, args, locale);
704     }
705 
706     public Object resolveResource(String key, List argsthrows NoSuchResourceException {
707         return resourceResolver.resolveResource(key, args);
708     }
709 
710     public Object resolveResource(String key, List args, Locale localethrows NoSuchResourceException {
711         return resourceResolver.resolveResource(key, args, locale);
712     }
713 
714     public Object resolveResource(String key, Object defaultValue) {
715         return resourceResolver.resolveResource(key, defaultValue);
716     }
717 
718     public Object resolveResource(String key, Object defaultValue, Locale locale) {
719         return resourceResolver.resolveResource(key, defaultValue, locale);
720     }
721 
722     public Object resolveResource(String key, Object[] args, Object defaultValue) {
723         return resourceResolver.resolveResource(key, args, defaultValue);
724     }
725 
726     public Object resolveResource(String key, Object[] args, Object defaultValue, Locale locale) {
727         return resourceResolver.resolveResource(key, args, defaultValue, locale);
728     }
729 
730     public Object resolveResource(String key, List args, Object defaultValue) {
731         return resourceResolver.resolveResource(key, args, defaultValue);
732     }
733 
734     public Object resolveResource(String key, List args, Object defaultValue, Locale locale) {
735         return resourceResolver.resolveResource(key, args, defaultValue, locale);
736     }
737 
738     public Object resolveResource(String key, Map<String, Object> argsthrows NoSuchResourceException {
739         return resourceResolver.resolveResource(key, args);
740     }
741 
742     public Object resolveResource(String key, Map<String, Object> args, Locale localethrows NoSuchResourceException {
743         return resourceResolver.resolveResource(key, args, locale);
744     }
745 
746     public Object resolveResource(String key, Map<String, Object> args, Object defaultValue) {
747         return resourceResolver.resolveResource(key, args, defaultValue);
748     }
749 
750     public Object resolveResource(String key, Map<String, Object> args, Object defaultValue, Locale locale) {
751         return resourceResolver.resolveResource(key, args, defaultValue, locale);
752     }
753 
754     public GriffonControllerActionManager getActionManager() {
755         return actionManager;
756     }
757 
758     public void setActionManager(GriffonControllerActionManager actionManager) {
759         this.actionManager = actionManager;
760     }
761 }