Skip to content

Package: ViewModelListener

ViewModelListener

nameinstructionbranchcomplexitylinemethod
ViewModelListener(EMFFormsViewContext, EMFFormsSettingToControlMapper)
M: 0 C: 64
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 17
100%
M: 0 C: 1
100%
addVControl(VControl)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
dispose()
M: 1 C: 23
96%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 7
88%
M: 0 C: 1
100%
isDisposed()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
notifyChange(ModelChangeNotification)
M: 2 C: 89
98%
M: 2 C: 12
86%
M: 2 C: 6
75%
M: 2 C: 22
92%
M: 0 C: 1
100%
removeVControl(VControl)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2016 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: * Lucas Koehler - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.internal.core.services.controlmapper;
15:
16: import java.util.LinkedHashSet;
17: import java.util.List;
18: import java.util.Set;
19:
20: import org.eclipse.emf.common.notify.Notification;
21: import org.eclipse.emf.common.util.BasicEList;
22: import org.eclipse.emf.common.util.Diagnostic;
23: import org.eclipse.emf.common.util.EList;
24: import org.eclipse.emf.common.util.TreeIterator;
25: import org.eclipse.emf.ecore.EObject;
26: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
27: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
28: import org.eclipse.emf.ecp.view.spi.model.VControl;
29: import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
30: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
31: import org.eclipse.emf.ecp.view.spi.model.VViewFactory;
32: import org.eclipse.emfforms.spi.core.services.controlmapper.EMFFormsSettingToControlMapper;
33: import org.eclipse.emfforms.spi.core.services.structuralchange.EMFFormsStructuralChangeTester;
34: import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;
35: import org.osgi.framework.BundleContext;
36: import org.osgi.framework.FrameworkUtil;
37: import org.osgi.framework.ServiceReference;
38:
39: /**
40: * A {@link ModelChangeListener} that listens to the view model of a {@link EMFFormsViewContext} and updates a
41: * {@link EMFFormsSettingToControlMapper} whenever the view model was changed in a way that is important to its
42: * {@link org.eclipse.emf.ecp.view.spi.model.VDomainModelReference VDomainModelReferences}.
43: *
44: * @author Lucas Koehler
45: *
46: */
47: public class ViewModelListener implements ModelChangeListener {
48:
49:         private boolean isDisposed;
50:         // private final EMFFormsDomainExpander domainExpander;
51:         // private final ServiceReference<EMFFormsDomainExpander> domainExpanderServiceReference;
52:         private final EMFFormsStructuralChangeTester structuralChangeTester;
53:         private final ServiceReference<EMFFormsStructuralChangeTester> structuralChangeTesterServiceReference;
54:         private final EMFFormsViewContext viewModelContext;
55:         private final EMFFormsSettingToControlMapper settingToControlMapper;
56:         private final Set<VControl> vControls = new LinkedHashSet<VControl>();
57:         // private final ServiceReference<ReportService> reportServiceReference;
58:         // private final ReportService reportService;
59:
60:         /**
61:          * Creates a new instance of {@link ViewModelListener}.
62:          *
63:          * @param context The {@link EMFFormsViewContext} this {@link ViewModelListener} listens to
64:          * @param mapper The {@link EMFFormsSettingToControlMapper} to keep updated
65:          */
66:         public ViewModelListener(EMFFormsViewContext context, EMFFormsSettingToControlMapper mapper) {
67:                 isDisposed = false;
68:                 viewModelContext = context;
69:                 settingToControlMapper = mapper;
70:
71:                 // Get needed services
72:                 final BundleContext bundleContext = FrameworkUtil.getBundle(ViewModelListener.class).getBundleContext();
73:                 // domainExpanderServiceReference = bundleContext.getServiceReference(EMFFormsDomainExpander.class);
74:                 // domainExpander = bundleContext.getService(domainExpanderServiceReference);
75:                 // reportServiceReference = bundleContext.getServiceReference(ReportService.class);
76:                 // reportService = bundleContext.getService(reportServiceReference);
77:                 structuralChangeTesterServiceReference = bundleContext
78:                         .getServiceReference(EMFFormsStructuralChangeTester.class);
79:                 structuralChangeTester = bundleContext.getService(structuralChangeTesterServiceReference);
80:
81:                 final TreeIterator<EObject> eAllContents = viewModelContext.getViewModel().eAllContents();
82:•                while (eAllContents.hasNext()) {
83:                         final EObject eObject = eAllContents.next();
84:•                        if (VControl.class.isInstance(eObject)) {
85:                                 final VControl vControl = VControl.class.cast(eObject);
86:                                 vControls.add(vControl);
87:                         }
88:                 }
89:                 viewModelContext.registerDomainChangeListener(this);
90:         }
91:
92:         /**
93:          * {@inheritDoc}
94:          *
95:          * @see org.eclipse.emf.ecp.view.spi.model.ModelChangeListener#notifyChange(org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification)
96:          */
97:         @Override
98:         public void notifyChange(ModelChangeNotification notification) {
99:•                if (notification.getRawNotification().isTouch()) {
100:                         return;
101:                 }
102:•                if (notification.getRawNotification().getEventType() == Notification.REMOVING_ADAPTER) {
103:                         return;
104:                 }
105:•                for (final VControl control : vControls) {
106:                         // TODO: table detail views might have a different root.
107:
108:                         final VDomainModelReference reference = control.getDomainModelReference();
109:•                        if (reference == null) {
110:                                 /*
111:                                  * don't call structural change testers, because they have Asserts that the reference is not null ->
112:                                  * avoid IAE
113:                                  * TODO what is the expected behaviour here?
114:                                  */
115:                                 continue;
116:                         }
117:•                        if (structuralChangeTester.isStructureChanged(reference, viewModelContext.getDomainModel(), notification)) {
118:                                 SettingToControlExpandHelper.resolveDomainReferences(control, viewModelContext.getDomainModel(),
119:                                         viewModelContext);
120:                                 settingToControlMapper.updateControlMapping(control);
121:
122:                                 // TODO move it somewhere eg to the controlMapper?
123:                                 // clean diagnostic
124:•                                if (!notification.getStructuralFeature().isMany()) {
125:                                         control.setDiagnostic(null);
126:•                                } else if (control.getDiagnostic() != null) {
127:                                         final List<Diagnostic> diagnostics = control.getDiagnostic()
128:                                                 .getDiagnostic(notification.getNotifier(), notification.getStructuralFeature());
129:
130:                                         final EList<Object> newDiagnostics = new BasicEList<Object>(
131:                                                 control.getDiagnostic().getDiagnostics());
132:                                         newDiagnostics.removeAll(diagnostics);
133:                                         final VDiagnostic vDiagnostic = VViewFactory.eINSTANCE.createDiagnostic();
134:                                         vDiagnostic.getDiagnostics().addAll(newDiagnostics);
135:                                         control.setDiagnostic(vDiagnostic);
136:                                 }
137:
138:                                 // re-resolve DMR
139:                                 // TODO discuss this
140:                                 // try {
141:                                 // domainExpander.prepareDomainObject(reference,
142:                                 // viewModelContext.getDomainModel());
143:                                 // } catch (final EMFFormsExpandingFailedException ex) {
144:                                 // reportService.report(new AbstractReport(ex,
145:                                 // "The DMR " + reference + " could not be re-resolved!")); //$NON-NLS-1$//$NON-NLS-2$
146:                                 // }
147:                         }
148:                 }
149:         }
150:
151:         /**
152:          * Adds a {@link VControl} to this {@link ViewModelListener} in order to check the control's
153:          * {@link org.eclipse.emf.ecp.view.spi.model.VDomainModelReference VDomainModelReference} for changes to the domain
154:          * model.
155:          *
156:          * @param control The VControl to add
157:          * @return true if this {@link ViewModelListener} didn't already know the control and it was added, false otherwise.
158:          */
159:         public boolean addVControl(VControl control) {
160:                 return vControls.add(control);
161:         }
162:
163:         /**
164:          * Remove a {@link VControl} from this {@link ViewModelListener}. It's
165:          * {@link org.eclipse.emf.ecp.view.spi.model.VDomainModelReference VDomainModelReference} will the no longer be
166:          * checked for changes to the domain model.
167:          *
168:          * @param control The VControl to remove.
169:          * @return true if the {@link ViewModelListener} knew this {@link VControl} and it was removed, false otherwise.
170:          */
171:         public boolean removeVControl(VControl control) {
172:                 return vControls.remove(control);
173:         }
174:
175:         /**
176:          * Dispose this {@link ViewModelListener}.
177:          */
178:         public void dispose() {
179:•                if (isDisposed) {
180:                         return;
181:                 }
182:
183:                 viewModelContext.unregisterDomainChangeListener(this);
184:                 vControls.clear();
185:
186:                 final BundleContext bundleContext = FrameworkUtil.getBundle(ViewModelListener.class).getBundleContext();
187:                 // bundleContext.ungetService(domainExpanderServiceReference);
188:                 // bundleContext.ungetService(reportServiceReference);
189:                 bundleContext.ungetService(structuralChangeTesterServiceReference);
190:
191:                 isDisposed = true;
192:         }
193:
194:         /**
195:          * Returns whether this {@link ViewModelListener} is disposed.
196:          *
197:          * @return true if this {@link ViewModelListener} is disposed, false otherwise
198:          */
199:         public boolean isDisposed() {
200:                 return isDisposed;
201:         }
202:
203: }