### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.ui
Index: ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java,v
retrieving revision 1.46
diff -u -r1.46 TypeHierarchyLifeCycle.java
--- ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java 31 Dec 2008 21:13:30 -0000 1.46
+++ ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java 30 Oct 2009 09:21:43 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
* 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
@@ -14,12 +14,19 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.swt.widgets.Display;
+
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
@@ -37,6 +44,9 @@
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+import org.eclipse.jdt.internal.corext.util.Messages;
+
+import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jdt.internal.ui.JavaPlugin;
@@ -52,8 +62,30 @@
private List fChangeListeners;
- public TypeHierarchyLifeCycle() {
+ /**
+ * The type hierarchy view part.
+ *
+ * @since 3.6
+ */
+ private TypeHierarchyViewPart fTypeHierarchyViewPart;
+
+ /**
+ * The job that runs in the background to refresh the type hierarchy.
+ *
+ * @since 3.6
+ */
+ private Job fRefreshHierarchyJob;
+
+ /**
+ * Creates the type hierarchy life cycle.
+ *
+ * @param part the type hierarchy view part
+ * @since 3.6
+ */
+ public TypeHierarchyLifeCycle(TypeHierarchyViewPart part) {
this(false);
+ fTypeHierarchyViewPart= part;
+ fRefreshHierarchyJob= null;
}
public TypeHierarchyLifeCycle(boolean isSuperTypesOnly) {
@@ -98,7 +130,27 @@
}
}
+ /**
+ * Refreshes the type hierarchy for the java element if it exists.
+ *
+ * @param element the java element for which the type hierarchy is computed
+ * @param context the runnable context
+ * @throws InterruptedException thrown from the OperationCanceledException
when the monitor is canceled
+ * @throws InvocationTargetException thrown from the JavaModelException
if the java element does not exist or if an exception occurs while accessing its corresponding resource
+ */
public void ensureRefreshedTypeHierarchy(final IJavaElement element, IRunnableContext context) throws InvocationTargetException, InterruptedException {
+ synchronized (this) {
+ if (fRefreshHierarchyJob != null) {
+ fRefreshHierarchyJob.cancel();
+ try {
+ fRefreshHierarchyJob.join();
+ } catch (InterruptedException e) {
+ // ignore
+ } finally {
+ fRefreshHierarchyJob= null;
+ }
+ }
+ }
if (element == null || !element.exists()) {
freeHierarchy();
return;
@@ -106,21 +158,86 @@
boolean hierachyCreationNeeded= (fHierarchy == null || !element.equals(fInputElement));
if (hierachyCreationNeeded || fHierarchyRefreshNeeded) {
-
- IRunnableWithProgress op= new IRunnableWithProgress() {
- public void run(IProgressMonitor pm) throws InvocationTargetException, InterruptedException {
- try {
- doHierarchyRefresh(element, pm);
- } catch (JavaModelException e) {
- throw new InvocationTargetException(e);
- } catch (OperationCanceledException e) {
- throw new InterruptedException();
+ if (fTypeHierarchyViewPart == null) {
+ IRunnableWithProgress op= new IRunnableWithProgress() {
+ public void run(IProgressMonitor pm) throws InvocationTargetException, InterruptedException {
+ try {
+ doHierarchyRefresh(element, pm);
+ } catch (JavaModelException e) {
+ throw new InvocationTargetException(e);
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException();
+ }
+ }
+ };
+ fHierarchyRefreshNeeded= true;
+ context.run(true, true, op);
+ fHierarchyRefreshNeeded= false;
+ } else {
+ final String label= Messages.format(TypeHierarchyMessages.TypeHierarchyLifeCycle_computeInput, JavaElementLabels.getElementLabel(element, JavaElementLabels.ALL_DEFAULT));
+ fRefreshHierarchyJob= new Job(label) {
+ /*
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public IStatus run(IProgressMonitor pm) {
+ pm.beginTask(label, LONG);
+ try {
+ doHierarchyRefreshBackground(element, pm);
+ } catch (OperationCanceledException e) {
+ fTypeHierarchyViewPart.setCanceledViewer(false);
+ return Status.CANCEL_STATUS;
+ } catch (JavaModelException e) {
+ return e.getStatus();
+ } finally {
+ fHierarchyRefreshNeeded= true;
+ pm.done();
+ }
+ return Status.OK_STATUS;
}
+ };
+ fRefreshHierarchyJob.setUser(true);
+ IWorkbenchSiteProgressService progressService= (IWorkbenchSiteProgressService)fTypeHierarchyViewPart.getSite()
+ .getAdapter(IWorkbenchSiteProgressService.class);
+ progressService.schedule(fRefreshHierarchyJob, 0);
+
+ }
+ }
+ }
+
+ /**
+ * Returns true
if the refresh job is running, false
otherwise.
+ *
+ * @return true
if the refresh job is running, false
otherwise
+ *
+ * @since 3.6
+ */
+ public boolean isRefreshJob() {
+ return fRefreshHierarchyJob != null;
+ }
+
+ /**
+ * Refreshes the hierarchy in the background and updates the hierarchy viewer asynchronously in
+ * the UI thread.
+ *
+ * @param element the java element on which the hierarchy is computed
+ * @param pm the progress monitor
+ * @throws JavaModelException if the java element does not exist or if an exception occurs while
+ * accessing its corresponding resource.
+ *
+ * @since 3.6
+ */
+ protected void doHierarchyRefreshBackground(final IJavaElement element, final IProgressMonitor pm) throws JavaModelException {
+ doHierarchyRefresh(element, pm);
+ if (!pm.isCanceled()) {
+ Display.getDefault().asyncExec(new Runnable() {
+ /*
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+ fTypeHierarchyViewPart.setViewerInput();
+ fTypeHierarchyViewPart.updateViewers();
}
- };
- fHierarchyRefreshNeeded= true;
- context.run(true, true, op);
- fHierarchyRefreshNeeded= false;
+ });
}
}
@@ -160,7 +277,7 @@
}
- public synchronized void doHierarchyRefresh(IJavaElement element, IProgressMonitor pm) throws JavaModelException {
+ public void doHierarchyRefresh(IJavaElement element, IProgressMonitor pm) throws JavaModelException {
boolean hierachyCreationNeeded= (fHierarchy == null || !element.equals(fInputElement));
// to ensure the order of the two listeners always remove / add listeners on operations
// on type hierarchies
@@ -176,6 +293,8 @@
fInputElement= element;
} else {
fHierarchy.refresh(pm);
+ if (pm != null && pm.isCanceled())
+ throw new OperationCanceledException();
}
fHierarchy.addTypeHierarchyChangedListener(this);
JavaCore.addElementChangedListener(this);
Index: ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.java,v
retrieving revision 1.12
diff -u -r1.12 TypeHierarchyMessages.java
--- ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.java 6 Aug 2009 13:53:47 -0000 1.12
+++ ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.java 30 Oct 2009 09:21:43 -0000
@@ -72,6 +72,7 @@
public static String TypeHierarchyViewPart_ws_tooltip;
public static String TypeHierarchyViewPart_restoreinput;
public static String TypeHierarchyViewPart_layout_submenu;
+ public static String TypeHierarchyLifeCycle_computeInput;
public static String ToggleViewAction_subtypes_label;
public static String ToggleViewAction_subtypes_tooltip;
public static String ToggleViewAction_subtypes_description;
Index: ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.properties
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.properties,v
retrieving revision 1.59
diff -u -r1.59 TypeHierarchyMessages.properties
--- ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.properties 17 Aug 2009 15:28:36 -0000 1.59
+++ ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyMessages.properties 30 Oct 2009 09:21:43 -0000
@@ -62,6 +62,7 @@
SortByDefiningTypeAction_label=Sort by the Defining Type
SortByDefiningTypeAction_tooltip=Sort Methods by the Defining Type
SortByDefiningTypeAction_description=Sort methods by the defining type
+TypeHierarchyLifeCycle_computeInput=Computing type hierarchy of ''{0}''...
TypeHierarchyViewPart_error_title=Open Type Hierarchy
TypeHierarchyViewPart_createinput=Creating type hierarchy of ''{0}''...
Index: ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyViewPart.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyViewPart.java,v
retrieving revision 1.227
diff -u -r1.227 TypeHierarchyViewPart.java
--- ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyViewPart.java 6 Aug 2009 13:53:47 -0000 1.227
+++ ui/org/eclipse/jdt/internal/ui/typehierarchy/TypeHierarchyViewPart.java 30 Oct 2009 09:21:44 -0000
@@ -242,6 +242,20 @@
private OpenAction fOpenAction;
+ /**
+ * Indicates whether the restore job was canceled.
+ *
+ * @since 3.6
+ */
+ private boolean fIsRestoreJobCancel= false;
+
+ /**
+ * Indicates whether the current viewer shown is the empty viewer.
+ *
+ * @since 3.6
+ */
+ private boolean fIsShowingEmptyViewer= true;
+
public TypeHierarchyViewPart() {
fSelectedType= null;
@@ -251,7 +265,7 @@
fSelectInEditor= true;
fRestoreStateJob= null;
- fHierarchyLifeCycle= new TypeHierarchyLifeCycle();
+ fHierarchyLifeCycle= new TypeHierarchyLifeCycle(this);
fTypeHierarchyLifeCycleListener= new ITypeHierarchyLifeCycleListener() {
public void typeHierarchyChanged(TypeHierarchyLifeCycle typeHierarchy, IType[] changedTypes) {
doTypeHierarchyChanged(typeHierarchy, changedTypes);
@@ -511,6 +525,7 @@
synchronized (this) {
if (fRestoreStateJob != null) {
fRestoreStateJob.cancel();
+ fIsRestoreJobCancel= true;
try {
fRestoreStateJob.join();
} catch (InterruptedException e) {
@@ -529,6 +544,11 @@
if (inputElement == null) {
clearInput();
} else {
+ if (!inputElement.equals(prevInput)) {
+ for (int i= 0; i < fAllViewers.length; i++) {
+ fAllViewers[i].setInput(null);
+ }
+ }
fInputElement= inputElement;
fNoHierarchyShownLabel.setText(Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_createinput, JavaElementLabels.getElementLabel(inputElement, JavaElementLabels.ALL_DEFAULT)));
try {
@@ -537,34 +557,45 @@
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, getSite().getShell(), TypeHierarchyMessages.TypeHierarchyViewPart_exception_title, TypeHierarchyMessages.TypeHierarchyViewPart_exception_message);
clearInput();
- return;
+ return;// panic code. This code wont be executed.
} catch (InterruptedException e) {
fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
- return;
+ return;// panic code. This code wont be executed.
}
if (inputElement.getElementType() != IJavaElement.TYPE) {
setHierarchyMode(HIERARCHY_MODE_CLASSIC);
}
- // turn off member filtering
- fSelectInEditor= false;
- setMemberFilter(null);
- internalSelectType(null, false); // clear selection
- fIsEnableMemberFilter= false;
- if (!inputElement.equals(prevInput)) {
- updateHierarchyViewer(true);
- }
- IType root= getSelectableType(inputElement);
- internalSelectType(root, true);
- updateMethodViewer(root);
- updateToolbarButtons();
- updateToolTipAndDescription();
- showMembersInHierarchy(false);
- fPagebook.showPage(fTypeMethodsSplitter);
- fSelectInEditor= true;
+ updateViewers();
}
}
+ /**
+ * Updates the viewers, toolbar buttons and tooltip.
+ *
+ * @since 3.6
+ */
+ public void updateViewers() {
+ if (!fHierarchyLifeCycle.isRefreshJob()) {
+ setViewerInput();
+ }
+ setViewerVisibility(true);
+ // turn off member filtering
+ fSelectInEditor= false;
+ setMemberFilter(null);
+ internalSelectType(null, false); // clear selection
+ fIsEnableMemberFilter= false;
+ updateHierarchyViewer(true);
+ IType root= getSelectableType(fInputElement);
+ internalSelectType(root, true);
+ updateMethodViewer(root);
+ updateToolbarButtons();
+ updateToolTipAndDescription();
+ showMembersInHierarchy(false);
+ fPagebook.showPage(fTypeMethodsSplitter);
+ fSelectInEditor= true;
+ }
+
private void processOutstandingEvents() {
Display display= getDisplay();
if (display != null && !display.isDisposed())
@@ -1086,7 +1117,7 @@
/*
* Toggles between the empty viewer page and the hierarchy
*/
- private void setViewerVisibility(boolean showHierarchy) {
+ public void setViewerVisibility(boolean showHierarchy) {
if (showHierarchy) {
fViewerbook.showPage(getCurrentViewer().getControl());
} else {
@@ -1124,7 +1155,7 @@
* updateHierarchyViewer brings up the correct view and refreshes
* the current tree
*/
- private void updateHierarchyViewer(final boolean doExpand) {
+ public void updateHierarchyViewer(final boolean doExpand) {
if (fInputElement == null) {
fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
fPagebook.showPage(fNoHierarchyShownLabel);
@@ -1139,9 +1170,14 @@
if (!isChildVisible(fViewerbook, getCurrentViewer().getControl())) {
setViewerVisibility(true);
}
- } else {
- fEmptyTypesViewer.setText(Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_nodecl, JavaElementLabels.getElementLabel(fInputElement, JavaElementLabels.ALL_DEFAULT)));
- setViewerVisibility(false);
+ } else if (!fIsShowingEmptyViewer) {//Show the empty hierarchy viewer till fresh computation is done.
+ if (fIsRestoreJobCancel) {
+ setCanceledViewer(false);
+ fIsRestoreJobCancel= false;
+ } else {
+ fEmptyTypesViewer.setText(Messages.format(TypeHierarchyMessages.TypeHierarchyViewPart_nodecl, JavaElementLabels.getElementLabel(fInputElement, JavaElementLabels.ALL_DEFAULT)));
+ setViewerVisibility(false);
+ }
}
}
}
@@ -1566,6 +1602,7 @@
} catch (JavaModelException e) {
return e.getStatus();
} catch (OperationCanceledException e) {
+ setCanceledViewer(true);
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
@@ -1579,17 +1616,16 @@
private void doRestoreInBackground(final IMemento memento, final IJavaElement hierarchyInput, IProgressMonitor monitor) throws JavaModelException {
fHierarchyLifeCycle.doHierarchyRefresh(hierarchyInput, monitor);
final boolean doRestore= !monitor.isCanceled();
- Display.getDefault().asyncExec(new Runnable() {
- public void run() {
- // running async: check first if view still exists
- if (fPagebook != null && !fPagebook.isDisposed()) {
- if (doRestore)
+ if (doRestore) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ // running async: check first if view still exists
+ if (fPagebook != null && !fPagebook.isDisposed()) {
doRestoreState(memento, hierarchyInput);
- else
- fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
+ }
}
- }
- });
+ });
+ }
}
@@ -1602,6 +1638,7 @@
}
fWorkingSetActionGroup.restoreState(memento);
+ setShowingEmptyViewer(false);
setInputElement(input);
Integer viewerIndex= memento.getInteger(TAG_VIEW);
@@ -1640,6 +1677,19 @@
}
/**
+ * Sets whether the previous viewer shown was an empty viewer.
+ *
+ * @param isShowingEmptyViewer true
if the previous viewer was empty,
+ * false
otherwise
+ *
+ * @since 3.6
+ */
+ private void setShowingEmptyViewer(boolean isShowingEmptyViewer) {
+ fIsShowingEmptyViewer= isShowingEmptyViewer;
+
+ }
+
+ /**
* View part becomes visible.
*
* @param isVisible true
if visible
@@ -1731,4 +1781,54 @@
fNeedRefresh= false;
}
+ /**
+ * Sets the empty viewer after the canceled job in the display thread.
+ * @param isRestoreJob true
when restore job is canceled, false
otherwise
+ *
+ * @since 3.6
+ */
+ public void setCanceledViewer(final boolean isRestoreJob) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ if (isRestoreJob) {
+ fNoHierarchyShownLabel.setText(TypeHierarchyMessages.TypeHierarchyViewPart_empty);
+ } else {
+ setViewerVisibility(false);
+ String label= "Type Hierarchy computation canceled"; //$NON-NLS-1$
+ fEmptyTypesViewer.setText(""); //$NON-NLS-1$
+ updateMethodViewer(null);
+ setContentDescription(label);
+ setTitleToolTip(""); //$NON-NLS-1$
+ for (int i= 0; i < fViewActions.length; i++) {
+ fViewActions[i].setEnabled(false);
+ }
+ }
+ setShowingEmptyViewer(true);
+ }
+ });
+ }
+
+ /**
+ * Returns the type hierarchy life cycle.
+ *
+ * @return the type hierarchy life cycle
+ *
+ * @since 3.6
+ */
+ public TypeHierarchyLifeCycle getTypeHierarchyLifeCycle() {
+ return fHierarchyLifeCycle;
+
+ }
+
+ /**
+ * Sets the input for all the hierarchy viewers with their respective viewer instances.
+ *
+ * @since 3.6
+ */
+ public void setViewerInput() {
+ for (int i= 0; i < fAllViewers.length; i++) {
+ fAllViewers[i].setInput(fAllViewers[i]);
+ }
+ setShowingEmptyViewer(false);
+ }
}