diff options
author | Tobias Schwarz | 2013-08-22 12:47:24 +0000 |
---|---|---|
committer | Tobias Schwarz | 2013-08-22 12:47:24 +0000 |
commit | 3e04f26cf1a0d3fdf2fcecd6e88aed9dc7f5f98b (patch) | |
tree | 18c1093f5667fab863a599eb3cfb619b10be0d90 /target_explorer | |
parent | 10ae6658d7cc152ec5c2f0c4e76704120e4c3f3e (diff) | |
download | org.eclipse.tcf-3e04f26cf1a0d3fdf2fcecd6e88aed9dc7f5f98b.tar.gz org.eclipse.tcf-3e04f26cf1a0d3fdf2fcecd6e88aed9dc7f5f98b.tar.xz org.eclipse.tcf-3e04f26cf1a0d3fdf2fcecd6e88aed9dc7f5f98b.zip |
Target Explorer: rework ProcessesV1 support
Diffstat (limited to 'target_explorer')
15 files changed, 334 insertions, 61 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/delegates/GsonMapPersistenceDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/delegates/GsonMapPersistenceDelegate.java index ac94f1a8d..ef2868499 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/delegates/GsonMapPersistenceDelegate.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/delegates/GsonMapPersistenceDelegate.java @@ -47,6 +47,8 @@ public class GsonMapPersistenceDelegate extends ExecutableExtension implements I protected static final String VARIABLES = "__VariablesMap__"; //$NON-NLS-1$ + private final Gson gson = new GsonBuilder().setPrettyPrinting().enableComplexMapKeySerialization().create(); + /** * Constructor. */ @@ -126,7 +128,7 @@ public class GsonMapPersistenceDelegate extends ExecutableExtension implements I file = path.addFileExtension(getDefaultFileExtension()).toFile(); } - Gson gson = new GsonBuilder().setPrettyPrinting().create(); +// Gson gson = new GsonBuilder().setPrettyPrinting().create(); Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); //$NON-NLS-1$ if (!isList) { try { @@ -150,7 +152,7 @@ public class GsonMapPersistenceDelegate extends ExecutableExtension implements I } } else if (String.class.equals(container)) { - Gson gson = new GsonBuilder().create(); +// Gson gson = new GsonBuilder().create(); if (!isList) { container = gson.toJson(internalToMap(context)); @@ -216,7 +218,7 @@ public class GsonMapPersistenceDelegate extends ExecutableExtension implements I private Object read(Object context, Object container, boolean isList) throws IOException { Assert.isNotNull(container); - Gson gson = new GsonBuilder().create(); +// Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create(); List<Map<String, Object>> data = new ArrayList<Map<String, Object>>(); if (container instanceof URI) { diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/META-INF/MANIFEST.MF index e51f6ce16..c050cd4e6 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/META-INF/MANIFEST.MF +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/META-INF/MANIFEST.MF @@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0", org.eclipse.tcf.te.runtime.services;bundle-version="1.1.0", org.eclipse.tcf.te.runtime.stepper;bundle-version="1.1.0", org.eclipse.tcf.te.tcf.core;bundle-version="1.1.0", - org.eclipse.tcf.te.tcf.core.model;bundle-version="1.1.0" + org.eclipse.tcf.te.tcf.core.model;bundle-version="1.1.0", + org.eclipse.tcf.te.runtime.concurrent;bundle-version="1.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin 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 2d208dfa8..c933ebf4e 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 @@ -170,10 +170,17 @@ <stepGroup id="org.eclipse.tcf.te.tcf.locator.connectStepGroup"> <references> + <reference id="org.eclipse.tcf.te.tcf.locator.connectNoAttachStepGroup"/> + <reference id="org.eclipse.tcf.te.tcf.locator.startDebuggerStepGroup"/> + </references> + </stepGroup> + + <stepGroup + id="org.eclipse.tcf.te.tcf.locator.connectNoAttachStepGroup"> + <references> <reference id="org.eclipse.tcf.te.tcf.locator.setWaitForReadyStep"/> <reference id="org.eclipse.tcf.te.tcf.locator.startSimulatorStepGroup"/> <reference id="org.eclipse.tcf.te.tcf.locator.waitForReadyStepGroup"/> - <reference id="org.eclipse.tcf.te.tcf.locator.startDebuggerStepGroup"/> </references> </stepGroup> diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/IStepAttributes.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/IStepAttributes.java new file mode 100644 index 000000000..2fd7db3d2 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/interfaces/IStepAttributes.java @@ -0,0 +1,27 @@ +/** + * IModuleLoadDataProperties.java + * Created on Jul 2, 2013 + * + * Copyright (c) 2013 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.tcf.te.tcf.locator.interfaces; + +/** + * Keys for module load data. + */ +public interface IStepAttributes { + + /** + * Define the prefix used by all other attribute id's as prefix. + */ + public static final String ATTR_PREFIX = "org.eclipse.tcf.te.tcf.locator"; //$NON-NLS-1$ + + /** + * Marker for AttachDebuggerStep if the debugger should be attached or not to the active context. + */ + public static final String ATTR_START_DEBUGGER = ATTR_PREFIX + ".start_debugger"; //$NON-NLS-1$ +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/iterators/StartDebuggerIterator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/iterators/StartDebuggerIterator.java index 35e14e2bb..2d789a7ce 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/iterators/StartDebuggerIterator.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/iterators/StartDebuggerIterator.java @@ -16,8 +16,10 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; +import org.eclipse.tcf.te.runtime.stepper.StepperAttributeUtil; import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId; import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext; +import org.eclipse.tcf.te.tcf.locator.interfaces.IStepAttributes; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; @@ -60,5 +62,6 @@ public class StartDebuggerIterator extends AbstractPeerModelStepGroupIterator { */ @Override public void internalNext(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor) throws CoreException { + StepperAttributeUtil.setProperty(IStepAttributes.ATTR_START_DEBUGGER, fullQualifiedId, data, true); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/StartDebuggerStep.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/StartDebuggerStep.java index af866e541..b952c781e 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/StartDebuggerStep.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/StartDebuggerStep.java @@ -23,9 +23,11 @@ import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; import org.eclipse.tcf.te.runtime.services.ServiceManager; import org.eclipse.tcf.te.runtime.services.interfaces.IDebugService; +import org.eclipse.tcf.te.runtime.stepper.StepperAttributeUtil; import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId; import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext; import org.eclipse.tcf.te.runtime.utils.StatusHelper; +import org.eclipse.tcf.te.tcf.locator.interfaces.IStepAttributes; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModelProperties; import org.eclipse.tcf.te.tcf.locator.interfaces.services.ILocatorModelPeerNodeQueryService; @@ -56,6 +58,7 @@ public class StartDebuggerStep extends AbstractPeerModelStep { final IPeerModel node = getActivePeerModelContext(context, data, fullQualifiedId); Assert.isNotNull(node); + if (StepperAttributeUtil.getBooleanProperty(IStepAttributes.ATTR_START_DEBUGGER, fullQualifiedId, data)) { Runnable runnable = new Runnable() { @Override public void run() { @@ -90,16 +93,16 @@ public class StartDebuggerStep extends AbstractPeerModelStep { dbgService.attach(node, props, monitor, callback); } else { - callback.done(StartDebuggerStep.this, Status.OK_STATUS); + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); } } }; Protocol.invokeLater(runnable); } else { - callback.done(StartDebuggerStep.this, Status.OK_STATUS); + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); } } else { - callback.done(StartDebuggerStep.this, StatusHelper.getStatus(error)); + callback(data, fullQualifiedId, callback, StatusHelper.getStatus(error), null); } } }); @@ -107,6 +110,10 @@ public class StartDebuggerStep extends AbstractPeerModelStep { }; Protocol.invokeLater(runnable); + } + else { + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); + } } /* (non-Javadoc) @@ -121,7 +128,7 @@ public class StartDebuggerStep extends AbstractPeerModelStep { dbgService.detach(node, props, null, callback); } else { - callback.done(this, Status.OK_STATUS); + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); } } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/WaitForReadyStep.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/WaitForReadyStep.java index 21712c6a9..0d5be9306 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/WaitForReadyStep.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/steps/WaitForReadyStep.java @@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.tcf.protocol.IPeer; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.runtime.callback.Callback; +import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId; @@ -63,11 +64,11 @@ public class WaitForReadyStep extends AbstractPeerModelStep { int refreshCount = 0; @Override public void run() { - if (monitor.isCanceled()) { - callback.done(WaitForReadyStep.this, Status.CANCEL_STATUS); + if (ProgressHelper.isCancel(WaitForReadyStep.this, monitor, callback)) { + return; } else if (refreshCount >= getTotalWork(context, data)) { - callback.done(WaitForReadyStep.this, StatusHelper.getStatus(new TimeoutException(Messages.WaitForReadyStep_error_timeout))); + callback(data, fullQualifiedId, callback, StatusHelper.getStatus(new TimeoutException(Messages.WaitForReadyStep_error_timeout)), null); } else if (getActivePeerModelContext(context, data, fullQualifiedId).isProperty(IPeerModelProperties.PROP_STATE, IPeerModelProperties.STATE_WAITING_FOR_READY)) { // Refresh the model now (must be executed within the TCF dispatch thread) @@ -82,16 +83,26 @@ public class WaitForReadyStep extends AbstractPeerModelStep { } else { int state = getActivePeerModelContext(context, data, fullQualifiedId).getIntProperty(IPeerModelProperties.PROP_STATE); - if (state == IPeerModelProperties.STATE_CONNECTED || state == IPeerModelProperties.STATE_REACHABLE) - callback.done(WaitForReadyStep.this, Status.OK_STATUS); + if (state == IPeerModelProperties.STATE_CONNECTED || state == IPeerModelProperties.STATE_REACHABLE) { + Object wait = getParameters().get("wait"); //$NON-NLS-1$ + if (wait != null) { + try { + int waitValue = Integer.parseInt(wait.toString()); + ExecutorsUtil.waitAndExecute(waitValue, null); + } + catch (Exception e) { + } + } + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); + } else - callback.done(WaitForReadyStep.this, StatusHelper.getStatus(new CoreException(new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), Messages.WaitForReadyStep_error_state)))); + callback(data, fullQualifiedId, callback, StatusHelper.getStatus(new CoreException(new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), Messages.WaitForReadyStep_error_state))), null); } } }); } else { - callback.done(this, Status.OK_STATUS); + callback(data, fullQualifiedId, callback, Status.OK_STATUS, null); } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java index bb9a0a433..93c334b25 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/launcher/IProcessLauncher.java @@ -101,6 +101,14 @@ public interface IProcessLauncher extends IAdaptable { public static String PROP_CONNECTION_NAME = "connection.name"; //$NON-NLS-1$ /** + * Property denoting additional parameters for ProcessesV1. + * When set, parameters are only used from this map. + * <p> + * The property type is {@link Map<String,Object>}. + */ + public static String PROP_PROCESSESV1_PARAMS = "processesV1.params"; //$NON-NLS-1$ + + /** * Launch a remote process defined by the given launch properties at the target specified by the * given peer. * <p> diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/steps/IProcessesStepAttributes.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/steps/IProcessesStepAttributes.java index 268bf27c8..893ffa912 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/steps/IProcessesStepAttributes.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/interfaces/steps/IProcessesStepAttributes.java @@ -61,6 +61,11 @@ public interface IProcessesStepAttributes { public static final String ATTR_OUTPUT_FILE = ATTR_PREFIX + ".process_output_file"; //$NON-NLS-1$ /** + * Launch configuration attribute: The file name to redirect the output. + */ + public static final String ATTR_ADDITIONAL_PARAMETERS = ATTR_PREFIX + ".process_additional_parameters"; //$NON-NLS-1$ + + /** * Launch configuration attribute (internal use): The process context object. */ public static final String ATTR_PROCESS_CONTEXT = ATTR_PREFIX + ".process_context"; //$NON-NLS-1$ diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java index b1b1eefba..dc8589b02 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/launcher/ProcessLauncher.java @@ -25,6 +25,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.runtime.Assert; @@ -831,8 +832,13 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher if (processEnvDiff != null && !processEnvDiff.isEmpty()) { processEnv.putAll(processEnvDiff); } - // Assure that the TERM variable is set to "ansi" - processEnv.put("TERM", "ansi"); //$NON-NLS-1$ //$NON-NLS-2$ + + boolean processConsole = properties.getBooleanProperty(IProcessLauncher.PROP_PROCESS_ASSOCIATE_CONSOLE); + + if (processConsole) { + // Assure that the TERM variable is set to "ansi" + processEnv.put("TERM", "ansi"); //$NON-NLS-1$ //$NON-NLS-2$ + } boolean attach = properties.getBooleanProperty(IProcessLauncher.PROP_PROCESS_ATTACH); @@ -841,11 +847,19 @@ public class ProcessLauncher extends PlatformObject implements IProcessLauncher // Fill in the process launch parameter Map<String, Object> params = new HashMap<String, Object>(); - params.put(IProcessesV1.START_ATTACH, Boolean.valueOf(attach)); - params.put(IProcessesV1.START_ATTACH_CHILDREN, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_ATTACH_CHILDREN))); - params.put(IProcessesV1.START_STOP_AT_ENTRY, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_STOP_AT_ENTRY))); - params.put(IProcessesV1.START_STOP_AT_MAIN, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_STOP_AT_MAIN))); - params.put(IProcessesV1.START_USE_TERMINAL, Boolean.TRUE); + if (properties.getProperty(IProcessLauncher.PROP_PROCESSESV1_PARAMS) != null) { + Map<String, Object> addParams = (Map<String, Object>)properties.getProperty(IProcessLauncher.PROP_PROCESSESV1_PARAMS); + for (Entry<String,Object> entry : addParams.entrySet()) { + params.put(entry.getKey(), entry.getValue()); + } + } + else { + params.put(IProcessesV1.START_ATTACH, Boolean.valueOf(attach)); + params.put(IProcessesV1.START_ATTACH_CHILDREN, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_ATTACH_CHILDREN))); + params.put(IProcessesV1.START_STOP_AT_ENTRY, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_STOP_AT_ENTRY))); + params.put(IProcessesV1.START_STOP_AT_MAIN, Boolean.valueOf(properties.getBooleanProperty(IProcessesV1.START_STOP_AT_MAIN))); + params.put(IProcessesV1.START_USE_TERMINAL, Boolean.valueOf(processConsole)); + } ((IProcessesV1)getSvcProcesses()).start(processCWD, processPath, processArgs, processEnv, params, new IProcesses.DoneStart() { @Override diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java index 95106fea6..cafea2767 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/IProcessContextNodeProperties.java @@ -30,4 +30,12 @@ public interface IProcessContextNodeProperties { * The command line of the context. The command line is a string array. */ public static final String PROPERTY_CMD_LINE = "cmdline"; //$NON-NLS-1$ + + /** + * The capabilities the "ProcessesV1" service provides for the given process id. + * <p> + * The property data is a <code>Map<String, Object></code>. + */ + public static final String PROPERTY_CAPABILITIES = "capabilities"; //$NON-NLS-1$ + } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelLookupService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelLookupService.java new file mode 100644 index 000000000..f2b5f6d29 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/interfaces/runtime/IRuntimeModelLookupService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013 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.processes.core.model.interfaces.runtime; + +import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; +import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelLookupService; + +/** + * Common interface to be implemented by a model lookup service. + */ +public interface IRuntimeModelLookupService extends IModelLookupService { + + public static final String CAPABILITY_THREAD_CREATION = "ThreadCreation"; //$NON-NLS-1$ + public static final String CAPABILITY_PROCESS_CREATION = "ProcessCreation"; //$NON-NLS-1$ + + /** + * Search the associated model for the process context root node + * providing the given capabilities. + * <p> + * The callback result contains either the process context root node or <code>null</code>. + * + * @param capabilities The capabilities. Must not be <code>null</code> and must not be empty. + * @param callback The callback. Must not be <code>null</code>. + */ + public void lkupModelNodeByCapability(String[] capabilities, ICallback callback); + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java index a387ad28c..c8bc0c169 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/RuntimeModel.java @@ -31,6 +31,7 @@ import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelService; import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelUpdateService; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModelLookupService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelChannelService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelLookupService; import org.eclipse.tcf.te.tcf.processes.core.model.runtime.services.RuntimeModelRefreshService; @@ -53,7 +54,7 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo // Reference to the refresh service private final IModelRefreshService refreshService = new RuntimeModelRefreshService(this); // Reference to the lookup service - private final IModelLookupService lookupService = new RuntimeModelLookupService(this); + private final IRuntimeModelLookupService lookupService = new RuntimeModelLookupService(this); // Reference to the update service private final IModelUpdateService updateService = new RuntimeModelUpdateService(this); // Reference to the channel service @@ -133,6 +134,9 @@ public final class RuntimeModel extends ContainerModelNode implements IRuntimeMo if (IModelRefreshService.class.equals(adapter)) { return refreshService; } + if (IRuntimeModelLookupService.class.equals(adapter)) { + return lookupService; + } if (IModelLookupService.class.equals(adapter)) { return lookupService; } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelLookupService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelLookupService.java index 0137d2349..033df0754 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelLookupService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelLookupService.java @@ -11,20 +11,30 @@ package org.eclipse.tcf.te.tcf.processes.core.model.runtime.services; import java.util.ArrayList; import java.util.List; +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.Status; +import org.eclipse.tcf.te.runtime.callback.Callback; +import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; -import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelLookupService; +import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx; +import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx.QueryState; +import org.eclipse.tcf.te.runtime.model.interfaces.contexts.IAsyncRefreshableCtx.QueryType; +import org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelRefreshService; import org.eclipse.tcf.te.tcf.core.model.services.AbstractModelService; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNodeProperties; import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModel; +import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.runtime.IRuntimeModelLookupService; /** * Runtime model lookup service implementation. */ -public class RuntimeModelLookupService extends AbstractModelService<IRuntimeModel> implements IModelLookupService { +public class RuntimeModelLookupService extends AbstractModelService<IRuntimeModel> implements IRuntimeModelLookupService { /** * Constructor. @@ -116,4 +126,73 @@ public class RuntimeModelLookupService extends AbstractModelService<IRuntimeMode return nodes; } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.tcf.core.model.interfaces.services.IModelLookupService#lkupModelNodeByCapability(java.lang.String[], org.eclipse.tcf.te.runtime.interfaces.callback.ICallback) + */ + @Override + public void lkupModelNodeByCapability(final String[] capabilities, final ICallback callback) { + Assert.isNotNull(capabilities); + Assert.isTrue(capabilities.length > 0); + Assert.isNotNull(callback); + + final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)getModel().getAdapter(IAsyncRefreshableCtx.class); + if (refreshable != null && refreshable.getQueryState(QueryType.CHILD_LIST) != QueryState.DONE) { + // The model needs a refresh + getModel().getService(IModelRefreshService.class).refresh(new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + callback.setResult(findInContainerByCapabilitiesRecursively(getModel(), capabilities)); + callback.done(RuntimeModelLookupService.this, Status.OK_STATUS); + } + }); + } else { + callback.setResult(findInContainerByCapabilitiesRecursively(getModel(), capabilities)); + callback.done(RuntimeModelLookupService.this, Status.OK_STATUS); + } + } + + /** + * Search the given container recursively and returns all nodes matching the given capabilities. + * + * @param container The container. Must not be <code>null</code<. + * @param capabilities The capabilities to match. Must not be <code>null</code>. + * + * @return The list of matching nodes, or an empty list. + */ + protected IProcessContextNode findInContainerByCapabilitiesRecursively(IContainerModelNode container, String[] capabilities) { + Assert.isNotNull(container); + Assert.isNotNull(capabilities); + + IProcessContextNode node = null; + List<IProcessContextNode> candidates = container.getChildren(IProcessContextNode.class); + for (IProcessContextNode candidate : candidates) { + Map<String, Object> caps = (Map<String, Object>)candidate.getProperty(IProcessContextNodeProperties.PROPERTY_CAPABILITIES); + if (caps != null) { + boolean allFound = true; + for (String capability : capabilities) { + if (!caps.containsKey(capability) || !Boolean.parseBoolean(caps.get(capability).toString())) { + allFound = false; + break; + } + } + + if (allFound) { + node = candidate; + break; + } + } + } + + if (node == null) { + for (IProcessContextNode candidate : candidates) { + node = findInContainerByCapabilitiesRecursively(candidate, capabilities); + if (node != null) { + break; + } + } + } + + return node; + } } diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java index 2e04f5cbb..7be46e069 100644 --- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java +++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.processes.core/src/org/eclipse/tcf/te/tcf/processes/core/model/runtime/services/RuntimeModelRefreshService.java @@ -23,6 +23,7 @@ import org.eclipse.tcf.protocol.IChannel; import org.eclipse.tcf.protocol.IToken; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.services.IProcesses; +import org.eclipse.tcf.services.IProcessesV1; import org.eclipse.tcf.services.ISysMonitor; import org.eclipse.tcf.services.ISysMonitor.SysMonitorContext; import org.eclipse.tcf.te.core.async.AsyncCallbackCollector; @@ -289,6 +290,7 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod if (error == null) { final IProcesses service = channel.getRemoteService(IProcesses.class); Assert.isNotNull(service); + final IProcessesV1 serviceV1 = channel.getRemoteService(IProcessesV1.class); final ISysMonitor sysMonService = channel.getRemoteService(ISysMonitor.class); Assert.isNotNull(sysMonService); final String contextId = ((IProcessContextNode)node).getStringProperty(IModelNode.PROPERTY_ID); @@ -308,7 +310,18 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod @Override public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { ((IProcessContextNode)node).setProcessContext(context); - callback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + if (serviceV1 != null) { + serviceV1.getCapabilities(context.getID(), new IProcessesV1.DoneGetCapabilities() { + @Override + public void doneGetCapabilities(IToken token, Exception error, Map<String, Object> properties) { + ((IProcessContextNode)node).setProperty(IProcessContextNodeProperties.PROPERTY_CAPABILITIES, properties); + + callback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + }); + } + else + callback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); } }); } @@ -354,6 +367,7 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod // Get the Systems service and query the configuration id's final IProcesses service = channel.getRemoteService(IProcesses.class); Assert.isNotNull(service); + final IProcessesV1 serviceV1 = channel.getRemoteService(IProcessesV1.class); final ISysMonitor sysMonService = channel.getRemoteService(ISysMonitor.class); Assert.isNotNull(sysMonService); sysMonService.getChildren(parentContextId, new ISysMonitor.DoneGetChildren() { @@ -402,44 +416,93 @@ public class RuntimeModelRefreshService extends AbstractModelService<IRuntimeMod public void doneGetContext(IToken token, Exception error, IProcesses.ProcessContext context) { // Errors are ignored node.setProcessContext(context); - if (context != null) node.setProperty(IProcessContextNodeProperties.PROPERTY_NAME, context.getName()); - // Get the asynchronous refresh context adapter - final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); - - // Refresh the children of the node if the depth is still larger than 0 - if (depth - 1 > 0 && (refreshable == null || !refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.IN_PROGRESS))) { - if (refreshable != null) { - // Mark the refresh as in progress - refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.IN_PROGRESS); - // Create a new pending operation node and associate it with the refreshable - PendingOperationModelNode pendingNode = new PendingOperationNode(); - pendingNode.setParent(node); - refreshable.setPendingOperationNode(pendingNode); - } + if (context != null) node.setProperty(IProcessContextNodeProperties.PROPERTY_NAME, context.getName()); - // Don't send change events while refreshing - final boolean changed = node.setChangeEventsEnabled(false); - // Initiate the refresh - List<IProcessContextNode> oldChildren = node.getChildren(IProcessContextNode.class); - refreshContextChildren(oldChildren, model, node, depth - 1, new Callback() { + if (serviceV1 != null) { + serviceV1.getCapabilities(context.getID(), new IProcessesV1.DoneGetCapabilities() { @Override - protected void internalDone(Object caller, IStatus status) { - // Mark the refresh as done - refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.DONE); - // Reset the pending operation node - refreshable.setPendingOperationNode(null); - // Re-enable the change events if they had been enabled before - if (changed) node.setChangeEventsEnabled(true); - // Trigger a refresh of the view content - ChangeEvent event = new ChangeEvent(node, IContainerModelNode.NOTIFY_CHANGED, null, null); - EventManager.getInstance().fireEvent(event); - // Finally invoke the callback - innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); - } + public void doneGetCapabilities(IToken token, Exception error, Map<String, Object> properties) { + node.setProperty(IProcessContextNodeProperties.PROPERTY_CAPABILITIES, properties); + // Get the asynchronous refresh context adapter + final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); + + // Refresh the children of the node if the depth is still larger than 0 + if (depth - 1 > 0 && (refreshable == null || !refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.IN_PROGRESS))) { + if (refreshable != null) { + // Mark the refresh as in progress + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.IN_PROGRESS); + // Create a new pending operation node and associate it with the refreshable + PendingOperationModelNode pendingNode = new PendingOperationNode(); + pendingNode.setParent(node); + refreshable.setPendingOperationNode(pendingNode); + } + + // Don't send change events while refreshing + final boolean changed = node.setChangeEventsEnabled(false); + // Initiate the refresh + List<IProcessContextNode> oldChildren = node.getChildren(IProcessContextNode.class); + refreshContextChildren(oldChildren, model, node, depth - 1, new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + // Mark the refresh as done + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.DONE); + // Reset the pending operation node + refreshable.setPendingOperationNode(null); + // Re-enable the change events if they had been enabled before + if (changed) node.setChangeEventsEnabled(true); + // Trigger a refresh of the view content + ChangeEvent event = new ChangeEvent(node, IContainerModelNode.NOTIFY_CHANGED, null, null); + EventManager.getInstance().fireEvent(event); + // Finally invoke the callback + innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + }); + } else { + innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + } }); - } else { - innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + else { + // Get the asynchronous refresh context adapter + final IAsyncRefreshableCtx refreshable = (IAsyncRefreshableCtx)node.getAdapter(IAsyncRefreshableCtx.class); + + // Refresh the children of the node if the depth is still larger than 0 + if (depth - 1 > 0 && (refreshable == null || !refreshable.getQueryState(QueryType.CHILD_LIST).equals(QueryState.IN_PROGRESS))) { + if (refreshable != null) { + // Mark the refresh as in progress + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.IN_PROGRESS); + // Create a new pending operation node and associate it with the refreshable + PendingOperationModelNode pendingNode = new PendingOperationNode(); + pendingNode.setParent(node); + refreshable.setPendingOperationNode(pendingNode); + } + + // Don't send change events while refreshing + final boolean changed = node.setChangeEventsEnabled(false); + // Initiate the refresh + List<IProcessContextNode> oldChildren = node.getChildren(IProcessContextNode.class); + refreshContextChildren(oldChildren, model, node, depth - 1, new Callback() { + @Override + protected void internalDone(Object caller, IStatus status) { + // Mark the refresh as done + refreshable.setQueryState(QueryType.CHILD_LIST, QueryState.DONE); + // Reset the pending operation node + refreshable.setPendingOperationNode(null); + // Re-enable the change events if they had been enabled before + if (changed) node.setChangeEventsEnabled(true); + // Trigger a refresh of the view content + ChangeEvent event = new ChangeEvent(node, IContainerModelNode.NOTIFY_CHANGED, null, null); + EventManager.getInstance().fireEvent(event); + // Finally invoke the callback + innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + }); + } else { + innerCallback.done(RuntimeModelRefreshService.this, Status.OK_STATUS); + } + } } }); |