| 
001 /*002  * Copyright 2008-2017 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 package org.codehaus.griffon.runtime.core.mvc;
 017
 018 import griffon.core.Context;
 019 import griffon.core.ContextFactory;
 020 import griffon.core.GriffonApplication;
 021 import griffon.core.artifact.GriffonController;
 022 import griffon.core.artifact.GriffonModel;
 023 import griffon.core.artifact.GriffonMvcArtifact;
 024 import griffon.core.artifact.GriffonView;
 025 import griffon.core.mvc.MVCFunction;
 026 import griffon.core.mvc.MVCGroup;
 027 import griffon.core.mvc.MVCGroupConfiguration;
 028 import griffon.core.mvc.MVCGroupConfigurationFactory;
 029 import griffon.core.mvc.MVCGroupFactory;
 030 import griffon.core.mvc.MVCGroupFunction;
 031 import griffon.core.mvc.MVCGroupManager;
 032 import griffon.core.mvc.TypedMVCGroup;
 033 import griffon.core.mvc.TypedMVCGroupFunction;
 034 import griffon.exceptions.ArtifactNotFoundException;
 035 import griffon.exceptions.MVCGroupConfigurationException;
 036 import griffon.exceptions.MVCGroupInstantiationException;
 037 import griffon.util.AnnotationUtils;
 038 import org.slf4j.Logger;
 039 import org.slf4j.LoggerFactory;
 040
 041 import javax.annotation.Nonnull;
 042 import javax.annotation.Nullable;
 043 import javax.inject.Inject;
 044 import java.lang.reflect.Constructor;
 045 import java.util.Collections;
 046 import java.util.LinkedHashMap;
 047 import java.util.List;
 048 import java.util.Map;
 049
 050 import static griffon.core.GriffonExceptionHandler.sanitize;
 051 import static griffon.util.GriffonNameUtils.isBlank;
 052 import static griffon.util.GriffonNameUtils.requireNonBlank;
 053 import static java.util.Arrays.asList;
 054 import static java.util.Collections.unmodifiableMap;
 055 import static java.util.Objects.requireNonNull;
 056
 057 /**
 058  * Base implementation of the {@code MVCGroupManager} interface.
 059  *
 060  * @author Andres Almiray
 061  * @since 2.0.0
 062  */
 063 public abstract class AbstractMVCGroupManager implements MVCGroupManager {
 064     protected static final String ERROR_MVCTYPE_BLANK = "Argument 'mvcType' must not be blank";
 065     protected static final String ERROR_MVCID_BLANK = "Argument 'mvcId' must not be blank";
 066     protected static final String ERROR_CONFIGURATION_NULL = "Argument 'configuration' must not be null";
 067     protected static final String ERROR_GROUP_NULL = "Argument 'group' must not be null";
 068     protected static final String ERROR_CONFIG_NULL = "Argument 'config' must not be null";
 069     protected static final String ERROR_ARGS_NULL = "Argument 'args' must not be null";
 070     protected static final String ERROR_NAME_BLANK = "Argument 'name' cannot be blank";
 071     protected static final String ERROR_TYPE_NULL = "Argument 'type' cannot be null";
 072     private static final Logger LOG = LoggerFactory.getLogger(AbstractMVCGroupManager.class);
 073     private final GriffonApplication application;
 074
 075     private final Map<String, MVCGroupConfiguration> configurations = new LinkedHashMap<>();
 076     private final Map<String, MVCGroup> groups = new LinkedHashMap<>();
 077     private final Object lock = new Object[0];
 078     private boolean initialized;
 079
 080     @Inject
 081     private MVCGroupConfigurationFactory mvcGroupConfigurationFactory;
 082
 083     @Inject
 084     private MVCGroupFactory mvcGroupFactory;
 085
 086     @Inject
 087     private ContextFactory contextFactory;
 088
 089     @Inject
 090     public AbstractMVCGroupManager(@Nonnull GriffonApplication application) {
 091         this.application = requireNonNull(application, "Argument 'application' must not be null");
 092     }
 093
 094     @Override
 095     public GriffonApplication getApplication() {
 096         return application;
 097     }
 098
 099     @Nonnull
 100     public MVCGroupConfiguration newMVCGroupConfiguration(@Nonnull String mvcType, @Nonnull Map<String, String> members, @Nonnull Map<String, Object> config) {
 101         return mvcGroupConfigurationFactory.create(mvcType, members, config);
 102     }
 103
 104     @Nonnull
 105     public MVCGroup newMVCGroup(@Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> members, @Nullable MVCGroup parentGroup) {
 106         return mvcGroupFactory.create(configuration, mvcId, members, parentGroup);
 107     }
 108
 109     @Nonnull
 110     @Override
 111     public Context newContext(@Nullable MVCGroup parentGroup) {
 112         Context parentContext = parentGroup != null ? parentGroup.getContext() : getApplication().getContext();
 113         return contextFactory.create(parentContext);
 114     }
 115
 116     @Nonnull
 117     public Map<String, MVCGroupConfiguration> getConfigurations() {
 118         synchronized (lock) {
 119             return unmodifiableMap(configurations);
 120         }
 121     }
 122
 123     @Nonnull
 124     public Map<String, MVCGroup> getGroups() {
 125         synchronized (lock) {
 126             return unmodifiableMap(groups);
 127         }
 128     }
 129
 130     @Nonnull
 131     public MVCGroupConfiguration findConfiguration(@Nonnull String mvcType) {
 132         requireNonBlank(mvcType, ERROR_MVCTYPE_BLANK);
 133         MVCGroupConfiguration configuration;
 134         synchronized (lock) {
 135             configuration = configurations.get(mvcType);
 136         }
 137
 138         if (configuration == null) {
 139             throw new MVCGroupConfigurationException("Unknown MVC type '" + mvcType + "'. Known types are " + configurations.keySet(), mvcType);
 140         }
 141         return configuration;
 142     }
 143
 144     @Nullable
 145     public MVCGroup findGroup(@Nonnull String mvcId) {
 146         requireNonBlank(mvcId, ERROR_MVCID_BLANK);
 147         synchronized (lock) {
 148             LOG.debug("Searching group {}", mvcId);
 149             return groups.get(mvcId);
 150         }
 151     }
 152
 153     @Nullable
 154     public MVCGroup getAt(@Nonnull String mvcId) {
 155         return findGroup(mvcId);
 156     }
 157
 158     public final void initialize(@Nonnull Map<String, MVCGroupConfiguration> configurations) {
 159         requireNonNull(configurations, "Argument 'configurations' must not be null");
 160         if (configurations.isEmpty()) { return; }
 161         synchronized (lock) {
 162             if (!initialized) {
 163                 doInitialize(configurations);
 164                 initialized = true;
 165             }
 166         }
 167     }
 168
 169     public void addConfiguration(@Nonnull MVCGroupConfiguration configuration) {
 170         requireNonNull(configuration, ERROR_CONFIGURATION_NULL);
 171         synchronized (lock) {
 172             if (initialized && configurations.get(configuration.getMvcType()) != null) {
 173                 return;
 174             }
 175             configurations.put(configuration.getMvcType(), configuration);
 176         }
 177     }
 178
 179     public void removeConfiguration(@Nonnull MVCGroupConfiguration configuration) {
 180         requireNonNull(configuration, ERROR_CONFIGURATION_NULL);
 181         removeConfiguration(configuration.getMvcType());
 182     }
 183
 184     public void removeConfiguration(@Nonnull String name) {
 185         requireNonBlank(name, "Argument 'name' must not be blank");
 186         if (!isBlank(name)) {
 187             synchronized (lock) {
 188                 configurations.remove(name);
 189             }
 190         }
 191     }
 192
 193     protected void addGroup(@Nonnull MVCGroup group) {
 194         requireNonNull(group, ERROR_GROUP_NULL);
 195         synchronized (lock) {
 196             LOG.debug("Adding group {}:{}", group.getMvcId(), group);
 197             groups.put(group.getMvcId(), group);
 198         }
 199     }
 200
 201     protected void removeGroup(@Nonnull MVCGroup group) {
 202         requireNonNull(group, ERROR_GROUP_NULL);
 203         synchronized (lock) {
 204             LOG.debug("Removing group {}:{}", group.getMvcId(), group);
 205             groups.remove(group.getMvcId());
 206         }
 207     }
 208
 209     @Nonnull
 210     public final Map<String, ? extends GriffonModel> getModels() {
 211         Map<String, GriffonModel> models = new LinkedHashMap<>();
 212         synchronized (lock) {
 213             for (MVCGroup group : groups.values()) {
 214                 GriffonModel model = group.getModel();
 215                 if (model != null) {
 216                     models.put(group.getMvcId(), model);
 217                 }
 218             }
 219         }
 220         return unmodifiableMap(models);
 221     }
 222
 223     @Nonnull
 224     public final Map<String, ? extends GriffonView> getViews() {
 225         Map<String, GriffonView> views = new LinkedHashMap<>();
 226         synchronized (lock) {
 227             for (MVCGroup group : groups.values()) {
 228                 GriffonView view = group.getView();
 229                 if (view != null) {
 230                     views.put(group.getMvcId(), view);
 231                 }
 232             }
 233         }
 234         return unmodifiableMap(views);
 235     }
 236
 237     @Nonnull
 238     public final Map<String, ? extends GriffonController> getControllers() {
 239         Map<String, GriffonController> controllers = new LinkedHashMap<>();
 240         synchronized (lock) {
 241             for (MVCGroup group : groups.values()) {
 242                 GriffonController controller = group.getController();
 243                 if (controller != null) {
 244                     controllers.put(group.getMvcId(), controller);
 245                 }
 246             }
 247         }
 248         return unmodifiableMap(controllers);
 249     }
 250
 251     @Nonnull
 252     @Override
 253     public MVCGroupConfiguration cloneMVCGroupConfiguration(@Nonnull String mvcType, @Nonnull Map<String, Object> config) {
 254         requireNonBlank(mvcType, ERROR_MVCTYPE_BLANK);
 255         requireNonNull(config, ERROR_CONFIG_NULL);
 256         MVCGroupConfiguration configuration = findConfiguration(mvcType);
 257         Map<String, Object> configCopy = new LinkedHashMap<>();
 258         configCopy.putAll(configuration.getConfig());
 259         configCopy.putAll(config);
 260         return newMVCGroupConfiguration(mvcType, configuration.getMembers(), configCopy);
 261     }
 262
 263     @Nonnull
 264     protected List<? extends GriffonMvcArtifact> createMVC(@Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> args) {
 265         MVCGroup group = createMVCGroup(findConfiguration(configuration.getMvcType()), mvcId, args);
 266         return asList(group.getModel(), group.getView(), group.getController());
 267     }
 268
 269     @SuppressWarnings("unchecked")
 270     protected <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVCGroup(@Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCFunction<M, V, C> handler) {
 271         MVCGroup group = null;
 272         try {
 273             group = createMVCGroup(configuration, mvcId, args);
 274             handler.apply((M) group.getModel(), (V) group.getView(), (C) group.getController());
 275         } finally {
 276             try {
 277                 if (group != null) {
 278                     destroyMVCGroup(group.getMvcId());
 279                 }
 280             } catch (Exception x) {
 281                 LOG.warn("Could not destroy group [{}] of type {}", mvcId, configuration.getMvcType(), sanitize(x));
 282             }
 283         }
 284     }
 285
 286     @SuppressWarnings("unchecked")
 287     protected void withMVCGroup(@Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
 288         MVCGroup group = null;
 289         try {
 290             group = createMVCGroup(configuration, mvcId, args);
 291             handler.apply(group);
 292         } finally {
 293             try {
 294                 if (group != null) {
 295                     destroyMVCGroup(group.getMvcId());
 296                 }
 297             } catch (Exception x) {
 298                 LOG.warn("Could not destroy group [{}] of type {}", mvcId, configuration.getMvcType(), sanitize(x));
 299             }
 300         }
 301     }
 302
 303     @Nonnull
 304     protected abstract MVCGroup createMVCGroup(@Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> args);
 305
 306     protected abstract void doInitialize(@Nonnull Map<String, MVCGroupConfiguration> configurations);
 307
 308     @Nonnull
 309     @Override
 310     public MVCGroup createMVCGroup(@Nonnull String mvcType) {
 311         return createMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap());
 312     }
 313
 314     @Nonnull
 315     @Override
 316     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId) {
 317         return createMVCGroup(findConfiguration(mvcType), mvcId, Collections.<String, Object>emptyMap());
 318     }
 319
 320     @Nonnull
 321     @Override
 322     public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
 323         return createMVCGroup(findConfiguration(mvcType), null, args);
 324     }
 325
 326     @Nonnull
 327     @Override
 328     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
 329         return createMVCGroup(findConfiguration(mvcType), null, args);
 330     }
 331
 332     @Nonnull
 333     @Override
 334     public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
 335         return createMVCGroup(findConfiguration(mvcType), mvcId, args);
 336     }
 337
 338     @Nonnull
 339     @Override
 340     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 341         return createMVCGroup(findConfiguration(mvcType), mvcId, args);
 342     }
 343
 344     @Nonnull
 345     @Override
 346     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType) {
 347         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), null, Collections.<String, Object>emptyMap()));
 348     }
 349
 350     @Nonnull
 351     @Override
 352     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
 353         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, Collections.<String, Object>emptyMap()));
 354     }
 355
 356     @Nonnull
 357     @Override
 358     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType) {
 359         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), null, args));
 360     }
 361
 362     @Nonnull
 363     @Override
 364     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args) {
 365         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), null, args));
 366     }
 367
 368     @Nonnull
 369     @Override
 370     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
 371         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, args));
 372     }
 373
 374     @Nonnull
 375     @Override
 376     public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 377         return typedMvcGroup(mvcType, createMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, args));
 378     }
 379
 380     @Nonnull
 381     @Override
 382     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType) {
 383         return createMVC(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap());
 384     }
 385
 386     @Nonnull
 387     @Override
 388     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
 389         return createMVC(findConfiguration(mvcType), null, args);
 390     }
 391
 392     @Nonnull
 393     @Override
 394     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
 395         return createMVC(findConfiguration(mvcType), null, args);
 396     }
 397
 398     @Nonnull
 399     @Override
 400     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId) {
 401         return createMVC(findConfiguration(mvcType), mvcId, Collections.<String, Object>emptyMap());
 402     }
 403
 404     @Nonnull
 405     @Override
 406     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
 407         return createMVC(findConfiguration(mvcType), mvcId, args);
 408     }
 409
 410     @Nonnull
 411     @Override
 412     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 413         return createMVC(findConfiguration(mvcType), mvcId, args);
 414     }
 415
 416     @Nonnull
 417     @Override
 418     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType) {
 419         return createMVC(findConfiguration(nameOf(mvcType)), null, Collections.<String, Object>emptyMap());
 420     }
 421
 422     @Nonnull
 423     @Override
 424     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType) {
 425         return createMVC(findConfiguration(nameOf(mvcType)), null, args);
 426     }
 427
 428     @Nonnull
 429     @Override
 430     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args) {
 431         return createMVC(findConfiguration(nameOf(mvcType)), null, args);
 432     }
 433
 434     @Nonnull
 435     @Override
 436     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
 437         return createMVC(findConfiguration(nameOf(mvcType)), mvcId, Collections.<String, Object>emptyMap());
 438     }
 439
 440     @Nonnull
 441     @Override
 442     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
 443         return createMVC(findConfiguration(nameOf(mvcType)), mvcId, args);
 444     }
 445
 446     @Nonnull
 447     @Override
 448     public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 449         return createMVC(findConfiguration(nameOf(mvcType)), mvcId, args);
 450     }
 451
 452     @Override
 453     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull MVCFunction<M, V, C> handler) {
 454         withMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap(), handler);
 455     }
 456
 457     @Override
 458     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
 459         withMVCGroup(findConfiguration(mvcType), mvcId, Collections.<String, Object>emptyMap(), handler);
 460     }
 461
 462     @Override
 463     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCFunction<M, V, C> handler) {
 464         withMVCGroup(findConfiguration(mvcType), mvcId, args, handler);
 465     }
 466
 467     @Override
 468     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
 469         withMVCGroup(findConfiguration(mvcType), mvcId, args, handler);
 470     }
 471
 472     @Override
 473     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCFunction<M, V, C> handler) {
 474         withMVCGroup(findConfiguration(mvcType), null, args, handler);
 475     }
 476
 477     @Override
 478     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull MVCFunction<M, V, C> handler) {
 479         withMVCGroup(findConfiguration(mvcType), null, args, handler);
 480     }
 481
 482     @Override
 483     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull MVCFunction<M, V, C> handler) {
 484         withMVCGroup(findConfiguration(nameOf(mvcType)), null, Collections.<String, Object>emptyMap(), handler);
 485     }
 486
 487     @Override
 488     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
 489         withMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, Collections.<String, Object>emptyMap(), handler);
 490     }
 491
 492     @Override
 493     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCFunction<M, V, C> handler) {
 494         withMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, args, handler);
 495     }
 496
 497     @Override
 498     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
 499         withMVCGroup(findConfiguration(nameOf(mvcType)), mvcId, args, handler);
 500     }
 501
 502     @Override
 503     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCFunction<M, V, C> handler) {
 504         withMVCGroup(findConfiguration(nameOf(mvcType)), null, args, handler);
 505     }
 506
 507     @Override
 508     public <MVC extends TypedMVCGroup, M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull MVCFunction<M, V, C> handler) {
 509         withMVCGroup(findConfiguration(nameOf(mvcType)), null, args, handler);
 510     }
 511
 512     @Override
 513     public void withMVCGroup(@Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
 514         withMVCGroup(findConfiguration(mvcType), null, Collections.<String, Object>emptyMap(), handler);
 515     }
 516
 517     @Override
 518     public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCGroupFunction handler) {
 519         withMVCGroup(findConfiguration(mvcType), mvcId, Collections.<String, Object>emptyMap(), handler);
 520     }
 521
 522     @Override
 523     public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
 524         withMVCGroup(findConfiguration(mvcType), mvcId, args, handler);
 525     }
 526
 527     @Override
 528     public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCGroupFunction handler) {
 529         withMVCGroup(findConfiguration(mvcType), mvcId, args, handler);
 530     }
 531
 532     @Override
 533     public void withMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
 534         withMVCGroup(findConfiguration(mvcType), null, args, handler);
 535     }
 536
 537     @Override
 538     public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
 539         withMVCGroup(findConfiguration(mvcType), null, args, handler);
 540     }
 541
 542     @Override
 543     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 544         withMVCGroup(mvcType, null, Collections.<String, Object>emptyMap(), handler);
 545     }
 546
 547     @Override
 548     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 549         withMVCGroup(mvcType, mvcId, Collections.<String, Object>emptyMap(), handler);
 550     }
 551
 552     @Override
 553     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 554         MVC group = null;
 555         try {
 556             group = createMVCGroup(mvcType, mvcId, args);
 557             handler.apply(group);
 558         } finally {
 559             try {
 560                 if (group != null) {
 561                     destroyMVCGroup(group.getMvcId());
 562                 }
 563             } catch (Exception x) {
 564                 LOG.warn("Could not destroy group [{}] of type {}", mvcId, nameOf(mvcType), sanitize(x));
 565             }
 566         }
 567     }
 568
 569     @Override
 570     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 571         withMVCGroup(mvcType, mvcId, args, handler);
 572     }
 573
 574     @Override
 575     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 576         withMVCGroup(mvcType, null, args, handler);
 577     }
 578
 579     @Override
 580     public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull TypedMVCGroupFunction<MVC> handler) {
 581         withMVCGroup(mvcType, null, args, handler);
 582     }
 583
 584     @Nonnull
 585     @Override
 586     public <C extends GriffonController> C getController(@Nonnull String name, @Nonnull Class<C> type) throws ArtifactNotFoundException {
 587         requireNonBlank(name, ERROR_NAME_BLANK);
 588         requireNonNull(type, ERROR_TYPE_NULL);
 589         GriffonController controller = getControllers().get(name);
 590         if (controller != null) {
 591             return type.cast(controller);
 592         }
 593         throw new ArtifactNotFoundException(type, name);
 594     }
 595
 596     @Nonnull
 597     @Override
 598     public <M extends GriffonModel> M getModel(@Nonnull String name, @Nonnull Class<M> type) throws ArtifactNotFoundException {
 599         requireNonBlank(name, ERROR_NAME_BLANK);
 600         requireNonNull(type, ERROR_TYPE_NULL);
 601         GriffonModel model = getModels().get(name);
 602         if (model != null) {
 603             return type.cast(model);
 604         }
 605         throw new ArtifactNotFoundException(type, name);
 606     }
 607
 608     @Nonnull
 609     @Override
 610     public <V extends GriffonView> V getView(@Nonnull String name, @Nonnull Class<V> type) throws ArtifactNotFoundException {
 611         requireNonBlank(name, ERROR_NAME_BLANK);
 612         requireNonNull(type, ERROR_TYPE_NULL);
 613         GriffonView view = getViews().get(name);
 614         if (view != null) {
 615             return type.cast(view);
 616         }
 617         throw new ArtifactNotFoundException(type, name);
 618     }
 619
 620     @Nullable
 621     @Override
 622     public <C extends GriffonController> C findController(@Nonnull String name, @Nonnull Class<C> type) {
 623         try {
 624             return getController(name, type);
 625         } catch (ArtifactNotFoundException anfe) {
 626             return null;
 627         }
 628     }
 629
 630     @Nullable
 631     @Override
 632     public <M extends GriffonModel> M findModel(@Nonnull String name, @Nonnull Class<M> type) {
 633         try {
 634             return getModel(name, type);
 635         } catch (ArtifactNotFoundException anfe) {
 636             return null;
 637         }
 638     }
 639
 640     @Nullable
 641     @Override
 642     public <V extends GriffonView> V findView(@Nonnull String name, @Nonnull Class<V> type) {
 643         try {
 644             return getView(name, type);
 645         } catch (ArtifactNotFoundException anfe) {
 646             return null;
 647         }
 648     }
 649
 650     @Nonnull
 651     protected <MVC extends TypedMVCGroup> String nameOf(@Nonnull Class<? extends MVC> mvcType) {
 652         return AnnotationUtils.nameFor(mvcType, true);
 653     }
 654
 655     @Nonnull
 656     protected <MVC extends TypedMVCGroup> MVC typedMvcGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull MVCGroup mvcGroup) {
 657         try {
 658             Constructor<? extends MVC> constructor = mvcType.getDeclaredConstructor(MVCGroup.class);
 659             return constructor.newInstance(mvcGroup);
 660         } catch (Exception e) {
 661             throw new MVCGroupInstantiationException("Unexpected error", mvcGroup.getMvcType(), mvcGroup.getMvcId(), e);
 662         }
 663     }
 664 }
 |