Passed
Push — master ( cc7f70...c0fb06 )
by Alessandro
06:52
created

create(String,String[],ExecutionNode)   A

Complexity

Conditions 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
dl 0
loc 12
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
	 * @param cmdId
87
	 * @return
88
	 */
89
	public synchronized PlatformCommand getDispatchedCommand(long cmdId) {
90
		// get command from cache
91
		return this.dispatchedIndex.get(cmdId);
92
	}
93
	
94
	/**
95
	 * 
96
	 * This method sends a request to the real/simulated platform to execute a command.
97
	 * 
98
	 * This method is usually meant for partially controllable commands. The platform/environment is 
99
	 * in charge of the execution of the related command and therefore it will then notify the 
100
	 * acting agent about the successful execution or failures.
101
	 * 
102
	 * Feedbacks about the execution of the command will be then received through the PlatformObserver 
103
	 * interface
104
	 * 
105
	 * @param node
106
	 * @return
107
	 * @throws PlatformException
108
	 */
109
	public abstract PlatformCommand executeNode(ExecutionNode node) 
110
			throws PlatformException;
111
	
112
	/**
113
	 * 
114
	 * This method sends a request to the real/simulated platform to start the execution of a command.
115
	 * 
116
	 * This method is usually meant for controllable commands. The acting agent is in charge of 
117
	 * deciding when to start the execution of a command.
118
	 * 
119
	 * @param node
120
	 * @return
121
	 * @throws PlatformException
122
	 */
123
	public abstract PlatformCommand startNode(ExecutionNode node) 
124
			throws PlatformException;
125
	
126
127
	/**
128
	 * 
129
	 * This method sends a request to the real/simulated platform to stop the execution of a command
130
	 * 
131
	 * This method is usually meant for controllable commands. The acting agent is in charge of 
132
	 * deciding when to stop the execution of a previously started command.  
133
	 * 
134
	 * @param cmd
135
	 * @throws PlatformException
136
	 */
137
	public abstract void stopNode(ExecutionNode node) 
138
			throws PlatformException;
139
	
140
	/**
141
	 * This method check whether an execution node represents a platform command or not. 
142
	 * 
143
	 *  Namely, the method checks if a particular token of a plan actually represents a 
144
	 *  command to be executed on some platform. 
145
	 *  
146
	 *  Clearly, the implementation of this method strongly depends on the functional layer 
147
	 *  provided by the hardware or software platform considered for the execution of 
148
	 *  timeline-based plan.
149
	 * 
150
	 * @param node
151
	 * @return
152
	 */
153
	public abstract boolean isPlatformCommand(ExecutionNode node);
154
	
155
	
156
	/**
157
	 * 
158
	 * @param observation
159
	 */
160
	public void notify(PlatformObservation<? extends Object> observation) 
161
	{
162
		// get platform observers
163
		synchronized (observers) {
164
			// notify observers
165
			for (PlatformObserver observer : observers) {
166
				// notify observation to platform observer
167
				observer.observation(observation);
168
			}
169
		}
170
	}
171
	
172
	/**
173
	 * 
174
	 * @param feedback
175
	 */
176
	public void notify(PlatformFeedback feedback) 
177
	{
178
		// get platform observers
179
		synchronized (observers) {
180
			// notify observers
181
			for (PlatformObserver observer : observers) {
182
				// notify observation to platform observer
183
				observer.feedback(feedback);
184
				
185
			}
186
		}
187
	}
188
		
189
	/**
190
	 * 
191
	 * @param msg
192
	 */
193
	public void notify(AgentTaskDescription msg) {
194
		
195
		// get platform observers
196
		synchronized (observers) {
197
			// notify observers
198
			for (PlatformObserver observer : observers) {
199
				// notify task to platform observers
200
				observer.task(msg);
201
			}
202
		}
203
	}
204
	
205
	/**
206
	 * 
207
	 * @param name
208
	 * @param params
209
	 * @return
210
	 */
211
	public PlatformCommand create(String name, String[] params, ExecutionNode node) {
212
		
213
		// create platform command
214
		PlatformCommand cmd = new PlatformCommand(
215
				cmdIdCounter.getAndIncrement(), 
216
				name, 
217
				params, 
218
				node, 
219
				0);				// command type 0 = start execution request
220
		
221
		// return created command
222
		return cmd;
223
	}
224
	
225
	/**
226
	 * 
227
	 * @param cmd
228
	 */
229
	public void success(PlatformCommand cmd) {
230
		
231
		// create positive feedback
232
		PlatformFeedback feedback = new PlatformFeedback(
233
				obsIdCounter.getAndIncrement(), 
234
				cmd, 
235
				PlatformFeedbackType.SUCCESS);
236
		
237
		// notify feedback
238
		this.notify(feedback);
239
	}
240
	
241
	/**
242
	 * 
243
	 * @param cmd
244
	 */
245
	public void failure(PlatformCommand cmd) {
246
247
		// create negative feedback
248
		PlatformFeedback feedback = new PlatformFeedback(
249
				obsIdCounter.getAndIncrement(), 
250
				cmd, 
251
				PlatformFeedbackType.FAILURE);
252
		
253
		// notify feedback
254
		this.notify(feedback);
255
	}
256
	
257
	
258
	/**
259
	 * 
260
	 * @param node
261
	 * @return
262
	 */
263
	public static String extractCommandName(ExecutionNode node) 
264
	{ 
265
		// get signature
266
		String name = node.getGroundSignature();
267
		// "clear" command name from "control tags"
268
		if (name.startsWith("_")) {
269
			// remove partial controllability tag
270
			name = name.replaceFirst("_", "");
271
		}
272
		
273
		// discard parameters if any 
274
		String[] splits = name.split("-");
275
		// set the first element as command name
276
		name = splits[0];
277
		
278
		// get cleared command name 
279
		return name.toLowerCase();
280
	}
281
	
282
	
283
	/**
284
	 * 
285
	 * @param node
286
	 * @return
287
	 */
288
	public static String[] extractCommandParameters(ExecutionNode node) {
289
		// extract command parameter from node to execute
290
		String[] splits = node.getGroundSignature().split("-");
291
		// get parameters
292
		String[] parameters = Arrays.copyOfRange(splits, 1, splits.length);
293
		// get parameters		
294
		return parameters;
295
	}
296
}
297