8d1838e18fbb40bee1f0c390ff40bd5d5bb6d041
[scilab.git] / scilab / modules / external_objects_java / src / cpp / ScilabJavaEnvironment.cpp
1 /*
2  * PIMS ( http://forge.scilab.org/index.php/p/pims ) - This file is part of PIMS
3  * Copyright (C) 2013 - Scilab Enterprises - Sylvestre LEDRU
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifdef _MSC_VER
14 #include "windows.h"
15 #endif
16
17 #include <jni.h>
18
19 #include "ScilabJavaEnvironment.hxx"
20 #include "JavaOptionsHelper.hxx"
21 #include "ScilabClassLoader.hxx"
22 #include "ScilabJavaClass.hxx"
23 #include "ScilabJavaObject.hxx"
24 #include "ScilabJavaArray.hxx"
25 #include "ScilabJavaCompiler.hxx"
26 #include "NoMoreScilabMemoryException.hxx"
27
28 //#include "ScilabJavaObjectHelper.hxx"
29 extern "C" {
30 #include "getScilabJavaVM.h"
31 #include "tmpdir.h"
32 }
33
34 namespace org_scilab_modules_external_objects_java
35 {
36
37 const std::string ScilabJavaEnvironment::environmentName = "Java Environment";
38 int ScilabJavaEnvironment::envId = -1;
39 ScilabJavaEnvironment * ScilabJavaEnvironment::instance = 0;
40 bool ScilabJavaEnvironment::usable = true;
41
42 ScilabJavaEnvironment::ScilabJavaEnvironment() :
43     helper(*new JavaOptionsHelper()),
44     gwOptions(*new ScilabGatewayOptions()),
45     wrapper(*new ScilabJavaEnvironmentWrapper(helper)),
46     traceEnabled(false),
47     isInit(false),
48     scilabStream(*new ScilabStream()),
49     file(0) { }
50
51 //    ScilabJavaEnvironment::ScilabJavaEnvironment() {}
52 ScilabJavaEnvironment::~ScilabJavaEnvironment()
53 {
54     //    delete &scope;
55     delete &helper;
56     delete &gwOptions;
57     delete &wrapper;
58
59     if (file)
60     {
61         file->flush();
62         file->close();
63         delete file;
64         file = 0;
65     }
66 }
67
68 int ScilabJavaEnvironment::start()
69 {
70     /*    if (!usable)
71         {
72             throw ScilabJavaException(__LINE__, __FILE__, gettext("Due to Java interpreter limitations, Scilab must be restarted"));
73             }*/
74
75     if (envId == -1)
76     {
77         instance = new ScilabJavaEnvironment();
78         envId = ScilabEnvironments::registerScilabEnvironment(instance);
79         instance->Initialize();
80         /*        ScilabJavaOStream::initJavaStreams();
81                 ScilabJavaOStream::setStdOutStream(&instance->scilabStream);
82                 ScilabJavaOStream::setStdErrStream(&instance->scilabStream);*/
83         instance->helper.setUseLastName(true);
84         instance->helper.setNewAllowed(true);
85         instance->enabletrace((std::string(getTMPDIR()) + std::string("/eo_java.log")).c_str());
86     }
87
88     return envId;
89 }
90
91 void ScilabJavaEnvironment::finish()
92 {
93     if (envId != -1)
94     {
95         ScilabEnvironments::unregisterScilabEnvironment(envId);
96         envId = -1;
97         delete instance;
98         instance = 0;
99         instance->Finalize();
100         usable = false;
101     }
102 }
103
104 void ScilabJavaEnvironment::Initialize()
105 {
106     if (!isInit)
107     {
108         isInit = true;
109         // No need to init the Java VM. Scilab is already using it
110     }
111 }
112
113 void ScilabJavaEnvironment::Finalize()
114 {
115     // Scilab cannot kill the Java VM. It would probably crash the application
116 }
117
118 JavaOptionsHelper & ScilabJavaEnvironment::getOptionsHelper()
119 {
120     return helper;
121 }
122
123 ScilabGatewayOptions & ScilabJavaEnvironment::getGatewayOptions()
124 {
125     return gwOptions;
126 }
127
128 ScilabAbstractEnvironmentWrapper & ScilabJavaEnvironment::getWrapper()
129 {
130     return wrapper;
131 }
132
133 const std::string & ScilabJavaEnvironment::getEnvironmentName()
134 {
135     return environmentName;
136 }
137
138 void ScilabJavaEnvironment::getEnvironmentInfos(const ScilabStringStackAllocator & allocator)
139 {
140
141     writeLog("getEnvironmentInfos", "Get information");
142
143     /*
144         std::vector<char *> version = breakInLines(std::string(Py_GetVersion()));
145         std::vector<char *> platform = breakInLines(std::string(Py_GetPlatform()));
146         std::vector<char *> copyright = breakInLines(std::string(Py_GetCopyright()));
147         std::vector<char *> compiler = breakInLines(std::string(Py_GetCompiler()));
148         std::vector<char *> buildInfo = breakInLines(std::string(Py_GetBuildInfo()));
149
150         int nbRows = version.size() + platform.size() + copyright.size() + compiler.size() + buildInfo.size();
151
152         std::vector<char *> all(nbRows, const_cast<char* >(""));
153         all[0] = const_cast<char* >("Version");
154         all[version.size()] = const_cast<char* >("Platform");
155         all[version.size() + platform.size()] = const_cast<char* >("Copyright");
156         all[version.size() + platform.size() + copyright.size()] = const_cast<char* >("Compiler");
157         all[version.size() + platform.size() + copyright.size() + compiler.size()] = const_cast<char* >("Build info");
158
159         all.insert(all.end(), version.begin(), version.end());
160         all.insert(all.end(), platform.begin(), platform.end());
161         all.insert(all.end(), copyright.begin(), copyright.end());
162         all.insert(all.end(), compiler.begin(), compiler.end());
163         all.insert(all.end(), buildInfo.begin(), buildInfo.end());
164
165         allocator.allocate(nbRows, 2, &(all[0]));
166     */
167 }
168
169 int ScilabJavaEnvironment::extract(int id, int * args, int argsSize)
170 {
171     if (traceEnabled)
172     {
173         std::ostringstream os;
174         for (int i = 0; i < argsSize - 1; i++)
175         {
176             os << args[i] << ", ";
177         }
178         os << args[argsSize - 1];
179         os.flush();
180
181         writeLog("extract", "Extraction on object %d with arguments: %s.", id, os.str().c_str());
182     }
183
184     /*    PyObject * obj = scope.getObject(id);
185         if (!obj)
186         {
187             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
188         }
189
190         if (PyDict_Check(obj))
191         {
192             if (argsSize != 1)
193             {
194                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot extract more than one element from a dictionary"));
195             }
196
197             PyObject * key = scope.getObject(*args);
198             if (!obj)
199             {
200                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
201             }
202
203             if (!PyDict_Contains(obj, key))
204             {
205                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key"));
206             }
207
208             PyObject * value = PyDict_GetItem(obj, key);
209         Py_INCREF(value);
210
211             int ret = scope.addObject(value);
212             writeLog("extract", "returned id: %d.", ret);
213
214             return ret;
215             }
216     */
217
218     throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot extract from Java object"));
219 }
220
221 void ScilabJavaEnvironment::insert(int id, int * args, int argsSize)
222 {
223     if (traceEnabled)
224     {
225         std::ostringstream os;
226         for (int i = 0; i < argsSize - 1; i++)
227         {
228             os << args[i] << ", ";
229         }
230         os << args[argsSize - 1];
231         os.flush();
232
233         writeLog("insert", "Insertion on object %d with arguments: %s.", id, os.str().c_str());
234     }
235     /*
236         PyObject * obj = scope.getObject(id);
237         if (!obj)
238         {
239             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
240         }
241
242         if (argsSize != 2)
243         {
244             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert more than one element in a dictionary"));
245         }
246
247         PyObject * key = scope.getObject(args[0]);
248         if (!obj)
249         {
250             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
251         }
252
253         PyObject * value = scope.getObject(args[1]);
254         if (!value)
255         {
256             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid value object"));
257         }
258
259         if (PyDict_Check(obj))
260         {
261             PyDict_SetItem(obj, key, value);
262
263             writeLog("insert", "success.");
264
265             return;
266         }
267         else
268         {
269             if (!PyString_Check(key))
270             {
271                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object: A string expected"));
272             }
273
274             int ret = PyObject_SetAttr(obj, key, value);
275             if (ret == -1)
276             {
277                 if (PyErr_Occurred())
278                 {
279                     PyObject *type, *value, *traceback;
280                     PyErr_Fetch(&type, &value, &traceback);
281                     PyErr_NormalizeException(&type, &value, &traceback);
282                     PyErr_Clear();
283
284                     throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
285                 }
286                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the attribute."));
287             }
288
289             writeLog("insert", "success.");
290
291             return;
292         }
293     */
294     throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert in Java object"));
295 }
296
297 void ScilabJavaEnvironment::garbagecollect() { }
298
299 void ScilabJavaEnvironment::addtoclasspath(const char * path)
300 {
301     writeLog("addtoclasspath", "Add the path %s to syspath", path);
302     /*
303         PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
304         PyObject * _path = PyString_FromString(path);
305         PyList_Append(syspath, _path);
306     */
307 }
308
309 void ScilabJavaEnvironment::getclasspath(const ScilabStringStackAllocator & allocator)
310 {
311     writeLog("getclasspath", "Get syspath");
312     /*
313         PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
314         int size = PyList_Size(syspath);
315         char ** arr = new char*[size];
316
317         for (int i = 0; i < size; i++)
318         {
319             PyObject * item = PyList_GetItem(syspath, i);
320             arr[i] = strdup(PyString_AsString(item));
321         }
322
323         allocator.allocate(size, 1, arr);
324         for (int i = 0; i < size; i++)
325         {
326             free(arr[i]);
327         }
328         delete arr;
329     */
330 }
331
332 void ScilabJavaEnvironment::addNamedVariable(int id, const char * varName)
333 {
334     writeLog("addNamedVariable", "Associate the variable named %s with object with id %d.", varName, id);
335
336     /*    PyObject * obj = scope.getObject(id);
337         if (!obj)
338         {
339             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
340         }
341
342         PyObject * _main_ = PyImport_AddModule("__main__");
343         if (!_main_)
344         {
345             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
346         }
347
348         if (PyObject_SetAttrString(_main_, varName, obj) == -1)
349         {
350             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the variable named %s."), varName);
351         }
352     */
353 }
354
355 int ScilabJavaEnvironment::getNamedVariable(const char * varName)
356 {
357     writeLog("getNamedVariable", "Get the variable named %s.", varName);
358     /*
359         PyObject * _main_ = PyImport_AddModule("__main__");
360         if (!_main_)
361         {
362             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
363         }
364
365         PyObject * var = PyObject_GetAttrString(_main_, varName);
366         if (!var)
367         {
368             if (PyErr_Occurred())
369             {
370                 PyObject *type, *value, *traceback;
371                 PyErr_Fetch(&type, &value, &traceback);
372                 PyErr_NormalizeException(&type, &value, &traceback);
373                 PyErr_Clear();
374
375                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot get the variable value"));
376             }
377             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the variable value"));
378         }
379
380         int ret = scope.addObject(var);
381
382         writeLog("getNamedVariable", "returned id %d.", ret);
383
384         return ret;
385     */
386     return 0;
387 }
388
389 void ScilabJavaEnvironment::evalString(const char ** code, int nbLines, ScilabStringStackAllocator * allocator)
390 {
391     writeLog("evalString", "Evaluate code: %s...(truncated)", *code);
392     /*
393         std::ostringstream os;
394         for (int i = 0; i < nbLines; i++)
395         {
396             os << code[i] << std::endl;
397         }
398         os.flush();
399
400         PyObject * _main_ = PyImport_AddModule("__main__");
401         if (!_main_)
402         {
403             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
404         }
405
406         std::ostream * old;
407         std::ostringstream os1;
408         if (allocator)
409         {
410             old = ScilabJavaOStream::setStdOutStream(&os1);
411         }
412
413         PyObject * dict = PyModule_GetDict(_main_);
414         PyObject * ret = PyRun_StringFlags(os.str().c_str(), Py_file_input, dict, dict, 0);
415
416         if (allocator)
417         {
418             ScilabJavaOStream::setStdOutStream(old);
419         }
420
421         if (!ret)
422         {
423             if (PyErr_Occurred())
424             {
425                 PyObject *type, *value, *traceback;
426                 PyErr_Fetch(&type, &value, &traceback);
427                 PyErr_NormalizeException(&type, &value, &traceback);
428                 PyErr_Clear();
429
430                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
431             }
432             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code"));
433         }
434
435         if (allocator)
436         {
437             std::vector<char *> buf = breakInLines(os1.str());
438             allocator->allocate(buf.size(), 1, &(buf[0]));
439             for (std::vector<char *>::iterator i = buf.begin(); i != buf.end(); i++)
440             {
441                 free(*i);
442             }
443         }
444
445         Py_DECREF(ret);
446     */
447 }
448
449 int ScilabJavaEnvironment::createarray(char * className, int * dims, int len)
450 {
451     writeLog("createarray", "Create array %s of size (%d, %d).", className, dims, len);
452     JavaVM *vm = getScilabJavaVM();
453     return ScilabJavaArray::newInstance(vm, className, dims, len);
454 }
455
456 int ScilabJavaEnvironment::loadclass(char * className, char * currentSciPath, bool isNamedVarCreated, bool allowReload)
457 {
458     writeLog("loadclass", "Load the module %s and allowReload is set to %s", className, allowReload ? "true" : "false");
459     JavaVM *vm = getScilabJavaVM();
460     return ScilabClassLoader::loadJavaClass(vm, className, allowReload);
461 }
462
463 void ScilabJavaEnvironment::getrepresentation(int id, const ScilabStringStackAllocator & allocator)
464 {
465     writeLog("getrepresentation", "Get the representation of object %d.", id);
466     JavaVM *vm = getScilabJavaVM();
467     char *str = ScilabJavaObject::getRepresentation(vm, id);
468     allocator.allocate(1, 1, &str);
469 }
470
471 std::string ScilabJavaEnvironment::getrepresentation(int id)
472 {
473     writeLog("getrepresentation", "Get the representation of object %d.", id);
474     JavaVM *vm = getScilabJavaVM();
475     return std::string(ScilabJavaObject::getRepresentation(vm, id));
476 }
477
478 /* Used by jexists */
479 bool ScilabJavaEnvironment::isvalidobject(int id)
480 {
481
482     JavaVM *vm = getScilabJavaVM();
483     bool ret = ScilabJavaObject::isValidJavaObject(vm, id);
484     writeLog("isvalidobject", "Test the validity of object %d which is%s valid.", id, ret ? "" : " not");
485     return ret;
486 }
487
488 int ScilabJavaEnvironment::newinstance(int id, int * args, int argsSize)
489 {
490     JavaVM *vm = getScilabJavaVM();
491     return ScilabJavaClass::newInstance(vm, id, args, argsSize);
492 }
493
494 int ScilabJavaEnvironment::operation(int idA, int idB, const OperatorsType type)
495 {
496     writeLog("operation", "Evalute an operation (%d) with objects with id %d and %d.", (int)type, idA, idB);
497     /*
498         const char * opName = getOpNameFromType(type);
499
500         PyObject * _operator_ = PyImport_AddModule("operator");
501         if (!_operator_)
502         {
503             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the operator module."));
504         }
505
506         PyObject * objA = scope.getObject(idA);
507         if (!objA)
508         {
509             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idA);
510         }
511
512         PyObject * objB = 0;
513         if (idB != -1)
514         {
515             // Binary op
516             objB = scope.getObject(idB);
517             if (!objB)
518             {
519                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idB);
520             }
521         }
522
523         PyObject * _op_ = PyObject_GetAttrString(_operator_, opName);
524
525         PyObject * pArgs = PyTuple_New(objB ? 2 : 1);
526         Py_INCREF(objA);
527         PyTuple_SetItem(pArgs, 0, objA);
528
529         if (objB)
530         {
531             Py_INCREF(objB);
532             PyTuple_SetItem(pArgs, 1, objB);
533         }
534
535         PyObject * result = PyObject_Call(_op_, pArgs, 0);
536         Py_DECREF(pArgs);
537         Py_DECREF(_op_);
538
539         if (!result)
540         {
541             if (PyErr_Occurred())
542             {
543                 PyObject * type, * value, * traceback;
544                 PyErr_Fetch(&type, &value, &traceback);
545                 PyErr_NormalizeException(&type, &value, &traceback);
546                 PyErr_Clear();
547
548                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Unable to make the operation (%s)."), opName);
549             }
550             throw ScilabJavaException(__LINE__, __FILE__, gettext("Unable to make the operation (%s)."), opName);
551         }
552
553         int ret = scope.addObject(result);
554
555         writeLog("operation", "returned id %d.", ret);
556
557         return ret;
558     */
559     return 0;
560 }
561
562 int * ScilabJavaEnvironment::invoke(int id, const char * methodName, int * args, int argsSize)
563 {
564     if (traceEnabled)
565     {
566         std::ostringstream os;
567         for (int i = 0; i < argsSize - 1; i++)
568         {
569             os << args[i] << ", ";
570         }
571         os << args[argsSize - 1];
572         os.flush();
573
574         writeLog("invoke", "Invoke the method %s on object %d with arguments: %s.", methodName, id, os.str().c_str());
575     }
576
577     JavaVM *vm = getScilabJavaVM();
578     int * invokedId = new int[2];
579     invokedId[0] = 1 ; //1 object returned
580     invokedId[1] = ScilabJavaObject::invoke(vm, id, methodName, args, argsSize);
581     return invokedId;
582 }
583
584 void ScilabJavaEnvironment::setfield(int id, const char * fieldName, int idarg)
585 {
586     writeLog("setfield", "Set the field named %s with value id %d on object with id %d.", fieldName, idarg, id);
587
588     if (*fieldName == '\0')
589     {
590         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
591     }
592
593     try
594     {
595         JavaVM * vm = getScilabJavaVM();
596         ScilabJavaObject::setField(vm, id, fieldName, idarg);
597     }
598     catch (const GiwsException::JniCallMethodException & e)
599     {
600         throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the field: %s"), fieldName);
601     }
602
603     writeLog("setfield", "Value successfully set.");
604 }
605
606 int ScilabJavaEnvironment::getfield(int id, const char * fieldName)
607 {
608     writeLog("getfield", "Get the field named %s on object with id %d.", fieldName, id);
609
610     if (*fieldName == '\0')
611     {
612         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
613     }
614
615     JavaVM * vm = getScilabJavaVM();
616     int ret = ScilabJavaObject::getField(vm, id, fieldName);
617
618     return ret;
619 }
620
621 int ScilabJavaEnvironment::getfieldtype(int id, const char * fieldName)
622 {
623     writeLog("getfieldtype", "Get the type of the field %s on object with id %d.", fieldName, id);
624
625     if ((!helper.getShowPrivate() && *fieldName == '_') || *fieldName == '\0')
626     {
627         writeLog("getfieldtype", "Return NONE.");
628         return -1;
629     }
630     /*
631         PyObject * obj = scope.getObject(id);
632         if (!obj)
633         {
634             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
635         }
636
637         if (!PyObject_HasAttrString(obj, fieldName))
638         {
639             writeLog("getfieldtype", "Return NONE.");
640             return -1;
641         }
642
643         PyObject * field = PyObject_GetAttrString(obj, fieldName);
644         if (!field)
645         {
646             writeLog("getfieldtype", "Return NONE.");
647             return -1;
648         }
649
650         if (PyCallable_Check(field))
651         {
652             Py_DECREF(field);
653             writeLog("getfieldtype", "Return METHOD.");
654             return 0;
655         }
656         else
657         {
658             Py_DECREF(field);
659             writeLog("getfieldtype", "Return FIELD.");
660             return 1;
661         }
662     */
663     return 0;
664 }
665
666 int ScilabJavaEnvironment::getarrayelement(int id, int * index, int length)
667 {
668     if (traceEnabled)
669     {
670         std::ostringstream os;
671         for (int i = 0; i < length - 1; i++)
672         {
673             os << index[i] << ", ";
674         }
675         os << index[length - 1];
676         os.flush();
677
678         writeLog("getarrayelement", "Get element from array with id %d and with index: %s.", id, os.str().c_str());
679     }
680     /*
681         PyObject * obj = scope.getObject(id);
682         if (!obj)
683         {
684             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
685         }
686
687         if (!PyList_Check(obj) && !PyArray_Check(obj))
688         {
689             throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list or an array"));
690         }
691
692         if (length == 0)
693         {
694             return 0;
695         }
696
697         if (PyList_Check(obj))
698         {
699             for (int i = 0; i < length; i++)
700             {
701                 if (index[i] < 0 || index[i] >= PyList_Size(obj))
702                 {
703                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index"));
704                 }
705                 obj = PyList_GetItem(obj, index[i]);
706                 if (i != length - 1 && !PyList_Check(obj))
707                 {
708                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list"));
709                 }
710             }
711         Py_INCREF(obj);
712         }
713         else if (PyArray_Check(obj))
714         {
715             PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
716             npy_intp * ind = reinterpret_cast<npy_intp *>(index);
717
718             if (length != PyArray_NDIM(arr))
719             {
720                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
721             }
722
723             npy_intp * dims = PyArray_DIMS(arr);
724
725             if (sizeof(int) != sizeof(npy_intp))
726             {
727                 ind = new npy_intp[length];
728                 for (int i = 0; i < length; i++)
729                 {
730                     if (index[i] < 0 || index[i] >= dims[i])
731                     {
732                         delete[] ind;
733                         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
734                     }
735
736                     ind[i] = static_cast<npy_intp>(index[i]);
737                 }
738             }
739
740             obj = PyArray_GETITEM(arr, PyArray_GetPtr(arr, ind));
741
742             if (sizeof(int) != sizeof(npy_intp))
743             {
744                 delete[] ind;
745             }
746         }
747         else
748         {
749             throw ScilabJavaException(__LINE__, __FILE__, gettext("Must be a list or a Numpy array"));
750         }
751
752         int ret = scope.addObject(obj);
753         writeLog("getarrayelement", "returned id %d.", ret);
754
755         return ret;
756     */
757     return 0;
758 }
759
760 void ScilabJavaEnvironment::setarrayelement(int id, int * index, int length, int idArg)
761 {
762     if (traceEnabled)
763     {
764         std::ostringstream os;
765         for (int i = 0; i < length - 1; i++)
766         {
767             os << index[i] << ", ";
768         }
769         os << index[length - 1];
770         os.flush();
771
772         writeLog("setarrayelement", "Set element with id %d in array with id %d and with index: %s.", idArg, id, os.str().c_str());
773     }
774     /*
775         PyObject * obj = scope.getObject(id);
776         if (!obj)
777         {
778             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
779         }
780
781         PyObject * value = scope.getObject(idArg);
782         if (!value)
783         {
784             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
785         }
786
787         if (PyList_Check(obj))
788         {
789             if (length == 0)
790             {
791                 return;
792             }
793
794             for (int i = 0; i < length - 1; i++)
795             {
796                 if (index[i] < 0 || index[i] >= PyList_Size(obj))
797                 {
798                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
799                 }
800                 obj = PyList_GetItem(obj, index[i]);
801                 if (!PyList_Check(obj))
802                 {
803                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list at position %d"), index[i]);
804                 }
805             }
806
807             Py_INCREF(value);
808             PyList_SetItem(obj, index[length - 1], value);
809         }
810         else if (PyArray_Check(obj))
811         {
812             PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
813             npy_intp * ind = reinterpret_cast<npy_intp *>(index);
814
815             if (length != PyArray_NDIM(arr))
816             {
817                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
818             }
819
820             npy_intp * dims = PyArray_DIMS(arr);
821
822             if (sizeof(int) != sizeof(npy_intp))
823             {
824                 ind = new npy_intp[length];
825                 for (int i = 0; i < length; i++)
826                 {
827                     if (index[i] < 0 || index[i] >= dims[i])
828                     {
829                         delete[] ind;
830                         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i);
831                     }
832
833                     ind[i] = static_cast<npy_intp>(index[i]);
834                 }
835             }
836
837             int ret = PyArray_SETITEM(arr, PyArray_GetPtr(arr, ind), value);
838
839             if (sizeof(int) != sizeof(npy_intp))
840             {
841                 delete[] ind;
842             }
843
844             if (ret == -1)
845             {
846                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the value in the array"));
847             }
848         }
849     */
850     writeLog("setarrayelement", "Successfully set");
851 }
852
853 int ScilabJavaEnvironment::cast(int id, char * className)
854 {
855     JavaVM *vm = getScilabJavaVM();
856     return ScilabJavaObject::javaCast(vm, id, className);
857 }
858
859 int ScilabJavaEnvironment::castwithid(int id, int classId)
860 {
861     JavaVM *vm = getScilabJavaVM();
862     return ScilabJavaObject::javaCast(vm, id, classId);
863 }
864
865 void ScilabJavaEnvironment::removeobject(int id)
866 {
867     writeLog("removeobject", "Remove object with id %d.", id);
868     //    scope.removeObject(id);
869     //    ScilabAutoCleaner::unregisterVariable(envId, id);
870 }
871
872 void ScilabJavaEnvironment::autoremoveobject(int id)
873 {
874     //    scope.removeObject(id);
875 }
876
877 void ScilabJavaEnvironment::getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator)
878 {
879     writeLog("getaccessiblemethods", "Get accessible methods on object with id %d.", id);
880     JavaVM *vm = getScilabJavaVM();
881     getMethodResult(vm, "getAccessibleMethods", id, allocator);
882 }
883
884 void ScilabJavaEnvironment::getaccessiblefields(int id, const ScilabStringStackAllocator & allocator)
885 {
886     writeLog("getaccessiblefields", "Get accessible fields on object with id %d.", id);
887     JavaVM *vm = getScilabJavaVM();
888     getMethodResult(vm, "getAccessibleFields", id, allocator);
889     getAccessibleFields(id, allocator, true);
890 }
891
892 std::string ScilabJavaEnvironment::getclassname(int id)
893 {
894     writeLog("getclassname", "Get the class name of object with id %d.", id);
895     JavaVM *vm = getScilabJavaVM();
896     return std::string(ScilabJavaObject::getClassName(vm, id));
897 }
898
899 VariableType ScilabJavaEnvironment::isunwrappable(int id)
900 {
901     writeLog("isunwrappable", "Test if the object with id %d is unwrappable.", id);
902     return wrapper.isunwrappable(id);
903 }
904
905 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
906 {
907     writeLog("compilecode", "Compile the code %s...", *code);
908
909     std::ostringstream os;
910     for (int i = 0; i < size; i++)
911     {
912         os << code[i] << std::endl;
913     }
914     os.flush();
915
916     JavaVM *vm = getScilabJavaVM();
917     return ScilabJavaCompiler::compileCode(vm, className, code, size);
918 }
919
920 void ScilabJavaEnvironment::enabletrace(const char * filename)
921 {
922     JavaVM *vm = getScilabJavaVM();
923     ScilabJavaObject::enableTrace(vm, filename);
924 }
925
926 void ScilabJavaEnvironment::disabletrace(void)
927 {
928     JavaVM *vm = getScilabJavaVM();
929     ScilabJavaObject::disableTrace(vm);
930 }
931
932 void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string str, ...) const
933 {
934     if (traceEnabled)
935     {
936         char _str[LOG_BUFFER_SIZE];
937         va_list args;
938
939         va_start(args, str);
940         vsnprintf(_str, LOG_BUFFER_SIZE, str.c_str(), args);
941         va_end(args);
942
943         *file << fun << ": " << _str << std::endl;
944     }
945 }
946
947 #define SCILABJAVAOBJECT "org/scilab/modules/external_objects_java/ScilabJavaObject"
948
949 void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const methodName, int id, const ScilabStringStackAllocator & allocator)
950 {
951     JNIEnv * curEnv = NULL;
952     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
953     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
954     if (cls == NULL)
955     {
956         throw GiwsException::JniClassNotFoundException(curEnv, SCILABJAVAOBJECT);
957     }
958
959     jmethodID jobjectArray_getAccessibleMethodsjintID = curEnv->GetStaticMethodID(cls, methodName, "(I)[Ljava/lang/String;");
960     if (jobjectArray_getAccessibleMethodsjintID == NULL)
961     {
962         throw GiwsException::JniMethodNotFoundException(curEnv, methodName);
963     }
964
965     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, jobjectArray_getAccessibleMethodsjintID, id));
966     if (curEnv->ExceptionCheck())
967     {
968         throw GiwsException::JniCallMethodException(curEnv);
969     }
970     jint lenRow = curEnv->GetArrayLength(res);
971     jboolean isCopy = JNI_FALSE;
972
973     char **addr = new char*[lenRow];
974     jstring *resString = new jstring[lenRow];
975
976     for (jsize i = 0; i < lenRow; i++)
977     {
978         resString[i] = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i));
979         addr[i] = const_cast<char *>(curEnv->GetStringUTFChars(resString[i], &isCopy));
980     }
981     int lenCol = lenRow == 0 ? 0 : 1;
982     allocator.allocate(lenRow, lenCol, addr);
983     /*
984             SciErr err = createMatrixOfString(pvApiCtx, pos, lenCol, lenRow, addr);
985
986             for (jsize i = 0; i < lenRow; i++)
987             {
988                 curEnv->ReleaseStringUTFChars(resString[i], addr[i]);
989                 curEnv->DeleteLocalRef(resString[i]);
990                 }*/
991     delete[] addr;
992     delete[] resString;
993
994     // if (err.iErr)
995     // {
996     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
997     // }
998
999     curEnv->DeleteLocalRef(res);
1000     curEnv->DeleteLocalRef(cls);
1001     if (curEnv->ExceptionCheck())
1002     {
1003         throw GiwsException::JniCallMethodException(curEnv);
1004     }
1005 };
1006
1007 /*
1008 template <typename T, typename U, class V>
1009 void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1010 {
1011     SciErr err;
1012     jint lenRow, lenCol;
1013     jboolean isCopy = JNI_FALSE;
1014     jarray oneDim;
1015     JNIEnv * curEnv = NULL;
1016     U *addr = NULL;
1017
1018     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1019     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1020
1021     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMatMethodName(), V::getMatMethodSignature()) ;
1022     if (id == NULL)
1023     {
1024         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMatMethodName());
1025     }
1026
1027     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
1028     if (curEnv->ExceptionCheck())
1029     {
1030         throw GiwsException::JniCallMethodException(curEnv);
1031     }
1032
1033     lenRow = curEnv->GetArrayLength(res);
1034     oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, 0));
1035     lenCol = curEnv->GetArrayLength(oneDim);
1036     curEnv->DeleteLocalRef(oneDim);
1037
1038 //    allocator.allocate(lenRow, lenCol, addr);
1039
1040     if (getMethodOfConv())
1041     {
1042         err = V::allocMatrix(pvApiCtx, pos, lenRow, lenCol, (void**) &addr);
1043     }
1044     else
1045     {
1046         err = V::allocMatrix(pvApiCtx, pos, lenCol, lenRow, (void**) &addr);
1047     }
1048
1049     if (err.iErr)
1050     {
1051         curEnv->DeleteLocalRef(res);
1052         throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1053     }
1054
1055     T *resultsArray;
1056     for (int i = 0; i < lenRow; i++)
1057     {
1058         oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, i));
1059         resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy));
1060         if (getMethodOfConv())
1061         {
1062             for (int j = 0; j < lenCol; j++)
1063             {
1064                 addr[j * lenRow + i] = static_cast<U>(resultsArray[j]);
1065             }
1066         }
1067         else
1068         {
1069             for (int j = 0; j < lenCol; j++)
1070             {
1071                 addr[i * lenCol + j] = static_cast<U>(resultsArray[j]);
1072             }
1073         }
1074         curEnv->ReleasePrimitiveArrayCritical(oneDim, resultsArray, JNI_ABORT);
1075         curEnv->DeleteLocalRef(oneDim);
1076     }
1077
1078     curEnv->DeleteLocalRef(res);
1079     if (curEnv->ExceptionCheck())
1080     {
1081         throw GiwsException::JniCallMethodException(curEnv);
1082     }
1083 }
1084
1085 template <typename T, typename U, class V>
1086 void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1087 {
1088     SciErr err;
1089     jint lenRow;
1090     jboolean isCopy = JNI_FALSE;
1091     JNIEnv * curEnv = NULL;
1092     U *addr = NULL;
1093
1094     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1095     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1096
1097     jmethodID id = curEnv->GetStaticMethodID(cls, V::getRowMethodName(), V::getRowMethodSignature());
1098     if (id == NULL)
1099     {
1100         throw GiwsException::JniMethodNotFoundException(curEnv, V::getRowMethodName());
1101     }
1102
1103     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
1104     if (curEnv->ExceptionCheck())
1105     {
1106         curEnv->DeleteLocalRef(res);
1107         throw GiwsException::JniCallMethodException(curEnv);
1108     }
1109
1110     lenRow = curEnv->GetArrayLength(res);
1111
1112     // err = V::allocMatrix(pvApiCtx, pos, 1, lenRow, (void**) &addr);
1113
1114     // if (err.iErr)
1115     // {
1116     //     curEnv->DeleteLocalRef(res);
1117     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1118     // }
1119
1120     T *resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy));
1121     for (int i = 0; i < lenRow; i++)
1122     {
1123         addr[i] = static_cast<U>(resultsArray[i]);
1124     }
1125
1126     allocator.allocate(lenRow, lenCol, addr);
1127
1128     curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT);
1129     curEnv->DeleteLocalRef(res);
1130     if (curEnv->ExceptionCheck())
1131     {
1132         throw GiwsException::JniCallMethodException(curEnv);
1133     }
1134 }
1135
1136 template <typename T, typename U, class V>
1137 void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1138 {
1139     SciErr err;
1140     JNIEnv * curEnv = NULL;
1141     U *addr = NULL;
1142
1143     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1144     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1145
1146     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMethodName(), V::getMethodSignature()) ;
1147     if (id == NULL)
1148     {
1149         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMethodName());
1150     }
1151
1152     // err = V::allocMatrix(pvApiCtx, pos, 1, 1, (void**) &addr);
1153
1154     // if (err.iErr)
1155     // {
1156     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1157     // }
1158
1159
1160
1161     *addr = static_cast<U>(V::getSingleVar(curEnv, cls, id, javaID));
1162     allocator.allocate(lenRow, lenCol, addr);
1163
1164     if (curEnv->ExceptionCheck())
1165     {
1166         throw GiwsException::JniCallMethodException(curEnv);
1167     }
1168 */
1169 }