Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Stieber2012-02-19 16:45:27 +0000
committerUwe Stieber2012-02-19 16:45:27 +0000
commitb953bce70507af630a13163d6b82868f9b5e7711 (patch)
treede7baf9edefb6b9d3ae816ce9cb22506bea5e4cf /target_explorer/plugins
parent71bd059af3fb739c3a2ba6859e5b6a94243ec905 (diff)
downloadorg.eclipse.tcf-b953bce70507af630a13163d6b82868f9b5e7711.tar.gz
org.eclipse.tcf-b953bce70507af630a13163d6b82868f9b5e7711.tar.xz
org.eclipse.tcf-b953bce70507af630a13163d6b82868f9b5e7711.zip
Target Explorer: Continued launch context selector work
Diffstat (limited to 'target_explorer/plugins')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/lm/interfaces/IContextSelectorLaunchAttributes.java24
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/persistence/ContextSelectorPersistenceDelegate.java528
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java8
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java57
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate2.java20
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java16
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate2.java37
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IPropertiesAccessService.java16
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStepContext.java24
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/tracing/TraceHandler.java9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/AdapterFactory.java16
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/StepContextAdapter.java85
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/plugin.xml9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/ModelNodeFactoryDelegate.java47
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/services/PropertiesAccessService.java24
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.services.contexts/src/org/eclipse/tcf/te/tcf/services/contexts/internal/AdapterFactory.java16
18 files changed, 936 insertions, 29 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/lm/interfaces/IContextSelectorLaunchAttributes.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/lm/interfaces/IContextSelectorLaunchAttributes.java
new file mode 100644
index 000000000..f1730858c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/lm/interfaces/IContextSelectorLaunchAttributes.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.launch.core.lm.interfaces;
+
+/**
+ * Defines the launch configuration attribute id's to access the launch step contexts.
+ */
+public interface IContextSelectorLaunchAttributes {
+
+ /**
+ * Launch configuration attribute: The launch contexts the launch is operating with. Use
+ * {@link ContextSelectorPersistanceDelegate} to access
+ * this attribute within a launch configuration.
+ */
+ public static final String ATTR_LAUNCH_CONTEXTS = ICommonLaunchAttributes.ATTR_PREFIX + ".launch_contexts"; //$NON-NLS-1$
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/persistence/ContextSelectorPersistenceDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/persistence/ContextSelectorPersistenceDelegate.java
new file mode 100644
index 000000000..c26a521d9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/persistence/ContextSelectorPersistenceDelegate.java
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.launch.core.persistence;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.tcf.te.launch.core.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.launch.core.lm.interfaces.IContextSelectorLaunchAttributes;
+import org.eclipse.tcf.te.launch.core.lm.interfaces.ILaunchSpecification;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext;
+import org.osgi.framework.Bundle;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Context selector persistence delegate.
+ */
+public class ContextSelectorPersistenceDelegate {
+ // The read cache for step contexts. Avoid running time consuming
+ // re-parsing of an already parsed step context description again and again.
+ private final static Map<String, List<IStepContext>> readCache = new LinkedHashMap<String, List<IStepContext>>();
+ // The write cache for target contexts. Avoids re-generating the XML again and again.
+ private final static Map<String, String> writeCache = new LinkedHashMap<String, String>();
+
+ // Limit the read cache to the last 10 read step contexts
+ private final static int READ_CACHE_MAX_CAPACITY = 25;
+ // Limit the write cache to the last 10 written step contexts
+ private final static int WRITE_CACHE_MAX_CAPACITY = 25;
+
+ /**
+ * Saves the selected launch contexts to the specified launch configuration working copy. If the
+ * selected launch contexts are <code>null</code> or empty, the attribute will be removed from
+ * the specified launch configuration working copy.
+ *
+ * @param wc The launch configuration working copy. Must not be <code>null</code>.
+ * @param contexts The launch contexts to save or <code>null</code>.
+ */
+ public final static void setLaunchContexts(ILaunchConfigurationWorkingCopy wc, IStepContext[] contexts) {
+ Assert.isNotNull(wc);
+
+ if (contexts == null || contexts.length == 0) {
+ DefaultPersistenceDelegate.setAttribute(wc, IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS, (String) null);
+ return;
+ }
+
+ // Get the encoded XML representation
+ String xml = encodeLaunchContexts(contexts);
+ // And save them to the launch configuration. If XML == null, the
+ // launch contexts will be removed from the launch configuration
+ DefaultPersistenceDelegate.setAttribute(wc, IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS, xml);
+ }
+
+ /**
+ * Saves the selected launch contexts to the specified launch specification. If the selected
+ * launch contexts are <code>null</code> or empty, the attribute will be removed from the
+ * specified launch specification.
+ *
+ * @param launchSpec The launch specification. Must not be <code>null</code>.
+ * @param contexts The launch contexts to save or <code>null</code>.
+ */
+ public final static void setLaunchContexts(ILaunchSpecification launchSpec, IStepContext[] contexts) {
+ Assert.isNotNull(launchSpec);
+
+ if (contexts == null || contexts.length == 0) {
+ launchSpec.removeAttribute(IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS);
+ return;
+ }
+
+ // Get the encoded XML representation
+ String xml = encodeLaunchContexts(contexts);
+ // And save them to the launch specification. If XML == null, the
+ // launch contexts will be removed from the launch specification
+ launchSpec.addAttribute(IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS, xml);
+ }
+
+ /**
+ * Writes the given launch contexts into a string encoded in XML.
+ *
+ * @param contexts The launch contexts to encode. Must not be <code>null</code>.
+ * @return The full XML representation of the given contexts or <code>null</code>.
+ */
+ public final static String encodeLaunchContexts(IStepContext[] contexts) {
+ Assert.isNotNull(contexts);
+
+ // The final result
+ String result = null;
+
+ // Generate the write cache key
+ String writeCacheKey = makeWriteCacheKey(contexts);
+
+ // Check if we have the contexts already generated before
+ synchronized (writeCache) {
+ if (writeCache.containsKey(writeCacheKey)) {
+ result = writeCache.get(writeCacheKey);
+ }
+ }
+
+ // If no cache hit, generate from scratch
+ if (result == null) {
+ // First, we write the selected contexts as XML representation into a string
+ StringWriter writer = new StringWriter();
+
+ try {
+ // Write the header and get the initial indentation
+ String indentation = writeHeader(writer);
+ // Iterate over the given selected step contexts and write them out.
+ for (IStepContext node : contexts) {
+ writeStepContext(writer, indentation, node);
+ }
+ // Write the footer
+ writeFooter(writer);
+
+ // Convert into a string
+ result = writer.toString();
+
+ synchronized (writeCache) {
+ // Limit the write cache capacity
+ checkCacheCapacity(writeCache, WRITE_CACHE_MAX_CAPACITY);
+ // And put it into the write cache
+ writeCache.put(writeCacheKey, result);
+ }
+ }
+ catch (IOException e) {
+ // Export to the string writer failed --> remove attribute from launch configuration
+ if (CoreBundleActivator.getTraceHandler().getDebugMode() > 0) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ "Launch framework internal error: " + e.getLocalizedMessage(), e); //$NON-NLS-1$
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ result = null;
+ }
+ finally {
+ try {
+ writer.close();
+ }
+ catch (IOException e) { /* ignored on purpose */
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Generates a write cache key from the given contexts.
+ *
+ * @param contexts The contexts
+ * @return The corresponding write key cache.
+ */
+ private static String makeWriteCacheKey(IStepContext[] contexts) {
+ Assert.isNotNull(contexts);
+
+ StringBuffer key = new StringBuffer();
+ for (IStepContext context : contexts) {
+ key.append(Integer.toHexString(context.hashCode()));
+ key.append(':');
+ }
+ if (key.charAt(key.length() - 1) == ':') {
+ key.setCharAt(key.length() - 1, ' ');
+ }
+ return key.toString().trim();
+ }
+
+ /**
+ * Writes the header to the given writer and returns the indentation to be used for following
+ * elements.
+ *
+ * @param writer The writer instance. Must not be <code>null</code>.
+ * @throws IOException in case the write failed.
+ */
+ private static String writeHeader(Writer writer) throws IOException {
+ Assert.isNotNull(writer);
+ writer.write("<contexts>\n"); //$NON-NLS-1$
+ return "\t"; //$NON-NLS-1$
+ }
+
+ /**
+ * Writes the footer to the given writer and returns the indentation to be used for following
+ * elements.
+ *
+ * @param writer The writer instance. Must not be <code>null</code>.
+ * @throws IOException in case the write failed.
+ */
+ private static String writeFooter(Writer writer) throws IOException {
+ Assert.isNotNull(writer);
+ writer.write("</contexts>\n"); //$NON-NLS-1$
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Writes the step context element to the given writer.
+ *
+ * @param writer The writer instance. Must not be <code>null</code>.
+ * @param indentation The indentation to prefix each exported line with. Must not be <code>null</code>.
+ * @param context The step context instance. Must not be <code>null</code>.
+ *
+ * @throws IOException in case the write failed.
+ */
+ private static void writeStepContext(Writer writer, String indentation, IStepContext context) throws IOException {
+ Assert.isNotNull(writer);
+ Assert.isNotNull(indentation);
+ Assert.isNotNull(context);
+
+ writer.write(indentation + "<context type=\"" + context.getModelNode().getClass().getName() + "\">\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.write(indentation + "\t" + context.encode() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ writer.write(indentation + "</context>\n"); //$NON-NLS-1$
+ }
+
+ /**
+ * Reads the selected launch contexts from the given XML encoded string.
+ *
+ * @param encodedContexts The selected launch contexts encoded as XML string. Must not be <code>null</code>.
+ * @return The selected launch contexts or an empty array.
+ */
+ public final static IStepContext[] decodeLaunchContexts(String encodedContexts) {
+ Assert.isNotNull(encodedContexts);
+
+ List<IStepContext> contexts = null;
+
+ if (!"".equals(encodedContexts.trim())) { //$NON-NLS-1$
+ synchronized (readCache) {
+ // Check if we have the contexts already parsed before
+ if (readCache.containsKey(encodedContexts)) {
+ // Take the result from the cache
+ contexts = readCache.get(encodedContexts);
+ // check sanity. If empty or we cannot find the step context,
+ // drop the cache value and decode again.
+ ListIterator<IStepContext> iterator = contexts.listIterator();
+ while (iterator.hasNext()) {
+ IStepContext node = iterator.next();
+ if (!node.exists()) {
+ contexts = null;
+ readCache.remove(encodedContexts);
+ break;
+ }
+ }
+
+ if (contexts != null && contexts.isEmpty()) {
+ readCache.remove(encodedContexts);
+ contexts = null;
+ }
+ }
+ }
+
+ if (contexts == null || contexts.isEmpty()) {
+ contexts = new ArrayList<IStepContext>();
+ // We have to parse the contexts from the string
+ InputStream input = new ByteArrayInputStream(encodedContexts.getBytes());
+ // Instantiate the XML parser
+ LaunchContextXMLParser xmlParser = new LaunchContextXMLParser();
+ xmlParser.initXMLParser();
+ xmlParser.setContexts(contexts);
+ try {
+ xmlParser.getXMLReader().parse(input, xmlParser);
+ if (!contexts.isEmpty()) {
+ synchronized (readCache) {
+ // Limit the read cache capacity
+ checkCacheCapacity(readCache, READ_CACHE_MAX_CAPACITY);
+ // Put the result into the read cache
+ readCache.put(encodedContexts, contexts);
+ }
+ }
+ }
+ catch (Exception e) {
+ // Import failed --> remove attribute from launch configuration
+ if (CoreBundleActivator.getTraceHandler().getDebugMode() > 0) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ "Launch framework internal error: " + e.getLocalizedMessage(), e); //$NON-NLS-1$
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ contexts = null;
+ }
+ }
+ }
+
+ return contexts != null ? contexts.toArray(new IStepContext[contexts.size()]) : new IStepContext[0];
+ }
+
+ /**
+ * Internal helper method to ensure a maximum capacity of the caches.
+ */
+ private final static void checkCacheCapacity(Map<String, ?> cache, int maxCapacity) {
+ if (cache.size() < maxCapacity) {
+ return;
+ }
+ // Get all keys
+ String[] keys = cache.keySet().toArray(new String[cache.keySet().size()]);
+ // And remove all keys starting with the eldest till the
+ // capacity is fine again.
+ for (String key : keys) {
+ cache.remove(key);
+ if (cache.size() < maxCapacity / 2) {
+ break;
+ }
+ }
+ }
+
+ private final static class LaunchContextXMLParser extends DefaultHandler {
+ private final int IN_CONTEXTS_DEFINITION = 1;
+ private final int IN_CONTEXT_DEFINITION = 2;
+
+ private SAXParser parser;
+
+ private int parseState;
+ private String lastData;
+ private String lastType;
+ private List<IStepContext> contexts;
+
+ /**
+ * Constructor
+ */
+ public LaunchContextXMLParser() {
+ super();
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(false);
+ factory.setValidating(false);
+ try {
+ parser = factory.newSAXParser();
+ }
+ catch (ParserConfigurationException e) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), e.getClass().getName(), e);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ catch (SAXException e) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), e.getClass().getName(), e);
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+
+ /**
+ * Returns the associated XML parser instance.
+ */
+ protected SAXParser getXMLReader() {
+ return parser;
+ }
+
+ /**
+ * Reset the XML parser to a defined start point.
+ */
+ protected void initXMLParser() {
+ parseState = 0;
+ lastData = null;
+ lastType = null;
+ contexts = null;
+ }
+
+ /**
+ * Associate the list instance to store the identified contexts.
+ */
+ protected void setContexts(List<IStepContext> contexts) {
+ this.contexts = contexts;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ if ("contexts".equalsIgnoreCase(name) && (parseState & IN_CONTEXTS_DEFINITION) == IN_CONTEXTS_DEFINITION) { //$NON-NLS-1$
+ parseState ^= IN_CONTEXTS_DEFINITION;
+ }
+ if ("context".equalsIgnoreCase(name) && (parseState & IN_CONTEXT_DEFINITION) == IN_CONTEXT_DEFINITION) { //$NON-NLS-1$
+ parseState ^= IN_CONTEXT_DEFINITION;
+
+ // The context encoded string is in last data
+ if (lastType != null && lastData != null) {
+ Class<IModelNode> clazz = null;
+ try {
+ clazz = (Class<IModelNode>)CoreBundleActivator.getContext().getBundle().loadClass(lastType);
+ } catch (ClassNotFoundException e) {
+ if (CoreBundleActivator.getTraceHandler().getDebugMode() > 0) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ "Launch framework internal error: " + e.getLocalizedMessage(), e); //$NON-NLS-1$
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+
+ // If the class could not be loaded by our own bundle class loader, try to find
+ // the bundle from the class name and try to load the class through the bundle.
+ if (clazz == null) {
+ String bundleId = lastType;
+ Bundle bundle = null;
+ while (bundleId != null && bundle == null) {
+ bundle = Platform.getBundle(bundleId);
+ if (bundle == null) {
+ int i = bundleId.lastIndexOf('.');
+ if (i != -1) {
+ bundleId = bundleId.substring(0, i);
+ } else {
+ bundleId = null;
+ }
+ }
+ }
+
+ if (bundle != null) {
+ try {
+ clazz = (Class<IModelNode>)bundle.loadClass(lastType);
+ } catch (ClassNotFoundException e) {
+ if (CoreBundleActivator.getTraceHandler().getDebugMode() > 0) {
+ IStatus status = new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(),
+ "Launch framework internal error: " + e.getLocalizedMessage(), e); //$NON-NLS-1$
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+ }
+ }
+
+ if (clazz != null) {
+ // Try to load the step context
+ IStepContext context = (IStepContext)Platform.getAdapterManager().loadAdapter(clazz, IStepContext.class.getName());
+ if (context != null && !contexts.contains(context)) {
+ contexts.add(context);
+ }
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
+ // Each time we start a new element, throw away the lastData content
+ lastData = null;
+
+ if ("contexts".equalsIgnoreCase(name)) { //$NON-NLS-1$
+ parseState |= IN_CONTEXTS_DEFINITION;
+ }
+ if ("context".equalsIgnoreCase(name) && (parseState & IN_CONTEXTS_DEFINITION) == IN_CONTEXTS_DEFINITION) { //$NON-NLS-1$
+ parseState |= IN_CONTEXT_DEFINITION;
+ lastType = attributes.getValue("type"); //$NON-NLS-1$
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+ */
+ @Override
+ public void characters(char ch[], int start, int length) {
+ if (lastData == null) {
+ lastData = new String(ch, start, length).trim();
+ }
+ else {
+ lastData += new String(ch, start, length).trim();
+ }
+ }
+ }
+
+ /**
+ * Returns the list of configured launch contexts from the given launch configuration.
+ * <p>
+ * If the given launch configuration is <code>null</code> and the method will return an empty
+ * array.
+ *
+ * @param configuration The launch configuration or <code>null</code>.
+ * @return The list of configured launch contexts or an empty array.
+ */
+ public static final IStepContext[] getLaunchContexts(ILaunchConfiguration configuration) {
+ IStepContext[] contexts = new IStepContext[0];
+
+ // First read the contexts written by the launch context selector control.
+ if (configuration != null) {
+ // Read the context attribute from the launch configuration
+ String encodedContexts = DefaultPersistenceDelegate.getAttribute(configuration, IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS, (String) null);
+ if (encodedContexts != null) {
+ contexts = ContextSelectorPersistenceDelegate.decodeLaunchContexts(encodedContexts);
+ }
+ }
+
+ return contexts;
+ }
+
+ /**
+ * Returns the list of configured launch contexts from the given launch specification.
+ * <p>
+ * If the given launch specification is <code>null</code> and the method will return an empty
+ * array.
+ *
+ * @param launchSpec The launch specification or <code>null</code>.
+ * @return The list of configured launch contexts or an empty array.
+ */
+ public static final IStepContext[] getLaunchContexts(ILaunchSpecification launchSpec) {
+ IStepContext[] contexts = new IStepContext[0];
+
+ // First read the contexts written by the launch context selector control.
+ if (launchSpec != null) {
+ // Read the context attribute from the launch specification
+ String encodedContexts = (String) launchSpec.getAttribute(IContextSelectorLaunchAttributes.ATTR_LAUNCH_CONTEXTS, null);
+ if (encodedContexts != null) {
+ contexts = ContextSelectorPersistenceDelegate.decodeLaunchContexts(encodedContexts);
+ }
+ }
+
+ return contexts;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
index 2bb37b79b..2dad81dea 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
@@ -377,8 +377,12 @@ public class ContextSelectorControl extends BaseDialogPageControl implements ISe
// checked, drop the model node and the use the container node only.
if (element instanceof IModelNode) {
IModelNode node = (IModelNode) element;
- if (node.getParent() != null && checked.contains(node.getParent())
- && !grayed.contains(node.getParent())) {
+
+ // Determine the parent node
+ IPropertiesAccessService service = ServiceManager.getInstance().getService(node, IPropertiesAccessService.class);
+ IModelNode parent = service != null ? (IModelNode)service.getParent(node) : node.getParent();
+
+ if (parent != null && checked.contains(parent) && !grayed.contains(parent)) {
continue;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java
index 85fee43ec..721555d85 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java
@@ -9,7 +9,11 @@
*******************************************************************************/
package org.eclipse.tcf.te.launch.ui.tabs.selector;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.action.Action;
@@ -18,10 +22,13 @@ import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.launch.core.persistence.ContextSelectorPersistenceDelegate;
import org.eclipse.tcf.te.launch.ui.activator.UIPlugin;
import org.eclipse.tcf.te.launch.ui.interfaces.ILaunchConfigurationTabFormPart;
import org.eclipse.tcf.te.launch.ui.internal.ImageConsts;
import org.eclipse.tcf.te.launch.ui.nls.Messages;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext;
import org.eclipse.tcf.te.ui.forms.parts.AbstractSection;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
@@ -94,7 +101,15 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
createSectionToolbar(section, toolkit);
// Create the section sub controls
- selector = new StepContextSelectorControl(null);
+ selector = new StepContextSelectorControl(null) {
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.launch.ui.tabs.selector.StepContextSelectorControl#onModelNodeCheckStateChanged(org.eclipse.tcf.te.runtime.model.interfaces.IModelNode, boolean)
+ */
+ @Override
+ protected void onModelNodeCheckStateChanged(IModelNode node, boolean checked) {
+ getManagedForm().dirtyStateChanged();
+ }
+ };
selector.setFormToolkit(toolkit);
selector.setupPanel(client);
}
@@ -122,6 +137,24 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
*/
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
+ Assert.isNotNull(configuration);
+
+ if (selector != null) {
+ IStepContext[] contexts = ContextSelectorPersistenceDelegate.getLaunchContexts(configuration);
+ if (contexts != null && contexts.length > 0) {
+ // Loop the contexts and create a list of nodes
+ List<IModelNode> nodes = new ArrayList<IModelNode>();
+ for (IStepContext context : contexts) {
+ IModelNode node = context.getModelNode();
+ if (node != null && !nodes.contains(node)) {
+ nodes.add(node);
+ }
+ }
+ if (!nodes.isEmpty()) {
+ selector.setCheckedModelContexts(nodes.toArray(new IModelNode[nodes.size()]));
+ }
+ }
+ }
}
/* (non-Javadoc)
@@ -129,6 +162,28 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
*/
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ Assert.isNotNull(configuration);
+
+ if (selector != null) {
+ IModelNode[] nodes = selector.getCheckedModelContexts();
+ // Loop the nodes and create a list of step contexts
+ List<IStepContext> contexts = new ArrayList<IStepContext>();
+ for (IModelNode node : nodes) {
+ IStepContext context = (IStepContext)Platform.getAdapterManager().loadAdapter(node, IStepContext.class.getName());
+ if (context != null && !contexts.contains(context)) {
+ contexts.add(context);
+ }
+ }
+
+ // Write the selected contexts to the launch configuration
+ if (!contexts.isEmpty()) {
+ ContextSelectorPersistenceDelegate.setLaunchContexts(configuration, contexts.toArray(new IStepContext[contexts.size()]));
+ } else {
+ ContextSelectorPersistenceDelegate.setLaunchContexts(configuration, null);
+ }
+ } else {
+ ContextSelectorPersistenceDelegate.setLaunchContexts(configuration, null);
+ }
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate2.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate2.java
new file mode 100644
index 000000000..410afb33f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate2.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.factory;
+
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate2;
+
+
+/**
+ * Abstract model node factory delegate implementing {@link IFactoryDelegate2}.
+ */
+public abstract class AbstractFactoryDelegate2 extends AbstractFactoryDelegate implements IFactoryDelegate2 {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java
index b4c47aad7..926b9129a 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java
@@ -14,6 +14,7 @@ import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactory;
import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate2;
import org.eclipse.tcf.te.runtime.model.internal.factory.FactoryDelegateManager;
/**
@@ -43,13 +44,8 @@ public final class Factory extends PlatformObject implements IFactory {
super();
}
- /**
- * Creates an new instance of the model node object implementing
- * the specified node interface.
- *
- * @param nodeInterface The node interface to be implemented by the model node object to create.
- * Must not be <code>null</code>.
- * @return The model not object implementing the specified node interface or <code>null</code>.
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactory#newInstance(java.lang.Class)
*/
@Override
public <V extends IModelNode> V newInstance(Class<V> nodeInterface) {
@@ -58,6 +54,19 @@ public final class Factory extends PlatformObject implements IFactory {
// Determine the model node factory delegate to use
IFactoryDelegate delegate = manager.getFactoryDelegate(nodeInterface);
// Return the model node instance
- return delegate != null ? (V)delegate.newInstance(nodeInterface) : null;
+ return delegate != null ? (V) delegate.newInstance(nodeInterface) : null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactory#newInstance(java.lang.Class, java.lang.Object[])
+ */
+ @Override
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface, Object[] args) {
+ Assert.isNotNull(nodeInterface);
+
+ // Determine the model node factory delegate to use
+ IFactoryDelegate delegate = manager.getFactoryDelegate(nodeInterface);
+ // Return the model node instance
+ return delegate instanceof IFactoryDelegate2 ? (V) ((IFactoryDelegate2)delegate).newInstance(nodeInterface, args) : null;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java
index 0c1b5b407..176023481 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java
@@ -25,4 +25,20 @@ public interface IFactory extends IAdaptable {
* @return The node object implementing the specified node interface or <code>null</code>.
*/
public <V extends IModelNode> V newInstance(Class<V> nodeInterface);
+
+ /**
+ * Creates an new instance of an node object implementing the specified node interface.
+ * <p>
+ * <b>Note:</b> Factory delegates must implement {@link IFactoryDelegate2} to be invoked by
+ * this method.
+ *
+ * @param nodeInterface The node interface to be implemented by the node object to be created.
+ * Must not be <code>null</code>.
+ * @param args The arguments to be passed to a matching constructor, or <code>null</code>.
+ *
+ * @return The node object implementing the specified node interface or <code>null</code>.
+ *
+ * @see IFactoryDelegate2#newInstance(Class, Object[])
+ */
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface, Object[] args);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate2.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate2.java
new file mode 100644
index 000000000..6b3f6cc72
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate2.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.interfaces.factory;
+
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+
+/**
+ * Interface to be implemented by model node factory delegates.
+ */
+public interface IFactoryDelegate2 extends IFactoryDelegate {
+
+ /**
+ * Returns a new instance of an node object implementing the given node interface.
+ * <p>
+ * If <code>args</code> is <code>null</code>, the node object returned by this method
+ * should be the same as by calling {@link #newInstance(Class)}.
+ * <p>
+ * If <code>args</code> is not <code>null</code>, the method is matching the argument
+ * types with the argument types of the node object constructor(s) and call the matched
+ * constructor. If no constructor is matching the argument types, the method does return
+ * <code>null</code>.
+ *
+ * @param nodeInterface The node interface to be implemented by the node object to be created.
+ * Must not be <code>null</code>.
+ * @param args The arguments to be passed to a matching constructor, or <code>null</code>.
+ *
+ * @return The node object implementing the specified node interface or <code>null</code>.
+ */
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface, Object[] args);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IPropertiesAccessService.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IPropertiesAccessService.java
index 29b1de9bc..f26b29b67 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IPropertiesAccessService.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.services/src/org/eclipse/tcf/te/runtime/services/interfaces/IPropertiesAccessService.java
@@ -14,8 +14,8 @@ import java.util.Map;
/**
* Properties access service.
* <p>
- * Allows generic access to properties of a given context without having
- * to know all the details and limitations for accessing the desired properties.
+ * Allows generic access to properties of a given context without having to know all the details and
+ * limitations for accessing the desired properties.
*/
public interface IPropertiesAccessService extends IService {
@@ -40,8 +40,8 @@ public interface IPropertiesAccessService extends IService {
public Map<String, String> getTargetAddress(Object context);
/**
- * Returns the property value stored under the given property key. If the property
- * does not exist, <code>null</code> is returned.
+ * Returns the property value stored under the given property key. If the property does not
+ * exist, <code>null</code> is returned.
*
* @param context The context to get the property from. Must not be <code>null</code>.
* @param key The property key. Must not be <code>null</code>.
@@ -49,4 +49,12 @@ public interface IPropertiesAccessService extends IService {
* @return The stored property value or <code>null</code>.
*/
public Object getProperty(Object context, String key);
+
+ /**
+ * Returns the direct parent node of the given context object.
+ *
+ * @param context The context to get the parent from. Must not be <code>null</code>.
+ * @return The direct parent node or <code>null</code>.
+ */
+ public Object getParent(Object context);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStepContext.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStepContext.java
index fb8b1a712..082d9ff23 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStepContext.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.stepper/src/org/eclipse/tcf/te/runtime/stepper/interfaces/IStepContext.java
@@ -40,4 +40,28 @@ public interface IStepContext extends IModelNodeProvider {
* @return The context information or <code>null</code>.
*/
public String getInfo(IPropertiesContainer data);
+
+ /**
+ * Returns if or if not the associated model node really exist.
+ *
+ * @return <code>True</code> if the associated model node really exists, <code>false</code> otherwise.
+ */
+ public boolean exists();
+
+ /**
+ * Encodes the context to an persistable representation.
+ * <p>
+ * <b>Note:</b> The persistable representation is expected to be a single line.
+ *
+ * @return The persistable representation of the context.
+ */
+ public String encode();
+
+ /**
+ * Decodes the given persistable representation and store the result
+ * in the context.
+ *
+ * @param value The persistable representation of the context. Must not be <code>null</code>.
+ */
+ public void decode(String value);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/tracing/TraceHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/tracing/TraceHandler.java
index 12e1df46e..354c60a49 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/tracing/TraceHandler.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/tracing/TraceHandler.java
@@ -194,7 +194,7 @@ public class TraceHandler {
/**
* Returns the tracer instance. Create a new tracer instance
- * on first invokation.
+ * on first invocation.
*
* @return The tracer instance.
*/
@@ -206,6 +206,13 @@ public class TraceHandler {
}
/**
+ * Return the current debug mode.
+ */
+ public final int getDebugMode() {
+ return getTracer().getDebugMode();
+ }
+
+ /**
* Check whether a trace slot is enabled with the given debug mode.
*
* @param debugMode The debug mode
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/AdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/AdapterFactory.java
index 0b7c00eda..e375bd046 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/AdapterFactory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/AdapterFactory.java
@@ -13,8 +13,10 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext;
+import org.eclipse.tcf.te.tcf.locator.interfaces.IModelListener;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.tcf.locator.listener.ModelAdapter;
@@ -35,7 +37,7 @@ public class AdapterFactory implements IAdapterFactory {
* Constructor.
*/
public AdapterFactory() {
- Model.getModel().addListener(new ModelAdapter() {
+ final IModelListener listener = new ModelAdapter() {
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tcf.locator.listener.ModelAdapter#locatorModelChanged(org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel, org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel, boolean)
*/
@@ -47,7 +49,17 @@ public class AdapterFactory implements IAdapterFactory {
if (adapter instanceof IDisposable) ((IDisposable)adapter).dispose();
}
}
- });
+ };
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ Model.getModel().addListener(listener);
+ }
+ };
+
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeAndWait(runnable);
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/StepContextAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/StepContextAdapter.java
index 5b701e0e0..963e9afa1 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/StepContextAdapter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/internal/adapters/StepContextAdapter.java
@@ -9,10 +9,15 @@
*******************************************************************************/
package org.eclipse.tcf.te.tcf.launch.core.internal.adapters;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.protocol.JSON;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
@@ -24,7 +29,7 @@ import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
*/
public class StepContextAdapter extends PlatformObject implements IStepContext {
// Reference to the wrapped peer model
- /* default */ final IPeerModel peerModel;
+ /* default */ IPeerModel peerModel;
/**
* Constructor.
@@ -50,7 +55,7 @@ public class StepContextAdapter extends PlatformObject implements IStepContext {
*/
@Override
public String getId() {
- return peerModel.getPeerId();
+ return peerModel != null ? peerModel.getPeerId() : null;
}
/* (non-Javadoc)
@@ -60,25 +65,89 @@ public class StepContextAdapter extends PlatformObject implements IStepContext {
public String getName() {
final AtomicReference<String> name = new AtomicReference<String>();
+ if (peerModel != null) {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ name.set(peerModel.getName());
+ }
+ };
+
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeAndWait(runnable);
+ }
+
+ return name.get();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext#getInfo(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer)
+ */
+ @Override
+ public String getInfo(IPropertiesContainer data) {
+ return ""; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext#exists()
+ */
+ @Override
+ public boolean exists() {
+ final AtomicBoolean isGhost = new AtomicBoolean();
+
+ if (peerModel != null) {
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ isGhost.set(peerModel.getBooleanProperty(IModelNode.PROPERTY_IS_GHOST));
+ }
+ };
+
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeAndWait(runnable);
+ }
+
+ return peerModel != null && !isGhost.get();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext#encode()
+ */
+ @Override
+ public String encode() {
+ final AtomicReference<String> encoded = new AtomicReference<String>();
+
Runnable runnable = new Runnable() {
@Override
public void run() {
- name.set(peerModel.getName());
+ try {
+ Map<String, String> attrs = new HashMap<String, String>(peerModel.getPeer().getAttributes());
+
+ // Remove all transient attributes
+ String[] keys = attrs.keySet().toArray(new String[attrs.keySet().size()]);
+ for (String key : keys) {
+ if (key.endsWith(".transient")) { //$NON-NLS-1$
+ attrs.remove(key);
+ }
+ }
+
+ encoded.set(JSON.toJSON(attrs));
+ }
+ catch (IOException e) { /* ignored on purpose */ }
}
};
if (Protocol.isDispatchThread()) runnable.run();
else Protocol.invokeAndWait(runnable);
- return name.get();
+ return encoded.get() != null ? encoded.get() : ""; //$NON-NLS-1$
}
/* (non-Javadoc)
- * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext#getInfo(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext#decode(java.lang.String)
*/
@Override
- public String getInfo(IPropertiesContainer data) {
- return ""; //$NON-NLS-1$
+ public void decode(String value) {
+ Assert.isNotNull(value);
}
-
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/plugin.xml
index 525a72695..7e16fab85 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/plugin.xml
@@ -56,4 +56,13 @@
</service>
</extension>
+<!-- Model node factory delegate contributions -->
+ <extension point="org.eclipse.tcf.te.runtime.model.factoryDelegates">
+ <delegate
+ class="org.eclipse.tcf.te.tcf.locator.internal.ModelNodeFactoryDelegate"
+ id="org.eclipse.tcf.te.tcf.locator.model.factory.delegate">
+ <nodeType class="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel"/>
+ </delegate>
+ </extension>
+
</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/ModelNodeFactoryDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/ModelNodeFactoryDelegate.java
new file mode 100644
index 000000000..b60c862ec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/ModelNodeFactoryDelegate.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.locator.internal;
+
+import org.eclipse.tcf.protocol.IPeer;
+import org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate2;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tcf.te.tcf.locator.nodes.PeerModel;
+
+/**
+ * Locator model node factory delegate implementation.
+ */
+public class ModelNodeFactoryDelegate extends AbstractFactoryDelegate2 {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate#newInstance(java.lang.Class)
+ */
+ @Override
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate2#newInstance(java.lang.Class, java.lang.Object[])
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface, Object[] args) {
+ if (IPeerModel.class.equals(nodeInterface)) {
+ // Peer model constructor has 2 arguments, ILocatorModel and IPeer
+ if (args.length == 2 && args[0] instanceof ILocatorModel && args[1] instanceof IPeer) {
+ return (V) new PeerModel((ILocatorModel)args[0], (IPeer)args[1]);
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/services/PropertiesAccessService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/services/PropertiesAccessService.java
index 3ed95ee12..e8a96f61c 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/services/PropertiesAccessService.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/services/PropertiesAccessService.java
@@ -92,4 +92,28 @@ public class PropertiesAccessService extends AbstractService implements IPropert
return value.get();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.services.interfaces.IPropertiesAccessService#getParent(java.lang.Object)
+ */
+ @Override
+ public Object getParent(final Object context) {
+ Assert.isNotNull(context);
+
+ final AtomicReference<Object> value = new AtomicReference<Object>();
+ if (context instanceof IPeerModel) {
+ final IPeerModel peerModel = (IPeerModel) context;
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ value.set(peerModel.getParent());
+ }
+ };
+
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeAndWait(runnable);
+ }
+
+ return value.get();
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java
index 75c6d362a..d7df59572 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/nodes/PeerModel.java
@@ -35,7 +35,7 @@ public class PeerModel extends ContainerModelNode implements IPeerModel, IWorkin
* Constructor.
*
* @param model The parent locator model. Must not be <code>null</code>.
- * @param peer The peer or <code>null</code>.
+ * @param peer The peer. Must not be <code>null</code>.
*/
public PeerModel(ILocatorModel model, IPeer peer) {
super();
@@ -43,6 +43,8 @@ public class PeerModel extends ContainerModelNode implements IPeerModel, IWorkin
Assert.isNotNull(model);
this.model = model;
+ Assert.isNotNull(peer);
+
// Set the default properties before enabling the change events.
// The properties changed listeners should not be called from the
// constructor.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.services.contexts/src/org/eclipse/tcf/te/tcf/services/contexts/internal/AdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.services.contexts/src/org/eclipse/tcf/te/tcf/services/contexts/internal/AdapterFactory.java
index b6f8770d3..d0e1ac86e 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.services.contexts/src/org/eclipse/tcf/te/tcf/services/contexts/internal/AdapterFactory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.services.contexts/src/org/eclipse/tcf/te/tcf/services/contexts/internal/AdapterFactory.java
@@ -14,7 +14,9 @@ import java.util.Map;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.tcf.protocol.IPeer;
+import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
+import org.eclipse.tcf.te.tcf.locator.interfaces.IModelListener;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.tcf.locator.listener.ModelAdapter;
@@ -36,7 +38,7 @@ public class AdapterFactory implements IAdapterFactory {
* Constructor.
*/
public AdapterFactory() {
- Model.getModel().addListener(new ModelAdapter() {
+ final IModelListener listener = new ModelAdapter() {
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tcf.locator.listener.ModelAdapter#locatorModelChanged(org.eclipse.tcf.te.tcf.locator.interfaces.nodes.ILocatorModel, org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel, boolean)
*/
@@ -48,7 +50,17 @@ public class AdapterFactory implements IAdapterFactory {
if (adapter instanceof IDisposable) ((IDisposable)adapter).dispose();
}
}
- });
+ };
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ Model.getModel().addListener(listener);
+ }
+ };
+
+ if (Protocol.isDispatchThread()) runnable.run();
+ else Protocol.invokeAndWait(runnable);
}
/* (non-Javadoc)

Back to the top