JIMS: plug extraction
[scilab.git] / scilab / modules / external_objects_java / src / cpp / ScilabJavaEnvironment.hxx
1 /*
2  * PIMS ( http://forge.scilab.org/index.php/p/pims ) - This file is part of PIMS
3  * Copyright (C) 2010 - Baozeng Ding
4  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 #ifndef __SCILABPYTHONENVIRNOMENT_HXX__
15 #define __SCILABPYTHONENVIRNOMENT_HXX__
16
17 #ifdef _MSC_VER
18 #define PATHSEPARATOR ";"
19 #else
20 #define PATHSEPARATOR ":"
21 #endif
22
23 #include "dynlib_external_objects_java_scilab.h"
24
25 #include <jni.h>
26
27 //#include "PythonVariablesScope.hxx"
28 #include "ScilabAbstractEnvironment.hxx"
29 #include "ScilabEnvironments.hxx"
30 #include "ScilabJavaException.hxx"
31 #include "ScilabJavaEnvironmentWrapper.hxx"
32 // #include "ScilabPythonInvokers.hxx"
33 #include "JavaOptionsHelper.hxx"
34 #include "ScilabStream.hxx"
35 //#include "ScilabPythonOStream.hxx"
36
37 #include <sstream>
38 #include <iostream>
39 #include <fstream>
40 #include <map>
41 #include <string>
42
43 #ifdef _MSC_VER
44 #include "strdup_windows.h"
45 #endif
46
47 // #if defined(PIMS_EXPORTS)
48 // #pragma message("defined(PIMS_EXPORTS)")
49 // #else
50 // #pragma message("Houston !")
51 // #endif
52 #define LOG_BUFFER_SIZE 4096
53
54 using namespace org_modules_external_objects;
55
56 namespace org_scilab_modules_external_objects_java
57 {
58
59 class EXTERNAL_OBJECTS_JAVA_SCILAB_IMPEXP ScilabJavaEnvironment : public ScilabAbstractEnvironment
60 {
61     static const std::string environmentName;
62     static int envId;
63     static ScilabJavaEnvironment * instance;
64     static bool usable;
65
66     //    PythonVariablesScope & scope;
67     bool traceEnabled;
68     bool isInit;
69     std::ofstream * file;
70     ScilabStream & scilabStream;
71     JavaOptionsHelper & helper;
72     ScilabGatewayOptions & gwOptions;
73     ScilabJavaEnvironmentWrapper & wrapper;
74
75 public :
76
77     ScilabJavaEnvironment();
78
79     ~ScilabJavaEnvironment();
80     /*
81         ScilabJavaTupleInvoker getTupleInvoker()
82         {
83             return ScilabJavaTupleInvoker(scope);
84         }
85
86         ScilabJavaDictionaryInvoker getDictionaryInvoker()
87         {
88             return ScilabJavaDictionaryInvoker(scope);
89         }
90
91         ScilabJavaListInvoker getListInvoker()
92         {
93             return ScilabJavaListInvoker(scope);
94         }
95
96         ScilabJavaSetInvoker getSetInvoker()
97         {
98             return ScilabJavaSetInvoker(scope);
99         }
100
101         ScilabJavaGetAttrInvoker getGetAttrInvoker()
102         {
103             return ScilabJavaGetAttrInvoker(scope);
104         }
105
106         ScilabJavaInvokeInvoker getInvokeInvoker()
107         {
108             return ScilabJavaInvokeInvoker(scope);
109         }
110
111         ScilabJavaBuiltinInvoker getBuiltinInvoker(const std::string & name)
112         {
113             return ScilabJavaBuiltinInvoker(scope, name);
114         }
115
116         ScilabJavaModuleInvoker getModuleInvoker(const std::string & name)
117         {
118             return ScilabJavaModuleInvoker(scope, name);
119             }*/
120
121     void Initialize();
122
123     void Finalize();
124
125     static int start();
126
127     static void finish();
128
129     static ScilabJavaEnvironment & getInstance()
130     {
131         return *instance;
132     }
133
134     JavaOptionsHelper & getOptionsHelper();
135
136     ScilabGatewayOptions & getGatewayOptions();
137
138     ScilabAbstractEnvironmentWrapper & getWrapper();
139
140     const std::string & getEnvironmentName();
141
142     int extract(int id, int * args, int argsSize);
143
144     void insert(int id, int * args, int argsSize);
145
146     void addNamedVariable(int id, const char * varName);
147
148     int getNamedVariable(const char * varName);
149
150     void evalString(const char ** code, int nbLines, ScilabStringStackAllocator * allocator);
151
152     void getEnvironmentInfos(const ScilabStringStackAllocator & allocator);
153
154     void garbagecollect();
155
156     void addtoclasspath(const char * path);
157
158     void getclasspath(const ScilabStringStackAllocator & allocator);
159
160     int createarray(char * className, int * dims, int len);
161
162     int loadclass(char * className, char * currentSciPath, bool isNamedVarCreated, bool allowReload);
163
164     void getrepresentation(int id, const ScilabStringStackAllocator & allocator);
165
166     std::string getrepresentation(int id);
167
168     bool isvalidobject(int id);
169
170     int newinstance(int id, int * args, int argsSize);
171
172     int operation(int idA, int idB, const OperatorsType type);
173
174     int * invoke(int id, const char * methodName, int * args, int argsSize);
175
176     void setfield(int id, const char * fieldName, int idarg);
177
178     int getfield(int id, const char * fieldName);
179
180     int getfieldtype(int id, const char * fieldName);
181
182     int getarrayelement(int id, int * index, int length);
183
184     void setarrayelement(int id, int * index, int length, int idArg);
185
186     int cast(int id, char * className);
187
188     int castwithid(int id, int classId);
189
190     void removeobject(int id);
191
192     void autoremoveobject(int id);
193
194     void getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator);
195
196     void getaccessiblefields(int id, const ScilabStringStackAllocator & allocator);
197
198     std::string getclassname(int id);
199
200     VariableType isunwrappable(int id);
201
202     int compilecode(char * className, char ** code, int size);
203
204     void enabletrace(const char * filename);
205
206     void disabletrace();
207
208     void writeLog(const std::string & fun, const std::string str, ...) const;
209
210     inline int getEnvId() const
211     {
212         return envId;
213     }
214
215     inline bool isTraceEnabled() const
216     {
217         return traceEnabled;
218     }
219
220     /*    static inline std::wstring getWString(PyObject * obj)
221           {
222             if (PyString_Check(obj))
223             {
224                 int len = PyString_GET_SIZE(obj);
225                 char * str = PyString_AsString(obj);
226
227                 return std::wstring(str, str + len);
228             }
229             else if (PyUnicode_Check(obj))
230             {
231                 return std::wstring(reinterpret_cast<const wchar_t *>(PyUnicode_AS_DATA(obj)));
232             }
233
234             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot convert in a wide string"));
235             } */
236
237 private:
238
239     //    static void initNumpy();
240
241     void getMethodResult(JavaVM * jvm_, const char * const methodName, int id, const ScilabStringStackAllocator & allocator);
242
243     // template <typename T, typename U, class V> void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator);
244     // template <typename T, typename U, class V> void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator);
245     // template <typename T, typename U, class V> void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator);
246
247
248     inline void getAccessibleFields(int id, const ScilabStringStackAllocator & allocator, const bool isField)
249     {
250
251         /*
252                 PyObject * obj = scope.getObject(id);
253                 if (!obj)
254                 {
255                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
256                 }
257
258                 PyObject * dir = PyObject_Dir(obj);
259                 if (!dir || PyList_Size(dir) == 0)
260                 {
261                     allocator.allocate(0, 0, static_cast<char **>(0));
262                     return;
263                 }
264
265                 int size = PyList_Size(dir);
266                 int j = 0;
267                 char ** arr = new char*[size];
268
269                 for (int i = 0; i < size; i++)
270                 {
271                     PyObject * fieldName = PyList_GetItem(dir, i);
272                     char * _field = PyString_AsString(fieldName);
273                     if (helper.getShowPrivate() || _field[0] != '_')
274                     {
275                         PyObject * field = PyObject_GetAttr(obj, fieldName);
276                         if (isField && !PyCallable_Check(field))
277                         {
278                             arr[j++] = _field;
279                         }
280                         else if (!isField && PyCallable_Check(field))
281                         {
282                             arr[j++] = _field;
283                         }
284                     }
285                 }
286
287                 allocator.allocate(j, 1, arr);
288                 delete[] arr;
289         */
290     }
291
292     // TODO => Ici
293     /*
294         static inline PyObject * createMultiList(const int * dims, const int len)
295         {
296             if (len == 0)
297             {
298                 return PyList_New(0);
299             }
300
301             if (len == 1)
302             {
303                 return PyList_New(dims[0]);
304             }
305
306             PyObject * list = PyList_New(dims[0]);
307             for (int i = 0; i < dims[0]; i++)
308             {
309                 PyList_SetItem(list, i, createMultiList(dims + 1, len - 1));
310             }
311
312             return list;
313         }
314     */
315
316     static inline std::vector<char *> breakInLines(const std::string & str)
317     {
318         std::vector<char *> buf;
319         std::size_t prev(0);
320         std::size_t pos = str.find_first_of("\n");
321         while (pos != std::string::npos)
322         {
323             buf.push_back(strdup(str.substr(prev, pos - prev).c_str()));
324             prev = pos + 1;
325             pos = str.find_first_of("\n", prev);
326         }
327         buf.push_back(strdup(str.substr(prev).c_str()));
328
329         std::vector<char *>::iterator last = buf.end();
330         for (std::vector<char *>::iterator i = buf.end() - 1; i >= buf.begin(); i--)
331         {
332             if (strlen(*i) == 0)
333             {
334                 last = i;
335                 free(*i);
336             }
337             else
338             {
339                 break;
340             }
341         }
342         buf.erase(last, buf.end());
343
344         return buf;
345     }
346
347     static inline const char * getOpNameFromType(const OperatorsType type)
348     {
349         switch (type)
350         {
351             case Transp :
352                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: \'"));
353             case Add :
354                 return "add";
355             case Sub :
356                 return "sub";
357             case Mul :
358                 return "mul";
359             case Div :
360                 return "div";
361             case Backslash :
362                 return "truediv";
363             case Pow :
364                 return "pow";
365             case DotMul :
366                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .*"));
367             case DotDiv :
368                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: ./"));
369             case DotBackslash :
370                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .\\"));
371             case DotMulDot :
372                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .*."));
373             case DotDivDot :
374                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: ./."));
375             case DotBackslashDot :
376                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .\\."));
377             case Eq :
378                 return "eq";
379             case Neq :
380                 return "ne";
381             case Or :
382                 return "or";
383             case And :
384                 return "and";
385             case DotPow :
386                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .^"));
387             case Not :
388                 return "not_";
389             case DotTransp :
390                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operator: .\'"));
391             case Lt :
392                 return "lt";
393             case Gt :
394                 return "gt";
395             case Leq :
396                 return "le";
397             case Geq :
398                 return "ge";
399         }
400
401         return "";
402     }
403 };
404
405 }
406
407 #endif // __SCILABJAVAENVIRONMENT_HXX__