Continue the work on the wrap
[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     JavaVM * vm = getScilabJavaVM();
682
683     return ScilabJavaObject::getArrayElement(vm, id, index, length);
684 }
685
686 void ScilabJavaEnvironment::setarrayelement(int id, int * index, int length, int idArg)
687 {
688     if (traceEnabled)
689     {
690         std::ostringstream os;
691         for (int i = 0; i < length - 1; i++)
692         {
693             os << index[i] << ", ";
694         }
695         os << index[length - 1];
696         os.flush();
697
698         writeLog("setarrayelement", "Set element with id %d in array with id %d and with index: %s.", idArg, id, os.str().c_str());
699     }
700
701     JavaVM * vm = getScilabJavaVM();
702
703     ScilabJavaObject::setArrayElement(vm, id, index, length, idArg);
704
705     writeLog("setarrayelement", "Successfully set");
706 }
707
708 int ScilabJavaEnvironment::cast(int id, char * className)
709 {
710     JavaVM *vm = getScilabJavaVM();
711     return ScilabJavaObject::javaCast(vm, id, className);
712 }
713
714 int ScilabJavaEnvironment::castwithid(int id, int classId)
715 {
716     JavaVM *vm = getScilabJavaVM();
717     return ScilabJavaObject::javaCast(vm, id, classId);
718 }
719
720 void ScilabJavaEnvironment::removeobject(int id)
721 {
722     writeLog("removeobject", "Remove object with id %d.", id);
723     //    scope.removeObject(id);
724     //    ScilabAutoCleaner::unregisterVariable(envId, id);
725 }
726
727 void ScilabJavaEnvironment::autoremoveobject(int id)
728 {
729     //    scope.removeObject(id);
730 }
731
732 void ScilabJavaEnvironment::getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator)
733 {
734     writeLog("getaccessiblemethods", "Get accessible methods on object with id %d.", id);
735     JavaVM *vm = getScilabJavaVM();
736     getMethodResult(vm, "getAccessibleMethods", id, allocator);
737 }
738
739 void ScilabJavaEnvironment::getaccessiblefields(int id, const ScilabStringStackAllocator & allocator)
740 {
741     writeLog("getaccessiblefields", "Get accessible fields on object with id %d.", id);
742     JavaVM *vm = getScilabJavaVM();
743     getMethodResult(vm, "getAccessibleFields", id, allocator);
744     getAccessibleFields(id, allocator, true);
745 }
746
747 std::string ScilabJavaEnvironment::getclassname(int id)
748 {
749     writeLog("getclassname", "Get the class name of object with id %d.", id);
750     JavaVM *vm = getScilabJavaVM();
751     return std::string(ScilabJavaObject::getClassName(vm, id));
752 }
753
754 VariableType ScilabJavaEnvironment::isunwrappable(int id)
755 {
756     writeLog("isunwrappable", "Test if the object with id %d is unwrappable.", id);
757     return wrapper.isunwrappable(id);
758 }
759
760 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
761 {
762     writeLog("compilecode", "Compile the code %s...", *code);
763
764     std::ostringstream os;
765     for (int i = 0; i < size; i++)
766     {
767         os << code[i] << std::endl;
768     }
769     os.flush();
770
771     JavaVM *vm = getScilabJavaVM();
772     return ScilabJavaCompiler::compileCode(vm, className, code, size);
773 }
774
775 void ScilabJavaEnvironment::enabletrace(const char * filename)
776 {
777     JavaVM *vm = getScilabJavaVM();
778     ScilabJavaObject::enableTrace(vm, filename);
779 }
780
781 void ScilabJavaEnvironment::disabletrace(void)
782 {
783     JavaVM *vm = getScilabJavaVM();
784     ScilabJavaObject::disableTrace(vm);
785 }
786
787 void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string str, ...) const
788 {
789     if (traceEnabled)
790     {
791         char _str[LOG_BUFFER_SIZE];
792         va_list args;
793
794         va_start(args, str);
795         vsnprintf(_str, LOG_BUFFER_SIZE, str.c_str(), args);
796         va_end(args);
797
798         *file << fun << ": " << _str << std::endl;
799     }
800 }
801
802 #define SCILABJAVAOBJECT "org/scilab/modules/external_objects_java/ScilabJavaObject"
803
804 void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const methodName, int id, const ScilabStringStackAllocator & allocator)
805 {
806     JNIEnv * curEnv = NULL;
807     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
808     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
809     if (cls == NULL)
810     {
811         throw GiwsException::JniClassNotFoundException(curEnv, SCILABJAVAOBJECT);
812     }
813
814     jmethodID jobjectArray_getAccessibleMethodsjintID = curEnv->GetStaticMethodID(cls, methodName, "(I)[Ljava/lang/String;");
815     if (jobjectArray_getAccessibleMethodsjintID == NULL)
816     {
817         throw GiwsException::JniMethodNotFoundException(curEnv, methodName);
818     }
819
820     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, jobjectArray_getAccessibleMethodsjintID, id));
821     if (curEnv->ExceptionCheck())
822     {
823         throw GiwsException::JniCallMethodException(curEnv);
824     }
825     jint lenRow = curEnv->GetArrayLength(res);
826     jboolean isCopy = JNI_FALSE;
827
828     char **addr = new char*[lenRow];
829     jstring *resString = new jstring[lenRow];
830
831     for (jsize i = 0; i < lenRow; i++)
832     {
833         resString[i] = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i));
834         addr[i] = const_cast<char *>(curEnv->GetStringUTFChars(resString[i], &isCopy));
835     }
836     int lenCol = lenRow == 0 ? 0 : 1;
837     allocator.allocate(lenRow, lenCol, addr);
838     /*
839             SciErr err = createMatrixOfString(pvApiCtx, pos, lenCol, lenRow, addr);
840
841             for (jsize i = 0; i < lenRow; i++)
842             {
843                 curEnv->ReleaseStringUTFChars(resString[i], addr[i]);
844                 curEnv->DeleteLocalRef(resString[i]);
845                 }*/
846     delete[] addr;
847     delete[] resString;
848
849     // if (err.iErr)
850     // {
851     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
852     // }
853
854     curEnv->DeleteLocalRef(res);
855     curEnv->DeleteLocalRef(cls);
856     if (curEnv->ExceptionCheck())
857     {
858         throw GiwsException::JniCallMethodException(curEnv);
859     }
860 };
861
862 /*
863 template <typename T, typename U, class V>
864 void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
865 {
866     SciErr err;
867     jint lenRow, lenCol;
868     jboolean isCopy = JNI_FALSE;
869     jarray oneDim;
870     JNIEnv * curEnv = NULL;
871     U *addr = NULL;
872
873     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
874     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
875
876     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMatMethodName(), V::getMatMethodSignature()) ;
877     if (id == NULL)
878     {
879         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMatMethodName());
880     }
881
882     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
883     if (curEnv->ExceptionCheck())
884     {
885         throw GiwsException::JniCallMethodException(curEnv);
886     }
887
888     lenRow = curEnv->GetArrayLength(res);
889     oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, 0));
890     lenCol = curEnv->GetArrayLength(oneDim);
891     curEnv->DeleteLocalRef(oneDim);
892
893 //    allocator.allocate(lenRow, lenCol, addr);
894
895     if (getMethodOfConv())
896     {
897         err = V::allocMatrix(pvApiCtx, pos, lenRow, lenCol, (void**) &addr);
898     }
899     else
900     {
901         err = V::allocMatrix(pvApiCtx, pos, lenCol, lenRow, (void**) &addr);
902     }
903
904     if (err.iErr)
905     {
906         curEnv->DeleteLocalRef(res);
907         throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
908     }
909
910     T *resultsArray;
911     for (int i = 0; i < lenRow; i++)
912     {
913         oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, i));
914         resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy));
915         if (getMethodOfConv())
916         {
917             for (int j = 0; j < lenCol; j++)
918             {
919                 addr[j * lenRow + i] = static_cast<U>(resultsArray[j]);
920             }
921         }
922         else
923         {
924             for (int j = 0; j < lenCol; j++)
925             {
926                 addr[i * lenCol + j] = static_cast<U>(resultsArray[j]);
927             }
928         }
929         curEnv->ReleasePrimitiveArrayCritical(oneDim, resultsArray, JNI_ABORT);
930         curEnv->DeleteLocalRef(oneDim);
931     }
932
933     curEnv->DeleteLocalRef(res);
934     if (curEnv->ExceptionCheck())
935     {
936         throw GiwsException::JniCallMethodException(curEnv);
937     }
938 }
939
940 template <typename T, typename U, class V>
941 void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
942 {
943     SciErr err;
944     jint lenRow;
945     jboolean isCopy = JNI_FALSE;
946     JNIEnv * curEnv = NULL;
947     U *addr = NULL;
948
949     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
950     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
951
952     jmethodID id = curEnv->GetStaticMethodID(cls, V::getRowMethodName(), V::getRowMethodSignature());
953     if (id == NULL)
954     {
955         throw GiwsException::JniMethodNotFoundException(curEnv, V::getRowMethodName());
956     }
957
958     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
959     if (curEnv->ExceptionCheck())
960     {
961         curEnv->DeleteLocalRef(res);
962         throw GiwsException::JniCallMethodException(curEnv);
963     }
964
965     lenRow = curEnv->GetArrayLength(res);
966
967     // err = V::allocMatrix(pvApiCtx, pos, 1, lenRow, (void**) &addr);
968
969     // if (err.iErr)
970     // {
971     //     curEnv->DeleteLocalRef(res);
972     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
973     // }
974
975     T *resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy));
976     for (int i = 0; i < lenRow; i++)
977     {
978         addr[i] = static_cast<U>(resultsArray[i]);
979     }
980
981     allocator.allocate(lenRow, lenCol, addr);
982
983     curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT);
984     curEnv->DeleteLocalRef(res);
985     if (curEnv->ExceptionCheck())
986     {
987         throw GiwsException::JniCallMethodException(curEnv);
988     }
989 }
990
991 template <typename T, typename U, class V>
992 void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
993 {
994     SciErr err;
995     JNIEnv * curEnv = NULL;
996     U *addr = NULL;
997
998     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
999     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
1000
1001     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMethodName(), V::getMethodSignature()) ;
1002     if (id == NULL)
1003     {
1004         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMethodName());
1005     }
1006
1007     // err = V::allocMatrix(pvApiCtx, pos, 1, 1, (void**) &addr);
1008
1009     // if (err.iErr)
1010     // {
1011     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
1012     // }
1013
1014
1015
1016     *addr = static_cast<U>(V::getSingleVar(curEnv, cls, id, javaID));
1017     allocator.allocate(lenRow, lenCol, addr);
1018
1019     if (curEnv->ExceptionCheck())
1020     {
1021         throw GiwsException::JniCallMethodException(curEnv);
1022     }
1023 */
1024 }