| 
001 /*002  * Copyright 2008-2015 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.artifact.GriffonController;
 020 import griffon.core.artifact.GriffonControllerClass;
 021 import griffon.core.artifact.GriffonModel;
 022 import griffon.core.artifact.GriffonModelClass;
 023 import griffon.core.artifact.GriffonMvcArtifact;
 024 import griffon.core.artifact.GriffonView;
 025 import griffon.core.artifact.GriffonViewClass;
 026 import griffon.core.mvc.MVCFunction;
 027 import griffon.core.mvc.MVCGroup;
 028 import griffon.core.mvc.MVCGroupConfiguration;
 029 import griffon.core.mvc.MVCGroupFunction;
 030 import griffon.core.mvc.MVCGroupManager;
 031
 032 import javax.annotation.Nonnull;
 033 import javax.annotation.Nullable;
 034 import java.util.LinkedHashMap;
 035 import java.util.List;
 036 import java.util.Map;
 037 import java.util.UUID;
 038
 039 import static griffon.util.GriffonClassUtils.requireState;
 040 import static griffon.util.GriffonClassUtils.setPropertyOrFieldValue;
 041 import static griffon.util.GriffonNameUtils.isBlank;
 042 import static griffon.util.GriffonNameUtils.requireNonBlank;
 043 import static java.util.Collections.unmodifiableMap;
 044 import static java.util.Objects.requireNonNull;
 045
 046 /**
 047  * Base implementation of the {@code MVCGroup} interface
 048  *
 049  * @author Andres Almiray
 050  * @since 2.0.0
 051  */
 052 public abstract class AbstractMVCGroup extends AbstractMVCHandler implements MVCGroup {
 053     protected final MVCGroupConfiguration configuration;
 054     protected final String mvcId;
 055     protected final Context context;
 056     protected final Map<String, Object> members = new LinkedHashMap<>();
 057     private final Object[] lock = new Object[0];
 058     protected MVCGroup parentGroup;
 059     private boolean alive;
 060
 061     public AbstractMVCGroup(@Nonnull MVCGroupManager mvcGroupManager, @Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> members, @Nullable MVCGroup parentGroup) {
 062         super(mvcGroupManager);
 063         this.configuration = requireNonNull(configuration, "Argument 'configuration' must not be null");
 064         this.mvcId = isBlank(mvcId) ? configuration.getMvcType() + "-" + UUID.randomUUID().toString() : mvcId;
 065         this.members.putAll(requireNonNull(members, "Argument 'members' must not be null"));
 066         this.alive = true;
 067         this.parentGroup = parentGroup;
 068         this.context = mvcGroupManager.newContext(parentGroup);
 069
 070         for (Object o : this.members.values()) {
 071             if (o instanceof GriffonMvcArtifact) {
 072                 setPropertyOrFieldValue(o, "mvcGroup", this);
 073             }
 074         }
 075     }
 076
 077     @Nonnull
 078     @Override
 079     public Context getContext() {
 080         return context;
 081     }
 082
 083     @Nullable
 084     @Override
 085     public MVCGroup getParentGroup() {
 086         return parentGroup;
 087     }
 088
 089     @Nonnull
 090     @Override
 091     public MVCGroupConfiguration getConfiguration() {
 092         return configuration;
 093     }
 094
 095     @Nonnull
 096     @Override
 097     public String getMvcType() {
 098         return configuration.getMvcType();
 099     }
 100
 101     @Nonnull
 102     @Override
 103     public String getMvcId() {
 104         return mvcId;
 105     }
 106
 107     @Nullable
 108     @Override
 109     public GriffonModel getModel() {
 110         return (GriffonModel) getMember(GriffonModelClass.TYPE);
 111     }
 112
 113     @Nullable
 114     @Override
 115     public GriffonView getView() {
 116         return (GriffonView) getMember(GriffonViewClass.TYPE);
 117     }
 118
 119     @Nullable
 120     @Override
 121     public GriffonController getController() {
 122         return (GriffonController) getMember(GriffonControllerClass.TYPE);
 123     }
 124
 125     @Nullable
 126     @Override
 127     public Object getMember(@Nonnull String name) {
 128         requireNonBlank(name, "Argument 'name' must not be blank");
 129         checkIfAlive();
 130         return members.get(name);
 131     }
 132
 133     @Nonnull
 134     @Override
 135     public Map<String, Object> getMembers() {
 136         checkIfAlive();
 137         return unmodifiableMap(members);
 138     }
 139
 140     @Override
 141     public void destroy() {
 142         if (isAlive()) {
 143             getMvcGroupManager().destroyMVCGroup(mvcId);
 144             members.clear();
 145             parentGroup = null;
 146             context.destroy();
 147             synchronized (lock) {
 148                 alive = false;
 149             }
 150         }
 151     }
 152
 153     @Override
 154     public boolean isAlive() {
 155         synchronized (lock) {
 156             return alive;
 157         }
 158     }
 159
 160     protected void checkIfAlive() {
 161         requireState(isAlive(), "Group " + getMvcType() + ":" + mvcId + " has been destroyed already.");
 162     }
 163
 164     @Nonnull
 165     @Override
 166     public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
 167         return super.createMVCGroup(injectParentGroup(args), mvcType);
 168     }
 169
 170     @Nonnull
 171     @Override
 172     public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
 173         return super.createMVCGroup(injectParentGroup(args), mvcType, mvcId);
 174     }
 175
 176     @Nonnull
 177     @Override
 178     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
 179         return super.createMVCGroup(mvcType, injectParentGroup(args));
 180     }
 181
 182     @Nonnull
 183     @Override
 184     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 185         return super.createMVCGroup(mvcType, mvcId, injectParentGroup(args));
 186     }
 187
 188     @Nonnull
 189     @Override
 190     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
 191         return super.createMVC(injectParentGroup(args), mvcType);
 192     }
 193
 194     @Nonnull
 195     @Override
 196     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
 197         return super.createMVC(injectParentGroup(args), mvcType, mvcId);
 198     }
 199
 200     @Nonnull
 201     @Override
 202     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
 203         return super.createMVC(mvcType, injectParentGroup(args));
 204     }
 205
 206     @Nonnull
 207     @Override
 208     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
 209         return super.createMVC(mvcType, mvcId, injectParentGroup(args));
 210     }
 211
 212     @Override
 213     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) {
 214         super.withMVC(injectParentGroup(args), mvcType, handler);
 215     }
 216
 217     @Override
 218     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) {
 219         super.withMVC(injectParentGroup(args), mvcType, mvcId, handler);
 220     }
 221
 222     @Override
 223     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) {
 224         super.withMVC(mvcType, injectParentGroup(args), handler);
 225     }
 226
 227     @Override
 228     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) {
 229         super.withMVC(mvcType, mvcId, injectParentGroup(args), handler);
 230     }
 231
 232     @Override
 233     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull MVCFunction<M, V, C> handler) {
 234         super.withMVC(mvcType, injectParentGroup(), handler);
 235     }
 236
 237     @Override
 238     public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
 239         super.withMVC(mvcType, mvcId, injectParentGroup(), handler);
 240     }
 241
 242     @Override
 243     public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
 244         super.withMVCGroup(injectParentGroup(args), mvcType, handler);
 245     }
 246
 247     @Override
 248     public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCGroupFunction handler) {
 249         super.withMVCGroup(injectParentGroup(args), mvcType, mvcId, handler);
 250     }
 251
 252     @Override
 253     public void withMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
 254         super.withMVCGroup(mvcType, injectParentGroup(args), handler);
 255     }
 256
 257     @Override
 258     public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
 259         super.withMVCGroup(mvcType, mvcId, injectParentGroup(args), handler);
 260     }
 261
 262     @Override
 263     public void withMVCGroup(@Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
 264         super.withMVCGroup(mvcType, injectParentGroup(), handler);
 265     }
 266
 267     @Override
 268     public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCGroupFunction handler) {
 269         super.withMVCGroup(mvcType, mvcId, injectParentGroup(), handler);
 270     }
 271
 272     @Nonnull
 273     @Override
 274     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId) {
 275         return super.createMVC(mvcType, mvcId, injectParentGroup());
 276     }
 277
 278     @Nonnull
 279     @Override
 280     public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType) {
 281         return super.createMVC(mvcType, injectParentGroup());
 282     }
 283
 284     @Nonnull
 285     @Override
 286     public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId) {
 287         return super.createMVCGroup(mvcType, mvcId, injectParentGroup());
 288     }
 289
 290     @Nonnull
 291     @Override
 292     public MVCGroup createMVCGroup(@Nonnull String mvcType) {
 293         return super.createMVCGroup(mvcType, injectParentGroup());
 294     }
 295
 296     @Nonnull
 297     private Map<String, Object> injectParentGroup() {
 298         return injectParentGroup(new LinkedHashMap<String, Object>());
 299     }
 300
 301     @Nonnull
 302     private Map<String, Object> injectParentGroup(@Nonnull Map<String, Object> args) {
 303         Map<String, Object> map = new LinkedHashMap<>();
 304         map.put("parentGroup", this);
 305         map.putAll(args);
 306         return map;
 307     }
 308 }
 |