]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/src/org/simantics/fmil/core/FMIL.java
Renamed org.simantics.fmil to org.simantics.fmil.core to prevent having bundles and...
[simantics/fmil.git] / org.simantics.fmil.core / src / org / simantics / fmil / core / FMIL.java
1 package org.simantics.fmil.core;\r
2 \r
3 import java.io.File;\r
4 import java.io.IOException;\r
5 import java.io.RandomAccessFile;\r
6 import java.nio.channels.FileChannel;\r
7 import java.nio.channels.FileLock;\r
8 import java.util.ArrayList;\r
9 import java.util.HashSet;\r
10 import java.util.List;\r
11 import java.util.Set;\r
12 import java.util.UUID;\r
13 \r
14 import org.eclipse.core.runtime.FileLocator;\r
15 import org.eclipse.core.runtime.Platform;\r
16 import org.osgi.framework.Bundle;\r
17 import org.simantics.Simantics;\r
18 import org.simantics.fmil.core.ExecEnvironment.ARCHType;\r
19 import org.simantics.fmil.core.ExecEnvironment.OSType;\r
20 import org.simantics.utils.FileUtils;\r
21 \r
22 import gnu.trove.list.array.TIntArrayList;\r
23 import gnu.trove.map.hash.TObjectIntHashMap;\r
24 \r
25 \r
26 public class FMIL {\r
27 \r
28     /**\r
29      * Static variables\r
30      */\r
31     private static int      ERROR               = 0;\r
32     private static int      OK                  = 1;\r
33     private static String   UNSATISFIED_LINK    = "Method not found. DLL might not be loaded properly.";    \r
34     private static String   TEMP_FMU_DIRECTORY_NAME = "fmil";    \r
35     public static String    TEMP_FMU_COMMON_DIRECTORY;  \r
36     public static String    LOCK_FILE_NAME      = "fmil.lock";\r
37 \r
38     public static Object syncObject = new Object();\r
39 \r
40     /**\r
41      * Static: load native libraries required for the FMU simulation to work.\r
42      */\r
43     static {\r
44         \r
45         File[] libraries = new File[2];\r
46 \r
47         Bundle bundle = null;\r
48         \r
49         ExecEnvironment env = ExecEnvironment.calculate();\r
50         if (env.os == OSType.WINDOWS) {\r
51             if (env.arch == ARCHType.X86) {\r
52                 bundle = Platform.getBundle("org.simantics.fmil.win32");\r
53             } else if (env.arch == ARCHType.X86_64) {\r
54                 bundle = Platform.getBundle("org.simantics.fmil.win64");\r
55             }\r
56         }\r
57         \r
58         if (bundle != null) {\r
59             try{\r
60                 String root = FileLocator.getBundleFile(bundle).getAbsolutePath();\r
61 //                if (env.arch == ARCHType.X86_64) {\r
62 //                    File newFIle = new File(root, "libraries/libexpat.dll");\r
63 //                    System.load(newFIle.getAbsolutePath());\r
64 //                }\r
65 //                libraries[0] = new File(root, "libraries/zlibwapi.dll");\r
66 //                libraries[1] = new File(root, "libraries/miniunz.dll");\r
67                 libraries[0] = new File(root, "libraries/fmilib_shared.dll");\r
68                 libraries[1] = new File(root, "libraries/FMUSimulator.dll");\r
69             }\r
70             catch (Exception e) {\r
71                 e.printStackTrace();\r
72             }\r
73         }\r
74 \r
75         for(File library : libraries) {\r
76             if(library == null) {\r
77                 System.err.println("FMU library not loaded. FMU simulation not working.");\r
78                 continue;\r
79             } else if(!library.isFile()) {\r
80                 System.err.println(library.getAbsolutePath() + " not found");\r
81             } else {\r
82                 try {\r
83                     System.load(library.getAbsolutePath());\r
84                 } catch (Throwable t) {\r
85                     System.err.println(t.getMessage());\r
86                 }\r
87             } \r
88         }\r
89     }\r
90 \r
91     /**\r
92      * Static: initialize fmu temp folder\r
93      */\r
94     static {\r
95         File dir = Simantics.getTemporaryDirectory(TEMP_FMU_DIRECTORY_NAME);\r
96         TEMP_FMU_COMMON_DIRECTORY = dir.getAbsolutePath(); \r
97     }\r
98 \r
99 \r
100     private String fmuDir;\r
101     private int id;\r
102 \r
103     public String TEMP_FOLDER_1;\r
104     public String TEMP_FOLDER_2;\r
105     public String TEMP_FMU_DIRECTORY;\r
106     private String dirName;\r
107 \r
108         private String[] variableNames;\r
109         private String[] variableDescriptions;\r
110         private String[] variableDeclaredTypes;\r
111         private int[] variableReferences;\r
112         private int[] variableTypes;\r
113         private int[] variableCausalities;\r
114         private int[] variableVariabilities;\r
115         \r
116         private String[] declaredTypes;\r
117         private String[] declaredTypeDescriptions;\r
118         private String[] declaredTypeQuantities;\r
119         private String[] declaredTypeUnits;\r
120         \r
121         private TObjectIntHashMap<String> variableMap = new TObjectIntHashMap<String>();\r
122         \r
123         private Set<String> subscriptionSet = new HashSet<String>();\r
124         private TIntArrayList subscription = new TIntArrayList();\r
125         private ArrayList<String> subscribedNames = new ArrayList<String>();\r
126         \r
127         public List<String> getSubscribedNames() {\r
128                 return subscribedNames;\r
129         }\r
130         \r
131         public boolean subscribe(String name) throws FMILException {\r
132                 // Safety check\r
133                 int vr = variableMap.get(name);\r
134                 if(vr == 0) return false;\r
135                 if(!subscriptionSet.add(name)) return false;\r
136                 subscribedNames.add(name);\r
137                 System.err.println("subscribed : " + name + " => " + subscribedNames.size());\r
138                 subscription.add(vr);\r
139                 subscribe(new int[] { vr });\r
140                 return true;\r
141         }\r
142 \r
143     public FMIL() {\r
144         // Create a directory for this control\r
145         File tempDir = new File(TEMP_FMU_COMMON_DIRECTORY, UUID.randomUUID().toString());\r
146         tempDir.mkdir();\r
147         TEMP_FMU_DIRECTORY = tempDir.getAbsolutePath();\r
148 \r
149         // Create two directories inside the temp directory for this control\r
150         dirName = UUID.randomUUID().toString();\r
151         File fmuDir = new File(TEMP_FMU_DIRECTORY, dirName);\r
152         fmuDir.mkdir();\r
153 \r
154         TEMP_FOLDER_1 = fmuDir.toString();\r
155         TEMP_FOLDER_2 = fmuDir.toString() + "_2";\r
156 \r
157         // Lock fmu directory in temp directory\r
158         lockFMUDirectory();\r
159     }\r
160 \r
161     public int getModelIDNew() {\r
162         return id;\r
163     }\r
164 \r
165     public String getModelID() {\r
166         return dirName;\r
167     }\r
168 \r
169     public String getFmuDir() {\r
170         return fmuDir;\r
171     }\r
172 \r
173     /**\r
174      * Load fmu from a given file path. Releases the (possible) previously\r
175      * loaded fmu.\r
176      * \r
177      * @param path absolute file path for fmu file\r
178      * @throws FMILException\r
179      */\r
180     private int fmuN = 0;\r
181     private boolean fmuLoaded = false;\r
182     public void loadFMUFile(String path) throws FMILException {\r
183 \r
184         synchronized(syncObject) {\r
185 \r
186             if(fmuN % 2 == 0) {\r
187                 fmuDir = TEMP_FOLDER_1;\r
188                 fmuN++;\r
189             } else {\r
190                 fmuDir = TEMP_FOLDER_2;\r
191                 fmuN = 0;\r
192             }\r
193 \r
194             File tempDir = new File(fmuDir);\r
195             if(tempDir.isDirectory()) {\r
196                 try {\r
197                     FileUtils.deleteAll(tempDir);\r
198                 } catch (IOException e) {\r
199                     throw new FMILException("Could not create temp folder for fmu");\r
200                 }\r
201                 tempDir.mkdir();\r
202             } else {\r
203                 tempDir.mkdir();\r
204             }\r
205 \r
206 \r
207             try {\r
208                 String tmpPath = tempDir.getAbsolutePath();\r
209                 if(!tmpPath.endsWith("\\"))\r
210                     tmpPath = tmpPath + "\\";\r
211                 id = loadFMUFile_(path, tmpPath);\r
212                 \r
213                 getAllVariables();\r
214                 getAllVariableReferences();\r
215                 \r
216                 for(int i=0;i<variableNames.length;i++) {\r
217                         variableMap.put(variableNames[i], variableReferences[i]);\r
218                 }\r
219 \r
220                 fmuLoaded = true;\r
221             } catch (UnsatisfiedLinkError err) {\r
222                 throw new FMILException(UNSATISFIED_LINK, err);\r
223             } catch (Exception e) {\r
224                 throw new FMILException(e.getMessage());\r
225             }\r
226         }\r
227     }\r
228 \r
229     private native int loadFMUFile_(String path, String toDir);\r
230 \r
231     /**\r
232      * Set a step length for simulation\r
233      * \r
234      * @param step Step length for simulation\r
235      * @throws FMILException\r
236      */\r
237     public void setStepLength(double step) throws FMILException {\r
238         synchronized(syncObject) {\r
239 \r
240             try {\r
241 \r
242                 int ret = setStepLength_(getModelIDNew(), step);\r
243                 if(ret == ERROR)\r
244                     throw new FMILException(getLastErrorMessage());\r
245 \r
246             } catch (UnsatisfiedLinkError err) {\r
247                 throw new FMILException(UNSATISFIED_LINK);\r
248             } catch (Exception e) {\r
249                 throw new FMILException(e.getMessage());\r
250             }\r
251         }\r
252     }\r
253 \r
254     private native int setStepLength_(int id, double step);\r
255 \r
256     /**\r
257      * Instantiates a simulation. \r
258      * <p>\r
259      * Make sure that an FMU is loaded first.\r
260      * @throws FMILException\r
261      */\r
262     public void instantiateSimulation() throws FMILException {\r
263         synchronized(syncObject) {\r
264 \r
265             try {\r
266 \r
267                 int ret = instantiateSimulation_(getModelIDNew()); \r
268                 if(ret == ERROR)\r
269                     throw new FMILException(getLastErrorMessage());\r
270 \r
271             } catch (UnsatisfiedLinkError err) {\r
272                 throw new FMILException(UNSATISFIED_LINK);\r
273             } catch (Exception e) {\r
274                 throw new FMILException(e.getMessage());\r
275             }\r
276         }\r
277     }\r
278 \r
279     private native int instantiateSimulation_(int id);\r
280 \r
281     \r
282     /**\r
283      * Initializes a simulation. \r
284      * <p>\r
285      * Make sure that simulation is instantiated first!\r
286      * @throws FMILException\r
287      */\r
288     public void initializeSimulation() throws FMILException {\r
289         synchronized(syncObject) {\r
290 \r
291             try {\r
292 \r
293                 int ret = initializeSimulation_(getModelIDNew()); \r
294                 if(ret == ERROR)\r
295                     throw new FMILException(getLastErrorMessage());\r
296 \r
297             } catch (UnsatisfiedLinkError err) {\r
298                 throw new FMILException(UNSATISFIED_LINK);\r
299             } catch (Exception e) {\r
300                 throw new FMILException(e.getMessage());\r
301             }\r
302         }\r
303     }\r
304 \r
305     private native int initializeSimulation_(int id);\r
306 \r
307     /**\r
308      * Subscribe a set of variables from a loaded simulation.\r
309      * <p>\r
310      * Make sure that an FMU is loaded first.\r
311      * @param variables Array of variables\r
312      * @throws FMILException\r
313      */\r
314     public void subscribe(int[] variables) throws FMILException {\r
315         synchronized(syncObject) {\r
316 \r
317             try {\r
318 \r
319                 int ret = subscribe_(getModelIDNew(), variables); \r
320                 if(ret == ERROR)\r
321                     throw new FMILException(getLastErrorMessage());\r
322 \r
323             } catch (UnsatisfiedLinkError err) {\r
324                 throw new FMILException(UNSATISFIED_LINK);\r
325             } catch (Exception e) {\r
326                 throw new FMILException(e.getMessage());\r
327             }\r
328         }\r
329     }\r
330 \r
331     private native int subscribe_(int id, int[] variables);\r
332 \r
333     /**\r
334      * Set a new (Real, double) value for a variable. If the variable is a \r
335      * parameter, the change is effective immediately.\r
336      *  \r
337      * @param name Variable\r
338      * @param value New (Real, double) value\r
339      * @throws FMILException\r
340      */\r
341     public void setRealValue(String name, double value) throws FMILException {\r
342         \r
343         synchronized(syncObject) {\r
344 \r
345             try {\r
346 \r
347                 int ret = setRealValue_(getModelIDNew(), variableMap.get(name), value); \r
348                 if(ret == ERROR)\r
349                     throw new FMILException(getLastErrorMessage());\r
350 \r
351             } catch (UnsatisfiedLinkError err) {\r
352                 throw new FMILException(UNSATISFIED_LINK);\r
353             } catch (Exception e) {\r
354                 throw new FMILException(e.getMessage());\r
355             }\r
356             \r
357         }\r
358         \r
359     }\r
360 \r
361     public void setRealValue(int variableReference, double value) throws FMILException {\r
362         \r
363         synchronized(syncObject) {\r
364 \r
365             try {\r
366 \r
367                 int ret = setRealValue_(getModelIDNew(), variableReference, value); \r
368                 if(ret == ERROR)\r
369                     throw new FMILException(getLastErrorMessage());\r
370 \r
371             } catch (UnsatisfiedLinkError err) {\r
372                 throw new FMILException(UNSATISFIED_LINK);\r
373             } catch (Exception e) {\r
374                 throw new FMILException(e.getMessage());\r
375             }\r
376             \r
377         }\r
378         \r
379     }\r
380 \r
381     private native int setRealValue_(int id, int variableReference, double value);\r
382 \r
383 //    /**\r
384 //     * Set a new (integer) value for a variable. If the variable is a \r
385 //     * parameter, the change is effective immediately.\r
386 //     *  \r
387 //     * @param name Variable\r
388 //     * @param value New (integer) value\r
389 //     * @throws FMILException\r
390 //     */\r
391 //    public void setIntegerValue(String name, int value) throws FMILException {\r
392 //        synchronized(syncObject) {\r
393 //\r
394 //            try {\r
395 //\r
396 //                int ret = setIntegerValue_(getModelID(), name, value); \r
397 //                if(ret == ERROR)\r
398 //                    throw new FMILException(getLastErrorMessage());\r
399 //\r
400 //            } catch (UnsatisfiedLinkError err) {\r
401 //                throw new FMILException(UNSATISFIED_LINK);\r
402 //            } catch (Exception e) {\r
403 //                throw new FMILException(e.getMessage());\r
404 //            }\r
405 //        }\r
406 //    }\r
407 //    private native int setIntegerValue_(String id, String name, int value);\r
408 //\r
409 //    /**\r
410 //     * Set a new (boolean) value for a variable. If the variable is a \r
411 //     * parameter, the change is effective immediately.\r
412 //     *  \r
413 //     * @param name Variable\r
414 //     * @param value New (boolean) value\r
415 //     * @throws FMILException\r
416 //     */\r
417 //    public void setBooleanValue(String name, boolean value) throws FMILException {\r
418 //        synchronized(syncObject) {\r
419 //\r
420 //            try {\r
421 //\r
422 //                int ret = setBooleanValue_(getModelID(), name, value); \r
423 //                if(ret == ERROR)\r
424 //                    throw new FMILException(getLastErrorMessage());\r
425 //\r
426 //            } catch (UnsatisfiedLinkError err) {\r
427 //                throw new FMILException(UNSATISFIED_LINK);\r
428 //            } catch (Exception e) {\r
429 //                throw new FMILException(e.getMessage());\r
430 //            }\r
431 //        }\r
432 //    }\r
433 //    private native int setBooleanValue_(String id, String name, boolean value);\r
434 //\r
435 //    public void setTime(double time) throws FMILException {\r
436 //        synchronized(syncObject) {\r
437 //\r
438 //            try {\r
439 //\r
440 //                int ret = setTime_(getModelID(), time); \r
441 //                if(ret == ERROR)\r
442 //                    throw new FMILException(getLastErrorMessage());\r
443 //\r
444 //            } catch (UnsatisfiedLinkError err) {\r
445 //                throw new FMILException(UNSATISFIED_LINK);\r
446 //            } catch (Exception e) {\r
447 //                throw new FMILException(e.getMessage());\r
448 //            }\r
449 //        }\r
450 //    }\r
451 //    private native int setTime_(String id, double time);\r
452 \r
453     /**\r
454      * Simulate one step forward. The step length can be set with\r
455      * setStepLength()\r
456      * \r
457      * @throws FMILException\r
458      */\r
459     public void simulateStep() throws FMILException {\r
460         synchronized(syncObject) {\r
461 \r
462             try {\r
463 \r
464                 int ret = simulateStep_(getModelIDNew()); \r
465                 if(ret == ERROR)\r
466                     throw new FMILException(getLastErrorMessage());\r
467 \r
468             } catch (UnsatisfiedLinkError err) {\r
469                 throw new FMILException(UNSATISFIED_LINK);\r
470             } catch (Exception e) {\r
471                 throw new FMILException(e.getMessage());\r
472             }\r
473         }\r
474     }\r
475     private native int simulateStep_(int id);\r
476 \r
477     /**\r
478      * Get an array containing the current values for subscribed variables. The\r
479      * values are in the same order as in the subscription.\r
480      * \r
481      * @param results An array the size of subscribed results\r
482      * @return\r
483      */\r
484     public double[] getSubscribedResults() throws FMILException {\r
485         synchronized(syncObject) {\r
486 \r
487             try {\r
488 \r
489                 double[] results = new double[subscription.size()];\r
490                 return getSubscribedResults_(getModelIDNew(), results);\r
491 \r
492             } catch (UnsatisfiedLinkError err) {\r
493                 throw new FMILException(UNSATISFIED_LINK);\r
494             } catch (Exception e) {\r
495                 throw new FMILException(e.getMessage());\r
496             }\r
497         }\r
498     }\r
499 \r
500     private native double[] getSubscribedResults_(int id, double[] results);\r
501     \r
502 \r
503     /**\r
504      * Unload FMU and the dll:s that it requires.\r
505      * <p>\r
506      * To be called after all FMU simulations are ended. \r
507      * If the fmu is loaded again / changed, call to loadFMUFile is sufficient. loadFMUFile \r
508      * releases the previous fmu.dll  \r
509      * \r
510      * @throws FMILException\r
511      */\r
512     public void unloadFMU() throws FMILException {\r
513         synchronized(syncObject) {\r
514 \r
515             try {\r
516 \r
517                 unlockFMUDirectory();\r
518                 if(fmuLoaded) {\r
519                     int ret = unloadFMU_(getModelIDNew()); \r
520                     if(ret == ERROR)\r
521                         throw new FMILException(getLastErrorMessage());\r
522                 }\r
523                 removeFMUDirectoryContents();\r
524 \r
525             } catch (UnsatisfiedLinkError err) {\r
526                 throw new FMILException(UNSATISFIED_LINK);\r
527             } catch (Exception e) {\r
528                 throw new FMILException(e.getMessage());\r
529             }\r
530         }\r
531     }\r
532     private native int unloadFMU_(int id);\r
533     \r
534 //    /**\r
535 //     * Checks if fmu has been initialized\r
536 //     * @return current simulation time\r
537 //     */\r
538 //    public boolean isInitialized() throws FMILException {\r
539 //        synchronized(syncObject) {\r
540 //            try {\r
541 //                return isInitialized_(getModelID());\r
542 //            } catch (UnsatisfiedLinkError err) {\r
543 //                throw new FMILException(UNSATISFIED_LINK);\r
544 //            } catch (Exception e) {\r
545 //                throw new FMILException(e.getMessage());\r
546 //            }\r
547 //        }\r
548 //    }\r
549 //\r
550 //    private native boolean isInitialized_(String id);\r
551 //\r
552     /**\r
553      * Get the current simulation time\r
554      * @return current simulation time\r
555      */\r
556     public double getTime() throws FMILException {\r
557         synchronized(syncObject) {\r
558 \r
559             try {\r
560 \r
561                 return getTime_(getModelIDNew());\r
562 \r
563             } catch (UnsatisfiedLinkError err) {\r
564                 throw new FMILException(UNSATISFIED_LINK);\r
565             } catch (Exception e) {\r
566                 throw new FMILException(e.getMessage());\r
567             }\r
568         }\r
569     }\r
570 \r
571     private native double getTime_(int id);\r
572 \r
573     /**\r
574      * Get all variables in a loaded model\r
575      * @return all variables in a loaded model\r
576      */\r
577     public String[] getAllVariables() throws FMILException {\r
578         synchronized(syncObject) {\r
579 \r
580             try {\r
581 \r
582                 if(variableNames == null) {\r
583                         variableNames = getAllVariables_(getModelIDNew());\r
584                 }\r
585                 return variableNames;\r
586 \r
587             } catch (UnsatisfiedLinkError err) {\r
588                 throw new FMILException(UNSATISFIED_LINK);\r
589             } catch (Exception e) {\r
590                 throw new FMILException(e.getMessage());\r
591             }\r
592         }\r
593     }\r
594 \r
595     private native String[] getAllVariables_(int id);\r
596 \r
597     public String[] getAllVariableDescriptions() throws FMILException {\r
598         synchronized(syncObject) {\r
599 \r
600             try {\r
601 \r
602                 if(variableDescriptions == null) {\r
603                         variableDescriptions = getAllVariableDescriptions_(getModelIDNew());\r
604                 }\r
605                 return variableDescriptions;\r
606 \r
607             } catch (UnsatisfiedLinkError err) {\r
608                 throw new FMILException(UNSATISFIED_LINK);\r
609             } catch (Exception e) {\r
610                 throw new FMILException(e.getMessage());\r
611             }\r
612         }\r
613     }\r
614 \r
615     private native String[] getAllVariableDescriptions_(int id);\r
616     \r
617     public String[] getAllVariableDeclaredTypes() throws FMILException {\r
618         synchronized(syncObject) {\r
619 \r
620             try {\r
621 \r
622                 if(variableDeclaredTypes == null) {\r
623                         variableDeclaredTypes = getAllVariableDeclaredTypes_(getModelIDNew());\r
624                 }\r
625                 return variableDeclaredTypes;\r
626 \r
627             } catch (UnsatisfiedLinkError err) {\r
628                 throw new FMILException(UNSATISFIED_LINK);\r
629             } catch (Exception e) {\r
630                 throw new FMILException(e.getMessage());\r
631             }\r
632         }\r
633     }\r
634 \r
635     private native String[] getAllVariableDeclaredTypes_(int id);\r
636 \r
637     public int[] getAllVariableReferences() throws FMILException {\r
638         synchronized(syncObject) {\r
639 \r
640             try {\r
641 \r
642                 if(variableReferences == null) {\r
643                         variableReferences = getAllVariableReferences_(getModelIDNew(), new int[variableNames.length]); \r
644                 }\r
645                 return variableReferences;\r
646 \r
647             } catch (UnsatisfiedLinkError err) {\r
648                 throw new FMILException(UNSATISFIED_LINK);\r
649             } catch (Exception e) {\r
650                 throw new FMILException(e.getMessage());\r
651             }\r
652         }\r
653     }\r
654 \r
655     private native int[] getAllVariableReferences_(int id, int[] array);\r
656 \r
657     public int[] getAllVariableTypes() throws FMILException {\r
658         synchronized(syncObject) {\r
659 \r
660             try {\r
661 \r
662                 if(variableTypes == null) {\r
663                         variableTypes = getAllVariableTypes_(getModelIDNew(), new int[variableNames.length]); \r
664                 }\r
665                 return variableTypes;\r
666 \r
667             } catch (UnsatisfiedLinkError err) {\r
668                 throw new FMILException(UNSATISFIED_LINK);\r
669             } catch (Exception e) {\r
670                 throw new FMILException(e.getMessage());\r
671             }\r
672         }\r
673     }\r
674 \r
675     private native int[] getAllVariableTypes_(int id, int[] array);\r
676 \r
677     public int[] getAllVariableCausalities() throws FMILException {\r
678         synchronized(syncObject) {\r
679 \r
680             try {\r
681 \r
682                 if(variableCausalities == null) {\r
683                         variableCausalities = getAllVariableCausalities_(getModelIDNew(), new int[variableNames.length]); \r
684                 }\r
685                 return variableCausalities;\r
686 \r
687             } catch (UnsatisfiedLinkError err) {\r
688                 throw new FMILException(UNSATISFIED_LINK);\r
689             } catch (Exception e) {\r
690                 throw new FMILException(e.getMessage());\r
691             }\r
692         }\r
693     }\r
694 \r
695     private native int[] getAllVariableCausalities_(int id, int[] array);\r
696 \r
697     public int[] getAllVariableVariabilities() throws FMILException {\r
698         synchronized(syncObject) {\r
699 \r
700             try {\r
701 \r
702                 if(variableVariabilities == null) {\r
703                         variableVariabilities = getAllVariableVariabilities_(getModelIDNew(), new int[variableNames.length]); \r
704                 }\r
705                 return variableVariabilities;\r
706 \r
707             } catch (UnsatisfiedLinkError err) {\r
708                 throw new FMILException(UNSATISFIED_LINK);\r
709             } catch (Exception e) {\r
710                 throw new FMILException(e.getMessage());\r
711             }\r
712         }\r
713     }\r
714 \r
715     private native int[] getAllVariableVariabilities_(int id, int[] array);\r
716 \r
717     /**\r
718      * Get all variables in a loaded model\r
719      * @return all variables in a loaded model\r
720      */\r
721     public String[] getAllDeclaredTypes() throws FMILException {\r
722         synchronized(syncObject) {\r
723 \r
724             try {\r
725 \r
726                 if(declaredTypes == null) {\r
727                         declaredTypes = getAllDeclaredTypes_(getModelIDNew());\r
728                 }\r
729                 return declaredTypes;\r
730 \r
731             } catch (UnsatisfiedLinkError err) {\r
732                 throw new FMILException(UNSATISFIED_LINK);\r
733             } catch (Exception e) {\r
734                 throw new FMILException(e.getMessage());\r
735             }\r
736         }\r
737     }\r
738 \r
739     private native String[] getAllDeclaredTypes_(int id);\r
740     \r
741     public String[] getAllDeclaredTypeDescriptions() throws FMILException {\r
742         synchronized(syncObject) {\r
743 \r
744             try {\r
745 \r
746                 if(declaredTypeDescriptions == null) {\r
747                         declaredTypeDescriptions = getAllDeclaredTypeDescriptions_(getModelIDNew());\r
748                 }\r
749                 return declaredTypeDescriptions;\r
750 \r
751             } catch (UnsatisfiedLinkError err) {\r
752                 throw new FMILException(UNSATISFIED_LINK);\r
753             } catch (Exception e) {\r
754                 throw new FMILException(e.getMessage());\r
755             }\r
756         }\r
757     }\r
758 \r
759     private native String[] getAllDeclaredTypeDescriptions_(int id);\r
760     \r
761     public String[] getAllDeclaredTypeQuantities() throws FMILException {\r
762         synchronized(syncObject) {\r
763 \r
764             try {\r
765 \r
766                 if(declaredTypeQuantities == null) {\r
767                         declaredTypeQuantities = getAllDeclaredTypeQuantities_(getModelIDNew());\r
768                 }\r
769                 return declaredTypeQuantities;\r
770 \r
771             } catch (UnsatisfiedLinkError err) {\r
772                 throw new FMILException(UNSATISFIED_LINK);\r
773             } catch (Exception e) {\r
774                 throw new FMILException(e.getMessage());\r
775             }\r
776         }\r
777     }\r
778 \r
779     private native String[] getAllDeclaredTypeQuantities_(int id);\r
780 \r
781     public String[] getAllDeclaredTypeUnits() throws FMILException {\r
782         synchronized(syncObject) {\r
783 \r
784             try {\r
785 \r
786                 if(declaredTypeUnits == null) {\r
787                         declaredTypeUnits = getAllDeclaredTypeUnits_(getModelIDNew());\r
788                 }\r
789                 return declaredTypeUnits;\r
790 \r
791             } catch (UnsatisfiedLinkError err) {\r
792                 throw new FMILException(UNSATISFIED_LINK);\r
793             } catch (Exception e) {\r
794                 throw new FMILException(e.getMessage());\r
795             }\r
796         }\r
797     }\r
798 \r
799     private native String[] getAllDeclaredTypeUnits_(int id);\r
800     \r
801     \r
802 //\r
803 //    /**\r
804 //     * Get all variables from model that match the filter (and time variable)\r
805 //     * \r
806 //     * @param regexp Regular expression filter\r
807 //     * @return An array of variable names that match regexp filter (and time-variable)\r
808 //     * @throws FMILException\r
809 //     */\r
810 //    public String[] filterVariables(String regexp) throws FMILException {       \r
811 //        synchronized(syncObject) {\r
812 //            try {\r
813 //\r
814 //                return filterVariables_(getModelID(), regexp + "|time");\r
815 //\r
816 //            } catch (UnsatisfiedLinkError err) {\r
817 //                throw new FMILException(UNSATISFIED_LINK);\r
818 //            } catch (Exception e) {\r
819 //                throw new FMILException(e.getMessage());\r
820 //            }\r
821 //        }\r
822 //    }\r
823 //\r
824 //    private native String[] filterVariables_(String id, String regexp);\r
825 //\r
826     /**\r
827      * Get the last error message\r
828      * @return Last error message\r
829      */\r
830     public String getLastErrorMessage() throws FMILException {\r
831         synchronized(syncObject) {\r
832 \r
833             try {\r
834 \r
835                 return "err";\r
836                 //return getLastErrorMessage_(getModelID());\r
837 \r
838             } catch (UnsatisfiedLinkError err) {\r
839                 throw new FMILException(UNSATISFIED_LINK);\r
840             } catch (Exception e) {\r
841                 throw new FMILException(e.getMessage());\r
842             }\r
843         }\r
844     }\r
845 //\r
846 //    private native String getLastErrorMessage_(String id);\r
847 \r
848     /**\r
849      * Get a real (double) value for variable\r
850      * @param name Name of the variable\r
851      * @return value\r
852      * @throws FMILException\r
853      */\r
854     public double getRealValue(String name) throws FMILException {\r
855         synchronized(syncObject) {\r
856 \r
857             try {\r
858                 // TODO: printtaa id ja name, jotta saadaan virheessä kiinni\r
859                 double result = getRealValue_(getModelIDNew(), variableMap.get(name));\r
860                 System.err.println("getRealValue " + name + " = " + result);\r
861                 return  result;\r
862             } catch (UnsatisfiedLinkError err) {\r
863                 throw new FMILException(UNSATISFIED_LINK);\r
864             } catch (Exception e) {\r
865                 throw new FMILException(e.getMessage());\r
866             }\r
867         }\r
868     }\r
869 \r
870     private native double getRealValue_(int id, int variableReference);\r
871 \r
872 //    /**\r
873 //     * Get a string value for variable\r
874 //     * @param name Name of the variable\r
875 //     * @return value\r
876 //     * @throws FMILException\r
877 //     */\r
878 //    public String getStringValue(String name) throws FMILException {\r
879 //        synchronized(syncObject) {\r
880 //\r
881 //            try {\r
882 //                return getStringValue_(getModelID(), name); \r
883 //            } catch (UnsatisfiedLinkError err) {\r
884 //                throw new FMILException(UNSATISFIED_LINK);\r
885 //            } catch (Exception e) {\r
886 //                throw new FMILException(e.getMessage());\r
887 //            }\r
888 //        }\r
889 //    }\r
890 //\r
891 //    private native String getStringValue_(String id, String name);\r
892 //\r
893 //    /**\r
894 //     * Get an integer value for variable\r
895 //     * @param name Name of the variable\r
896 //     * @return value\r
897 //     * @throws FMILException\r
898 //     */\r
899 //    public int getIntegerValue(String name) throws FMILException {\r
900 //        synchronized(syncObject) {\r
901 //\r
902 //            try {\r
903 //                return getIntegerValue_(getModelID(), name); \r
904 //            } catch (UnsatisfiedLinkError err) {\r
905 //                throw new FMILException(UNSATISFIED_LINK);\r
906 //            } catch (Exception e) {\r
907 //                throw new FMILException(e.getMessage());\r
908 //            }\r
909 //        }\r
910 //    }\r
911 //\r
912 //    private native int getIntegerValue_(String id, String name);\r
913 //\r
914 //    /**\r
915 //     * Get a real (double) value for variable\r
916 //     * @param name Name of the variable\r
917 //     * @return value\r
918 //     * @throws FMILException\r
919 //     */\r
920 //    public boolean getBooleanValue(String name) throws FMILException {\r
921 //        synchronized(syncObject) {\r
922 //\r
923 //            try {\r
924 //                return getBooleanValue_(getModelID(), name); \r
925 //            } catch (UnsatisfiedLinkError err) {\r
926 //                throw new FMILException(UNSATISFIED_LINK);\r
927 //            } catch (Exception e) {\r
928 //                throw new FMILException(e.getMessage());\r
929 //            }\r
930 //        }\r
931 //    }\r
932 //\r
933 //    private native boolean getBooleanValue_(String id, String name);\r
934 \r
935     private FileChannel channel; \r
936     private FileLock lock;\r
937 \r
938     @SuppressWarnings("resource")\r
939     private boolean lockFMUDirectory() {\r
940 \r
941         try {\r
942             // Get a file channel for the lock file\r
943             File lockFile = new File(TEMP_FMU_DIRECTORY, LOCK_FILE_NAME);\r
944             if(!lockFile.isFile())\r
945                 lockFile.createNewFile();\r
946 \r
947             channel = new RandomAccessFile(lockFile, "rw").getChannel();\r
948 \r
949             // Use the file channel to create a lock on the file.\r
950             // This method blocks until it can retrieve the lock.\r
951             lock = channel.lock();\r
952 \r
953             //          // Try acquiring the lock without blocking. This method returns\r
954             //          // null or throws an exception if the file is already locked.\r
955             //          try {\r
956             //              lock = channel.tryLock();\r
957             //          } catch (OverlappingFileLockException e) {\r
958             //              // File is already locked in this thread or virtual machine\r
959             //          }\r
960         } catch (IOException e) {\r
961             return false;\r
962         }\r
963 \r
964         return true;\r
965     }\r
966 \r
967     private boolean unlockFMUDirectory() {\r
968         try {\r
969             // Release the lock\r
970             if(lock != null)\r
971                 lock.release();\r
972 \r
973             // Close the file\r
974             if(channel != null)\r
975                 channel.close();\r
976         } catch (IOException e) {\r
977             return false;\r
978         }\r
979         return true;\r
980     }\r
981 \r
982     private boolean removeFMUDirectoryContents() {\r
983         // Remove contents\r
984         try {\r
985             File tempDir = new File(TEMP_FMU_DIRECTORY);\r
986             FileUtils.deleteAll(tempDir);\r
987             tempDir.delete();\r
988         } catch (IOException e) {\r
989             return false;\r
990         }\r
991         return true;\r
992     }\r
993 }\r