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 }
|