diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.tcf.core/src/org/eclipse')
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 "TCF
+ * task aborted". 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;
+ }
+}
|