Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -835,22 +835,33 @@ public void resolveImports(List<MApplicationElement> imports, List<MApplicationE
element = null;
}
commands.add(() -> {
MApplicationElement resolved = element;
if (resolved != null && !feature.getEType().isInstance(resolved)) {
// a different-typed element sharing the id must not abort model assembly
warn("Could not resolve import for {}: incompatible with feature {} of {}", //$NON-NLS-1$
resolved.getElementId(), feature.getName(), target);
resolved = null;
}
if (feature.isMany()) {
@SuppressWarnings("unchecked")
List<Object> l = (List<Object>) target.eGet(feature);
if (resolved == null) {
l.remove(importObject);
return;
}
error("""
Replacing in {}.
Feature={}.
InternalElement={} contributed by {}.
ImportObject={}
""", target, feature.getName(), element.getElementId(), element.getContributorURI(), //$NON-NLS-1$
""", target, feature.getName(), resolved.getElementId(), resolved.getContributorURI(), //$NON-NLS-1$
importObject);
@SuppressWarnings("unchecked")
List<Object> l = (List<Object>) target.eGet(feature);
int index = l.indexOf(importObject);
if (index >= 0) {
l.set(index, element);
l.set(index, resolved);
}
} else {
target.eSet(feature, element);
target.eSet(feature, resolved);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.eclipse.e4.ui.tests.workbench;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import jakarta.annotation.PostConstruct;
Expand Down Expand Up @@ -44,6 +45,7 @@
import org.eclipse.e4.ui.internal.workbench.swt.E4Application;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.model.application.commands.MBindingContext;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MHandler;
import org.eclipse.e4.ui.model.application.impl.ApplicationFactoryImpl;
Expand Down Expand Up @@ -561,6 +563,66 @@ public void testImports_noImportElementId() throws Exception {
assertEquals("Could not resolve import for null", logMessages.poll());
}

/** Tests that an import resolving to an element of an incompatible type is dropped. */
@Test
public void testImports_typeIncompatibleElement() throws Exception {
List<MApplicationElement> imports = new ArrayList<>();
List<MApplicationElement> addedElements = new ArrayList<>();

final String sharedElementId = "testImports_typeIncompatible_id";
MTrimmedWindow importWindow = modelService.createModelElement(MTrimmedWindow.class);
importWindow.setElementId(sharedElementId);
MModelFragments fragment = MFragmentFactory.INSTANCE.createModelFragments();
fragment.getImports().add(importWindow);
imports.add(importWindow);
MCommand collidingCommand = modelService.createModelElement(MCommand.class);
collidingCommand.setElementId(sharedElementId);
application.getCommands().add(collidingCommand);

MPlaceholder placeholder = modelService.createModelElement(MPlaceholder.class);
placeholder.setRef(importWindow);
addedElements.add(placeholder);

CountDownLatch countDownLatch = new CountDownLatch(1);
this.logListener.countDownLatch = countDownLatch;

assembler.resolveImports(imports, addedElements);
assertNull(placeholder.getRef());

boolean completed = countDownLatch.await(COUNTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
assertTrue(completed, "Timeout - no event received");
assertEquals(1, logMessages.size());
assertTrue(logMessages.poll().startsWith("Could not resolve import for " + sharedElementId + ": incompatible"));
}

/** Tests that an unresolved import in a many-valued reference is removed. */
@Test
public void testImports_unresolvedInManyValuedFeature() throws Exception {
List<MApplicationElement> imports = new ArrayList<>();
List<MApplicationElement> addedElements = new ArrayList<>();

MBindingContext importContext = modelService.createModelElement(MBindingContext.class);
importContext.setElementId("testImports_unresolvedMany_context");
MModelFragments fragment = MFragmentFactory.INSTANCE.createModelFragments();
fragment.getImports().add(importContext);
imports.add(importContext);

MPart part = modelService.createModelElement(MPart.class);
part.getBindingContexts().add(importContext);
addedElements.add(part);

CountDownLatch countDownLatch = new CountDownLatch(1);
this.logListener.countDownLatch = countDownLatch;

assembler.resolveImports(imports, addedElements);
assertTrue(part.getBindingContexts().isEmpty());

boolean completed = countDownLatch.await(COUNTDOWN_TIMEOUT, TimeUnit.MILLISECONDS);
assertTrue(completed, "Timeout - no event received");
assertEquals(1, logMessages.size());
assertEquals("Could not resolve import for testImports_unresolvedMany_context", logMessages.poll());
}

/**
* Make sure that all fragments and imports are resolved before the
* post-processors are run. For reference, see
Expand Down
Loading