AbstractGriffonAddon.java
001 /*
002  * Copyright 2010-2012 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.GriffonAddon;
020 import griffon.core.GriffonApplication;
021 import griffon.core.UIThreadManager;
022 import griffon.util.GriffonNameUtils;
023 import groovy.lang.Closure;
024 import groovy.lang.GroovyObjectSupport;
025 import groovy.util.FactoryBuilderSupport;
026 import org.codehaus.griffon.runtime.util.GriffonApplicationHelper;
027 import org.slf4j.Logger;
028 import org.slf4j.LoggerFactory;
029 
030 import java.io.InputStream;
031 import java.net.URL;
032 import java.util.ArrayList;
033 import java.util.LinkedHashMap;
034 import java.util.List;
035 import java.util.Map;
036 import java.util.concurrent.Callable;
037 import java.util.concurrent.ExecutorService;
038 import java.util.concurrent.Future;
039 
040 /**
041  * Base implementation of the GriffonAddon interface.
042  *
043  @author Andres Almiray
044  @since 0.9.2
045  */
046 public abstract class AbstractGriffonAddon extends GroovyObjectSupport implements GriffonAddon {
047     private final GriffonApplication app;
048     private final Logger log;
049     private final ResourceLocator resourceLocator = new ResourceLocator();
050 
051     protected final Map<String, Object> factories = new LinkedHashMap<String, Object>();
052     protected final Map<String, Closure> methods = new LinkedHashMap<String, Closure>();
053     protected final Map<String, Map<String, Closure>> props = new LinkedHashMap<String, Map<String, Closure>>();
054     protected final Map<String, Closure> events = new LinkedHashMap<String, Closure>();
055     protected final Map<String, Map<String, Object>> mvcGroups = new LinkedHashMap<String, Map<String, Object>>();
056     protected final List<Closure> attributeDelegates = new ArrayList<Closure>();
057     protected final List<Closure> preInstantiateDelegates = new ArrayList<Closure>();
058     protected final List<Closure> postInstantiateDelegates = new ArrayList<Closure>();
059     protected final List<Closure> postNodeCompletionDelegates = new ArrayList<Closure>();
060 
061     public AbstractGriffonAddon(GriffonApplication app) {
062         this(app, null);
063     }
064 
065     protected AbstractGriffonAddon(GriffonApplication app, String loggingCategory) {
066         this.app = app;
067         if (GriffonNameUtils.isBlank(loggingCategory)) loggingCategory = "griffon.addon." + getClass().getName();
068         log = LoggerFactory.getLogger(loggingCategory);
069     }
070 
071     public GriffonApplication getApp() {
072         return app;
073     }
074 
075     public Logger getLog() {
076         return log;
077     }
078 
079     /**
080      * Creates a new instance of the specified class and type.<br/>
081      * Triggers the Event.NEW_INSTANCE with the following parameters
082      <ul>
083      <li>clazz - the Class of the object</li>
084      <li>type - the symbolical type of the object</li>
085      <li>instance -> the object that was created</li>
086      </ul>
087      *
088      @param clazz the Class for which an instance must be created
089      @param type  a symbolical type, for example 'controller' or 'service'. May be null.
090      @return a newly instantiated object of type <tt>clazz</tt>. Implementations must be sure
091      *         to trigger an event of type Event.NEW_INSTANCE.
092      */
093     public Object newInstance(Class clazz, String type) {
094         return GriffonApplicationHelper.newInstance(getApp(), clazz, type);
095     }
096 
097     public void addonInit(GriffonApplication app) {
098     }
099 
100     public void addonPostInit(GriffonApplication app) {
101     }
102 
103     public void addonBuilderInit(GriffonApplication app, FactoryBuilderSupport builder) {
104     }
105 
106     public void addonBuilderPostInit(GriffonApplication app, FactoryBuilderSupport builder) {
107     }
108 
109     public Map<String, Object> getFactories() {
110         return factories;
111     }
112 
113     public Map<String, Closure> getMethods() {
114         return methods;
115     }
116 
117     public Map<String, Map<String, Closure>> getProps() {
118         return props;
119     }
120 
121     public Map<String, Closure> getEvents() {
122         return events;
123     }
124 
125     public Map<String, Map<String, Object>> getMvcGroups() {
126         return mvcGroups;
127     }
128 
129     public List<Closure> getAttributeDelegates() {
130         return attributeDelegates;
131     }
132 
133     public List<Closure> getPreInstantiateDelegates() {
134         return preInstantiateDelegates;
135     }
136 
137     public List<Closure> getPostInstantiateDelegates() {
138         return postInstantiateDelegates;
139     }
140 
141     public List<Closure> getPostNodeCompletionDelegates() {
142         return postNodeCompletionDelegates;
143     }
144 
145     public boolean isUIThread() {
146         return UIThreadManager.getInstance().isUIThread();
147     }
148 
149     // TODO @deprecated - remove before 1.0
150     public void execAsync(Runnable runnable) {
151         execInsideUIAsync(runnable);
152     }
153 
154     // TODO @deprecated - remove before 1.0
155     public void execSync(Runnable runnable) {
156         execInsideUIAsync(runnable);
157     }
158 
159     // TODO @deprecated - remove before 1.0
160     public void execOutside(Runnable runnable) {
161         execOutsideUI(runnable);
162     }
163 
164     public void execInsideUIAsync(Runnable runnable) {
165         UIThreadManager.getInstance().executeAsync(runnable);
166     }
167 
168     public void execInsideUISync(Runnable runnable) {
169         UIThreadManager.getInstance().executeSync(runnable);
170     }
171 
172     public void execOutsideUI(Runnable runnable) {
173         UIThreadManager.getInstance().executeOutside(runnable);
174     }
175 
176     public Future execFuture(ExecutorService executorService, Closure closure) {
177         return UIThreadManager.getInstance().executeFuture(executorService, closure);
178     }
179 
180     public Future execFuture(Closure closure) {
181         return UIThreadManager.getInstance().executeFuture(closure);
182     }
183 
184     public Future execFuture(ExecutorService executorService, Callable callable) {
185         return UIThreadManager.getInstance().executeFuture(executorService, callable);
186     }
187 
188     public Future execFuture(Callable callable) {
189         return UIThreadManager.getInstance().executeFuture(callable);
190     }
191 
192     protected Map<String, String> groupDef(String[][] parts) {
193         Map<String, String> map = new LinkedHashMap<String, String>();
194         for (int i = 0; i < parts.length; i++) {
195             map.put(parts[i][0], parts[i][1]);
196         }
197         return map;
198     }
199 
200     public InputStream getResourceAsStream(String name) {
201         return resourceLocator.getResourceAsStream(name);
202     }
203 
204     public URL getResourceAsURL(String name) {
205         return resourceLocator.getResourceAsURL(name);
206     }
207 
208     public List<URL> getResources(String name) {
209         return resourceLocator.getResources(name);
210     }
211 }