001 /*
002 * Copyright 2009-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.exceptions.MVCGroupConfigurationException;
021 import groovy.lang.Closure;
022 import groovy.util.FactoryBuilderSupport;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 import java.util.*;
027
028 import static griffon.util.GriffonExceptionHandler.sanitize;
029 import static griffon.util.GriffonNameUtils.isBlank;
030
031 /**
032 * Base implementation of the {@code MVCGroupManager} interface.
033 *
034 * @author Andres Almiray
035 * @since 0.9.4
036 */
037 public abstract class AbstractMVCGroupManager implements MVCGroupManager {
038 private static final Logger LOG = LoggerFactory.getLogger(AbstractMVCGroupManager.class);
039
040 private final GriffonApplication app;
041
042 private final Map<String, MVCGroupConfiguration> configurations = new LinkedHashMap<String, MVCGroupConfiguration>();
043 private final Map<String, MVCGroup> groups = new LinkedHashMap<String, MVCGroup>();
044 private final Object lock = new Object();
045 private boolean initialized;
046
047 public AbstractMVCGroupManager(GriffonApplication app) {
048 this.app = app;
049 }
050
051 public GriffonApplication getApp() {
052 return app;
053 }
054
055 public Map<String, MVCGroupConfiguration> getConfigurations() {
056 synchronized (lock) {
057 return Collections.unmodifiableMap(configurations);
058 }
059 }
060
061 public Map<String, MVCGroup> getGroups() {
062 synchronized (lock) {
063 return Collections.unmodifiableMap(groups);
064 }
065 }
066
067 public MVCGroupConfiguration findConfiguration(String mvcType) {
068 MVCGroupConfiguration configuration = null;
069 synchronized (lock) {
070 configuration = configurations.get(mvcType);
071 }
072
073 if (configuration == null) {
074 throw new MVCGroupConfigurationException("Unknown MVC type '" + mvcType + "'. Known types are " + configurations.keySet(), mvcType);
075 }
076 return configuration;
077 }
078
079 public MVCGroup findGroup(String mvcId) {
080 synchronized (lock) {
081 if (LOG.isDebugEnabled()) {
082 LOG.debug("Searching group " + mvcId);
083 }
084 return groups.get(mvcId);
085 }
086 }
087
088 public MVCGroup getAt(String mvcId) {
089 return findGroup(mvcId);
090 }
091
092 public final void initialize(Map<String, MVCGroupConfiguration> configurations) {
093 synchronized (lock) {
094 if (!initialized) {
095 doInitialize(configurations);
096 initialized = true;
097 }
098 }
099 }
100
101 public void addConfiguration(MVCGroupConfiguration configuration) {
102 synchronized (lock) {
103 if (initialized && configurations.get(configuration.getMvcType()) != null) {
104 return;
105 }
106 configurations.put(configuration.getMvcType(), configuration);
107 }
108 }
109
110 public void removeConfiguration(MVCGroupConfiguration configuration) {
111 if (configuration != null) {
112 removeConfiguration(configuration.getMvcType());
113 }
114 }
115
116 public void removeConfiguration(String name) {
117 if (!isBlank(name)) {
118 synchronized (lock) {
119 configurations.remove(name);
120 }
121 }
122 }
123
124 protected void addGroup(MVCGroup group) {
125 synchronized (lock) {
126 if (group != null) {
127 if (LOG.isDebugEnabled()) {
128 LOG.debug("Adding group " + group.getMvcId() + ":" + group);
129 }
130 groups.put(group.getMvcId(), group);
131 }
132 }
133 }
134
135 protected void removeGroup(MVCGroup group) {
136 synchronized (lock) {
137 if (group != null) {
138 if (LOG.isDebugEnabled()) {
139 LOG.debug("Removing group " + group.getMvcId() + ":" + group);
140 }
141 groups.remove(group.getMvcId());
142 }
143 }
144 }
145
146 public MVCGroupConfiguration cloneMVCGroupConfiguration(String mvcType, Map<String, Object> config) {
147 MVCGroupConfiguration configuration = findConfiguration(mvcType);
148 Map<String, Object> configCopy = new LinkedHashMap<String, Object>();
149 configCopy.putAll(configuration.getConfig());
150 if (config != null) configCopy.putAll(config);
151 return newMVCGroupConfiguration(mvcType, configuration.getMembers(), configCopy);
152 }
153
154 protected abstract void doInitialize(Map<String, MVCGroupConfiguration> configurations);
155
156 public MVCGroup buildMVCGroup(String mvcType) {
157 return buildMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap());
158 }
159
160 public MVCGroup buildMVCGroup(String mvcType, String mvcName) {
161 return buildMVCGroup(findConfiguration(mvcType), mvcName, Collections.<String, Object>emptyMap());
162 }
163
164 public MVCGroup buildMVCGroup(Map<String, Object> args, String mvcType) {
165 return buildMVCGroup(findConfiguration(mvcType), null, args);
166 }
167
168 public MVCGroup buildMVCGroup(String mvcType, Map<String, Object> args) {
169 return buildMVCGroup(findConfiguration(mvcType), null, args);
170 }
171
172 public MVCGroup buildMVCGroup(Map<String, Object> args, String mvcType, String mvcName) {
173 return buildMVCGroup(findConfiguration(mvcType), mvcName, args);
174 }
175
176 public MVCGroup buildMVCGroup(String mvcType, String mvcName, Map<String, Object> args) {
177 return buildMVCGroup(findConfiguration(mvcType), mvcName, args);
178 }
179
180 public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType) {
181 return createMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap());
182 }
183
184 public List<? extends GriffonMvcArtifact> createMVCGroup(Map<String, Object> args, String mvcType) {
185 return createMVCGroup(findConfiguration(mvcType), null, args);
186 }
187
188 public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, Map<String, Object> args) {
189 return createMVCGroup(findConfiguration(mvcType), null, args);
190 }
191
192 public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, String mvcName) {
193 return createMVCGroup(findConfiguration(mvcType), mvcName, Collections.<String, Object>emptyMap());
194 }
195
196 public List<? extends GriffonMvcArtifact> createMVCGroup(Map<String, Object> args, String mvcType, String mvcName) {
197 return createMVCGroup(findConfiguration(mvcType), mvcName, args);
198 }
199
200 public List<? extends GriffonMvcArtifact> createMVCGroup(String mvcType, String mvcName, Map<String, Object> args) {
201 return createMVCGroup(findConfiguration(mvcType), mvcName, args);
202 }
203
204 public void withMVCGroup(String mvcType, Closure handler) {
205 withMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap(), handler);
206 }
207
208 public void withMVCGroup(String mvcType, String mvcName, Closure handler) {
209 withMVCGroup(findConfiguration(mvcType), mvcName, Collections.<String, Object>emptyMap(), handler);
210 }
211
212 public void withMVCGroup(String mvcType, Map<String, Object> args, Closure handler) {
213 withMVCGroup(findConfiguration(mvcType), null, args, handler);
214 }
215
216 public void withMVCGroup(Map<String, Object> args, String mvcType, Closure handler) {
217 withMVCGroup(findConfiguration(mvcType), null, args, handler);
218 }
219
220 public void withMVCGroup(Map<String, Object> args, String mvcType, String mvcName, Closure handler) {
221 withMVCGroup(findConfiguration(mvcType), mvcName, args, handler);
222 }
223
224 public void withMVCGroup(String mvcType, String mvcName, Map<String, Object> args, Closure handler) {
225 withMVCGroup(findConfiguration(mvcType), mvcName, args, handler);
226 }
227
228 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, MVCClosure<M, V, C> handler) {
229 withMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap(), handler);
230 }
231
232 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, String mvcName, MVCClosure<M, V, C> handler) {
233 withMVCGroup(findConfiguration(mvcType), mvcName, Collections.<String, Object>emptyMap(), handler);
234 }
235
236 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(String mvcType, Map<String, Object> args, MVCClosure<M, V, C> handler) {
237 withMVCGroup(findConfiguration(mvcType), null, args, handler);
238 }
239
240 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(Map<String, Object> args, String mvcType, MVCClosure<M, V, C> handler) {
241 withMVCGroup(findConfiguration(mvcType), null, args, handler);
242 }
243
244 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) {
245 withMVCGroup(findConfiguration(mvcType), mvcName, args, handler);
246 }
247
248 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) {
249 withMVCGroup(findConfiguration(mvcType), mvcName, args, handler);
250 }
251
252 protected List<? extends GriffonMvcArtifact> createMVCGroup(MVCGroupConfiguration configuration, String mvcName, Map<String, Object> args) {
253 MVCGroup group = buildMVCGroup(findConfiguration(configuration.getMvcType()), mvcName, args);
254 return Arrays.asList(group.getModel(), group.getView(), group.getController());
255 }
256
257 protected void withMVCGroup(MVCGroupConfiguration configuration, String mvcId, Map<String, Object> args, Closure handler) {
258 MVCGroup group = null;
259 try {
260 group = buildMVCGroup(configuration, mvcId, args);
261 handler.call(group.getModel(), group.getView(), group.getController());
262 } finally {
263 try {
264 if (group != null) {
265 destroyMVCGroup(group.getMvcId());
266 }
267 } catch (Exception x) {
268 if (app.getLog().isWarnEnabled()) {
269 app.getLog().warn("Could not destroy group [" + mvcId + "] of type " + configuration.getMvcType() + ".", sanitize(x));
270 }
271 }
272 }
273 }
274
275 protected <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(MVCGroupConfiguration configuration, String mvcId, Map<String, Object> args, MVCClosure<M, V, C> handler) {
276 MVCGroup group = null;
277 try {
278 group = buildMVCGroup(configuration, mvcId, args);
279 handler.call((M) group.getModel(), (V) group.getView(), (C) group.getController());
280 } finally {
281 try {
282 if (group != null) {
283 destroyMVCGroup(group.getMvcId());
284 }
285 } catch (Exception x) {
286 if (app.getLog().isWarnEnabled()) {
287 app.getLog().warn("Could not destroy group [" + mvcId + "] of type " + configuration.getMvcType() + ".", sanitize(x));
288 }
289 }
290 }
291 }
292
293 protected abstract MVCGroup buildMVCGroup(MVCGroupConfiguration configuration, String mvcId, Map<String, Object> args);
294
295 public final Map<String, ? extends FactoryBuilderSupport> getBuilders() {
296 Map<String, FactoryBuilderSupport> builders = new LinkedHashMap<String, FactoryBuilderSupport>();
297 synchronized (lock) {
298 for (MVCGroup group : groups.values()) {
299 FactoryBuilderSupport builder = group.getBuilder();
300 if (builder != null) {
301 builders.put(group.getMvcId(), builder);
302 }
303 }
304 }
305 return Collections.unmodifiableMap(builders);
306 }
307
308 public final Map<String, ? extends GriffonModel> getModels() {
309 Map<String, GriffonModel> models = new LinkedHashMap<String, GriffonModel>();
310 synchronized (lock) {
311 for (MVCGroup group : groups.values()) {
312 GriffonModel model = group.getModel();
313 if (model != null) {
314 models.put(group.getMvcId(), model);
315 }
316 }
317 }
318 return Collections.unmodifiableMap(models);
319 }
320
321 public final Map<String, ? extends GriffonView> getViews() {
322 Map<String, GriffonView> views = new LinkedHashMap<String, GriffonView>();
323 synchronized (lock) {
324 for (MVCGroup group : groups.values()) {
325 GriffonView view = group.getView();
326 if (view != null) {
327 views.put(group.getMvcId(), view);
328 }
329 }
330 }
331 return Collections.unmodifiableMap(views);
332 }
333
334 public final Map<String, ? extends GriffonController> getControllers() {
335 Map<String, GriffonController> controllers = new LinkedHashMap<String, GriffonController>();
336 synchronized (lock) {
337 for (MVCGroup group : groups.values()) {
338 GriffonController controller = group.getController();
339 if (controller != null) {
340 controllers.put(group.getMvcId(), controller);
341 }
342 }
343 }
344 return Collections.unmodifiableMap(controllers);
345 }
346 }
|