Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/Tcf.java298
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java62
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java56
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/ITransportTypes.java45
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java162
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/Startup.java84
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/interfaces/IChannelOpenListener.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java100
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/utils/LogUtils.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataProvider.java76
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataReceiver.java76
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/utils/ExceptionUtils.java43
17 files changed, 1282 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/Tcf.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/Tcf.java
new file mode 100644
index 000000000..6a7bcbfc1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/Tcf.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * 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.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.protocol.Protocol.ChannelOpenListener;
+import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager;
+import org.eclipse.tcf.te.tcf.core.interfaces.listeners.IChannelStateChangeListener;
+import org.eclipse.tcf.te.tcf.core.interfaces.listeners.IProtocolStateChangeListener;
+import org.eclipse.tcf.te.tcf.core.internal.ChannelManager;
+import org.eclipse.tcf.te.tcf.core.internal.Startup;
+import org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tcf.te.tcf.core.internal.listener.InternalChannelOpenListener;
+
+
+/**
+ * The main entry point to access the TCF framework extensions.
+ */
+public final class Tcf {
+ /* default */ IChannelManager channelManager;
+
+ /* default */ ChannelOpenListener channelOpenListener;
+
+ /* default */ final List<IProtocolStateChangeListener> protocolStateChangeListeners = new ArrayList<IProtocolStateChangeListener>();
+ /* default */ final List<IChannelStateChangeListener> channelStateChangeListeners = new ArrayList<IChannelStateChangeListener>();
+
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static Tcf instance = new Tcf();
+ }
+
+ /**
+ * Constructor.
+ */
+ /* default */ Tcf() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance.
+ */
+ /* default */ static Tcf getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /**
+ * Executes the given runnable within the TCF protocol dispatch thread.
+ * <p>
+ * <b>Note:</b> Code which is executed in the TCF protocol dispatch thread
+ * cannot use any blocking API!
+ *
+ * @param runnable The runnable. Must not be <code>null</code>.
+ */
+ private static final void runSafe(Runnable runnable) {
+ Assert.isNotNull(runnable);
+
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ } else {
+ Protocol.invokeAndWait(runnable);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified once the TCF framework state changes.
+ *
+ * @param listener The listener. Must not be <code>null</code>.
+ */
+ public static final void addProtocolStateChangeListener(IProtocolStateChangeListener listener) {
+ Assert.isTrue(Protocol.isDispatchThread());
+ Assert.isNotNull(listener);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ if (!tcf.protocolStateChangeListeners.contains(listener)) {
+ tcf.protocolStateChangeListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified protocol state change listener.
+ *
+ * @param listener The listener. Must not be <code>null</code>.
+ */
+ public static final void removeProtocolStateChangeListener(IProtocolStateChangeListener listener) {
+ Assert.isTrue(Protocol.isDispatchThread());
+ Assert.isNotNull(listener);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ tcf.protocolStateChangeListeners.remove(listener);
+ }
+
+ /**
+ * Adds a listener that will be notified once the TCF framework state changes.
+ *
+ * @param listener The listener. Must not be <code>null</code>.
+ */
+ public static final void addChannelStateChangeListener(IChannelStateChangeListener listener) {
+ Assert.isTrue(Protocol.isDispatchThread());
+ Assert.isNotNull(listener);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ if (!tcf.channelStateChangeListeners.contains(listener)) {
+ tcf.channelStateChangeListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the specified protocol state change listener.
+ *
+ * @param listener The listener. Must not be <code>null</code>.
+ */
+ public static final void removeChannelStateChangeListener(IChannelStateChangeListener listener) {
+ Assert.isTrue(Protocol.isDispatchThread());
+ Assert.isNotNull(listener);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ tcf.channelStateChangeListeners.remove(listener);
+ }
+
+ /**
+ * Fires the channel state change listeners.
+ *
+ * @param channel The channel which changed state. Must not be <code>null</code>.
+ * @param state The new state.
+ */
+ public static final void fireChannelStateChangeListeners(final IChannel channel, final int state) {
+ Assert.isTrue(Protocol.isDispatchThread());
+ Assert.isNotNull(channel);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ final IChannelStateChangeListener[] listeners = tcf.channelStateChangeListeners.toArray(new IChannelStateChangeListener[tcf.channelStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ for (IChannelStateChangeListener listener : listeners) {
+ listener.stateChanged(channel, state);
+ }
+ }
+ }
+
+ /**
+ * Returns if or if not the TCF framework is up and running.
+ *
+ * @return <code>True</code> if the framework is up and running, <code>false</code> otherwise.
+ */
+ public static final boolean isRunning() {
+ return Startup.isStarted();
+ }
+
+ /**
+ * Startup TCF related services and listeners once the core
+ * TCF framework starts up.
+ * <p>
+ * <b>Note:</b> The method is expected to be called within the TCF protocol dispatch thread.
+ *
+ * @see Startup#setStarted(boolean)
+ */
+ public static void start() {
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ // Create and register the global channel open listener
+ if (tcf.channelOpenListener == null) {
+ tcf.channelOpenListener = new InternalChannelOpenListener();
+ Protocol.addChannelOpenListener(tcf.channelOpenListener);
+ }
+
+ // Signal (asynchronously) to interested listeners that we've started up
+ final IProtocolStateChangeListener[] listeners = tcf.protocolStateChangeListeners.toArray(new IProtocolStateChangeListener[tcf.protocolStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ for (IProtocolStateChangeListener listener : listeners) {
+ listener.stateChanged(true);
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Shutdown TCF related services and listeners once the core
+ * TCF framework shuts down.
+ * <p>
+ * <b>Note:</b> The method is expected to be called within the TCF protocol dispatch thread.
+ *
+ * @see Startup#setStarted(boolean)
+ */
+ public static void stop() {
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ // Unregister the channel open listener of created
+ if (tcf.channelOpenListener != null) {
+ Protocol.removeChannelOpenListener(tcf.channelOpenListener);
+ tcf.channelOpenListener = null;
+ }
+
+ // Signal to interested listeners that we've just went down
+ final IProtocolStateChangeListener[] listeners = tcf.protocolStateChangeListeners.toArray(new IProtocolStateChangeListener[tcf.protocolStateChangeListeners.size()]);
+ if (listeners.length > 0) {
+ // Catch IllegalStateException: TCF event dispatcher might have been shut down already
+ try {
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ for (IProtocolStateChangeListener listener : listeners) {
+ listener.stateChanged(false);
+ }
+ }
+ });
+ } catch (IllegalStateException e) { /* ignored on purpose */ }
+ }
+ }
+
+ /**
+ * Returns the channel manager instance.
+ * <p>
+ * <b>Note:</b> The method will create the channel manager instance on
+ * first invocation.
+ *
+ * @return The channel manager instance.
+ */
+ public static IChannelManager getChannelManager() {
+ final Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ runSafe(new Runnable() {
+ @Override
+ public void run() {
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ if (tcf.channelManager == null) {
+ // We have to create the channel manager
+ tcf.channelManager = new ChannelManager();
+ }
+ }
+ });
+
+ return tcf.channelManager;
+ }
+
+ /**
+ * Returns an object which is an instance of the given class associated with the given object.
+ * Returns <code>null</code> if no such object can be found.
+ *
+ * @param adapter The type of adapter to look up
+ * @return An object castable to the given adapter type, or <code>null</code>
+ * if the given adaptable object does not have an available adapter of the given type
+ *
+ * @see IAdapterManager#getAdapter(Object, Class)
+ */
+ public static Object getAdapter(Class<?> adapter) {
+ Assert.isNotNull(adapter);
+
+ Tcf tcf = getInstance();
+ Assert.isNotNull(tcf);
+
+ if (IChannelManager.class.equals(adapter)) {
+ return tcf.channelManager;
+ }
+ if (IChannelOpenListener.class.equals(adapter)) {
+ return tcf.channelOpenListener;
+ }
+
+ return Platform.getAdapterManager().getAdapter(tcf, adapter);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java
new file mode 100644
index 000000000..e716a3b8d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/activator/CoreBundleActivator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.core.activator;
+
+import org.eclipse.tcf.te.tcf.core.internal.Startup;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class CoreBundleActivator implements BundleActivator {
+ // The bundle context
+ private static BundleContext context;
+
+ /**
+ * Returns the bundle context
+ *
+ * @return the bundle context
+ */
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getContext() != null && getContext().getBundle() != null) {
+ return getContext().getBundle().getSymbolicName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = bundleContext;
+ }
+
+ /* (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext bundleContext) throws Exception {
+ CoreBundleActivator.context = null;
+
+ // Mark the core framework as not started anymore
+ Startup.setStarted(false);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java
new file mode 100644
index 000000000..b7d7aca1f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/IChannelManager.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.core.interfaces;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IPeer;
+
+/**
+ * TCF channel manager public API declaration.
+ */
+public interface IChannelManager extends IAdaptable {
+
+ /**
+ * Client call back interface for openChannel(...).
+ */
+ interface DoneOpenChannel {
+ /**
+ * Called when the channel fully opened or failed to open.
+ *
+ * @param error The error description if operation failed, <code>null</code> if succeeded.
+ * @param channel The channel object or <code>null</code>.
+ */
+ void doneOpenChannel(Throwable error, IChannel channel);
+ }
+
+ /**
+ * Opens a new channel to communicate with the given peer.
+ * <p>
+ * The method can be called from any thread context.
+ *
+ * @param peer The peer. Must not be <code>null</code>.
+ * @param done The client callback. Must not be <code>null</code>.
+ */
+ public void openChannel(IPeer peer, DoneOpenChannel done);
+
+ /**
+ * Opens a new channel to communicate with the peer described by the
+ * given peer attributes.
+ * <p>
+ * The method can be called from any thread context.
+ *
+ * @param peerAttributes The peer attributes. Must not be <code>null</code>.
+ * @param done The client callback. Must not be <code>null</code>.
+ */
+ public void openChannel(Map<String, String> peerAttributes, DoneOpenChannel done);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/ITransportTypes.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/ITransportTypes.java
new file mode 100644
index 000000000..b218febea
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/ITransportTypes.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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.core.interfaces;
+
+/**
+ * Declaration of the TCF transport type constants.
+ * <p>
+ * The constants defined in this interface needs to be kept in sync with
+ * the TCF framework transport manager implementation. Probably the interface
+ * should be moved to the core TCF framework plug-in's some when.
+ */
+public interface ITransportTypes {
+
+ /**
+ * Transport type "TCP".
+ */
+ public static final String TRANSPORT_TYPE_TCP = "TCP"; //$NON-NLS-1$
+
+ /**
+ * Transport type "SSL".
+ */
+ public static final String TRANSPORT_TYPE_SSL = "SSL"; //$NON-NLS-1$
+
+ /**
+ * Transport type "PIPE".
+ */
+ public static final String TRANSPORT_TYPE_PIPE = "PIPE"; //$NON-NLS-1$
+
+ /**
+ * Transport type "Loop".
+ */
+ public static final String TRANSPORT_TYPE_LOOP = "Loop"; //$NON-NLS-1$
+
+ /**
+ * Custom transport type.
+ */
+ public static final String TRANSPORT_TYPE_CUSTOM = "Custom"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java
new file mode 100644
index 000000000..3257bd225
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IChannelStateChangeListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.core.interfaces.listeners;
+
+import org.eclipse.tcf.protocol.IChannel;
+
+/**
+ * Interface for clients to implement that wishes to listen
+ * channel state changes, like opening and closing of a channel.
+ */
+public interface IChannelStateChangeListener {
+
+ /**
+ * Invoked if the channel state has changed.
+ *
+ * @param channel The channel which changed state.
+ * @param state The new state.
+ */
+ public void stateChanged(IChannel channel, int state);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java
new file mode 100644
index 000000000..ff69500f8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/interfaces/listeners/IProtocolStateChangeListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.core.interfaces.listeners;
+
+/**
+ * Interface for clients to implement that wishes to listen
+ * for the TCF protocol framework to come up and shutdown.
+ */
+public interface IProtocolStateChangeListener {
+
+ /**
+ * Invoked if the TCF framework comes up, <i>state == true</i>, or
+ * if it shuts down, <i>state == false</i>.
+ *
+ * @param state The current TCF framework state.
+ */
+ public void stateChanged(boolean state);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
new file mode 100644
index 000000000..1be6135fa
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/ChannelManager.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * 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.core.internal;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.core.AbstractPeer;
+import org.eclipse.tcf.core.TransientPeer;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IPeer;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager;
+
+
+/**
+ * TCF channel manager implementation.
+ */
+public final class ChannelManager extends PlatformObject implements IChannelManager {
+
+ /**
+ * Constructor.
+ */
+ public ChannelManager() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(org.eclipse.tcf.protocol.IPeer, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)
+ */
+ @Override
+ public void openChannel(final IPeer peer, final DoneOpenChannel done) {
+ if (Protocol.isDispatchThread()) {
+ internalOpenChannel(peer, done);
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ internalOpenChannel(peer, done);
+ }
+ });
+ }
+ }
+
+ /**
+ * Internal implementation of {@link #openChannel(IPeer, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)}.
+ * <p>
+ * Method must be called within the TCF dispatch thread.
+ *
+ * @param peer The peer. Must not be <code>null</code>.
+ * @param done The client callback. Must not be <code>null</code>.
+ */
+ /* default */ void internalOpenChannel(final IPeer peer, final DoneOpenChannel done) {
+ Assert.isNotNull(peer);
+ Assert.isNotNull(done);
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ // Open the channel
+ final IChannel channel = peer.openChannel();
+ // Register the channel listener
+ if (channel != null) {
+ channel.addChannelListener(new IChannel.IChannelListener() {
+
+ @Override
+ public void onChannelOpened() {
+ // Remove ourself as listener from the channel
+ channel.removeChannelListener(this);
+ // Channel opening succeeded
+ done.doneOpenChannel(null, channel);
+ }
+
+ @Override
+ public void onChannelClosed(Throwable error) {
+ // Remove ourself as listener from the channel
+ channel.removeChannelListener(this);
+ // Channel opening failed
+ done.doneOpenChannel(error, channel);
+ }
+
+ @Override
+ public void congestionLevel(int level) {
+ // ignored
+ }
+ });
+ } else {
+ // Channel is null? Something went terrible wrong.
+ done.doneOpenChannel(new Exception("Unexpected null return value from IPeer#openChannel()!"), null); //$NON-NLS-1$
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager#openChannel(java.util.Map, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)
+ */
+ @Override
+ public void openChannel(final Map<String, String> peerAttributes, final DoneOpenChannel done) {
+ if (Protocol.isDispatchThread()) {
+ internalOpenChannel(peerAttributes, done);
+ } else {
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ internalOpenChannel(peerAttributes, done);
+ }
+ });
+ }
+ }
+
+ /**
+ * Internal implementation of {@link #openChannel(Map, org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel)}.
+ * <p>
+ * Method must be called within the TCF dispatch thread.
+ *
+ * @param peerAttributes The peer attributes. Must not be <code>null</code>.
+ * @param done The client callback. Must not be <code>null</code>.
+ */
+ /* default */ void internalOpenChannel(final Map<String, String> peerAttributes, final DoneOpenChannel done) {
+ Assert.isNotNull(peerAttributes);
+ Assert.isNotNull(done);
+ Assert.isTrue(Protocol.isDispatchThread());
+ internalOpenChannel(getOrCreatePeerInstance(peerAttributes), done);
+ }
+
+ /**
+ * Tries to find an existing peer instance or create an new {@link IPeer}
+ * instance if not found.
+ * <p>
+ * <b>Note:</b> This method must be invoked at the TCF dispatch thread.
+ *
+ * @param peerAttributes The peer attributes. Must not be <code>null</code>.
+ * @return The peer instance.
+ */
+ private IPeer getOrCreatePeerInstance(final Map<String, String> peerAttributes) {
+ Assert.isNotNull(peerAttributes);
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ // Get the peer id from the properties
+ String peerId = peerAttributes.get(IPeer.ATTR_ID);
+ Assert.isNotNull(peerId);
+
+ // Check if we shall open the peer transient
+ boolean isTransient = peerAttributes.containsKey("transient") ? Boolean.parseBoolean(peerAttributes.remove("transient")) : false; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Look the peer via the Locator Service.
+ IPeer peer = Protocol.getLocator().getPeers().get(peerId);
+ // If not peer could be found, create a new one
+ if (peer == null) {
+ peer = isTransient ? new TransientPeer(peerAttributes) : new AbstractPeer(peerAttributes);
+ }
+
+ // Return the peer instance
+ return peer;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/Startup.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/Startup.java
new file mode 100644
index 000000000..0cae997dc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/Startup.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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.core.internal;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.core.activator.CoreBundleActivator;
+
+
+/**
+ * Class loaded by the TCF core framework when the framework is fired up. The static
+ * constructor of the class will trigger whatever is necessary in this case.
+ * <p>
+ * <b>Note:</b> This will effectively trigger {@link CoreBundleActivator#start(org.osgi.framework.BundleContext)}
+ * to be called.
+ */
+public class Startup {
+ // Atomic boolean to store the started state of the TCF core framework
+ /* default */ final static AtomicBoolean STARTED = new AtomicBoolean(false);
+
+ static {
+ // We might get here on shutdown as well, and if TCF has not
+ // been loaded, than we will run into an NPE. Lets double check.
+ if (Protocol.getEventQueue() != null) {
+ // Initialize the framework status by scheduling a simple
+ // runnable to execute and be invoked once the framework
+ // is fully up and usable.
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ // Core framework is scheduling the runnables, means it is started.
+ setStarted(true);
+ }
+ });
+ }
+ }
+
+ /**
+ * Set the core framework started state to the given state.
+ *
+ * @param started <code>True</code> when the framework is started, <code>false</code> otherwise.
+ */
+ public static final void setStarted(boolean started) {
+ STARTED.set(started);
+
+ // Start/Stop should be called in the TCF protocol dispatch thread
+ if (Protocol.getEventQueue() != null) {
+ // Catch IllegalStateException: TCF event dispatcher has shut down
+ try {
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (STARTED.get()) Tcf.start(); else Tcf.stop();
+ }
+ });
+ } catch (IllegalStateException e) {
+ if (!STARTED.get() && "TCF event dispatcher has shut down".equals(e.getLocalizedMessage())) { //$NON-NLS-1$
+ // ignore the exception on shutdown
+ } else {
+ // re-throw in any other case
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns if or if not the core framework has been started.
+ *
+ * @return <code>True</code> when the framework is started, <code>false</code> otherwise.
+ */
+ public static final boolean isStarted() {
+ return STARTED.get();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/interfaces/IChannelOpenListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/interfaces/IChannelOpenListener.java
new file mode 100644
index 000000000..f665ad52b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/interfaces/IChannelOpenListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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.core.internal.interfaces;
+
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.Protocol.ChannelOpenListener;
+
+/**
+ * Enhanced channel open listener interface for internal use.
+ */
+public interface IChannelOpenListener extends ChannelOpenListener {
+
+ /**
+ * Stores the given channel listener to the internal map. The map
+ * key is the given channel. If the given channel listener is <code>null</code>,
+ * the channel is removed from the internal map.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ * @param listener The channel listener or <code>null</code>.
+ */
+ public void setChannelListener(IChannel channel, IChannel.IChannelListener listener);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java
new file mode 100644
index 000000000..8f77376ad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelListener.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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.core.internal.listener;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tcf.te.tcf.core.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.core.internal.utils.LogUtils;
+
+
+/**
+ * Internal channel listener. Attached to a TCF channel for tracing purpose.
+ */
+public class InternalChannelListener implements IChannel.IChannelListener {
+ // The reference to the channel
+ private final IChannel channel;
+
+ /**
+ * Constructor.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ */
+ public InternalChannelListener(IChannel channel) {
+ Assert.isNotNull(channel);
+ this.channel = channel;
+ }
+
+ /**
+ * Return the associated channel.
+ *
+ * @return The channel instance.
+ */
+ protected final IChannel getChannel() {
+ return channel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#congestionLevel(int)
+ */
+ @Override
+ public void congestionLevel(int level) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelClosed(java.lang.Throwable)
+ */
+ @Override
+ public void onChannelClosed(Throwable error) {
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ // Detach the listeners cleanly
+ detachListeners(getChannel());
+
+ // Construct the cause message
+ String cause = ""; //$NON-NLS-1$
+ if (error != null) {
+ cause = NLS.bind(Messages.InternalChannelListener_onChannelClosed_cause, error.getLocalizedMessage());
+ }
+
+ // Trace the channel closing
+ LogUtils.logMessageForChannel(getChannel(), NLS.bind(Messages.InternalChannelListener_onChannelClosed_message, cause), "debug/channels", this); //$NON-NLS-1$
+
+ // Fire the property change event for the channel
+ Tcf.fireChannelStateChangeListeners(getChannel(), IChannel.STATE_CLOSED);
+ }
+
+ /**
+ * Detach all registered listeners from the given channel.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ */
+ protected void detachListeners(IChannel channel) {
+ Assert.isNotNull(channel);
+
+ // Cleanly remove all listeners from the channel
+ channel.removeChannelListener(this);
+
+ // And remove the listener references from the global channel open listener
+ IChannelOpenListener openListener = (IChannelOpenListener)Tcf.getAdapter(IChannelOpenListener.class);
+ if (openListener != null) openListener.setChannelListener(channel, null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.IChannel.IChannelListener#onChannelOpened()
+ */
+ @Override
+ public void onChannelOpened() {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java
new file mode 100644
index 000000000..9d5e093c4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/listener/InternalChannelOpenListener.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.core.internal.listener;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IChannel.IChannelListener;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener;
+import org.eclipse.tcf.te.tcf.core.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.core.internal.utils.LogUtils;
+
+
+/**
+ * Internal channel open listener taking care of logging and caching.
+ */
+public class InternalChannelOpenListener implements IChannelOpenListener {
+ // Static map containing the channel listeners per channel. Access to the
+ // map should happen from the TCF protocol dispatch thread only.
+ private final Map<IChannel, IChannel.IChannelListener> channelListeners = new HashMap<IChannel, IChannel.IChannelListener>();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.protocol.Protocol.ChannelOpenListener#onChannelOpen(org.eclipse.tcf.protocol.IChannel)
+ */
+ @Override
+ public void onChannelOpen(IChannel channel) {
+ Assert.isNotNull(channel);
+ Assert.isTrue(Protocol.isDispatchThread());
+
+ // Trace the channel opening
+ LogUtils.logMessageForChannel(channel, Messages.InternalChannelOpenListener_onChannelOpen_message, "debug/channels", this); //$NON-NLS-1$
+
+ // As the channel has just opened, there should be no channel listener, but better be safe and check.
+ IChannel.IChannelListener channelListener = channelListeners.remove(channel);
+ if (channelListener != null) channel.removeChannelListener(channelListener);
+ // Create a new channel listener instance
+ channelListener = new InternalChannelListener(channel);
+ // Add the channel listener to the global map
+ setChannelListener(channel, channelListener);
+ // Attach channel listener to the channel
+ channel.addChannelListener(channelListener);
+
+ // Fire the property change event for the channel
+ Tcf.fireChannelStateChangeListeners(channel, IChannel.STATE_OPEN);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.core.internal.interfaces.IChannelOpenListener#setChannelListener(org.eclipse.tcf.protocol.IChannel, org.eclipse.tcf.protocol.IChannel.IChannelListener)
+ */
+ @Override
+ public void setChannelListener(IChannel channel, IChannelListener listener) {
+ Assert.isNotNull(channel);
+ if (listener != null) channelListeners.put(channel, listener);
+ else channelListeners.remove(channel);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java
new file mode 100644
index 000000000..a3e6ca469
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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.core.internal.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tcf.te.tcf.core.internal.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ if (field != null) {
+ return (String)field.get(null);
+ }
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String InternalChannelOpenListener_onChannelOpen_message;
+
+ public static String InternalChannelListener_onChannelClosed_message;
+ public static String InternalChannelListener_onChannelClosed_cause;
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties
new file mode 100644
index 000000000..50c4de0de
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/nls/Messages.properties
@@ -0,0 +1,9 @@
+#
+# org.eclipse.tcf.te.tcf.core
+# Externalized Strings.
+#
+
+InternalChannelOpenListener_onChannelOpen_message=Channel opened.
+
+InternalChannelListener_onChannelClosed_message=Channel closed. {0}
+InternalChannelListener_onChannelClosed_cause=; Possibly caused by: {0}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/utils/LogUtils.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/utils/LogUtils.java
new file mode 100644
index 000000000..fdea98cf8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/internal/utils/LogUtils.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.core.internal.utils;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.te.tcf.core.activator.CoreBundleActivator;
+
+
+/**
+ * Logging utilities helper implementations.
+ */
+public final class LogUtils {
+
+ /**
+ * Log the given message for the given channel.
+ *
+ * @param channel The channel. Must not be <code>null</code>.
+ * @param message The message to log. Must not be <code>null</code>.
+ * @param slotId The Eclipse debug slot id which must be enabled to log the message. Must not be <code>null</code>.
+ * @param clazz The invoking class or <code>null</code>.
+ */
+ public static void logMessageForChannel(IChannel channel, String message, String slotId, Object clazz) {
+ Assert.isNotNull(channel);
+ Assert.isNotNull(message);
+ Assert.isNotNull(slotId);
+
+ // Trace the message
+ String fullMessage = channel.toString() + ": " + message; //$NON-NLS-1$
+
+ if (Boolean.parseBoolean(Platform.getDebugOption(CoreBundleActivator.getUniqueIdentifier() + "/" + slotId))) { //$NON-NLS-1$
+ IStatus status = new Status(IStatus.INFO, CoreBundleActivator.getUniqueIdentifier(), fullMessage.trim());
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataProvider.java
new file mode 100644
index 000000000..17adba4f5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataProvider.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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.core.streams;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.services.IProcesses;
+
+/**
+ * Remote context streams data provider implementation.
+ */
+public class StreamsDataProvider extends PlatformObject {
+ // The associated reader instance
+ private final Reader reader;
+ // The list of applicable stream type id's
+ private final List<String> streamTypeIds;
+
+ /**
+ * Constructor.
+ *
+ * @param reader The reader instance. Must not be <code>null</code>.
+ * @param streamTypeIds The list of applicable stream type id's or <code>null</code>.
+ *
+ * @see IProcesses
+ */
+ public StreamsDataProvider(Reader reader, String[] streamTypeIds) {
+ Assert.isNotNull(reader);
+ this.reader = reader;
+ this.streamTypeIds = streamTypeIds != null ? Arrays.asList(streamTypeIds) : null;
+ }
+
+ /**
+ * Dispose the data provider instance.
+ */
+ public void dispose() {
+ try {
+ reader.close();
+ }
+ catch (IOException e) {
+ /* ignored on purpose */
+ }
+ }
+
+ /**
+ * Returns the associated reader instance.
+ *
+ * @return The associated reader instance.
+ */
+ public final Reader getReader() {
+ return reader;
+ }
+
+ /**
+ * Returns if or if not the given stream type id is applicable for this data receiver.
+ *
+ * @param streamTypeId The stream type id. Must not be <code>null</code>.
+ * @return <code>True</code> if the given stream type id is applicable for this data receiver,
+ * <code>false</code> otherwise.
+ */
+ public final boolean isApplicable(String streamTypeId) {
+ Assert.isNotNull(streamTypeId);
+ return streamTypeIds == null || streamTypeIds.contains(streamTypeId);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataReceiver.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataReceiver.java
new file mode 100644
index 000000000..0de12c694
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/streams/StreamsDataReceiver.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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.core.streams;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.services.IProcesses;
+
+/**
+ * Remote context streams data receiver implementation.
+ */
+public class StreamsDataReceiver extends PlatformObject {
+ // The associated writer instance
+ private final Writer writer;
+ // The list of applicable stream type id's
+ private final List<String> streamTypeIds;
+
+ /**
+ * Constructor.
+ *
+ * @param writer The writer instance. Must not be <code>null</code>.
+ * @param streamTypeIds The list of applicable stream type id's or <code>null</code>.
+ *
+ * @see IProcesses
+ */
+ public StreamsDataReceiver(Writer writer, String[] streamTypeIds) {
+ Assert.isNotNull(writer);
+ this.writer = writer;
+ this.streamTypeIds = streamTypeIds != null ? Arrays.asList(streamTypeIds) : null;
+ }
+
+ /**
+ * Dispose the data receiver instance.
+ */
+ public void dispose() {
+ try {
+ writer.close();
+ }
+ catch (IOException e) {
+ /* ignored on purpose */
+ }
+ }
+
+ /**
+ * Returns the associated writer instance.
+ *
+ * @return The associated writer instance.
+ */
+ public final Writer getWriter() {
+ return writer;
+ }
+
+ /**
+ * Returns if or if not the given stream type id is applicable for this data receiver.
+ *
+ * @param streamTypeId The stream type id. Must not be <code>null</code>.
+ * @return <code>True</code> if the given stream type id is applicable for this data receiver, <code>false</code>
+ * otherwise.
+ */
+ public final boolean isApplicable(String streamTypeId) {
+ Assert.isNotNull(streamTypeId);
+ return streamTypeIds == null || streamTypeIds.contains(streamTypeId);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/utils/ExceptionUtils.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/utils/ExceptionUtils.java
new file mode 100644
index 000000000..58deb17b5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse/tcf/te/tcf/core/utils/ExceptionUtils.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.core.utils;
+
+import java.util.concurrent.ExecutionException;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.util.TCFTask;
+
+/**
+ * Exception utilities helper implementations.
+ */
+public final class ExceptionUtils {
+
+ /**
+ * The {@link TCFTask} implementation is wrapping the error cause into an
+ * {@link ExecutionException} with the default error message &quot;TCF
+ * task aborted&quot;. As this message is not very informative to the user,
+ * unpack the given exception to reveal the real error cause to the clients.
+ *
+ * @param e The source exception. Must not be <code>null</code>.
+ * returns Exception The real error cause.
+ */
+ public static Exception checkAndUnwrapException(Exception e) {
+ Assert.isNotNull(e);
+
+ // If the incoming exception is a ExecutionException and has set
+ // the default error message text, get the embedded cause.
+ if (e instanceof ExecutionException && "TCF task aborted".equals(e.getMessage())) { //$NON-NLS-1$
+ // Get the cause
+ if (e.getCause() instanceof Exception) return (Exception)e.getCause();
+ }
+
+ return e;
+ }
+}

Back to the top