From 39834a77766568f15c099000d4da467a43780a85 Mon Sep 17 00:00:00 2001 From: Uwe Stieber Date: Tue, 22 Oct 2013 14:36:58 +0200 Subject: Target Explorer: Fix system monitor auto-refresh not working --- .../runtime/IRuntimeModelRefreshService.java | 27 ++++++ .../processes/core/model/runtime/RuntimeModel.java | 12 ++- .../services/RuntimeModelRefreshService.java | 106 +++++++++++++++++++-- .../services/RuntimeModelUpdateService.java | 22 ++++- .../ui/navigator/events/TreeViewerListener.java | 77 +++++++-------- 5 files changed, 190 insertions(+), 54 deletions(-) create mode 100644 target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelRefreshService.java (limited to 'target_explorer') diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelRefreshService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelRefreshService.java new file mode 100644 index 000000000..58966d510 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelRefreshService.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Wind River Systems, Inc. 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 http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime; + +import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; +import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelRefreshService; + +/** + * Interface to be implemented by processes runtime model refresh services. + */ +public interface IRuntimeModelRefreshService extends IModelRefreshService { + + /** + * Auto refresh the content of the model from the top. It search for + * all nodes with query state "done" and refresh them one by one. + * + * @param callback The callback to invoke once the refresh operation finished, or null. + */ + public void autoRefresh(ICallback callback); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java index 07c161af6..3d321e24b 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java @@ -32,6 +32,7 @@ import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelUpdateService import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModelLookupService; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModelRefreshService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelChannelService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelLookupService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelRefreshService; @@ -52,7 +53,7 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo private final IPeerModel peerModel; // Reference to the refresh service - private final IModelRefreshService refreshService = new RuntimeModelRefreshService(this); + private final IRuntimeModelRefreshService refreshService = new RuntimeModelRefreshService(this); // Reference to the lookup service private final IRuntimeModelLookupService lookupService = new RuntimeModelLookupService(this); // Reference to the update service @@ -131,6 +132,9 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo */ @Override public Object getAdapter(Class adapter) { + if (IRuntimeModelRefreshService.class.equals(adapter)) { + return refreshService; + } if (IModelRefreshService.class.equals(adapter)) { return refreshService; } @@ -208,7 +212,7 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo // Create the timer timer = new Timer(); - timer.schedule(task, this.interval); + timer.schedule(task, this.interval * 1000); } else if (interval == 0 && timer != null) { timer.cancel(); timer = null; @@ -235,7 +239,7 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo @Override public void run() { // Refresh the model - RuntimeModel.this.getService(IModelRefreshService.class).refresh(new Callback() { + RuntimeModel.this.getService(IRuntimeModelRefreshService.class).autoRefresh(new Callback() { @Override protected void internalDone(Object caller, IStatus status) { // Re-schedule ourself if the interval is still > 0 @@ -251,7 +255,7 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo } }; - timer.schedule(task, RuntimeModel.this.interval); + timer.schedule(task, RuntimeModel.this.interval * 1000); } } }); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java index 94ce299a0..d61cf2803 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java @@ -41,7 +41,6 @@ import org.eclipse.tcf.te.tcf.core.async.CallbackInvocationDelegate; import org.eclipse.tcf.te.tcf.core.model.interfaces.IModel; import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelChannelService; import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelLookupService; -import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelRefreshService; import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelUpdateService; import org.eclipse.tcf.te.tcf.core.model.services.AbstractModelService; import org.eclipse.tcf.te.tcf.processes.core.activator.CoreBundleActivator; @@ -49,12 +48,13 @@ import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNod import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode.TYPE; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNodeProperties; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModelRefreshService; import org.eclipse.tcf.te.tcf.processes.core.model.nodes.PendingOperationNode; /** * Runtime model refresh service implementation. */ -public class RuntimeModelRefreshService extends AbstractModelService implements IModelRefreshService { +public class RuntimeModelRefreshService extends AbstractModelService implements IRuntimeModelRefreshService { /** * Constructor. @@ -170,7 +170,101 @@ public class RuntimeModelRefreshService extends AbstractModelService children = model.getChildren(IProcessContextNode.class); + if (children.size() > 0) { + // Initiate the refresh of the children + doAutoRefresh(model, children.toArray(new IProcessContextNode[children.size()]), 0, collector); + } + + // Mark the collector initialization done + collector.initDone(); + } + + /** + * Performs the auto refresh of the given nodes. + * + * @param model The runtime model. Must not be null. + * @param nodes The nodes. Must not be null. + * @param index The index of the node to refresh within the nodes array. Must be greater or equal than 0 and less than the array length. + * @param collector The callback collector. Must not be null. + */ + protected void doAutoRefresh(final IRuntimeModel model, final IProcessContextNode[] nodes, final int index, final AsyncCallbackCollector collector) { + Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ + Assert.isNotNull(model); + Assert.isNotNull(nodes); + Assert.isTrue(index >= 0 && index < nodes.length); + Assert.isNotNull(collector); + + final IProcessContextNode node = nodes[index]; + + // Get the asynchronous refresh context adapter + final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); + if (refreshable != null) { + // Schedule a refresh if the node got refreshed before + if (refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.DONE)) { + // Create a new callback for the collector to wait for + final ICallback callback = new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + // We need a reference to the outer callback (== this) + final ICallback outerCallback = this; + // Create the inner callback + final ICallback innerCallback = new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + // More nodes to process? + int newIndex = index + 1; + if (newIndex < nodes.length) { + doAutoRefresh(model, nodes, newIndex, collector); + } + // Remove the outer callback from the collector + collector.removeCallback(outerCallback); + } + }; + + // If the node has children, process them first + List children = node.getChildren(IProcessContextNode.class); + if (children.size() > 0) { + // Create a new callback collector for processing the children + final AsyncCallbackCollector childCollector = new AsyncCallbackCollector(innerCallback, new CallbackInvocationDelegate()); + // Initiate the refresh of the children + doAutoRefresh(model, children.toArray(new IProcessContextNode[children.size()]), 0, childCollector); + // Mark the collector initialization done + childCollector.initDone(); + } else { + // Invoke the inner callback right away + innerCallback.done(this, Status.OK_STATUS); + } + } + }; + collector.addCallback(callback); + // Refresh the node (only node and the direct children) + doRefresh(model, node, 1, callback); + } + } } /** @@ -178,10 +272,10 @@ public class RuntimeModelRefreshService extends AbstractModelServicenull. * @param node The node. Must not be null. - * @param flags The flags. See the defined constants for details. + * @param depth Until which depth the tree gets refreshed. * @param callback The callback to invoke once the refresh operation finished, or null. */ - protected void doRefresh(final IRuntimeModel model, final IModelNode node, final int flags, final ICallback callback) { + protected void doRefresh(final IRuntimeModel model, final IModelNode node, final int depth, final ICallback callback) { Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ Assert.isNotNull(model); Assert.isNotNull(node); @@ -199,7 +293,7 @@ public class RuntimeModelRefreshService extends AbstractModelService oldChildren = ((IProcessContextNode)node).getChildren(IProcessContextNode.class); // Refresh the children of the process context node from the agent - refreshContextChildren(oldChildren, model, (IProcessContextNode)node, 2, new Callback() { + refreshContextChildren(oldChildren, model, (IProcessContextNode)node, depth, new Callback() { @Override protected void internalDone(Object caller, IStatus status) { final AtomicBoolean isDisposed = new AtomicBoolean(); diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java index 45dad363f..83720350d 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelUpdateService.java @@ -10,8 +10,10 @@ package org.eclipse.tcf.te.tcf.processes.core.model.runtime.services; import org.eclipse.core.runtime.Assert; +import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx; +import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx.QueryState; import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx.QueryType; import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelUpdateService; import org.eclipse.tcf.te.tcf.core.model.services.AbstractModelService; @@ -70,9 +72,23 @@ public class RuntimeModelUpdateService extends AbstractModelService