Skip to content

Package: EMFFormsDatabindingImpl

EMFFormsDatabindingImpl

nameinstructionbranchcomplexitylinemethod
EMFFormsDatabindingImpl()
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
addDomainModelReferenceConverter(DomainModelReferenceConverterEMF)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addDomainModelReferenceSegmentConverter(DomainModelReferenceSegmentConverterEMF)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
extractFeature(IObservableList)
M: 24 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
extractFeature(IObservableValue)
M: 24 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
extractObserved(IObservableList)
M: 25 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
extractObserved(IObservableValue)
M: 25 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
getBestDomainModelReferenceConverter(VDomainModelReference)
M: 5 C: 19
79%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 6
86%
M: 0 C: 1
100%
getBestDomainModelReferenceSegmentConverter(VDomainModelReferenceSegment)
M: 0 C: 24
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
getEditingDomain(EObject)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getListProperty(VDomainModelReference, EObject)
M: 88 C: 49
36%
M: 3 C: 3
50%
M: 2 C: 2
50%
M: 20 C: 13
39%
M: 0 C: 1
100%
getObservableList(VDomainModelReference, EObject)
M: 12 C: 21
64%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 4 C: 6
60%
M: 0 C: 1
100%
getObservableValue(VDomainModelReference, EObject)
M: 12 C: 21
64%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 4 C: 6
60%
M: 0 C: 1
100%
getSetting(VDomainModelReference, EObject)
M: 24 C: 79
77%
M: 1 C: 7
88%
M: 1 C: 4
80%
M: 4 C: 21
84%
M: 0 C: 1
100%
getValueProperty(VDomainModelReference, EClass)
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%
getValueProperty(VDomainModelReference, EClass, EditingDomain)
M: 0 C: 30
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
getValueProperty(VDomainModelReference, EObject)
M: 0 C: 34
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
internalGetValueProperty(VDomainModelReference, EClass, EditingDomain)
M: 0 C: 64
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 17
100%
M: 0 C: 1
100%
lambda$0(VDomainModelReference, DomainModelReferenceConverterEMF)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$1(VDomainModelReferenceSegment, DomainModelReferenceSegmentConverterEMF)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$2(VDomainModelReferenceSegment, VDomainModelReference)
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
removeDomainModelReferenceConverter(DomainModelReferenceConverterEMF)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
removeDomainModelReferenceSegmentConverter(DomainModelReferenceSegmentConverterEMF)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
resolveSegment(VDomainModelReferenceSegment, EObject)
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%
static {...}
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
unpackNextEClass(Optional, VDomainModelReference, VDomainModelReferenceSegment)
M: 0 C: 7
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-2018 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: * Eugen Neufeld - changed interface to EMFFormsDatabindingEMF
14: * Lucas Koehler - Added support for DMR Segments
15: ******************************************************************************/
16: package org.eclipse.emfforms.internal.core.services.databinding;
17:
18: import java.util.LinkedHashSet;
19: import java.util.Optional;
20: import java.util.Set;
21:
22: import org.eclipse.core.databinding.observable.Realm;
23: import org.eclipse.core.databinding.observable.list.IObservableList;
24: import org.eclipse.core.databinding.observable.value.IObservableValue;
25: import org.eclipse.core.databinding.property.list.IListProperty;
26: import org.eclipse.emf.common.util.EList;
27: import org.eclipse.emf.databinding.IEMFListProperty;
28: import org.eclipse.emf.databinding.IEMFObservable;
29: import org.eclipse.emf.databinding.IEMFValueProperty;
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.ecp.common.spi.asserts.Assert;
35: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
36: import org.eclipse.emf.ecp.view.spi.model.VDomainModelReferenceSegment;
37: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
38: import org.eclipse.emf.edit.domain.EditingDomain;
39: import org.eclipse.emfforms.common.RankingHelper;
40: import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
41: import org.eclipse.emfforms.spi.core.services.databinding.DomainModelReferenceConverter;
42: import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
43: import org.eclipse.emfforms.spi.core.services.databinding.emf.DomainModelReferenceConverterEMF;
44: import org.eclipse.emfforms.spi.core.services.databinding.emf.DomainModelReferenceSegmentConverterEMF;
45: import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
46: import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsSegmentResolver;
47: import org.eclipse.emfforms.spi.core.services.databinding.emf.SegmentConverterListResultEMF;
48: import org.eclipse.emfforms.spi.core.services.databinding.emf.SegmentConverterValueResultEMF;
49: import org.osgi.service.component.annotations.Component;
50: import org.osgi.service.component.annotations.Reference;
51: import org.osgi.service.component.annotations.ReferenceCardinality;
52: import org.osgi.service.component.annotations.ReferencePolicy;
53:
54: /**
55: * EMF implementation of {@link EMFFormsDatabindingEMF}.
56: *
57: * @author Lucas Koehler
58: *
59: */
60: @Component(name = "databindingService", service = { EMFFormsDatabinding.class, EMFFormsDatabindingEMF.class,
61:         EMFFormsSegmentResolver.class })
62: public class EMFFormsDatabindingImpl implements EMFFormsDatabindingEMF, EMFFormsSegmentResolver {
63:
64:         private static final RankingHelper<DomainModelReferenceConverterEMF> DMR_RANKING_HELPER = //
65:                 new RankingHelper<DomainModelReferenceConverterEMF>(
66:                         DomainModelReferenceConverter.class,
67:                         DomainModelReferenceConverter.NOT_APPLICABLE,
68:                         DomainModelReferenceConverter.NOT_APPLICABLE);
69:
70:         private static final RankingHelper<DomainModelReferenceSegmentConverterEMF> SEGMENTS_RANKING_HELPER = //
71:                 new RankingHelper<>(
72:                         DomainModelReferenceSegmentConverterEMF.class,
73:                         DomainModelReferenceSegmentConverterEMF.NOT_APPLICABLE,
74:                         DomainModelReferenceSegmentConverterEMF.NOT_APPLICABLE);
75:
76:         private final Set<DomainModelReferenceConverterEMF> referenceConverters = new LinkedHashSet<>();
77:         private final Set<DomainModelReferenceSegmentConverterEMF> segmentConverters = new LinkedHashSet<>();
78:
79:         /**
80:          * Adds the given {@link DomainModelReferenceSegmentConverterEMF} to the Set of segment converters.
81:          *
82:          * @param converter The {@link DomainModelReferenceSegmentConverterEMF} to add
83:          */
84:         @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
85:         protected void addDomainModelReferenceSegmentConverter(DomainModelReferenceSegmentConverterEMF converter) {
86:                 segmentConverters.add(converter);
87:         }
88:
89:         /**
90:          * Removes the given {@link DomainModelReferenceSegmentConverterEMF} from the Set of segment converters.
91:          *
92:          * @param converter The {@link DomainModelReferenceSegmentConverterEMF} to remove
93:          */
94:         protected void removeDomainModelReferenceSegmentConverter(DomainModelReferenceSegmentConverterEMF converter) {
95:                 segmentConverters.remove(converter);
96:         }
97:
98:         @Override
99:         public IObservableValue getObservableValue(VDomainModelReference domainModelReference, EObject object)
100:                 throws DatabindingFailedException {
101:                 Assert.create(domainModelReference).notNull();
102:                 Assert.create(object).notNull();
103:
104:                 final IEMFValueProperty valueProperty = getValueProperty(domainModelReference, object);
105:                 final Realm realm = Realm.getDefault();
106:•                if (realm != null) {
107:                         return valueProperty.observe(object);
108:                 }
109:                 final DefaultRealm dr = new DefaultRealm();
110:                 final IObservableValue observableValue = valueProperty.observe(object);
111:                 dr.dispose();
112:                 return observableValue;
113:         }
114:
115:         @Override
116:         public IEMFValueProperty getValueProperty(VDomainModelReference domainModelReference, EObject object)
117:                 throws DatabindingFailedException {
118:                 Assert.create(domainModelReference).notNull();
119:
120:                 final EList<VDomainModelReferenceSegment> segments = domainModelReference.getSegments();
121:•                if (segments.isEmpty()) {
122:                         // No segments => Fall back to legacy dmr resolving
123:                         final DomainModelReferenceConverterEMF bestConverter = getBestDomainModelReferenceConverter(
124:                                 domainModelReference);
125:                         return bestConverter.convertToValueProperty(domainModelReference, object);
126:                 }
127:
128:                 Assert.create(object).notNull();
129:                 final EditingDomain editingDomain = getEditingDomain(object);
130:                 return internalGetValueProperty(domainModelReference, object.eClass(), editingDomain);
131:         }
132:
133:         @Override
134:         public IEMFValueProperty getValueProperty(VDomainModelReference domainModelReference, EClass rootEClass)
135:                 throws DatabindingFailedException {
136:                 return getValueProperty(domainModelReference, rootEClass, null);
137:         }
138:
139:         @Override
140:         public IEMFValueProperty getValueProperty(VDomainModelReference domainModelReference, EClass rootEClass,
141:                 EditingDomain editingDomain) throws DatabindingFailedException {
142:                 Assert.create(domainModelReference).notNull();
143:
144:                 final EList<VDomainModelReferenceSegment> segments = domainModelReference.getSegments();
145:•                if (segments.isEmpty()) {
146:                         // No segments => Fall back to legacy dmr resolving
147:                         final DomainModelReferenceConverterEMF bestConverter = getBestDomainModelReferenceConverter(
148:                                 domainModelReference);
149:                         return bestConverter.convertToValueProperty(domainModelReference, rootEClass, editingDomain);
150:                 }
151:
152:                 Assert.create(rootEClass).notNull();
153:                 return internalGetValueProperty(domainModelReference, rootEClass, editingDomain);
154:         }
155:
156:         /**
157:          * Actual calculation of a value property using {@link VDomainModelReferenceSegment segments}.
158:          *
159:          * @param domainModelReference The domain model reference pointing to the desired value
160:          * @param rootEClass The root EClass of the rendered form
161:          * @param editingDomain The {@link EditingDomain} of the resulting value property, may be null
162:          * @return The resulting {@link IEMFValueProperty}
163:          * @throws DatabindingFailedException
164:          */
165:         private IEMFValueProperty internalGetValueProperty(VDomainModelReference domainModelReference, EClass rootEClass,
166:                 EditingDomain editingDomain) throws DatabindingFailedException {
167:
168:                 final EList<VDomainModelReferenceSegment> segments = domainModelReference.getSegments();
169:
170:                 // Get value property for the (always present) first segment
171:                 final DomainModelReferenceSegmentConverterEMF firstConverter = getBestDomainModelReferenceSegmentConverter(
172:                         segments.get(0));
173:                 SegmentConverterValueResultEMF converterResult = firstConverter.convertToValueProperty(segments.get(0),
174:                         rootEClass, editingDomain);
175:                 IEMFValueProperty resultProperty = converterResult.getValueProperty();
176:
177:                 // Iterate over all remaining segments and get the value properties for their corresponding EClasses.
178:•                for (int i = 1; i < segments.size(); i++) {
179:                         final EClass nextEClass = unpackNextEClass(converterResult.getNextEClass(), domainModelReference,
180:                                 segments.get(i));
181:                         final VDomainModelReferenceSegment segment = segments.get(i);
182:
183:                         final DomainModelReferenceSegmentConverterEMF bestConverter = getBestDomainModelReferenceSegmentConverter(
184:                                 segment);
185:                         converterResult = bestConverter.convertToValueProperty(segment,
186:                                 nextEClass, editingDomain);
187:                         final IEMFValueProperty nextProperty = converterResult.getValueProperty();
188:                         // Chain the properties together
189:                         resultProperty = resultProperty.value(nextProperty);
190:                 }
191:
192:                 return resultProperty;
193:         }
194:
195:         /**
196:          * Adds the given {@link DomainModelReferenceConverterEMF} to the Set of reference converters.
197:          *
198:          * @param converter The {@link DomainModelReferenceConverterEMF} to add
199:          */
200:         @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
201:         protected void addDomainModelReferenceConverter(DomainModelReferenceConverterEMF converter) {
202:                 referenceConverters.add(converter);
203:         }
204:
205:         /**
206:          * Removes the given {@link DomainModelReferenceConverterEMF} to the Set of reference converters.
207:          *
208:          * @param converter The {@link DomainModelReferenceConverterEMF} to remove
209:          */
210:         protected void removeDomainModelReferenceConverter(DomainModelReferenceConverterEMF converter) {
211:                 referenceConverters.remove(converter);
212:         }
213:
214:         @Override
215:         public IObservableList getObservableList(VDomainModelReference domainModelReference, EObject object)
216:                 throws DatabindingFailedException {
217:                 Assert.create(domainModelReference).notNull();
218:                 Assert.create(object).notNull();
219:
220:                 final IListProperty listProperty = getListProperty(domainModelReference, object);
221:                 final Realm realm = Realm.getDefault();
222:•                if (realm != null) {
223:                         return listProperty.observe(object);
224:                 }
225:                 final DefaultRealm dr = new DefaultRealm();
226:                 final IObservableList observableList = listProperty.observe(object);
227:                 dr.dispose();
228:                 return observableList;
229:         }
230:
231:         @Override
232:         public IEMFListProperty getListProperty(VDomainModelReference domainModelReference, EObject object)
233:                 throws DatabindingFailedException {
234:                 Assert.create(domainModelReference).notNull();
235:
236:                 final EList<VDomainModelReferenceSegment> segments = domainModelReference.getSegments();
237:•                if (segments.isEmpty()) {
238:                         // No segments => Fall back to legacy dmr resolving
239:                         final DomainModelReferenceConverterEMF bestConverter = getBestDomainModelReferenceConverter(
240:                                 domainModelReference);
241:                         return bestConverter.convertToListProperty(domainModelReference, object);
242:                 }
243:
244:                 Assert.create(object).notNull();
245:                 final EditingDomain editingDomain = getEditingDomain(object);
246:
247:                 // If there is only one segment, get its list property. Otherwise, get its value property
248:                 final DomainModelReferenceSegmentConverterEMF firstConverter = getBestDomainModelReferenceSegmentConverter(
249:                         segments.get(0));
250:•                if (segments.size() == 1) {
251:                         // If there is only one segment, directly return its list property
252:                         return firstConverter.convertToListProperty(segments.get(0), object.eClass(), editingDomain)
253:                                 .getListProperty();
254:                 }
255:
256:                 final SegmentConverterValueResultEMF converterResult = firstConverter.convertToValueProperty(segments.get(0),
257:                         object.eClass(), editingDomain);
258:                 IEMFValueProperty valueProperty = converterResult.getValueProperty();
259:
260:                 /*
261:                  * Iterate over all "middle" segments and get the value properties for their corresponding EClasses.
262:                  * Get the EClass by getting the target EClass of the EReference from the value property of the previously
263:                  * resolved segment.
264:                  */
265:                 EClass nextEClass = unpackNextEClass(converterResult.getNextEClass(), domainModelReference, segments.get(0));
266:•                for (int i = 1; i < segments.size() - 1; i++) {
267:                         final VDomainModelReferenceSegment segment = segments.get(i);
268:
269:                         final DomainModelReferenceSegmentConverterEMF bestConverter = getBestDomainModelReferenceSegmentConverter(
270:                                 segment);
271:                         final SegmentConverterValueResultEMF nextConverterResult = bestConverter.convertToValueProperty(segment,
272:                                 nextEClass, editingDomain);
273:                         final IEMFValueProperty nextProperty = nextConverterResult.getValueProperty();
274:
275:                         nextEClass = unpackNextEClass(nextConverterResult.getNextEClass(), domainModelReference, segment);
276:                         // Chain the properties together
277:                         valueProperty = valueProperty.value(nextProperty);
278:                 }
279:
280:                 // Get the list property for the last segment
281:                 final int lastIndex = segments.size() - 1;
282:                 final DomainModelReferenceSegmentConverterEMF lastConverter = getBestDomainModelReferenceSegmentConverter(
283:                         segments.get(lastIndex));
284:                 final SegmentConverterListResultEMF converterListResult = lastConverter.convertToListProperty(
285:                         segments.get(lastIndex), nextEClass,
286:                         editingDomain);
287:
288:                 return valueProperty.list(converterListResult.getListProperty());
289:         }
290:
291:         /**
292:          * Returns the most suitable {@link DomainModelReferenceConverter}, that is registered to this
293:          * {@link EMFFormsDatabindingImpl}, for the given {@link VDomainModelReference}.
294:          *
295:          * @param domainModelReference The {@link VDomainModelReference} for which a {@link DomainModelReferenceConverter}
296:          * is needed
297:          * @return The most suitable {@link DomainModelReferenceConverter}
298:          * @throws DatabindingFailedException If no applicable DMR Converter was found
299:          */
300:         private DomainModelReferenceConverterEMF getBestDomainModelReferenceConverter(
301:                 final VDomainModelReference domainModelReference) throws DatabindingFailedException {
302:•                if (domainModelReference == null) {
303:                         throw new IllegalArgumentException("The given VDomainModelReference must not be null."); //$NON-NLS-1$
304:                 }
305:
306:                 final DomainModelReferenceConverterEMF bestConverter = DMR_RANKING_HELPER.getHighestRankingElement(
307:                         referenceConverters, converter -> converter.isApplicable(domainModelReference));
308:•                if (bestConverter == null) {
309:                         throw new DatabindingFailedException("No applicable DomainModelReferenceConverter could be found."); //$NON-NLS-1$
310:                 }
311:                 return bestConverter;
312:         }
313:
314:         @Override
315:         public EStructuralFeature extractFeature(IObservableValue observableValue) throws DatabindingFailedException {
316:•                if (IEMFObservable.class.isInstance(observableValue)) {
317:                         return IEMFObservable.class.cast(observableValue).getStructuralFeature();
318:                 }
319:                 throw new DatabindingFailedException(
320:                         String.format("The IObservableValue class %1$s is not supported!", observableValue.getClass().getName())); //$NON-NLS-1$
321:         }
322:
323:         @Override
324:         public EStructuralFeature extractFeature(IObservableList observableList) throws DatabindingFailedException {
325:•                if (IEMFObservable.class.isInstance(observableList)) {
326:                         return IEMFObservable.class.cast(observableList).getStructuralFeature();
327:                 }
328:                 throw new DatabindingFailedException(
329:                         String.format("The IObservableList class %1$s is not supported!", observableList.getClass().getName())); //$NON-NLS-1$
330:         }
331:
332:         @Override
333:         public EObject extractObserved(IObservableValue observableValue) throws DatabindingFailedException {
334:•                if (IEMFObservable.class.isInstance(observableValue)) {
335:                         return (EObject) IEMFObservable.class.cast(observableValue).getObserved();
336:                 }
337:                 throw new DatabindingFailedException(
338:                         String.format("The IObservableValue class %1$s is not supported!", observableValue.getClass().getName())); //$NON-NLS-1$
339:         }
340:
341:         @Override
342:         public EObject extractObserved(IObservableList observableList) throws DatabindingFailedException {
343:•                if (IEMFObservable.class.isInstance(observableList)) {
344:                         return (EObject) IEMFObservable.class.cast(observableList).getObserved();
345:                 }
346:                 throw new DatabindingFailedException(
347:                         String.format("The IObservableList class %1$s is not supported!", observableList.getClass().getName())); //$NON-NLS-1$
348:         }
349:
350:         @Override
351:         public Setting getSetting(VDomainModelReference domainModelReference, EObject object)
352:                 throws DatabindingFailedException {
353:                 Assert.create(domainModelReference).notNull();
354:                 Assert.create(object).notNull();
355:
356:                 final EList<VDomainModelReferenceSegment> segments = domainModelReference.getSegments();
357:•                if (segments.isEmpty()) {
358:                         // No segments => Fall back to legacy dmr resolving
359:                         final DomainModelReferenceConverterEMF bestConverter = getBestDomainModelReferenceConverter(
360:                                 domainModelReference);
361:                         final Realm realm = Realm.getDefault();
362:•                        if (realm != null) {
363:                                 return bestConverter.getSetting(domainModelReference, object);
364:                         }
365:                         final DefaultRealm dr = new DefaultRealm();
366:                         final Setting setting = bestConverter.getSetting(domainModelReference, object);
367:                         dr.dispose();
368:                         return setting;
369:                 }
370:
371:                 Setting setting = resolveSegment(segments.get(0), object);
372:
373:                 /*
374:                  * If present, iterate over the remaining segments. For every iteration step, use the resolved EObject of the
375:                  * previously resolved Setting in order to resolve the next Setting.
376:                  */
377:•                for (int i = 1; i < segments.size(); i++) {
378:                         final VDomainModelReferenceSegment segment = segments.get(i);
379:                         final Object nextObject = setting.get(true);
380:
381:•                        if (!EObject.class.isInstance(nextObject)) {
382:                                 throw new DatabindingFailedException(
383:                                         String.format(
384:                                                 "The Setting could not be fully resolved because an intermediate Object was no EObject or was null. " //$NON-NLS-1$
385:                                                         + "The DMR was %1$s. The last resolved segment was %2$s. The root EObject was %3$s.", //$NON-NLS-1$
386:                                                 domainModelReference, segments.get(i - 1), object));
387:                         }
388:
389:                         final EObject nextEObject = (EObject) nextObject;
390:                         setting = resolveSegment(segment, nextEObject);
391:                 }
392:
393:                 return setting;
394:         }
395:
396:         /**
397:          * Returns the most suitable {@link DomainModelReferenceSegmentConverterEMF}, that is registered to this
398:          * {@link EMFFormsDatabindingImpl}, for the given {@link VDomainModelReferenceSegment}.
399:          *
400:          * @param segment The {@link VDomainModelReferenceSegment} for which a
401:          * {@link DomainModelReferenceSegmentConverterEMF}
402:          * is needed
403:          * @return The most suitable {@link DomainModelReferenceSegmentConverterEMF}, does not return <code>null</code>
404:          * @throws DatabindingFailedException if no suitable segment converter could be found
405:          */
406:         private DomainModelReferenceSegmentConverterEMF getBestDomainModelReferenceSegmentConverter(
407:                 final VDomainModelReferenceSegment segment) throws DatabindingFailedException {
408:
409:                 final DomainModelReferenceSegmentConverterEMF bestConverter = SEGMENTS_RANKING_HELPER.getHighestRankingElement(
410:                         segmentConverters, converter -> converter.isApplicable(segment));
411:
412:•                if (bestConverter == null) {
413:                         throw new DatabindingFailedException(String
414:                                 .format("No suitable DomainModelReferenceSegmentConverter could be found for segment %1$s", segment)); //$NON-NLS-1$
415:                 }
416:                 return bestConverter;
417:
418:         }
419:
420:         /**
421:          * Unpacks the given {@link EClass} Optional and throws an exception if it is not present.
422:          *
423:          * @param nextEClass the {@link EClass} to check
424:          * @param domainModelReference only needed for exception description
425:          * @param segment only needed for exception description
426:          * @return the unpacked {@link EClass}
427:          * @throws DatabindingFailedException if the next EClass is <code>null</code>
428:          */
429:         private EClass unpackNextEClass(final Optional<EClass> nextEClass, VDomainModelReference domainModelReference,
430:                 final VDomainModelReferenceSegment segment) throws DatabindingFailedException {
431:                 return nextEClass.orElseThrow(() -> new DatabindingFailedException(String.format(
432:                         "The Segment [%1$s] could not be resolved because this segment's root EClass" //$NON-NLS-1$
433:                                 + " could not be resolved from the preceding segment. The DMR is %2$s.", //$NON-NLS-1$
434:                         segment, domainModelReference)));
435:         }
436:
437:         private EditingDomain getEditingDomain(EObject object) throws DatabindingFailedException {
438:                 return AdapterFactoryEditingDomain.getEditingDomainFor(object);
439:         }
440:
441:         @Override
442:         public Setting resolveSegment(VDomainModelReferenceSegment segment, EObject domainObject)
443:                 throws DatabindingFailedException {
444:                 final DomainModelReferenceSegmentConverterEMF bestConverter = getBestDomainModelReferenceSegmentConverter(
445:                         segment);
446:                 return bestConverter.getSetting(segment, domainObject);
447:         }
448: }