diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java index 0e1ffd2c16b..63fcf21b0de 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/internal/ui/view/SystemView.java @@ -98,6 +98,7 @@ import org.eclipse.rse.core.model.ISystemMessageObject; import org.eclipse.rse.core.model.ISystemRegistry; import org.eclipse.rse.core.model.SystemMessageObject; import org.eclipse.rse.core.references.IRSEBaseReferencingObject; +import org.eclipse.rse.core.subsystems.IRemoteObjectIdentifier; import org.eclipse.rse.core.subsystems.ISubSystem; import org.eclipse.rse.internal.ui.SystemResources; import org.eclipse.rse.internal.ui.actions.SystemCascadingGoToAction; @@ -2824,6 +2825,7 @@ public class SystemView extends SafeTreeViewer rmtAdapter = getViewAdapter(remoteObject); if (rmtAdapter == null) return false; subsystem = rmtAdapter.getSubSystem(remoteObject); + assert subsystem!=null : "EVENT_REFRESH_REMOTE outside subsystem"; //$NON-NLS-1$ oldElementName = rmtAdapter.getAbsoluteName(remoteObject); doesDeferredQueries = rmtAdapter.supportsDeferredQueries(subsystem); } else @@ -2833,10 +2835,14 @@ public class SystemView extends SafeTreeViewer // STEP 2: find all references to the object findAllRemoteItemReferences(oldElementName, remoteObject, subsystem, matches); if (remoteObject instanceof String) { + //TODO one String may reference multiple different context objects, so we should really iterate over all matches here + //See javadoc of findAllRemoteItemReferences remoteObject = getFirstRemoteObject(matches); rmtAdapter = getViewAdapter(remoteObject); + assert rmtAdapter!=null; //cannot happen because matches were result of String query if (rmtAdapter!=null) { subsystem = rmtAdapter.getSubSystem(remoteObject); + assert subsystem!=null : "EVENT_REFRESH_REMOTE outside subsystem"; //$NON-NLS-1$ doesDeferredQueries = rmtAdapter.supportsDeferredQueries(subsystem); } } @@ -2904,7 +2910,8 @@ public class SystemView extends SafeTreeViewer } /** - * Given the result of findAllRemoteItemReferences, scan for first non-filter object + * Given the result TreeItems of findAllRemoteItemReferences, + * return the Data of the first Item. */ protected Object getFirstRemoteObject(Vector matches) { if ((matches == null) || (matches.size() == 0)) return null; @@ -4054,14 +4061,23 @@ public class SystemView extends SafeTreeViewer /** * Recursively tries to find all occurrences of a given remote object, starting at the tree root. * Since the object memory object for a remote object is not dependable we call getAbsoluteName() - * on the adapter to do the comparisons. + * on the adapter to do the comparisons. + *

+ * TODO: This method should not return any invalid matches, i.e. remote objects + * that do match the String identifier but have been deleted already. Because the + * same remote object can appear in multiple contexts in the RSE Tree, a single + * remote object identifier String may evaluate to multiple different matches + * to fill into the matches argument. All those context object matches, however, + * reference the same real-world model objects due to the constraint that + * {@link IRemoteObjectIdentifier} uniquely identifies a remote object. *

* This overload takes a string and a subsystem. * - * @param searchString the absolute name of the remote object to which we want to find a tree item which references it. + * @param searchString the absolute name of the remote object to which + * we want to find a tree item which references it. * @param elementObject the actual remote element to find, for binary matching * @param subsystem optional subsystem to search within - * @param matches the vector to populate with hits + * @param matches the vector to populate with hits (TreeItem objects) */ protected Vector findAllRemoteItemReferences(String searchString, Object elementObject, ISubSystem subsystem, Vector matches) { Tree tree = getTree(); diff --git a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java index 6205ad7e839..a1759414db3 100644 --- a/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java +++ b/rse/plugins/org.eclipse.rse.ui/UI/org/eclipse/rse/ui/view/ISystemViewElementAdapter.java @@ -177,28 +177,32 @@ public interface ISystemViewElementAdapter extends IPropertySource, ISystemDragD public Object getParent(Object element); /** - * Return the children of this model object. + * Return the children of this model object. + * + * When {@link #supportsDeferredQueries(ISubSystem)} returns false, + * this query will be called in the dispatch thread, so the implementation + * needs to make sure that SWT thread exceptions are avoided. + * * @param element the model object to query * @param monitor the progress monitor - * * @return the children of element - * - * The implementation needs to take this into - * account so that SWT thread exceptions are avoided. */ public Object[] getChildren(IAdaptable element, IProgressMonitor monitor); /** - * Return the children of this object. When a contextObject is passed in - * instead of an adaptable model object, the adapter needs handle both the model object - * as well as the associated filter. + * Return the children of this object. + * + * When a contextObject is passed in instead of an adaptable model + * object, the adapter needs handle both the model object as well + * as the associated filter. + * + * When {@link #supportsDeferredQueries(ISubSystem)} returns false, + * this query will be called in the dispatch thread, so the implementation + * needs to make sure that SWT thread exceptions are avoided. + * * @param contextObject a wrapper object that contains the model object plus context information * @param monitor the progress monitor - * * @return the children of the model object in contextObject that matches the filter in contextObject - * - * The implementation needs to take this into - * account so that SWT thread exceptions are avoided. */ public Object[] getChildren(IContextObject contextObject, IProgressMonitor monitor); @@ -208,12 +212,25 @@ public interface ISystemViewElementAdapter extends IPropertySource, ISystemDragD public Object[] getChildrenUsingExpandToFilter(Object element, String expandToFilter); /** - * Return true if this object has children + * Return true if this object has children. + *

+ * In case this adapter returns true for {@link #supportsDeferredQueries(ISubSystem)}, + * it is expected that the underlying subsystem caches the hasChildren() attribute + * such that it does not necessarily perform a server round trip. In this case, it + * has more the semantics of "can have children". In that case, + * a deferred {@link #getChildren(IAdaptable, IProgressMonitor)} + * call is still allowed to return an empty array indicating no children. + *

+ * @param element the element to check + * @return true if this element can have children. */ public boolean hasChildren(IAdaptable element); /** - * Return true if this object has children + * Return true if this object has children. + * @see #hasChildren(IAdaptable) + * @param element the element to check + * @return true if this element can have children. */ public boolean hasChildren(IContextObject element);