Skip to content
Open
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 @@ -33,6 +33,7 @@
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
Expand All @@ -58,6 +59,9 @@
*/
public class PerspectiveRegistry implements IPerspectiveRegistry, IExtensionChangeHandler {

private static final String PLATFORM_PLUGIN_PREFIX = "platform:/plugin/"; //$NON-NLS-1$
private static final String PLATFORM_FRAGMENT_PREFIX = "platform:/fragment/"; //$NON-NLS-1$

@Inject
private IExtensionRegistry extensionRegistry;

Expand Down Expand Up @@ -137,19 +141,49 @@ public void createDescriptor(MPerspective perspective) {
String id = perspective.getElementId();
PerspectiveDescriptor newDescriptor = new PerspectiveDescriptor(id, label, originalDescriptor);

if (perspective.getIconURI() != null) {
String iconURI = perspective.getIconURI();
if (iconURI != null && isIconAvailable(iconURI)) {
try {
ImageDescriptor img = ImageDescriptor.createFromURL(new URI(perspective.getIconURI()).toURL());
ImageDescriptor img = ImageDescriptor.createFromURL(new URI(iconURI).toURL());
newDescriptor.setImageDescriptor(img);
} catch (MalformedURLException | URISyntaxException | IllegalArgumentException e) {
logger.warn(e, MessageFormat.format("Error on applying configured perspective icon: {0}", //$NON-NLS-1$
perspective.getIconURI()));
iconURI));
}
}

descriptors.put(id, newDescriptor);
}

/**
* Tells whether the bundle a platform icon URI points to is installed. Loading
* an icon of a missing bundle logs an error per attempt in the platform URL
* layer.
*/
private boolean isIconAvailable(String iconURI) {
String reference = null;
for (String prefix : new String[] { PLATFORM_PLUGIN_PREFIX, PLATFORM_FRAGMENT_PREFIX }) {
if (iconURI.startsWith(prefix)) {
reference = iconURI.substring(prefix.length()).split("/", 2)[0]; //$NON-NLS-1$
break;
}
}
if (reference == null) {
return true;
}
if (Platform.getBundle(reference) != null) {
return true;
}
// the reference may carry a version, as in "com.example_1.0.0"
int underscore = reference.indexOf('_');
if (underscore > 0 && Platform.getBundle(reference.substring(0, underscore)) != null) {
return true;
}
logger.warn(MessageFormat.format("Skipping the perspective icon {0} of the not installed bundle {1}", //$NON-NLS-1$
iconURI, reference));
return false;
}

/**
* Construct a new registry.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchImages;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.tests.harness.util.ArrayUtil;
import org.junit.Before;
Expand Down Expand Up @@ -139,6 +141,43 @@ public void testModelPerspective() {
}
}

/**
* A perspective whose contributing bundle is gone must fall back to the default
* icon instead of loading the one its model element names.
*/
@Test
public void testModelPerspectiveWithUninstalledIconBundle() {
WorkbenchWindow window = (WorkbenchWindow) PlatformUI.getWorkbench().getActiveWorkbenchWindow();
EModelService modelService = window.getService(EModelService.class);

List<MPerspectiveStack> stacks = modelService.findElements(window.getModel(), null, MPerspectiveStack.class);
assertFalse("expected a perspective stack in the active window", stacks.isEmpty());
MPerspectiveStack stack = stacks.get(0);

String id = "org.eclipse.ui.tests.perspectiveWithUninstalledIconBundle";
MPerspective perspective = modelService.createModelElement(MPerspective.class);
perspective.setElementId(id);
perspective.setLabel("Perspective With Uninstalled Icon Bundle");
perspective.setIconURI("platform:/plugin/org.eclipse.ui.tests.uninstalled/icons/missing.svg");
perspective.setToBeRendered(false);
stack.getChildren().add(perspective);

try {
fReg.getPerspectives(); // registers perspectives added to the model
IPerspectiveDescriptor descriptor = fReg.findPerspectiveWithId(id);
assertNotNull("model-contributed perspective must be resolvable by id", descriptor);
assertEquals("the default perspective icon must be used for an uninstalled bundle",
WorkbenchImages.getImageDescriptor(ISharedImages.IMG_ETOOL_DEF_PERSPECTIVE),
descriptor.getImageDescriptor());
} finally {
stack.getChildren().remove(perspective);
IPerspectiveDescriptor descriptor = fReg.findPerspectiveWithId(id);
if (descriptor != null) {
fReg.deletePerspective(descriptor);
}
}
}

@Test
@Ignore
public void XXXtestDeleteClonedPerspective() {
Expand Down
Loading