blob: d2815b8e13f2f29ac82497f153ecdc77cb6ce945 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.api.tools.ui.internal.views;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.ISession;
import org.eclipse.pde.api.tools.internal.provisional.ISessionListener;
import org.eclipse.pde.api.tools.internal.provisional.ISessionManager;
import org.eclipse.pde.api.tools.internal.provisional.ITreeModel;
import org.eclipse.pde.api.tools.internal.provisional.ITreeNode;
import org.eclipse.pde.api.tools.internal.provisional.comparator.DeltaProcessor;
import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.ui.internal.ApiImageDescriptor;
import org.eclipse.pde.api.tools.ui.internal.ApiUIPlugin;
import org.eclipse.pde.api.tools.ui.internal.IApiToolsConstants;
import org.eclipse.pde.api.tools.ui.internal.IApiToolsHelpContextIds;
import org.eclipse.pde.api.tools.ui.internal.SWTFactory;
import org.eclipse.pde.api.tools.ui.internal.actions.CollapseAllAction;
import org.eclipse.pde.api.tools.ui.internal.actions.ExpandAllAction;
import org.eclipse.pde.api.tools.ui.internal.actions.ExportSessionAction;
import org.eclipse.pde.api.tools.ui.internal.actions.NavigateAction;
import org.eclipse.pde.api.tools.ui.internal.actions.RemoveActiveSessionAction;
import org.eclipse.pde.api.tools.ui.internal.actions.RemoveAllSessionsAction;
import org.eclipse.pde.api.tools.ui.internal.actions.SelectSessionAction;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheetPage;
/**
* The class is used to show API Tools task results in a tree view.
*/
public class APIToolingView extends ViewPart implements ISessionListener {
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "org.eclipse.pde.api.tools.ui.views.apitooling.views.apitoolingview"; //$NON-NLS-1$
public TreeViewer viewer;
Label sessionDescription = null;
IAction removeActiveSessionAction;
IAction removeAllSessionsAction;
IAction selectSessionAction;
Action doubleClickAction;
ExportSessionAction exportSessionAction;
NavigateAction nextAction;
NavigateAction previousAction;
ExpandAllAction expandallAction;
CollapseAllAction collapseallAction;
private IPropertySheetPage page;
class ViewContentProvider implements ITreeContentProvider {
ITreeModel model;
@Override
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
this.model = null;
}
@Override
public Object[] getElements(Object parent) {
if (parent instanceof ISession) {
ISession session = (ISession) parent;
if (this.model == null) {
this.model = session.getModel();
}
return getChildren(this.model.getRoot());
}
return getChildren(parent);
}
@Override
public Object getParent(Object child) {
return null;
}
@Override
public Object[] getChildren(Object parent) {
if (parent instanceof ITreeNode) {
return ((ITreeNode) parent).getChildren();
}
return new Object[0];
}
@Override
public boolean hasChildren(Object parent) {
if (parent instanceof ITreeNode) {
return ((ITreeNode) parent).hasChildren();
}
return false;
}
}
class ViewLabelProvider extends LabelProvider {
@Override
public String getText(Object obj) {
return obj.toString();
}
@Override
public Image getImage(Object obj) {
if (obj instanceof ITreeNode) {
ITreeNode treeNode = (ITreeNode) obj;
switch (treeNode.getId()) {
case ITreeNode.CLASS:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CLASS);
case ITreeNode.INTERFACE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_INTERFACE);
case ITreeNode.ANNOTATION:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_ANNOTATION);
case ITreeNode.ENUM:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_ENUM);
case ITreeNode.PACKAGE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PACKAGE);
default:
break;
}
Object data = treeNode.getData();
if (data instanceof IDelta) {
IDelta delta = (IDelta) data;
Image image = getDeltaElementImage(delta);
if (image != null) {
int flags = (DeltaProcessor.isCompatible(delta) ? ApiImageDescriptor.SUCCESS : ApiImageDescriptor.ERROR);
ImageDescriptor descriptor = ImageDescriptor.createFromImage(image);
ApiImageDescriptor desc = new ApiImageDescriptor(descriptor, flags);
return ApiUIPlugin.getImage(desc);
}
}
}
return null;
}
private Image getDeltaElementImage(IDelta delta) {
switch (delta.getFlags()) {
case IDelta.API_FIELD:
case IDelta.FIELD: {
int modifiers = delta.getNewModifiers();
switch (delta.getKind()) {
case IDelta.REMOVED: {
modifiers = delta.getOldModifiers();
break;
}
default:
break;
}
if (Flags.isPublic(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PUBLIC);
} else if (Flags.isProtected(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PROTECTED);
} else if (Flags.isPrivate(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PRIVATE);
} else {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_DEFAULT);
}
}
case IDelta.METHOD:
case IDelta.METHOD_MOVED_DOWN:
case IDelta.METHOD_MOVED_UP:
case IDelta.METHOD_WITH_DEFAULT_VALUE:
case IDelta.METHOD_WITHOUT_DEFAULT_VALUE:
case IDelta.CONSTRUCTOR:
case IDelta.CLINIT: {
int modifiers = delta.getNewModifiers();
switch (delta.getKind()) {
case IDelta.REMOVED: {
modifiers = delta.getOldModifiers();
break;
}
default:
break;
}
if (Flags.isPublic(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PUBLIC);
} else if (Flags.isProtected(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PROTECTED);
} else if (Flags.isPrivate(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PRIVATE);
} else {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CLASS_DEFAULT);
}
}
default:
break;
}
switch (delta.getElementType()) {
case IDelta.ANNOTATION_ELEMENT_TYPE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_ANNOTATION);
case IDelta.ENUM_ELEMENT_TYPE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_ENUM);
case IDelta.CLASS_ELEMENT_TYPE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CLASS);
case IDelta.INTERFACE_ELEMENT_TYPE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_INTERFACE);
case IDelta.FIELD_ELEMENT_TYPE: {
int modifiers = delta.getNewModifiers();
switch (delta.getKind()) {
case IDelta.REMOVED: {
modifiers = delta.getOldModifiers();
break;
}
default:
break;
}
if (Flags.isPublic(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PUBLIC);
} else if (Flags.isProtected(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PROTECTED);
} else if (Flags.isPrivate(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_PRIVATE);
} else {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_FIELD_DEFAULT);
}
}
case IDelta.METHOD_ELEMENT_TYPE:
case IDelta.CONSTRUCTOR_ELEMENT_TYPE: {
int modifiers = delta.getNewModifiers();
switch (delta.getKind()) {
case IDelta.REMOVED: {
modifiers = delta.getOldModifiers();
break;
}
default:
break;
}
if (Flags.isPublic(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PUBLIC);
} else if (Flags.isProtected(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PROTECTED);
} else if (Flags.isPrivate(modifiers)) {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PRIVATE);
} else {
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_CLASS_DEFAULT);
}
}
case IDelta.TYPE_PARAMETER_ELEMENT_TYPE:
return JavaUI.getSharedImages().getImage(org.eclipse.jdt.ui.ISharedImages.IMG_OBJS_PUBLIC);
case IDelta.API_BASELINE_ELEMENT_TYPE:
case IDelta.API_COMPONENT_ELEMENT_TYPE: {
String componentVersionId = delta.getComponentVersionId();
IApiComponent component = null;
if (componentVersionId != null) {
int indexOfOpen = componentVersionId.lastIndexOf('(');
String componentID = componentVersionId.substring(0, indexOfOpen);
IApiBaseline baseline = ApiBaselineManager.getManager().getWorkspaceBaseline();
if (baseline != null) {
IApiComponent apiComponent = baseline.getApiComponent(componentID);
if (apiComponent != null) {
component = apiComponent;
}
}
}
if (component != null) {
if (component.isSystemComponent()) {
return ApiUIPlugin.getSharedImage(IApiToolsConstants.IMG_OBJ_API_SYSTEM_LIBRARY);
}
try {
if (component.isFragment()) {
return ApiUIPlugin.getSharedImage(IApiToolsConstants.IMG_OBJ_FRAGMENT);
}
} catch (CoreException e) {
ApiPlugin.log(e);
}
}
return ApiUIPlugin.getSharedImage(IApiToolsConstants.IMG_OBJ_BUNDLE);
}
default:
break;
}
return null;
}
}
/**
* The constructor.
*/
public APIToolingView() {
}
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
@Override
public void createPartControl(Composite parent) {
ViewForm form = new ViewForm(parent, SWT.FLAT);
PlatformUI.getWorkbench().getHelpSystem().setHelp(form, IApiToolsHelpContextIds.API_TOOLING_VIEW);
this.sessionDescription = SWTFactory.createLabel(form, null, 1);
form.setTopCenterSeparate(true);
form.setTopCenter(this.sessionDescription);
this.viewer = new TreeViewer(form, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
this.viewer.setContentProvider(new ViewContentProvider());
this.viewer.setComparator(new ViewerComparator() {
@Override
public int category(Object element) {
ITreeNode node = (ITreeNode) element;
switch (node.getId()) {
case ITreeNode.PACKAGE:
return 1;
default:
return 0;
}
}
});
this.viewer.setLabelProvider(new ViewLabelProvider());
createActions();
updateActions();
configureToolbar();
hookDoubleClickAction();
form.setContent(this.viewer.getTree());
getSite().setSelectionProvider(this.viewer);
final ISessionManager sessionManager = ApiPlugin.getDefault().getSessionManager();
ISession[] sessions = sessionManager.getSessions();
if (sessions.length > 0) {
ISession activeSession = sessionManager.getActiveSession();
if (sessions[0] != activeSession) {
sessionManager.activateSession(sessions[0]);
} else {
this.viewer.setInput(activeSession);
updateActions();
}
}
}
@Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
final ISessionManager sessionManager = ApiPlugin.getDefault().getSessionManager();
sessionManager.addSessionListener(this);
}
private void hookDoubleClickAction() {
this.viewer.addDoubleClickListener(event -> APIToolingView.this.doubleClickAction.run());
}
@Override
public void dispose() {
ApiPlugin.getDefault().getSessionManager().removeSessionListener(this);
}
protected void configureToolbar() {
IActionBars actionBars = getViewSite().getActionBars();
IToolBarManager tbm = actionBars.getToolBarManager();
tbm.add(new Separator());
tbm.add(this.removeActiveSessionAction);
tbm.add(this.removeAllSessionsAction);
tbm.add(new Separator());
tbm.add(this.selectSessionAction);
tbm.add(new Separator());
tbm.add(this.nextAction);
tbm.add(this.previousAction);
tbm.add(new Separator());
tbm.add(this.expandallAction);
tbm.add(this.collapseallAction);
tbm.add(new Separator());
tbm.add(this.exportSessionAction);
}
private void createActions() {
final IActionBars actionBars = getViewSite().getActionBars();
this.removeActiveSessionAction = new RemoveActiveSessionAction();
actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), removeActiveSessionAction);
this.removeAllSessionsAction = new RemoveAllSessionsAction();
this.selectSessionAction = new SelectSessionAction();
this.doubleClickAction = new Action() {
@Override
public void run() {
ISelection selection = viewer.getSelection();
if (selection instanceof IStructuredSelection) {
Object item = ((IStructuredSelection) selection).getFirstElement();
if (APIToolingView.this.viewer.getExpandedState(item)) {
APIToolingView.this.viewer.collapseToLevel(item, 1);
} else {
APIToolingView.this.viewer.expandToLevel(item, 1);
}
if (item instanceof ITreeNode) {
ITreeNode node = (ITreeNode) item;
if (node.getData() != null && !node.hasChildren()) {
// show the Properties view
ApiUIPlugin.getDefault().showPropertiesView();
}
}
}
}
};
this.exportSessionAction = new ExportSessionAction(this);
this.nextAction = new NavigateAction(this, true);
this.previousAction = new NavigateAction(this, false);
this.expandallAction = new ExpandAllAction(this.viewer);
this.collapseallAction = new CollapseAllAction(this.viewer);
}
private void updateActions() {
this.viewer.getControl().getDisplay().asyncExec(() -> {
ISessionManager sessionManager = ApiPlugin.getDefault().getSessionManager();
ISession active = sessionManager.getActiveSession();
APIToolingView.this.sessionDescription.setText(active == null ? "No Description" : active.getDescription()); //$NON-NLS-1$
ISession[] sessions = sessionManager.getSessions();
boolean atLeastOne = sessions.length >= 1;
APIToolingView.this.removeActiveSessionAction.setEnabled(atLeastOne);
APIToolingView.this.removeAllSessionsAction.setEnabled(atLeastOne);
APIToolingView.this.selectSessionAction.setEnabled(atLeastOne);
APIToolingView.this.exportSessionAction.setEnabled(active != null);
APIToolingView.this.expandallAction.setEnabled(atLeastOne);
APIToolingView.this.collapseallAction.setEnabled(atLeastOne);
APIToolingView.this.nextAction.setEnabled(atLeastOne);
APIToolingView.this.previousAction.setEnabled(atLeastOne);
});
}
/**
* Passing the focus request to the viewer's control.
*/
@Override
public void setFocus() {
this.viewer.getControl().setFocus();
}
@Override
public void sessionAdded(final ISession session) {
this.viewer.getControl().getDisplay().asyncExec(() -> APIToolingView.this.viewer.setInput(session));
updateActions();
}
@Override
public void sessionRemoved(ISession session) {
this.viewer.setInput(null);
updateActions();
}
@Override
public void sessionActivated(final ISession session) {
this.viewer.getControl().getDisplay().asyncExec(() -> APIToolingView.this.viewer.setInput(session));
updateActions();
}
/**
* Returns the property sheet.
*/
protected IPropertySheetPage getPropertySheet() {
if (this.page == null) {
this.page = new PropertySheetPage();
}
return this.page;
}
@Override
@SuppressWarnings("unchecked")
public <T> T getAdapter(Class<T> adapter) {
if (adapter.equals(IPropertySheetPage.class)) {
return (T) getPropertySheet();
}
return super.getAdapter(adapter);
}
}