Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: d002acf6a7ef9b5c803586addc3a15c2bbfa2478 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*******************************************************************************
 * Copyright (c) 2014 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.utils;

import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
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.interfaces.callback.ICallback;
import org.eclipse.tcf.te.runtime.services.ServiceManager;
import org.eclipse.tcf.te.runtime.services.interfaces.IService;
import org.eclipse.tcf.te.runtime.services.interfaces.ISimulatorService;
import org.eclipse.tcf.te.tcf.core.interfaces.IPeerProperties;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;

/**
 * Simulator related utilities.
 */
public final class SimulatorUtils {

	/**
	 * Result of getSimulatorService.
	 */
	public static class Result {
		public ISimulatorService service;
		public String id;
		public String settings;
	}

	/**
	 * Returns if or if the given peer model has the simulator enabled or not.
	 *
	 * @param peerNode The peer model node. Must not be <code>null</code>.
	 * @return <code>True</code> if the simulator is enabled, <code>false</code> otherwise.
	 */
	public static boolean isSimulatorEnabled(final IPeerNode peerNode) {
		Assert.isNotNull(peerNode);

		final AtomicBoolean isEnabled = new AtomicBoolean(false);

		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				String subType = peerNode.getPeer().getAttributes().get(IPeerProperties.PROP_SUBTYPE);
				if (subType != null) {
					isEnabled.set(subType.equals(IPeerProperties.SUBTYPE_SIM));
				}
			}
		};

		if (Protocol.isDispatchThread()) runnable.run();
		else Protocol.invokeAndWait(runnable);

		return isEnabled.get();
	}

	/**
	 * Returns the simulator service and the settings for the simulator launch.
	 * If no simulator service is configured in the peer
	 * or the configured service is not available, <code>null</code> will be returned.
	 *
	 * @param peerNode The peer model node. Must not be <code>null</code>.
	 * @return The {@link Result} containing the simulator service and the settings or <code>null</code>.
	 */
	public static Result getSimulatorService(final IPeerNode peerNode) {
		Assert.isNotNull(peerNode);

		Result result = null;

		IPeer peer = peerNode.getPeer();
		if (peer != null) {
			if (isSimulatorEnabled(peerNode)) {
				String type = peer.getAttributes().get(IPeerProperties.PROP_SIM_TYPE);
				IService[] services = ServiceManager.getInstance().getServices(peerNode, ISimulatorService.class, false);
				for (IService service : services) {
					Assert.isTrue(service instanceof ISimulatorService);
					// Get the UI service which is associated with the simulator service
					String id = service.getId();
					if (id != null && id.equals(type)) {
						result = new Result();
						result.service = (ISimulatorService)service;
						result.id = id;
						result.settings = peer.getAttributes().get(IPeerProperties.PROP_SIM_PROPERTIES);
						break;
					}
				}
			}
		}

		return result;
	}

	/**
	 * Returns the simulator service and the settings for the simulator launch.
	 * If no simulator service is configured in the peer
	 * or the configured service is not available, <code>null</code> will be returned.
	 *
	 * @param peerNode The peer model node. Must not be <code>null</code>.
	 * @return The {@link Result} containing the simulator service and the settings or <code>null</code>.
	 */
	public static ISimulatorService getSimulatorService(final Object context, final String type) {
		Assert.isNotNull(context);

		IService[] services = ServiceManager.getInstance().getServices(context, ISimulatorService.class, false);
		for (IService service : services) {
			Assert.isTrue(service instanceof ISimulatorService);
			// Get the UI service which is associated with the simulator service
			String id = service.getId();
			if (id != null && id.equals(type)) {
				return (ISimulatorService)service;
			}
		}

		return null;
	}

	/**
	 * Starts the simulator if the simulator launch is enabled for the given peer
	 * model node and the configured simulator service type is available. In any
	 * other cases, the given callback is invoked immediately.
	 *
	 * @param peerNode The peer model node. Must not be <code>null</code>.
	 * @param monitor The progress monitor.
	 * @param callback The callback to invoke if finished. Must not be <code>null</code>.
	 */
	public static void start(final IPeerNode peerNode, final IProgressMonitor monitor, final ICallback callback) {
		Assert.isNotNull(peerNode);
		Assert.isNotNull(callback);

		// Determine if we have to start a simulator first
		final Result result = getSimulatorService(peerNode);
		if (result != null && result.service != null) {
			// Check if the simulator is already running
			result.service.isRunning(peerNode, result.settings, new Callback() {
				@Override
				protected void internalDone(Object caller, IStatus status) {
					Object cbResult = getResult();
					if (cbResult instanceof Boolean && !((Boolean)cbResult).booleanValue()) {
						// Start the simulator
						result.service.start(peerNode, result.settings, new Callback() {
							@Override
							protected void internalDone(Object caller, IStatus status) {
								setUsedRunningSimulator(peerNode, false);
								callback.setResult(new Boolean(status.isOK()));
								callback.done(caller, status);
							}
						}, monitor);
					} else {
						// Try to use running simulator
						result.service.useRunning(peerNode, result.settings, new Callback() {
							@Override
							protected void internalDone(Object caller, IStatus status) {
								setUsedRunningSimulator(peerNode, true);
								callback.setResult(new Boolean(status.isOK()));
								callback.done(caller, status);
							}
						}, monitor);
					}
				}
			}, monitor);
		} else {
			setUsedRunningSimulator(peerNode, false);
			callback.setResult(Boolean.FALSE);
			callback.done(null, Status.OK_STATUS);
		}
	}

	protected static void setUsedRunningSimulator(final IPeerNode peerNode, final boolean usedRunning) {
		Protocol.invokeAndWait(new Runnable() {
			@Override
			public void run() {
				peerNode.setProperty(SimulatorUtils.class.getSimpleName() + ".usedRunning", usedRunning ? new Boolean(usedRunning) : null); //$NON-NLS-1$
			}
		});
	}

	protected static boolean getUsedRunningSimulator(final IPeerNode peerNode) {
		final AtomicBoolean usedRunning = new AtomicBoolean(false);
		Protocol.invokeAndWait(new Runnable() {
			@Override
			public void run() {
				usedRunning.set(peerNode.getBooleanProperty(SimulatorUtils.class.getSimpleName() + ".usedRunning")); //$NON-NLS-1$
			}
		});
		return usedRunning.get();
	}

	/**
	 * Stops the simulator if the simulator launch is enabled for the given peer
	 * model node and the configured simulator service type is available. In any
	 * other cases, the given callback is invoked immediately.
	 *
	 * @param peerNode The peer model node. Must not be <code>null</code>.
	 * @param monitor The progress monitor.
	 * @param callback The callback to invoke if finished. Must not be <code>null</code>.
	 */
	public static void stop(final IPeerNode peerNode, final IProgressMonitor monitor, final ICallback callback) {
		Assert.isNotNull(peerNode);
		Assert.isNotNull(callback);

		// Get the associated simulator service
		final Result result = getSimulatorService(peerNode);
		if (result != null && result.service != null && !getUsedRunningSimulator(peerNode)) {
			setUsedRunningSimulator(peerNode, false);
			// Determine if the simulator is at all running
			result.service.isRunning(peerNode, result.settings, new Callback() {
				@Override
				protected void internalDone(Object caller, IStatus status) {
					Object cbResult = getResult();
					if (cbResult instanceof Boolean && ((Boolean)cbResult).booleanValue()) {
						// Stop the simulator
						result.service.stop(peerNode, result.settings, new Callback(callback) {
							@Override
							protected void internalDone(Object caller, IStatus status) {
								callback.done(caller, status);
							}
						}, monitor);
					} else {
						result.service.cleanup(peerNode, result.settings);
						callback.done(null, Status.OK_STATUS);
					}
				}
			}, monitor);
		} else {
			setUsedRunningSimulator(peerNode, false);
			callback.done(null, Status.OK_STATUS);
		}
	}
}

Back to the top