Passed
Push — master ( da9b86...c9f981 )
by Alessandro
07:16
created

clearDispatchedIndex()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
dl 0
loc 2
rs 10
1
package it.cnr.istc.pst.platinum.control.platform;
2
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.HashMap;
6
import java.util.List;
7
import java.util.Map;
8
import java.util.concurrent.atomic.AtomicInteger;
9
10
import it.cnr.istc.pst.platinum.ai.executive.pdb.ExecutionNode;
11
import it.cnr.istc.pst.platinum.control.lang.AgentTaskDescription;
12
import it.cnr.istc.pst.platinum.control.lang.PlatformCommand;
13
import it.cnr.istc.pst.platinum.control.lang.PlatformFeedback;
14
import it.cnr.istc.pst.platinum.control.lang.PlatformFeedbackType;
15
import it.cnr.istc.pst.platinum.control.lang.PlatformObservation;
16
import it.cnr.istc.pst.platinum.control.lang.ex.PlatformException;
17
18
/**
19
 * 
20
 * @author alessandro
21
 *
22
 */
23
public abstract class PlatformProxy 
24
{	
25
	protected static final AtomicInteger obsIdCounter = new AtomicInteger(0);
26
	protected static final AtomicInteger cmdIdCounter = new AtomicInteger(0);
27
	
28
	protected final List<PlatformObserver> observers;							// list of platform observers
29
	
30
	protected Map<Long, PlatformCommand> dispatchedIndex;						// index of dispatched commands by command ID
31
	
32
	/**
33
	 * 
34
	 */
35
	protected PlatformProxy() {
36
		// setup data structures
37
		this.observers = new ArrayList<>();
38
		this.dispatchedIndex = new HashMap<>();
39
	}
40
	
41
	/**
42
	 * 
43
	 * @param cfgFile
44
	 * @throws PlatformException
45
	 */
46
	public abstract void initialize(String cfgFile) 
47
			throws PlatformException;
48
	
49
	
50
	/**
51
	 * This method registers an observer to a particular (physical) platform.
52
	 * 
53
	 *  The interactions between the executive and the physical platform are 
54
	 *  managed through a dedicated PROXY which must implement this interface
55
	 * 
56
	 * @param executive
57
	 */
58
	public void register(PlatformObserver observer) {
59
		// register a new observer
60
		synchronized (this.observers) {
61
			// add the observer
62
			this.observers.add(observer);
63
			// send signal
64
			this.observers.notifyAll();
65
		}
66
	}
67
	
68
	/**
69
	 * Unregister a (previously) registered observer to a particular (physical) platform.
70
	 * 
71
	 * 
72
	 * @param observer
73
	 */
74
	public void unregister(PlatformObserver observer) {
75
		// unregister observers
76
		synchronized (this.observers) {
77
			// remove observer
78
			this.observers.remove(observer);
79
			// send signal
80
			this.observers.notifyAll();
81
		}
82
	}
83
	
84
	/**
85
	 * 
86
	 */
87
	public void clearDispatchedIndex() {
88
		this.dispatchedIndex.clear();
89
	}
90
	
91
	/**
92
	 * 
93
	 * @param cmdId
94
	 * @return
95
	 */
96
	public synchronized PlatformCommand getDispatchedCommand(long cmdId) {
97
		// get command from cache
98
		return this.dispatchedIndex.get(cmdId);
99
	}
100
	
101
	/**
102
	 * 
103
	 * This method sends a request to the real/simulated platform to execute a command.
104
	 * 
105
	 * This method is usually meant for partially controllable commands. The platform/environment is 
106
	 * in charge of the execution of the related command and therefore it will then notify the 
107
	 * acting agent about the successful execution or failures.
108
	 * 
109
	 * Feedbacks about the execution of the command will be then received through the PlatformObserver 
110
	 * interface
111
	 * 
112
	 * @param node
113
	 * @return
114
	 * @throws PlatformException
115
	 */
116
	public abstract PlatformCommand executeNode(ExecutionNode node) 
117
			throws PlatformException;
118
	
119
	/**
120
	 * 
121
	 * This method sends a request to the real/simulated platform to start the execution of a command.
122
	 * 
123
	 * This method is usually meant for controllable commands. The acting agent is in charge of 
124
	 * deciding when to start the execution of a command.
125
	 * 
126
	 * @param node
127
	 * @return
128
	 * @throws PlatformException
129
	 */
130
	public abstract PlatformCommand startNode(ExecutionNode node) 
131
			throws PlatformException;
132
	
133
134
	/**
135
	 * 
136
	 * This method sends a request to the real/simulated platform to stop the execution of a command
137
	 * 
138
	 * This method is usually meant for controllable commands. The acting agent is in charge of 
139
	 * deciding when to stop the execution of a previously started command.  
140
	 * 
141
	 * @param cmd
142
	 * @throws PlatformException
143
	 */
144
	public abstract void stopNode(ExecutionNode node) 
145
			throws PlatformException;
146
	
147
	/**
148
	 * This method check whether an execution node represents a platform command or not. 
149
	 * 
150
	 *  Namely, the method checks if a particular token of a plan actually represents a 
151
	 *  command to be executed on some platform. 
152
	 *  
153
	 *  Clearly, the implementation of this method strongly depends on the functional layer 
154
	 *  provided by the hardware or software platform considered for the execution of 
155
	 *  timeline-based plan.
156
	 * 
157
	 * @param node
158
	 * @return
159
	 */
160
	public abstract boolean isPlatformCommand(ExecutionNode node);
161
	
162
	
163
	/**
164
	 * 
165
	 * @param observation
166
	 */
167
	public void notify(PlatformObservation<? extends Object> observation) 
168
	{
169
		// get platform observers
170
		synchronized (observers) {
171
			// notify observers
172
			for (PlatformObserver observer : observers) {
173
				// notify observation to platform observer
174
				observer.observation(observation);
175
			}
176
		}
177
	}
178
	
179
	/**
180
	 * 
181
	 * @param feedback
182
	 */
183
	public void notify(PlatformFeedback feedback) 
184
	{
185
		// get platform observers
186
		synchronized (observers) {
187
			// notify observers
188
			for (PlatformObserver observer : observers) {
189
				// notify observation to platform observer
190
				observer.feedback(feedback);
191
				
192
			}
193
		}
194
	}
195
		
196
	/**
197
	 * 
198
	 * @param msg
199
	 */
200
	public void notify(AgentTaskDescription msg) {
201
		
202
		// get platform observers
203
		synchronized (observers) {
204
			// notify observers
205
			for (PlatformObserver observer : observers) {
206
				// notify task to platform observers
207
				observer.task(msg);
208
			}
209
		}
210
	}
211
	
212
	/**
213
	 * 
214
	 * @param name
215
	 * @param params
216
	 * @return
217
	 */
218
	public PlatformCommand create(String name, String[] params, ExecutionNode node) {
219
		
220
		// create platform command
221
		PlatformCommand cmd = new PlatformCommand(
222
				cmdIdCounter.getAndIncrement(), 
223
				name, 
224
				params, 
225
				node, 
226
				0);				// command type 0 = start execution request
227
		
228
		// return created command
229
		return cmd;
230
	}
231
	
232
	/**
233
	 * 
234
	 * @param cmd
235
	 */
236
	public void success(PlatformCommand cmd) {
237
		
238
		// create positive feedback
239
		PlatformFeedback feedback = new PlatformFeedback(
240
				obsIdCounter.getAndIncrement(), 
241
				cmd, 
242
				PlatformFeedbackType.SUCCESS);
243
		
244
		// notify feedback
245
		this.notify(feedback);
246
	}
247
	
248
	/**
249
	 * 
250
	 * @param cmd
251
	 */
252
	public void failure(PlatformCommand cmd) {
253
254
		// create negative feedback
255
		PlatformFeedback feedback = new PlatformFeedback(
256
				obsIdCounter.getAndIncrement(), 
257
				cmd, 
258
				PlatformFeedbackType.FAILURE);
259
		
260
		// notify feedback
261
		this.notify(feedback);
262
	}
263
	
264
	
265
	/**
266
	 * 
267
	 * @param node
268
	 * @return
269
	 */
270
	public static String extractCommandName(ExecutionNode node) 
271
	{ 
272
		// get signature
273
		String name = node.getGroundSignature();
274
		// "clear" command name from "control tags"
275
		if (name.startsWith("_")) {
276
			// remove partial controllability tag
277
			name = name.replaceFirst("_", "");
278
		}
279
		
280
		// discard parameters if any 
281
		String[] splits = name.split("-");
282
		// set the first element as command name
283
		name = splits[0];
284
		
285
		// get cleared command name 
286
		return name.toLowerCase();
287
	}
288
	
289
	
290
	/**
291
	 * 
292
	 * @param node
293
	 * @return
294
	 */
295
	public static String[] extractCommandParameters(ExecutionNode node) {
296
		// extract command parameter from node to execute
297
		String[] splits = node.getGroundSignature().split("-");
298
		// get parameters
299
		String[] parameters = Arrays.copyOfRange(splits, 1, splits.length);
300
		// get parameters		
301
		return parameters;
302
	}
303
}
304