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.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 import griffon.core.mvc.TypedMVCGroup;
032 import griffon.core.mvc.TypedMVCGroupFunction;
033
034 import javax.annotation.Nonnull;
035 import javax.annotation.Nullable;
036 import java.util.ArrayList;
037 import java.util.Collections;
038 import java.util.LinkedHashMap;
039 import java.util.List;
040 import java.util.Map;
041 import java.util.UUID;
042
043 import static griffon.util.GriffonClassUtils.requireState;
044 import static griffon.util.GriffonClassUtils.setPropertyOrFieldValue;
045 import static griffon.util.GriffonNameUtils.isBlank;
046 import static griffon.util.GriffonNameUtils.requireNonBlank;
047 import static java.util.Collections.unmodifiableMap;
048 import static java.util.Objects.requireNonNull;
049
050 /**
051 * Base implementation of the {@code MVCGroup} interface
052 *
053 * @author Andres Almiray
054 * @since 2.0.0
055 */
056 public abstract class AbstractMVCGroup extends AbstractMVCHandler implements MVCGroup {
057 protected final MVCGroupConfiguration configuration;
058 protected final String mvcId;
059 protected final Context context;
060 protected final Map<String, Object> members = new LinkedHashMap<>();
061 protected final Map<String, MVCGroup> children = new LinkedHashMap<>();
062 private final Object[] lock = new Object[0];
063 protected MVCGroup parentGroup;
064 private boolean alive;
065 private final List<Object> injectedInstances = new ArrayList<>();
066
067 public AbstractMVCGroup(@Nonnull MVCGroupManager mvcGroupManager, @Nonnull MVCGroupConfiguration configuration, @Nullable String mvcId, @Nonnull Map<String, Object> members, @Nullable MVCGroup parentGroup) {
068 super(mvcGroupManager);
069 this.configuration = requireNonNull(configuration, "Argument 'configuration' must not be null");
070 this.mvcId = isBlank(mvcId) ? configuration.getMvcType() + "-" + UUID.randomUUID().toString() : mvcId;
071 this.members.putAll(requireNonNull(members, "Argument 'members' must not be null"));
072 this.alive = true;
073 this.parentGroup = parentGroup;
074 this.context = mvcGroupManager.newContext(parentGroup);
075
076 for (Object o : this.members.values()) {
077 if (o instanceof GriffonMvcArtifact) {
078 setPropertyOrFieldValue(o, "mvcGroup", this);
079 }
080 }
081 }
082
083 @Nonnull
084 public List<Object> getInjectedInstances() {
085 return injectedInstances;
086 }
087
088 @Nonnull
089 @Override
090 public Context getContext() {
091 return context;
092 }
093
094 @Nullable
095 @Override
096 public MVCGroup getParentGroup() {
097 return parentGroup;
098 }
099
100 @Nonnull
101 @Override
102 public MVCGroupConfiguration getConfiguration() {
103 return configuration;
104 }
105
106 @Nonnull
107 @Override
108 public String getMvcType() {
109 return configuration.getMvcType();
110 }
111
112 @Nonnull
113 @Override
114 public String getMvcId() {
115 return mvcId;
116 }
117
118 @Nullable
119 @Override
120 public GriffonModel getModel() {
121 return (GriffonModel) getMember(GriffonModelClass.TYPE);
122 }
123
124 @Nullable
125 @Override
126 public GriffonView getView() {
127 return (GriffonView) getMember(GriffonViewClass.TYPE);
128 }
129
130 @Nullable
131 @Override
132 public GriffonController getController() {
133 return (GriffonController) getMember(GriffonControllerClass.TYPE);
134 }
135
136 @Nullable
137 @Override
138 public Object getMember(@Nonnull String name) {
139 requireNonBlank(name, "Argument 'name' must not be blank");
140 checkIfAlive();
141 return members.get(name);
142 }
143
144 @Nonnull
145 @Override
146 public Map<String, Object> getMembers() {
147 checkIfAlive();
148 return unmodifiableMap(members);
149 }
150
151 @Override
152 public void destroy() {
153 if (isAlive()) {
154 List<String> childrenIds = new ArrayList<>(children.keySet());
155 Collections.reverse(childrenIds);
156 for (String id : childrenIds) {
157 getMvcGroupManager().destroyMVCGroup(id);
158 }
159 getMvcGroupManager().destroyMVCGroup(mvcId);
160 members.clear();
161 children.clear();
162 if (parentGroup != null) {
163 parentGroup.notifyMVCGroupDestroyed(mvcId);
164 }
165 parentGroup = null;
166 context.destroy();
167 synchronized (lock) {
168 alive = false;
169 }
170 }
171 }
172
173 @Override
174 public void notifyMVCGroupDestroyed(@Nonnull String mvcId) {
175 requireNonBlank(mvcId, "Argument 'mvcId' must not be blank");
176 children.remove(mvcId);
177 }
178
179 @Override
180 public boolean isAlive() {
181 synchronized (lock) {
182 return alive;
183 }
184 }
185
186 protected void checkIfAlive() {
187 requireState(isAlive(), "Group " + getMvcType() + ":" + mvcId + " has been destroyed already.");
188 }
189
190
191 @Nonnull
192 @Override
193 public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId) {
194 return manageChildGroup(super.createMVCGroup(mvcType, mvcId, injectParentGroup()));
195 }
196
197 @Nonnull
198 @Override
199 public MVCGroup createMVCGroup(@Nonnull String mvcType) {
200 return manageChildGroup(super.createMVCGroup(mvcType, injectParentGroup()));
201 }
202
203 @Nonnull
204 @Override
205 public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
206 return manageChildGroup(super.createMVCGroup(injectParentGroup(args), mvcType));
207 }
208
209 @Nonnull
210 @Override
211 public MVCGroup createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
212 return manageChildGroup(super.createMVCGroup(injectParentGroup(args), mvcType, mvcId));
213 }
214
215 @Nonnull
216 @Override
217 public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
218 return manageChildGroup(super.createMVCGroup(mvcType, injectParentGroup(args)));
219 }
220
221 @Nonnull
222 @Override
223 public MVCGroup createMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
224 return manageChildGroup(super.createMVCGroup(mvcType, mvcId, injectParentGroup(args)));
225 }
226
227 @Nonnull
228 @Override
229 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
230 return manageTypedChildGroup(super.createMVCGroup(mvcType, mvcId, injectParentGroup()));
231 }
232
233 @Nonnull
234 @Override
235 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType) {
236 return manageTypedChildGroup(super.createMVCGroup(mvcType, injectParentGroup()));
237 }
238
239 @Nonnull
240 @Override
241 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType) {
242 return manageTypedChildGroup(super.createMVCGroup(injectParentGroup(args), mvcType));
243 }
244
245 @Nonnull
246 @Override
247 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
248 return manageTypedChildGroup(super.createMVCGroup(injectParentGroup(args), mvcType, mvcId));
249 }
250
251 @Nonnull
252 @Override
253 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args) {
254 return manageTypedChildGroup(super.createMVCGroup(mvcType, injectParentGroup(args)));
255 }
256
257 @Nonnull
258 @Override
259 public <MVC extends TypedMVCGroup> MVC createMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
260 return manageTypedChildGroup(super.createMVCGroup(mvcType, mvcId, injectParentGroup(args)));
261 }
262
263 @Nonnull
264 @Override
265 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId) {
266 return manageChildGroup(super.createMVC(mvcType, mvcId, injectParentGroup()));
267 }
268
269 @Nonnull
270 @Override
271 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType) {
272 return manageChildGroup(super.createMVC(mvcType, injectParentGroup()));
273 }
274
275 @Nonnull
276 @Override
277 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType) {
278 return manageChildGroup(super.createMVC(injectParentGroup(args), mvcType));
279 }
280
281 @Nonnull
282 @Override
283 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId) {
284 return manageChildGroup(super.createMVC(injectParentGroup(args), mvcType, mvcId));
285 }
286
287 @Nonnull
288 @Override
289 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull Map<String, Object> args) {
290 return manageChildGroup(super.createMVC(mvcType, injectParentGroup(args)));
291 }
292
293 @Nonnull
294 @Override
295 public List<? extends GriffonMvcArtifact> createMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
296 return manageChildGroup(super.createMVC(mvcType, mvcId, injectParentGroup(args)));
297 }
298
299 @Nonnull
300 @Override
301 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
302 return manageChildGroup(super.createMVC(mvcType, mvcId, injectParentGroup()));
303 }
304
305 @Nonnull
306 @Override
307 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType) {
308 return manageChildGroup(super.createMVC(mvcType, injectParentGroup()));
309 }
310
311 @Nonnull
312 @Override
313 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType) {
314 return manageChildGroup(super.createMVC(injectParentGroup(args), mvcType));
315 }
316
317 @Nonnull
318 @Override
319 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId) {
320 return manageChildGroup(super.createMVC(injectParentGroup(args), mvcType, mvcId));
321 }
322
323 @Nonnull
324 @Override
325 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args) {
326 return manageChildGroup(super.createMVC(mvcType, injectParentGroup(args)));
327 }
328
329 @Nonnull
330 @Override
331 public <MVC extends TypedMVCGroup> List<? extends GriffonMvcArtifact> createMVC(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args) {
332 return manageChildGroup(super.createMVC(mvcType, mvcId, injectParentGroup(args)));
333 }
334
335 @Override
336 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) {
337 super.withMVC(injectParentGroup(args), mvcType, new MVCFunctionDecorator<>(handler));
338 }
339
340 @Override
341 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) {
342 super.withMVC(injectParentGroup(args), mvcType, mvcId, new MVCFunctionDecorator<>(handler));
343 }
344
345 @Override
346 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) {
347 super.withMVC(mvcType, injectParentGroup(args), new MVCFunctionDecorator<>(handler));
348 }
349
350 @Override
351 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) {
352 super.withMVC(mvcType, mvcId, injectParentGroup(args), new MVCFunctionDecorator<>(handler));
353 }
354
355 @Override
356 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull MVCFunction<M, V, C> handler) {
357 super.withMVC(mvcType, injectParentGroup(), new MVCFunctionDecorator<>(handler));
358 }
359
360 @Override
361 public <M extends GriffonModel, V extends GriffonView, C extends GriffonController> void withMVC(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCFunction<M, V, C> handler) {
362 super.withMVC(mvcType, mvcId, injectParentGroup(), new MVCFunctionDecorator<>(handler));
363 }
364
365 @Override
366 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) {
367 super.withMVC(injectParentGroup(args), mvcType, new MVCFunctionDecorator<>(handler));
368 }
369
370 @Override
371 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) {
372 super.withMVC(injectParentGroup(args), mvcType, mvcId, new MVCFunctionDecorator<>(handler));
373 }
374
375 @Override
376 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) {
377 super.withMVC(mvcType, injectParentGroup(args), new MVCFunctionDecorator<>(handler));
378 }
379
380 @Override
381 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) {
382 super.withMVC(mvcType, mvcId, injectParentGroup(args), new MVCFunctionDecorator<>(handler));
383 }
384
385 @Override
386 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) {
387 super.withMVC(mvcType, injectParentGroup(), new MVCFunctionDecorator<>(handler));
388 }
389
390 @Override
391 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) {
392 super.withMVC(mvcType, mvcId, injectParentGroup(), new MVCFunctionDecorator<>(handler));
393 }
394
395 @Override
396 public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
397 super.withMVCGroup(injectParentGroup(args), mvcType, new MVCGroupFunctionDecorator(handler));
398 }
399
400 @Override
401 public void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull String mvcType, @Nonnull String mvcId, @Nonnull MVCGroupFunction handler) {
402 super.withMVCGroup(injectParentGroup(args), mvcType, mvcId, new MVCGroupFunctionDecorator(handler));
403 }
404
405 @Override
406 public void withMVCGroup(@Nonnull String mvcType, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
407 super.withMVCGroup(mvcType, injectParentGroup(args), new MVCGroupFunctionDecorator(handler));
408 }
409
410 @Override
411 public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull MVCGroupFunction handler) {
412 super.withMVCGroup(mvcType, mvcId, injectParentGroup(args), new MVCGroupFunctionDecorator(handler));
413 }
414
415 @Override
416 public void withMVCGroup(@Nonnull String mvcType, @Nonnull MVCGroupFunction handler) {
417 super.withMVCGroup(mvcType, injectParentGroup(), new MVCGroupFunctionDecorator(handler));
418 }
419
420 @Override
421 public void withMVCGroup(@Nonnull String mvcType, @Nonnull String mvcId, @Nonnull final MVCGroupFunction handler) {
422 super.withMVCGroup(mvcType, mvcId, injectParentGroup(), new MVCGroupFunctionDecorator(handler));
423 }
424
425 @Override
426 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull TypedMVCGroupFunction<MVC> handler) {
427 super.withMVCGroup(injectParentGroup(args), mvcType, new TypedMVCGroupFunctionDecorator<>(handler));
428 }
429
430 @Override
431 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Map<String, Object> args, @Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull TypedMVCGroupFunction<MVC> handler) {
432 super.withMVCGroup(injectParentGroup(args), mvcType, mvcId, new TypedMVCGroupFunctionDecorator<>(handler));
433 }
434
435 @Override
436 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull Map<String, Object> args, @Nonnull TypedMVCGroupFunction<MVC> handler) {
437 super.withMVCGroup(mvcType, injectParentGroup(args), new TypedMVCGroupFunctionDecorator<>(handler));
438 }
439
440 @Override
441 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull Map<String, Object> args, @Nonnull TypedMVCGroupFunction<MVC> handler) {
442 super.withMVCGroup(mvcType, mvcId, injectParentGroup(args), new TypedMVCGroupFunctionDecorator<>(handler));
443 }
444
445 @Override
446 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull TypedMVCGroupFunction<MVC> handler) {
447 super.withMVCGroup(mvcType, injectParentGroup(), new TypedMVCGroupFunctionDecorator<>(handler));
448 }
449
450 @Override
451 public <MVC extends TypedMVCGroup> void withMVCGroup(@Nonnull Class<? extends MVC> mvcType, @Nonnull String mvcId, @Nonnull final TypedMVCGroupFunction<MVC> handler) {
452 super.withMVCGroup(mvcType, mvcId, injectParentGroup(), new TypedMVCGroupFunctionDecorator<>(handler));
453 }
454
455 @Nonnull
456 private MVCGroup manageChildGroup(@Nonnull MVCGroup group) {
457 children.put(group.getMvcId(), group);
458 return group;
459 }
460
461 @Nonnull
462 private <MVC extends TypedMVCGroup> MVC manageTypedChildGroup(@Nonnull MVC group) {
463 children.put(group.getMvcId(), group);
464 return group;
465 }
466
467 @Nonnull
468 private List<? extends GriffonMvcArtifact> manageChildGroup(@Nonnull List<? extends GriffonMvcArtifact> artifacts) {
469 MVCGroup group = null;
470 for (GriffonMvcArtifact artifact : artifacts) {
471 if (artifact != null) {
472 group = artifact.getMvcGroup();
473 break;
474 }
475 }
476 if (group != null) {
477 children.put(group.getMvcId(), group);
478 }
479 return artifacts;
480 }
481
482 @Nonnull
483 @Override
484 public Map<String, MVCGroup> getChildrenGroups() {
485 return unmodifiableMap(children);
486 }
487
488 @Nonnull
489 private Map<String, Object> injectParentGroup() {
490 return injectParentGroup(new LinkedHashMap<String, Object>());
491 }
492
493 @Nonnull
494 private Map<String, Object> injectParentGroup(@Nonnull Map<String, Object> args) {
495 Map<String, Object> map = new LinkedHashMap<>();
496 map.put("parentGroup", this);
497 map.putAll(args);
498 return map;
499 }
500
501 private final class MVCFunctionDecorator<M extends GriffonModel, V extends GriffonView, C extends GriffonController> implements MVCFunction<M, V, C> {
502 private final MVCFunction<M, V, C> delegate;
503
504 private MVCFunctionDecorator(MVCFunction<M, V, C> delegate) {
505 this.delegate = delegate;
506 }
507
508 @Override
509 public void apply(@Nullable M model, @Nullable V view, @Nullable C controller) {
510 MVCGroup group = null;
511 if (model != null) { group = model.getMvcGroup(); }
512 if (view != null) { group = view.getMvcGroup(); }
513 if (controller != null) { group = controller.getMvcGroup(); }
514
515 if (group != null) { children.put(group.getMvcId(), group); }
516 delegate.apply(model, view, controller);
517 if (group != null) { children.remove(group.getMvcId()); }
518 }
519 }
520
521 private final class MVCGroupFunctionDecorator implements MVCGroupFunction {
522 private final MVCGroupFunction delegate;
523
524 private MVCGroupFunctionDecorator(MVCGroupFunction delegate) {
525 this.delegate = delegate;
526 }
527
528 @Override
529 public void apply(@Nonnull MVCGroup group) {
530 children.put(group.getMvcId(), group);
531 delegate.apply(group);
532 children.remove(group.getMvcId());
533 }
534 }
535
536 private final class TypedMVCGroupFunctionDecorator<MVC extends TypedMVCGroup> implements TypedMVCGroupFunction<MVC> {
537 private final TypedMVCGroupFunction<MVC> delegate;
538
539 private TypedMVCGroupFunctionDecorator(TypedMVCGroupFunction<MVC> delegate) {
540 this.delegate = delegate;
541 }
542
543 @Override
544 public void apply(@Nonnull MVC group) {
545 children.put(group.getMvcId(), group);
546 delegate.apply(group);
547 children.remove(group.getMvcId());
548 }
549 }
550 }
|