Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse')
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/activator/CoreBundleActivator.java71
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/callback/Callback.java295
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/EventManager.java533
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/PropertyChangeEvent.java117
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/AbstractExtensionPointManager.java173
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtension.java129
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtensionProxy.java157
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/IConditionTester.java31
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/callback/ICallback.java51
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventFireDelegate.java31
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventListener.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/extensions/IExecutableExtension.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/properties/IPropertiesContainer.java285
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/tracing/ITraceIds.java26
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/DebugEventListener.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PreferencesPropertyTester.java76
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PropertiesContainerPropertyTester.java55
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.properties8
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/preferences/ScopedEclipsePreferences.java459
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/progress/ProgressHelper.java317
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/properties/PropertiesContainer.java504
-rw-r--r--target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/tracing/TraceHandler.java275
23 files changed, 3727 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/activator/CoreBundleActivator.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/activator/CoreBundleActivator.java
new file mode 100644
index 000000000..a8ca3f56e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/activator/CoreBundleActivator.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.activator;
+
+import org.eclipse.tm.te.runtime.tracing.TraceHandler;
+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;
+ // The trace handler instance
+ private static TraceHandler traceHandler;
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns the bundles trace handler.
+ *
+ * @return The bundles trace handler.
+ */
+ public static TraceHandler getTraceHandler() {
+ if (traceHandler == null) {
+ traceHandler = new TraceHandler(getUniqueIdentifier());
+ }
+ return traceHandler;
+ }
+
+ /* (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;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/callback/Callback.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/callback/Callback.java
new file mode 100644
index 000000000..97d5b011a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/callback/Callback.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.callback;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.IConditionTester;
+import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tm.te.runtime.progress.ProgressHelper;
+import org.eclipse.tm.te.runtime.properties.PropertiesContainer;
+
+/**
+ * Default implementation of the <code>ICallback</code> interface.
+ */
+public class Callback extends PropertiesContainer implements ICallback {
+
+ protected static final String PROPERTY_PARENT_CALLBACK = "parentCallback"; //$NON-NLS-1$
+ protected static final String PROPERTY_PROGRESS_MONITOR = "progressMonitor"; //$NON-NLS-1$
+ protected static final String PROPERTY_PROGRESS_TICKS = "progressTicks"; //$NON-NLS-1$
+ protected static final String PROPERTY_IS_DONE = "isDone"; //$NON-NLS-1$
+ protected static final String PROPERTY_STATUS = "status"; //$NON-NLS-1$
+
+ private static final String[] PROPERTY_KEYS_NOT_TO_COPY = {
+ PROPERTY_PARENT_CALLBACK, PROPERTY_PROGRESS_MONITOR,
+ PROPERTY_PROGRESS_TICKS, PROPERTY_IS_DONE, PROPERTY_STATUS
+ };
+ private static final List<String> PROPERTY_KEYS_NOT_TO_COPY_LIST = Arrays.asList(PROPERTY_KEYS_NOT_TO_COPY);
+
+ /**
+ * Condition tester for ExecutorsUtil to check whether the callback is done
+ * or the {@link IProgressMonitor} is canceled.
+ */
+ private class CallbackDoneConditionTester implements IConditionTester {
+ final ICallback callback;
+ final IProgressMonitor monitor;
+
+ /**
+ * Constructor.
+ *
+ * @param callback
+ * The callback to check. Must not be <code>null</code>.
+ * @param monitor
+ * The progress monitor to check.
+ */
+ public CallbackDoneConditionTester(ICallback callback, IProgressMonitor monitor) {
+ Assert.isNotNull(callback);
+ this.callback = callback;
+ this.monitor = monitor;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IConditionTester#isConditionFulfilled()
+ */
+ @Override
+ public boolean isConditionFulfilled() {
+ if (monitor == null) {
+ return callback.isDone();
+ }
+ return monitor.isCanceled() || callback.isDone();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IConditionTester#cleanup()
+ */
+ @Override
+ public void cleanup() {
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public Callback() {
+ this(null);
+ }
+
+ /**
+ * Constructor to wrap a parent callback.
+ *
+ * @param parentCallback
+ * The parent callback.
+ */
+ public Callback(ICallback parentCallback) {
+ this(null, -1, parentCallback);
+ }
+
+ /**
+ * Constructor to handle a progress monitor.
+ *
+ * @param monitor
+ * The progress monitor.
+ * @param ticksToUse
+ * The ticks to add when done.
+ */
+ public Callback(IProgressMonitor monitor, int ticksToUse) {
+ this(monitor, ticksToUse, null);
+ }
+
+ /**
+ * Constructor to handle a progress monitor and wrap a parent callback.
+ *
+ * @param monitor
+ * The progress monitor.
+ * @param ticksToUse
+ * The ticks to add when done.
+ * @param parentCallback
+ * The parent callback.
+ */
+ public Callback(IProgressMonitor monitor, int ticksToUse, ICallback parentCallback) {
+ super();
+ setProperty(PROPERTY_PARENT_CALLBACK, parentCallback);
+ setProperty(PROPERTY_PROGRESS_MONITOR, monitor);
+ setProperty(PROPERTY_PROGRESS_TICKS, ticksToUse);
+ }
+
+ /**
+ * Get a condition tester for this callback.
+ *
+ * @param monitor
+ * The progress monitor or <code>null</code>.
+ * @return The condition tester.
+ */
+ public final IConditionTester getDoneConditionTester(IProgressMonitor monitor) {
+ return new CallbackDoneConditionTester(this, monitor);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.callback.ICallback#done(java.lang.Object, org.eclipse.core.runtime.IStatus)
+ */
+ @Override
+ public final void done(Object caller, IStatus status) {
+ assert status != null;
+
+ if (isDone()) {
+ CoreBundleActivator.getTraceHandler().trace("WARNING: callback called twice!!", 1, this); //$NON-NLS-1$
+ return;
+ }
+
+ status = checkStatusIntegrity(status);
+
+ setProperty(PROPERTY_IS_DONE, true);
+ setProperty(PROPERTY_STATUS, status);
+
+ ICallback parentCallback = (ICallback) getProperty(PROPERTY_PARENT_CALLBACK);
+ if (parentCallback != null && parentCallback.isDone()) {
+ CoreBundleActivator.getTraceHandler().trace("WARNING: parent callback called twice!!", 1, this); //$NON-NLS-1$
+ }
+
+ internalDone(caller, status);
+
+ if (isDone()) {
+ if (getProperty(PROPERTY_PROGRESS_MONITOR) instanceof IProgressMonitor) {
+ IProgressMonitor progress = ((IProgressMonitor) getProperty(PROPERTY_PROGRESS_MONITOR));
+ if (!progress.isCanceled() && getStatus().getSeverity() != IStatus.CANCEL) {
+ int ticks = getIntProperty(PROPERTY_PROGRESS_TICKS);
+ if (ticks > 0) {
+ progress.worked(ticks);
+ } else if (ticks == ProgressHelper.PROGRESS_DONE) {
+ progress.done();
+ }
+ }
+ }
+
+ parentCallback = (ICallback) getProperty(PROPERTY_PARENT_CALLBACK);
+ if (parentCallback != null && !parentCallback.isDone()) {
+ copyProperties(this, parentCallback);
+ if (!ProgressHelper.isCancelOrError(this,
+ getStatus(),
+ (IProgressMonitor) getProperty(PROPERTY_PROGRESS_MONITOR),
+ parentCallback)) {
+ parentCallback.done(caller, getStatus());
+ }
+ }
+ }
+ }
+
+ /**
+ * Copy the properties from the given source callback to the given
+ * destination callback.
+ *
+ * @param source
+ * The source callback. Must not be <code>null</code>.
+ * @param destination
+ * The destination callback. Must not be <code>null</code> and
+ * not yet done.
+ */
+ public static final void copyProperties(ICallback source, ICallback destination) {
+ Assert.isNotNull(source);
+ Assert.isNotNull(destination);
+ Assert.isTrue(!destination.isDone());
+
+ for (String key : source.getProperties().keySet()) {
+ if (!PROPERTY_KEYS_NOT_TO_COPY_LIST.contains(key)) {
+ destination.setProperty(key, source.getProperty(key));
+ }
+ }
+ assert !destination.isDone();
+ }
+
+ /**
+ * Checks the status integrity.
+ *
+ * @param status
+ * The status or <code>null</code>.
+ * @return The checked status.
+ */
+ private IStatus checkStatusIntegrity(IStatus status) {
+ if (status == null) status = Status.OK_STATUS;
+
+ if (status.getSeverity() == IStatus.CANCEL && status.getException() == null) {
+ status = new Status(IStatus.CANCEL, status.getPlugin(),
+ status.getMessage(), new OperationCanceledException(status.getMessage()));
+ }
+
+ if (status.getSeverity() == IStatus.WARNING && status.getException() == null) {
+ status = new Status(IStatus.WARNING, status.getPlugin(),
+ status.getMessage(), new Exception(status.getMessage()));
+ }
+
+ if (status.getSeverity() == IStatus.ERROR && status.getException() == null) {
+ status = new Status(IStatus.ERROR, status.getPlugin(),
+ status.getMessage(), new Exception(status.getMessage()));
+ }
+
+ return status;
+ }
+
+ /**
+ * Return the progress monitor or <code>null</code>.
+ */
+ protected final IProgressMonitor getProgressMonitor() {
+ return (IProgressMonitor) getProperty(PROPERTY_PROGRESS_MONITOR);
+ }
+
+ /**
+ * Internal callback done.
+ *
+ * @param caller
+ * The caller.
+ * @param status
+ * The status.
+ */
+ protected void internalDone(Object caller, IStatus status) {
+ }
+
+ /**
+ * Return the result on done.
+ */
+ public final IStatus getStatus() {
+ IStatus status = (IStatus) getProperty(PROPERTY_STATUS);
+ if (status == null && getProperty(PROPERTY_PROGRESS_MONITOR) instanceof IProgressMonitor) {
+ IProgressMonitor monitor = (IProgressMonitor) getProperty(PROPERTY_PROGRESS_MONITOR);
+ if (monitor.isCanceled()) {
+ return checkStatusIntegrity(Status.CANCEL_STATUS);
+ }
+ }
+
+ return checkStatusIntegrity(status);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.callback.ICallback#isDone()
+ */
+ @Override
+ public final boolean isDone() {
+ return getBooleanProperty(PROPERTY_IS_DONE);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.callback.ICallback#addParentCallback(org.eclipse.tm.te.runtime.interfaces.callback.ICallback)
+ */
+ @Override
+ public void addParentCallback(ICallback callback) {
+ if (getProperty(PROPERTY_PARENT_CALLBACK) instanceof ICallback) {
+ ICallback parentCallback = (ICallback) getProperty(PROPERTY_PARENT_CALLBACK);
+ parentCallback.addParentCallback(callback);
+ } else {
+ setProperty(PROPERTY_PARENT_CALLBACK, callback);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/EventManager.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/EventManager.java
new file mode 100644
index 000000000..d38686eee
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/EventManager.java
@@ -0,0 +1,533 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.events;
+
+import java.util.ArrayList;
+import java.util.EventListener;
+import java.util.EventObject;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.events.IEventFireDelegate;
+import org.eclipse.tm.te.runtime.interfaces.events.IEventListener;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+import org.osgi.framework.Bundle;
+
+
+/**
+ * The event manager implementation.
+ */
+public final class EventManager {
+ // Flag to remember if the extension point has been processed.
+ private boolean extensionPointProcessed;
+ // The list of registered listeners.
+ private final List<ListenerListEntry> listeners = new ArrayList<ListenerListEntry>();
+
+ /**
+ * Runnable implementation to fire a given event to a given listener.
+ */
+ protected static class FireRunnable implements Runnable {
+ private final IEventListener listener;
+ private final EventObject event;
+
+ /**
+ * Constructor.
+ *
+ * @param listener The event listener. Must not be <code>null</code>.
+ * @param event The event. Must not be <code>null</code>.
+ */
+ public FireRunnable(IEventListener listener, EventObject event) {
+ Assert.isNotNull(listener);
+ Assert.isNotNull(event);
+ this.listener = listener;
+ this.event = event;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ listener.eventFired(event);
+ }
+ }
+
+ /**
+ * Listener list entry.
+ * <p>
+ * Each entry contains a reference to the listener and a list of valid source classes.
+ * If an event source can be casted to one of the classes the listener is invoked.
+ */
+ private class ListenerListEntry {
+ private final IEventListener listener;
+ private final Object[] eventSources;
+ private final Class<?>[] eventTypes;
+
+ /**
+ * Constructor.
+ *
+ * @param listener The listener.
+ * @param eventType The event type the listener is interested in.
+ * @param eventSource The source type for which events should be fired to the listener.
+ */
+ protected ListenerListEntry(IEventListener listener, Class<?> eventType, Object eventSource) {
+ this(listener, eventType == null ? null : new Class[] { eventType }, eventSource == null ? null : new Object[] { eventSource });
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param listener The listener.
+ * @param eventTypes The event types the listener is interested in.
+ * @param eventSources The source types for which events should be fired to the listener.
+ */
+ protected ListenerListEntry(IEventListener listener, Class<?>[] eventTypes, Object[] eventSources) {
+ this.listener = listener;
+ if (eventTypes == null || eventTypes.length == 0) {
+ this.eventTypes = null;
+ } else {
+ this.eventTypes = eventTypes;
+ }
+ if (eventSources == null || eventSources.length == 0) {
+ this.eventSources = null;
+ } else {
+ this.eventSources = eventSources;
+ }
+ }
+
+ /**
+ * Get the listener of this entry.
+ */
+ protected EventListener getListener() {
+ return listener;
+ }
+
+ /**
+ * Check whether the listener wants to be called for changes of the source.
+ * The check is made through <code>instanceof</code>.
+ *
+ * @param source The source of the event.
+ * @return True, if the source can be casted to one of the registered event source types
+ * or no event sources are registered.
+ */
+ protected boolean listensTo(EventObject event) {
+ boolean types = (eventTypes == null || eventTypes.length == 0);
+ boolean sources = (eventSources == null || eventSources.length == 0);
+
+ int t = 0;
+ while (!types && eventTypes != null && t < eventTypes.length) {
+ types = eventTypes[t].isInstance(event);
+ t++;
+ }
+
+ int s = 0;
+ while (!sources && eventSources != null && s < eventSources.length) {
+ Object eventSource = eventSources[s];
+ if (eventSource instanceof Class<?>) {
+ Class<?> eventSourceClass = (Class<?>)eventSource;
+ sources = eventSourceClass.isInstance(event.getSource());
+ } else {
+ sources = eventSource == event.getSource();
+ }
+ s++;
+ }
+
+ return types && sources;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj != null && obj instanceof ListenerListEntry) {
+ ListenerListEntry other = (ListenerListEntry)obj;
+ return this.getListener() == other.getListener();
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return getClass().getName() + "{" + //$NON-NLS-1$
+ "listener=" + listener + //$NON-NLS-1$
+ ",eventTypes=" + eventTypes + //$NON-NLS-1$
+ ",eventSources=" + eventSources + //$NON-NLS-1$
+ "}"; //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static EventManager instance = new EventManager();
+ }
+
+ /**
+ * Private Constructor.
+ */
+ EventManager() {
+ extensionPointProcessed = false;
+ }
+
+ /**
+ * Returns the singleton instance for the event manager.
+ */
+ public static EventManager getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /**
+ * Add a change listener to listen to a single event.
+ *
+ * @param listener The listener to add.
+ * @param eventType The event type this listeners wants to be invoked.
+ */
+ public void addEventListener(IEventListener listener, Class<?> eventType) {
+ addEventListener(listener, eventType != null ? new Class[] { eventType } : null, null);
+ }
+
+ /**
+ * Add a change listener to listen to multiple events.
+ *
+ * @param listener The listener to add.
+ * @param eventTypes The event types this listeners wants to be invoked.
+ */
+ public void addEventListener(IEventListener listener, Class<?>[] eventTypes) {
+ addEventListener(listener, eventTypes, null);
+ }
+
+ /**
+ * Add a change listener to listen to event from the specified event
+ * source. If the listener instance had been registered already, the listener
+ * event sources are updated
+ *
+ * @param listener The listener to add.
+ * @param eventType The event type this listeners wants to be invoked.
+ * @param eventSource The event source type this listeners wants to be invoked.
+ */
+ public void addEventListener(IEventListener listener, Class<?> eventType, Object eventSource) {
+ addEventListener(listener, eventType != null ? new Class[] { eventType } : null, eventSource != null ? new Object[] { eventSource } : null);
+ }
+
+ /**
+ * Add a change listener to listen to events from the specified event
+ * sources. If the listener instance had been registered already, the listener
+ * event sources are updated
+ *
+ * @param listener The listener to add.
+ * @param eventType The event type this listeners wants to be invoked.
+ * @param eventSources The event sources type this listeners wants to be invoked.
+ */
+ public void addEventListener(IEventListener listener, Class<?> eventType, Object[] eventSources) {
+ addEventListener(listener, eventType != null ? new Class[] { eventType } : null, eventSources);
+ }
+
+ /**
+ * Add a change listener to listen to event from the specified event
+ * sources. If the listener instance had been registered already, the listener
+ * event sources are updated
+ *
+ * @param listener The listener to add.
+ * @param eventTypes The event types this listeners wants to be invoked.
+ * @param eventSources The event source types this listeners wants to be invoked.
+ */
+ public void addEventListener(IEventListener listener, Class<?>[] eventTypes, Object[] eventSources) {
+ ListenerListEntry listEntry = new ListenerListEntry(listener, eventTypes, eventSources);
+ // We must assure that the existing list entries can _never_ change!
+ synchronized (listeners) {
+ if (listeners.contains(listEntry)) {
+ listeners.remove(listEntry);
+ }
+ listeners.add(listEntry);
+ }
+ }
+
+ /**
+ * Remove a change listener for all event types and sources.
+ *
+ * @param listener The listener to remove.
+ */
+ public void removeEventListener(IEventListener listener) {
+ ListenerListEntry listEntry = new ListenerListEntry(listener, (Class<?>)null, (Object)null);
+ listeners.remove(listEntry);
+ }
+
+ /**
+ * Remove all change listeners for all event types and sources.
+ */
+ public void clear() {
+ listeners.clear();
+ extensionPointProcessed = false;
+ }
+
+ /**
+ * Notify all registered listeners.
+ *
+ * @param event The event. Must not be <code>null</code>
+ */
+ public void fireEvent(final EventObject event) {
+ Assert.isNotNull(event);
+
+ synchronized (this) {
+ // if the extension point has not been processed till here, now we have to do
+ if (!extensionPointProcessed) {
+ addExtensionPointNotificationListeners();
+ extensionPointProcessed = true;
+ }
+ }
+
+ // Based on the current listener listener list, compile a list of event
+ // listeners to where this event would have been send to in a synchronous invocation scheme.
+ List<ListenerListEntry> affected = new ArrayList<ListenerListEntry>();
+
+ // Get the array of registered event listeners.
+ ListenerListEntry[] registered = listeners.toArray(new ListenerListEntry[listeners.size()]);
+
+ for (ListenerListEntry listEntry : registered) {
+ // ignore listeners not listening to the event type and source
+ if (listEntry.listensTo(event)) {
+ affected.add(listEntry);
+ }
+ }
+
+ // If no current listener is affected, return now immediately
+ if (affected.size() == 0) {
+ return;
+ }
+
+ // Loop over the list of affected listeners and fire the event.
+ // If the affected listener is a fire delegate -> use it itself to fire the event
+ for (ListenerListEntry listEntry : affected) {
+ if (!(listEntry.getListener() instanceof IEventListener)) {
+ continue;
+ }
+ // Create the runnable to use for executing the event firing
+ Runnable runnable = new FireRunnable((IEventListener)listEntry.getListener(), event);
+ // Check on how to fire the runnable
+ if (listEntry.getListener() instanceof IEventFireDelegate) {
+ // The listener is a fire delegate -> use it itself to fire the runnable
+ ((IEventFireDelegate)listEntry.getListener()).fire(runnable);
+ } else {
+ // Listener isn't a fire delegate -> fire the runnable directly
+ runnable.run();
+ }
+ }
+ }
+
+ /*
+ * Register change listeners defined by extension.
+ */
+ private void addExtensionPointNotificationListeners() {
+ IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.tm.te.runtime.eventListeners"); //$NON-NLS-1$
+ if (ep != null) {
+ IExtension[] extensions = ep.getExtensions();
+ if (extensions != null && extensions.length > 0) {
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] configElements = extension.getConfigurationElements();
+ if (configElements != null && configElements.length > 0) {
+ for (IConfigurationElement configElement : configElements) {
+ String name = configElement.getName();
+ if ("eventListener".equals(name)) { //$NON-NLS-1$
+ // try to read the "eventType" and "eventSourceType" configuration elements if any.
+ List<Class<?>> eventTypes = new ArrayList<Class<?>>();
+ List<Class<?>> eventSourceTypes = new ArrayList<Class<?>>();
+
+ IConfigurationElement[] children = configElement.getChildren();
+ for (IConfigurationElement child : children) {
+ if ("eventType".equals(child.getName())) { //$NON-NLS-1$
+ // The event types, we have to instantiate here as we need the class object!
+ try {
+ // First we try to instantiate the class using our own local class loader.
+ // This trick can avoid activating the contributing plugin if we can load
+ // the class ourself.
+ // First we try to instantiate the class using our own context
+ String className = child.getAttribute("class"); //$NON-NLS-1$
+ if (className == null || className.trim().length() == 0) {
+ continue;
+ }
+
+ String bundleId = child.getAttribute("bundleId"); //$NON-NLS-1$
+
+ // If a bundle id got specified, use the specified bundle to load the service class
+ Bundle bundle = bundleId != null ? bundle = Platform.getBundle(bundleId) : null;
+ // If we don't have a bundle to load from yet, fallback to the declaring bundle
+ if (bundle == null) bundle = Platform.getBundle(child.getDeclaringExtension().getNamespaceIdentifier());
+ // And finally, use our own bundle to load the class. This fallback is expected
+ // to never be used.
+ if (bundle == null) bundle = CoreBundleActivator.getContext().getBundle();
+
+ // Try to load the event type class now
+ Class<?> eventType = bundle != null ? bundle.loadClass(className) : Class.forName(className);
+ if (!eventTypes.contains(eventType)) {
+ eventTypes.add(eventType);
+ }
+ } catch (Exception ex) {
+ if (isTracingEnabled())
+ CoreBundleActivator.getTraceHandler().trace("Error instantiating event listener event type object instance: " + child.getAttribute("class"), //$NON-NLS-1$ //$NON-NLS-2$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.ERROR, this);
+ }
+ }
+
+ if ("eventSourceType".equals(child.getName())) { //$NON-NLS-1$
+ // The event source types, we have to instantiate here as we need the class object!
+ try {
+ // First we try to instantiate the class using our own local class loader.
+ // This trick can avoid activating the contributing plugin if we can load
+ // the class ourself.
+ // First we try to instantiate the class using our own context
+ String className = child.getAttribute("class"); //$NON-NLS-1$
+ if (className == null || className.trim().length() == 0) {
+ continue;
+ }
+
+ String bundleId = child.getAttribute("bundleId"); //$NON-NLS-1$
+
+ // If a bundle id got specified, use the specified bundle to load the service class
+ Bundle bundle = bundleId != null ? bundle = Platform.getBundle(bundleId) : null;
+ // If we don't have a bundle to load from yet, fallback to the declaring bundle
+ if (bundle == null) bundle = Platform.getBundle(child.getDeclaringExtension().getNamespaceIdentifier());
+ // And finally, use our own bundle to load the class. This fallback is expected
+ // to never be used.
+ if (bundle == null) bundle = CoreBundleActivator.getContext().getBundle();
+
+ // Try to load the event source type class now
+ Class<?> eventSourceType = bundle != null ? bundle.loadClass(className) : Class.forName(className);
+ if (!eventSourceTypes.contains(eventSourceType)) {
+ eventSourceTypes.add(eventSourceType);
+ }
+ } catch (Exception ex) {
+ if (isTracingEnabled())
+ CoreBundleActivator.getTraceHandler().trace("Error instantiating event listener event source type object instance: " + child.getAttribute("class"), //$NON-NLS-1$ //$NON-NLS-2$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.ERROR, this);
+ }
+ }
+ }
+
+ // For extension point contributed event listeners, we use delegating
+ // event listener instances
+ IEventListener listener = new EventListenerProxy(configElement);
+ addEventListener(listener,
+ !eventTypes.isEmpty() ? eventTypes.toArray(new Class[eventTypes.size()]) : null,
+ !eventSourceTypes.isEmpty() ? eventSourceTypes.toArray(new Class[eventSourceTypes.size()]) : null
+ );
+
+ if (isTracingEnabled())
+ CoreBundleActivator.getTraceHandler().trace("Add extension point change listener: " + configElement.getAttribute("class"), //$NON-NLS-1$ //$NON-NLS-2$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.INFO, this);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Internal class used to delay the instantiation and plugin activation of
+ * event listeners which are contributed via extension point till they
+ * are really fired.
+ */
+ private class EventListenerProxy implements IEventListener, IEventFireDelegate {
+ private final IConfigurationElement configElement;
+ private IEventListener delegate;
+
+ /**
+ * Constructor.
+ *
+ * @param configElement The contributing configuration element of the encapsulated event listener.
+ * Must not be <code>null</code>.
+ */
+ public EventListenerProxy(IConfigurationElement configElement) {
+ Assert.isNotNull(configElement);
+ this.configElement = configElement;
+ delegate = null;
+ }
+
+ /**
+ * Returns the event listener delegate and instantiate the delegate
+ * if not yet done.
+ *
+ * @return The event listener delegate or <code>null</code> if the instantiation fails.
+ */
+ private IEventListener getDelegate() {
+ if (delegate == null) {
+ // Check the contributing plug-in state
+ boolean forcePluginActivation = Boolean.parseBoolean(configElement.getAttribute("forcePluginActivation")); //$NON-NLS-1$
+ if (!forcePluginActivation) {
+ Bundle bundle = Platform.getBundle(configElement.getContributor().getName());
+ forcePluginActivation = bundle != null ? bundle.getState() == Bundle.ACTIVE : false;
+ }
+ // Load the event listener implementation class if plugin activations is allowed.
+ if (forcePluginActivation) {
+ try {
+ Object executable = configElement.createExecutableExtension("class"); //$NON-NLS-1$
+ if (executable instanceof IEventListener) {
+ delegate = (IEventListener)executable;
+ }
+ } catch (Exception ex) {
+ if (isTracingEnabled())
+ CoreBundleActivator.getTraceHandler().trace("Error instantiating extension point event listener: " + configElement.getAttribute("class") //$NON-NLS-1$ //$NON-NLS-2$
+ + "(Possible Cause: " + ex.getLocalizedMessage() + ")", //$NON-NLS-1$ //$NON-NLS-2$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.ERROR, this);
+ }
+ }
+ }
+
+ return delegate;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject)
+ */
+ @Override
+ public void eventFired(EventObject event) {
+ Assert.isNotNull(event);
+ // Get the delegate (may force instantiation)
+ IEventListener delegate = getDelegate();
+ // And pass on the event to the delegate if we got a valid delegate
+ if (delegate != null) delegate.eventFired(event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.events.IEventFireDelegate#fire(java.lang.Runnable)
+ */
+ @Override
+ public void fire(Runnable runnable) {
+ Assert.isNotNull(runnable);
+ // Pass on to the delegate if the delegate itself is an fire delegate,
+ if (getDelegate() instanceof IEventFireDelegate) {
+ ((IEventFireDelegate)getDelegate()).fire(runnable);
+ }
+ else {
+ runnable.run();
+ }
+ }
+ }
+
+ /**
+ * Return <code>true</code> if the tracing mode is enabled for the
+ * event manager and trace messages shall be printed to the debug console.
+ */
+ public static boolean isTracingEnabled() {
+ return CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_EVENTS);
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/PropertyChangeEvent.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/PropertyChangeEvent.java
new file mode 100644
index 000000000..8f79ea0f9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/events/PropertyChangeEvent.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.events;
+
+import java.util.EventObject;
+
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * Property change event implementation.
+ */
+public class PropertyChangeEvent extends EventObject {
+ private static final long serialVersionUID = -7859159130977760588L;
+
+ private Object eventId;
+ private Object oldValue;
+ private Object newValue;
+
+ /**
+ * Constructor.
+ *
+ * @param source The source object. Must not be <code>null</code>.
+ * @param eventId The event id. Must not be <code>null</code>.
+ * @param oldValue The old value.
+ * @param newValue The new value.
+ *
+ * @exception IllegalArgumentException if eventId == null.
+ */
+ public PropertyChangeEvent(Object source, Object eventId, Object oldValue, Object newValue) {
+ super(source);
+
+ if (eventId == null)
+ throw new IllegalArgumentException("null eventId"); //$NON-NLS-1$
+
+ this.eventId = eventId;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ /**
+ * Returns the event id.
+ *
+ * @return The event id.
+ */
+ public final Object getEventId() {
+ return eventId;
+ }
+
+ /**
+ * Returns the old value.
+ *
+ * @return The old value or <code>null</code>.
+ */
+ public final Object getOldValue() {
+ return oldValue;
+ }
+
+ /**
+ * Returns the new value.
+ *
+ * @return The new value or <code>null</code>.
+ */
+ public final Object getNewValue() {
+ return newValue;
+ }
+
+ /*
+ * Formats a value due to its type.
+ */
+ private Object formatValue(Object value) {
+ Object formattedValue = value;
+ if (value != null && value.getClass().isArray()) {
+ StringBuilder str = new StringBuilder();
+ str.append("{"); //$NON-NLS-1$
+ for (int i = 0; i < ((Object[]) value).length; i++) {
+ if (i > 0) str.append(","); //$NON-NLS-1$
+ str.append(formatValue(((Object[]) value)[i]));
+ }
+ str.append("}"); //$NON-NLS-1$
+ formattedValue = str.toString();
+ }
+ return formattedValue;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.EventObject#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder toString = new StringBuilder(getClass().getName());
+
+ String prefix = ""; //$NON-NLS-1$
+ // if tracing the event, formating them a little bit better readable.
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_EVENTS))
+ prefix = "\n\t\t"; //$NON-NLS-1$
+
+ toString.append(prefix + "{eventId="); //$NON-NLS-1$
+ toString.append(eventId);
+ toString.append("," + prefix + "source="); //$NON-NLS-1$ //$NON-NLS-2$
+ toString.append(source);
+ toString.append("," + prefix + "oldValue="); //$NON-NLS-1$ //$NON-NLS-2$
+ toString.append(formatValue(oldValue));
+ toString.append("," + prefix + "newValue="); //$NON-NLS-1$ //$NON-NLS-2$
+ toString.append(formatValue(newValue));
+ toString.append("}"); //$NON-NLS-1$
+
+ return toString.toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/AbstractExtensionPointManager.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/AbstractExtensionPointManager.java
new file mode 100644
index 000000000..1c0bc7554
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/AbstractExtensionPointManager.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.extensions;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.nls.Messages;
+
+/**
+ * Target Explorer: Abstract extension point manager implementation.
+ */
+public abstract class AbstractExtensionPointManager<V> {
+ // Flag to mark the extension point manager initialized (extensions loaded).
+ private boolean initialized = false;
+ // The map of loaded extension listed by their unique id's
+ private Map<String, ExecutableExtensionProxy<V>> extensionsMap = new LinkedHashMap<String, ExecutableExtensionProxy<V>>();
+
+ /**
+ * Constructor.
+ */
+ public AbstractExtensionPointManager() {
+ }
+
+ /**
+ * Returns if or if not the extension point manager got initialized already.
+ * <p>
+ * Initialized means that the manager read the extensions for the managed extension point.
+ *
+ * @return <code>True</code> if already initialized, <code>false</code> otherwise.
+ */
+ protected boolean isInitialized() {
+ return initialized;
+ }
+
+ /**
+ * Sets if or if not the extension point manager is initialized.
+ * <p>
+ * Initialized means that the manager has read the extensions for the managed extension point.
+ *
+ * @return <code>True</code> to set the extension point manager is initialized, <code>false</code> otherwise.
+ */
+ protected void setInitialized(boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ /**
+ * Returns the map of managed extensions. If not loaded before,
+ * this methods trigger the loading of the extensions to the managed
+ * extension point.
+ *
+ * @return The map of extensions.
+ */
+ protected Map<String, ExecutableExtensionProxy<V>> getExtensions() {
+ // Load and store the extensions thread-safe!
+ synchronized (extensionsMap) {
+ if (!isInitialized()) { loadExtensions(); setInitialized(true); }
+ }
+ return extensionsMap;
+ }
+
+ /**
+ * Returns the extension point id to read. The method
+ * must return never <code>null</code>.
+ *
+ * @return The extension point id.
+ */
+ protected abstract String getExtensionPointId();
+
+ /**
+ * Returns the configuration element name. The method
+ * must return never <code>null</code>.
+ *
+ * @return The configuration element name.
+ */
+ protected abstract String getConfigurationElementName();
+
+ /**
+ * Creates the extension proxy instance.
+ *
+ * @param element The configuration element of the extension. Must not be <code>null</code>.
+ * @return The extension proxy instance.
+ *
+ * @throws CoreException If the extension proxy instantiation failed.
+ */
+ protected ExecutableExtensionProxy<V> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ Assert.isNotNull(element);
+ return new ExecutableExtensionProxy<V>(element);
+ }
+
+ /**
+ * Store the given extension to the given extensions store. Checks if an extension with the same id does exist
+ * already and throws an exception in this case.
+ *
+ * @param extensions The extensions store. Must not be <code>null</code>.
+ * @param candidate The extension. Must not be <code>null</code>.
+ * @param element The configuration element. Must not be <code>null</code>.
+ *
+ * @throws CoreException In case a extension with the same id as the given extension already exist.
+ */
+ protected void doStoreExtensionTo(Map<String, ExecutableExtensionProxy<V>> extensions, ExecutableExtensionProxy<V> candidate, IConfigurationElement element) throws CoreException {
+ Assert.isNotNull(extensions);
+ Assert.isNotNull(candidate);
+ Assert.isNotNull(element);
+
+ // If no extension with this id had been registered before, register now.
+ if (!extensions.containsKey(candidate.getId())) {
+ extensions.put(candidate.getId(), candidate);
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_duplicateExtension, candidate.getId(), element.getContributor().getName()),
+ null));
+ }
+ }
+
+ /**
+ * Loads the extensions for the managed extension point.
+ */
+ protected void loadExtensions() {
+ // If already initialized, this method will do nothing.
+ if (isInitialized()) return;
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint point = registry.getExtensionPoint(getExtensionPointId());
+ if (point != null) {
+ IExtension[] extensions = point.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if (getConfigurationElementName().equals(element.getName())) {
+ try {
+ ExecutableExtensionProxy<V> candidate = doCreateExtensionProxy(element);
+ if (candidate.getId() != null) {
+ doStoreExtensionTo(extensionsMap, candidate, element);
+ } else {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getAttribute("label")), //$NON-NLS-1$ //$NON-NLS-2$
+ null));
+ }
+ } catch (CoreException e) {
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtension.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtension.java
new file mode 100644
index 000000000..7d789d6b6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtension.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.extensions;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.extensions.IExecutableExtension;
+import org.eclipse.tm.te.runtime.nls.Messages;
+
+/**
+ * Target Explorer: Executable extension implementation.
+ */
+public class ExecutableExtension extends PlatformObject implements IExecutableExtension {
+ // The mandatory id of the extension
+ private String id = null;
+
+ // The configuration element
+ private IConfigurationElement configElement = null;
+
+ /**
+ * Clone the initialization data to the given executable extension instance.
+ *
+ * @param other The destination executable extension instance. Must not be <code>null</code>.
+ */
+ public void cloneInitializationData(ExecutableExtension other) {
+ Assert.isNotNull(other);
+ other.id = id;
+ other.configElement = configElement;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+ // Remember the configuration element
+ configElement = config;
+
+ // Initialize the id field by reading the <id> extension attribute.
+ // Throws an exception if the id is empty or null.
+ id = configElement != null ? configElement.getAttribute("id") : null; //$NON-NLS-1$
+ if (id == null || (id != null && "".equals(id.trim()))) { //$NON-NLS-1$
+ throw createMissingMandatoryAttributeException("id", config.getContributor().getName()); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Creates a new {@link CoreException} to be thrown if a mandatory extension attribute
+ * is missing.
+ *
+ * @param attributeName The attribute name. Must not be <code>null</code>.
+ * @param extensionId The extension id. Must not be <code>null</code>.
+ *
+ * @return The {@link CoreException} instance.
+ */
+ protected CoreException createMissingMandatoryAttributeException(String attributeName, String extensionId) {
+ Assert.isNotNull(attributeName);
+ Assert.isNotNull(extensionId);
+
+ return new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, attributeName, extensionId),
+ null));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.extensions.IExecutableExtension#getId()
+ */
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the configuration element of the extension. The method
+ * does return <code>null</code> if {@link #setInitializationData(IConfigurationElement, String, Object)}
+ * has not been called yet.
+ *
+ * @return The configuration element or <code>null</code> if none.
+ */
+ protected final IConfigurationElement getConfigElement() {
+ return configElement;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.extensions.IExecutableExtension#getLabel()
+ */
+ @Override
+ public String getLabel() {
+ // Try the "label" attribute first
+ String label = configElement != null ? configElement.getAttribute("label") : null; //$NON-NLS-1$
+ // If "label" is not found or empty, try the "name" attribute as fallback
+ if (label == null || "".equals(label.trim())) { //$NON-NLS-1$
+ label = configElement != null ? configElement.getAttribute("name") : null; //$NON-NLS-1$
+ }
+ return label != null ? label.trim() : ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.extensions.IExecutableExtension#getDescription()
+ */
+ @Override
+ public String getDescription() {
+ // Read the description text from the "<description>" child element
+ IConfigurationElement[] children = configElement != null ? configElement.getChildren("description") : null; //$NON-NLS-1$
+ // Only one description element is allow. All other will be ignored
+ if (children != null && children.length > 0) {
+ IConfigurationElement description = children[0];
+ String value = description.getValue();
+ return value != null ? value.trim() : ""; //$NON-NLS-1$
+ }
+
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtensionProxy.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtensionProxy.java
new file mode 100644
index 000000000..d6cfe1330
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/extensions/ExecutableExtensionProxy.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.extensions;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.nls.Messages;
+
+
+/**
+ * Target Explorer: Executable extension proxy implementation.
+ */
+public class ExecutableExtensionProxy<V> {
+ // The extension instance. Created on first access
+ private V instance;
+ // The configuration element
+ private final IConfigurationElement element;
+ // The unique id of the extension.
+ private String id;
+
+ /**
+ * Constructor.
+ *
+ * @param element The configuration element. Must not be <code>null</code>.
+ * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
+ */
+ public ExecutableExtensionProxy(IConfigurationElement element) throws CoreException {
+ Assert.isNotNull(element);
+ this.element = element;
+
+ // Extract the extension attributes
+ id = element.getAttribute("id"); //$NON-NLS-1$
+ if (id == null || id.trim().length() == 0) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ 0,
+ NLS.bind(Messages.Extension_error_missingRequiredAttribute, "id", element.getContributor().getName()), //$NON-NLS-1$
+ null));
+ }
+
+ instance = null;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id The id for this instance.
+ * @param instance The instance to add to proxy.
+ */
+ public ExecutableExtensionProxy(String id, V instance) {
+ Assert.isNotNull(id);
+ Assert.isNotNull(instance);
+ this.id = id;
+ this.instance = instance;
+ this.element = null;
+ }
+
+ /**
+ * Returns the extensions unique id.
+ *
+ * @return The unique id.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the configuration element for this extension.
+ *
+ * @return The configuration element.
+ */
+ public IConfigurationElement getConfigurationElement() {
+ return element;
+ }
+
+ /**
+ * Reset the extension instance to <code>null</code> and force the
+ * creation of a new extension instance on the next {@link #getInstance()}
+ * method invocation.
+ *
+ * @return The current extension instance or <code>null</code> if none.
+ */
+ public V reset() {
+ V oldExtension = instance;
+ instance = null;
+ return oldExtension;
+ }
+
+ /**
+ * Returns the extension class instance. The contributing
+ * plug-in will be activated if not yet activated anyway.
+ *
+ * @return The extension class instance or <code>null</code> if the instantiation fails.
+ */
+ public V getInstance() {
+ if (instance == null) instance = newInstance();
+ return instance;
+ }
+
+ /**
+ * Returns always a new extension class instance which is different
+ * to what {@link #getInstance()} would return.
+ *
+ * @return A new extension class instance or <code>null</code> if the instantiation fails.
+ */
+ public V newInstance() {
+ IConfigurationElement element = getConfigurationElement();
+ Assert.isNotNull(element);
+ // The "class" to load can be specified either as attribute or as child element
+ if (element != null && (element.getAttribute("class") != null || element.getChildren("class").length > 0)) { //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ return (V)element.createExecutableExtension("class"); //$NON-NLS-1$
+ } catch (Exception e) {
+ // Possible exceptions: CoreException, ClassCastException.
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(new Status(IStatus.ERROR,
+ CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.Extension_error_invalidExtensionPoint, element.getDeclaringExtension().getUniqueIdentifier()), e));
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ // Proxie's are equal if they have encapsulate an element
+ // with the same unique id
+ if (obj instanceof ExecutableExtensionProxy<?>) {
+ return getId().equals(((ExecutableExtensionProxy<?>)obj).getId());
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ // The hash code of a proxy is the one from the id
+ return getId().hashCode();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/IConditionTester.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/IConditionTester.java
new file mode 100644
index 000000000..4b200a9ff
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/IConditionTester.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.interfaces;
+
+/**
+ * This interface must be implemented by callers of the executors utilities
+ * <code>wait</code> method.
+ * <p>
+ * The call to <code>isConditionFulfilled</code> must return <code>true</code> only
+ * if the desired condition, the caller want's to wait for, has been completely fulfilled!
+ */
+public interface IConditionTester {
+ /**
+ * Returns <code>true</code> if the desired condition, the caller want's to wait
+ * for, has been completely fulfilled.
+ */
+ public boolean isConditionFulfilled();
+
+ /**
+ * Condition tester clean up. This method is called before any waiter method will
+ * be finally left.
+ */
+ public void cleanup();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/callback/ICallback.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/callback/ICallback.java
new file mode 100644
index 000000000..ce0d9855e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/callback/ICallback.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.interfaces.callback;
+
+import javax.security.auth.callback.Callback;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tm.te.runtime.interfaces.properties.IPropertiesContainer;
+
+
+/**
+ * Generic callback interface for asynchronous calls.
+ *
+ * @noimplement Not intended to be implemented by clients, use {@link Callback} as base implementation instead.
+ * @noextend
+ */
+public interface ICallback extends IPropertiesContainer {
+
+ /**
+ * Returns if or if not the callbacks <code>done</code> method
+ * was called already.
+ *
+ * @return <code>True</code> if {@link #done(Object, IStatus)} was called already, <code>false</code> otherwise.
+ */
+ public boolean isDone();
+
+ /**
+ * Callback method invoked when a request is completed.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param status
+ * The status. Must not be <code>null</code>.
+ */
+ public void done(Object caller, IStatus status);
+
+ /**
+ * Add an additional parent callback to the end of the parent callback list.
+ *
+ * @param callback
+ * The parent callback. Must not be <code>null</code>.
+ */
+ public void addParentCallback(ICallback callback);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventFireDelegate.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventFireDelegate.java
new file mode 100644
index 000000000..3eb6d5938
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventFireDelegate.java
@@ -0,0 +1,31 @@
+/**
+ * IWRNotificationFireDelegateListener.java
+ * Created on Sep 14, 2006
+ *
+ * Copyright (c) 2006 - 2009 Wind River Systems, Inc.
+ *
+ * The right to copy, distribute, modify, or otherwise make use
+ * of this software may be licensed only pursuant to the terms
+ * of an applicable Wind River license agreement.
+ */
+package org.eclipse.tm.te.runtime.interfaces.events;
+
+/**
+ * Common interface for notification fire delegate listeners.<br>
+ * If a notification listener additionally implements this interface, the notification
+ * manager will call the {@link #fire(Runnable)} method to delegate the thread
+ * handling.
+ *
+ * @author tobias.schwarz@windriver.com
+ */
+public interface IEventFireDelegate {
+
+ /**
+ * Fire the given runnable. If the given runnable is <code>null</code>,
+ * the method should return immediatelly. The implementator of the
+ * interface is responsible for the thread-handling.
+ *
+ * @param runnable The runnable that should be started for notification or <code>null</code>.
+ */
+ public void fire(final Runnable runnable);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventListener.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventListener.java
new file mode 100644
index 000000000..c5c9135f7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/events/IEventListener.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.tm.te.runtime.interfaces.events;
+
+import java.util.EventListener;
+import java.util.EventObject;
+
+/**
+ * Interface to be implemented by event listeners.
+ */
+public interface IEventListener extends EventListener{
+
+ /**
+ * Invoked by the event manager if the event listener registration
+ * applies for the given event object.
+ *
+ * @param event The event. Must not be <code>null</code>.
+ */
+ public void eventFired(EventObject event);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/extensions/IExecutableExtension.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/extensions/IExecutableExtension.java
new file mode 100644
index 000000000..56773775b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/extensions/IExecutableExtension.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.interfaces.extensions;
+
+
+/**
+ * Target Explorer: Executable extension public interface declaration.
+ */
+public interface IExecutableExtension extends org.eclipse.core.runtime.IExecutableExtension {
+
+ /**
+ * Returns the unique id of the extension. The returned
+ * id must be never <code>null</code> or an empty string.
+ *
+ * @return The unique id.
+ */
+ public String getId();
+
+ /**
+ * Returns the label or UI name of the extension.
+ *
+ * @return The label or UI name. An empty string if not set.
+ */
+ public String getLabel();
+
+ /**
+ * Returns the description of the extension.
+ *
+ * @return The description or an empty string.
+ */
+ public String getDescription();
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/properties/IPropertiesContainer.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/properties/IPropertiesContainer.java
new file mode 100644
index 000000000..cc4a2b8af
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/properties/IPropertiesContainer.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.interfaces.properties;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * A generic properties container.
+ */
+public interface IPropertiesContainer extends IAdaptable {
+
+ /**
+ * Returns the unique identified of the properties container.
+ *
+ * @return The unique identifier.
+ */
+ public UUID getUUID();
+
+ /**
+ * Set if or if not firing change events is enabled.
+ *
+ * @param param enabled <code>True</code> to enable the change events, <code>false</code> to disable the change events.
+ * @return <code>True</code> if the enablement has changed, <code>false</code> if not.
+ */
+ public boolean setChangeEventsEnabled(boolean enabled);
+
+ /**
+ * Returns if or if not firing change events is enabled.
+ *
+ * @return <code>True</code> if change events are enabled, <code>false</code> if disabled.
+ */
+ public boolean changeEventsEnabled();
+
+ /**
+ * Set the properties from the given map. Calling this method
+ * will overwrite all previous set properties.
+ *
+ * @param properties The map of properties to set. Must not be <code>null</code>.
+ */
+ public void setProperties(Map<String, Object> properties);
+
+ /**
+ * Stores the property under the given property key using the given property value.
+ * If the current property value is equal to the given property value, no store
+ * operation will be executed. If the property value is not <code>null</code> and
+ * is different from the current property value, the new value will be written to
+ * the property store and a property change event is fired. If the property value
+ * is <code>null</code>, the property key and the currently stored value are removed
+ * from the property store.
+ *
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ */
+ public boolean setProperty(String key, Object value);
+
+ /**
+ * Stores the property under the given property key using the given long
+ * property value. The given long value is transformed to an <code>Long</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, long value);
+
+ /**
+ * Stores the property under the given property key using the given integer
+ * property value. The given integer value is transformed to an <code>Integer</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, int value);
+
+ /**
+ * Stores the property under the given property key using the given boolean
+ * property value. The given boolean value is transformed to an <code>Boolean</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, boolean value);
+
+ /**
+ * Stores the property under the given property key using the given float
+ * property value. The given float value is transformed to an <code>Float</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, float value);
+
+ /**
+ * Stores the property under the given property key using the given double
+ * property value. The given double value is transformed to an <code>Double</code>
+ * object and stored to the properties store via <code>setProperty(java.lang.String, java.lang.Object)</code>.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @param value The property value.
+ * @return <code>true</code> if the property value had been applied to the property store, <code>false</code> otherwise.
+ *
+ * @see <code>setProperty(java.lang.String, java.lang.Object)</code>
+ */
+ public boolean setProperty(String key, double value);
+
+ /**
+ * Return all properties. The result map is read-only.
+ *
+ * @return A map containing all properties.
+ */
+ public Map<String, Object> getProperties();
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * does not exist, <code>null</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value or <code>null</code>.
+ */
+ public Object getProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.String</code>, the property value casted to
+ * <code>java.lang.String</code> is returned. In all other cases, <code>null</code>
+ * is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value casted <code>java.lang.String</code> or <code>null</code>.
+ */
+ public String getStringProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Long</code>, the property value converted
+ * to an long value is returned. In all other cases, <code>-1</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value converted to a long value or <code>-1</code>.
+ */
+ public long getLongProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Integer</code>, the property value converted
+ * to an integer value is returned. In all other cases, <code>-1</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value converted to an integer value or <code>-1</code>.
+ */
+ public int getIntProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Boolean</code>, the property value converted
+ * to an boolean value is returned. In all other cases, <code>false</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value converted to an boolean value or <code>false</code>.
+ */
+ public boolean getBooleanProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Float</code>, the property value converted
+ * to an float value is returned. In all other cases, <code>Float.NaN</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value converted to a float value or <code>Float.NaN</code>.
+ */
+ public float getFloatProperty(String key);
+
+ /**
+ * Queries the property value stored under the given property key. If the property
+ * exist and is of type <code>java.lang.Double</code>, the property value converted
+ * to an double value is returned. In all other cases, <code>Double.NaN</code> is returned.
+ *
+ * @param key The property key. Must not be <code>null</code>!
+ * @return The stored property value converted to a double value or <code>Double.NaN</code>.
+ */
+ public double getDoubleProperty(String key);
+
+ /**
+ * Remove all properties from the properties store. The method does not fire any
+ * properties changed event.
+ */
+ public void clearProperties();
+
+ /**
+ * Test if the property value stored under the given property is equal ignoring the case to the given
+ * expected string value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property string value.
+ * @return <code>true</code> if the expected string value is equal ignoring the case to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isPropertyIgnoreCase(String key, String value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, Object value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, long value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, int value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, boolean value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, float value);
+
+ /**
+ * Test if the property value stored under the given property is equal to the given
+ * expected value.
+ *
+ * @param key The property key. Must not be <code>null</code>.
+ * @param value The expected property value.
+ * @return <code>true</code> if the expected value is equal to the stored property value, <code>false</code> otherwise.
+ */
+ public boolean isProperty(String key, double value);
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/tracing/ITraceIds.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/tracing/ITraceIds.java
new file mode 100644
index 000000000..b613177d5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/interfaces/tracing/ITraceIds.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.interfaces.tracing;
+
+/**
+ * Target Explorer: Runtime plug-in trace slot identifiers.
+ */
+public interface ITraceIds {
+
+ /**
+ * If activated, trace information about event dispatching is printed out.
+ */
+ public static final String TRACE_EVENTS = "trace/events"; //$NON-NLS-1$
+
+ /**
+ * If activated, trace information about asynchronous callbacks is printed out.
+ */
+ public static final String TRACE_CALLBACKS = "trace/callbacks"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/DebugEventListener.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/DebugEventListener.java
new file mode 100644
index 000000000..ca4b43121
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/DebugEventListener.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.internal;
+
+import java.util.EventObject;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.interfaces.events.IEventListener;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * Event listener for internal debugging purpose.
+ */
+public class DebugEventListener implements IEventListener {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject)
+ */
+ @Override
+ public void eventFired(EventObject event) {
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_EVENTS))
+ CoreBundleActivator.getTraceHandler().trace("thread=[" + Thread.currentThread().getName() + "]\n\t" + event.toString(), //$NON-NLS-1$ //$NON-NLS-2$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.INFO, this);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PreferencesPropertyTester.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PreferencesPropertyTester.java
new file mode 100644
index 000000000..a119f4e9f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PreferencesPropertyTester.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.tm.te.runtime.internal;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.preferences.ScopedEclipsePreferences;
+
+/**
+ * Preferences property tester implementation.
+ */
+public class PreferencesPropertyTester extends PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ // The preferences property tester is not extending a specific object type.
+ // The tester ignores the given receiver object.
+
+ if ("preference".equals(property)) { //$NON-NLS-1$
+ String bundleId = CoreBundleActivator.getUniqueIdentifier();
+ String key = null;
+
+ // Search the args for bundle id, the preference type and the preference key
+ for (Object candidate : args) {
+ // We cannot handle arguments other than strings
+ if (!(candidate instanceof String)) continue;
+
+ String arg = (String)candidate;
+
+ // bundleId=<id>
+ if (arg.toLowerCase().startsWith("bundleid")) { //$NON-NLS-1$
+ String[] tokens = arg.split("=", 2); //$NON-NLS-1$
+ // Check if the given bundle id really resolves to an installed bundle
+ if (tokens.length == 2 && tokens[1] != null && Platform.getBundle(tokens[1].trim()) != null) {
+ bundleId = tokens[1].trim();
+ }
+ }
+
+ // key=<preference key>
+ if (arg.toLowerCase().startsWith("key")) { //$NON-NLS-1$
+ String[] tokens = arg.split("=", 2); //$NON-NLS-1$
+ // Check for the key not being empty or null
+ if (tokens.length == 2 && tokens[1] != null && !"".equals(tokens[1].trim())) { //$NON-NLS-1$
+ key = tokens[1].trim();
+ }
+ }
+ }
+
+ // Lookup the preference
+ if (key != null) {
+ // Check the preference within the instance and default scope
+ ScopedEclipsePreferences preferences = new ScopedEclipsePreferences(bundleId);
+ // If the expected value is not specified or "null", check if the preference
+ // key is set or not. Return "true" if the key is not set.
+ if (expectedValue == null || "null".equals(expectedValue)) return !preferences.containsKey(key); //$NON-NLS-1$
+
+ // Always check against the string value
+ return expectedValue.toString().equals(preferences.getString(key));
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PropertiesContainerPropertyTester.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PropertiesContainerPropertyTester.java
new file mode 100644
index 000000000..bfbc8ae6e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/internal/PropertiesContainerPropertyTester.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.internal;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tm.te.runtime.interfaces.properties.IPropertiesContainer;
+
+/**
+ * Property tester implementation for objects of type {@link IPropertiesContainer}.
+ */
+public class PropertiesContainerPropertyTester extends PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ // The receiver is expected to be a properties container
+ if (receiver instanceof IPropertiesContainer) {
+
+ if ("isProperty".equals(property)) { // //$NON-NLS-1$
+ // Test for an individual property within the property container
+ return testIsProperty((IPropertiesContainer)receiver, args, expectedValue);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test the specific model node properties.
+ *
+ * @param node The properties container. Must not be <code>null</code>.
+ * @param args The property arguments.
+ * @param expectedValue The expected value.
+ *
+ * @return <code>True</code> if the property to test has the expected value, <code>false</code> otherwise.
+ */
+ protected boolean testIsProperty(IPropertiesContainer node, Object[] args, Object expectedValue) {
+ assert node != null;
+
+ if (args != null && args.length > 0 && args[0] instanceof String) {
+ return node.isProperty((String)args[0], expectedValue);
+ }
+
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.java
new file mode 100644
index 000000000..7763b0a82
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Target Explorer Runtime plugin externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tm.te.runtime.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String Extension_error_missingRequiredAttribute;
+ public static String Extension_error_duplicateExtension;
+ public static String Extension_error_invalidExtensionPoint;
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.properties
new file mode 100644
index 000000000..0867746ba
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/nls/Messages.properties
@@ -0,0 +1,8 @@
+#
+# org.eclipse.tm.te.runtime
+# Externalized Strings.
+#
+
+Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"!
+Extension_error_duplicateExtension=Duplicate extension with id ''{0}''. Ignoring duplicated contribution from contributor ''{1}''!
+Extension_error_invalidExtensionPoint=Failed to instantiate the executable extension from extension point ''{0}''.
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/preferences/ScopedEclipsePreferences.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/preferences/ScopedEclipsePreferences.java
new file mode 100644
index 000000000..7d3c9ff20
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/preferences/ScopedEclipsePreferences.java
@@ -0,0 +1,459 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.preferences;
+
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.IPreferenceFilter;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Helper class to handle scoped Eclipse preferences for plug-in's. Scoped
+ * preferences means a given preference context plus the default preferences
+ * scope.
+ * <p>
+ * On changes a {@link PreferenceChangeEvent} is sent to inform all listeners of the change.
+ *
+ * @see IEclipsePreferences
+ * @see IEclipsePreferences.PreferenceChangeEvent
+ * @see IEclipsePreferences.IPreferenceChangeListener
+ */
+public class ScopedEclipsePreferences {
+ /**
+ * The preferences scope qualifier.
+ */
+ private final String qualifier;
+
+ /**
+ * The default scope preference node.
+ */
+ protected final IEclipsePreferences defaultPrefs;
+
+ /**
+ * The context scope preference node.
+ */
+ protected final IEclipsePreferences contextScopePrefs;
+
+ /**
+ * The registered preference change listeners.
+ */
+ private final ListenerList listeners = new ListenerList();
+
+ /**
+ * Constructor.
+ * <p>
+ * Initialize the scoped preferences with a new instance scope for the given qualifier. The default
+ * scope is determined by calling <code>DefaultScope().getNode(qualifier)</code>.
+ *
+ * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be <code>null</code>.
+ */
+ public ScopedEclipsePreferences(String qualifier) {
+ this(InstanceScope.INSTANCE, qualifier);
+ }
+
+ /**
+ * Constructor.
+ * <p>
+ * Initialize the scoped preferences with the given scope. The default scope
+ * is determined by calling <code>DefaultScope().getNode(qualifier)</code>.
+ *
+ * @param context The preference scope context. Must not be <code>null</code>.
+ * @param qualifier The qualifier for the preferences (in example the unique identifier of a plugin). Must not be <code>null</code>.
+ */
+ public ScopedEclipsePreferences(IScopeContext context, String qualifier) {
+ Assert.isNotNull(context);
+ Assert.isNotNull(qualifier);
+ this.qualifier = qualifier;
+ defaultPrefs = DefaultScope.INSTANCE.getNode(getQualifier());
+ contextScopePrefs = context.getNode(getQualifier());
+ }
+
+ /**
+ * Returns the qualifier that is used to get the preferences.
+ * For plugin preferences, this is the unique identifier of the plugin.
+ */
+ protected final String getQualifier() {
+ return qualifier;
+ }
+
+ /**
+ * Exports the preferences to the stream.
+ * <p>
+ * <b>Note:</b> The stream will be closed after the export.
+ *
+ * @param stream The stream to where preferences and defaults should be exported.
+ */
+ public void exportPreferences(OutputStream stream) {
+ Assert.isNotNull(stream);
+ try {
+ IPreferenceFilter filter = new IPreferenceFilter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getScopes()
+ */
+ @Override
+ public String[] getScopes() {
+ return new String[] { InstanceScope.SCOPE };
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.IPreferenceFilter#getMapping(java.lang.String)
+ */
+ @Override
+ public Map getMapping(String scope) {
+ return null;
+ }
+ };
+
+ Platform.getPreferencesService().exportPreferences(contextScopePrefs, new IPreferenceFilter[] { filter }, stream);
+ stream.close();
+ }
+ catch (Exception e) {
+ }
+ }
+
+ /**
+ * Check whether a key is set or not.
+ *
+ * @param key The key to check.
+ * @return <code>null</code> if the key does not exist.
+ */
+ public boolean containsKey(String key) {
+ return Platform.getPreferencesService().getString(getQualifier(), key, null, null) != null;
+ }
+
+ /**
+ * Get a String preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final String getString(String key) {
+ return Platform.getPreferencesService().getString(getQualifier(), key, null, null);
+ }
+
+ /**
+ * Get a boolean preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final boolean getBoolean(String key) {
+ return Platform.getPreferencesService().getBoolean(getQualifier(), key, false, null);
+ }
+
+ /**
+ * Get an int preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final int getInt(String key) {
+ return Platform.getPreferencesService().getInt(getQualifier(), key, 0, null);
+ }
+
+ /**
+ * Get a long preference value.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key or the default value if not set.
+ */
+ public final long getLong(String key) {
+ return Platform.getPreferencesService().getLong(getQualifier(), key, 0, null);
+ }
+
+ /**
+ * Get a default String preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or <code>null</code>.
+ */
+ public final String getDefaultString(String key) {
+ return defaultPrefs.get(key, null);
+ }
+
+ /**
+ * Get a default boolean preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or <code>null</code>.
+ */
+ public final boolean getDefaultBoolean(String key) {
+ return defaultPrefs.getBoolean(key, false);
+ }
+
+ /**
+ * Get a default int preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or <code>null</code>.
+ */
+ public final int getDefaultInt(String key) {
+ return defaultPrefs.getInt(key, 0);
+ }
+
+ /**
+ * Get a default long preference value.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key or <code>null</code>.
+ */
+ public final long getDefaultLong(String key) {
+ return defaultPrefs.getLong(key, 0);
+ }
+
+ /**
+ * Set a String preference value. If the value is <code>null</code> or is equal to
+ * the default value, the entry will be removed.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key.
+ */
+ public void putString(String key, String value) {
+ String defValue = defaultPrefs.get(key, null);
+ String instValue = getString(key);
+ if (value == null || value.equals(defValue)) {
+ contextScopePrefs.remove(key);
+ flushAndNotify(contextScopePrefs, key, instValue, defValue);
+ }
+ else if (!value.equals(instValue)) {
+ contextScopePrefs.put(key, value);
+ flushAndNotify(contextScopePrefs, key, instValue, value);
+ }
+ }
+
+ /**
+ * Set a boolean preference value. If the value is equal the default value,
+ * the entry will be removed.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key.
+ */
+ public void putBoolean(String key, boolean value) {
+ boolean defValue = defaultPrefs.getBoolean(key, false);
+ boolean instValue = getBoolean(key);
+ if (value == defValue) {
+ contextScopePrefs.remove(key);
+ flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(defValue));
+ }
+ else if (value != instValue) {
+ contextScopePrefs.putBoolean(key, value);
+ flushAndNotify(contextScopePrefs, key, Boolean.toString(instValue), Boolean.toString(value));
+ }
+ }
+
+ /**
+ * Set an int preference value. If the value is equal to the default value,
+ * the entry will be removed.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key.
+ */
+ public void putInt(String key, int value) {
+ int defValue = defaultPrefs.getInt(key, 0);
+ int instValue = getInt(key);
+ if (value == defValue) {
+ contextScopePrefs.remove(key);
+ flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(defValue));
+ }
+ else if (value != instValue) {
+ contextScopePrefs.putInt(key, value);
+ flushAndNotify(contextScopePrefs, key, Integer.toString(instValue), Integer.toString(value));
+ }
+ }
+
+ /**
+ * Set a long preference value. If the given value is equal to the default
+ * value, the entry will be removed.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The value of the preference key.
+ */
+ public void putLong(String key, long value) {
+ long defValue = defaultPrefs.getLong(key, 0);
+ long instValue = getLong(key);
+ if (value == defValue) {
+ contextScopePrefs.remove(key);
+ flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(defValue));
+ }
+ else if (value != instValue) {
+ contextScopePrefs.putLong(key, value);
+ flushAndNotify(contextScopePrefs, key, Long.toString(instValue), Long.toString(value));
+ }
+ }
+
+ /**
+ * Set a default String preference value. If the given value is <code>null</code>,
+ * the entry will be removed.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key.
+ */
+ public void putDefaultString(String key, String value) {
+ String defValue = defaultPrefs.get(key, null);
+ if (value == null) {
+ defaultPrefs.remove(key);
+ flushAndNotify(defaultPrefs, key, defValue, null);
+ }
+ else if (!value.equals(defValue)) {
+ defaultPrefs.put(key, value);
+ flushAndNotify(defaultPrefs, key, defValue, value);
+ }
+ }
+
+ /**
+ * Set a default boolean preference value.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key.
+ */
+ public void putDefaultBoolean(String key, boolean value) {
+ boolean defValue = defaultPrefs.getBoolean(key, false);
+ if (value != defValue) {
+ defaultPrefs.putBoolean(key, value);
+ flushAndNotify(defaultPrefs, key, Boolean.toString(defValue), Boolean.toString(value));
+ }
+ }
+
+ /**
+ * Set a default int preference value.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key.
+ */
+ public void putDefaultInt(String key, int value) {
+ int defValue = defaultPrefs.getInt(key, 0);
+ if (value != defValue) {
+ defaultPrefs.putInt(key, value);
+ flushAndNotify(defaultPrefs, key, Integer.toString(defValue), Integer.toString(value));
+ }
+ }
+
+ /**
+ * Set a default long preference value.
+ * <p>
+ * A {@link PreferenceChangeEvent} is fired, if the value has changed. The old
+ * and new values are string representation in base 10.
+ *
+ * @param key The preference key.
+ * @return The default value of the preference key.
+ */
+ public void putDefaultLong(String key, long value) {
+ long defValue = defaultPrefs.getLong(key, 0);
+ if (value != defValue) {
+ defaultPrefs.putLong(key, value);
+ flushAndNotify(defaultPrefs, key, Long.toString(defValue), Long.toString(value));
+ }
+ }
+
+ /**
+ * Write back the changes to the store and notify all listeners about the changed key.
+ *
+ * @param node The preference node which has changed. Must not be <code>null</code>.
+ * @param key The key of the changed preference. Must not be <code>null</code>.
+ * @param oldValue The old value as a {@link String}, or <code>null</code>.
+ * @param newValue The new value as a {@link String}, or <code>null</code>.
+ */
+ protected final void flushAndNotify(IEclipsePreferences node, String key, String oldValue, String newValue) {
+ // Flush the preferences to the persistence store
+ try { node.flush(); } catch (BackingStoreException e) { /* Ignored on purpose */ }
+
+ // Notify the listeners
+ firePreferenceEvent(node, key, oldValue, newValue);
+ }
+
+ /**
+ * Register the given listener to receive notifications of preference changes to this node.
+ * Calling this method multiple times with the same listener has no effect. The given listener
+ * argument must not be <code>null</code>.
+ *
+ * @param listener The preference change listener. Must not be <code>null</code>.
+ */
+ public void addPreferenceChangeListener(IPreferenceChangeListener listener) {
+ Assert.isNotNull(listener);
+ listeners.add(listener);
+ }
+
+ /**
+ * De-register the given listener from receiving notifications of preference changes
+ * to this node. Calling this method multiple times with the same listener has no
+ * effect. The given listener argument must not be <code>null</code>.
+ *
+ * @param listener The preference change listener. Must not be <code>null</code>.
+ */
+ public void removePreferenceChangeListener(IPreferenceChangeListener listener) {
+ Assert.isNotNull(listener);
+ listeners.remove(listener);
+ }
+
+ /**
+ * Convenience method for notifying the registered preference change listeners.
+ *
+ * @param node The preference node which has changed. Must not be <code>null</code>.
+ * @param key The key of the changed preference. Must not be <code>null</code>.
+ * @param oldValue The old value as a {@link String}, or <code>null</code>.
+ * @param newValue The new value as a {@link String}, or <code>null</code>.
+ */
+ protected void firePreferenceEvent(IEclipsePreferences node, String key, String oldValue, String newValue) {
+ Assert.isNotNull(node);
+ Assert.isNotNull(key);
+
+ // If no listener is registered, we are done here
+ if (listeners.isEmpty()) return;
+
+ // Get the list or currently registered listeners
+ Object[] l = listeners.getListeners();
+ // Create the preference change event
+ final PreferenceChangeEvent event = new PreferenceChangeEvent(node, key, oldValue, newValue);
+ for (int i = 0; i < l.length; i++) {
+ final IPreferenceChangeListener listener = (IPreferenceChangeListener) l[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ @Override
+ public void run() throws Exception {
+ listener.preferenceChange(event);
+ }
+ };
+ SafeRunner.run(job);
+ }
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/progress/ProgressHelper.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/progress/ProgressHelper.java
new file mode 100644
index 000000000..26fdaafb4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/progress/ProgressHelper.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.progress;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.callback.Callback;
+import org.eclipse.tm.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * Helper implementation to deal with progress monitors and callbacks.
+ */
+public final class ProgressHelper {
+
+ public static final int PROGRESS_DONE = 0;
+ public static final int PROGRESS_NONE = -1;
+
+ /**
+ * Checks if there was an error or the operation was canceled.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param status
+ * The status. <code>null</code> if status should not be checked.
+ * @param progress
+ * The progress monitor. <code>null</code> if cancel should not
+ * be checked.
+ * @param callback
+ * The callback to call on cancel or error.
+ *
+ * @return <code>false</code> if everything is OK.
+ */
+ public static final boolean isCancelOrError(Object caller, IStatus status, IProgressMonitor progress, ICallback callback) {
+ if (status == null) status = Status.OK_STATUS;
+
+ if (!status.isOK() || (progress != null && progress.isCanceled())) {
+ if (status.getSeverity() == IStatus.CANCEL || (progress != null && progress.isCanceled())) {
+ status = new Status(IStatus.CANCEL, status.getPlugin(),
+ status.getCode(), status.getMessage(),
+ new OperationCanceledException());
+ } else if (status.getSeverity() == IStatus.ERROR) {
+ Throwable e = status.getException();
+ try {
+ throw e;
+ } catch (Throwable thrown) {
+ e = thrown;
+ }
+ CoreBundleActivator.getTraceHandler().trace(
+ status.getMessage(),
+ 1,
+ ITraceIds.TRACE_CALLBACKS,
+ status.getSeverity(),
+ caller != null ? caller.getClass() : ProgressHelper.class);
+ status = new Status(IStatus.ERROR, status.getPlugin(), status.getCode(), status.getMessage(), e);
+ }
+
+ if (callback != null) {
+ if (caller instanceof ICallback) {
+ Callback.copyProperties((ICallback) caller, callback);
+ }
+ callback.done(caller, status);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the operation was canceled.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param progress
+ * The progress monitor. Must not be <code>null</code>
+ * @param callback
+ * The callback to call on cancel or error.
+ *
+ * @return <code>false</code> if everything is OK.
+ */
+ public static final boolean isCancel(Object caller, IProgressMonitor progress, ICallback callback) {
+ Assert.isNotNull(progress);
+ return isCancel(caller, null, progress, callback);
+ }
+
+ /**
+ * Checks if the operation was canceled.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param status
+ * The status. Must not be <code>null</code>.
+ * @param callback
+ * The callback to call on cancel or error.
+ *
+ * @return <code>false</code> if everything is OK.
+ */
+ public static final boolean isCancel(Object caller, IStatus status, ICallback callback) {
+ Assert.isNotNull(status);
+ return isCancel(caller, status, null, callback);
+ }
+
+ /**
+ * Checks if the operation was canceled.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param status
+ * The status. <code>null</code> if status should not be checked.
+ * @param progress
+ * The progress monitor. <code>null</code> if cancel should not
+ * be checked.
+ * @param callback
+ * The callback to call on cancel or error.
+ *
+ * @return <code>false</code> if everything is OK.
+ */
+ public static final boolean isCancel(Object caller, IStatus status, IProgressMonitor progress, ICallback callback) {
+ if (status == null) status = Status.OK_STATUS;
+
+ if (status.getSeverity() == IStatus.CANCEL || (progress != null && progress.isCanceled())) {
+ status = new Status(IStatus.CANCEL, status.getPlugin(),
+ status.getCode(), status.getMessage(),
+ new OperationCanceledException());
+
+ if (callback != null) {
+ if (caller instanceof ICallback) {
+ Callback.copyProperties((ICallback) caller, callback);
+ }
+ callback.done(caller, status);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Checks if there was an error.
+ *
+ * @param caller
+ * The caller or <code>null</code>.
+ * @param status
+ * The status. <code>null</code> if status should not be checked.
+ * @param callback
+ * The callback to call on cancel or error.
+ *
+ * @return <code>false</code> if everything is OK.
+ */
+ public static final boolean isError(Object caller, IStatus status, ICallback callback) {
+ if (status == null) status = Status.OK_STATUS;
+
+ if (!status.isOK() && status.getSeverity() != IStatus.CANCEL) {
+ if (status.getSeverity() == IStatus.ERROR) {
+ Throwable e = status.getException();
+ try {
+ throw e;
+ } catch (Throwable thrown) {
+ e = thrown;
+ }
+ CoreBundleActivator.getTraceHandler().trace(
+ status.getMessage(),
+ 1,
+ ITraceIds.TRACE_CALLBACKS,
+ status.getSeverity(),
+ caller != null ? caller.getClass() : ProgressHelper.class);
+ status = new Status(IStatus.ERROR, status.getPlugin(), status.getCode(), status.getMessage(), e);
+ }
+
+ if (callback != null) {
+ if (caller instanceof ICallback) {
+ Callback.copyProperties((ICallback) caller, callback);
+ }
+ callback.done(caller, status);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Wraps the given progress monitor into a {@link SubProgressMonitor}. If
+ * the given monitor is <code>null</code>, a {@link NullProgressMonitor} is returned.
+ *
+ * @param progress
+ * The global progress monitor or <code>null</code>.
+ * @param ticksToUse
+ * The ticks to use.
+ *
+ * @return The progress monitor to use.
+ */
+ public static final IProgressMonitor getProgressMonitor(IProgressMonitor progress, int ticksToUse) {
+ if (progress != null) {
+ progress = new SubProgressMonitor(progress, ticksToUse, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+ } else {
+ progress = new NullProgressMonitor();
+ }
+ return progress;
+ }
+
+ /**
+ * Start a task.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ * @param name
+ * The name (label) of the task.
+ * @param ticks
+ * The ticks for this task.
+ */
+ public static final void beginTask(IProgressMonitor progress, String name, int ticks) {
+ if (progress != null) {
+ progress.beginTask("", ticks); //$NON-NLS-1$
+ progress.setTaskName(name);
+ }
+ }
+
+ /**
+ * Set a new task name.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ * @param taskName
+ * The name (label) of the task.
+ */
+ public static final void setTaskName(IProgressMonitor progress, String taskName) {
+ if (progress != null) {
+ progress.setTaskName(taskName);
+ }
+ }
+
+ /**
+ * Set a new sub task name.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ * @param subTask
+ * The name (label) of the sub task.
+ */
+ public static final void setSubTaskName(IProgressMonitor progress,
+ String subTaskName) {
+ if (progress != null) {
+ progress.subTask(subTaskName);
+ }
+ }
+
+ /**
+ * Add the given amount of worked steps to the progress monitor.
+ * <p>
+ * If the given amount of worked steps is less or equal than 0, the method
+ * will do nothing.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ * @param worked
+ * The amount of worked steps.
+ */
+ public static final void worked(IProgressMonitor progress, int worked) {
+ if (progress != null && !progress.isCanceled() && worked > 0) {
+ progress.worked(worked);
+ }
+ }
+
+ /**
+ * Set the progress monitor done.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ */
+ public static final void done(IProgressMonitor progress) {
+ if (progress != null) {
+ progress.setTaskName(""); //$NON-NLS-1$
+ progress.subTask(""); //$NON-NLS-1$
+ progress.done();
+ }
+ }
+
+ /**
+ * Set the progress monitor canceled.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ */
+ public static final void cancel(IProgressMonitor progress) {
+ if (progress != null && !progress.isCanceled()) {
+ progress.setCanceled(true);
+ }
+ }
+
+ /**
+ * Get the canceled state of the progress monitor.
+ *
+ * @param progress
+ * The progress monitor or <code>null</code>.
+ *
+ * @return <code>True</code> if the progress monitor is not
+ * <code>null</code> and if the progress monitor is canceled.
+ */
+ public static final boolean isCanceled(IProgressMonitor progress) {
+ if (progress != null) {
+ return progress.isCanceled();
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/properties/PropertiesContainer.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/properties/PropertiesContainer.java
new file mode 100644
index 000000000..675de2c8c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/properties/PropertiesContainer.java
@@ -0,0 +1,504 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.properties;
+
+import java.util.Collections;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tm.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tm.te.runtime.events.EventManager;
+import org.eclipse.tm.te.runtime.events.PropertyChangeEvent;
+import org.eclipse.tm.te.runtime.interfaces.properties.IPropertiesContainer;
+import org.eclipse.tm.te.runtime.interfaces.tracing.ITraceIds;
+
+/**
+ * A generic properties container implementation.
+ * <p>
+ * <b>Note:</b> The properties container implementation is not thread-safe. Clients requiring
+ * a thread-safe implementation should subclass the properties container and
+ * overwrite {@link #checkThreadAccess()}.
+ */
+public class PropertiesContainer extends PlatformObject implements IPropertiesContainer {
+ // Used to have a simple check that the random generated UUID isn't
+ // the same if objects of this type are created very rapidly.
+ private static UUID LAST_UUID_GENERATED = null;
+
+ // The unique node id
+ private final UUID uniqueId;
+
+ // The flag to remember the notification enablement
+ private boolean changeEventsEnabled = false;
+
+ /**
+ * The custom properties map. The keys are always strings, the value might be any object.
+ */
+ private Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+ /**
+ * Constructor.
+ */
+ public PropertiesContainer() {
+ super();
+
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+
+ // Initialize the unique node id.
+ UUID uuid = UUID.randomUUID();
+ while (LAST_UUID_GENERATED != null && LAST_UUID_GENERATED.equals(uuid)) {
+ uuid = UUID.randomUUID();
+ }
+ LAST_UUID_GENERATED = uuid;
+ uniqueId = LAST_UUID_GENERATED;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getUUID()
+ */
+ @Override
+ public final UUID getUUID() {
+ return uniqueId;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof PropertiesContainer) {
+ return uniqueId.equals(((PropertiesContainer)obj).uniqueId);
+ }
+ return super.equals(obj);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return uniqueId.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder buffer = new StringBuilder();
+
+ buffer.append("UUID=" + uniqueId.toString()); //$NON-NLS-1$
+
+ // print the first level of the properties map only
+ buffer.append(", properties={"); //$NON-NLS-1$
+ for (String key : properties.keySet()) {
+ buffer.append(key);
+ buffer.append("="); //$NON-NLS-1$
+
+ Object value = properties.get(key);
+ if (value instanceof Map || value instanceof IPropertiesContainer) {
+ buffer.append("{...}"); //$NON-NLS-1$
+ } else {
+ buffer.append(value);
+ }
+
+ buffer.append(", "); //$NON-NLS-1$
+ }
+ if (buffer.toString().endsWith(", ")) { //$NON-NLS-1$
+ buffer.deleteCharAt(buffer.length() - 1);
+ buffer.deleteCharAt(buffer.length() - 1);
+ }
+ buffer.append("}"); //$NON-NLS-1$
+
+ return buffer.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.nodes.IPropertiesContainer#setChangeEventsEnabled(boolean)
+ */
+ @Override
+ public final boolean setChangeEventsEnabled(boolean enabled) {
+ boolean changed = changeEventsEnabled != enabled;
+ if (changed) changeEventsEnabled = enabled;
+ return changed;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.nodes.IPropertiesContainer#changeEventsEnabled()
+ */
+ @Override
+ public final boolean changeEventsEnabled() {
+ return changeEventsEnabled;
+ }
+
+ /**
+ * Creates a new property change notification event object. The event object is initialized
+ * with the given parameter.
+ * <p>
+ * This method is typically called from {@link #setProperty(String, Object)} in case the
+ * property changed it's value. <code>Null</code> is returned if no event should be fired.
+ *
+ * @param source The source object. Must not be <code>null</code>.
+ * @param key The property key. Must not be <code>null</code>.
+ * @param oldValue The old properties value.
+ * @param newValue The new properties value.
+ *
+ * @return The new property change notification event instance or <code>null</code>.
+ */
+ protected final EventObject newEvent(Object source, String key, Object oldValue, Object newValue) {
+ Assert.isNotNull(source);
+ Assert.isNotNull(key);
+
+ // Check if the event is dropped
+ if (dropEvent(source, key, oldValue, newValue)) {
+ // Log the event dropping if tracing is enabled
+ if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITraceIds.TRACE_EVENTS)) {
+ CoreBundleActivator.getTraceHandler().trace("Drop event notification (not created change event)\n\t\t" + //$NON-NLS-1$
+ "for eventId = " + key + ",\n\t\t" + //$NON-NLS-1$ //$NON-NLS-2$
+ "currentValue = " + oldValue + ",\n\t\t" + //$NON-NLS-1$ //$NON-NLS-2$
+ "newValue = " + newValue, //$NON-NLS-1$
+ 0, ITraceIds.TRACE_EVENTS, IStatus.WARNING, this);
+ }
+ return null;
+ }
+
+ // Create the notification event instance.
+ return newEventDelegate(source, key, oldValue, newValue);
+ }
+
+ /**
+ * Creates a new property change notification event object instance.
+ * <p>
+ * This method is typically called from {@link #newEvent(Object, String, Object, Object)}
+ * if notifications are enabled.
+ *
+ * @param source The source object. Must not be <code>null</code>.
+ * @param key The property key. Must not be <code>null</code>.
+ * @param oldValue The old properties value.
+ * @param newValue The new properties value.
+ *
+ * @return The new property change notification event instance or <code>null</code>.
+ */
+ protected EventObject newEventDelegate(Object source, String key, Object oldValue, Object newValue) {
+ Assert.isNotNull(source);
+ Assert.isNotNull(key);
+ return new PropertyChangeEvent(source, key, oldValue, newValue);
+ }
+
+ /**
+ * Returns if or if not notifying the given property change has to be dropped.
+ *
+ * @param source The source object. Must not be <code>null</code>.
+ * @param key The property key. Must not be <code>null</code>.
+ * @param oldValue The old properties value.
+ * @param newValue The new properties value.
+ *
+ * @return <code>True</code> if dropping the property change notification, <code>false</code> if notifying the property change.
+ */
+ protected boolean dropEvent(Object source, String key, Object oldValue, Object newValue) {
+ Assert.isNotNull(source);
+ Assert.isNotNull(key);
+ return !changeEventsEnabled || key.endsWith(".silent"); //$NON-NLS-1$
+ }
+
+ /**
+ * Checks if the access to the properties container happens in
+ * a privileged thread.
+ * <p>
+ * The default implementation returns always <code>true</code>. Overwrite
+ * to implement thread-safe properties container access.
+ *
+ * @return <code>True</code> if the access to the properties container is allowed, <code>false</code> otherwise.
+ */
+ protected boolean checkThreadAccess() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getProperties()
+ */
+ @Override
+ public Map<String, Object> getProperties() {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ return Collections.unmodifiableMap(new HashMap<String, Object>(properties));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getProperty(java.lang.String)
+ */
+ @Override
+ public Object getProperty(String key) {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ return properties.get(key);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getBooleanProperty(java.lang.String)
+ */
+ @Override
+ public final boolean getBooleanProperty(String key) {
+ Object value = getProperty(key);
+ if (value instanceof Boolean) {
+ return ((Boolean)value).booleanValue();
+ }
+ if (value instanceof String) {
+ String val = ((String)value).trim();
+ return "TRUE".equalsIgnoreCase(val) || "1".equals(val) || "Y".equalsIgnoreCase(val) || //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "JA".equalsIgnoreCase(val) || "YES".equalsIgnoreCase(val); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getLongProperty(java.lang.String)
+ */
+ @Override
+ public final long getLongProperty(String key) {
+ Object value = getProperty(key);
+ if (value instanceof Long) {
+ return ((Long)value).longValue();
+ }
+ else if (value instanceof Integer) {
+ return ((Integer)value).intValue();
+ }
+ else if (value != null) {
+ try {
+ return Long.decode(value.toString()).longValue();
+ }
+ catch (Exception e) {}
+ }
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getIntProperty(java.lang.String)
+ */
+ @Override
+ public final int getIntProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Integer ? ((Integer)value).intValue() :
+ (value != null ? Integer.decode(value.toString()).intValue() : -1);
+ }
+ catch (Exception e) {
+ return -1;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getStringProperty(java.lang.String)
+ */
+ @Override
+ public final String getStringProperty(String key) {
+ Object value = getProperty(key);
+ return value instanceof String ? (String)value :
+ (value != null ? value.toString() : null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getFloatProperty(java.lang.String)
+ */
+ @Override
+ public final float getFloatProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Float ? ((Float)value).floatValue() :
+ (value != null ? Float.parseFloat(value.toString()) : Float.NaN);
+ }
+ catch (Exception e) {
+ return Float.NaN;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#getDoubleProperty(java.lang.String)
+ */
+ @Override
+ public final double getDoubleProperty(String key) {
+ Object value = getProperty(key);
+ try {
+ return value instanceof Double ? ((Double)value).doubleValue() :
+ (value != null ? Double.parseDouble(value.toString()) : Double.NaN);
+ }
+ catch (Exception e) {
+ return Double.NaN;
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperties(java.util.Map)
+ */
+ @Override
+ public final void setProperties(Map<String, Object> properties) {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ Assert.isNotNull(properties);
+
+ this.properties.clear();
+ this.properties.putAll(properties);
+
+ EventObject event = newEvent(this, "properties", null, properties); //$NON-NLS-1$
+ if (event != null) EventManager.getInstance().fireEvent(event);
+}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, boolean)
+ */
+ @Override
+ public final boolean setProperty(String key, boolean value) {
+ boolean oldValue = getBooleanProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Boolean.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, long)
+ */
+ @Override
+ public final boolean setProperty(String key, long value) {
+ long oldValue = getLongProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Long.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, int)
+ */
+ @Override
+ public final boolean setProperty(String key, int value) {
+ int oldValue = getIntProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Integer.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, float)
+ */
+ @Override
+ public final boolean setProperty(String key, float value) {
+ float oldValue = getFloatProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Float.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, double)
+ */
+ @Override
+ public final boolean setProperty(String key, double value) {
+ double oldValue = getDoubleProperty(key);
+ if (oldValue != value) {
+ return setProperty(key, Double.valueOf(value));
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#setProperty(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public boolean setProperty(String key, Object value) {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ Assert.isNotNull(key);
+
+ Object oldValue = properties.get(key);
+ if ((oldValue == null && value != null) || (oldValue != null && !oldValue.equals(value))) {
+ if (value != null) {
+ properties.put(key, value);
+ } else {
+ properties.remove(key);
+ }
+ EventObject event = newEvent(this, key, oldValue, value);
+ if (event != null) EventManager.getInstance().fireEvent(event);
+ return true;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#clearProperties()
+ */
+ @Override
+ public final void clearProperties() {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ properties.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, long)
+ */
+ @Override
+ public final boolean isProperty(String key, long value) {
+ return getLongProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, boolean)
+ */
+ @Override
+ public final boolean isProperty(String key, boolean value) {
+ return getBooleanProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, int)
+ */
+ @Override
+ public final boolean isProperty(String key, int value) {
+ return getIntProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, float)
+ */
+ @Override
+ public final boolean isProperty(String key, float value) {
+ return getFloatProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, double)
+ */
+ @Override
+ public final boolean isProperty(String key, double value) {
+ return getDoubleProperty(key) == value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isPropertyIgnoreCase(java.lang.String, java.lang.String)
+ */
+ @Override
+ public final boolean isPropertyIgnoreCase(String key, String value) {
+ String property = getStringProperty(key);
+ return (property == null && value == null) || (property != null && property.equalsIgnoreCase(value));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tm.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public final boolean isProperty(String key, Object value) {
+ Object property = getProperty(key);
+ return (property == null && value == null) || (property != null && property.equals(value));
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/tracing/TraceHandler.java b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/tracing/TraceHandler.java
new file mode 100644
index 000000000..b322c4585
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tm.te.runtime/src/org/eclipse/tm/te/runtime/tracing/TraceHandler.java
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * 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.tm.te.runtime.tracing;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Helper class to handle tracing using the platforms debug capabilities.
+ */
+public class TraceHandler {
+ /**
+ * The bundle identifier.
+ */
+ private final String identifier;
+
+ /**
+ * The tracer instance.
+ */
+ private Tracer tracer = null;
+
+ /**
+ * The tracer is responsible for writing the trace message to the desired
+ * output media.
+ */
+ protected static class Tracer {
+
+ /**
+ * The bundle identifier.
+ */
+ private final String fIdentifier;
+
+ /**
+ * The qualifier for the default &quot;&lt;bundle identifier&gt;/debugmode&quot;
+ * tracing slot.
+ */
+ private final String fDebugModeQualifier;
+
+ /**
+ * Constructor.
+ *
+ * @param identifier The bundle identifier. Must not be <code>null</code>.
+ */
+ public Tracer(String identifier) {
+ Assert.isNotNull(identifier);
+ fIdentifier = identifier;
+
+ // Initialize the debug mode qualifier
+ fDebugModeQualifier = fIdentifier + "/debugmode"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the value of the debug mode tracing slot.
+ * <p>
+ * If not set, or the value is not an {@link Integer}, the method returns <code>0</code>.
+ *
+ * @return The debug mode value.
+ */
+ protected int getDebugMode() {
+ try {
+ String mode = Platform.getDebugOption(fDebugModeQualifier);
+ if (mode != null && Integer.decode(mode).intValue() > 0) {
+ return Integer.decode(mode).intValue();
+ }
+ } catch (NumberFormatException e) { /* ignored on purpose */ }
+
+ return 0;
+ }
+
+ /**
+ * Check if the specified trace slot is enabled.
+ *
+ * @param slotId The name of the slot.
+ * @return <code>true</code> if the slot is defined and enabled, <code>false</code> otherwise.
+ */
+ protected boolean isSlotEnabled(String slotId) {
+ return fIdentifier != null ? Boolean.parseBoolean(Platform.getDebugOption(fIdentifier + "/" + slotId)) : false; //$NON-NLS-1$
+ }
+
+ /**
+ * Check if tracing is enabled for given mode and slot.
+ *
+ * @param debugMode The debug mode for the current debug.
+ * @param slotId The name of the slot.
+ *
+ * @return <code>true</code> if the debug should be written, <code>false</code> otherwise.
+ */
+ protected final boolean isEnabled(int debugMode, String slotId) {
+ return getDebugMode() < 0 ||
+ (debugMode <= getDebugMode() &&
+ (slotId == null || slotId.trim().length() == 0 || isSlotEnabled(slotId)));
+ }
+
+ /**
+ * Format the trace message.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ protected String getFormattedDebugMessage(String message, int debugMode, String slotId, int severity, Object clazz) {
+ StringBuffer debug = new StringBuffer();
+ if (slotId != null || clazz != null) {
+ if (clazz != null) {
+ String name = clazz instanceof Class<?> ? ((Class<?>)clazz).getSimpleName() : clazz.getClass().getSimpleName();
+ debug.append((name != null && name.trim().length() > 0) ? name.trim() : clazz instanceof Class<?> ? ((Class<?>)clazz).getName() : clazz.getClass().getName());
+ }
+ if (slotId != null) {
+ debug.append(" at "); //$NON-NLS-1$
+ debug.append(slotId);
+ }
+ if (debugMode >= 0) {
+ debug.append(" (Mode "); //$NON-NLS-1$
+ debug.append(debugMode);
+ debug.append(')');
+ }
+ debug.append('\n');
+ debug.append('\t');
+ }
+ debug.append(message);
+
+ return debug.toString();
+ }
+
+ /**
+ * Write the trace message.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ protected void write(String message, int debugMode, String slotId, int severity, Object clazz) {
+ String formattedMessage = getFormattedDebugMessage(message, debugMode, slotId, severity, clazz);
+ if (severity == IStatus.ERROR || severity == IStatus.WARNING) {
+ System.err.println(formattedMessage);
+ }
+ else {
+ System.out.println(formattedMessage);
+ }
+ }
+
+ /**
+ * Trace the given message with the given debug mode and slot.
+ *
+ * @param message The trace message.
+ * @param debugMode The debug mode.
+ * @param slotId The name of the slot.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer.
+ *
+ * @see IStatus
+ */
+ public final void trace(String message, int debugMode, String slotId, int severity, Object clazz) {
+ if (isEnabled(debugMode, slotId)) {
+ write(message, debugMode, slotId, severity, clazz);
+ }
+ }
+ }
+
+ /**
+ * Constructor.
+ * <p>
+ * Initializes the tracing handler with the given bundle identifier.
+ *
+ * @param identifier The bundle identifier. Must not be <code>null</code>.
+ */
+ public TraceHandler(String identifier) {
+ Assert.isNotNull(identifier);
+ this.identifier = identifier;
+ }
+
+ /**
+ * Returns the identifier.
+ */
+ protected final String getIdentifier() {
+ return identifier;
+ }
+
+ /**
+ * Returns the tracer instance. Create a new tracer instance
+ * on first invokation.
+ *
+ * @return The tracer instance.
+ */
+ protected Tracer getTracer() {
+ if (tracer == null) {
+ tracer = new Tracer(identifier);
+ }
+ return tracer;
+ }
+
+ /**
+ * Check whether a trace slot is enabled with the given debug mode.
+ *
+ * @param debugMode The debug mode
+ * @param slotId The name of the slot.
+ *
+ * @return <code>true</code> if the slot is enabled, <code>false</code> otherwise.
+ */
+ public final boolean isSlotEnabled(int debugMode, String slotId) {
+ return getTracer().isEnabled(debugMode, slotId);
+ }
+
+ /**
+ * Trace the given message.
+ * <p>
+ * The message severity will be {@link IStatus#INFO} and the message will be
+ * traced unconditionally.
+ *
+ * @param message The message.
+ * @param clazz The class that calls this tracer or <code>null</code>.
+ */
+ public final void trace(String message, Object clazz) {
+ getTracer().trace(message, 0, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ * <p>
+ * The message severity will be {@link IStatus#INFO}.
+ *
+ * @param message The message.
+ * @param debugMode The minimum debug mode that has to be set to write out the message.
+ * @param clazz The class that calls this tracer or <code>null</code>.
+ */
+ public final void trace(String message, int debugMode, Object clazz) {
+ getTracer().trace(message, debugMode, null, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ * <p>
+ * The message severity will be {@link IStatus#INFO} and the debug mode
+ * will default to <code>0</code>.
+ *
+ * @param message The message.
+ * @param slotId The slot that has to be enabled to write out the message.
+ * @param clazz The class that calls this tracer or <code>null</code>.
+ */
+ public final void trace(String message, String slotId, Object clazz) {
+ getTracer().trace(message, 0, slotId, IStatus.INFO, clazz);
+ }
+
+ /**
+ * Trace the given message.
+ *
+ * @param message The message.
+ * @param debugMode The minimum debug mode that has to be set to write out the message.
+ * @param slotId The slot that has to be enabled to write out the message.
+ * @param severity The severity. See {@link IStatus} for valid severity values.
+ * @param clazz The class that calls this tracer or <code>null</code>.
+ *
+ * @see IStatus
+ */
+ public final void trace(String message, int debugMode, String slotId, int severity, Object clazz) {
+ getTracer().trace(message, debugMode, slotId, severity, clazz);
+ }
+
+}

Back to the top