AbstractMVCGroup.java
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 (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 (GriffonModelgetMember(GriffonModelClass.TYPE);
111     }
112 
113     @Nullable
114     @Override
115     public GriffonView getView() {
116         return (GriffonViewgetMember(GriffonViewClass.TYPE);
117     }
118 
119     @Nullable
120     @Override
121     public GriffonController getController() {
122         return (GriffonControllergetMember(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 }