add external_objects_java on windows solution
[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     if (!helper.getShowPrivate() && *fieldName == '_')
594     {
595         throw ScilabJavaException(__LINE__, __FILE__, gettext("Private field: %s"), fieldName);
596     }
597
598     /*
599         PyObject * obj = scope.getObject(id);
600         if (!obj)
601         {
602             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
603         }
604
605         if (!PyObject_HasAttrString(obj, fieldName))
606         {
607             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name: %s"), fieldName);
608         }
609
610         PyObject * value = scope.getObject(idarg);
611         if (!value)
612         {
613             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
614         }
615
616         int ret = PyObject_SetAttrString(obj, fieldName, value);
617         if (ret == -1)
618         {
619             if (PyErr_Occurred())
620             {
621                 PyObject * type, * value, * traceback;
622                 PyErr_Fetch(&type, &value, &traceback);
623                 PyErr_NormalizeException(&type, &value, &traceback);
624                 PyErr_Clear();
625
626                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Unable to set the field: %s"), fieldName);
627             }
628             throw ScilabJavaException(__LINE__, __FILE__, gettext("Unable to set the field: %s"), fieldName);
629         }
630     */
631     writeLog("setfield", "Value successfully set.");
632 }
633
634 int ScilabJavaEnvironment::getfield(int id, const char * fieldName)
635 {
636     writeLog("getfield", "Get the field named %s on object with id %d.", fieldName, id);
637
638     JavaVM *vm = getScilabJavaVM();
639     int ret = ScilabJavaObject::getField(vm, id, fieldName);
640     return ret;
641     //    allocator.allocate(1, 1, &str);
642
643
644
645     /*
646     if (*fieldName == '\0')
647     {
648         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
649     }
650
651     if (!helper.getShowPrivate() && *fieldName == '_')
652     {
653         throw ScilabJavaException(__LINE__, __FILE__, gettext("Private field: %s"), fieldName);
654     }
655
656         PyObject * obj = scope.getObject(id);
657         if (!obj)
658         {
659             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
660         }
661
662         if (!PyObject_HasAttrString(obj, fieldName))
663         {
664             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name: %s"), fieldName);
665         }
666
667         PyObject * field = PyObject_GetAttrString(obj, fieldName);
668         if (!field)
669         {
670             if (PyErr_Occurred())
671             {
672                 PyObject * type, * value, * traceback;
673                 PyErr_Fetch(&type, &value, &traceback);
674                 PyErr_NormalizeException(&type, &value, &traceback);
675                 PyErr_Clear();
676
677                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Unable to get the field value: %s"), fieldName);
678             }
679             throw ScilabJavaException(__LINE__, __FILE__, gettext("Unable to get the field value: %s"), fieldName);
680         }
681
682         int ret = scope.addObject(field);
683         writeLog("getfield", "returned id %d.", ret);
684
685         return ret;
686     */
687     return 0;
688 }
689
690 int ScilabJavaEnvironment::getfieldtype(int id, const char * fieldName)
691 {
692     writeLog("getfieldtype", "Get the type of the field %s on object with id %d.", fieldName, id);
693
694     if ((!helper.getShowPrivate() && *fieldName == '_') || *fieldName == '\0')
695     {
696         writeLog("getfieldtype", "Return NONE.");
697         return -1;
698     }
699     /*
700         PyObject * obj = scope.getObject(id);
701         if (!obj)
702         {
703             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
704         }
705
706         if (!PyObject_HasAttrString(obj, fieldName))
707         {
708             writeLog("getfieldtype", "Return NONE.");
709             return -1;
710         }
711
712         PyObject * field = PyObject_GetAttrString(obj, fieldName);
713         if (!field)
714         {
715             writeLog("getfieldtype", "Return NONE.");
716             return -1;
717         }
718
719         if (PyCallable_Check(field))
720         {
721             Py_DECREF(field);
722             writeLog("getfieldtype", "Return METHOD.");
723             return 0;
724         }
725         else
726         {
727             Py_DECREF(field);
728             writeLog("getfieldtype", "Return FIELD.");
729             return 1;
730         }
731     */
732     return 0;
733 }
734
735 int ScilabJavaEnvironment::getarrayelement(int id, int * index, int length)
736 {
737     if (traceEnabled)
738     {
739         std::ostringstream os;
740         for (int i = 0; i < length - 1; i++)
741         {
742             os << index[i] << ", ";
743         }
744         os << index[length - 1];
745         os.flush();
746
747         writeLog("getarrayelement", "Get element from array with id %d and with index: %s.", id, os.str().c_str());
748     }
749     /*
750         PyObject * obj = scope.getObject(id);
751         if (!obj)
752         {
753             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
754         }
755
756         if (!PyList_Check(obj) && !PyArray_Check(obj))
757         {
758             throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list or an array"));
759         }
760
761         if (length == 0)
762         {
763             return 0;
764         }
765
766         if (PyList_Check(obj))
767         {
768             for (int i = 0; i < length; i++)
769             {
770                 if (index[i] < 0 || index[i] >= PyList_Size(obj))
771                 {
772                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index"));
773                 }
774                 obj = PyList_GetItem(obj, index[i]);
775                 if (i != length - 1 && !PyList_Check(obj))
776                 {
777                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list"));
778                 }
779             }
780         Py_INCREF(obj);
781         }
782         else if (PyArray_Check(obj))
783         {
784             PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
785             npy_intp * ind = reinterpret_cast<npy_intp *>(index);
786
787             if (length != PyArray_NDIM(arr))
788             {
789                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
790             }
791
792             npy_intp * dims = PyArray_DIMS(arr);
793
794             if (sizeof(int) != sizeof(npy_intp))
795             {
796                 ind = new npy_intp[length];
797                 for (int i = 0; i < length; i++)
798                 {
799                     if (index[i] < 0 || index[i] >= dims[i])
800                     {
801                         delete[] ind;
802                         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
803                     }
804
805                     ind[i] = static_cast<npy_intp>(index[i]);
806                 }
807             }
808
809             obj = PyArray_GETITEM(arr, PyArray_GetPtr(arr, ind));
810
811             if (sizeof(int) != sizeof(npy_intp))
812             {
813                 delete[] ind;
814             }
815         }
816         else
817         {
818             throw ScilabJavaException(__LINE__, __FILE__, gettext("Must be a list or a Numpy array"));
819         }
820
821         int ret = scope.addObject(obj);
822         writeLog("getarrayelement", "returned id %d.", ret);
823
824         return ret;
825     */
826     return 0;
827 }
828
829 void ScilabJavaEnvironment::setarrayelement(int id, int * index, int length, int idArg)
830 {
831     if (traceEnabled)
832     {
833         std::ostringstream os;
834         for (int i = 0; i < length - 1; i++)
835         {
836             os << index[i] << ", ";
837         }
838         os << index[length - 1];
839         os.flush();
840
841         writeLog("setarrayelement", "Set element with id %d in array with id %d and with index: %s.", idArg, id, os.str().c_str());
842     }
843     /*
844         PyObject * obj = scope.getObject(id);
845         if (!obj)
846         {
847             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
848         }
849
850         PyObject * value = scope.getObject(idArg);
851         if (!value)
852         {
853             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
854         }
855
856         if (PyList_Check(obj))
857         {
858             if (length == 0)
859             {
860                 return;
861             }
862
863             for (int i = 0; i < length - 1; i++)
864             {
865                 if (index[i] < 0 || index[i] >= PyList_Size(obj))
866                 {
867                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i + 1);
868                 }
869                 obj = PyList_GetItem(obj, index[i]);
870                 if (!PyList_Check(obj))
871                 {
872                     throw ScilabJavaException(__LINE__, __FILE__, gettext("Not a list at position %d"), index[i]);
873                 }
874             }
875
876             Py_INCREF(value);
877             PyList_SetItem(obj, index[length - 1], value);
878         }
879         else if (PyArray_Check(obj))
880         {
881             PyArrayObject * arr = reinterpret_cast<PyArrayObject *>(obj);
882             npy_intp * ind = reinterpret_cast<npy_intp *>(index);
883
884             if (length != PyArray_NDIM(arr))
885             {
886                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index dimension"));
887             }
888
889             npy_intp * dims = PyArray_DIMS(arr);
890
891             if (sizeof(int) != sizeof(npy_intp))
892             {
893                 ind = new npy_intp[length];
894                 for (int i = 0; i < length; i++)
895                 {
896                     if (index[i] < 0 || index[i] >= dims[i])
897                     {
898                         delete[] ind;
899                         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid index at position %d"), i);
900                     }
901
902                     ind[i] = static_cast<npy_intp>(index[i]);
903                 }
904             }
905
906             int ret = PyArray_SETITEM(arr, PyArray_GetPtr(arr, ind), value);
907
908             if (sizeof(int) != sizeof(npy_intp))
909             {
910                 delete[] ind;
911             }
912
913             if (ret == -1)
914             {
915                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the value in the array"));
916             }
917         }
918     */
919     writeLog("setarrayelement", "Successfully set");
920 }
921
922 int ScilabJavaEnvironment::cast(int id, char * className)
923 {
924     JavaVM *vm = getScilabJavaVM();
925     return ScilabJavaObject::javaCast(vm, id, className);
926 }
927
928 int ScilabJavaEnvironment::castwithid(int id, int classId)
929 {
930     JavaVM *vm = getScilabJavaVM();
931     return ScilabJavaObject::javaCast(vm, id, classId);
932 }
933
934 void ScilabJavaEnvironment::removeobject(int id)
935 {
936     writeLog("removeobject", "Remove object with id %d.", id);
937     //    scope.removeObject(id);
938     //    ScilabAutoCleaner::unregisterVariable(envId, id);
939 }
940
941 void ScilabJavaEnvironment::autoremoveobject(int id)
942 {
943     //    scope.removeObject(id);
944 }
945
946 void ScilabJavaEnvironment::getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator)
947 {
948     writeLog("getaccessiblemethods", "Get accessible methods on object with id %d.", id);
949     JavaVM *vm = getScilabJavaVM();
950     getMethodResult(vm, "getAccessibleMethods", id, allocator);
951 }
952
953 void ScilabJavaEnvironment::getaccessiblefields(int id, const ScilabStringStackAllocator & allocator)
954 {
955     writeLog("getaccessiblefields", "Get accessible fields on object with id %d.", id);
956     JavaVM *vm = getScilabJavaVM();
957     getMethodResult(vm, "getAccessibleFields", id, allocator);
958     getAccessibleFields(id, allocator, true);
959 }
960
961 std::string ScilabJavaEnvironment::getclassname(int id)
962 {
963     writeLog("getclassname", "Get the class name of object with id %d.", id);
964     JavaVM *vm = getScilabJavaVM();
965     return std::string(ScilabJavaObject::getClassName(vm, id));
966 }
967
968 VariableType ScilabJavaEnvironment::isunwrappable(int id)
969 {
970     writeLog("isunwrappable", "Test if the object with id %d is unwrappable.", id);
971     return wrapper.isunwrappable(id);
972 }
973
974 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
975 {
976     writeLog("compilecode", "Compile the code %s...", *code);
977
978     std::ostringstream os;
979     for (int i = 0; i < size; i++)
980     {
981         os << code[i] << std::endl;
982     }
983     os.flush();
984
985     JavaVM *vm = getScilabJavaVM();
986     return ScilabJavaCompiler::compileCode(vm, className, code, size);
987 }
988
989 void ScilabJavaEnvironment::enabletrace(const char * filename)
990 {
991     JavaVM *vm = getScilabJavaVM();
992     ScilabJavaObject::enableTrace(vm, filename);
993 }
994
995 void ScilabJavaEnvironment::disabletrace(void)
996 {
997     JavaVM *vm = getScilabJavaVM();
998     ScilabJavaObject::disableTrace(vm);
999 }
1000
1001 void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string str, ...) const
1002 {
1003     if (traceEnabled)
1004     {
1005         char _str[LOG_BUFFER_SIZE];
1006         va_list args;
1007
1008         va_start(args, str);
1009         vsnprintf(_str, LOG_BUFFER_SIZE, str.c_str(), args);
1010         va_end(args);
1011
1012         *file << fun << ": " << _str << std::endl;
1013     }
1014 }
1015
1016 #define SCILABJAVAOBJECT "org/scilab/modules/external_objects_java/ScilabJavaObject"
1017
1018 void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const methodName, int id, const ScilabStringStackAllocator & allocator)
1019 {
1020     JNIEnv * curEnv = NULL;
1021     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1022     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1023     if (cls == NULL)
1024     {
1025         throw GiwsException::JniClassNotFoundException(curEnv, SCILABJAVAOBJECT);
1026     }
1027
1028     jmethodID jobjectArray_getAccessibleMethodsjintID = curEnv->GetStaticMethodID(cls, methodName, "(I)[Ljava/lang/String;");
1029     if (jobjectArray_getAccessibleMethodsjintID == NULL)
1030     {
1031         throw GiwsException::JniMethodNotFoundException(curEnv, methodName);
1032     }
1033
1034     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, jobjectArray_getAccessibleMethodsjintID, id));
1035     if (curEnv->ExceptionCheck())
1036     {
1037         throw GiwsException::JniCallMethodException(curEnv);
1038     }
1039     jint lenRow = curEnv->GetArrayLength(res);
1040     jboolean isCopy = JNI_FALSE;
1041
1042     char **addr = new char*[lenRow];
1043     jstring *resString = new jstring[lenRow];
1044
1045     for (jsize i = 0; i < lenRow; i++)
1046     {
1047         resString[i] = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i));
1048         addr[i] = const_cast<char *>(curEnv->GetStringUTFChars(resString[i], &isCopy));
1049     }
1050     int lenCol = lenRow == 0 ? 0 : 1;
1051     allocator.allocate(lenRow, lenCol, addr);
1052     /*
1053             SciErr err = createMatrixOfString(pvApiCtx, pos, lenCol, lenRow, addr);
1054
1055             for (jsize i = 0; i < lenRow; i++)
1056             {
1057                 curEnv->ReleaseStringUTFChars(resString[i], addr[i]);
1058                 curEnv->DeleteLocalRef(resString[i]);
1059                 }*/
1060     delete[] addr;
1061     delete[] resString;
1062
1063     // if (err.iErr)
1064     // {
1065     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1066     // }
1067
1068     curEnv->DeleteLocalRef(res);
1069     curEnv->DeleteLocalRef(cls);
1070     if (curEnv->ExceptionCheck())
1071     {
1072         throw GiwsException::JniCallMethodException(curEnv);
1073     }
1074 };
1075
1076 /*
1077 template <typename T, typename U, class V>
1078 void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1079 {
1080     SciErr err;
1081     jint lenRow, lenCol;
1082     jboolean isCopy = JNI_FALSE;
1083     jarray oneDim;
1084     JNIEnv * curEnv = NULL;
1085     U *addr = NULL;
1086
1087     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1088     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1089
1090     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMatMethodName(), V::getMatMethodSignature()) ;
1091     if (id == NULL)
1092     {
1093         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMatMethodName());
1094     }
1095
1096     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
1097     if (curEnv->ExceptionCheck())
1098     {
1099         throw GiwsException::JniCallMethodException(curEnv);
1100     }
1101
1102     lenRow = curEnv->GetArrayLength(res);
1103     oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, 0));
1104     lenCol = curEnv->GetArrayLength(oneDim);
1105     curEnv->DeleteLocalRef(oneDim);
1106
1107 //    allocator.allocate(lenRow, lenCol, addr);
1108
1109     if (getMethodOfConv())
1110     {
1111         err = V::allocMatrix(pvApiCtx, pos, lenRow, lenCol, (void**) &addr);
1112     }
1113     else
1114     {
1115         err = V::allocMatrix(pvApiCtx, pos, lenCol, lenRow, (void**) &addr);
1116     }
1117
1118     if (err.iErr)
1119     {
1120         curEnv->DeleteLocalRef(res);
1121         throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1122     }
1123
1124     T *resultsArray;
1125     for (int i = 0; i < lenRow; i++)
1126     {
1127         oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, i));
1128         resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy));
1129         if (getMethodOfConv())
1130         {
1131             for (int j = 0; j < lenCol; j++)
1132             {
1133                 addr[j * lenRow + i] = static_cast<U>(resultsArray[j]);
1134             }
1135         }
1136         else
1137         {
1138             for (int j = 0; j < lenCol; j++)
1139             {
1140                 addr[i * lenCol + j] = static_cast<U>(resultsArray[j]);
1141             }
1142         }
1143         curEnv->ReleasePrimitiveArrayCritical(oneDim, resultsArray, JNI_ABORT);
1144         curEnv->DeleteLocalRef(oneDim);
1145     }
1146
1147     curEnv->DeleteLocalRef(res);
1148     if (curEnv->ExceptionCheck())
1149     {
1150         throw GiwsException::JniCallMethodException(curEnv);
1151     }
1152 }
1153
1154 template <typename T, typename U, class V>
1155 void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1156 {
1157     SciErr err;
1158     jint lenRow;
1159     jboolean isCopy = JNI_FALSE;
1160     JNIEnv * curEnv = NULL;
1161     U *addr = NULL;
1162
1163     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1164     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1165
1166     jmethodID id = curEnv->GetStaticMethodID(cls, V::getRowMethodName(), V::getRowMethodSignature());
1167     if (id == NULL)
1168     {
1169         throw GiwsException::JniMethodNotFoundException(curEnv, V::getRowMethodName());
1170     }
1171
1172     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
1173     if (curEnv->ExceptionCheck())
1174     {
1175         curEnv->DeleteLocalRef(res);
1176         throw GiwsException::JniCallMethodException(curEnv);
1177     }
1178
1179     lenRow = curEnv->GetArrayLength(res);
1180
1181     // err = V::allocMatrix(pvApiCtx, pos, 1, lenRow, (void**) &addr);
1182
1183     // if (err.iErr)
1184     // {
1185     //     curEnv->DeleteLocalRef(res);
1186     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1187     // }
1188
1189     T *resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy));
1190     for (int i = 0; i < lenRow; i++)
1191     {
1192         addr[i] = static_cast<U>(resultsArray[i]);
1193     }
1194
1195     allocator.allocate(lenRow, lenCol, addr);
1196
1197     curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT);
1198     curEnv->DeleteLocalRef(res);
1199     if (curEnv->ExceptionCheck())
1200     {
1201         throw GiwsException::JniCallMethodException(curEnv);
1202     }
1203 }
1204
1205 template <typename T, typename U, class V>
1206 void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
1207 {
1208     SciErr err;
1209     JNIEnv * curEnv = NULL;
1210     U *addr = NULL;
1211
1212     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
1213     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1214
1215     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMethodName(), V::getMethodSignature()) ;
1216     if (id == NULL)
1217     {
1218         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMethodName());
1219     }
1220
1221     // err = V::allocMatrix(pvApiCtx, pos, 1, 1, (void**) &addr);
1222
1223     // if (err.iErr)
1224     // {
1225     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1226     // }
1227
1228
1229
1230     *addr = static_cast<U>(V::getSingleVar(curEnv, cls, id, javaID));
1231     allocator.allocate(lenRow, lenCol, addr);
1232
1233     if (curEnv->ExceptionCheck())
1234     {
1235         throw GiwsException::JniCallMethodException(curEnv);
1236     }
1237 */
1238 }