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