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