Skip to content

Package: RuleService$RuleServiceViewChangeListener

RuleService$RuleServiceViewChangeListener

nameinstructionbranchcomplexitylinemethod
RuleService.RuleServiceViewChangeListener(RuleService, ViewModelContext)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
notifyAdd(Notifier)
M: 0 C: 157
100%
M: 0 C: 16
100%
M: 0 C: 9
100%
M: 0 C: 27
100%
M: 0 C: 1
100%
notifyChange(ModelChangeNotification)
M: 9 C: 81
90%
M: 8 C: 10
56%
M: 8 C: 2
20%
M: 7 C: 20
74%
M: 0 C: 1
100%
notifyRemove(Notifier)
M: 0 C: 84
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 17
100%
M: 0 C: 1
100%
reevaluateRule(Condition, Rule, VElement)
M: 21 C: 28
57%
M: 4 C: 4
50%
M: 3 C: 2
40%
M: 5 C: 8
62%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2013 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * Edgar Mueller - initial API and implementation
13: * Johannes Faltermeier - registry setting based instead of feature based
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.view.internal.rule;
16:
17: import java.util.Arrays;
18: import java.util.Collection;
19: import java.util.Collections;
20: import java.util.HashMap;
21: import java.util.HashSet;
22: import java.util.LinkedHashMap;
23: import java.util.LinkedHashSet;
24: import java.util.List;
25: import java.util.Map;
26: import java.util.Set;
27:
28: import org.eclipse.emf.common.notify.Notifier;
29: import org.eclipse.emf.common.util.TreeIterator;
30: import org.eclipse.emf.ecore.EClass;
31: import org.eclipse.emf.ecore.EObject;
32: import org.eclipse.emf.ecore.EStructuralFeature;
33: import org.eclipse.emf.ecore.EStructuralFeature.Setting;
34: import org.eclipse.emf.ecore.InternalEObject;
35: import org.eclipse.emf.ecp.common.spi.UniqueSetting;
36: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
37: import org.eclipse.emf.ecp.view.spi.context.ViewModelService;
38: import org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener;
39: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
40: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
41: import org.eclipse.emf.ecp.view.spi.model.VAttachment;
42: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
43: import org.eclipse.emf.ecp.view.spi.model.VElement;
44: import org.eclipse.emf.ecp.view.spi.model.VFeaturePathDomainModelReference;
45: import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
46: import org.eclipse.emf.ecp.view.spi.rule.model.Condition;
47: import org.eclipse.emf.ecp.view.spi.rule.model.EnableRule;
48: import org.eclipse.emf.ecp.view.spi.rule.model.LeafCondition;
49: import org.eclipse.emf.ecp.view.spi.rule.model.Rule;
50: import org.eclipse.emf.ecp.view.spi.rule.model.ShowRule;
51: import org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener;
52: import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;
53:
54: /**
55: * Rule service that, once instantiated, maintains and synchronizes
56: * the state of a rule with its {@link VElement}.
57: *
58: * @author emueller
59: * @author jfaltermeier
60: */
61: public class RuleService implements ViewModelService, EMFFormsContextListener {
62:
63:         private static final String DOMAIN_MODEL_NULL_EXCEPTION = "Domain model must not be null."; //$NON-NLS-1$
64:         private static final String VIEW_MODEL_NULL_EXCEPTION = "View model must not be null."; //$NON-NLS-1$
65:         private ViewModelContext context;
66:         private ModelChangeListener domainChangeListener;
67:         private ModelChangeAddRemoveListener viewChangeListener;
68:
69:         private RuleRegistry<EnableRule> enableRuleRegistry;
70:         private RuleRegistry<ShowRule> showRuleRegistry;
71:         private ConditionServiceManager conditionServiceManager;
72:
73:         /**
74:          * Instantiates the rule service.
75:          */
76:         public RuleService() {
77:         }
78:
79:         /**
80:          * {@inheritDoc}
81:          *
82:          * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#instantiate(org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
83:          */
84:         @Override
85:         public void instantiate(final ViewModelContext context) {
86:                 this.context = context;
87:                 enableRuleRegistry = new RuleRegistry<EnableRule>(context);
88:                 showRuleRegistry = new RuleRegistry<ShowRule>(context);
89:                 context.registerEMFFormsContextListener(this);
90:                 conditionServiceManager = context.getService(ConditionServiceManager.class);
91:         }
92:
93:         private void resetToVisible(VElement renderable) {
94:                 if (renderable == null) {
95:                         return;
96:                 }
97:                 final Map<VElement, Boolean> maps = new LinkedHashMap<VElement, Boolean>();
98:                 updateStateMap(maps, renderable, false, true, ShowRule.class);
99:                 for (final VElement vElement : maps.keySet()) {
100:                         vElement.setVisible(maps.get(vElement));
101:                 }
102:         }
103:
104:         private void resetToEnabled(VElement renderable) {
105:                 if (renderable == null) {
106:                         return;
107:                 }
108:                 final Map<VElement, Boolean> maps = new LinkedHashMap<VElement, Boolean>();
109:                 updateStateMap(maps, renderable, false, true, EnableRule.class);
110:                 for (final VElement vElement : maps.keySet()) {
111:                         vElement.setEnabled(maps.get(vElement));
112:                 }
113:         }
114:
115:         private static Collection<Rule> getRules(VElement renderable) {
116:                 final Map<Class<? extends Rule>, Rule> rules = new HashMap<Class<? extends Rule>, Rule>();
117:                 for (final VAttachment attachment : renderable.getAttachments()) {
118:                         if (Rule.class.isInstance(attachment)) {
119:                                 final Rule rule = (Rule) attachment;
120:                                 if (!rules.containsKey(rule.getClass())) {
121:                                         rules.put(rule.getClass(), rule);
122:                                 }
123:                         }
124:                 }
125:                 return rules.values();
126:         }
127:
128:         private static <T extends Rule> T getRule(Class<T> ruleType, VElement renderable) {
129:                 final Collection<Rule> rules = getRules(renderable);
130:                 for (final Rule rule : rules) {
131:                         if (ruleType.isInstance(rule)) {
132:                                 return ruleType.cast(rule);
133:                         }
134:                 }
135:                 return null;
136:         }
137:
138:         private <T extends Rule> void updateStateMap(Map<VElement, Boolean> stateMap, VElement renderable,
139:                 boolean isOpposite, boolean evalResult, Class<T> ruleType) {
140:
141:                 if (!stateMap.containsKey(renderable)) {
142:                         final Collection<Rule> rules = getRules(renderable);
143:                         boolean didUpdate = false;
144:                         for (final Rule rule : rules) {
145:                                 if (rule != null && ruleApplies(rule, ruleType)) {
146:                                         final Condition condition = rule.getCondition();
147:                                         if (condition != null && canOverrideParent(evalResult, isOpposite)) {
148:                                                 final boolean evaluate = conditionServiceManager.evaluate(condition, context.getDomainModel());
149:                                                 stateMap.put(renderable, isOpposite(rule) ? !evaluate : evaluate);
150:                                                 didUpdate = true;
151:                                         }
152:                                 }
153:                         }
154:                         // use result of parent
155:                         if (!didUpdate) {
156:                                 stateMap.put(renderable, isOpposite ? !evalResult : evalResult);
157:                         }
158:                 } else {
159:                         final Boolean currentState = stateMap.get(renderable).booleanValue();
160:                         if (currentState) {
161:                                 stateMap.put(renderable, isOpposite ? !evalResult : evalResult);
162:                         }
163:                 }
164:
165:                 for (final EObject childContent : renderable.eContents()) {
166:                         if (childContent instanceof VElement) {
167:                                 updateStateMap(stateMap, (VElement) childContent, isOpposite, evalResult, ruleType);
168:                         }
169:                 }
170:         }
171:
172:         private static boolean canOverrideParent(boolean evalResult, boolean isOpposite) {
173:                 return evalResult && !isOpposite || !evalResult && isOpposite;
174:         }
175:
176:         private static <T extends Rule> boolean ruleApplies(Rule rule, Class<T> ruleType) {
177:                 return Arrays.asList(rule.getClass().getInterfaces()).contains(ruleType);
178:         }
179:
180:         private static boolean isOpposite(Rule rule) {
181:                 return isHideRule(rule) || isDisableRule(rule);
182:         }
183:
184:         private <T extends Rule> Map<VElement, Boolean> evalAffectedRenderables(RuleRegistry<T> registry,
185:                 Class<T> ruleType, UniqueSetting setting, boolean isDryRun, Map<Setting, Object> possibleValues) {
186:
187:                 final Map<VElement, Boolean> map = new LinkedHashMap<VElement, Boolean>();
188:
189:                 for (final Map.Entry<T, VElement> ruleAndRenderable : registry.getAffectedRenderables(
190:                         setting).entrySet()) {
191:
192:                         final Rule rule = ruleAndRenderable.getKey();
193:
194:                         final VElement renderable = ruleAndRenderable.getValue();
195:                         // whether the value changed at all, if newValue has been provided
196:                         boolean hasChanged = true;
197:
198:                         if (!ruleType.isInstance(rule)) {
199:                                 continue;
200:                         }
201:
202:                         if (isDryRun) {
203:
204:                                 hasChanged = checkDryRun(possibleValues);
205:
206:                         }
207:
208:                         boolean result = false;
209:                         boolean updateMap = true;
210:                         if (rule.getCondition() == null) {
211:                                 result = true;
212:                         } else if (isDryRun && hasChanged) {
213:                                 result = conditionServiceManager.evaluateChangedValues(rule.getCondition(), context.getDomainModel(),
214:                                         possibleValues);
215:                         } else if (!isDryRun) {
216:                                 result = conditionServiceManager.evaluate(rule.getCondition(), context.getDomainModel());
217:                         } else {
218:                                 updateMap = false;
219:                         }
220:                         final boolean isOposite = isDisableRule(rule) || isHideRule(rule);
221:                         updateMap &= propagateChanges(result, isOposite, rule, renderable);
222:                         if (updateMap) {
223:                                 updateStateMap(map, renderable, isOposite, result, ruleType);
224:                         }
225:                 }
226:
227:                 return map;
228:         }
229:
230:         private static boolean propagateChanges(boolean result, boolean isOposite, Rule rule, VElement renderable) {
231:                 if (result && !isOposite || isOposite && !result) {
232:                         if (ShowRule.class.isInstance(rule)) {
233:                                 if (isOposite && result != renderable.isVisible()) {
234:                                         return false;
235:                                 } else if (!isOposite && result == renderable.isVisible()) {
236:                                         return false;
237:                                 }
238:                         } else if (EnableRule.class.isInstance(rule)) {
239:                                 if (isOposite && result != renderable.isEnabled()) {
240:                                         return false;
241:                                 } else if (!isOposite && result == renderable.isEnabled()) {
242:                                         return false;
243:                                 }
244:                         }
245:                 }
246:                 return true;
247:         }
248:
249:         private static boolean checkDryRun(Map<Setting, Object> possibleValues) {
250:                 boolean hasChanged = true;
251:                 for (final Setting setting : possibleValues.keySet()) {
252:                         final EObject parent = setting.getEObject();
253:                         final EStructuralFeature feature = setting.getEStructuralFeature();
254:                         final EClass attributeClass = feature.getEContainingClass();
255:                         if (!attributeClass.isInstance(parent)) {
256:                                 continue;
257:                         }
258:                         final Object actualValue = parent.eGet(feature);
259:                         final Object newValue = possibleValues.get(setting);
260:                         if (!feature.isMany()) {
261:                                 if (newValue == null) {
262:                                         hasChanged &= actualValue == null;
263:                                 } else {
264:                                         hasChanged &= !newValue.equals(actualValue);
265:                                 }
266:                         } else {
267:                                 // EMF API
268:                                 @SuppressWarnings("unchecked")
269:                                 final List<Object> objects = (List<Object>) actualValue;
270:                                 @SuppressWarnings("unchecked")
271:                                 final List<Object> newValues = (List<Object>) newValue;
272:                                 if (objects.size() == newValues.size()) {
273:                                         boolean sameEntries = true;
274:                                         for (final Object newValueListEntry : newValues) {
275:                                                 if (!objects.contains(newValueListEntry)) {
276:                                                         sameEntries = false;
277:                                                 }
278:                                         }
279:                                         hasChanged &= !sameEntries;
280:                                 } else {
281:                                         hasChanged = true;
282:                                 }
283:                         }
284:                 }
285:                 return hasChanged;
286:         }
287:
288:         private <T extends Rule> Map<VElement, Boolean> evalAffectedRenderables(RuleRegistry<T> registry,
289:                 Class<T> ruleType, UniqueSetting setting, Map<Setting, Object> possibleValues) {
290:                 return evalAffectedRenderables(registry, ruleType, setting, true, possibleValues);
291:         }
292:
293:         private <T extends Rule> Map<VElement, Boolean> evalAffectedRenderables(RuleRegistry<T> registry,
294:                 Class<T> ruleType, UniqueSetting setting) {
295:                 final Map<Setting, Object> changedValues = Collections.emptyMap();
296:                 return evalAffectedRenderables(registry, ruleType, setting, false, changedValues);
297:         }
298:
299:         private static boolean isDisableRule(Rule rule) {
300:                 if (isEnableRule(rule)) {
301:                         final EnableRule enableRule = (EnableRule) rule;
302:                         return enableRule.isDisable();
303:                 }
304:
305:                 return false;
306:         }
307:
308:         private static boolean isHideRule(Rule rule) {
309:                 if (isShowRule(rule)) {
310:                         final ShowRule showRule = (ShowRule) rule;
311:                         return showRule.isHide();
312:                 }
313:
314:                 return false;
315:         }
316:
317:         private static boolean isShowRule(Rule rule) {
318:                 return rule instanceof ShowRule;
319:         }
320:
321:         private <T extends Rule> void evalShow(UniqueSetting setting) {
322:
323:                 final Map<VElement, Boolean> visibleMap = evalAffectedRenderables(showRuleRegistry, ShowRule.class,
324:                         setting);
325:                 final Set<VElement> toBeVisible = new LinkedHashSet<VElement>();
326:                 final Set<VElement> toBeInvisible = new LinkedHashSet<VElement>();
327:                 for (final Map.Entry<VElement, Boolean> e : visibleMap.entrySet()) {
328:                         final Boolean isVisible = e.getValue();
329:                         final VElement renderable = e.getKey();
330:                         if (isVisible) {
331:                                 toBeVisible.add(renderable);
332:                         } else {
333:                                 toBeInvisible.add(renderable);
334:                         }
335:                 }
336:
337:                 for (final VElement vElement : toBeInvisible) {
338:                         vElement.setVisible(false);
339:                 }
340:                 for (final VElement vElement : toBeVisible) {
341:                         vElement.setVisible(true);
342:                 }
343:         }
344:
345:         private <T extends Rule> void evalEnable(UniqueSetting setting) {
346:
347:                 final Map<VElement, Boolean> enabledMap = evalAffectedRenderables(enableRuleRegistry, EnableRule.class,
348:                         setting);
349:
350:                 for (final Map.Entry<VElement, Boolean> e : enabledMap.entrySet()) {
351:                         e.getKey().setEnabled(e.getValue());
352:                 }
353:         }
354:
355:         private <T extends Rule> Set<UniqueSetting> init(RuleRegistry<T> registry, Class<T> ruleType,
356:                 EObject viewModel,
357:                 EObject domainObject) {
358:                 final TreeIterator<EObject> iterator = viewModel.eAllContents();
359:                 final Set<UniqueSetting> relevantSettings = new LinkedHashSet<UniqueSetting>();
360:                 relevantSettings.addAll(register(registry, ruleType, domainObject, viewModel));
361:
362:                 while (iterator.hasNext()) {
363:                         final EObject content = iterator.next();
364:                         relevantSettings.addAll(register(registry, ruleType, domainObject, content));
365:                 }
366:                 return relevantSettings;
367:         }
368:
369:         private <T extends Rule> Set<UniqueSetting> register(RuleRegistry<T> registry, Class<T> ruleType,
370:                 EObject domainObject, final EObject viewModel) {
371:                 final Set<UniqueSetting> result = new HashSet<UniqueSetting>();
372:                 if (viewModel instanceof VElement) {
373:                         final VElement renderable = (VElement) viewModel;
374:                         final T rule = getRule(ruleType, renderable);
375:                         if (rule != null) {
376:                                 result.addAll(registry.register(renderable, rule, rule.getCondition(), domainObject));
377:                         }
378:                 }
379:                 return result;
380:         }
381:
382:         /**
383:          * Returns all {@link VElement}s, that would we disabled if {@code possibleValues} would be set for the given
384:          * {@code setting}s.
385:          *
386:          * @param possibleValues
387:          * a mapping of settings to their would-be new value
388:          * @param setting the changed setting
389:          * @return the hidden {@link VElement}s and their new state if {@code possibleValues} would be set
390:          */
391:         public Map<VElement, Boolean> getDisabledRenderables(Map<Setting, Object> possibleValues,
392:                 UniqueSetting setting) {
393:
394:                 return evalAffectedRenderables(enableRuleRegistry,
395:                         EnableRule.class, setting, possibleValues);
396:         }
397:
398:         /**
399:          * Returns all {@link VElement}s, that would we hidden if {@code possibleValues} would be set for the given
400:          * {@code setting}s.
401:          *
402:          * @param possibleValues
403:          * a mapping of settings to their would-be new value
404:          * @param setting the setting that was changed
405:          * @return the hidden {@link VElement}s and their new state if {@code possibleValues} would be set
406:          */
407:         public Map<VElement, Boolean> getHiddenRenderables(Map<Setting, Object> possibleValues, UniqueSetting setting) {
408:
409:                 return evalAffectedRenderables(showRuleRegistry,
410:                         ShowRule.class, setting, possibleValues);
411:         }
412:
413:         /**
414:          * Dispose.
415:          */
416:         @Override
417:         public void dispose() {
418:                 // dispose stuff
419:                 context.unregisterEMFFormsContextListener(this);
420:                 context.unregisterDomainChangeListener(domainChangeListener);
421:                 context.unregisterViewChangeListener(viewChangeListener);
422:                 enableRuleRegistry.dispose();
423:                 showRuleRegistry.dispose();
424:         }
425:
426:         private static boolean isEnableRule(Rule rule) {
427:                 return EnableRule.class.isInstance(rule);
428:         }
429:
430:         /**
431:          * {@inheritDoc}
432:          *
433:          * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#getPriority()
434:          */
435:         @Override
436:         public int getPriority() {
437:                 return 1;
438:         }
439:
440:         /**
441:          * Lister of the rule service reacting to view model changes.
442:          */
443:         private final class RuleServiceViewChangeListener implements ModelChangeAddRemoveListener {
444:                 private final ViewModelContext context;
445:
446:                 /**
447:                  * @param context
448:                  */
449:                 private RuleServiceViewChangeListener(ViewModelContext context) {
450:                         this.context = context;
451:                 }
452:
453:                 @Override
454:                 public void notifyChange(ModelChangeNotification notification) {
455:•                        if (VFeaturePathDomainModelReference.class.isInstance(notification.getNotifier())) {
456:•                                if (notification.getStructuralFeature() == VViewPackage.eINSTANCE
457:                                         .getDomainModelReference_ChangeListener()) {
458:                                         return;
459:                                 }
460:                                 final VDomainModelReference domainModelReference = VDomainModelReference.class.cast(notification
461:                                         .getNotifier());
462:                                 final EObject eContainer = domainModelReference.eContainer();
463:•                                if (!LeafCondition.class.isInstance(eContainer)) {
464:                                         return;
465:                                 }
466:                                 final Condition condition = Condition.class.cast(eContainer);
467:                                 enableRuleRegistry.removeCondition(condition);
468:                                 showRuleRegistry.removeCondition(condition);
469:                                 EObject parent = condition.eContainer();
470:•                                while (parent != null && !Rule.class.isInstance(parent)) {
471:                                         parent = parent.eContainer();
472:                                 }
473:•                                if (parent == null) {
474:                                         return;
475:                                 }
476:•                                if (!Rule.class.isInstance(parent)) {
477:                                         return;
478:                                 }
479:                                 final Rule rule = Rule.class.cast(parent);
480:•                                final VElement renderable = VElement.class.isInstance(rule.eContainer())
481:                                         ? VElement.class.cast(rule.eContainer())
482:                                         : null;
483:
484:•                                if (renderable == null) {
485:                                         return;
486:                                 }
487:                                 reevaluateRule(condition, rule, renderable);
488:                         }
489:                 }
490:
491:                 private void reevaluateRule(final Condition condition, final Rule rule, final VElement renderable) {
492:•                        if (isEnableRule(rule)) {
493:                                 if (enableRuleRegistry.register(renderable, (EnableRule) rule, condition,
494:•                                        context.getDomainModel()).isEmpty()) {
495:                                         renderable.setEnabled(true);
496:                                 } else {
497:                                         resetToEnabled(renderable);
498:                                 }
499:                         }
500:•                        if (isShowRule(rule)) {
501:                                 if (showRuleRegistry.register(renderable, (ShowRule) rule, condition, context.getDomainModel())
502:•                                        .isEmpty()) {
503:                                         renderable.setVisible(true);
504:                                 } else {
505:                                         resetToVisible(renderable);
506:                                 }
507:                         }
508:                 }
509:
510:                 @Override
511:                 public void notifyAdd(Notifier notifier) {
512:•                        if (VElement.class.isInstance(notifier)) {
513:                                 register(enableRuleRegistry, EnableRule.class, context.getDomainModel(),
514:                                         VElement.class.cast(notifier));
515:                                 register(showRuleRegistry, ShowRule.class, context.getDomainModel(), VElement.class.cast(notifier));
516:
517:                                 final Collection<Rule> rules = getRules(VElement.class.cast(notifier));
518:•                                if (rules.isEmpty()) {
519:                                         return;
520:                                 }
521:•                                for (final Rule rule : rules) {
522:                                         final Set<UniqueSetting> settings = conditionServiceManager.getConditionSettings(
523:                                                 rule.getCondition(),
524:                                                 context.getDomainModel());
525:•                                        for (final UniqueSetting setting : settings) {
526:                                                 evalEnable(setting);
527:                                                 evalShow(setting);
528:                                         }
529:                                 }
530:
531:•                        } else if (EnableRule.class.isInstance(notifier)) {
532:                                 final Set<UniqueSetting> register = register(enableRuleRegistry, EnableRule.class,
533:                                         context.getDomainModel(),
534:                                         EnableRule.class.cast(notifier).eContainer());
535:
536:•                                for (final UniqueSetting setting : register) {
537:                                         evalEnable(setting);
538:                                 }
539:
540:•                        } else if (ShowRule.class.isInstance(notifier)) {
541:                                 final Set<UniqueSetting> register = register(showRuleRegistry, ShowRule.class,
542:                                         context.getDomainModel(), ShowRule.class.cast(notifier)
543:                                                 .eContainer());
544:
545:•                                for (final UniqueSetting setting : register) {
546:                                         evalShow(setting);
547:                                 }
548:
549:                         }
550:                 }
551:
552:                 @Override
553:                 public void notifyRemove(Notifier notifier) {
554:•                        if (VElement.class.isInstance(notifier)) {
555:                                 final VElement renderable = VElement.class.cast(notifier);
556:                                 showRuleRegistry.removeRenderable(renderable);
557:                                 enableRuleRegistry.removeRenderable(renderable);
558:•                        } else if (Condition.class.isInstance(notifier)) {
559:                                 final Condition condition = Condition.class.cast(notifier);
560:                                 resetToVisible(showRuleRegistry.removeCondition(condition));
561:
562:                                 resetToEnabled(enableRuleRegistry
563:                                         .removeCondition(condition));
564:
565:•                        } else if (ShowRule.class.isInstance(notifier)) {
566:                                 final ShowRule showRule = ShowRule.class.cast(notifier);
567:                                 resetToVisible(showRuleRegistry.removeRule(showRule));
568:
569:•                        } else if (EnableRule.class.isInstance(notifier)) {
570:                                 final EnableRule enableRule = EnableRule.class.cast(notifier);
571:                                 final VElement removeRule = enableRuleRegistry.removeRule(enableRule);
572:                                 resetToEnabled(removeRule);
573:
574:                         }
575:                 }
576:         }
577:
578:         /**
579:          * {@inheritDoc}
580:          *
581:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextAdded(org.eclipse.emf.ecp.view.spi.model.VElement,
582:          * org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
583:          */
584:         @Override
585:         public void childContextAdded(VElement parentElement, EMFFormsViewContext childContext) {
586:                 // do nothing
587:         }
588:
589:         /**
590:          * {@inheritDoc}
591:          *
592:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextDisposed(org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
593:          */
594:         @Override
595:         public void childContextDisposed(EMFFormsViewContext childContext) {
596:                 // do nothing
597:         }
598:
599:         /**
600:          * {@inheritDoc}
601:          *
602:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextInitialised()
603:          */
604:         @Override
605:         public void contextInitialised() {
606:                 final VElement view = context.getViewModel();
607:                 domainChangeListener = new ModelChangeListener() {
608:
609:                         @Override
610:                         public void notifyChange(ModelChangeNotification notification) {
611:                                 if (notification.getStructuralFeature() == null) {
612:                                         return;
613:                                 }
614:                                 // add && reference && !containment
615:                                 final Setting setting = ((InternalEObject) notification.getNotifier()).eSetting(notification
616:                                         .getStructuralFeature());
617:                                 evalShow(UniqueSetting.createSetting(setting));
618:                                 evalEnable(UniqueSetting.createSetting(setting));
619:                         }
620:                 };
621:                 context.registerDomainChangeListener(domainChangeListener);
622:                 viewChangeListener = new RuleServiceViewChangeListener(context);
623:                 context.registerViewChangeListener(viewChangeListener);
624:
625:                 if (view == null) {
626:                         throw new IllegalStateException(VIEW_MODEL_NULL_EXCEPTION);
627:                 }
628:
629:                 final EObject domainModel = context.getDomainModel();
630:
631:                 if (domainModel == null) {
632:                         throw new IllegalStateException(DOMAIN_MODEL_NULL_EXCEPTION);
633:                 }
634:
635:                 final Set<UniqueSetting> enableSettings = init(enableRuleRegistry, EnableRule.class, view, domainModel);
636:                 final Set<UniqueSetting> showSettings = init(showRuleRegistry, ShowRule.class, view, domainModel);
637:                 for (final UniqueSetting setting : enableSettings) {
638:                         evalEnable(setting);
639:                 }
640:                 for (final UniqueSetting setting : showSettings) {
641:                         evalShow(setting);
642:                 }
643:         }
644:
645:         /**
646:          * {@inheritDoc}
647:          *
648:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextDispose()
649:          */
650:         @Override
651:         public void contextDispose() {
652:                 // do nothing
653:         }
654: }