View Javadoc

1   /*
2    * Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton,
3    * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
4    *
5    * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
6    * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
7    * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
8    * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
9    * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10   * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
11   * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
12   * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
13   * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
14   * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
15   * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
16   * OR MODIFICATIONS.
17   * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
18   * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
19   * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
20   * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
21   */
22  
23  package de.desy.acop.transport.adapters;
24  
25  import java.util.Arrays;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  import com.cosylab.gui.displayers.CommonDisplayer;
30  import com.cosylab.gui.displayers.Displayer;
31  
32  import de.desy.acop.transport.AccessMode;
33  import de.desy.acop.transport.ConnectionFailed;
34  import de.desy.acop.transport.ConnectionParameters;
35  import de.desy.tine.definitions.TAccess;
36  import de.desy.tine.definitions.TArrayType;
37  import de.desy.tine.definitions.TFormat;
38  import de.desy.tine.queryUtils.TPropertyQuery;
39  import de.desy.tine.queryUtils.TQuery;
40  import de.desy.tine.types.NAME16;
41  import de.desy.tine.types.NAME32;
42  import de.desy.tine.types.NAME64;
43  import de.desy.tine.types.NAME8;
44  import de.desy.tine.types.USTRING;
45  
46  /**
47   * <code>DataSourceUtilities</code> provides common utilities for data and 
48   * connection manipulation. This class provides characteristics for a specific
49   * channel and provides methods for data conversion used by the 
50   * <code>AcopTransportDataSource</code>.
51   *  
52   * @author Jaka Bobnar, Cosylab
53   *
54   */
55  public class DataSourceUtilities {
56  	
57  	/**
58  	 * Returns the characteristics of the specified remote channel.
59  	 * 
60  	 * @param param remote channel specification
61  	 * @return map of all characteristics
62  	 * @throws ConnectionFailed if characteristics query failed
63  	 */
64  	public static Map<String, Object> getCharacteristics(ConnectionParameters param) throws ConnectionFailed {
65  		TPropertyQuery[] info=null;
66  		try {
67  	        info = TQuery.getPropertyInformation(param.getDeviceContext(),
68  	        		param.getDeviceGroup(), param.getDeviceName(), param.getDeviceProperty());
69  	        //is property a StockProperty
70  	        if (info==null) {
71  	        	info = TQuery.getStockPropertyInformation(param.getDeviceContext(),
72  	            		param.getDeviceGroup(), param.getDeviceName(), param.getDeviceProperty());
73  	        } 
74  		} catch (RuntimeException e) {
75  			throw new ConnectionFailed(param,e);
76  		}
77          
78          if (info==null) {
79          	throw new ConnectionFailed(param);
80          }
81          Map<String, Object> characteristics = new HashMap<String, Object>();
82          characteristics.put(CommonDisplayer.C_DESCRIPTION, info[0].prpDescription);
83          characteristics.put(CommonDisplayer.C_DISPLAY_NAME, param.getRemoteName());
84          if (info[0].prpMaxValue != 0 || info[0].prpMinValue != 0) {
85              characteristics.put(CommonDisplayer.C_MAXIMUM, info[0].prpMaxValue);
86              characteristics.put(CommonDisplayer.C_MINIMUM, info[0].prpMinValue);
87          }
88          characteristics.put("dataFormat", TFormat.valueOf(info[0].prpFormat));
89          characteristics.put(CommonDisplayer.C_FORMAT, getFormat(info[0].prpFormat));
90          characteristics.put(CommonDisplayer.C_UNITS, info[0].prpUnits);
91          characteristics.put(CommonDisplayer.C_SEQUENCE_LENGTH,info[0].prpSize);
92          characteristics.put("redirection",info[0].prpRedirection);
93          characteristics.put("tag",info[0].prpTag);
94          characteristics.put("rows",(int)info[0].numRows);
95          characteristics.put("rowSize",(int)info[0].rowSize);
96          characteristics.put("access",TAccess.valueOf(info[0].prpAccess));
97          characteristics.put(Displayer.C_EDITABLE,TAccess.valueOf(info[0].prpAccess).isWrite());
98          TArrayType arrayType = TArrayType.valueOf(info[0].prpArrayType);
99          
100         if (arrayType.isChannel()) {
101        		String[] names = TQuery.getDeviceNames(param.getDeviceContext(), param.getDeviceGroup(), param.getDeviceProperty());
102        		if (names != null) {
103 	       		String[] newNames = new String[names.length];
104 	       		int j = -1;
105 	       		int startPoint = -1;
106 	       		for (int i = 0; i < 2*names.length; i++) {
107 	       			if (i%names.length == startPoint) break;
108 	       			if (names[i%names.length].equals(param.getDeviceName())) {
109 	       				j = 0;
110 	       				startPoint = i;
111 	       			}
112 	       			if (j >= 0) {
113 	       				newNames[j] = names[i%names.length];
114 	       				j++;
115 	       			}
116 	       		}
117 	       		characteristics.put("xLabels",newNames);
118        		}
119        	}
120         //DOOCS sequence and names
121         if (param.getDeviceName().equals("*")) {
122         	String[] names = (String[])characteristics.get("xLabels"); 
123         	if (names == null) {
124         		names = TQuery.getDeviceNames(param.getDeviceContext(), param.getDeviceGroup(), param.getDeviceProperty());
125         		characteristics.put("xLabels", names);
126         		characteristics.put(CommonDisplayer.C_SEQUENCE_LENGTH, names.length);
127         	}
128         } 
129         
130        	//first fallback 
131        	//TODO this does not work OK - if type is a spectrum the returned names are empty strings
132 //       	if (characteristics.get("xLabels") == null) {
133 //       		AcopTransport atr = new AcopTransport();
134 //       		atr.setConnectionParameters(param);
135 //       		USTRING[] data = new USTRING[(Integer)characteristics.get(CommonDisplayer.C_SEQUENCE_LENGTH)];
136 //       		characteristics.put("xLabels", atr.getXAxisChannelNames(data));
137 //       	}
138        	//second fallback
139         String[] names = (String[])characteristics.get("xLabels");
140        	if (names == null && info[0].prpFormat != TFormat.CF_IMAGE) {
141        		try {
142            		names = TQuery.getDeviceNames(param.getDeviceContext(), param.getDeviceGroup(), param.getDeviceProperty());
143         		characteristics.put("xLabels", names);
144         		characteristics.put(CommonDisplayer.C_SEQUENCE_LENGTH, names.length);
145        		} catch (Exception e) {
146        			//ignore
147        		}
148     		if (names == null) {
149            		String[] data = new String[(Integer)characteristics.get(CommonDisplayer.C_SEQUENCE_LENGTH)];
150     			for (int i = 0; i < data.length; i++) {
151     				data[i] = String.valueOf(i);
152     			}
153     			characteristics.put("xLabels", data);
154     		}
155        	}
156        	characteristics.put("arrayType",arrayType);
157        	
158         return characteristics;
159 	}
160 	
161 	/**
162 	 * Returns the description of the remote channel.
163 	 * 
164 	 * @param param remote channel specification
165 	 * @return the description
166 	 * @throws ConnectionFailed if property information query failed
167 	 */
168 	public static String getDescription(ConnectionParameters param) throws ConnectionFailed {
169 		TPropertyQuery[] info = TQuery.getPropertyInformation(param.getDeviceContext(),
170         		param.getDeviceGroup(), param.getDeviceName(), param.getDeviceProperty());
171 		//is property a StockProperty
172         if (info==null) {
173         	info = TQuery.getStockPropertyInformation(param.getDeviceContext(),
174             		param.getDeviceGroup(), param.getDeviceName(), param.getDeviceProperty());
175         }
176         if (info==null) {
177         	throw new ConnectionFailed(param);
178         }
179         return info[0].prpDescription;
180 	}
181 	
182 	/**
183 	 * Converts TINE timestamp to UTC in millis.
184 	 * 
185 	 * @param stamp TINE timestamp
186 	 * @return UTC in milis
187 	 */
188     static long toUTC(double stamp) {
189     	return (long)(stamp*1E3);
190     }
191     
192     /**
193      * Returns the java object of the given size which corresponds to the specified
194      * TFormat.
195      * 
196      * @param format TINE format of the data
197      * @param size the size of the object
198      * @return data object
199      */
200     static Object getDataObject(TFormat format, int size) {
201     	switch (format.getValue()) {
202     		case TFormat.CF_DOUBLE :
203     			return new double[size];
204     		case TFormat.CF_INT16 :
205     			return new short[size];
206     		case TFormat.CF_BYTE :
207     			return new byte[size];
208     		case TFormat.CF_INT32:
209     			return new int[size];
210     		case TFormat.CF_FLOAT :
211     			return new float[size];
212             case TFormat.CF_INT64:
213               return new long[size];
214     		case TFormat.CF_BIT :
215     			return new boolean[size];
216     		case TFormat.CF_SPECTRUM :
217     			return new double[size];
218     		case TFormat.CF_USTRING :
219     			return new USTRING[size];
220     		case TFormat.CF_NAME64 :
221     			return new NAME64[size];
222     		case TFormat.CF_NAME32 :
223     			return new NAME32[size];
224     		case TFormat.CF_NAME16 :
225     			return new NAME16[size];
226     		case TFormat.CF_NAME8 :
227     			return new NAME8[size];
228     		default:
229     			return new double[size];
230     	}
231     }
232     
233     /**
234      * Extracts data from the <code>inData</code> which match the TINE format 
235      * <code>format</code>. Method rewrites data to the <code>data</code> parameter
236      * and returns this object. The <code>data</code> parameter should be
237      * the same size (or larger) than the <code>inData</code>.
238      * 
239      * @param format format of the incomming data
240      * @param inData incomming data
241      * @param data converted data
242      * @return converted data
243      */
244     static double[] extractData(TFormat format, Object inData, double[] data) {
245     	switch (format.getValue()) {
246     		case TFormat.CF_DOUBLE:
247     			return (double[])inData;
248     		case TFormat.CF_SHORT: {
249     			short[] d= (short[])inData;
250     			for (int i = 0; i < d.length; i++) {
251     				data[i]=d[i];
252 				}
253     			return data;
254     		}
255     		case TFormat.CF_BYTE: {
256     			byte[] d= (byte[])inData;
257     			for (int i = 0; i < d.length; i++) {
258     				data[i]=d[i];
259 				}
260     			return data;
261     		}
262             case TFormat.CF_INT32: {
263               int[] d= (int[])inData;
264               for (int i = 0; i < d.length; i++) {
265                   data[i]=d[i];
266               }
267               return data;
268           }
269     		case TFormat.CF_INT64: {
270     			long[] d= (long[])inData;
271     			for (int i = 0; i < d.length; i++) {
272     				data[i]=d[i];
273 				}
274     			return data;
275     		}
276     		case TFormat.CF_FLOAT: {
277     			float[] d= (float[])inData;
278     			for (int i = 0; i < d.length; i++) {
279     				data[i]=d[i];
280 				}
281     			return data;
282     		}
283     		case TFormat.CF_USTRING: {
284     			USTRING[] d = (USTRING[])inData;
285     			for (int i = 0; i < d.length; i++) {
286     				data[i] = d[i].f1val;
287     			}
288     			return data;
289     		}
290     		default:
291     			return (double[])inData;
292     			
293     	}
294     }
295     
296     /**
297      * Extracts data from the <code>inData</code> which match the TINE format 
298      * <code>format</code>. Method rewrites data to the <code>data</code> parameter
299      * and returns this object. The <code>data</code> parameter should be
300      * the same size (or larger) than the <code>inData</code>. This method handles
301      * String types of converted data. 
302      * 
303      * @param format format of the incomming data
304      * @param inData incomming data
305      * @param data converted data
306      * @return converted data
307      */
308     static String[] extractData(TFormat format, Object inData, String[] data) {
309     	switch (format.getValue()) {
310 	    	case TFormat.CF_USTRING: {
311 				USTRING[] d = (USTRING[])inData;
312 				for (int i = 0; i < d.length; i++) {
313 					data[i] = d[i].f1val + "," + d[i].f2val + "," + d[i].ival + "," + d[i].str.trim() + "," + d[i].tm;
314 				}
315 				return data;
316 			}	    	
317 	    	default : {
318 	    		Object[] d = (Object[])inData;
319 	    		for (int i = 0; i < d.length; i++) {
320 					data[i] = String.valueOf(d[i]);
321 				}
322 				return data;
323 	    	}
324 	    		
325     	}
326     }
327     
328     /**
329      * Transforms the double array to String array.
330      * 
331      * @param data 
332      * @return
333      */
334     static String[] toStringData(double[] data) {
335     	String[] s = new String[data.length];
336     	for (int i = 0; i < data.length; i++) {
337     		s[i] = String.valueOf(data[i]);
338     	}
339     	return s;
340     }
341     
342     /**
343      * Returns the C-type String format that match the given <code>format</code> 
344      * parameter. This parameter is the short code of the <code>TFormat</code>.
345      * @param format
346      * @return
347      */
348     private static String getFormat(short format) {
349     	switch(format) {
350 	    	case TFormat.CF_DOUBLE : return "%3.2f";
351 	    	case TFormat.CF_FLOAT : return "%3.2f";
352 	    	case TFormat.CF_LONG : return "%d";
353 	    	case TFormat.CF_SHORT : return "%d";
354 	    	default : return null;
355     	}    	
356     }
357     
358     public static void main(String[] args) throws ConnectionFailed {
359 		ConnectionParameters cp = new ConnectionParameters("TINE","TTF2","BLM1","*","CH00*", AccessMode.POLL, 500);
360 		System.out.println(Arrays.toString(TQuery.getDeviceNames("TTF2", "BLM1","CH00*")));
361 		
362 		//    	ConnectionParameters cp = new ConnectionParameters("TINE","DORIS","DORISDATA","V2 Rlf","DoArcTemp", AccessMode.POLL, 1000);
363 //		AcopTransport tp = new AcopTransport();
364 		Map<String, Object> map = DataSourceUtilities.getCharacteristics(cp);
365 		System.out.println(Arrays.toString((String[])map.get("xLabels")));
366 //		tp.setConnectionParameters(cp);
367 //		final USTRING[] data = new USTRING[40];
368 //		tp.addAcopTransportListener(new AcopTransportListener(){
369 //			public void dataEventReceived(AcopTransportEvent event) {
370 ////				System.out.println(event.getLinkError());
371 //				for (USTRING u : data) {
372 //					System.out.println(u.str.trim() + " " + u.f1val + " " + u.f2val);
373 //					
374 //				}
375 //			}
376 //		});
377 //		
378 //		tp.attachLink(data);
379 		
380 		
381 		
382 	}
383 	
384 }
385 
386 
387 /* __oOo__ */
388