001 /*
002 * Copyright 2010-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.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 public void execInsideUIAsync(Runnable runnable) {
150 UIThreadManager.getInstance().executeAsync(runnable);
151 }
152
153 public void execInsideUISync(Runnable runnable) {
154 UIThreadManager.getInstance().executeSync(runnable);
155 }
156
157 public void execOutsideUI(Runnable runnable) {
158 UIThreadManager.getInstance().executeOutside(runnable);
159 }
160
161 public Future execFuture(ExecutorService executorService, Closure closure) {
162 return UIThreadManager.getInstance().executeFuture(executorService, closure);
163 }
164
165 public Future execFuture(Closure closure) {
166 return UIThreadManager.getInstance().executeFuture(closure);
167 }
168
169 public Future execFuture(ExecutorService executorService, Callable callable) {
170 return UIThreadManager.getInstance().executeFuture(executorService, callable);
171 }
172
173 public Future execFuture(Callable callable) {
174 return UIThreadManager.getInstance().executeFuture(callable);
175 }
176
177 protected Map<String, Object> groupDef(String[][] parts) {
178 Map<String, Object> map = new LinkedHashMap<String, Object>();
179 for (int i = 0; i < parts.length; i++) {
180 map.put(parts[i][0], parts[i][1]);
181 }
182 return map;
183 }
184
185 public InputStream getResourceAsStream(String name) {
186 return resourceLocator.getResourceAsStream(name);
187 }
188
189 public URL getResourceAsURL(String name) {
190 return resourceLocator.getResourceAsURL(name);
191 }
192
193 public List<URL> getResources(String name) {
194 return resourceLocator.getResources(name);
195 }
196 }
|