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 }
|