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;
24  
25  import java.beans.PropertyChangeListener;
26  import java.beans.PropertyChangeSupport;
27  import java.util.Date;
28  import java.util.Vector;
29  import javax.swing.event.EventListenerList;
30  import de.desy.acop.chart.Acop;
31  import de.desy.acop.displayers.tools.ConnectionParametersReceiver;
32  
33  public class AcopTransport implements ConnectionParametersReceiver
34  {
35    private ConnectionParameters connectionParameters = null;
36    public String getConnectionInformation(String deviceContext,String deviceGroup,String deviceName, String deviceProperty)
37    {
38      AcopTransportPlug atp;
39      if ((atp = atf.getProtocol(connectionParameters.getAccessProtocol())) == null)
40      {
41        Status = "Protocol not available";
42        return null;
43      }
44      return atp.getTargetInformation(deviceContext,deviceGroup,deviceName,deviceProperty);
45    }
46    public String getConnectionInformation(int hLink)
47    {
48      if (hLink >= 0)
49      {
50        AcopTransportRequest a;
51        for (int i=0; i<acopLinkTable.size(); i++)
52        {
53          a = (AcopTransportRequest)acopLinkTable.elementAt(i);
54          if (a.getLinkIdentifier() == hLink)
55          {
56            return a.getDeviceInfo();
57          }
58        }
59      }
60      return null;
61    }
62    protected String acopConfig, Status;
63    /**
64     * @brief The grouped flag
65     * @return the isGrouped state of this transport
66     */
67    public boolean isGrouped;
68    protected int GroupIndex, ReceiveQueueDepth;
69    public int getReceiveQueueDepth()
70    {
71      return ReceiveQueueDepth;
72    }
73    protected double TimeStamp;
74    public double getDataTimeStamp()
75    {
76      return TimeStamp;
77    }
78    public double getDataTimeStamp(int hLink) 
79    { 
80      return ((double)(getDateStamp(hLink)).getTime()/1000);
81    }
82    protected Date dateStamp;
83    public Date getDateStamp()
84    {
85      return dateStamp;
86    }
87    public Date getDateStamp(int hLink) 
88    { 
89      if (hLink >= 0)
90      {
91        AcopTransportRequest a;
92        for (int i=0; i<acopLinkTable.size(); i++)
93        {
94          a = (AcopTransportRequest)acopLinkTable.elementAt(i);
95          if (a.getLinkIdentifier() == hLink)
96          {
97            return a.getDataTimeStamp();
98          }
99        }
100     }
101     return dateStamp;
102   }
103   // private Acop parentAcop;
104   protected AcopTransportFactory atf;
105   // protected AcopTransportRequest atr = new AcopTransportRequest();
106   protected final Vector acopLinkTable = new Vector();
107   public Vector getAcopLinkTable()
108   {
109     return acopLinkTable;
110   }
111   protected int lastUpdatedLink = -1, lastUpdatedDataSize = 0, lastUpdatedDataSizeEx = 0;
112   protected EventListenerList listeners = new EventListenerList();
113   public class AcopCallback implements AcopTransportCallback
114   {
115     public void callback(int linkHandle, int statusCode)
116     {
117       int linkTableId, identifier, i;
118       AcopTransportRequest a;
119       if ((linkTableId = getAcopLinkTableIdFromCallbackId(linkHandle)) < 0)
120       {
121         System.out.println("Link " + linkHandle + " not allocated");
122         return;
123       }
124       if ((a = (AcopTransportRequest) acopLinkTable.elementAt(linkTableId)) == null)
125       {
126         System.out.println("Link " + linkHandle + " no entry in link table!");
127         return;
128       }
129       boolean pending = false;
130       getData(a.getData(), a.getDataEx(), a.getLinkIdentifier());
131       identifier = a.getLinkIdentifier();
132       if (isGrouped)
133       {
134         for (i = 0; i < acopLinkTable.size(); i++)
135         {
136           if (i == linkTableId) ((AcopTransportRequest) acopLinkTable.elementAt(i)).pending = false;
137           if (((AcopTransportRequest) acopLinkTable.elementAt(i)).pending) pending = true;
138         }
139         if (pending) return;
140       }
141       else
142       {
143         a.pending = false;
144       }
145       fireAcopTransportEvent(identifier, statusCode);
146       if (isGrouped)
147       {
148         for (i = 0; i < acopLinkTable.size(); i++)
149           ((AcopTransportRequest) acopLinkTable.elementAt(i)).pending = true;
150       }
151       else
152       {
153         a.pending = true;
154       }
155       // TODO check this out (does it work ?)
156       if (a.accessMode.isReadMode() || a.accessMode.isWriteMode())
157       {
158        // closeLink(a.getLinkHandle());
159       }
160     }
161     private void fireAcopTransportEvent(int identifier, int statusCode)
162     {
163       AcopTransportEvent ev = new AcopTransportEvent(AcopTransport.this, identifier, statusCode);
164       AcopTransportListener[] l = (AcopTransportListener[]) listeners.getListeners(AcopTransportListener.class);
165       for (int i = 0; i < l.length; i++)
166       {
167         try
168         {
169           l[i].dataEventReceived(ev);
170         }
171         catch (Exception e)
172         {
173           e.printStackTrace();
174         }
175       }
176     }
177   }
178   protected AcopTransportCallback atc = new AcopCallback();
179   public int addAcopTransportProtocol(AcopTransportPlug plug)
180   {
181     return atf.addProtocol(plug);
182   }
183   public AcopTransport()
184   {
185     // {{INIT_CONTROLS
186     // parentAcop = acop;
187     acopConfig = "STANDARD";
188     Status = "";
189     ReceiveQueueDepth = 100;
190     TimeStamp = 0;
191     isGrouped = false;
192     GroupIndex = 0;
193     atf = AcopTransportFactory.getInstance();
194     // }}
195   }
196   // {{DECLARE_CONTROLS
197   protected AcopTransportRequest getAcopTransportRequest(AcopTransportRequest atr)
198   {
199     AcopTransportRequest a;
200     for (int i = 0; i < acopLinkTable.size(); i++)
201     {
202       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
203       if (a.compareTo(atr)) return a;
204     }
205     a = atr.cloneTransportRequest();
206     acopLinkTable.addElement(a);
207     return a;
208   }
209   protected AcopTransportRequest getAcopTransportRequest(int hLink)
210   { 
211     AcopTransportRequest atr;
212     if (hLink >= 0)
213     { // TODO: maybe use a hash map? or maybe not (never more than a few links in the table) 
214       for (int i = 0; i < acopLinkTable.size(); i++)
215       {
216         atr = (AcopTransportRequest) acopLinkTable.elementAt(i);
217         if (atr.getLinkIdentifier() == hLink)
218         {
219           return atr;
220         }
221       }
222     }
223     return null;
224   }
225   public int getAcopLinkTableId(AcopTransportRequest atr)
226   {
227     AcopTransportRequest a;
228     for (int i = 0; i < acopLinkTable.size(); i++)
229     {
230       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
231       if (a.compareTo(atr))
232       {
233         //TODO update the inputdata set here ?
234         return i;
235       }
236     }
237     return -1;
238   }
239   public int getAcopLinkTableId(int hLink)
240   {
241     AcopTransportRequest a;
242     for (int i = 0; i < acopLinkTable.size(); i++)
243     {
244       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
245       if (a.getLinkIdentifier() == hLink) return i;
246     }
247     return -1;
248   }
249   public int getAcopLinkTableIdFromCallbackId(int hLinkCallback)
250   {
251     AcopTransportRequest a;
252     for (int i = 0; i < acopLinkTable.size(); i++)
253     {
254       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
255       if (a.getLinkHandle() == hLinkCallback) return i;
256     }
257     return -1;
258   }
259   protected int getFreeIdentifier()
260   {
261     AcopTransportRequest a;
262     int identifier = 0;
263     for (int i = 0; i < acopLinkTable.size(); i++)
264     {
265       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
266       if (a.getLinkIdentifier() == identifier) identifier++;
267     }
268     return identifier;
269   }
270   public void halt()
271   {
272     atf.halt();
273   }
274   /**
275    * @brief Establishes and executes a synchronous data link using the Device
276    *        Properties assigned to the control. Use Execute for synchronous data
277    *        acquisition. Fill in the DeviceContext DeviceGroup, DeviceName, and
278    *        DeviceProperty bean property parameters, along with the
279    *        accessProtocol, accessMode, and accessRate bean property parameters.
280    *        This method blocks until either the transfer is complete or a
281    *        timeout has occurred (given by the accessRate setting). Asynchronous
282    *        READ and WRITE calls can be effected by using the AttachLink()
283    *        method and handling the results inside the corresponding receive
284    *        event.
285    * @param Data
286    *          is the primary data object and refers to the data object to hold
287    *          the output data returned from a server. Pass 'null' if no return
288    *          data is desired.
289    * @param ArraySize
290    *          is the data array size associated with the Data object. This may
291    *          be smaller than the actual size of the Data object, but NOT
292    *          bigger.
293    * @param DataEx
294    *          is the extended data object and refers to the data object to which
295    *          holds the input data to be sent to a server. Pass 'null' if no
296    *          return data is desired.
297    * @param ArraySizeEx
298    *          is the data array size associated with the DataEx object. This may
299    *          be smaller than the actual size of the DataEx object, but NOT
300    *          bigger.
301    * @return 0 if successful otherwise a positive return code or -1, in which case
302    *         the getStatus() method can be queried to determine the cause of
303    *         failure.
304    * @note The Data and DataEx objects above must refer to arrays of data types
305    *       (which are passed by reference) and not single values (which are
306    *       passed by value). So even if passing a single value, it must be
307    *       declared as an array of 1 element!
308    * @note The only allowed values of 'accessMode' are "READ" and "WRITE" when
309    *       using the Execute() method. \b Example: \include eg_acopExecute1.java
310    */
311   public int execute(Object Data, int ArraySize, Object DataEx, int ArraySizeEx)
312   {
313     if (getObjectSize(Data) < ArraySize || getObjectSize(DataEx) < ArraySizeEx)
314     {
315       Status = "Data object smaller than size given";
316       return -1;
317     }
318     AcopTransportRequest atr = new AcopTransportRequest();
319     AcopTransportPlug atp;
320     atr.accessMethod = AcopTransportAccessMethods.EXECUTE;
321     atr.setFromParameters(connectionParameters);
322     atr.setData(Data);
323     atr.setArraySize(ArraySize);
324     atr.setDataEx(DataEx);
325     atr.setArraySizeEx(ArraySizeEx);
326     atr.isUnboundToData = false;
327     if ((atp = atf.getProtocol(connectionParameters.getAccessProtocol())) == null)
328     {
329       Status = "Protocol not available";
330       return -1;
331     }
332     int rc = atp.handleRequest(atr);
333     lastUpdatedDataSize = atr.getDataSize();
334     lastUpdatedDataSizeEx = atr.getDataSizeEx();
335     setTimeStamp(atr.getDataTimeStamp());
336     Status = atr.status;
337     return rc;
338   }
339   /**
340    * @brief Establishes and executes a synchronous data link using the Device
341    *        Properties assigned to the control. Use Execute for synchronous data
342    *        acquisition. Fill in the DeviceContext DeviceGroup, DeviceName, and
343    *        DeviceProperty bean property parameters, along with the
344    *        accessProtocol, accessMode, and accessRate bean property parameters.
345    *        This method blocks until either the transfer is complete or a
346    *        timeout has occurred (given by the accessRate setting). Asynchronous
347    *        READ and WRITE calls can be effected by using the AttachLink()
348    *        method and handling the results inside the corresponding receive
349    *        event.
350    * @param Data
351    *          is the primary data object and refers to the data object to hold
352    *          the output data returned from a server. Pass 'null' if no return
353    *          data is desired.
354    * @param DataEx
355    *          is the extended data object and refers to the data object to which
356    *          holds the input data to be sent to a server. Pass 'null' if no
357    *          return data is desired.
358    * @return 0 if successful otherwise a positive return code or -1, in which case
359    *         the getStatus() method can be queried to determine the cause of
360    *         failure.
361    * @note The Data and DataEx objects above must refer to arrays of data types
362    *       (which are passed by reference) and not single values (which are
363    *       passed by value). So even if passing a single value, it must be
364    *       declared as an array of 1 element! The sizes of the arrays are in
365    *       turn used in establishing the link when using this form of the
366    *       Execute() method.
367    * @note The only allowed values of 'accessMode' are "READ" and "WRITE" when
368    *       using the Execute() method. \b Example: \include
369    *       eg_acopExecute1b.java
370    */
371   public int execute(Object Data, Object DataEx)
372   {
373     return execute(Data, getObjectSize(Data), DataEx, getObjectSize(DataEx));
374   }
375   /**
376    * @brief Establishes and executes a synchronous data link using the Device
377    *        Properties assigned to the control. Use Execute for synchronous data
378    *        acquisition. Fill in the DeviceContext DeviceGroup, DeviceName, and
379    *        DeviceProperty bean property parameters, along with the
380    *        accessProtocol, accessMode, and accessRate bean property parameters.
381    *        This method blocks until either the transfer is complete or a
382    *        timeout has occurred (given by the accessRate setting). Asynchronous
383    *        READ and WRITE calls can be effected by using the AttachLink()
384    *        method and handling the results inside the corresponding receive
385    *        event.
386    * @param Data
387    *          is the primary data object and refers to the data object to hold
388    *          the output data returned from a server. Pass 'null' if no return
389    *          data is desired.
390    * @return 0 if successful otherwise a positive return code or -1, in which case
391    *         the getStatus() method can be queried to determine the cause of
392    *         failure.
393    * @note The Data object above must refer to an array of data types (which is
394    *       passed by reference) and not a single value (which is passed by
395    *       value). So even if passing a single value, it must be declared as an
396    *       array of 1 element! The size of the array is in turn used in
397    *       establishing the link when using this form of the Execute() method.
398    * @note The only allowed values of 'accessMode' are "READ" and "WRITE" when
399    *       using the Execute() method. \b Example: \include
400    *       eg_acopExecute1c.java
401    */
402   public int execute(Object Data)
403   {
404     return execute(Data, getObjectSize(Data), null, 0);
405   }
406   /**
407    * @brief Establishes and executes a synchronous data link using the Device
408    *        Properties assigned to the control. Use Execute for synchronous data
409    *        acquisition. Fill in the DeviceContext DeviceGroup, DeviceName, and
410    *        DeviceProperty bean property parameters, along with the
411    *        accessProtocol, accessMode, and accessRate bean property parameters.
412    *        This method blocks until either the transfer is complete or a
413    *        timeout has occurred (given by the accessRate setting). Asynchronous
414    *        READ and WRITE calls can be effected by using the AttachLink()
415    *        method and handling the results inside the corresponding receive
416    *        event.
417    * @param Data
418    *          is the primary data object and refers to the data object to hold
419    *          the output data returned from a server. Pass 'null' if no return
420    *          data is desired.
421    * @param ArraySize
422    *          is the data array size associated with the Data object. This may
423    *          be smaller than the actual size of the Data object, but NOT
424    *          bigger.
425    * @return 0 if successful otherwise a positive return code or -1, in which case
426    *         the getStatus() method can be queried to determine the cause of
427    *         failure.
428    * @note The Data object above must refer to an array of data types (which is
429    *       passed by reference) and not a single value (which is passed by
430    *       value). So even if passing a single value, it must be declared as an
431    *       array of 1 element!
432    * @note The only allowed values of 'accessMode' are "READ" and "WRITE" when
433    *       using the Execute() method. \b Example: \include
434    *       eg_acopExecute1d.java
435    */
436   public int execute(Object Data, int ArraySize)
437   {
438     return execute(Data, ArraySize, null, 0);
439   }
440   // TODO: the only difference between AttachLink() and OpenLink() seems to be
441   // atr.isUnboundToData
442   // Execute() is also of the same ilk. Maybe put the meat into one method only?
443   /**
444    * @brief Establishes an asynchronous data link using the Device Properties
445    *        assigned to the control and Attaches the data objects passed. Use
446    *        AttachLink for asynchronous data acquisition. Fill in the
447    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
448    *        property parameters, along with the accessProtocol, accessMode, and
449    *        accessRate bean property parameters. Call this method to establish
450    *        the asynchronous data transfer link and attach the returning data to
451    *        the Data object passed. When new data arrive or the link status has
452    *        changed, the chart receive event will be fired.
453    * @param Data
454    *          is the primary data object and refers to the data object to hold
455    *          the output data returned from a server. Pass 'null' if no return
456    *          data is desired.
457    * @param ArraySize
458    *          is the data array size associated with the Data object. This may
459    *          be smaller than the actual size of the Data object, but NOT
460    *          bigger.
461    * @param DataEx
462    *          is the extended data object and refers to the data object to which
463    *          holds the input data to be sent to a server. Pass 'null' if no
464    *          return data is desired.
465    * @param ArraySizeEx
466    *          is the data array size associated with the DataEx object. This may
467    *          be smaller than the actual size of the DataEx object, but NOT
468    *          bigger.
469    * @param identifier
470    *          is a user-specified integer identifier which is used to identify
471    *          the link to the calling application. Following a receive() event,
472    *          the application can call getLinkId() to retrieve this number.
473    *          Other forms of AttachLink() will use the returned link handle as
474    *          and identifier.
475    * @return A positive link handle if successful otherwise -1, in which case
476    *         the getStatus() method can be queried to determine the cause of
477    *         failure.
478    * @note The Data and DataEx objects above must refer to arrays of data types
479    *       (which are passed by reference) and not single values (which are
480    *       passed by value). So even if passing a single value, it must be
481    *       declared as an array of 1 element! \b Example: \include
482    *       eg_acopAttach1f.java
483    */
484   public int attachLink(Object Data, int ArraySize, Object DataEx, int ArraySizeEx, int identifier)
485   {
486     if (getObjectSize(Data) < ArraySize || getObjectSize(DataEx) < ArraySizeEx)
487     {
488       Status = "Data object smaller than size given";
489       return -1;
490     }
491     AcopTransportRequest atr = new AcopTransportRequest();
492     AcopTransportPlug atp;
493     atr.accessMethod = AcopTransportAccessMethods.ATTACH;
494     atr.setFromParameters(connectionParameters);
495     atr.setData(Data);
496     atr.setArraySize(ArraySize);
497     atr.setDataEx(DataEx);
498     atr.setArraySizeEx(ArraySizeEx);
499     atr.atc = atc;
500     atr.isUnboundToData = false;
501     if (atr.accessMode == null)
502     {
503       Status = "access mode not set";
504       return -1;      
505     }
506     if ((atp = atf.getProtocol(connectionParameters.getAccessProtocol())) == null)
507     {
508       Status = "Protocol not available";
509       return -1;
510     }
511     boolean isSingleLink = (atr.accessMode.isReadMode() || atr.accessMode.isWriteMode());
512     if (!isSingleLink && getAcopLinkTableId(atr) >= 0) return atr.getLinkIdentifier();
513     if (atp.handleRequest(atr) < 0)
514     {
515       Status = atr.status;
516       return -1;
517     }
518     if (identifier == -1) identifier = getFreeIdentifier();
519     atr.setLinkIdentifier(identifier);
520     // getAcopTransportRequest(atr);
521     atr = getAcopTransportRequest(atr);
522     atr.pending = true;
523     Status = atr.status;
524     // AcopLinkTableId(atr.getLinkIdentifier());
525     return identifier;
526   }
527   /**
528    * @brief Establishes an asynchronous data link using the Device Properties
529    *        assigned to the control and Attaches the data objects passed. Use
530    *        AttachLink for asynchronous data acquisition. Fill in the
531    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
532    *        property parameters, along with the accessProtocol, accessMode, and
533    *        accessRate bean property parameters. Call this method to establish
534    *        the asynchronous data transfer link and attach the returning data to
535    *        the Data object passed. When new data arrive or the link status has
536    *        changed, the chart receive event will be fired.
537    * @param Data
538    *          is the primary data object and refers to the data object to hold
539    *          the output data returned from a server. Pass 'null' if no return
540    *          data is desired.
541    * @param ArraySize
542    *          is the data array size associated with the Data object. This may
543    *          be smaller than the actual size of the Data object, but NOT
544    *          bigger.
545    * @param DataEx
546    *          is the extended data object and refers to the data object to which
547    *          holds the input data to be sent to a server. Pass 'null' if no
548    *          return data is desired.
549    * @param ArraySizeEx
550    *          is the data array size associated with the DataEx object. This may
551    *          be smaller than the actual size of the DataEx object, but NOT
552    *          bigger.
553    * @return A positive link handle if successful otherwise -1, in which case
554    *         the getStatus() method can be queried to determine the cause of
555    *         failure.
556    * @note The Data and DataEx objects above must refer to arrays of data types
557    *       (which are passed by reference) and not single values (which are
558    *       passed by value). So even if passing a single value, it must be
559    *       declared as an array of 1 element! \b Example: \include
560    *       eg_acopAttach1.java
561    */
562   public int attachLink(Object Data, int ArraySize, Object DataEx, int ArraySizeEx)
563   {
564     return attachLink(Data, ArraySize, DataEx, ArraySizeEx, -1);
565   }
566   /**
567    * @brief Establishes an asynchronous data link using the Device Properties
568    *        assigned to the control and Attaches the data objects passed. Use
569    *        AttachLink for asynchronous data acquisition. Fill in the
570    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
571    *        property parameters, along with the accessProtocol, accessMode, and
572    *        accessRate bean property parameters. Call this method to establish
573    *        the asynchronous data tranfer link and attach the returning data to
574    *        the Data object passed. When new data arrive or the link status has
575    *        changed, the de.desy.acop.chart receive event will be fired.
576    * @param Data
577    *          is the primary data object and refers to the data object to hold
578    *          the output data returned from a server. Pass 'null' if no return
579    *          data is desired.
580    * @param DataEx
581    *          is the extended data object and refers to the data object to which
582    *          holds the input data to be sent to a server. Pass 'null' if no
583    *          return data is desired.
584    * @return A positive link handle if successful otherwise -1, in which case
585    *         the getStatus() method can be queried to determine the cause of
586    *         failure.
587    * @note The Data and DataEx objects above must refer to arrays of data types
588    *       (which are passed by reference) and not single values (which are
589    *       passed by value). So even if passing a single value, it must be
590    *       declared as an array of 1 element! The sizes of the arrays are in
591    *       turn used in establishing the link when using this form of the
592    *       AttachLink() method. \b Example: \include eg_acopAttach1b.java
593    */
594   public int attachLink(Object Data, Object DataEx)
595   {
596     return attachLink(Data, getObjectSize(Data), DataEx, getObjectSize(DataEx), -1);
597   }
598   /**
599    * @brief Establishes an asynchronous data link using the Device Properties
600    *        assigned to the control and Attaches the data object passed. Use
601    *        AttachLink for asynchronous data acquisition. Fill in the
602    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
603    *        property parameters, along with the accessProtocol, accessMode, and
604    *        accessRate bean property parameters. Call this method to establish
605    *        the asynchronous data tranfer link and attach the returning data to
606    *        the Data object passed. When new data arrive or the link status has
607    *        changed, the de.desy.acop.chart receive event will be fired.
608    * @param Data
609    *          is the primary data object and refers to the data object to hold
610    *          the output data returned from a server. Pass 'null' if no return
611    *          data is desired.
612    * @return A positive link handle if successful otherwise -1, in which case
613    *         the getStatus() method can be queried to determine the cause of
614    *         failure.
615    * @note The Data object above must refer to an array of data types (which is
616    *       passed by reference) and not a single value (which is passed by
617    *       value). So even if passing a single value, it must be declared as an
618    *       array of 1 element! The size of the array is in turn used in
619    *       establishing the link when using this form of the AttachLink()
620    *       method. \b Example: \include eg_acopAttach1c.java
621    */
622   public int attachLink(Object Data)
623   {
624     return attachLink(Data, getObjectSize(Data), null, 0, -1);
625   }
626   /**
627    * @brief Establishes an asynchronous data link using the Device Properties
628    *        assigned to the control and Attaches the data object passed. Use
629    *        AttachLink for asynchronous data acquisition. Fill in the
630    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
631    *        property parameters, along with the accessProtocol, accessMode, and
632    *        accessRate bean property parameters. Call this method to establish
633    *        the asynchronous data tranfer link and attach the returning data to
634    *        the Data object passed. When new data arrive or the link status has
635    *        changed, the de.desy.acop.chart receive event will be fired.
636    * @param Data
637    *          is the primary data object and refers to the data object to hold
638    *          the output data returned from a server. Pass 'null' if no return
639    *          data is desired.
640    * @param ArraySize
641    *          is the data array size associated with the Data object. This may
642    *          be smaller than the actual size of the Data object, but NOT
643    *          bigger.
644    * @return A positive link handle if successful otherwise -1, in which case
645    *         the getStatus() method can be queried to determine the cause of
646    *         failure.
647    * @note The Data object above must refer to an array of data types (which is
648    *       passed by reference) and not a single value (which is passed by
649    *       value). So even if passing a single value, it must be declared as an
650    *       array of 1 element! \b Example: \include eg_acopAttach1d.java
651    */
652   public int attachLink(Object Data, int ArraySize)
653   {
654     return attachLink(Data, ArraySize, null, 0, -1);
655   }
656   /**
657    * @brief Establishes an asynchronous data link using the Device Properties
658    *        assigned to the control and Attaches the data object passed. Use
659    *        AttachLink for asynchronous data acquisition. Fill in the
660    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
661    *        property parameters, along with the accessProtocol, accessMode, and
662    *        accessRate bean property parameters. Call this method to establish
663    *        the asynchronous data tranfer link and attach the returning data to
664    *        the Data object passed. When new data arrive or the link status has
665    *        changed, the de.desy.acop.chart receive event will be fired.
666    * @param Data
667    *          is the primary data object and refers to the data object to hold
668    *          the output data returned from a server. Pass 'null' if no return
669    *          data is desired.
670    * @param ArraySize
671    *          is the data array size associated with the Data object. This may
672    *          be smaller than the actual size of the Data object, but NOT
673    *          bigger.
674    * @param identifier
675    *          is a user-specified integer identifier which is used to identify
676    *          the link to the calling application. Following a receive() event,
677    *          the application can call getLinkId() to retrieve this number.
678    *          Other forms of AttachLink() will use the returned link handle as
679    *          and identifier.
680    * @return A positive link handle if successful otherwise -1, in which case
681    *         the getStatus() method can be queried to determine the cause of
682    *         failure.
683    * @note The Data object above must refer to an array of data types (which is
684    *       passed by reference) and not a single value (which is passed by
685    *       value). So even if passing a single value, it must be declared as an
686    *       array of 1 element! \b Example: \include eg_acopAttach1e.java
687    */
688   public int attachLink(Object Data, int ArraySize, int identifier)
689   {
690     return attachLink(Data, ArraySize, null, 0, identifier);
691   }
692   /**
693    * @brief Sets the link identifier to the value specified. Establishing a data
694    *        link by using either AttachLink() or OpenLink() will assign a link
695    *        identifier to the associated link when successful. This link
696    *        identifier (or link 'handle') will be set prior to event
697    *        notification via the Receive() event. One can set the link
698    *        identifier to a desired value either in the original call to
699    *        AttachLink() or OpenLink() or at a later time by calling this
700    *        method.
701    * @param currentLinkIdentifier
702    *          is the current link identifier of the data link to which the new
703    *          link identifier is to be assigned. If not originally set by the
704    *          initial call, it is the value returned by the initial call to
705    *          AttachLink() or OpenLink().
706    * @param linkIdentifier
707    *          is the desired link identifier to be associated with the data link
708    *          defined by linkHandle.
709    * @return The link identifier associated with the data link. If
710    *         de.desy.acop.chart is unable to set the link identifier to the new
711    *         value, it remains unchanged. If successful, the new link handle
712    *         will be set to the assigned link identifier. \b Example: \include
713    *         eg_acopSetLinkIdentifier.java
714    */
715   public int openLink(Object Data, int ArraySize, Object DataEx, int ArraySizeEx, int identifier)
716   {
717     if (getObjectSize(Data) < ArraySize || getObjectSize(DataEx) < ArraySizeEx)
718     {
719       Status = "Data object smaller than size given";
720       return -1;
721     }
722     AcopTransportRequest atr = new AcopTransportRequest();
723     AcopTransportPlug atp;
724     atr.accessMethod = AcopTransportAccessMethods.ATTACH;
725     atr.setFromParameters(connectionParameters);
726     atr.setData(Data);
727     atr.setArraySize(ArraySize);
728     atr.setDataEx(DataEx);
729     atr.setArraySizeEx(ArraySizeEx);
730     atr.atc = atc;
731     atr.isUnboundToData = true;
732     if ((atp = atf.getProtocol(connectionParameters.getAccessProtocol())) == null)
733     {
734       Status = "Protocol not available";
735       return -1;
736     }
737     if (getAcopLinkTableId(atr) >= 0) return atr.getLinkIdentifier();
738     if (atp.handleRequest(atr) < 0)
739     {
740       Status = atr.status;
741       return -1;
742     }
743     if (identifier == -1) identifier = getFreeIdentifier();
744     atr.setLinkIdentifier(identifier);
745     getAcopTransportRequest(atr);
746     atr.pending = true;
747     Status = atr.status;
748     getAcopLinkTableId(atr.getLinkIdentifier());
749     return identifier;
750   }
751   /**
752    * @brief Establishes an asynchronous data link using the Device Properties
753    *        assigned to the control, but does not Attach the data objects
754    *        passed. Use OpenLink for asynchronous data acquisition. Fill in the
755    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
756    *        property parameters, along with the accessProtocol, accessMode, and
757    *        accessRate bean property parameters. Call this method to establish
758    *        the asynchronous data tranfer link. The data returned from a server
759    *        is not bound to the Data object passed in the call and must be
760    *        obtained by an independent call to the GetData() method. When new
761    *        data arrive or the link status has changed, the de.desy.acop.chart
762    *        receive event will be fired.
763    * @param Data
764    *          is the primary data object and refers to the data object to hold
765    *          the output data returned from a server. Pass 'null' if no return
766    *          data is desired.
767    * @param ArraySize
768    *          is the data array size associated with the Data object. This may
769    *          be smaller than the actual size of the Data object, but NOT
770    *          bigger.
771    * @param DataEx
772    *          is the extended data object and refers to the data object to which
773    *          holds the input data to be sent to a server. Pass 'null' if no
774    *          return data is desired.
775    * @param ArraySizeEx
776    *          is the data array size associated with the DataEx object. This may
777    *          be smaller than the actual size of the DataEx object, but NOT
778    *          bigger.
779    * @return A positive link handle if successful otherwise -1, in which case
780    *         the getStatus() method can be queried to determine the cause of
781    *         failure.
782    * @note The Data and DataEx objects above must refer to arrays of data types
783    *       (which are passed by reference) and not single values (which are
784    *       passed by value). So even if passing a single value, it must be
785    *       declared as an array of 1 element!
786    */
787   public int openLink(Object Data, int ArraySize, Object DataEx, int ArraySizeEx)
788   {
789     return openLink(Data, ArraySize, DataEx, ArraySizeEx, -1);
790   }
791   /**
792    * @brief Establishes an asynchronous data link using the Device Properties
793    *        assigned to the control, but does not Attach the data objects
794    *        passed. Use OpenLink for asynchronous data acquisition. Fill in the
795    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
796    *        property parameters, along with the accessProtocol, accessMode, and
797    *        accessRate bean property parameters. Call this method to establish
798    *        the asynchronous data tranfer link. The data returned from a server
799    *        is not bound to the Data object passed in the call and must be
800    *        obtained by an independent call to the GetData() method. When new
801    *        data arrive or the link status has changed, the de.desy.acop.chart
802    *        receive event will be fired.
803    * @param Data
804    *          is the primary data object and refers to the data object to hold
805    *          the output data returned from a server. Pass 'null' if no return
806    *          data is desired.
807    * @param DataEx
808    *          is the extended data object and refers to the data object to which
809    *          holds the input data to be sent to a server. Pass 'null' if no
810    *          return data is desired.
811    * @return A positive link handle if successful otherwise -1, in which case
812    *         the getStatus() method can be queried to determine the cause of
813    *         failure.
814    * @note The Data and DataEx objects above must refer to arrays of data types
815    *       (which are passed by reference) and not single values (which are
816    *       passed by value). So even if passing a single value, it must be
817    *       declared as an array of 1 element! The size of the array is in turn
818    *       used in establishing the link when using this form of the OpenLink()
819    *       method.
820    */
821   public int openLink(Object Data, Object DataEx)
822   {
823     return openLink(Data, getObjectSize(Data), DataEx, getObjectSize(DataEx), -1);
824   }
825   /**
826    * @brief Establishes an asynchronous data link using the Device Properties
827    *        assigned to the control, but does not Attach the data object passed.
828    *        Use OpenLink for asynchronous data acquisition. Fill in the
829    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
830    *        property parameters, along with the accessProtocol, accessMode, and
831    *        accessRate bean property parameters. Call this method to establish
832    *        the asynchronous data tranfer link. The data returned from a server
833    *        is not bound to the Data object passed in the call and must be
834    *        obtained by an independent call to the GetData() method. When new
835    *        data arrive or the link status has changed, the de.desy.acop.chart
836    *        receive event will be fired.
837    * @param Data
838    *          is the primary data object and refers to the data object to hold
839    *          the output data returned from a server. Pass 'null' if no return
840    *          data is desired.
841    * @return A positive link handle if successful otherwise -1, in which case
842    *         the getStatus() method can be queried to determine the cause of
843    *         failure.
844    * @note The Data object above must refer to an array of data types (which is
845    *       passed by reference) and not a single value (which is passed by
846    *       value). So even if passing a single value, it must be declared as an
847    *       array of 1 element! The size of the array is in turn used in
848    *       establishing the link when using this form of the OpenLink() method.
849    */
850   public int openLink(Object Data)
851   {
852     return openLink(Data, getObjectSize(Data), null, 0, -1);
853   }
854   /**
855    * @brief Establishes an asynchronous data link using the Device Properties
856    *        assigned to the control, but does not Attach the data object passed.
857    *        Use OpenLink for asynchronous data acquisition. Fill in the
858    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
859    *        property parameters, along with the accessProtocol, accessMode, and
860    *        accessRate bean property parameters. Call this method to establish
861    *        the asynchronous data transfer link. The data returned from a server
862    *        is not bound to the Data object passed in the call and must be
863    *        obtained by an independent call to the GetData() method. When new
864    *        data arrive or the link status has changed, the chart
865    *        receive event will be fired.
866    * @param Data
867    *          is the primary data object and refers to the data object to hold
868    *          the output data returned from a server. Pass 'null' if no return
869    *          data is desired.
870    * @param ArraySize
871    *          is the data array size associated with the Data object. This may
872    *          be smaller than the actual size of the Data object, but NOT
873    *          bigger.
874    * @return A positive link handle if successful otherwise -1, in which case
875    *         the getStatus() method can be queried to determine the cause of
876    *         failure.
877    * @note The Data object above must refer to an array of data types (which is
878    *       passed by reference) and not a single value (which is passed by
879    *       value). So even if passing a single value, it must be declared as an
880    *       array of 1 element!
881    */
882   public int openLink(Object Data, int ArraySize)
883   {
884     return openLink(Data, ArraySize, null, 0, -1);
885   }
886   /**
887    * @brief Establishes an asynchronous data link using the Device Properties
888    *        assigned to the control, but does not Attach the data object passed.
889    *        Use OpenLink for asynchronous data acquisition. Fill in the
890    *        DeviceContext DeviceGroup, DeviceName, and DeviceProperty bean
891    *        property parameters, along with the accessProtocol, accessMode, and
892    *        accessRate bean property parameters. Call this method to establish
893    *        the asynchronous data transfer link. The data returned from a server
894    *        is not bound to the Data object passed in the call and must be
895    *        obtained by an independent call to the GetData() method. When new
896    *        data arrive or the link status has changed, the chart
897    *        receive event will be fired.
898    * @param Data
899    *          is the primary data object and refers to the data object to hold
900    *          the output data returned from a server. Pass 'null' if no return
901    *          data is desired.
902    * @param ArraySize
903    *          is the data array size associated with the Data object. This may
904    *          be smaller than the actual size of the Data object, but NOT
905    *          bigger.
906    * @param identifier
907    *          is a user-specified integer identifier which is used to identify
908    *          the link to the calling application. Following a receive() event,
909    *          the application can call getLinkId() to retrieve this number.
910    *          Other forms of AttachLink() will use the returned link handle as
911    *          and identifier.
912    * @return A positive link handle if successful otherwise -1, in which case
913    *         the getStatus() method can be queried to determine the cause of
914    *         failure.
915    * @note The Data object above must refer to an array of data types (which is
916    *       passed by reference) and not a single value (which is passed by
917    *       value). So even if passing a single value, it must be declared as an
918    *       array of 1 element!
919    */
920   public int openLink(Object Data, int ArraySize, int identifier)
921   {
922     return openLink(Data, ArraySize, null, 0, identifier);
923   }
924   public String getStatus(int hLink)
925   {
926     AcopTransportRequest atr = getAcopTransportRequest(hLink);
927     return (atr != null) ? atr.getStatus() : "link " + hLink + " not active";
928   }
929   public int getStatusCode(int hLink)
930   {
931     AcopTransportRequest atr = getAcopTransportRequest(hLink);
932     return (atr != null) ? atr.getStatusCode() : -1;
933   }
934   /**
935    * @brief Closes an existing data link. Using CloseLink()
936    *        with a '-1' input parameter will close all data links associated
937    *        with the acop bean.
938    * @param identifier
939    *          is the link handle of the acop data link which is to
940    *          be terminated. If identifier == -1 then all associated links will
941    *          be terminated.
942    * @return 0 if successful otherwise -1, in which case the getStatus() method
943    *         can be queried to determine the cause of failure. \b Example:
944    *         \include eg_acopCloseLink1.java
945    */
946   public int closeLink(int hLink) // hLink is the identifier !
947   {
948     AcopTransportRequest atr = new AcopTransportRequest();
949     AcopTransportPlug atp;
950     AcopTransportRequest a;
951     int i;
952     atr.accessMethod = AcopTransportAccessMethods.CLOSE;
953     if (hLink >= 0)
954     { //TODO: maybe use a hash map or something ? 
955       //(maybe not: the number of links is almost always small!) 
956       for (i = 0; i < acopLinkTable.size(); i++)
957       {
958         a = (AcopTransportRequest) acopLinkTable.elementAt(i);
959         if (a.getLinkIdentifier() == hLink)
960         {
961           atr.setLinkHandle(a.getLinkHandle());
962           atr.accessProtocol = a.accessProtocol;
963           if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
964           {
965             Status = "Protocol not available";
966             return -1;
967           }
968           atp.handleRequest(atr);
969           acopLinkTable.remove(i--); // backup !
970         }
971       }
972     }
973     else
974     {
975       for (i = 0; i < acopLinkTable.size(); i++)
976       {
977         a = (AcopTransportRequest) acopLinkTable.elementAt(i);
978         atr.setLinkHandle(a.getLinkHandle());
979         atr.accessProtocol = a.accessProtocol;
980         if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
981         {
982           Status = "Protocol not available";
983           continue;
984         }
985         atp.handleRequest(atr);
986       }
987       acopLinkTable.removeAllElements();
988     }
989     Status = atr.status;
990     return 0;
991   }
992   /**
993    * @brief Retrieves the data associated with the given link handle into the
994    *        data objects passed. This method is frequently used in conjunction
995    *        with the OpenLink() method of establishing a data link, in which
996    *        case the incoming data is not bound to a data object.
997    * @param Data
998    *          is the primary data object and refers to the data object to hold
999    *          the output data returned from a server. This must be a reference
1000    *          to the same type of object passed in the original call to
1001    *          AttachLink() or OpenLink().
1002    * @param DataEx
1003    *          is the extended data object and refers to the data object to which
1004    *          holds the input data to be sent to a server. This must be a
1005    *          reference to the same type of object passed in the original call
1006    *          to AttachLink() or OpenLink().
1007    * @param identifier
1008    *          is the link handle of the data link which is to
1009    *          be terminated. If identifier == -1 then all associated links will
1010    *          be terminated.
1011    * @return 0 if successful otherwise -1, in which case the getStatus() method
1012    *         can be queried to determine the cause of failure.
1013    */
1014   public int getData(Object Data, Object DataEx, int hLink)
1015   {
1016     AcopTransportRequest atr = new AcopTransportRequest();
1017     AcopTransportPlug atp;
1018     AcopTransportRequest a;
1019     int i;
1020     if (hLink < 0) hLink = 0;
1021     if ((i = getAcopLinkTableId(hLink)) < 0)
1022     {
1023       Status = "Link not allocated";
1024       return -1;
1025     }
1026     a = (AcopTransportRequest) acopLinkTable.elementAt(i);
1027     atr.accessMethod = AcopTransportAccessMethods.GETDATA;
1028     atr.setData(Data);
1029     atr.setArraySize(getObjectSize(Data));
1030     atr.setDataEx(DataEx);
1031     atr.setArraySizeEx(getObjectSize(DataEx));
1032     atr.setLinkHandle(a.getLinkHandle());
1033     atr.accessProtocol = a.accessProtocol;
1034     atr.isUnboundToData = a.isUnboundToData;
1035     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1036     {
1037       Status = "Protocol not available";
1038       return -1;
1039     }
1040     int rc = atp.handleRequest(atr);
1041     lastUpdatedLink = hLink;
1042     lastUpdatedDataSize = atr.getDataSize();
1043     lastUpdatedDataSizeEx = atr.getDataSizeEx();
1044     setTimeStamp(atr.getDataTimeStamp());
1045     a.setDataTimeStamp(atr.getDataTimeStamp());
1046     Status = atr.status;
1047     return rc;
1048   }
1049   public int acquireDisplayProperties(Acop a, String deviceContext, String deviceGroup, String deviceName,
1050       String deviceProperty)
1051   {
1052     AcopTransportRequest atr = new AcopTransportRequest();
1053     AcopTransportPlug atp;
1054     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1055     {
1056       Status = "Protocol not available";
1057       return -1;
1058     }
1059     return atp.acquireDisplayProperties(a, deviceContext, deviceGroup, deviceName, deviceProperty);
1060   }
1061   public double[] getXAxis(Object data)
1062   {
1063     AcopTransportRequest atr = new AcopTransportRequest();
1064     AcopTransportPlug atp;
1065     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1066     {
1067       Status = "Protocol not available";
1068       return null;
1069     }
1070     return atp.getXAxis(data);
1071   }
1072   public double[] getYAxis(Object data)
1073   {
1074     AcopTransportRequest atr = new AcopTransportRequest();
1075     AcopTransportPlug atp;
1076     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1077     {
1078       Status = "Protocol not available";
1079       return null;
1080     }
1081     return atp.getYAxis(data);
1082   }
1083   public String[] getXAxisChannelNames(Object data)
1084   {
1085     AcopTransportRequest atr = new AcopTransportRequest();
1086     AcopTransportPlug atp;
1087     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1088     {
1089       Status = "Protocol not available";
1090       return null;
1091     }
1092     String[] names = atp.getXAxisChannelNames(data);
1093     if (names == null) names = getDeviceNames();
1094     return names;
1095   }
1096   public int getObjectSize(Object data)
1097   {
1098     // AcopTransportRequest atr = new AcopTransportRequest();
1099     AcopTransportPlug atp;
1100     if ((atp = atf.getProtocol(this.connectionParameters.getAccessProtocol())) == null)
1101     {
1102       Status = "Protocol not available";
1103       return -1;
1104     }
1105     return atp.getObjectSize(data);
1106   }
1107   /**
1108    * @brief Gives the current data size of the data objects associated with the
1109    *        given link handle. This method provides an analogy with the
1110    *        equivalent method in the ACOP ActiveX control, where the arguments
1111    *        are explicitly passed by reference. In the ACOP java bean, the
1112    *        overloaded methods GetDataSize(int identifier) and GetDataSizeEx(int
1113    *        identifier) are preferred.
1114    * @param DataSize
1115    *          is a reference to the current data size of primary Data object
1116    *          attached to the data link. As this is passed by reference, this
1117    *          must be an array of 1 integer. A 'null' can be passed if you are
1118    *          not interested in this value.
1119    * @param DataSizeEx
1120    *          is a reference to the current data size of extended Data object
1121    *          attached to the data link. As this is passed by reference, this
1122    *          must be an array of 1 integer. A 'null' can be passed if you are
1123    *          not interested in this value.
1124    * @param identifier
1125    *          is the link handle of the data link for which
1126    *          the current data sizes are desired.
1127    * @return 0 if successful otherwise -1, in which case the getStatus() method
1128    *         can be queried to determine the cause of failure. \b Example:
1129    *         \include eg_acopGetDataSize1.java
1130    */
1131   public int getDataSize(int[] DataSize, int[] DataSizeEx, int hLink)
1132   {
1133     AcopTransportRequest a;
1134     int i;
1135     int[] dsize = new int[1], dsizeEx = new int[1];
1136     if (hLink < 0)
1137     { // synchronous link no long in tables, do the best we can :
1138       dsize[0] = lastUpdatedDataSize;
1139       dsizeEx[0] = lastUpdatedDataSizeEx;
1140     }
1141     else
1142     {
1143       if ((i = getAcopLinkTableId(hLink)) < 0)
1144       {
1145         Status = "Link not allocated";
1146         return -1;
1147       }
1148       a = (AcopTransportRequest) acopLinkTable.elementAt(i);
1149       dsize[0] = a.getDataSize();
1150       dsizeEx[0] = a.getDataSizeEx();
1151     }
1152     if (DataSize != null) DataSize[0] = dsize[0];
1153     if (DataSizeEx != null) DataSizeEx[0] = dsizeEx[0];
1154     return 0;
1155   }
1156   /**
1157    * @brief Queries for the available device contexts according to current
1158    *        setting of the accessProtocol
1159    * @return A string array containing the device contexts
1160    */
1161   public String[] getDeviceContexts()
1162   {
1163     AcopTransportRequest atr = new AcopTransportRequest();
1164     AcopTransportPlug atp;
1165     atr.accessMethod = AcopTransportAccessMethods.EXECUTE;
1166     atr.setFromParameters(connectionParameters);
1167     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1168     {
1169       Status = "Protocol not available";
1170       return null;
1171     }
1172     return atp.getDeviceContexts();
1173   }
1174   /**
1175    * @brief Queries for the available device groups according to current setting
1176    *        of the accessProtocol
1177    * @param deviceContext
1178    *          is the device context for which the device groups are desired
1179    * @param deviceGroup
1180    *          is the device group (sub-string + wildcards) for which the device
1181    *          groups are desired. 'null' is equivalent to "*".
1182    * @param deviceName
1183    *          is the device name for which the device groups are desired. This
1184    *          parameter should typically passed as 'null'.
1185    * @param deviceProperty
1186    *          is the device property for which the device groups are desired.
1187    *          This parameter should typically passed as 'null'.
1188    * @return A string array containing the device groups
1189    */
1190   public String[] getDeviceGroups(String deviceContext, String deviceGroup, String deviceName,
1191       String deviceProperty)
1192   {
1193     AcopTransportRequest atr = new AcopTransportRequest();
1194     AcopTransportPlug atp;
1195     atr.accessMethod = AcopTransportAccessMethods.EXECUTE;
1196     atr.setFromParameters(connectionParameters);
1197     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1198     {
1199       Status = "Protocol not available";
1200       return null;
1201     }
1202     return atp.getDeviceGroups(deviceContext, deviceGroup, deviceName, deviceProperty);
1203   }
1204   /**
1205    * @brief Queries for the available device groups according to current setting
1206    *        of the accessProtocol and Device parameters
1207    * @return A string array containing the device groups
1208    */
1209   public String[] getDeviceGroups()
1210   {
1211     return getDeviceGroups(getDeviceContext(), getDeviceGroup(), getDeviceName(), getDeviceProperty());
1212   }
1213   /**
1214    * @brief Queries for the available device names according to current setting
1215    *        of the accessProtocol
1216    * @param deviceContext
1217    *          is the device context for which the device names are desired
1218    * @param deviceGroup
1219    *          is the device group for which the device names are desired.
1220    * @param deviceName
1221    *          is the device name (sub-string + wildcards) for which the device
1222    *          names are desired. 'null' is equivalent to "*".
1223    * @param deviceProperty
1224    *          is the device property for which the device names are desired.
1225    * @return A string array containing the device names
1226    */
1227   public String[] getDeviceNames(String deviceContext, String deviceGroup, String deviceName,
1228       String deviceProperty)
1229   {
1230     AcopTransportRequest atr = new AcopTransportRequest();
1231     AcopTransportPlug atp;
1232     atr.accessMethod = AcopTransportAccessMethods.EXECUTE;
1233     atr.setFromParameters(connectionParameters);
1234     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1235     {
1236       Status = "Protocol not available";
1237       return null;
1238     }
1239     return atp.getDeviceNames(deviceContext, deviceGroup, deviceName, deviceProperty);
1240   }
1241   /**
1242    * @brief Queries for the available device names according to current setting
1243    *        of the accessProtocol and Device parameters
1244    * @return A string array containing the device names
1245    */
1246   public String[] getDeviceNames()
1247   {
1248     return getDeviceNames(getDeviceContext(), getDeviceGroup(), getDeviceName(), getDeviceProperty());
1249   }
1250   public java.lang.String toTimeString(int TimeStamp)
1251   {
1252     Date d = new Date((long) (TimeStamp * 1000));
1253     return d.toString();
1254   }
1255   public java.lang.String toTimeString(double TimeStamp)
1256   {
1257     Date d = new Date((long) (TimeStamp * 1000));
1258     return d.toString();
1259   }
1260   public java.lang.String toTimeString(Date TimeStamp)
1261   {
1262     return TimeStamp.toString();
1263   }
1264   public void setReceiveQueueDepth(int ReceiveQueueDepth)
1265   {
1266     this.ReceiveQueueDepth = ReceiveQueueDepth;
1267   }
1268   public void setTimeStamp(int TimeStamp)
1269   {
1270     this.TimeStamp = (double) TimeStamp;
1271     this.dateStamp = new Date(((long) TimeStamp) * 1000);
1272   }
1273   public void setTimeStamp(Date TimeStamp)
1274   {
1275     this.dateStamp = TimeStamp;
1276     if (TimeStamp != null) this.TimeStamp = (double) (TimeStamp.getTime()) / 1000;
1277   }
1278   public void setTimeStamp(double TimeStamp)
1279   {
1280     this.TimeStamp = TimeStamp;
1281     this.dateStamp = new Date((long) (TimeStamp * 1000));
1282   }
1283   /**
1284    * @brief The current data status string
1285    * @return The current data status string
1286    */
1287   public java.lang.String getStatus()
1288   {
1289     return Status;
1290   }
1291   public int getGroupIndex()
1292   {
1293     return isGrouped ? GroupIndex : -1;
1294   }
1295   /**
1296    * @brief Sets the grouped flag
1297    * @param isGrouped
1298    *          determines whether all data links associated with this
1299    *          acop are to fire one single event (isGrouped = true)
1300    *          when all link states have changed or not (isGrouped = false)
1301    */
1302   public void setGrouped(boolean Grouped)
1303   {
1304     this.isGrouped = Grouped;
1305   }
1306   public void setDeviceContext(java.lang.String deviceContext)
1307   {
1308     if (connectionParameters != null) {
1309 	  setConnectionParameters(connectionParameters.deriveWithDeviceContext(deviceContext));
1310     } else {
1311     	setConnectionParameters(new ConnectionParameters(null, deviceContext, null, null, null, null, 1000));
1312     }
1313   }
1314   public String getDeviceContext()
1315   {
1316     return connectionParameters.getDeviceContext();
1317   }
1318   public void setDeviceGroup(java.lang.String deviceGroup)
1319   {
1320 	  if (connectionParameters != null) {
1321 		  setConnectionParameters(connectionParameters.deriveWithDeviceGroup(deviceGroup));
1322 	  } else {
1323 	      setConnectionParameters(new ConnectionParameters(null, null, deviceGroup, null, null, null, 1000));
1324 	  }
1325   }
1326   public String getDeviceGroup()
1327   {
1328     return connectionParameters.getDeviceGroup();
1329   }
1330   public void setDeviceName(java.lang.String deviceName)
1331   {
1332 	  if (connectionParameters != null) {
1333 		  setConnectionParameters(connectionParameters.deriveWithDeviceName(deviceName));
1334 	  } else {
1335 		 setConnectionParameters(new ConnectionParameters(null, null, null, deviceName, null, null, 1000));
1336 	  }
1337   }
1338   public String getDeviceName()
1339   {
1340     return connectionParameters.getDeviceName();
1341   }
1342   public void setDeviceProperty(java.lang.String deviceProperty)
1343   {
1344 	  if (connectionParameters != null) {
1345 		  setConnectionParameters(connectionParameters.deriveWithDeviceProperty(deviceProperty));
1346 	  } else {
1347 		  setConnectionParameters(new ConnectionParameters(null, null, null, null, deviceProperty, null, 1000));
1348 	  }
1349   }
1350   public String getDeviceProperty()
1351   {
1352     return connectionParameters.getDeviceProperty();
1353   }
1354   public void setAccessMode(AccessMode am)
1355   {
1356 	  if (connectionParameters != null) {
1357 		  setConnectionParameters(connectionParameters.deriveWith(am));
1358 	  } else {
1359 		  setConnectionParameters(new ConnectionParameters(null, null, null, null, null, am, 1000));
1360 	  }
1361   }
1362   public AccessMode getAccessMode()
1363   {
1364     return connectionParameters.getAccessMode();
1365   }
1366   public void setAccessProtocol(java.lang.String accessProtocol)
1367   {
1368 	  if (connectionParameters != null) {
1369 		  setConnectionParameters(connectionParameters.deriveWithAccessProtocol(accessProtocol));
1370 	  } else {
1371 		  setConnectionParameters(new ConnectionParameters(accessProtocol, null, null, null, null, null, 1000));
1372 	  }
1373   }
1374   public String getAccessProtocol()
1375   {
1376     return connectionParameters.getAccessProtocol();
1377   }
1378   public void setAccessRate(String accessRate)
1379   {
1380 	  if (connectionParameters != null) {
1381 		  setConnectionParameters(connectionParameters.deriveWithAccessRate(Integer.parseInt(accessRate)));
1382 	  } else {
1383 		  setConnectionParameters(new ConnectionParameters(null, null, null, null, null, null, Integer.parseInt(accessRate)));
1384 	  }
1385   }
1386   public String getAccessRate()
1387   {
1388     return Integer.toString(connectionParameters.getAccessRate());
1389   }
1390   public void setPropertySize(String propertySize)
1391   {
1392 	  if (connectionParameters != null) {
1393 		  setConnectionParameters(connectionParameters.deriveWithPropertySize(Integer.parseInt(propertySize)));
1394 	  } else {
1395 		  setConnectionParameters(new ConnectionParameters(null, null, null, null, null, null, 1000, Integer.parseInt(propertySize)));
1396 	  }
1397   }
1398   public String getPropertySize() {
1399 	  return Integer.toString(connectionParameters.getPropertySize());
1400   }
1401   public void setAcopConfig(java.lang.String AcopConfig)
1402   {
1403     this.acopConfig = AcopConfig;
1404   }
1405   public String getAcopConfig()
1406   {
1407     return acopConfig;
1408   }
1409   public int setLinkIdentifier(int currentLinkIdentifier, int linkIdentifier)
1410   {
1411     AcopTransportRequest a;
1412     int identifier = currentLinkIdentifier;
1413     Vector lnkTbl = getAcopLinkTable();
1414     for (int i = 0; i < lnkTbl.size(); i++)
1415     {
1416       if ((a = (AcopTransportRequest) lnkTbl.elementAt(i)) == null) continue;
1417       if (a.getLinkIdentifier() != currentLinkIdentifier) continue;
1418       a.setLinkIdentifier(linkIdentifier);
1419       identifier = linkIdentifier;
1420     }
1421     return identifier;
1422   }
1423   /**
1424    * @brief Returns the current data size of the primary data object associated
1425    *        with the given link handle.
1426    * @param identifier
1427    *          is the link handle of the data link for which
1428    *          the current data sizes are desired.
1429    * @return The data size of the returned data if successful otherwise -1, in
1430    *         which case the getStatus() method can be queried to determine the
1431    *         cause of failure. \b Example: \include eg_acopGetDataSize2.java
1432    */
1433   public int getDataSize(int identifier)
1434   {
1435     int[] dsize = new int[1];
1436     int rc = getDataSize(dsize, null, identifier);
1437     if (rc < 0) return rc;
1438     return dsize[0];
1439   }
1440   /**
1441    * @brief Returns the current data size of the primary data object.
1442    * @return The data size of the returned data if successful otherwise -1, in
1443    *         which case the getStatus() method can be queried to determine the
1444    *         cause of failure. \b Example: \include eg_acopGetDataSize3.java
1445    */
1446   public int getDataSize()
1447   {
1448     int[] dsize = new int[1];
1449     int rc = getDataSize(dsize, null, -1);
1450     if (rc < 0) return rc;
1451     return dsize[0];
1452   }
1453   /**
1454    * @brief Returns the current data size of the extended data object associated
1455    *        with the given link handle.
1456    * @param identifier
1457    *          is the link handle of the data link for which
1458    *          the current data sizes are desired.
1459    * @return The data size of the sent data if successful otherwise -1, in which
1460    *         case the getStatus() method can be queried to determine the cause
1461    *         of failure.
1462    */
1463   public int getDataSizeEx(int identifier)
1464   {
1465     int[] dsize = new int[1];
1466     int rc = getDataSize(null, dsize, identifier);
1467     if (rc < 0) return rc;
1468     return dsize[0];
1469   }
1470   /**
1471    * @brief Returns the current data size of the extended data object.
1472    * @return The data size of the sent data if successful otherwise -1, in which
1473    *         case the getStatus() method can be queried to determine the cause
1474    *         of failure.
1475    */
1476   public int getDataSizeEx()
1477   {
1478     int[] dsize = new int[1];
1479     int rc = getDataSize(null, dsize, -1);
1480     if (rc < 0) return rc;
1481     return dsize[0];
1482   }
1483   /**
1484    * @brief The current data time stamp as a Date object
1485    * @return The current data time stamp as a Date object
1486    */
1487   public Date getTimeStamp()
1488   {
1489     return getDateStamp();
1490   }
1491   /**
1492    * @brief The grouped flag
1493    * @return the isGrouped state of this acop
1494    */
1495   public boolean getGrouped()
1496   {
1497     return isGrouped;
1498   }
1499   /**
1500    * @brief Queries for the available device properties according to current
1501    *        setting of the accessProtocol and Device parameters
1502    * @return A string array containing the device properties
1503    */
1504   public String[] getDeviceProperties()
1505   {
1506     return getDeviceProperties(getDeviceContext(), getDeviceGroup(), getDeviceName(), getDeviceProperty());
1507   }
1508   /**
1509    * @brief Queries for the available device properties according to current
1510    *        setting of the accessProtocol
1511    * @param deviceContext
1512    *          is the device context for which the device properties are desired
1513    * @param deviceGroup
1514    *          is the device group for which the device properties are desired.
1515    * @param deviceName
1516    *          is the device name for which the device properties are desired.
1517    * @param deviceProperty
1518    *          is the device property (sub-string + wildcards) for which the
1519    *          device properties are desired. 'null' is equivalent to "*".
1520    * @return A string array containing the device properties
1521    */
1522   public String[] getDeviceProperties(String deviceContext, String deviceGroup, String deviceName,
1523       String deviceProperty)
1524   {
1525     AcopTransportRequest atr = new AcopTransportRequest();
1526     AcopTransportPlug atp;
1527     atr.accessMethod = AcopTransportAccessMethods.EXECUTE;
1528     atr.setFromParameters(connectionParameters);
1529     if ((atp = atf.getProtocol(atr.accessProtocol)) == null)
1530     {
1531       Status = "Protocol not available";
1532       return null;
1533     }
1534     return atp.getDeviceProperties(deviceContext, deviceGroup, deviceName, deviceProperty);
1535   }
1536   /**
1537    * @brief Queries for the available display setting according to current
1538    *        setting of the accessProtocol This method uses the query mechanisms
1539    *        of the underlying transport to ascertain the maximum and minimum
1540    *        display settings and axis labels. The resulting 'Y' axis label will
1541    *        be the units associated with the queried property. The maximum and
1542    *        minimum settings for the 'Y' axis will be the range associated with
1543    *        the queried property. The resulting 'X' axis label will be the
1544    *        description associated with the queried property. The maximum and
1545    *        minimum settings for the 'X' axis will be 0 to the array size of the
1546    *        property queried, if the property corresponds to a multi-channel
1547    *        display.
1548    * @param deviceContext
1549    *          is the device context for which the device properties are desired
1550    * @param deviceGroup
1551    *          is the device group for which the device properties are desired.
1552    * @param deviceName
1553    *          is the device name for which the device properties are desired.
1554    * @param deviceProperty
1555    *          is the device property (sub-string + wildcards) for which the
1556    *          device properties are desired. 'null' is equivalent to "*".
1557    * @return 0 if successful otherwise -1.
1558    */
1559   public int acquireDisplayProperties(String deviceContext, String deviceGroup, String deviceName,
1560       String deviceProperty)
1561   {
1562     return acquireDisplayProperties(null, deviceContext, deviceGroup, deviceName, deviceProperty);
1563   }
1564   /**
1565    * @brief Queries for the available display setting according to current
1566    *        setting of the accessProtocol and display parameters. This method
1567    *        uses the query mechanisms of the underlying transport to ascertain
1568    *        the maximum and minimum display settings and axis labels. The
1569    *        resulting 'Y' axis label will be the units associated with the
1570    *        queried property. The maximum and minimum settings for the 'Y' axis
1571    *        will be the range associated with the queried property. The
1572    *        resulting 'X' axis label will be the description associated with the
1573    *        queried property. The maximum and minimum settings for the 'X' axis
1574    *        will be 0 to the array size of the property queried, if the property
1575    *        corresponds to a multi-channel display.
1576    * @return 0 if successful otherwise -1.
1577    */
1578   public int acquireDisplayProperties()
1579   {
1580     return acquireDisplayProperties(null, getDeviceContext(), getDeviceGroup(), getDeviceName(),
1581         getDeviceProperty());
1582   }
1583   public void addAcopTransportListener(AcopTransportListener l)
1584   {
1585     listeners.add(AcopTransportListener.class, l);
1586   }
1587   public void removeAcopTransportListener(AcopTransportListener l)
1588   {
1589     listeners.remove(AcopTransportListener.class, l);
1590   }
1591   /**
1592    * Returns the connectionParameters.
1593    * 
1594    * @return Returns the connectionParameters.
1595    */
1596   public ConnectionParameters getConnectionParameters()
1597   {
1598     return connectionParameters;
1599   }
1600   /**
1601    * Sets new connectionParameters.
1602    * 
1603    * @param connectionParameters
1604    *          The connectionParameters to set.
1605    */
1606   public void setConnectionParameters(ConnectionParameters connectionParameters)
1607   {
1608 	if ((this.connectionParameters != null && this.connectionParameters.equals(connectionParameters)) ||
1609 		  this.connectionParameters == null && connectionParameters == null) return;
1610     ConnectionParameters oldValue = this.connectionParameters;
1611     this.connectionParameters = connectionParameters;
1612     firePropertyChange(CONNECTION_PARAMETERS_PROPERTY, oldValue, this.connectionParameters);
1613   }
1614   
1615   private PropertyChangeSupport propertyChangeSupport;
1616   
1617   protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
1618 	  if (propertyChangeSupport == null) return;
1619 	  propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
1620   }
1621   
1622   public void addPropertyChangeListener(PropertyChangeListener listener) {
1623 	if (propertyChangeSupport == null) {
1624 		propertyChangeSupport = new PropertyChangeSupport(this);
1625 	}
1626 	propertyChangeSupport.addPropertyChangeListener(listener);	
1627   }
1628   
1629   public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
1630 	if (propertyChangeSupport == null) {
1631 		propertyChangeSupport = new PropertyChangeSupport(this);
1632 	}
1633 	propertyChangeSupport.addPropertyChangeListener(propertyName, listener);	
1634   }
1635 
1636   public void removePropertyChangeListener(PropertyChangeListener listener) {
1637 	if (propertyChangeSupport == null) return;
1638 	propertyChangeSupport.removePropertyChangeListener(listener);
1639   }
1640   public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
1641 	if (propertyChangeSupport == null) return;
1642 	propertyChangeSupport.removePropertyChangeListener(propertyName, listener);	
1643   }
1644 }