Passed
Push — master ( 8df666...567b11 )
by Alessandro
15:49
created

notify(AgentTaskDescription)   A

Complexity

Conditions 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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