Skip to content

Package: TableValidationInitiator$1

TableValidationInitiator$1

nameinstructionbranchcomplexitylinemethod
notifyChange(ModelChangeNotification)
M: 0 C: 46
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
{...}
M: 0 C: 6
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-2014 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: * Eugen Neufeld - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emf.ecp.view.table.internal.validation;
15:
16: import java.util.LinkedHashMap;
17: import java.util.LinkedHashSet;
18: import java.util.Map;
19: import java.util.Set;
20:
21: import org.eclipse.core.databinding.observable.IObserving;
22: import org.eclipse.core.databinding.observable.value.IObservableValue;
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.ecore.EStructuralFeature;
27: import org.eclipse.emf.ecp.common.spi.UniqueSetting;
28: import org.eclipse.emf.ecp.view.spi.context.GlobalViewModelService;
29: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
30: import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
31: import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
32: import org.eclipse.emf.ecp.view.spi.model.VElement;
33: import org.eclipse.emf.ecp.view.spi.model.VView;
34: import org.eclipse.emf.ecp.view.spi.model.VViewModelProperties;
35: import org.eclipse.emf.ecp.view.spi.model.util.ViewModelPropertiesHelper;
36: import org.eclipse.emf.ecp.view.spi.provider.EMFFormsViewService;
37: import org.eclipse.emf.ecp.view.spi.table.model.DetailEditing;
38: import org.eclipse.emf.ecp.view.spi.table.model.VTableControl;
39: import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
40: import org.eclipse.emfforms.spi.common.report.ReportService;
41: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
42: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
43: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
44: import org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener;
45: import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;
46:
47: /**
48: * The TableValidationInitiator searches for Tables with an Editing Panel, and creates the necessary ViewModelContexts.
49: *
50: * @author Eugen Neufeld
51: *
52: */
53: public class TableValidationInitiator implements GlobalViewModelService, EMFFormsContextListener {
54:
55:         /**
56:          * A Mapping Class for tables.
57:          *
58:          * @author Eugen Neufeld
59:          *
60:          */
61:         private static class TableContextMapping {
62:                 /**
63:                  * Default Constructor.
64:                  *
65:                  * @param control The {@link VTableControl}
66:                  * @param context The {@link ViewModelContext}
67:                  */
68:                 TableContextMapping(VTableControl control, ViewModelContext context) {
69:                         this.control = control;
70:                         this.context = context;
71:                 }
72:
73:                 private final VTableControl control;
74:                 private final ViewModelContext context;
75:         }
76:
77:         private final Map<UniqueSetting, Set<TableContextMapping>> mapping = new LinkedHashMap<UniqueSetting, Set<TableContextMapping>>();
78:         private ViewModelContext context;
79:
80:         @Override
81:         public void instantiate(ViewModelContext context) {
82:                 this.context = context;
83:                 context.registerDomainChangeListener(new ModelChangeListener() {
84:
85:                         @Override
86:                         public void notifyChange(ModelChangeNotification notification) {
87:•                                if (notification.getRawNotification().isTouch() || mapping.isEmpty()) {
88:                                         return;
89:                                 }
90:                                 final Set<TableContextMapping> tableContextMappings = mapping.get(UniqueSetting.createSetting(
91:                                         notification.getNotifier(), notification.getStructuralFeature()));
92:•                                if (tableContextMappings == null) {
93:                                         return;
94:                                 }
95:•                                for (final TableContextMapping tableContextMapping : tableContextMappings) {
96:                                         checkAdditions(notification, tableContextMapping);
97:
98:                                         checkRemovals(notification, tableContextMapping);
99:                                 }
100:                         }
101:                 });
102:                 checkForTables(context);
103:                 context.registerEMFFormsContextListener(this);
104:         }
105:
106:         @SuppressWarnings("unchecked")
107:         private void checkForTables(ViewModelContext context) {
108:                 final EObject viewRoot = context.getViewModel();
109:                 final TreeIterator<EObject> eAllContents = viewRoot.eAllContents();
110:                 while (eAllContents.hasNext()) {
111:                         final EObject eObject = eAllContents.next();
112:                         if (VTableControl.class.isInstance(eObject)) {
113:                                 final VTableControl tableControl = VTableControl.class.cast(eObject);
114:                                 if (!isCorrectContainer(tableControl, viewRoot)) {
115:                                         continue;
116:                                 }
117:                                 if (tableControl.getDetailEditing() == DetailEditing.WITH_PANEL) {
118:                                         final VTableDomainModelReference tableDomainModelReference = (VTableDomainModelReference) tableControl
119:                                                 .getDomainModelReference();
120:                                         final IObservableValue observableValue;
121:                                         try {
122:                                                 if (tableDomainModelReference.getDomainModelReference() != null) {
123:                                                         observableValue = context.getService(EMFFormsDatabinding.class)
124:                                                                 .getObservableValue(tableDomainModelReference.getDomainModelReference(),
125:                                                                         context.getDomainModel());
126:                                                 } else {
127:                                                         observableValue = context.getService(EMFFormsDatabinding.class)
128:                                                                 .getObservableValue(tableDomainModelReference, context.getDomainModel());
129:                                                 }
130:                                         } catch (final DatabindingFailedException ex) {
131:                                                 context.getService(ReportService.class).report(new DatabindingFailedReport(ex));
132:                                                 continue;
133:                                         }
134:                                         final IObserving observing = (IObserving) observableValue;
135:                                         final EStructuralFeature structuralFeature = (EStructuralFeature) observableValue.getValueType();
136:                                         final EObject observed = (EObject) observing.getObserved();
137:                                         observableValue.dispose();
138:
139:                                         final UniqueSetting setting = UniqueSetting.createSetting(observed, structuralFeature);
140:                                         if (!mapping.containsKey(setting)) {
141:                                                 mapping.put(setting, new LinkedHashSet<TableValidationInitiator.TableContextMapping>());
142:                                         }
143:                                         mapping.get(setting).add(new TableContextMapping(tableControl, context));
144:                                         final EList<EObject> tableContents = (EList<EObject>) observed.eGet(structuralFeature, true);
145:                                         for (final EObject tableEObject : tableContents) {
146:                                                 try {
147:                                                         final VView detailView = getView(tableControl, tableEObject);
148:                                                         final ViewModelContext childContext = context.getChildContext(tableEObject, tableControl,
149:                                                                 detailView);
150:                                                         childContext.addContextUser(this);
151:                                                 } catch (final DatabindingFailedException ex) {
152:                                                         context.getService(ReportService.class).report(new DatabindingFailedReport(ex));
153:                                                 }
154:                                         }
155:
156:                                 }
157:                         }
158:                 }
159:         }
160:
161:         private boolean isCorrectContainer(VTableControl tableControl, EObject root) {
162:                 EObject current = tableControl.eContainer();
163:                 while (!VView.class.isInstance(current) && current != root) {
164:                         current = current.eContainer();
165:                 }
166:                 return current == root;
167:         }
168:
169:         private VView getView(VTableControl tableControl, EObject newEntry) throws DatabindingFailedException {
170:                 VView detailView = tableControl.getDetailView();
171:                 if (detailView == null) {
172:                         final VElement viewModel = context.getViewModel();
173:                         final VViewModelProperties properties = ViewModelPropertiesHelper.getInhertitedPropertiesOrEmpty(viewModel);
174:                         detailView = context.getService(EMFFormsViewService.class).getView(newEntry, properties);
175:                 }
176:                 if (detailView == null) {
177:                         throw new IllegalStateException(
178:                                 String.format("No View Model could be created for %1$s. Please check your ViewModel Provider.", //$NON-NLS-1$
179:                                         newEntry.eClass().getName()));
180:                 }
181:                 return detailView;
182:         }
183:
184:         @Override
185:         public void dispose() {
186:                 context.unregisterEMFFormsContextListener(this);
187:         }
188:
189:         @Override
190:         public int getPriority() {
191:                 return 1;
192:         }
193:
194:         /**
195:          * {@inheritDoc}
196:          *
197:          * @see org.eclipse.emf.ecp.view.spi.context.GlobalViewModelService#childViewModelContextAdded(org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
198:          */
199:         @Override
200:         public void childViewModelContextAdded(ViewModelContext childContext) {
201:                 checkForTables(childContext);
202:                 childContext.registerEMFFormsContextListener(this);
203:         }
204:
205:         /**
206:          * {@inheritDoc}
207:          *
208:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextAdded(org.eclipse.emf.ecp.view.spi.model.VElement,
209:          * org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
210:          */
211:         @Override
212:         public void childContextAdded(VElement parentElement, EMFFormsViewContext childContext) {
213:                 if (ViewModelContext.class.isInstance(childContext)) {
214:                         checkForTables(ViewModelContext.class.cast(childContext));
215:                         childContext.registerEMFFormsContextListener(this);
216:                 }
217:         }
218:
219:         /**
220:          * {@inheritDoc}
221:          *
222:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextDisposed(org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
223:          */
224:         @Override
225:         public void childContextDisposed(EMFFormsViewContext childContext) {
226:                 // intentionally left empty
227:         }
228:
229:         /**
230:          * {@inheritDoc}
231:          *
232:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextInitialised()
233:          */
234:         @Override
235:         public void contextInitialised() {
236:                 // intentionally left empty
237:         }
238:
239:         /**
240:          * {@inheritDoc}
241:          *
242:          * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextDispose()
243:          */
244:         @Override
245:         public void contextDispose() {
246:                 // intentionally left empty
247:         }
248:
249:         private void checkAdditions(ModelChangeNotification notification, final TableContextMapping tableContextMapping) {
250:                 for (final EObject newValue : notification.getNewEObjects()) {
251:                         try {
252:                                 final ViewModelContext vmc = tableContextMapping.context.getChildContext(newValue,
253:                                         tableContextMapping.control, getView(tableContextMapping.control, newValue));
254:                                 vmc.addContextUser(this);
255:                         } catch (final DatabindingFailedException ex) {
256:                                 context.getService(ReportService.class).report(new DatabindingFailedReport(ex));
257:                         }
258:                 }
259:         }
260:
261:         private void checkRemovals(ModelChangeNotification notification, final TableContextMapping tableContextMapping) {
262:                 for (final EObject oldValue : notification.getOldEObjects()) {
263:                         try {
264:                                 final ViewModelContext vmc = tableContextMapping.context.getChildContext(oldValue,
265:                                         tableContextMapping.control, getView(tableContextMapping.control, oldValue));
266:                                 vmc.removeContextUser(this);
267:                         } catch (final DatabindingFailedException ex) {
268:                                 context.getService(ReportService.class).report(new DatabindingFailedReport(ex));
269:                         }
270:                 }
271:         }
272:
273: }