/******************************************************************************* * Copyright (c) 2012 - 2013 Pivotal Software, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pivotal Software, Inc. - initial API and implementation *******************************************************************************/ package org.springsource.ide.eclipse.dashboard.ui; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; import org.eclipse.ui.internal.WorkbenchPlugin; import org.springsource.ide.eclipse.commons.core.StatusHandler; import org.springsource.ide.eclipse.dashboard.internal.ui.IdeUiPlugin; /** * A dashboard page that support part contributions. * @author Steffen Pingel * @author Christian Dupuis * @author Terry Denney */ public abstract class AbstractDashboardPage extends FormPage { private static class ExtensionPartDescriptor extends PartDescriptor { private final IConfigurationElement element; public ExtensionPartDescriptor(IConfigurationElement element) { super(element.getAttribute(ATTRIBUTE_ID)); this.element = element; setPath(element.getAttribute(ATTRIBUTE_PATH)); } @Override public AbstractDashboardPart createPart() { try { Object object = WorkbenchPlugin.createExtension(element, ATTRIBUTE_CLASS); if (!(object instanceof AbstractDashboardPart)) { StatusHandler.log(new Status(IStatus.ERROR, IdeUiPlugin.PLUGIN_ID, "Could not load " + object.getClass().getCanonicalName() + " must implement " + AbstractDashboardPart.class.getCanonicalName())); return null; } return (AbstractDashboardPart) object; } catch (CoreException e) { StatusHandler.log(new Status(IStatus.ERROR, IdeUiPlugin.PLUGIN_ID, "Could not read dashboard extension", e)); } return null; } } private static abstract class PartDescriptor { private final String id; private String path; public PartDescriptor(String id) { Assert.isNotNull(id); this.id = id; } public abstract AbstractDashboardPart createPart(); @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } PartDescriptor other = (PartDescriptor) obj; return id.equals(other.id); } public final String getId() { return id; } public final String getPath() { return path; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id.hashCode(); return result; } public final PartDescriptor setPath(String path) { this.path = path; return this; } } private static final String EXTENSION_ID_DASHBOARD = "com.springsource.sts.ide.ui.dashboard"; private static final String ELEMENT_PART = "part"; private static final String ATTRIBUTE_ID = "id"; private static final String ATTRIBUTE_PATH = "path"; private static final String ATTRIBUTE_PAGE = "page"; private static final String ATTRIBUTE_CLASS = "class"; private List<PartDescriptor> partDescriptors; public AbstractDashboardPage(FormEditor editor, String id, String title) { super(editor, id, title); } public AbstractDashboardPage(String id, String title) { super(id, title); } protected List<AbstractDashboardPart> contributeParts(Composite parent, String path) { if (partDescriptors == null) { readExtensions(); } return createParts(parent, path, partDescriptors); } private List<AbstractDashboardPart> createParts(final Composite parent, String path, Collection<PartDescriptor> descriptors) { final List<AbstractDashboardPart> parts = Collections.synchronizedList(new ArrayList<AbstractDashboardPart>()); for (Iterator<PartDescriptor> it = descriptors.iterator(); it.hasNext();) { final PartDescriptor descriptor = it.next(); if (path == null || path.equals(descriptor.getPath())) { SafeRunner.run(new ISafeRunnable() { public void handleException(Throwable e) { StatusHandler.log(new Status(IStatus.ERROR, IdeUiPlugin.PLUGIN_ID, "Error creating dashboard part: \"" + descriptor.getId() + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$ } public void run() throws Exception { AbstractDashboardPart part = descriptor.createPart(); if (part != null) { if (part instanceof IEnabledDashboardPart) { if (!((IEnabledDashboardPart) part).shouldAdd()) { return; } } part.setId(descriptor.getId()); parts.add(part); initializePart(parent, part); } } }); it.remove(); } } return parts; } private void initializePart(Composite parent, AbstractDashboardPart part) { getManagedForm().addPart(part); part.initialize(getManagedForm()); part.createControl(parent); if (part.getControl() != null) { if (parent.getLayout() instanceof GridLayout) { GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(false, true).applyTo(part.getControl()); } else if (parent.getLayout() instanceof TableWrapLayout) { part.getControl().setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); } } } private void readExtensions() { this.partDescriptors = new ArrayList<PartDescriptor>(); IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_ID_DASHBOARD); IExtension[] extensions = extensionPoint.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] elements = extension.getConfigurationElements(); for (IConfigurationElement element : elements) { if (element.getName().equals(ELEMENT_PART)) { readPartExtension(element); } } } } private void readPartExtension(IConfigurationElement element) { String page = element.getAttribute(ATTRIBUTE_PAGE); if (getId().equals(page)) { partDescriptors.add(new ExtensionPartDescriptor(element)); } } }