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.simulator;
24  
25  import java.util.Date;
26  import java.util.Random;
27  
28  import de.desy.acop.chart.Acop;
29  import de.desy.acop.transport.AcopTransportAccessMethods;
30  import de.desy.acop.transport.AcopTransportCallback;
31  import de.desy.acop.transport.AcopTransportPlug;
32  import de.desy.acop.transport.AcopTransportRequest;
33  
34  /**
35   * @version 1.0
36   * @author
37   */
38  public class AcopTransportSimulator implements AcopTransportPlug
39  {
40    static private class SimulatorLink
41    {
42      int linkHandle = 0;
43      int pollingInterval = 1000;
44      long lastnotified = 0;
45    }
46    private final static int MAX_LINKS = 1000;
47    private SimulatorLink[] links = new SimulatorLink[MAX_LINKS];
48    private AcopTransportCallback atc;
49    private String[] AcopSimulatorString = new String[1];
50    /**
51     * @see AcopPack.acopTransportPlug#handleRequest(acopTransportRequest)
52     */
53    public int handleRequest(AcopTransportRequest atr)
54    {
55      switch (atr.accessMethod)
56      {
57        case AcopTransportAccessMethods.EXECUTE:
58          if (!atr.accessMode.isReadMode() 
59              && !atr.accessMode.isWriteMode())
60          {
61            atr.status = "illegal mode (READ or WRITE required)";
62            return -1;
63          }
64          if (atr.getData() != null)
65          {
66            int len = atr.getArraySize();
67            atr.statusCode = simulateData(atr.getData(), len);
68            atr.setDataSize(len); // just set it to the request
69            atr.status = "Success";
70            return 0;
71          }
72          break;
73        case AcopTransportAccessMethods.ATTACH:
74          int i = getLinkHandle();
75          atr.setLinkHandle(i);
76          links[i].pollingInterval = Integer.parseInt(atr.accessRate);
77          atc = atr.atc;
78          return 0;
79        case AcopTransportAccessMethods.CLOSE:
80          return rmvLinkHandle(atr.getLinkHandle());
81        case AcopTransportAccessMethods.GETDATA:
82          if (atr.getData() != null)
83          {
84            int len = atr.getArraySize();
85            atr.statusCode = simulateData(atr.getData(), len);
86            atr.setDataTimeStamp(new Date(ast.interim));
87            atr.setDataSize(len); // just set it to the request
88            atr.status = "Success";
89            return 0;
90          }
91          break;
92        case AcopTransportAccessMethods.SHUTDOWN:
93          active = false;
94          terminate = true;
95          break;
96        default:
97          return -1;
98      }
99      return 0;
100   }
101   /**
102    * @see AcopPack.acopTransportPlug#getPlugName()
103    */
104   public String getPlugName()
105   {
106     return "Simulate";
107   }
108   public int getObjectSize(Object data)
109   {
110     if (data == null) return 0;
111     if (data instanceof double[]) return ((double[]) data).length;
112     if (data instanceof float[]) return ((float[]) data).length;
113     if (data instanceof byte[]) return ((byte[]) data).length;
114     if (data instanceof short[]) return ((short[]) data).length;
115     if (data instanceof int[]) return ((int[]) data).length;
116     if (data instanceof String) return ((String) data).length();
117     if (data instanceof StringBuffer) return ((StringBuffer) data).length();
118     if (data instanceof char[]) return ((char[]) data).length;
119     return 0;
120   }
121   public double[] getYAxis(Object data)
122   {
123     int siz = getObjectSize(data);
124     if (siz > 0)
125     {
126       if (data instanceof double[]) return (double[]) data;
127       double[] y;
128       y = new double[siz];
129       if (data instanceof float[])
130         for (int i = 0; i < siz; i++)
131           y[i] = ((float[]) data)[i];
132       else if (data instanceof byte[])
133         for (int i = 0; i < siz; i++)
134           y[i] = ((byte[]) data)[i];
135       else if (data instanceof short[])
136         for (int i = 0; i < siz; i++)
137           y[i] = ((short[]) data)[i];
138       else if (data instanceof int[]) for (int i = 0; i < siz; i++)
139         y[i] = ((int[]) data)[i];
140       return y;
141     }
142     return null;
143   }
144   public String[] getXAxisChannelNames(Object data)
145   {
146     return null;
147   }
148   public double[] getXAxis(Object data)
149   {
150     int siz = getObjectSize(data);
151     if (siz > 0)
152     {
153       if (data instanceof double[]) return (double[]) data;
154       double[] x;
155       x = new double[siz];
156       if (data instanceof float[])
157         for (int i = 0; i < siz; i++)
158           x[i] = ((float[]) data)[i];
159       else if (data instanceof byte[])
160         for (int i = 0; i < siz; i++)
161           x[i] = ((byte[]) data)[i];
162       else if (data instanceof short[])
163         for (int i = 0; i < siz; i++)
164           x[i] = ((short[]) data)[i];
165       else if (data instanceof int[]) for (int i = 0; i < siz; i++)
166         x[i] = ((int[]) data)[i];
167       return x;
168     }
169     return null;
170   }
171   private int numberOfLinks = 0;
172   private int getLinkHandle()
173   {
174     int i;
175     for (i=0; i<numberOfLinks; i++) if (links[i].linkHandle < 0) break;
176     if (i >= MAX_LINKS) return -1;
177     if (i == numberOfLinks) 
178     {
179       numberOfLinks++;
180       links[i] = new SimulatorLink();
181       links[i].linkHandle = i;
182     }
183     return i;
184   }
185   private int rmvLinkHandle(int hLink)
186   {
187     if (hLink < 0 || hLink >= numberOfLinks) return -1;
188     links[hLink].linkHandle = -1;
189     if (hLink == numberOfLinks-1) numberOfLinks--;
190     return numberOfLinks;
191   }
192   private static final int simulatedDataArraySize = 512;
193   private float[] simulatedDataArray = new float[simulatedDataArraySize];
194   private int simulateData(Object data, int datalength)
195   {
196     int i, len;
197     if (data instanceof double[])
198     {
199       len = ((double[]) data).length;
200       if (datalength > 0 && datalength < len) len = datalength;
201       datalength = len;
202       for (i = 0; i < len; i++)
203         ((double[]) data)[i] = (double) simulatedDataArray[i % simulatedDataArraySize];
204       return 0;
205     }
206     else if (data instanceof float[])
207     {
208       len = ((float[]) data).length;
209       if (datalength > 0 && datalength < len) len = datalength;
210       datalength = len;
211       for (i = 0; i < len; i++)
212         ((float[]) data)[i] = simulatedDataArray[i % simulatedDataArraySize];
213       return 0;
214     }
215     else if (data instanceof int[])
216     {
217       len = ((int[]) data).length;
218       if (datalength > 0 && datalength < len) len = datalength;
219       datalength = len;
220       for (i = 0; i < len; i++)
221         ((int[]) data)[i] = (int) simulatedDataArray[i % simulatedDataArraySize];
222       return 0;
223     }
224     else if (data instanceof short[])
225     {
226       len = ((short[]) data).length;
227       if (datalength > 0 && datalength < len) len = datalength;
228       datalength = len;
229       for (i = 0; i < len; i++)
230         ((short[]) data)[i] = (short) simulatedDataArray[i % simulatedDataArraySize];
231       return 0;
232     }
233     return -1;
234   }
235   private Random acopSimulatorRandom = new Random();
236   private void updateSimulatedData()
237   {
238     for (int i = 0; i < simulatedDataArraySize; i++)
239     {
240       simulatedDataArray[i] = 
241         (float) (100 * Math.sin(i * 6.2832 / simulatedDataArraySize) + acopSimulatorRandom.nextFloat() * 10);
242     }
243   }
244   private boolean active = false;
245   private boolean terminate = false;
246   private acopSimulatorThread ast;
247   public AcopTransportSimulator()
248   {
249     active = true;
250     ast = new acopSimulatorThread();
251     ast.start();
252     updateSimulatedData();
253   }
254   private class acopSimulatorThread extends Thread
255   {
256     boolean isWaiting = false;
257     private long interim = 0;
258     public synchronized void run()
259     {
260       while (active)
261       {
262         if (terminate) break;
263         try
264         {
265           isWaiting = true;
266           sleep(100);
267           interim = System.currentTimeMillis();
268           isWaiting = false;
269           updateSimulatedData();
270           if (numberOfLinks > 0) // don't worry about link tables in the simulator
271           {
272             for (int i = 0; i < numberOfLinks; i++)
273             {
274               if (links[i].linkHandle < 0) continue;
275               if (interim < links[i].lastnotified + links[i].pollingInterval) continue;
276               if (atc != null)
277               {
278                 atc.callback(i, 0);
279               }
280               links[i].lastnotified = interim;
281             }
282           }
283         }
284         catch (InterruptedException e)
285         {
286           System.out.println(" InterruptedException : " + e);
287         }
288       }
289     }
290   }
291   public int acquireDisplayProperties(Acop a, String deviceContext, String deviceGroup, String deviceName,
292       String deviceProperty)
293   {
294     a.setYMax(100);
295     a.setYMin(-100);
296     a.setXMax(512);
297     a.setXMin(0);
298     a.setYAxisLabel("Amplitude");
299     a.setXAxisLabel("Simulated data");
300     a.setGraphStyle(0);
301     return 0;
302   }
303   public String[] getDeviceContexts()
304   {
305     if (AcopSimulatorString[0] == null)
306     {
307       AcopSimulatorString[0] = new String("TEST");
308     }
309     return AcopSimulatorString;
310   }
311   public String[] getDeviceGroups(String deviceContext, String deviceGroup, String deviceName,
312       String deviceProperty)
313   {
314     if (AcopSimulatorString[0] == null)
315     {
316       AcopSimulatorString[0] = new String("TEST");
317     }
318     return AcopSimulatorString;
319   }
320   public String[] getDeviceNames(String deviceContext, String deviceGroup, String deviceName,
321       String deviceProperty)
322   {
323     if (AcopSimulatorString[0] == null)
324     {
325       AcopSimulatorString[0] = new String("TEST");
326     }
327     return AcopSimulatorString;
328   }
329   public String[] getDeviceProperties(String deviceContext, String deviceGroup, String deviceName,
330       String deviceProperty)
331   {
332     if (AcopSimulatorString[0] == null)
333     {
334       AcopSimulatorString[0] = new String("TEST");
335     }
336     return AcopSimulatorString;
337   }
338   public String getTargetInformation(String deviceContext, String deviceGroup, String deviceName,
339       String deviceProperty)
340   {
341     return "simulated target";
342   }
343 }