Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/ScannerRunnable.java')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/ScannerRunnable.java186
1 files changed, 186 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/ScannerRunnable.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/ScannerRunnable.java
new file mode 100644
index 000000000..b004a70ef
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/ScannerRunnable.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.locator;
+
+import java.net.SocketTimeoutException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.core.ChannelTCP;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IPeer;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.services.ILocator;
+import org.eclipse.tcf.te.tcf.locator.interfaces.IScanner;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties;
+import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelLookupService;
+import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelUpdateService;
+import org.eclipse.tcf.te.tcf.locator.nodes.PeerModel;
+
+
+/**
+ * Scanner runnable to be executed for each peer to probe within the
+ * TCF event dispatch thread.
+ */
+public class ScannerRunnable implements Runnable, IChannel.IChannelListener {
+ /**
+ * The default socket connect timeout in milliseconds.
+ */
+ private static final int DEFAULT_SOCKET_CONNECT_TIMEOUT = 10000;
+
+ // Reference to the parent model scanner
+ private final IScanner parentScanner;
+ // Reference to the peer model node to update
+ private final IPeerModel peerNode;
+ // Reference to the channel
+ private IChannel channel = null;
+
+ /**
+ * Constructor.
+ *
+ * @param scanner The parent model scanner or <code>null</code> if the runnable is constructed from outside a scanner.
+ * @param peerNode The peer model instance. Must not be <code>null</code>.
+ */
+ public ScannerRunnable(IScanner scanner, IPeerModel peerNode) {
+ super();
+
+ parentScanner = scanner;
+
+ Assert.isNotNull(peerNode);
+ this.peerNode = peerNode;
+ }
+
+ /**
+ * Returns the parent scanner instance.
+ *
+ * @return The parent scanner instance or <code>null</code>.
+ */
+ protected final IScanner getParentScanner() {
+ return parentScanner;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ if (peerNode != null && peerNode.getPeer() != null) {
+ // Open the channel
+ channel = peerNode.getPeer().openChannel();
+ // Configure the connect timeout
+ if (channel instanceof ChannelTCP) {
+ int timeout = peerNode.getIntProperty(IPeerModelProperties.PROP_CONNECT_TIMEOUT);
+ if (timeout == -1) timeout = DEFAULT_SOCKET_CONNECT_TIMEOUT;
+ ((ChannelTCP)channel).setConnectTimeout(timeout);
+ }
+ // Add ourself as channel listener
+ channel.addChannelListener(this);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelOpened()
+ */
+ @Override
+ public void onChannelOpened() {
+ // Peer is reachable
+ if (channel != null) {
+ // Remove ourself as channel listener
+ channel.removeChannelListener(this);
+ }
+
+ // Set the peer state property
+ if (peerNode != null) {
+ int counter = peerNode.getIntProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER);
+ peerNode.setProperty(IPeerModelProperties.PROP_STATE, counter > 0 ? IPeerModelProperties.STATE_CONNECTED : IPeerModelProperties.STATE_REACHABLE);
+ peerNode.setProperty(IPeerModelProperties.PROP_LAST_SCANNER_ERROR, null);
+ }
+
+ if (channel != null && channel.getState() == IChannel.STATE_OPEN) {
+ // Get the parent model from the model mode
+ final ILocatorModel model = (ILocatorModel)peerNode.getAdapter(ILocatorModel.class);
+ if (model != null) {
+ // Get the local service
+ Collection<String> localServices = new ArrayList<String>(channel.getLocalServices());
+ // Get the remote services
+ Collection<String> remoteServices = new ArrayList<String>(channel.getRemoteServices());
+
+ // Get the update service
+ ILocatorModelUpdateService updateService = model.getService(ILocatorModelUpdateService.class);
+ if (updateService != null) {
+ // Update the services nodes
+ updateService.updatePeerServices(peerNode, localServices, remoteServices);
+ }
+
+ // Use the open channel to ask the remote peer what other
+ // peers it knows
+ ILocator locator = channel.getRemoteService(ILocator.class);
+ if (locator != null) {
+ final Map<String, IPeer> peers = locator.getPeers();
+ if (peers != null && !peers.isEmpty()) {
+ // Execute asynchronously within the TCF dispatch thread
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ for (String peerId : peers.keySet()) {
+ // Try to find an existing peer node first
+ IPeerModel peerNode = model.getService(ILocatorModelLookupService.class).lkupPeerModelById(peerId);
+ if (peerNode == null) peerNode = new PeerModel(model, peers.get(peerId));
+ // Add the peer node to model
+ model.getService(ILocatorModelUpdateService.class).add(peerNode);
+ // And schedule for immediate status update
+ Runnable runnable = new ScannerRunnable(getParentScanner(), peerNode);
+ Protocol.invokeLater(runnable);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ // And close the channel
+ channel.close();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable)
+ */
+ @Override
+ public void onChannelClosed(Throwable error) {
+ // Peer is not reachable
+
+ if (channel != null) {
+ // Remove ourself as channel listener
+ channel.removeChannelListener(this);
+ }
+
+ // Set the peer state property, if the scanner the runnable
+ // has been scheduled from is still active.
+ if (peerNode != null && (parentScanner == null || parentScanner != null && !parentScanner.isTerminated())) {
+ peerNode.setProperty(IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, null);
+ peerNode.setProperty(IPeerModelProperties.PROP_STATE,
+ error instanceof SocketTimeoutException ? IPeerModelProperties.STATE_NOT_REACHABLE : IPeerModelProperties.STATE_ERROR);
+ peerNode.setProperty(IPeerModelProperties.PROP_LAST_SCANNER_ERROR, error instanceof SocketTimeoutException ? null : error);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#congestionLevel(int)
+ */
+ @Override
+ public void congestionLevel(int level) {
+ }
+
+}

Back to the top