Skip to content

Package: DefaultReferenceService_PTest$2

DefaultReferenceService_PTest$2

nameinstructionbranchcomplexitylinemethod
run()
M: 0 C: 41
100%
M: 3 C: 5
63%
M: 3 C: 2
40%
M: 0 C: 11
100%
M: 0 C: 1
100%
{...}
M: 0 C: 15
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) 2018 Christian W. Damus 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: * Christian W. Damus - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emf.ecp.ui.view.swt;
15:
16: import static org.hamcrest.CoreMatchers.anything;
17: import static org.hamcrest.CoreMatchers.hasItem;
18: import static org.hamcrest.CoreMatchers.instanceOf;
19: import static org.hamcrest.CoreMatchers.is;
20: import static org.hamcrest.MatcherAssert.assertThat;
21: import static org.junit.Assert.fail;
22: import static org.mockito.Matchers.any;
23: import static org.mockito.Matchers.anyCollectionOf;
24: import static org.mockito.Matchers.eq;
25: import static org.mockito.Mockito.mock;
26: import static org.mockito.Mockito.verify;
27: import static org.mockito.Mockito.verifyNoMoreInteractions;
28: import static org.mockito.Mockito.when;
29:
30: import java.lang.reflect.InvocationTargetException;
31: import java.lang.reflect.Method;
32: import java.util.Arrays;
33: import java.util.Collection;
34: import java.util.HashSet;
35: import java.util.Hashtable;
36: import java.util.Iterator;
37: import java.util.List;
38: import java.util.Set;
39: import java.util.concurrent.Executors;
40: import java.util.concurrent.ScheduledExecutorService;
41: import java.util.concurrent.TimeUnit;
42: import java.util.concurrent.atomic.AtomicBoolean;
43:
44: import org.eclipse.emf.common.command.BasicCommandStack;
45: import org.eclipse.emf.common.util.URI;
46: import org.eclipse.emf.ecore.EAttribute;
47: import org.eclipse.emf.ecore.EClass;
48: import org.eclipse.emf.ecore.EClassifier;
49: import org.eclipse.emf.ecore.EDataType;
50: import org.eclipse.emf.ecore.EObject;
51: import org.eclipse.emf.ecore.EOperation;
52: import org.eclipse.emf.ecore.EPackage;
53: import org.eclipse.emf.ecore.EReference;
54: import org.eclipse.emf.ecore.EStructuralFeature;
55: import org.eclipse.emf.ecore.ETypedElement;
56: import org.eclipse.emf.ecore.EcoreFactory;
57: import org.eclipse.emf.ecore.EcorePackage;
58: import org.eclipse.emf.ecore.InternalEObject;
59: import org.eclipse.emf.ecore.resource.Resource;
60: import org.eclipse.emf.ecore.resource.ResourceSet;
61: import org.eclipse.emf.ecore.util.EcoreUtil;
62: import org.eclipse.emf.ecp.edit.spi.ReferenceService;
63: import org.eclipse.emf.ecp.ui.view.swt.reference.AttachmentStrategy;
64: import org.eclipse.emf.ecp.ui.view.swt.reference.EObjectSelectionStrategy;
65: import org.eclipse.emf.ecp.ui.view.swt.reference.OpenInNewContextStrategy;
66: import org.eclipse.emf.ecp.ui.view.swt.reference.ReferenceServiceCustomizationVendor;
67: import org.eclipse.emf.ecp.ui.view.swt.reference.ReferenceStrategy;
68: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
69: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
70: import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
71: import org.eclipse.emfforms.bazaar.Create;
72: import org.eclipse.emfforms.bazaar.Vendor;
73: import org.eclipse.jface.dialogs.Dialog;
74: import org.eclipse.jface.dialogs.IDialogConstants;
75: import org.eclipse.swt.SWT;
76: import org.eclipse.swt.widgets.Composite;
77: import org.eclipse.swt.widgets.Control;
78: import org.eclipse.swt.widgets.Display;
79: import org.eclipse.swt.widgets.Event;
80: import org.eclipse.swt.widgets.Item;
81: import org.eclipse.swt.widgets.Shell;
82: import org.eclipse.swt.widgets.Table;
83: import org.eclipse.swt.widgets.Tree;
84: import org.eclipse.swt.widgets.Widget;
85: import org.hamcrest.CoreMatchers;
86: import org.junit.After;
87: import org.junit.Before;
88: import org.junit.Test;
89: import org.junit.runner.RunWith;
90: import org.mockito.Mock;
91: import org.mockito.invocation.InvocationOnMock;
92: import org.mockito.runners.MockitoJUnitRunner;
93: import org.mockito.stubbing.Answer;
94: import org.osgi.framework.BundleContext;
95: import org.osgi.framework.Constants;
96: import org.osgi.framework.FrameworkUtil;
97: import org.osgi.framework.ServiceRegistration;
98: import org.osgi.service.component.ComponentContext;
99:
100: /**
101: * Test cases for the {@link DefaultReferenceService} class.
102: */
103: @RunWith(MockitoJUnitRunner.class)
104: public class DefaultReferenceService_PTest {
105:
106:         private final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
107:
108:         @Mock
109:         private ViewModelContext context;
110:
111:         @Mock
112:         private OpenInNewContextStrategy openStrategy;
113:
114:         private List<ServiceRegistration<?>> registrations;
115:
116:         private DefaultReferenceServiceFactory factory;
117:         private DefaultReferenceService fixture;
118:
119:         private EPackage testPackage;
120:         private EPackage typesPackage;
121:
122:         /**
123:          * Initializes me.
124:          */
125:         public DefaultReferenceService_PTest() {
126:                 super();
127:         }
128:
129:         @Test
130:         public void addExistingModelElements() {
131:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
132:                 final EClass abstrakt = (EClass) testPackage.getEClassifier("Abstract");
133:
134:                 // When the dialog appears, select the first element and okay
135:                 final AtomicBoolean doIt = new AtomicBoolean(true);
136:                 final Runnable selectRunnable = selectFirstElementInDialog(Display.getCurrent(), getShells(), doIt);
137:                 exec.scheduleAtFixedRate(selectRunnable, 100L, 100L, TimeUnit.MILLISECONDS);
138:
139:                 fixture.addExistingModelElements(foo, EcorePackage.Literals.ECLASS__ESUPER_TYPES);
140:
141:                 // If the dialog didn't appear, don't try anything after the test suite has moved on
142:                 doIt.set(false);
143:
144:                 // The reference was set to the only eligible choice
145:                 assertThat(foo.getESuperTypes(), hasItem(abstrakt));
146:
147:                 // The open strategy is not involved
148:                 verifyNoMoreInteractions(openStrategy);
149:         }
150:
151:         @Test
152:         public void addExistingModelElements2() {
153:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
154:                 final EStructuralFeature state = foo.getEStructuralFeature("state");
155:                 final EClassifier intType = typesPackage.getEClassifier("int");
156:
157:                 // A canary
158:                 final EObjectSelectionStrategy canary = mock(EObjectSelectionStrategy.class);
159:                 when(canary.collectExistingObjects(any(EObject.class), any(EReference.class), anyCollectionOf(EObject.class)))
160:                         .then(new Answer<Collection<EObject>>() {
161:                                 @SuppressWarnings("unchecked")
162:                                 @Override
163:                                 public Collection<EObject> answer(InvocationOnMock invocation) throws Throwable {
164:                                         return (Collection<EObject>) invocation.getArguments()[2];
165:                                 }
166:                         });
167:                 register(vendor(canary));
168:
169:                 // When the dialog appears, select the first element and okay
170:                 final AtomicBoolean doIt = new AtomicBoolean(true);
171:                 final Runnable selectRunnable = selectFirstElementInDialog(Display.getCurrent(), getShells(), doIt);
172:                 exec.scheduleAtFixedRate(selectRunnable, 100L, 100L, TimeUnit.MILLISECONDS);
173:
174:                 fixture.addExistingModelElements(state, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE);
175:
176:                 // If the dialog didn't appear, don't try anything after the test suite has moved on
177:                 doIt.set(false);
178:
179:                 // Check the canary
180:                 verify(canary).collectExistingObjects(eq(state), eq(EcorePackage.Literals.ETYPED_ELEMENT__ETYPE),
181:                         anyCollectionOf(EObject.class));
182:
183:                 assertThat(state.getEType(), is(intType));
184:                 assertThat(state.getLowerBound(), is(1)); // Our strategy's side-effect
185:
186:                 // The open strategy is not involved
187:                 verifyNoMoreInteractions(openStrategy);
188:         }
189:
190:         @Test
191:         public void addNewModelElements() {
192:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
193:
194:                 fixture.addNewModelElements(foo, EcorePackage.Literals.ECLASS__EOPERATIONS, true);
195:                 // test that an operation was added to foo
196:                 assertThat(foo.getEOperations().size(), is(1));
197:
198:                 verify(openStrategy).openInNewContext(foo, EcorePackage.Literals.ECLASS__EOPERATIONS,
199:                         foo.getEOperations().get(0));
200:         }
201:
202:         @Test
203:         public void attachDefaultCase_inOwner() {
204:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
205:                 fixture.addNewModelElements(foo, EcorePackage.Literals.ECLASS__EOPERATIONS, true);
206:                 assertThat(foo.getEOperations(), CoreMatchers.<EOperation> hasItem(anything()));
207:                 final EOperation op = foo.getEOperations().get(0);
208:
209:                 assertThat(op.getEContainingClass(), is(foo));
210:
211:                 // The reference service "opened" this new object
212:                 verify(openStrategy).openInNewContext(foo, EcorePackage.Literals.ECLASS__EOPERATIONS, op);
213:         }
214:
215:         @Test
216:         public void attachDefaultCase_inAncestorOfOwner() {
217:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
218:                 fixture.addNewModelElements(foo, EcorePackage.Literals.ECLASS__ESUPER_TYPES, true);
219:                 assertThat(foo.getESuperTypes(), CoreMatchers.<EClass> hasItem(anything()));
220:                 final EClass supertype = foo.getESuperTypes().get(0);
221:
222:                 assertThat(supertype.getEPackage(), is(testPackage));
223:
224:                 // The reference service "opened" this new object
225:                 verify(openStrategy).openInNewContext(testPackage, EcorePackage.Literals.EPACKAGE__ECLASSIFIERS, supertype);
226:         }
227:
228:         @Test
229:         public void attachDefaultCase_inResource() {
230:                 // Same as above, except there's no package: the class is directly in the resource
231:                 final Resource resource = testPackage.eResource();
232:                 resource.getContents().remove(testPackage);
233:                 final EClass foo = (EClass) testPackage.getEClassifier("Foo");
234:                 testPackage.getEClassifiers().remove(foo);
235:                 resource.getContents().add(foo);
236:
237:                 fixture.addNewModelElements(foo, EcorePackage.Literals.ECLASS__ESUPER_TYPES, true);
238:                 assertThat(foo.getESuperTypes(), CoreMatchers.<EClass> hasItem(anything()));
239:                 final EClass supertype = foo.getESuperTypes().get(0);
240:
241:                 assertThat(((InternalEObject) supertype).eDirectResource(), is(resource));
242:
243:                 // The reference service "opened" this new object
244:                 verify(openStrategy).openInNewContext(null, null, supertype);
245:         }
246:
247:         @Test
248:         public void openInNewContext() {
249:                 fixture.openInNewContext(testPackage);
250:
251:                 // The reference service "opened" this "new" object, but it's in a resource
252:                 verify(openStrategy).openInNewContext(null, null, testPackage);
253:         }
254:
255:         //
256:         // Test framework
257:         //
258:
259:         @Before
260:         public void createFixture() {
261:                 // Ensure that we don't fall back to the default, which opens a dialog
262:                 when(openStrategy.openInNewContext(any(EObject.class), any(EReference.class), any(EObject.class)))
263:                         .thenReturn(true);
264:
265:                 final AdapterFactoryEditingDomain domain = new AdapterFactoryEditingDomain(
266:                         new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),
267:                         new BasicCommandStack());
268:
269:                 testPackage = createTestPackage();
270:                 createResource(domain.getResourceSet(), testPackage);
271:
272:                 typesPackage = createTypesPackage();
273:                 createResource(domain.getResourceSet(), typesPackage);
274:
275:                 when(context.getDomainModel()).thenReturn(testPackage);
276:
277:                 final ComponentContext componentContext = mock(ComponentContext.class);
278:                 when(componentContext.getBundleContext()).thenReturn(FrameworkUtil.getBundle(getClass()).getBundleContext());
279:                 when(componentContext.getProperties()).thenReturn(new Hashtable<String, Object>());
280:
281:                 factory = new DefaultReferenceServiceFactory();
282:                 factory.activate(componentContext);
283:                 registerReferenceCustomizations();
284:
285:                 final ReferenceService service = factory.createService(context);
286:                 assertThat("Factory created wrong service implementation", service,
287:                         instanceOf(DefaultReferenceService.class));
288:
289:                 fixture = (DefaultReferenceService) service;
290:         }
291:
292:         @After
293:         public void destroyFixture() {
294:                 exec.shutdown();
295:
296:                 fixture.dispose();
297:                 factory.deactivate();
298:                 unregisterReferenceCustomizations();
299:         }
300:
301:         EPackage createTestPackage() {
302:                 final EPackage result = createPackage("test");
303:                 final EClass foo = EcoreFactory.eINSTANCE.createEClass();
304:                 foo.setName("Foo");
305:                 result.getEClassifiers().add(foo);
306:                 final EAttribute state = EcoreFactory.eINSTANCE.createEAttribute();
307:                 state.setName("state");
308:                 foo.getEStructuralFeatures().add(state);
309:                 final EClass abstrakt = EcoreFactory.eINSTANCE.createEClass();
310:                 abstrakt.setAbstract(true);
311:                 abstrakt.setName("Abstract");
312:                 result.getEClassifiers().add(abstrakt);
313:                 return result;
314:         }
315:
316:         void createResource(ResourceSet rset, EPackage ePackage) {
317:                 final Resource resource = rset.createResource(URI.createURI(ePackage.getNsURI()).appendFileExtension("ecore"));
318:                 resource.getContents().add(ePackage);
319:         }
320:
321:         EPackage createTypesPackage() {
322:                 final EPackage result = createPackage("types");
323:                 final EDataType intType = EcoreFactory.eINSTANCE.createEDataType();
324:                 intType.setName("int");
325:                 result.getEClassifiers().add(intType);
326:                 return result;
327:         }
328:
329:         EPackage createPackage(String name) {
330:                 final EPackage result = EcoreFactory.eINSTANCE.createEPackage();
331:                 result.setName(name);
332:                 result.setNsURI(String.format("http://test/%s.ecore", name));
333:                 result.setNsPrefix(name);
334:                 return result;
335:         }
336:
337:         /**
338:          * Get all of the shells currently open at this instant.
339:          *
340:          * @return the currently open shells
341:          */
342:         Set<Shell> getShells() {
343:                 return new HashSet<Shell>(Arrays.asList(Display.getCurrent().getShells()));
344:         }
345:
346:         /**
347:          * Obtain a runnable that async-execs on the given {@code display} to find the first
348:          * currently open shell that is not amongst the given {@code initialShells}, to
349:          * make a selection in it and close it, so long as {@link doIt} remains {@code true}.
350:          *
351:          * @param display the display to which the resulting runnable should async-exec its action
352:          * @param initialShells the shells that are/were open before starting the thread that
353:          * runs the resulting runnable
354:          * @param doIt a flag that will turn off when the test no longer needs to look for the dialog
355:          *
356:          * @return the dialog selection runnable
357:          */
358:         Runnable selectFirstElementInDialog(final Display display, final Set<Shell> initialShells,
359:                 final AtomicBoolean doIt) {
360:                 final Runnable onUI = new Runnable() {
361:
362:                         @Override
363:                         public void run() {
364:•                                if (doIt.get()) {
365:                                         Shell dialog = null;
366:                                         final Shell[] all = display.getShells();
367:•                                        for (final Shell next : all) {
368:•                                                if (!initialShells.contains(next)) {
369:                                                         // This is the newly opened dialog
370:                                                         dialog = next;
371:                                                         break;
372:                                                 }
373:                                         }
374:
375:•                                        if (dialog != null) {
376:                                                 selectFirstElement(dialog);
377:                                                 finishWizard(dialog);
378:                                         }
379:                                 }
380:                         }
381:                 };
382:
383:                 return new Runnable() {
384:
385:                         @Override
386:                         public void run() {
387:                                 display.asyncExec(onUI);
388:                         }
389:                 };
390:         }
391:
392:         static void selectFirstElement(Shell shell) {
393:                 Widget notify = null;
394:                 Item selected = null;
395:
396:                 final Table table = findControl(shell, Table.class);
397:                 if (table != null) {
398:                         table.setSelection(0);
399:                         notify = table;
400:                         selected = table.getItem(0);
401:                 } else {
402:                         final Tree tree = findControl(shell, Tree.class);
403:                         if (tree != null) {
404:                                 tree.setSelection(tree.getItem(0));
405:                                 notify = tree;
406:                                 selected = tree.getItem(0);
407:                         } else {
408:                                 throw new IllegalStateException("no table nor tree to select");
409:                         }
410:                 }
411:
412:                 // Have to fire notification for JFace viewer to pick up
413:                 final Event event = new Event();
414:                 event.type = SWT.Selection;
415:                 event.widget = notify;
416:                 event.item = selected;
417:                 notify.notifyListeners(SWT.Selection, event);
418:         }
419:
420:         static <C extends Control> C findControl(Composite composite, Class<C> type) {
421:                 C result = null;
422:
423:                 if (type.isInstance(composite)) {
424:                         result = type.cast(composite);
425:                 } else {
426:                         for (final Control child : composite.getChildren()) {
427:                                 if (child instanceof Composite) {
428:                                         result = findControl((Composite) child, type);
429:                                 } else if (type.isInstance(child)) {
430:                                         result = type.cast(child);
431:                                 }
432:
433:                                 if (result != null) {
434:                                         break;
435:                                 }
436:                         }
437:                 }
438:
439:                 return result;
440:         }
441:
442:         static void finishWizard(Shell shell) {
443:                 final Dialog dialog = (Dialog) shell.getData();
444:
445:                 try {
446:                         final Method buttonPressed = Dialog.class.getDeclaredMethod("buttonPressed", int.class);
447:                         buttonPressed.setAccessible(true);
448:                         buttonPressed.invoke(dialog, IDialogConstants.FINISH_ID);
449:                         // BEGIN COMPLEX CODE
450:                 } catch (final Exception e) {
451:                         // END COMPLEX CODE
452:                         throw new RuntimeException(e);
453:                 }
454:         }
455:
456:         private void registerReferenceCustomizations() {
457:
458:                 registrations = Arrays.asList(
459:                         register(new Attachment()),
460:                         register(new Reference()),
461:                         register(new EObjectSelection()),
462:                         register(new OpenInNewContext()));
463:         }
464:
465:         void unregisterReferenceCustomizations() {
466:                 for (final ServiceRegistration<?> reg : registrations) {
467:                         reg.unregister();
468:                 }
469:         }
470:
471:         ServiceRegistration<?> register(ReferenceServiceCustomizationVendor<?> vendor) {
472:                 final BundleContext ctx = FrameworkUtil.getBundle(getClass()).getBundleContext();
473:
474:                 final Hashtable<String, Object> properties = new Hashtable<String, Object>();
475:                 properties.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE);
476:
477:                 inject(factory, vendor);
478:
479:                 return ctx.registerService(Vendor.class, vendor, properties);
480:         }
481:
482:         private void inject(Object target, Object dependency) {
483:                 final Class<?> toInject = dependency.getClass();
484:
485:                 try {
486:                         for (final Method next : target.getClass().getDeclaredMethods()) {
487:                                 if (next.getName().startsWith("add")) {
488:                                         final Class<?>[] parms = next.getParameterTypes();
489:                                         if (parms.length == 1 && parms[0].isAssignableFrom(toInject)) {
490:                                                 next.setAccessible(true);
491:                                                 next.invoke(target, dependency);
492:                                                 return;
493:                                         }
494:                                 }
495:                         }
496:                         fail(String.format("No suitable injection of %s into %s", dependency.getClass().getSimpleName(),
497:                                 target.getClass().getSimpleName()));
498:                 } catch (final IllegalAccessException e) {
499:                         fail("Illegal access in injection");
500:                 } catch (final InvocationTargetException e) {
501:                         e.getTargetException().printStackTrace();
502:                         fail("Injection failed");
503:                 }
504:         }
505:
506:         /**
507:          * Obtain an attachment strategy that adds classifiers to the given package instead of
508:          * the one in which contextx they are being created.
509:          *
510:          * @param ePackage the package in which to attach classifiers
511:          * @return the attachment strategy
512:          */
513:         final AttachmentStrategy createIn(final EPackage ePackage) {
514:                 return new AttachmentStrategy() {
515:
516:                         @Override
517:                         public boolean addElementToModel(EObject owner, EReference reference, EObject object) {
518:                                 if (object instanceof EClassifier) {
519:                                         ePackage.getEClassifiers().add((EClassifier) object);
520:                                         return true;
521:                                 }
522:
523:                                 return false;
524:                         }
525:                 };
526:         }
527:
528:         /**
529:          * Obtain a reference strategy that sets an attribute's typed lower bound to one.
530:          *
531:          * @param ePackage the package in which to attach classifiers
532:          * @return the attachment strategy
533:          */
534:         ReferenceStrategy setTypedElementRequired() {
535:                 return new ReferenceStrategy() {
536:
537:                         @Override
538:                         public boolean addElementsToReference(EObject owner, EReference reference, Set<? extends EObject> objects) {
539:                                 if (reference == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE && owner instanceof EAttribute) {
540:                                         ((ETypedElement) owner).setLowerBound(1);
541:                                         DEFAULT.addElementsToReference(owner, reference, objects);
542:                                         return true;
543:                                 }
544:
545:                                 return false;
546:                         }
547:
548:                 };
549:         }
550:
551:         /**
552:          * Obtain a strategy that allows selection only of objects contained within the given {@code ancestor}.
553:          *
554:          * @param ancestor an object in which to find the eligible existing objects to reference
555:          * @return the strategy
556:          */
557:         EObjectSelectionStrategy containedIn(final EObject ancestor) {
558:                 return new EObjectSelectionStrategy() {
559:
560:                         @Override
561:                         public Collection<EObject> collectExistingObjects(EObject owner, EReference reference,
562:                                 Collection<EObject> existingObjects) {
563:                                 for (final Iterator<EObject> iter = existingObjects.iterator(); iter.hasNext();) {
564:                                         if (!EcoreUtil.isAncestor(ancestor, iter.next())) {
565:                                                 iter.remove();
566:                                         }
567:                                 }
568:                                 return existingObjects;
569:                         }
570:                 };
571:         }
572:
573:         /**
574:          * Obtain a strategy that allows selection only of abstract classes.
575:          *
576:          * @return the strategy
577:          */
578:         EObjectSelectionStrategy onlyAbstractEClasses() {
579:                 return new EObjectSelectionStrategy() {
580:
581:                         @Override
582:                         public Collection<EObject> collectExistingObjects(EObject owner, EReference reference,
583:                                 Collection<EObject> existingObjects) {
584:                                 for (final Iterator<EObject> iter = existingObjects.iterator(); iter.hasNext();) {
585:                                         final EObject next = iter.next();
586:                                         if (!(next instanceof EClass) || !((EClass) next).isAbstract()) {
587:                                                 iter.remove();
588:                                         }
589:                                 }
590:                                 return existingObjects;
591:                         }
592:                 };
593:         }
594:
595:         ReferenceServiceCustomizationVendor<EObjectSelectionStrategy> vendor(final EObjectSelectionStrategy strategy) {
596:                 class StaticProvider extends ReferenceServiceCustomizationVendor<EObjectSelectionStrategy>
597:                         implements EObjectSelectionStrategy.Provider {
598:                         @Create
599:                         public EObjectSelectionStrategy create() {
600:                                 return strategy;
601:                         }
602:                 }
603:
604:                 return new StaticProvider();
605:         }
606:
607:         //
608:         // Nested types
609:         //
610:
611:         private class Attachment extends ReferenceServiceCustomizationVendor<AttachmentStrategy>
612:                 implements AttachmentStrategy.Provider {
613:
614:                 @Override
615:                 protected boolean handles(EObject owner, EReference reference) {
616:                         return reference == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE && owner instanceof EAttribute;
617:                 }
618:
619:                 @Create
620:                 public AttachmentStrategy create() {
621:                         return createIn(typesPackage);
622:                 }
623:         }
624:
625:         private class Reference extends ReferenceServiceCustomizationVendor<ReferenceStrategy>
626:                 implements ReferenceStrategy.Provider {
627:
628:                 @Override
629:                 protected boolean handles(EObject owner, EReference reference) {
630:                         return reference == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE && owner instanceof EAttribute;
631:                 }
632:
633:                 @Create
634:                 public ReferenceStrategy create() {
635:                         return setTypedElementRequired();
636:                 }
637:         }
638:
639:         private class EObjectSelection extends ReferenceServiceCustomizationVendor<EObjectSelectionStrategy>
640:                 implements EObjectSelectionStrategy.Provider {
641:
642:                 @Override
643:                 protected boolean handles(EObject owner, EReference reference) {
644:                         return reference == EcorePackage.Literals.ECLASS__ESUPER_TYPES
645:                                 || reference == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE && owner instanceof EAttribute;
646:                 }
647:
648:                 @Create
649:                 public EObjectSelectionStrategy create(EObject owner, EReference reference) {
650:                         EObjectSelectionStrategy result = null;
651:
652:                         if (reference == EcorePackage.Literals.ECLASS__ESUPER_TYPES) {
653:                                 result = onlyAbstractEClasses();
654:                         } else if (reference == EcorePackage.Literals.ETYPED_ELEMENT__ETYPE
655:                                 && owner instanceof EAttribute) {
656:
657:                                 result = containedIn(typesPackage);
658:                         }
659:
660:                         return result;
661:                 }
662:         }
663:
664:         private class OpenInNewContext extends ReferenceServiceCustomizationVendor<OpenInNewContextStrategy>
665:                 implements OpenInNewContextStrategy.Provider {
666:
667:                 @Create
668:                 public OpenInNewContextStrategy create() {
669:                         return openStrategy;
670:                 }
671:         }
672: }