124521fb6341f4be378837e2e9ca92cabf39a100
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / io / scicos / ScilabDirectHandler.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2011 - Scilab Enterprises - Clement DAVID
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 package org.scilab.modules.xcos.io.scicos;
17
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20 import java.util.concurrent.Semaphore;
21 import java.util.concurrent.TimeUnit;
22 import java.util.logging.Logger;
23
24 import org.scilab.modules.javasci.JavasciException;
25 import org.scilab.modules.javasci.Scilab;
26 import org.scilab.modules.types.ScilabMList;
27 import org.scilab.modules.types.ScilabString;
28 import org.scilab.modules.types.ScilabType;
29
30 /**
31  * Scilab data direct access.
32  */
33 public class ScilabDirectHandler implements Handler {
34     /**
35      * Context Scilab variable name
36      */
37     public static final String CONTEXT = "context";
38     /**
39      * Diagram Scilab variable name
40      */
41     public static final String SCS_M = "scs_m";
42     /**
43      * Block Scilab variable name
44      */
45     public static final String BLK = "blk";
46
47     private static final Logger LOG = Logger.getLogger(ScilabDirectHandler.class.getPackage().getName());
48     private static final ScilabDirectHandler INSTANCE = new ScilabDirectHandler();
49
50     private final Semaphore lock = new Semaphore(1, true);
51
52     private ScilabDirectHandler() {
53     }
54
55     /*
56      * Lock management to avoid multiple actions
57      */
58
59     /**
60      * Get the current instance of a ScilabDirectHandler.
61      *
62      * Please note that after calling {@link #acquire()} and performing action,
63      * you should release the instance using {@link #release()}.
64      *
65      * <p>
66      * It is recommended practice to <em>always</em> immediately follow a call
67      * to {@code getInstance()} with a {@code try} block, most typically in a
68      * before/after construction such as:
69      *
70      * <pre>
71      * class X {
72      *
73      *     // ...
74      *
75      *     public void m() {
76      *         final ScilabDirectHandler handler = ScilabDirectHandler.getInstance();
77      *         try {
78      *             // ... method body
79      *         } finally {
80      *             handler.release();
81      *         }
82      *     }
83      * }
84      * </pre>
85      *
86      * @see #release()
87      * @return the instance or null if another operation is in progress
88      */
89     public static ScilabDirectHandler acquire() {
90         LOG.finest("lock request");
91
92         try {
93             final boolean status = INSTANCE.lock.tryAcquire(0, TimeUnit.SECONDS);
94             if (!status) {
95                 return null;
96             }
97         } catch (InterruptedException e) {
98             e.printStackTrace();
99         }
100
101         LOG.finest("lock acquired");
102
103         return INSTANCE;
104     }
105
106     /**
107      * Release the instance
108      */
109     public void release() {
110         LOG.finest("lock release");
111
112         INSTANCE.lock.release();
113     }
114
115     /*
116      * Handler implementation
117      */
118
119     @Override
120     public synchronized Map<String, String> readContext() {
121         LOG.entering("ScilabDirectHandler", "readContext");
122         final ScilabMList list;
123         final Map<String, String> result = new LinkedHashMap<String, String>();
124
125         final ScilabType data;
126         try {
127             data = Scilab.getInCurrentScilabSession(CONTEXT);
128         } catch (JavasciException e) {
129             throw new RuntimeException(e);
130         }
131         if (data instanceof ScilabMList) {
132             list = (ScilabMList) data;
133             LOG.finer("data available");
134         } else {
135             list = new ScilabMList();
136             LOG.finer("data unavailable");
137         }
138
139         // We are starting at 2 because a struct is composed of
140         // - the fields names (ScilabString)
141         // - the dimension
142         // - variables values...
143         for (int index = 2; index < list.size(); index++) {
144             String key = ((ScilabString) list.get(0)).getData()[0][index];
145             String value = list.get(index).toString();
146
147             result.put(key, value);
148         }
149
150         LOG.exiting("ScilabDirectHandler", "readContext");
151         return result;
152     }
153
154     @Override
155     public void writeContext(final String[] context) {
156         LOG.entering("ScilabDirectHandler", "writeContext");
157
158         try {
159             Scilab.putInCurrentScilabSession(CONTEXT, new ScilabString(context));
160         } catch (JavasciException e) {
161             throw new RuntimeException(e);
162         }
163
164         LOG.exiting("ScilabDirectHandler", "writeContext");
165     }
166 }