1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package de.desy.acop.transport.adapters;
24
25 import java.beans.Beans;
26 import java.beans.PropertyVetoException;
27 import java.util.Arrays;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import com.cosylab.gui.displayers.CommonDisplayer;
32 import com.cosylab.gui.displayers.DataConsumer;
33 import com.cosylab.gui.displayers.DataSource;
34 import com.cosylab.gui.displayers.DataSourceSupport;
35 import com.cosylab.gui.displayers.DataState;
36 import com.cosylab.gui.displayers.Displayer;
37 import com.cosylab.gui.displayers.DoubleSeqConsumer;
38 import com.cosylab.gui.displayers.StringConsumer;
39 import com.cosylab.gui.displayers.StringSeqConsumer;
40 import com.cosylab.util.ObjectList;
41
42 import de.desy.acop.transport.AcopTransport;
43 import de.desy.acop.transport.AcopTransportEvent;
44 import de.desy.acop.transport.AcopTransportListener;
45 import de.desy.acop.transport.ConnectionFailed;
46 import de.desy.acop.transport.ConnectionParameters;
47 import de.desy.tine.definitions.TArrayType;
48 import de.desy.tine.definitions.TErrorList;
49 import de.desy.tine.definitions.TFormat;
50 import de.desy.tine.queryUtils.TQuery;
51 import de.desy.tine.types.NAME16;
52 import de.desy.tine.types.NAME32;
53 import de.desy.tine.types.NAME64;
54 import de.desy.tine.types.USTRING;
55
56
57
58
59
60
61
62
63
64
65
66 public class AcopTransportDataSource extends DataSourceSupport implements AcopTransportListener {
67
68 private static final long serialVersionUID = -6371576395329401933L;
69 int useCount = 0;
70 protected ObjectList dcon= new ObjectList(DoubleSeqConsumer.class);
71 protected ObjectList scon = new ObjectList(StringConsumer.class);
72 protected ObjectList sseqcon = new ObjectList(StringSeqConsumer.class);
73 private AcopTransport transport;
74 private int id=-1;
75 protected double[] data;
76 protected String[] objectData;
77 private Object inData;
78 private long timestamp;
79 private Map<String,Object> characteristics;
80 private ConnectionParameters param;
81 private ReverseConsumer reverseConsumer;
82 private TFormat dataFormat;
83 private int errorId=-1;
84 private DataState dataState = new DataState(DataState.UNDEFINED);
85
86
87
88
89 @SuppressWarnings("unchecked")
90 public AcopTransportDataSource() {
91 super(new Class[]{DoubleSeqConsumer.class});
92 transport= new AcopTransport();
93 transport.addAcopTransportListener(this);
94 }
95
96
97
98
99 @Override
100 public void addConsumer(DataConsumer consumer) throws PropertyVetoException {
101 DataConsumer dc = consumer.getDefaultDataConsumer();
102
103 if (dc instanceof StringConsumer) {
104 scon.add(dc);
105 super.addConsumer(consumer);
106
107 } else if (dc instanceof StringSeqConsumer) {
108 sseqcon.add(dc);
109 super.addConsumer(consumer);
110
111 } else {
112 dc = consumer.getDataConsumer(DoubleSeqConsumer.class);
113
114 if (dc==null) {
115 return;
116 }
117 dcon.add(dc);
118 super.addConsumer(consumer);
119
120 }
121
122
123 try {
124 Map<String, Object> ch = null;
125
126 if (!Beans.isDesignTime()) {
127 ch= getCharacteristics();
128 } else if (param != null){
129 ch = new HashMap<String, Object>();
130 ch.put(CommonDisplayer.C_DISPLAY_NAME,param.getRemoteName());
131 }
132 if (ch!=null) {
133 consumer.setCharacteristics(ch);
134 }
135 } catch (ConnectionFailed e) {
136 e.printStackTrace();
137 }
138
139 if (consumer instanceof DataSource) {
140 if (dataFormat.getValue() != TFormat.CF_USTRING &&
141 dataFormat.getValue() != TFormat.CF_NAME8 &&
142 dataFormat.getValue() != TFormat.CF_NAME16 &&
143 dataFormat.getValue() != TFormat.CF_NAME32 &&
144 dataFormat.getValue() != TFormat.CF_NAME64) {
145 ((DataSource)consumer).addConsumer(getReverseConsumer());
146 } else {
147 Map<String, Object> ch = new HashMap<String, Object>();
148 ch.put(Displayer.C_EDITABLE, false);
149 consumer.setCharacteristics(ch);
150 }
151 }
152
153 consumer.updateDataState(dataState);
154 }
155
156
157
158
159
160
161
162
163
164
165 public Map<String,Object> getCharacteristics() throws ConnectionFailed {
166 if (characteristics == null && param!=null) {
167 characteristics = DataSourceUtilities.getCharacteristics(param);
168 }
169 return characteristics;
170 }
171
172
173
174
175
176
177 public AcopTransport getTransport() {
178 return transport;
179 }
180
181
182
183
184
185
186 public ConnectionParameters getConnectionParameters() {
187 return param;
188 }
189
190
191
192
193
194
195
196 public void connect(ConnectionParameters conn) throws ConnectionFailed {
197 param=conn;
198
199 transport.setConnectionParameters(conn);
200 int size = conn.getPropertySize();
201
202 if ((size == ConnectionParameters.ACTUAL_PROPERTY_SIZE ||
203 size == ConnectionParameters.AUTO_PROPERTY_SIZE) &&
204 (Integer)getCharacteristics().get(CommonDisplayer.C_SEQUENCE_LENGTH) > 1 &&
205 !((TArrayType)getCharacteristics().get("arrayType")).isChannel()) {
206 size = (Integer)getCharacteristics().get(CommonDisplayer.C_SEQUENCE_LENGTH);
207 }
208 if (size == ConnectionParameters.ACTUAL_PROPERTY_SIZE ||
209 size == ConnectionParameters.AUTO_PROPERTY_SIZE) {
210 if (!param.getDeviceName().contains("*")) {
211 size= (Integer)getCharacteristics().get(CommonDisplayer.C_SEQUENCE_LENGTH);
212 } else {
213 String[] names = TQuery.getDeviceNames(conn.getDeviceContext(), conn.getDeviceGroup());
214 size = names.length;
215 }
216 }
217 if (param.getDeviceProperty().contains("*")) {
218 dataFormat = TFormat.valueOf(TFormat.CF_USTRING);
219 } else {
220 dataFormat = (TFormat)getCharacteristics().get("dataFormat");
221 }
222 inData= DataSourceUtilities.getDataObject(dataFormat,size);
223
224 if (inData instanceof double[]) {
225 data= (double[])inData;
226 } else if (inData instanceof USTRING[] || inData instanceof NAME64[] ||
227 inData instanceof NAME32[] || inData instanceof NAME16[]) {
228 objectData= new String[size];
229 } else {
230 data= new double[size];
231 }
232
233 if (!Beans.isDesignTime()) {
234 id = transport.attachLink(inData, conn.getDynamicParameters());
235 if (id < 0) {
236 updateDataState(new DataState(DataState.ERROR));
237 }
238 }
239 updateCharacteristics();
240 }
241
242
243
244
245
246 public void disconnect() {
247 if (!Beans.isDesignTime()) {
248 transport.closeLink(id);
249 clear();
250 if (getReverseConsumer() != null)
251 getReverseConsumer().release();
252 reverseConsumer=null;
253 }
254 clear();
255 }
256
257
258
259
260
261 public void dataEventReceived(AcopTransportEvent e)
262 {
263 int id = e.getLinkId();
264 if (id != this.id)
265 return;
266 int error = e.getLinkError();
267 timestamp = DataSourceUtilities.toUTC(transport.getDataTimeStamp());
268
269 if (error!=errorId) {
270 errorId=error;
271
272 if (error==0) {
273 dataState= new DataState(DataState.NORMAL,timestamp,TErrorList.toString(error));
274 } else {
275 dataState= new DataState(DataState.ERROR,timestamp,TErrorList.toString(error));
276 }
277 updateDataState(dataState);
278
279 }
280
281 updateConsumers();
282 }
283
284 private void updateConsumers() {
285
286 if (dataFormat.getValue() == TFormat.CF_USTRING ||
287 dataFormat.getValue() == TFormat.CF_NAME8 ||
288 dataFormat.getValue() == TFormat.CF_NAME16 ||
289 dataFormat.getValue() == TFormat.CF_NAME32 ||
290 dataFormat.getValue() == TFormat.CF_NAME64) {
291 objectData = DataSourceUtilities.extractData(dataFormat,inData,objectData);
292 StringConsumer[] sc= (StringConsumer[])scon.toArray();
293
294 String data = "";
295 if (objectData != null) {
296 if (objectData.length == 1) {
297 data = objectData[0];
298 } else if (objectData.length > 1) {
299 data = Arrays.toString(objectData);
300 }
301 }
302
303 for (int i = 0; i < sc.length; i++) {
304 try {
305 sc[i].updateValue(timestamp,data);
306 } catch (Exception e) {
307 e.printStackTrace();
308 }
309 }
310
311 StringSeqConsumer[] ssc= (StringSeqConsumer[])sseqcon.toArray();
312 for (int i = 0; i < ssc.length; i++) {
313 try {
314 ssc[i].updateValue(timestamp,objectData);
315 } catch (Exception e) {
316 e.printStackTrace();
317 }
318 }
319 } else {
320 data= DataSourceUtilities.extractData(dataFormat,inData,data);
321 DoubleSeqConsumer[] dsc= (DoubleSeqConsumer[])dcon.toArray();
322 for (int i = 0; i < dsc.length; i++) {
323 try {
324 dsc[i].updateValue(timestamp,data);
325 } catch (Exception e) {
326 e.printStackTrace();
327 }
328 }
329 StringConsumer[] sc= (StringConsumer[])scon.toArray();
330 for (int i = 0; i < sc.length; i++) {
331 try {
332 sc[i].updateValue(timestamp,Arrays.toString(data));
333 } catch (Exception e) {
334 e.printStackTrace();
335 }
336 }
337
338 StringSeqConsumer[] ssc= (StringSeqConsumer[])sseqcon.toArray();
339 for (int i = 0; i < ssc.length; i++) {
340 try {
341 ssc[i].updateValue(timestamp,DataSourceUtilities.toStringData(data));
342 } catch (Exception e) {
343 e.printStackTrace();
344 }
345 }
346 }
347
348 }
349
350 private void updateCharacteristics() {
351 try {
352 Map ch= getCharacteristics();
353 DataConsumer[] dsc= (DataConsumer[])dcon.toArray();
354 for (int i = 0; i < dsc.length; i++) {
355 try {
356 dsc[i].setCharacteristics(ch);
357 } catch (Exception e) {
358 e.printStackTrace();
359 }
360 }
361 } catch (ConnectionFailed e) {
362 e.printStackTrace();
363 }
364 }
365
366
367
368
369
370
371
372 protected ReverseConsumer getReverseConsumer() {
373 if (reverseConsumer == null) {
374 if (data != null)
375 reverseConsumer = new ReverseConsumer(param,transport,data.length);
376 }
377
378 return reverseConsumer;
379 }
380
381
382
383
384 @Override
385 public void clear() {
386 DataConsumer[] cc= getConsumers();
387 for (DataConsumer c:cc) {
388 if (c instanceof DataSource) {
389 ((DataSource)c).removeConsumer(getReverseConsumer());
390 }
391 }
392 super.clear();
393 }
394
395
396
397
398
399
400 protected TFormat getDataFormat() {
401 return dataFormat;
402 }
403
404
405
406
407
408
409 protected void setDataFormat(TFormat format) {
410 this.dataFormat = format;
411 }
412
413
414
415
416
417
418 private void updateDataState(DataState state) {
419 DataConsumer[] delegates = getConsumers();
420
421 for (int i = 0; i < delegates.length; i++) {
422 try {
423 delegates[i].updateDataState(state);
424 } catch (Exception e) {
425 e.printStackTrace();
426 }
427 }
428 }
429
430
431
432
433 public void removeConsumer(DataConsumer consumer) {
434 super.removeConsumer(consumer);
435 dcon.remove(consumer);
436 scon.remove(consumer);
437 sseqcon.remove(consumer);
438 if (consumer instanceof DataSource &&
439 (dataFormat.getValue() != TFormat.CF_USTRING ||
440 dataFormat.getValue() != TFormat.CF_NAME8 ||
441 dataFormat.getValue() != TFormat.CF_NAME16 ||
442 dataFormat.getValue() != TFormat.CF_NAME32 ||
443 dataFormat.getValue() != TFormat.CF_NAME64)) {
444 ((DataSource)consumer).removeConsumer(getReverseConsumer());
445 }
446
447 }
448
449
450
451
452
453
454 protected int getDataLength() {
455 return data.length;
456 }
457
458 }