diff options
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java')
-rw-r--r-- | org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java | 2010 |
1 files changed, 1005 insertions, 1005 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java index 4608c48b0..80c487b76 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java @@ -67,327 +67,327 @@ import org.eclipse.ui.progress.WorkbenchJob; */ public class TreeModelContentProvider implements ITreeModelContentProvider, IContentProvider, IModelChangedListener { - /** - * Tree model viewer that this content provider is used with. - */ - private IInternalTreeModelViewer fViewer; - - /** - * Mask used to filter delta updates coming from the model. - */ - private int fModelDeltaMask = ~0; - - /** - * Map tree paths to model proxy responsible for element - * - * Used to install different model proxy instances for one element depending - * on the tree path. - */ + /** + * Tree model viewer that this content provider is used with. + */ + private IInternalTreeModelViewer fViewer; + + /** + * Mask used to filter delta updates coming from the model. + */ + private int fModelDeltaMask = ~0; + + /** + * Map tree paths to model proxy responsible for element + * + * Used to install different model proxy instances for one element depending + * on the tree path. + */ private Map<TreePath, IModelProxy> fTreeModelProxies = new HashMap<>(); // tree // model // proxy // by // element tree path - /** - * Map element to model proxy responsible for it. - * - * Used to install a single model proxy which is responsible for all - * instances of an element in the model tree. - */ + /** + * Map element to model proxy responsible for it. + * + * Used to install a single model proxy which is responsible for all + * instances of an element in the model tree. + */ private Map<Object, IModelProxy> fModelProxies = new HashMap<>(); // model // proxy // by // element - /** - * Map of nodes that have been filtered from the viewer. - */ - private FilterTransform fTransform = new FilterTransform(); + /** + * Map of nodes that have been filtered from the viewer. + */ + private FilterTransform fTransform = new FilterTransform(); - /** - * Model listeners - */ + /** + * Model listeners + */ private ListenerList<IModelChangedListener> fModelListeners = new ListenerList<>(); - /** - * Viewer update listeners - */ + /** + * Viewer update listeners + */ private ListenerList<IViewerUpdateListener> fUpdateListeners = new ListenerList<>(); - /** - * Flag indicating whether we are currently in a model sequence. - * @see IViewerUpdateListener - */ - private boolean fModelSequenceRunning = false; + /** + * Flag indicating whether we are currently in a model sequence. + * @see IViewerUpdateListener + */ + private boolean fModelSequenceRunning = false; - /** - * Map of updates in progress: element path -> list of requests - */ + /** + * Map of updates in progress: element path -> list of requests + */ private Map<TreePath, List<ViewerUpdateMonitor>> fRequestsInProgress = new HashMap<>(); - /** - * Map of dependent requests waiting for parent requests to complete: - * element path -> list of requests - */ + /** + * Map of dependent requests waiting for parent requests to complete: + * element path -> list of requests + */ private Map<TreePath, List<ViewerUpdateMonitor>> fWaitingRequests = new HashMap<>(); private List<ViewerUpdateMonitor> fCompletedUpdates = new ArrayList<>(); - private Runnable fCompletedUpdatesRunnable; + private Runnable fCompletedUpdatesRunnable; - private ViewerStateTracker fStateTracker = new ViewerStateTracker(this); + private ViewerStateTracker fStateTracker = new ViewerStateTracker(this); private TreePath fRevealPath; private int fRevealIndex; - /** - * Update type constants - */ - static final int UPDATE_SEQUENCE_BEGINS = 0; + /** + * Update type constants + */ + static final int UPDATE_SEQUENCE_BEGINS = 0; - static final int UPDATE_SEQUENCE_COMPLETE = 1; + static final int UPDATE_SEQUENCE_COMPLETE = 1; - static final int UPDATE_BEGINS = 2; + static final int UPDATE_BEGINS = 2; - static final int UPDATE_COMPLETE = 3; + static final int UPDATE_COMPLETE = 3; - /** - * Constant for an empty tree path. - */ - static final TreePath EMPTY_TREE_PATH = new TreePath(new Object[] {}); + /** + * Constant for an empty tree path. + */ + static final TreePath EMPTY_TREE_PATH = new TreePath(new Object[] {}); - @Override + @Override public void dispose() { - if (fViewer == null) { + if (fViewer == null) { return; } fDelayedDoModelChangeJob.shutdown(); - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - // cancel pending updates + // cancel pending updates for (List<ViewerUpdateMonitor> requests : fRequestsInProgress.values()) { for (ViewerUpdateMonitor vu : requests) { vu.cancel(); - } - } - fWaitingRequests.clear(); - - fStateTracker.dispose(); - fModelListeners.clear(); - fUpdateListeners.clear(); - disposeAllModelProxies(); - - synchronized(this) { - fViewer = null; - } - } - - /** - * @return Returns whether the content provider is disposed. - */ - boolean isDisposed() { - synchronized(this) { - return fViewer == null; - } - } - - @Override + } + } + fWaitingRequests.clear(); + + fStateTracker.dispose(); + fModelListeners.clear(); + fUpdateListeners.clear(); + disposeAllModelProxies(); + + synchronized(this) { + fViewer = null; + } + } + + /** + * @return Returns whether the content provider is disposed. + */ + boolean isDisposed() { + synchronized(this) { + return fViewer == null; + } + } + + @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - synchronized(this) { - fViewer = (IInternalTreeModelViewer) viewer; - } + synchronized(this) { + fViewer = (IInternalTreeModelViewer) viewer; + } - Assert.isTrue( fViewer.getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( fViewer.getDisplay().getThread() == Thread.currentThread() ); - if (oldInput != null) { - fStateTracker.saveViewerState(oldInput); - } - } + if (oldInput != null) { + fStateTracker.saveViewerState(oldInput); + } + } - @Override + @Override public void postInputChanged(IInternalTreeModelViewer viewer, Object oldInput, Object newInput) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - - cancelSubtreeUpdates(TreePath.EMPTY); - disposeAllModelProxies(); - cancelSubtreeUpdates(TreePath.EMPTY); - fTransform.clear(); - if (newInput != null) { - installModelProxy(newInput, TreePath.EMPTY); - fStateTracker.restoreViewerState(newInput); - } - } - - @Override + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + + cancelSubtreeUpdates(TreePath.EMPTY); + disposeAllModelProxies(); + cancelSubtreeUpdates(TreePath.EMPTY); + fTransform.clear(); + if (newInput != null) { + installModelProxy(newInput, TreePath.EMPTY); + fStateTracker.restoreViewerState(newInput); + } + } + + @Override public void addViewerUpdateListener(IViewerUpdateListener listener) { - fUpdateListeners.add(listener); - } + fUpdateListeners.add(listener); + } - @Override + @Override public void removeViewerUpdateListener(IViewerUpdateListener listener) { - fUpdateListeners.remove(listener); - } + fUpdateListeners.remove(listener); + } - @Override + @Override public void addStateUpdateListener(IStateUpdateListener listener) { - fStateTracker.addStateUpdateListener(listener); - } + fStateTracker.addStateUpdateListener(listener); + } - @Override + @Override public void preserveState(TreePath path) { - fStateTracker.appendToPendingStateDelta(path); - } + fStateTracker.appendToPendingStateDelta(path); + } - @Override + @Override public void removeStateUpdateListener(IStateUpdateListener listener) { - fStateTracker.removeStateUpdateListener(listener); - } + fStateTracker.removeStateUpdateListener(listener); + } - @Override + @Override public void addModelChangedListener(IModelChangedListener listener) { - fModelListeners.add(listener); - } + fModelListeners.add(listener); + } - @Override + @Override public void removeModelChangedListener(IModelChangedListener listener) { - fModelListeners.remove(listener); - } + fModelListeners.remove(listener); + } - @Override + @Override public void cancelRestore(final TreePath path, final int flags) { - fStateTracker.cancelRestore(path, flags); - } + fStateTracker.cancelRestore(path, flags); + } - @Override + @Override public boolean setChecked(TreePath path, boolean checked) { - IModelProxy elementProxy = getElementProxy(path); - if (elementProxy instanceof ICheckboxModelProxy) { - return ((ICheckboxModelProxy) elementProxy).setChecked(getPresentationContext(), getViewer().getInput(), path, checked); - } - return false; - } - - /** - * Installs the model proxy for the given element into this content provider - * if not already installed. - * @param input the input to install the model proxy on - * @param path the {@link TreePath} to install the proxy for - */ - private void installModelProxy(Object input, TreePath path) { - - if (!fTreeModelProxies.containsKey(path) && !fModelProxies.containsKey(path.getLastSegment())) { - Object element = path.getSegmentCount() != 0 ? path.getLastSegment() : input; - IModelProxy proxy = null; - IModelProxyFactory2 modelProxyFactory2 = ViewerAdapterService.getModelProxyFactory2(element); - if (modelProxyFactory2 != null) { - proxy = modelProxyFactory2.createTreeModelProxy(input, path, getPresentationContext()); - if (proxy != null) { - fTreeModelProxies.put(path, proxy); - } - } - if (proxy == null) { - IModelProxyFactory modelProxyFactory = ViewerAdapterService.getModelProxyFactory(element); - if (modelProxyFactory != null) { - proxy = modelProxyFactory.createModelProxy(element, getPresentationContext()); - if (proxy != null) { - fModelProxies.put(element, proxy); - } - } - } - - if (proxy instanceof IModelProxy2) { - proxy.addModelChangedListener(this); - ((IModelProxy2)proxy).initialize(getViewer()); - } else if (proxy != null) { - final IModelProxy finalProxy = proxy; - Job job = new Job("Model Proxy installed notification job") {//$NON-NLS-1$ - @Override + IModelProxy elementProxy = getElementProxy(path); + if (elementProxy instanceof ICheckboxModelProxy) { + return ((ICheckboxModelProxy) elementProxy).setChecked(getPresentationContext(), getViewer().getInput(), path, checked); + } + return false; + } + + /** + * Installs the model proxy for the given element into this content provider + * if not already installed. + * @param input the input to install the model proxy on + * @param path the {@link TreePath} to install the proxy for + */ + private void installModelProxy(Object input, TreePath path) { + + if (!fTreeModelProxies.containsKey(path) && !fModelProxies.containsKey(path.getLastSegment())) { + Object element = path.getSegmentCount() != 0 ? path.getLastSegment() : input; + IModelProxy proxy = null; + IModelProxyFactory2 modelProxyFactory2 = ViewerAdapterService.getModelProxyFactory2(element); + if (modelProxyFactory2 != null) { + proxy = modelProxyFactory2.createTreeModelProxy(input, path, getPresentationContext()); + if (proxy != null) { + fTreeModelProxies.put(path, proxy); + } + } + if (proxy == null) { + IModelProxyFactory modelProxyFactory = ViewerAdapterService.getModelProxyFactory(element); + if (modelProxyFactory != null) { + proxy = modelProxyFactory.createModelProxy(element, getPresentationContext()); + if (proxy != null) { + fModelProxies.put(element, proxy); + } + } + } + + if (proxy instanceof IModelProxy2) { + proxy.addModelChangedListener(this); + ((IModelProxy2)proxy).initialize(getViewer()); + } else if (proxy != null) { + final IModelProxy finalProxy = proxy; + Job job = new Job("Model Proxy installed notification job") {//$NON-NLS-1$ + @Override protected IStatus run(IProgressMonitor monitor) { - if (!monitor.isCanceled()) { - IPresentationContext context = null; - Viewer viewer = null; - synchronized (TreeModelContentProvider.this) { - if (!isDisposed()) { - context = getPresentationContext(); - viewer = (Viewer) getViewer(); - } - } - if (viewer != null && context != null && !finalProxy.isDisposed()) { - finalProxy.init(context); - finalProxy.addModelChangedListener(TreeModelContentProvider.this); - finalProxy.installed(viewer); - } - } - return Status.OK_STATUS; - } - - @Override + if (!monitor.isCanceled()) { + IPresentationContext context = null; + Viewer viewer = null; + synchronized (TreeModelContentProvider.this) { + if (!isDisposed()) { + context = getPresentationContext(); + viewer = (Viewer) getViewer(); + } + } + if (viewer != null && context != null && !finalProxy.isDisposed()) { + finalProxy.init(context); + finalProxy.addModelChangedListener(TreeModelContentProvider.this); + finalProxy.installed(viewer); + } + } + return Status.OK_STATUS; + } + + @Override public boolean shouldRun() { - return !isDisposed(); - } - }; - job.setSystem(true); - job.schedule(); - } - } - } - - /** - * Finds the model proxy that an element with a given path is associated with. - * @param path Path of the element. - * @return Element's model proxy. - */ - private IModelProxy getElementProxy(TreePath path) { - while (path != null) { - IModelProxy proxy = fTreeModelProxies.get(path); - if (proxy != null) { - return proxy; - } - - Object element = path.getSegmentCount() == 0 ? getViewer().getInput() : path.getLastSegment(); - proxy = fModelProxies.get(element); - if (proxy != null) { - return proxy; - } - - path = path.getParentPath(); - } - return null; - } - - /** - * Removes all model proxies - */ - private void disposeAllModelProxies() { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + return !isDisposed(); + } + }; + job.setSystem(true); + job.schedule(); + } + } + } + + /** + * Finds the model proxy that an element with a given path is associated with. + * @param path Path of the element. + * @return Element's model proxy. + */ + private IModelProxy getElementProxy(TreePath path) { + while (path != null) { + IModelProxy proxy = fTreeModelProxies.get(path); + if (proxy != null) { + return proxy; + } + + Object element = path.getSegmentCount() == 0 ? getViewer().getInput() : path.getLastSegment(); + proxy = fModelProxies.get(element); + if (proxy != null) { + return proxy; + } + + path = path.getParentPath(); + } + return null; + } + + /** + * Removes all model proxies + */ + private void disposeAllModelProxies() { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); for (IModelProxy proxy : fModelProxies.values()) { - proxy.dispose(); - } - fModelProxies.clear(); + proxy.dispose(); + } + fModelProxies.clear(); for (IModelProxy proxy : fTreeModelProxies.values()) { - proxy.dispose(); - } - fTreeModelProxies.clear(); - } - - /** - * Removes the model proxy installed for the given element, if any. - * @param path the {@link TreePath} to dispose the model proxy for - */ - private void disposeModelProxy(TreePath path) { - IModelProxy proxy = fTreeModelProxies.remove(path); - if (proxy != null) { - proxy.dispose(); - } - proxy = fModelProxies.remove(path.getLastSegment()); - if (proxy != null) { - proxy.dispose(); - } - } + proxy.dispose(); + } + fTreeModelProxies.clear(); + } + + /** + * Removes the model proxy installed for the given element, if any. + * @param path the {@link TreePath} to dispose the model proxy for + */ + private void disposeModelProxy(TreePath path) { + IModelProxy proxy = fTreeModelProxies.remove(path); + if (proxy != null) { + proxy.dispose(); + } + proxy = fModelProxies.remove(path.getLastSegment()); + if (proxy != null) { + proxy.dispose(); + } + } private static class DelayedDoModelChange { public final IModelDelta delta; @@ -488,280 +488,280 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon private final DelayedDoModelChangedJob fDelayedDoModelChangeJob = new DelayedDoModelChangedJob(); - @Override + @Override public void modelChanged(final IModelDelta delta, final IModelProxy proxy) { - Display display = null; - - // Check if the viewer is still available, i.e. if the content provider - // is not disposed. - synchronized(this) { - if (fViewer != null && !proxy.isDisposed()) { - display = fViewer.getDisplay(); - } - } - if (display != null) { - // If we're in display thread, process the delta immediately to - // avoid "skid" in processing events. - if (Thread.currentThread().equals(display.getThread())) { - doModelChanged(delta, proxy); - } - else { + Display display = null; + + // Check if the viewer is still available, i.e. if the content provider + // is not disposed. + synchronized(this) { + if (fViewer != null && !proxy.isDisposed()) { + display = fViewer.getDisplay(); + } + } + if (display != null) { + // If we're in display thread, process the delta immediately to + // avoid "skid" in processing events. + if (Thread.currentThread().equals(display.getThread())) { + doModelChanged(delta, proxy); + } + else { try { Job.getJobManager().join(ElementContentProvider.class, null); } catch (OperationCanceledException | InterruptedException e) { DebugUIPlugin.log(new Status(IStatus.WARNING, DebugUIPlugin.getUniqueIdentifier(), "Interrupted while waiting on ElementContentProvider jobs", e)); //$NON-NLS-1$ } fDelayedDoModelChangeJob.runDelayed(delta, proxy); - } - } - } - - /** - * Executes the model proxy in UI thread. - * @param delta Delta to process - * @param proxy Proxy that fired the delta. - */ - private void doModelChanged(IModelDelta delta, IModelProxy proxy) { - if (!proxy.isDisposed()) { - if (DebugUIPlugin.DEBUG_DELTAS && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("RECEIVED DELTA: " + delta.toString()); //$NON-NLS-1$ - } - - updateModel(delta, getModelDeltaMask()); - - // Initiate model update sequence before notifying of the model changed. - trigger(null); - - // Call model listeners after updating the viewer model. + } + } + } + + /** + * Executes the model proxy in UI thread. + * @param delta Delta to process + * @param proxy Proxy that fired the delta. + */ + private void doModelChanged(IModelDelta delta, IModelProxy proxy) { + if (!proxy.isDisposed()) { + if (DebugUIPlugin.DEBUG_DELTAS && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("RECEIVED DELTA: " + delta.toString()); //$NON-NLS-1$ + } + + updateModel(delta, getModelDeltaMask()); + + // Initiate model update sequence before notifying of the model changed. + trigger(null); + + // Call model listeners after updating the viewer model. for (IModelChangedListener iModelChangedListener : fModelListeners) { iModelChangedListener.modelChanged(delta, proxy); } - } - } + } + } - @Override + @Override public void setModelDeltaMask(int mask) { - fModelDeltaMask = mask; - } + fModelDeltaMask = mask; + } - @Override + @Override public int getModelDeltaMask() { - return fModelDeltaMask; - } + return fModelDeltaMask; + } - @Override + @Override public void updateModel(IModelDelta delta, int mask) { - // Processing deltas with null input leads to NPEs - // (Bug 380288 - NPE switching to the Breakpoints View) - if (getViewer() == null || getViewer().getInput() == null) { + // Processing deltas with null input leads to NPEs + // (Bug 380288 - NPE switching to the Breakpoints View) + if (getViewer() == null || getViewer().getInput() == null) { return; } fRevealPath = null; - IModelDelta[] deltaArray = new IModelDelta[] { delta }; - updateNodes(deltaArray, mask & (IModelDelta.REMOVED | IModelDelta.UNINSTALL)); - updateNodes(deltaArray, mask & ITreeModelContentProvider.UPDATE_MODEL_DELTA_FLAGS - & ~(IModelDelta.REMOVED | IModelDelta.UNINSTALL)); - updateNodes(deltaArray, mask & ITreeModelContentProvider.CONTROL_MODEL_DELTA_FLAGS); - - fStateTracker.checkIfRestoreComplete(); - } - - /** - * Returns a tree path for the node including the root element. - * - * @param node - * model delta - * @return corresponding tree path - */ - TreePath getFullTreePath(IModelDelta node) { + IModelDelta[] deltaArray = new IModelDelta[] { delta }; + updateNodes(deltaArray, mask & (IModelDelta.REMOVED | IModelDelta.UNINSTALL)); + updateNodes(deltaArray, mask & ITreeModelContentProvider.UPDATE_MODEL_DELTA_FLAGS + & ~(IModelDelta.REMOVED | IModelDelta.UNINSTALL)); + updateNodes(deltaArray, mask & ITreeModelContentProvider.CONTROL_MODEL_DELTA_FLAGS); + + fStateTracker.checkIfRestoreComplete(); + } + + /** + * Returns a tree path for the node including the root element. + * + * @param node + * model delta + * @return corresponding tree path + */ + TreePath getFullTreePath(IModelDelta node) { ArrayList<Object> list = new ArrayList<>(); - while (node.getParentDelta() != null) { - list.add(0, node.getElement()); - node = node.getParentDelta(); - } - return new TreePath(list.toArray()); - } - - /** - * Returns a tree path for the node, *not* including the root element. - * - * @param node - * model delta - * @return corresponding tree path - */ - TreePath getViewerTreePath(IModelDelta node) { + while (node.getParentDelta() != null) { + list.add(0, node.getElement()); + node = node.getParentDelta(); + } + return new TreePath(list.toArray()); + } + + /** + * Returns a tree path for the node, *not* including the root element. + * + * @param node + * model delta + * @return corresponding tree path + */ + TreePath getViewerTreePath(IModelDelta node) { ArrayList<Object> list = new ArrayList<>(); - IModelDelta parentDelta = node.getParentDelta(); - while (parentDelta != null) { - list.add(0, node.getElement()); - node = parentDelta; - parentDelta = node.getParentDelta(); - } - return new TreePath(list.toArray()); - } - - /** - * Returns the viewer this content provider is working for. - * - * @return viewer - */ - protected IInternalTreeModelViewer getViewer() { - synchronized(this) { - return fViewer; - } - } - - @Override + IModelDelta parentDelta = node.getParentDelta(); + while (parentDelta != null) { + list.add(0, node.getElement()); + node = parentDelta; + parentDelta = node.getParentDelta(); + } + return new TreePath(list.toArray()); + } + + /** + * Returns the viewer this content provider is working for. + * + * @return viewer + */ + protected IInternalTreeModelViewer getViewer() { + synchronized(this) { + return fViewer; + } + } + + @Override public int viewToModelIndex(TreePath parentPath, int index) { - return fTransform.viewToModelIndex(parentPath, index); - } + return fTransform.viewToModelIndex(parentPath, index); + } - @Override + @Override public int viewToModelCount(TreePath parentPath, int count) { - return fTransform.viewToModelCount(parentPath, count); - } + return fTransform.viewToModelCount(parentPath, count); + } - @Override + @Override public int modelToViewIndex(TreePath parentPath, int index) { - return fTransform.modelToViewIndex(parentPath, index); - } + return fTransform.modelToViewIndex(parentPath, index); + } - @Override + @Override public int modelToViewChildCount(TreePath parentPath, int count) { - return fTransform.modelToViewCount(parentPath, count); - } + return fTransform.modelToViewCount(parentPath, count); + } - @Override + @Override public boolean areTreeModelViewerFiltersApplicable(Object parentElement) { - ViewerFilter[] filters = fViewer.getFilters(); - if (filters.length > 0) { - for (int j = 0; j < filters.length; j++) { - if (filters[j] instanceof TreeModelViewerFilter && - ((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement)) - { - return true; - } - } - } - return false; - } - - @Override + ViewerFilter[] filters = fViewer.getFilters(); + if (filters.length > 0) { + for (int j = 0; j < filters.length; j++) { + if (filters[j] instanceof TreeModelViewerFilter && + ((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement)) + { + return true; + } + } + } + return false; + } + + @Override public boolean shouldFilter(Object parentElementOrTreePath, Object element) { - ViewerFilter[] filters = fViewer.getFilters(); - if (filters.length > 0) { - for (int j = 0; j < filters.length; j++) { - if (filters[j] instanceof TreeModelViewerFilter) { - // Skip the filter if not applicable to parent element - Object parentElement = parentElementOrTreePath instanceof TreePath - ? ((TreePath)parentElementOrTreePath).getLastSegment() : parentElementOrTreePath; - if (parentElement == null) { + ViewerFilter[] filters = fViewer.getFilters(); + if (filters.length > 0) { + for (int j = 0; j < filters.length; j++) { + if (filters[j] instanceof TreeModelViewerFilter) { + // Skip the filter if not applicable to parent element + Object parentElement = parentElementOrTreePath instanceof TreePath + ? ((TreePath)parentElementOrTreePath).getLastSegment() : parentElementOrTreePath; + if (parentElement == null) { parentElement = fViewer.getInput(); } - if (!((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement)) { - continue; - } - } - - if (!(filters[j].select((Viewer) fViewer, parentElementOrTreePath, element))) { - return true; - } - } - } - return false; - } - - @Override + if (!((TreeModelViewerFilter)filters[j]).isApplicable(fViewer, parentElement)) { + continue; + } + } + + if (!(filters[j].select((Viewer) fViewer, parentElementOrTreePath, element))) { + return true; + } + } + } + return false; + } + + @Override public void unmapPath(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - fTransform.clear(path); - cancelSubtreeUpdates(path); - } - - - boolean addFilteredIndex(TreePath parentPath, int index, Object element) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - return fTransform.addFilteredIndex(parentPath, index, element); - } - - void removeElementFromFilters(TreePath parentPath, int index) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - fTransform.removeElementFromFilters(parentPath, index); - } - - boolean removeElementFromFilters(TreePath parentPath, Object element) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - return fTransform.removeElementFromFilters(parentPath, element); - } - - void setModelChildCount(TreePath parentPath, int childCount) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - fTransform.setModelChildCount(parentPath, childCount); - } - - boolean isFiltered(TreePath parentPath, int index) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - return fTransform.isFiltered(parentPath, index); - } - - int[] getFilteredChildren(TreePath parent) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - return fTransform.getFilteredChildren(parent); - } - - void clearFilteredChild(TreePath parent, int modelIndex) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - fTransform.clear(parent, modelIndex); - } - - void clearFilters(TreePath parent) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - fTransform.clear(parent); - } - - /** - * Notification an update request has started - * - * @param update the update to notify about - */ - void updateStarted(ViewerUpdateMonitor update) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + fTransform.clear(path); + cancelSubtreeUpdates(path); + } + + + boolean addFilteredIndex(TreePath parentPath, int index, Object element) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + return fTransform.addFilteredIndex(parentPath, index, element); + } + + void removeElementFromFilters(TreePath parentPath, int index) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + fTransform.removeElementFromFilters(parentPath, index); + } + + boolean removeElementFromFilters(TreePath parentPath, Object element) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + return fTransform.removeElementFromFilters(parentPath, element); + } + + void setModelChildCount(TreePath parentPath, int childCount) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + fTransform.setModelChildCount(parentPath, childCount); + } + + boolean isFiltered(TreePath parentPath, int index) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + return fTransform.isFiltered(parentPath, index); + } + + int[] getFilteredChildren(TreePath parent) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + return fTransform.getFilteredChildren(parent); + } + + void clearFilteredChild(TreePath parent, int modelIndex) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + fTransform.clear(parent, modelIndex); + } + + void clearFilters(TreePath parent) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + fTransform.clear(parent); + } + + /** + * Notification an update request has started + * + * @param update the update to notify about + */ + void updateStarted(ViewerUpdateMonitor update) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(update.getSchedulingPath()); - if (requests == null) { + if (requests == null) { requests = new ArrayList<>(); - fRequestsInProgress.put(update.getSchedulingPath(), requests); - } - requests.add(update); - if (!fModelSequenceRunning) { - fModelSequenceRunning = true; - if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("MODEL SEQUENCE BEGINS"); //$NON-NLS-1$ - } - notifyUpdate(UPDATE_SEQUENCE_BEGINS, null); - } - if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("\tBEGIN - " + update); //$NON-NLS-1$ - } - notifyUpdate(UPDATE_BEGINS, update); - } - - /** - * Notification an update request has completed - * - * @param updates the updates to notify - */ + fRequestsInProgress.put(update.getSchedulingPath(), requests); + } + requests.add(update); + if (!fModelSequenceRunning) { + fModelSequenceRunning = true; + if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("MODEL SEQUENCE BEGINS"); //$NON-NLS-1$ + } + notifyUpdate(UPDATE_SEQUENCE_BEGINS, null); + } + if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("\tBEGIN - " + update); //$NON-NLS-1$ + } + notifyUpdate(UPDATE_BEGINS, update); + } + + /** + * Notification an update request has completed + * + * @param updates the updates to notify + */ void updatesComplete(final List<ViewerUpdateMonitor> updates) { - for (int i = 0; i < updates.size(); i++) { - ViewerUpdateMonitor update = updates.get(i); - notifyUpdate(UPDATE_COMPLETE, update); - if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("\tEND - " + update); //$NON-NLS-1$ - } - } - - // Wait a single cycle to allow viewer to queue requests triggered by completed updates. + for (int i = 0; i < updates.size(); i++) { + ViewerUpdateMonitor update = updates.get(i); + notifyUpdate(UPDATE_COMPLETE, update); + if (DebugUIPlugin.DEBUG_UPDATE_SEQUENCE && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("\tEND - " + update); //$NON-NLS-1$ + } + } + + // Wait a single cycle to allow viewer to queue requests triggered by completed updates. getViewer().getDisplay().asyncExec(() -> { if (isDisposed()) { return; @@ -811,355 +811,355 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } }); - } - - /** - * @return Returns true if there are outstanding updates in the viewer. - */ - boolean areRequestsPending() { - return !fRequestsInProgress.isEmpty() || !fWaitingRequests.isEmpty(); - } - - /** - * @return Returns the state tracker for the content provider. - */ - ViewerStateTracker getStateTracker() { - return fStateTracker; - } - - /** - * Notifies listeners about given update. - * @param type Type of update to call listeners with. - * @param update Update to notify about. - */ - private void notifyUpdate(final int type, final IViewerUpdate update) { - if (!fUpdateListeners.isEmpty()) { + } + + /** + * @return Returns true if there are outstanding updates in the viewer. + */ + boolean areRequestsPending() { + return !fRequestsInProgress.isEmpty() || !fWaitingRequests.isEmpty(); + } + + /** + * @return Returns the state tracker for the content provider. + */ + ViewerStateTracker getStateTracker() { + return fStateTracker; + } + + /** + * Notifies listeners about given update. + * @param type Type of update to call listeners with. + * @param update Update to notify about. + */ + private void notifyUpdate(final int type, final IViewerUpdate update) { + if (!fUpdateListeners.isEmpty()) { for (IViewerUpdateListener iViewerUpdateListener : fUpdateListeners) { final IViewerUpdateListener listener = iViewerUpdateListener; - SafeRunner.run(new ISafeRunnable() { - @Override + SafeRunner.run(new ISafeRunnable() { + @Override public void run() throws Exception { - switch (type) { - case UPDATE_SEQUENCE_BEGINS: - listener.viewerUpdatesBegin(); - break; - case UPDATE_SEQUENCE_COMPLETE: - listener.viewerUpdatesComplete(); - break; - case UPDATE_BEGINS: - listener.updateStarted(update); - break; - case UPDATE_COMPLETE: - listener.updateComplete(update); - break; + switch (type) { + case UPDATE_SEQUENCE_BEGINS: + listener.viewerUpdatesBegin(); + break; + case UPDATE_SEQUENCE_COMPLETE: + listener.viewerUpdatesComplete(); + break; + case UPDATE_BEGINS: + listener.updateStarted(update); + break; + case UPDATE_COMPLETE: + listener.updateComplete(update); + break; default: break; - } - } + } + } - @Override + @Override public void handleException(Throwable exception) { - DebugUIPlugin.log(exception); - } - }); - } - } - } - - /** - * Cancels outstanding updates for the element at given path and its - * children. - * @param path Path of element. - */ - private void cancelSubtreeUpdates(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + DebugUIPlugin.log(exception); + } + }); + } + } + } + + /** + * Cancels outstanding updates for the element at given path and its + * children. + * @param path Path of element. + */ + private void cancelSubtreeUpdates(TreePath path) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); for (Entry<TreePath, List<ViewerUpdateMonitor>> entry : fRequestsInProgress.entrySet()) { - TreePath entryPath = entry.getKey(); - if (entryPath.startsWith(path, null)) { + TreePath entryPath = entry.getKey(); + if (entryPath.startsWith(path, null)) { List<ViewerUpdateMonitor> requests = entry.getValue(); Iterator<ViewerUpdateMonitor> reqIter = requests.iterator(); - while (reqIter.hasNext()) { - // Cancel update and remove from requests list. Removing from - // fRequestsInProgress ensures that isRequestBlocked() won't be triggered - // by a canceled update. + while (reqIter.hasNext()) { + // Cancel update and remove from requests list. Removing from + // fRequestsInProgress ensures that isRequestBlocked() won't be triggered + // by a canceled update. reqIter.next().cancel(); - reqIter.remove(); - } - } - } + reqIter.remove(); + } + } + } List<TreePath> purge = new ArrayList<>(); for (TreePath entryPath : fWaitingRequests.keySet()) { - if (entryPath.startsWith(path, null)) { - purge.add(entryPath); - } - } + if (entryPath.startsWith(path, null)) { + purge.add(entryPath); + } + } for (TreePath tp : purge) { fWaitingRequests.remove(tp); - } + } - fStateTracker.cancelStateSubtreeUpdates(path); - } + fStateTracker.cancelStateSubtreeUpdates(path); + } - /** - * Returns whether this given request should be run, or should wait for - * parent update to complete. - * - * @param update the update the schedule - */ - private void schedule(final ViewerUpdateMonitor update) { - Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); + /** + * Returns whether this given request should be run, or should wait for + * parent update to complete. + * + * @param update the update the schedule + */ + private void schedule(final ViewerUpdateMonitor update) { + Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); - TreePath schedulingPath = update.getSchedulingPath(); + TreePath schedulingPath = update.getSchedulingPath(); List<ViewerUpdateMonitor> requests = fWaitingRequests.get(schedulingPath); - if (requests == null) { + if (requests == null) { requests = new LinkedList<>(); - requests.add(update); - fWaitingRequests.put(schedulingPath, requests); + requests.add(update); + fWaitingRequests.put(schedulingPath, requests); List<ViewerUpdateMonitor> inProgressList = fRequestsInProgress.get(schedulingPath); - if (inProgressList != null) { - int staleUpdateIndex = inProgressList.indexOf(update); - if (staleUpdateIndex >= 0) { - // Cancel update and remove from requests list. Removing from - // fRequestsInProgress ensures that isRequestBlocked() won't be triggered - // by a canceled update. - ViewerUpdateMonitor staleUpdate = inProgressList.remove(staleUpdateIndex); - staleUpdate.cancel(); - // Note: Do not reset the inProgressList to null. This would cause the - // updateStarted() method to think that a new update sequence is - // being started. Since there are waiting requests for this scheduling - // path, the list will be cleaned up later. - } - } - if (inProgressList == null || inProgressList.isEmpty()) { + if (inProgressList != null) { + int staleUpdateIndex = inProgressList.indexOf(update); + if (staleUpdateIndex >= 0) { + // Cancel update and remove from requests list. Removing from + // fRequestsInProgress ensures that isRequestBlocked() won't be triggered + // by a canceled update. + ViewerUpdateMonitor staleUpdate = inProgressList.remove(staleUpdateIndex); + staleUpdate.cancel(); + // Note: Do not reset the inProgressList to null. This would cause the + // updateStarted() method to think that a new update sequence is + // being started. Since there are waiting requests for this scheduling + // path, the list will be cleaned up later. + } + } + if (inProgressList == null || inProgressList.isEmpty()) { getViewer().getDisplay().asyncExec(() -> { if (isDisposed()) { return; } trigger(update.getSchedulingPath()); }); - } - } else { - // there are waiting requests: coalesce with existing request and add to list - requests.add(coalesce(requests, update)); - } - } - - /** - * Tries to coalesce the given request with any request in the list. If a match is found, - * the resulting request is then coalesced again with candidates in list. - * @param requests List of waiting requests to coalesce with - * @param toCoalesce request to coalesce - * @return Returns either the coalesced request. If no match was found it returns the - * toCoalesce parameter request. Either way the returned request needs to be added to the - * waiting requests list. - */ + } + } else { + // there are waiting requests: coalesce with existing request and add to list + requests.add(coalesce(requests, update)); + } + } + + /** + * Tries to coalesce the given request with any request in the list. If a match is found, + * the resulting request is then coalesced again with candidates in list. + * @param requests List of waiting requests to coalesce with + * @param toCoalesce request to coalesce + * @return Returns either the coalesced request. If no match was found it returns the + * toCoalesce parameter request. Either way the returned request needs to be added to the + * waiting requests list. + */ private ViewerUpdateMonitor coalesce(List<ViewerUpdateMonitor> requests, ViewerUpdateMonitor toCoalesce) { for (ViewerUpdateMonitor waiting : requests) { - if (waiting.coalesce(toCoalesce)) { - requests.remove(waiting); - // coalesced with existing request, done - // try to coalesce the combined requests with other waiting requests - return coalesce(requests, waiting); - } - } - return toCoalesce; - } - - /** - * Returns whether there are outstanding ChildrenUpdate updates for the given path. - * This method is expected to be called during processing of a ChildrenRequest, - * therefore one running children request is ignored. - * @param path Path of element to check. - * @return True if there are outstanding children updates for given element. - */ - boolean areChildrenUpdatesPending(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + if (waiting.coalesce(toCoalesce)) { + requests.remove(waiting); + // coalesced with existing request, done + // try to coalesce the combined requests with other waiting requests + return coalesce(requests, waiting); + } + } + return toCoalesce; + } + + /** + * Returns whether there are outstanding ChildrenUpdate updates for the given path. + * This method is expected to be called during processing of a ChildrenRequest, + * therefore one running children request is ignored. + * @param path Path of element to check. + * @return True if there are outstanding children updates for given element. + */ + boolean areChildrenUpdatesPending(TreePath path) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); List<ViewerUpdateMonitor> requests = fWaitingRequests.get(path); - if (requests != null) { - for (int i = 0; i < requests.size(); i++) { - if (requests.get(i) instanceof ChildrenUpdate) { - return true; - } - } - } - requests = fRequestsInProgress.get(path); - if (requests != null) { - int numChildrenUpdateRequests = 0; - for (int i = 0; i < requests.size(); i++) { - if (requests.get(i) instanceof ChildrenUpdate) { - if (++numChildrenUpdateRequests > 1) { - return true; - } - } - } - } - return false; - } - - /** - * Triggers waiting requests based on the given request that just - * completed. - * <p> - * Requests are processed in order such that updates to - * children are delayed until updates for parent elements are completed. - * This allows the expansion/selection state of the elements to be - * properly restored as new elements are retrieved from model. - * </p> - * @param schedulingPath schedulingPath path or requests to start processing. May - * be <code>null</code> to start the shortest path request. - */ - private void trigger(TreePath schedulingPath) { - Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); - - if (fWaitingRequests.isEmpty()) { - return; - } + if (requests != null) { + for (int i = 0; i < requests.size(); i++) { + if (requests.get(i) instanceof ChildrenUpdate) { + return true; + } + } + } + requests = fRequestsInProgress.get(path); + if (requests != null) { + int numChildrenUpdateRequests = 0; + for (int i = 0; i < requests.size(); i++) { + if (requests.get(i) instanceof ChildrenUpdate) { + if (++numChildrenUpdateRequests > 1) { + return true; + } + } + } + } + return false; + } + + /** + * Triggers waiting requests based on the given request that just + * completed. + * <p> + * Requests are processed in order such that updates to + * children are delayed until updates for parent elements are completed. + * This allows the expansion/selection state of the elements to be + * properly restored as new elements are retrieved from model. + * </p> + * @param schedulingPath schedulingPath path or requests to start processing. May + * be <code>null</code> to start the shortest path request. + */ + private void trigger(TreePath schedulingPath) { + Assert.isTrue(getViewer().getDisplay().getThread() == Thread.currentThread()); + + if (fWaitingRequests.isEmpty()) { + return; + } List<ViewerUpdateMonitor> waiting = fWaitingRequests.get(schedulingPath); - if (waiting == null) { - // no waiting, update the entry with the shortest path - int length = Integer.MAX_VALUE; + if (waiting == null) { + // no waiting, update the entry with the shortest path + int length = Integer.MAX_VALUE; Entry<TreePath, List<ViewerUpdateMonitor>> candidate = null; for (Entry<TreePath, List<ViewerUpdateMonitor>> entry : fWaitingRequests.entrySet()) { - TreePath key = entry.getKey(); - if (key.getSegmentCount() < length && !isRequestBlocked(key)) { - candidate = entry; - length = key.getSegmentCount(); - } - } - if (candidate != null) { - startHighestPriorityRequest(candidate.getKey(), candidate.getValue()); - } - } else if (!isRequestBlocked(schedulingPath)) { - // start the highest priority request - startHighestPriorityRequest(schedulingPath, waiting); - } - } - - /** - * Returns true if there are running requests for any parent element of - * the given tree path. - * @param requestPath Path of element to check. - * @return Returns true if requests are running. - */ - private boolean isRequestBlocked(TreePath requestPath) { - TreePath parentPath = requestPath; + TreePath key = entry.getKey(); + if (key.getSegmentCount() < length && !isRequestBlocked(key)) { + candidate = entry; + length = key.getSegmentCount(); + } + } + if (candidate != null) { + startHighestPriorityRequest(candidate.getKey(), candidate.getValue()); + } + } else if (!isRequestBlocked(schedulingPath)) { + // start the highest priority request + startHighestPriorityRequest(schedulingPath, waiting); + } + } + + /** + * Returns true if there are running requests for any parent element of + * the given tree path. + * @param requestPath Path of element to check. + * @return Returns true if requests are running. + */ + private boolean isRequestBlocked(TreePath requestPath) { + TreePath parentPath = requestPath; List<ViewerUpdateMonitor> parentRequests = fRequestsInProgress.get(parentPath); - while (parentRequests == null || parentRequests.isEmpty()) { - parentPath = parentPath.getParentPath(); - if (parentPath == null) { - // no running requests: start request - return false; - } - parentRequests = fRequestsInProgress.get(parentPath); - } - return true; - } - - /** - * @param key the {@link TreePath} - * @param waiting the list of waiting requests - */ + while (parentRequests == null || parentRequests.isEmpty()) { + parentPath = parentPath.getParentPath(); + if (parentPath == null) { + // no running requests: start request + return false; + } + parentRequests = fRequestsInProgress.get(parentPath); + } + return true; + } + + /** + * @param key the {@link TreePath} + * @param waiting the list of waiting requests + */ private void startHighestPriorityRequest(TreePath key, List<ViewerUpdateMonitor> waiting) { - int priority = 4; - ViewerUpdateMonitor next = null; + int priority = 4; + ViewerUpdateMonitor next = null; for (ViewerUpdateMonitor vu : waiting) { - if (vu.getPriority() < priority) { - next = vu; - priority = next.getPriority(); - } - } - if (next != null) { - waiting.remove(next); - if (waiting.isEmpty()) { - fWaitingRequests.remove(key); - } - next.start(); - } - } - - /** - * Returns the element corresponding to the given tree path. - * - * @param path - * tree path - * @return model element - */ - protected Object getElement(TreePath path) { - if (path.getSegmentCount() > 0) { - return path.getLastSegment(); - } - return getViewer().getInput(); - } - - /** - * Reschedule any children updates in progress for the given parent that - * have a start index greater than the given index. An element has been - * removed at this index, invalidating updates in progress. - * - * @param parentPath - * view tree path to parent element - * @param modelIndex - * index at which an element was removed - */ - private void rescheduleUpdates(TreePath parentPath, int modelIndex) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + if (vu.getPriority() < priority) { + next = vu; + priority = next.getPriority(); + } + } + if (next != null) { + waiting.remove(next); + if (waiting.isEmpty()) { + fWaitingRequests.remove(key); + } + next.start(); + } + } + + /** + * Returns the element corresponding to the given tree path. + * + * @param path + * tree path + * @return model element + */ + protected Object getElement(TreePath path) { + if (path.getSegmentCount() > 0) { + return path.getLastSegment(); + } + return getViewer().getInput(); + } + + /** + * Reschedule any children updates in progress for the given parent that + * have a start index greater than the given index. An element has been + * removed at this index, invalidating updates in progress. + * + * @param parentPath + * view tree path to parent element + * @param modelIndex + * index at which an element was removed + */ + private void rescheduleUpdates(TreePath parentPath, int modelIndex) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); List<ViewerUpdateMonitor> requests = fRequestsInProgress.get(parentPath); List<IChildrenUpdate> reCreate = null; - if (requests != null) { + if (requests != null) { Iterator<ViewerUpdateMonitor> iterator = requests.iterator(); - while (iterator.hasNext()) { + while (iterator.hasNext()) { ViewerUpdateMonitor update = iterator.next(); - if (update instanceof IChildrenUpdate) { - IChildrenUpdate childrenUpdate = (IChildrenUpdate) update; - if (childrenUpdate.getOffset() > modelIndex) { - // Cancel update and remove from requests list. Removing from - // fRequestsInProgress ensures that isRequestBlocked() won't be triggered - // by a canceled update. - childrenUpdate.cancel(); - iterator.remove(); - if (reCreate == null) { + if (update instanceof IChildrenUpdate) { + IChildrenUpdate childrenUpdate = (IChildrenUpdate) update; + if (childrenUpdate.getOffset() > modelIndex) { + // Cancel update and remove from requests list. Removing from + // fRequestsInProgress ensures that isRequestBlocked() won't be triggered + // by a canceled update. + childrenUpdate.cancel(); + iterator.remove(); + if (reCreate == null) { reCreate = new ArrayList<>(); - } - reCreate.add(childrenUpdate); - if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("canceled update in progress handling REMOVE: " + childrenUpdate); //$NON-NLS-1$ - } - } - } - } - } - requests = fWaitingRequests.get(parentPath); - if (requests != null) { + } + reCreate.add(childrenUpdate); + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("canceled update in progress handling REMOVE: " + childrenUpdate); //$NON-NLS-1$ + } + } + } + } + } + requests = fWaitingRequests.get(parentPath); + if (requests != null) { for (ViewerUpdateMonitor update : requests) { - if (update instanceof IChildrenUpdate) { - IChildrenUpdate childrenUpdate = (IChildrenUpdate) update; - if (childrenUpdate.getOffset() > modelIndex) { - ((ChildrenUpdate) childrenUpdate).setOffset(childrenUpdate.getOffset() - 1); - if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("modified waiting update handling REMOVE: " + childrenUpdate); //$NON-NLS-1$ - } - } - } - } - } - // re-schedule canceled updates at new position. - // have to do this last else the requests would be waiting and - // get modified. - if (reCreate != null) { + if (update instanceof IChildrenUpdate) { + IChildrenUpdate childrenUpdate = (IChildrenUpdate) update; + if (childrenUpdate.getOffset() > modelIndex) { + ((ChildrenUpdate) childrenUpdate).setOffset(childrenUpdate.getOffset() - 1); + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("modified waiting update handling REMOVE: " + childrenUpdate); //$NON-NLS-1$ + } + } + } + } + } + // re-schedule canceled updates at new position. + // have to do this last else the requests would be waiting and + // get modified. + if (reCreate != null) { for (IChildrenUpdate childrenUpdate : reCreate) { - int start = childrenUpdate.getOffset() - 1; - int end = start + childrenUpdate.getLength(); - for (int i = start; i < end; i++) { - doUpdateElement(parentPath, i); - } - } - } - } + int start = childrenUpdate.getOffset() - 1; + int end = start + childrenUpdate.getLength(); + for (int i = start; i < end; i++) { + doUpdateElement(parentPath, i); + } + } + } + } private void doUpdateChildCount(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); Object element = getElement(path); IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(element); @@ -1170,7 +1170,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } void doUpdateElement(TreePath parentPath, int modelIndex) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); Object parent = getElement(parentPath); IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(parent); @@ -1181,7 +1181,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } private void doUpdateHasChildren(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); Object element = getElement(path); IElementContentProvider contentAdapter = ViewerAdapterService.getContentProvider(element); @@ -1197,73 +1197,73 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @param path Path of element to check. * @return Returns true if there are outstanding updates. */ - boolean areElementUpdatesPending(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + boolean areElementUpdatesPending(TreePath path) { + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); - TreePath parentPath = path.getParentPath(); + TreePath parentPath = path.getParentPath(); List<ViewerUpdateMonitor> requests = fWaitingRequests.get(path); - if (requests != null) { - for (int i = 0; i < requests.size(); i++) { - ViewerUpdateMonitor update = requests.get(i); - if (update instanceof ChildrenUpdate) { - return true; - } - } - } - requests = fWaitingRequests.get(parentPath); - if (requests != null) { - for (int i = 0; i < requests.size(); i++) { - ViewerUpdateMonitor update = requests.get(i); - if (update.containsUpdate(path)) { - return true; - } - } - } - requests = fRequestsInProgress.get(path); - if (requests != null) { - for (int i = 0; i < requests.size(); i++) { - ViewerUpdateMonitor update = requests.get(i); - if (update instanceof ChildrenUpdate) { - return true; - } - } - } - requests = fRequestsInProgress.get(parentPath); - if (requests != null) { - for (int i = 0; i < requests.size(); i++) { - ViewerUpdateMonitor update = requests.get(i); - if (update.getElement().equals(path.getLastSegment())) { - return true; - } - } - } - return false; - } - - /** - * Returns the presentation context for this content provider. - * - * @return presentation context - */ + if (requests != null) { + for (int i = 0; i < requests.size(); i++) { + ViewerUpdateMonitor update = requests.get(i); + if (update instanceof ChildrenUpdate) { + return true; + } + } + } + requests = fWaitingRequests.get(parentPath); + if (requests != null) { + for (int i = 0; i < requests.size(); i++) { + ViewerUpdateMonitor update = requests.get(i); + if (update.containsUpdate(path)) { + return true; + } + } + } + requests = fRequestsInProgress.get(path); + if (requests != null) { + for (int i = 0; i < requests.size(); i++) { + ViewerUpdateMonitor update = requests.get(i); + if (update instanceof ChildrenUpdate) { + return true; + } + } + } + requests = fRequestsInProgress.get(parentPath); + if (requests != null) { + for (int i = 0; i < requests.size(); i++) { + ViewerUpdateMonitor update = requests.get(i); + if (update.getElement().equals(path.getLastSegment())) { + return true; + } + } + } + return false; + } + + /** + * Returns the presentation context for this content provider. + * + * @return presentation context + */ protected IPresentationContext getPresentationContext() { - ITreeModelViewer viewer = getViewer(); - if (viewer != null) { - return viewer.getPresentationContext(); - } - return null; - } - - /** - * Updates the viewer with the following deltas. - * - * @param nodes Model deltas to be processed. - * @param mask the model delta mask - * @see IModelDelta for a list of masks - */ - protected void updateNodes(IModelDelta[] nodes, int mask) { - for (int i = 0; i < nodes.length; i++) { - IModelDelta node = nodes[i]; - int flags = node.getFlags() & mask; + ITreeModelViewer viewer = getViewer(); + if (viewer != null) { + return viewer.getPresentationContext(); + } + return null; + } + + /** + * Updates the viewer with the following deltas. + * + * @param nodes Model deltas to be processed. + * @param mask the model delta mask + * @see IModelDelta for a list of masks + */ + protected void updateNodes(IModelDelta[] nodes, int mask) { + for (int i = 0; i < nodes.length; i++) { + IModelDelta node = nodes[i]; + int flags = node.getFlags() & mask; if (flags != 0) { if ((flags & IModelDelta.ADDED) != 0) { handleAdd(node); @@ -1301,36 +1301,36 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if ((flags & IModelDelta.REVEAL) != 0) { handleReveal(node); } - } - updateNodes(node.getChildDeltas(), mask); - } - } + } + updateNodes(node.getChildDeltas(), mask); + } + } - protected void handleInstall(IModelDelta delta) { - installModelProxy(getViewer().getInput(), getFullTreePath(delta)); - } + protected void handleInstall(IModelDelta delta) { + installModelProxy(getViewer().getInput(), getFullTreePath(delta)); + } - protected void handleUninstall(IModelDelta delta) { - disposeModelProxy(getFullTreePath(delta)); - } + protected void handleUninstall(IModelDelta delta) { + disposeModelProxy(getFullTreePath(delta)); + } - protected void handleAdd(IModelDelta delta) { + protected void handleAdd(IModelDelta delta) { IModelDelta parentDelta = delta.getParentDelta(); if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; } TreePath parentPath = getViewerTreePath(parentDelta); Object element = delta.getElement(); int count = parentDelta.getChildCount(); if (count > 0) { - setModelChildCount(parentPath, count); - int modelIndex = count - 1; - if (delta.getIndex() != -1) { - // assume addition at end, unless index specified by delta - modelIndex = delta.getIndex(); - } + setModelChildCount(parentPath, count); + int modelIndex = count - 1; + if (delta.getIndex() != -1) { + // assume addition at end, unless index specified by delta + modelIndex = delta.getIndex(); + } if (shouldFilter(parentPath, element)) { addFilteredIndex(parentPath, modelIndex, element); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { @@ -1341,7 +1341,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (isFiltered(parentPath, modelIndex)) { clearFilteredChild(parentPath, modelIndex); } - int viewIndex = modelToViewIndex(parentPath, modelIndex); + int viewIndex = modelToViewIndex(parentPath, modelIndex); int viewCount = modelToViewChildCount(parentPath, count); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { DebugUIPlugin.trace("handleAdd(" + delta.getElement() + ") viewIndex: " + viewIndex + " modelIndex: " + modelIndex + " viewCount: " + viewCount + " modelCount: " + count); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ @@ -1357,11 +1357,11 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { DebugUIPlugin.trace("handleAdd(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } - doUpdateChildCount(getViewerTreePath(delta.getParentDelta())); + doUpdateChildCount(getViewerTreePath(delta.getParentDelta())); } } - protected void handleContent(IModelDelta delta) { + protected void handleContent(IModelDelta delta) { if (delta.getParentDelta() == null && delta.getChildCount() == 0) { // if the delta is for the root, ensure the root still matches viewer input if (!delta.getElement().equals(getViewer().getInput())) { @@ -1373,13 +1373,13 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon getViewer().refresh(getElement(treePath)); } - protected void handleCollapse(IModelDelta delta) { + protected void handleCollapse(IModelDelta delta) { TreePath elementPath = getViewerTreePath(delta); getViewer().setExpandedState(elementPath, false); - cancelRestore(elementPath, IModelDelta.EXPAND); + cancelRestore(elementPath, IModelDelta.EXPAND); } - protected void handleExpand(IModelDelta delta) { + protected void handleExpand(IModelDelta delta) { // expand each parent, then this node IModelDelta parentDelta = delta.getParentDelta(); if (parentDelta != null) { @@ -1388,22 +1388,22 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } expand(delta); } else { - int childCount = delta.getChildCount(); - TreePath elementPath = getViewerTreePath(delta); - if (childCount > 0) { - int viewCount = modelToViewChildCount(elementPath, childCount); - if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { - DebugUIPlugin.trace("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - getViewer().setChildCount(elementPath, viewCount); - } - } - } - - /** - * Expands the element pointed to by given delta. - * @param delta Delta that points to the element to expand. - */ + int childCount = delta.getChildCount(); + TreePath elementPath = getViewerTreePath(delta); + if (childCount > 0) { + int viewCount = modelToViewChildCount(elementPath, childCount); + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { + DebugUIPlugin.trace("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + getViewer().setChildCount(elementPath, viewCount); + } + } + } + + /** + * Expands the element pointed to by given delta. + * @param delta Delta that points to the element to expand. + */ private void expand(IModelDelta delta) { int childCount = delta.getChildCount(); int modelIndex = delta.getIndex(); @@ -1435,9 +1435,9 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon DebugUIPlugin.trace("[expand] setChildCount(" + delta.getElement() + ", (model) " + childCount + " (view) " + viewCount); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } treeViewer.setChildCount(elementPath, viewCount); - if (!treeViewer.getExpandedState(elementPath)) { - treeViewer.expandToLevel(elementPath, 1); - } + if (!treeViewer.getExpandedState(elementPath)) { + treeViewer.expandToLevel(elementPath, 1); + } cancelRestore(elementPath, IModelDelta.COLLAPSE); } } @@ -1451,7 +1451,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @param element element to insert * @param modelIndex index of the element in the model * @return Returns the view index of the newly inserted element - * or -1 if not inserted. + * or -1 if not inserted. */ private int unfilterElement(TreePath parentPath, Object element, int modelIndex) { // Element is filtered - if no longer filtered, insert the element @@ -1478,11 +1478,11 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } protected void handleInsert(IModelDelta delta) { - IModelDelta parentDelta = delta.getParentDelta(); - if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; - } + IModelDelta parentDelta = delta.getParentDelta(); + if (parentDelta == null) { + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } TreePath parentPath = getViewerTreePath(delta.getParentDelta()); Object element = delta.getElement(); @@ -1505,7 +1505,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { DebugUIPlugin.trace("handleInsert(" + delta.getElement() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } - doUpdateChildCount(getViewerTreePath(delta.getParentDelta())); + doUpdateChildCount(getViewerTreePath(delta.getParentDelta())); } } @@ -1515,8 +1515,8 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } IModelDelta parentDelta = delta.getParentDelta(); if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; } IInternalTreeModelViewer treeViewer = getViewer(); TreePath parentPath = getViewerTreePath(parentDelta); @@ -1530,16 +1530,16 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon int unmappedIndex = -1; int itemCount = -1; if (modelIndex < 0) { - itemCount = treeViewer.getChildCount(parentPath); - if (itemCount == -1) { - clearFilters(parentPath); - } - viewIndex = treeViewer.findElementIndex(parentPath, element); - if (viewIndex >= 0) { - modelIndex = viewToModelIndex(parentPath, viewIndex); - } else { - unmappedIndex = treeViewer.findElementIndex(parentPath, null); - } + itemCount = treeViewer.getChildCount(parentPath); + if (itemCount == -1) { + clearFilters(parentPath); + } + viewIndex = treeViewer.findElementIndex(parentPath, element); + if (viewIndex >= 0) { + modelIndex = viewToModelIndex(parentPath, viewIndex); + } else { + unmappedIndex = treeViewer.findElementIndex(parentPath, null); + } } else { viewIndex = modelToViewIndex(parentPath, modelIndex); } @@ -1583,41 +1583,41 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } protected void handleReplace(IModelDelta delta) { - IModelDelta parentDelta = delta.getParentDelta(); - if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; - } + IModelDelta parentDelta = delta.getParentDelta(); + if (parentDelta == null) { + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } TreePath parentPath = getViewerTreePath(parentDelta); int index = delta.getIndex(); if (index < 0) { - index = fTransform.indexOfFilteredElement(parentPath, delta.getElement()); + index = fTransform.indexOfFilteredElement(parentPath, delta.getElement()); } if (index >= 0) { - boolean filtered = isFiltered(parentPath, index); - boolean shouldFilter = shouldFilter(parentPath, delta.getReplacementElement()); - - // Update the filter transform - if (filtered) { - clearFilteredChild(parentPath, index); - } - if (shouldFilter) { - addFilteredIndex(parentPath, index, delta.getElement()); - } - - // Update the viewer - if (filtered) { - if (!shouldFilter) { - getViewer().insert(parentPath, delta.getReplacementElement(), modelToViewIndex(parentPath, index)); - } - //else do nothing - } else { - if (shouldFilter) { - getViewer().remove(parentPath, modelToViewIndex(parentPath, index)); - } else { - getViewer().replace(parentPath, delta.getIndex(), delta.getReplacementElement()); - } - } + boolean filtered = isFiltered(parentPath, index); + boolean shouldFilter = shouldFilter(parentPath, delta.getReplacementElement()); + + // Update the filter transform + if (filtered) { + clearFilteredChild(parentPath, index); + } + if (shouldFilter) { + addFilteredIndex(parentPath, index, delta.getElement()); + } + + // Update the viewer + if (filtered) { + if (!shouldFilter) { + getViewer().insert(parentPath, delta.getReplacementElement(), modelToViewIndex(parentPath, index)); + } + //else do nothing + } else { + if (shouldFilter) { + getViewer().remove(parentPath, modelToViewIndex(parentPath, index)); + } else { + getViewer().replace(parentPath, delta.getIndex(), delta.getReplacementElement()); + } + } } } @@ -1627,18 +1627,18 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon // check if selection is allowed IStructuredSelection candidate = new TreeSelection(getViewerTreePath(delta)); if ((delta.getFlags() & IModelDelta.FORCE) == 0 && - !treeViewer.overrideSelection(treeViewer.getSelection(), candidate)) + !treeViewer.overrideSelection(treeViewer.getSelection(), candidate)) { return; } // empty the selection before replacing elements to avoid materializing elements (@see bug 305739) treeViewer.clearSelectionQuiet(); if (modelIndex >= 0) { - IModelDelta parentDelta = delta.getParentDelta(); - if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; - } + IModelDelta parentDelta = delta.getParentDelta(); + if (parentDelta == null) { + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } TreePath parentPath = getViewerTreePath(parentDelta); int viewIndex = modelToViewIndex(parentPath, modelIndex); if (viewIndex >= 0) { @@ -1659,7 +1659,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } TreePath selectionPath = getViewerTreePath(delta); if (treeViewer.trySelection(new TreeSelection(selectionPath), false, (delta.getFlags() | IModelDelta.FORCE) == 0)) { - cancelRestore(selectionPath, IModelDelta.SELECT); + cancelRestore(selectionPath, IModelDelta.SELECT); } } @@ -1669,13 +1669,13 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon protected void handleReveal(IModelDelta delta) { IModelDelta parentDelta = delta.getParentDelta(); - if (parentDelta == null) { - DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ - return; - } - handleExpand(parentDelta); - reveal(delta); - cancelRestore(getViewerTreePath(delta), IModelDelta.REVEAL); + if (parentDelta == null) { + DebugUIPlugin.log(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), "Invalid viewer update: " + delta + ", in " + getPresentationContext().getId(), null )); //$NON-NLS-1$ //$NON-NLS-2$ + return; + } + handleExpand(parentDelta); + reveal(delta); + cancelRestore(getViewerTreePath(delta), IModelDelta.REVEAL); } /** @@ -1708,7 +1708,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon // only move tree based on force flag and selection policy if ((delta.getFlags() & IModelDelta.FORCE) != 0 || - treeViewer.overrideSelection(treeViewer.getSelection(), new TreeSelection(elementPath))) + treeViewer.overrideSelection(treeViewer.getSelection(), new TreeSelection(elementPath))) { /* * Bug 438724 - Save reveal parameters and redo reveal on @@ -1717,7 +1717,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon */ fRevealPath = parentPath; fRevealIndex = viewIndex; - treeViewer.reveal(parentPath, viewIndex); + treeViewer.reveal(parentPath, viewIndex); } } } @@ -1729,7 +1729,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon @Override public void updateChildCount(TreePath treePath, int currentChildCount) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { DebugUIPlugin.trace("updateChildCount(" + getElement(treePath) + ", " + currentChildCount + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ @@ -1739,7 +1739,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon @Override public void updateElement(TreePath parentPath, int viewIndex) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); int modelIndex = viewToModelIndex(parentPath, viewIndex); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { @@ -1750,7 +1750,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon @Override public void updateHasChildren(TreePath path) { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER && DebugUIPlugin.DEBUG_TEST_PRESENTATION_ID(getPresentationContext())) { DebugUIPlugin.trace("updateHasChildren(" + getElement(path)); //$NON-NLS-1$ @@ -1765,61 +1765,61 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon * @param update Update to perform. */ void scheduleViewerUpdate(ViewerUpdateMonitor update) { - Display display; - Runnable updateJob = null; - synchronized(this) { - if (isDisposed()) { + Display display; + Runnable updateJob = null; + synchronized(this) { + if (isDisposed()) { return; } - display = getViewer().getDisplay(); - fCompletedUpdates.add(update); - if (fCompletedUpdatesRunnable == null) { + display = getViewer().getDisplay(); + fCompletedUpdates.add(update); + if (fCompletedUpdatesRunnable == null) { fCompletedUpdatesRunnable = () -> { if (!isDisposed()) { performUpdates(); } }; - updateJob = fCompletedUpdatesRunnable; - } - } - - if (updateJob != null) { - if (Thread.currentThread() == display.getThread()) { - performUpdates(); - } else { + updateJob = fCompletedUpdatesRunnable; + } + } + + if (updateJob != null) { + if (Thread.currentThread() == display.getThread()) { + performUpdates(); + } else { fDelayedDoModelChangeJob.runDelayed(updateJob); - } - } + } + } } /** * Perform the updates pointed to by given array on the viewer. */ private void performUpdates() { - Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); + Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); List<ViewerUpdateMonitor> jobCompletedUpdates; - synchronized(this) { - if (isDisposed()) { - return; - } - jobCompletedUpdates = fCompletedUpdates; - fCompletedUpdatesRunnable = null; + synchronized(this) { + if (isDisposed()) { + return; + } + jobCompletedUpdates = fCompletedUpdates; + fCompletedUpdatesRunnable = null; fCompletedUpdates = new ArrayList<>(); - } - // necessary to check if viewer is disposed - try { - for (int i = 0; i < jobCompletedUpdates.size(); i++) { - ViewerUpdateMonitor completedUpdate = jobCompletedUpdates.get(i); - if (!completedUpdate.isCanceled() && !isDisposed()) { - IStatus status = completedUpdate.getStatus(); - if (status == null || status.isOK()) { - completedUpdate.performUpdate(); - } - } - } - } finally { - updatesComplete(jobCompletedUpdates); - } + } + // necessary to check if viewer is disposed + try { + for (int i = 0; i < jobCompletedUpdates.size(); i++) { + ViewerUpdateMonitor completedUpdate = jobCompletedUpdates.get(i); + if (!completedUpdate.isCanceled() && !isDisposed()) { + IStatus status = completedUpdate.getStatus(); + if (status == null || status.isOK()) { + completedUpdate.performUpdate(); + } + } + } + } finally { + updatesComplete(jobCompletedUpdates); + } } } |