JIMS: plug extraction
[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     JavaVM * vm = getScilabJavaVM();
185     return ScilabJavaObject::extract(vm, id, args, argsSize);
186 }
187
188 void ScilabJavaEnvironment::insert(int id, int * args, int argsSize)
189 {
190     if (traceEnabled)
191     {
192         std::ostringstream os;
193         for (int i = 0; i < argsSize - 1; i++)
194         {
195             os << args[i] << ", ";
196         }
197         os << args[argsSize - 1];
198         os.flush();
199
200         writeLog("insert", "Insertion on object %d with arguments: %s.", id, os.str().c_str());
201     }
202     /*
203         PyObject * obj = scope.getObject(id);
204         if (!obj)
205         {
206             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
207         }
208
209         if (argsSize != 2)
210         {
211             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert more than one element in a dictionary"));
212         }
213
214         PyObject * key = scope.getObject(args[0]);
215         if (!obj)
216         {
217             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
218         }
219
220         PyObject * value = scope.getObject(args[1]);
221         if (!value)
222         {
223             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid value object"));
224         }
225
226         if (PyDict_Check(obj))
227         {
228             PyDict_SetItem(obj, key, value);
229
230             writeLog("insert", "success.");
231
232             return;
233         }
234         else
235         {
236             if (!PyString_Check(key))
237             {
238                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object: A string expected"));
239             }
240
241             int ret = PyObject_SetAttr(obj, key, value);
242             if (ret == -1)
243             {
244                 if (PyErr_Occurred())
245                 {
246                     PyObject *type, *value, *traceback;
247                     PyErr_Fetch(&type, &value, &traceback);
248                     PyErr_NormalizeException(&type, &value, &traceback);
249                     PyErr_Clear();
250
251                     throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
252                 }
253                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the attribute."));
254             }
255
256             writeLog("insert", "success.");
257
258             return;
259         }
260     */
261     throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert in Java object"));
262 }
263
264 void ScilabJavaEnvironment::garbagecollect() { }
265
266 void ScilabJavaEnvironment::addtoclasspath(const char * path)
267 {
268     writeLog("addtoclasspath", "Add the path %s to syspath", path);
269     /*
270         PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
271         PyObject * _path = PyString_FromString(path);
272         PyList_Append(syspath, _path);
273     */
274 }
275
276 void ScilabJavaEnvironment::getclasspath(const ScilabStringStackAllocator & allocator)
277 {
278     writeLog("getclasspath", "Get syspath");
279     /*
280         PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
281         int size = PyList_Size(syspath);
282         char ** arr = new char*[size];
283
284         for (int i = 0; i < size; i++)
285         {
286             PyObject * item = PyList_GetItem(syspath, i);
287             arr[i] = strdup(PyString_AsString(item));
288         }
289
290         allocator.allocate(size, 1, arr);
291         for (int i = 0; i < size; i++)
292         {
293             free(arr[i]);
294         }
295         delete arr;
296     */
297 }
298
299 void ScilabJavaEnvironment::addNamedVariable(int id, const char * varName)
300 {
301     writeLog("addNamedVariable", "Associate the variable named %s with object with id %d.", varName, id);
302
303     /*    PyObject * obj = scope.getObject(id);
304         if (!obj)
305         {
306             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
307         }
308
309         PyObject * _main_ = PyImport_AddModule("__main__");
310         if (!_main_)
311         {
312             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
313         }
314
315         if (PyObject_SetAttrString(_main_, varName, obj) == -1)
316         {
317             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the variable named %s."), varName);
318         }
319     */
320 }
321
322 int ScilabJavaEnvironment::getNamedVariable(const char * varName)
323 {
324     writeLog("getNamedVariable", "Get the variable named %s.", varName);
325     /*
326         PyObject * _main_ = PyImport_AddModule("__main__");
327         if (!_main_)
328         {
329             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
330         }
331
332         PyObject * var = PyObject_GetAttrString(_main_, varName);
333         if (!var)
334         {
335             if (PyErr_Occurred())
336             {
337                 PyObject *type, *value, *traceback;
338                 PyErr_Fetch(&type, &value, &traceback);
339                 PyErr_NormalizeException(&type, &value, &traceback);
340                 PyErr_Clear();
341
342                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot get the variable value"));
343             }
344             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the variable value"));
345         }
346
347         int ret = scope.addObject(var);
348
349         writeLog("getNamedVariable", "returned id %d.", ret);
350
351         return ret;
352     */
353     return 0;
354 }
355
356 void ScilabJavaEnvironment::evalString(const char ** code, int nbLines, ScilabStringStackAllocator * allocator)
357 {
358     writeLog("evalString", "Evaluate code: %s...(truncated)", *code);
359     /*
360         std::ostringstream os;
361         for (int i = 0; i < nbLines; i++)
362         {
363             os << code[i] << std::endl;
364         }
365         os.flush();
366
367         PyObject * _main_ = PyImport_AddModule("__main__");
368         if (!_main_)
369         {
370             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code since __main__ is not accessible."));
371         }
372
373         std::ostream * old;
374         std::ostringstream os1;
375         if (allocator)
376         {
377             old = ScilabJavaOStream::setStdOutStream(&os1);
378         }
379
380         PyObject * dict = PyModule_GetDict(_main_);
381         PyObject * ret = PyRun_StringFlags(os.str().c_str(), Py_file_input, dict, dict, 0);
382
383         if (allocator)
384         {
385             ScilabJavaOStream::setStdOutStream(old);
386         }
387
388         if (!ret)
389         {
390             if (PyErr_Occurred())
391             {
392                 PyObject *type, *value, *traceback;
393                 PyErr_Fetch(&type, &value, &traceback);
394                 PyErr_NormalizeException(&type, &value, &traceback);
395                 PyErr_Clear();
396
397                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
398             }
399             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot evaluate the code"));
400         }
401
402         if (allocator)
403         {
404             std::vector<char *> buf = breakInLines(os1.str());
405             allocator->allocate(buf.size(), 1, &(buf[0]));
406             for (std::vector<char *>::iterator i = buf.begin(); i != buf.end(); i++)
407             {
408                 free(*i);
409             }
410         }
411
412         Py_DECREF(ret);
413     */
414 }
415
416 int ScilabJavaEnvironment::createarray(char * className, int * dims, int len)
417 {
418     writeLog("createarray", "Create array %s of size (%d, %d).", className, dims, len);
419     JavaVM *vm = getScilabJavaVM();
420     return ScilabJavaArray::newInstance(vm, className, dims, len);
421 }
422
423 int ScilabJavaEnvironment::loadclass(char * className, char * currentSciPath, bool isNamedVarCreated, bool allowReload)
424 {
425     writeLog("loadclass", "Load the module %s and allowReload is set to %s", className, allowReload ? "true" : "false");
426     JavaVM *vm = getScilabJavaVM();
427     return ScilabClassLoader::loadJavaClass(vm, className, allowReload);
428 }
429
430 void ScilabJavaEnvironment::getrepresentation(int id, const ScilabStringStackAllocator & allocator)
431 {
432     writeLog("getrepresentation", "Get the representation of object %d.", id);
433     JavaVM *vm = getScilabJavaVM();
434     char *str = ScilabJavaObject::getRepresentation(vm, id);
435     allocator.allocate(1, 1, &str);
436 }
437
438 std::string ScilabJavaEnvironment::getrepresentation(int id)
439 {
440     writeLog("getrepresentation", "Get the representation of object %d.", id);
441     JavaVM *vm = getScilabJavaVM();
442     return std::string(ScilabJavaObject::getRepresentation(vm, id));
443 }
444
445 /* Used by jexists */
446 bool ScilabJavaEnvironment::isvalidobject(int id)
447 {
448
449     JavaVM *vm = getScilabJavaVM();
450     bool ret = ScilabJavaObject::isValidJavaObject(vm, id);
451     writeLog("isvalidobject", "Test the validity of object %d which is%s valid.", id, ret ? "" : " not");
452     return ret;
453 }
454
455 int ScilabJavaEnvironment::newinstance(int id, int * args, int argsSize)
456 {
457     JavaVM *vm = getScilabJavaVM();
458     return ScilabJavaClass::newInstance(vm, id, args, argsSize);
459 }
460
461 int ScilabJavaEnvironment::operation(int idA, int idB, const OperatorsType type)
462 {
463     writeLog("operation", "Evalute an operation (%d) with objects with id %d and %d.", (int)type, idA, idB);
464     /*
465         const char * opName = getOpNameFromType(type);
466
467         PyObject * _operator_ = PyImport_AddModule("operator");
468         if (!_operator_)
469         {
470             throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot get the operator module."));
471         }
472
473         PyObject * objA = scope.getObject(idA);
474         if (!objA)
475         {
476             throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idA);
477         }
478
479         PyObject * objB = 0;
480         if (idB != -1)
481         {
482             // Binary op
483             objB = scope.getObject(idB);
484             if (!objB)
485             {
486                 throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), idB);
487             }
488         }
489
490         PyObject * _op_ = PyObject_GetAttrString(_operator_, opName);
491
492         PyObject * pArgs = PyTuple_New(objB ? 2 : 1);
493         Py_INCREF(objA);
494         PyTuple_SetItem(pArgs, 0, objA);
495
496         if (objB)
497         {
498             Py_INCREF(objB);
499             PyTuple_SetItem(pArgs, 1, objB);
500         }
501
502         PyObject * result = PyObject_Call(_op_, pArgs, 0);
503         Py_DECREF(pArgs);
504         Py_DECREF(_op_);
505
506         if (!result)
507         {
508             if (PyErr_Occurred())
509             {
510                 PyObject * type, * value, * traceback;
511                 PyErr_Fetch(&type, &value, &traceback);
512                 PyErr_NormalizeException(&type, &value, &traceback);
513                 PyErr_Clear();
514
515                 throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Unable to make the operation (%s)."), opName);
516             }
517             throw ScilabJavaException(__LINE__, __FILE__, gettext("Unable to make the operation (%s)."), opName);
518         }
519
520         int ret = scope.addObject(result);
521
522         writeLog("operation", "returned id %d.", ret);
523
524         return ret;
525     */
526     return 0;
527 }
528
529 int * ScilabJavaEnvironment::invoke(int id, const char * methodName, int * args, int argsSize)
530 {
531     if (traceEnabled)
532     {
533         std::ostringstream os;
534         for (int i = 0; i < argsSize - 1; i++)
535         {
536             os << args[i] << ", ";
537         }
538         os << args[argsSize - 1];
539         os.flush();
540
541         writeLog("invoke", "Invoke the method %s on object %d with arguments: %s.", methodName, id, os.str().c_str());
542     }
543
544     JavaVM *vm = getScilabJavaVM();
545     int * invokedId = new int[2];
546     invokedId[0] = 1 ; //1 object returned
547     invokedId[1] = ScilabJavaObject::invoke(vm, id, methodName, args, argsSize);
548     return invokedId;
549 }
550
551 void ScilabJavaEnvironment::setfield(int id, const char * fieldName, int idarg)
552 {
553     writeLog("setfield", "Set the field named %s with value id %d on object with id %d.", fieldName, idarg, id);
554
555     if (*fieldName == '\0')
556     {
557         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
558     }
559
560     try
561     {
562         JavaVM * vm = getScilabJavaVM();
563         ScilabJavaObject::setField(vm, id, fieldName, idarg);
564     }
565     catch (const GiwsException::JniCallMethodException & e)
566     {
567         throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the field: %s"), fieldName);
568     }
569
570     writeLog("setfield", "Value successfully set.");
571 }
572
573 int ScilabJavaEnvironment::getfield(int id, const char * fieldName)
574 {
575     writeLog("getfield", "Get the field named %s on object with id %d.", fieldName, id);
576
577     if (*fieldName == '\0')
578     {
579         throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid field name"));
580     }
581
582     JavaVM * vm = getScilabJavaVM();
583     int ret = ScilabJavaObject::getField(vm, id, fieldName);
584
585     return ret;
586 }
587
588 int ScilabJavaEnvironment::getfieldtype(int id, const char * fieldName)
589 {
590     writeLog("getfieldtype", "Get the type of the field %s on object with id %d.", fieldName, id);
591
592     JavaVM * vm = getScilabJavaVM();
593
594     return ScilabJavaObject::getFieldType(vm, id, fieldName);
595 }
596
597 int ScilabJavaEnvironment::getarrayelement(int id, int * index, int length)
598 {
599     if (traceEnabled)
600     {
601         std::ostringstream os;
602         for (int i = 0; i < length - 1; i++)
603         {
604             os << index[i] << ", ";
605         }
606         os << index[length - 1];
607         os.flush();
608
609         writeLog("getarrayelement", "Get element from array with id %d and with index: %s.", id, os.str().c_str());
610     }
611
612     JavaVM * vm = getScilabJavaVM();
613
614     return ScilabJavaObject::getArrayElement(vm, id, index, length);
615 }
616
617 void ScilabJavaEnvironment::setarrayelement(int id, int * index, int length, int idArg)
618 {
619     if (traceEnabled)
620     {
621         std::ostringstream os;
622         for (int i = 0; i < length - 1; i++)
623         {
624             os << index[i] << ", ";
625         }
626         os << index[length - 1];
627         os.flush();
628
629         writeLog("setarrayelement", "Set element with id %d in array with id %d and with index: %s.", idArg, id, os.str().c_str());
630     }
631
632     JavaVM * vm = getScilabJavaVM();
633
634     ScilabJavaObject::setArrayElement(vm, id, index, length, idArg);
635
636     writeLog("setarrayelement", "Successfully set");
637 }
638
639 int ScilabJavaEnvironment::cast(int id, char * className)
640 {
641     JavaVM *vm = getScilabJavaVM();
642     return ScilabJavaObject::javaCast(vm, id, className);
643 }
644
645 int ScilabJavaEnvironment::castwithid(int id, int classId)
646 {
647     JavaVM *vm = getScilabJavaVM();
648     return ScilabJavaObject::javaCast(vm, id, classId);
649 }
650
651 void ScilabJavaEnvironment::removeobject(int id)
652 {
653     writeLog("removeobject", "Remove object with id %d.", id);
654     //    scope.removeObject(id);
655     //    ScilabAutoCleaner::unregisterVariable(envId, id);
656 }
657
658 void ScilabJavaEnvironment::autoremoveobject(int id)
659 {
660     //    scope.removeObject(id);
661 }
662
663 void ScilabJavaEnvironment::getaccessiblemethods(int id, const ScilabStringStackAllocator & allocator)
664 {
665     writeLog("getaccessiblemethods", "Get accessible methods on object with id %d.", id);
666     JavaVM *vm = getScilabJavaVM();
667     getMethodResult(vm, "getAccessibleMethods", id, allocator);
668 }
669
670 void ScilabJavaEnvironment::getaccessiblefields(int id, const ScilabStringStackAllocator & allocator)
671 {
672     writeLog("getaccessiblefields", "Get accessible fields on object with id %d.", id);
673     JavaVM *vm = getScilabJavaVM();
674     getMethodResult(vm, "getAccessibleFields", id, allocator);
675     getAccessibleFields(id, allocator, true);
676 }
677
678 std::string ScilabJavaEnvironment::getclassname(int id)
679 {
680     writeLog("getclassname", "Get the class name of object with id %d.", id);
681     JavaVM *vm = getScilabJavaVM();
682     return std::string(ScilabJavaObject::getClassName(vm, id));
683 }
684
685 VariableType ScilabJavaEnvironment::isunwrappable(int id)
686 {
687     writeLog("isunwrappable", "Test if the object with id %d is unwrappable.", id);
688     return wrapper.isunwrappable(id);
689 }
690
691 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
692 {
693     writeLog("compilecode", "Compile the code %s...", *code);
694
695     std::ostringstream os;
696     for (int i = 0; i < size; i++)
697     {
698         os << code[i] << std::endl;
699     }
700     os.flush();
701
702     JavaVM *vm = getScilabJavaVM();
703     return ScilabJavaCompiler::compileCode(vm, className, code, size);
704 }
705
706 void ScilabJavaEnvironment::enabletrace(const char * filename)
707 {
708     JavaVM *vm = getScilabJavaVM();
709     ScilabJavaObject::enableTrace(vm, filename);
710 }
711
712 void ScilabJavaEnvironment::disabletrace(void)
713 {
714     JavaVM *vm = getScilabJavaVM();
715     ScilabJavaObject::disableTrace(vm);
716 }
717
718 void ScilabJavaEnvironment::writeLog(const std::string & fun, const std::string str, ...) const
719 {
720     if (traceEnabled)
721     {
722         char _str[LOG_BUFFER_SIZE];
723         va_list args;
724
725         va_start(args, str);
726         vsnprintf(_str, LOG_BUFFER_SIZE, str.c_str(), args);
727         va_end(args);
728
729         *file << fun << ": " << _str << std::endl;
730     }
731 }
732
733 #define SCILABJAVAOBJECT "org/scilab/modules/external_objects_java/ScilabJavaObject"
734
735 void ScilabJavaEnvironment::getMethodResult(JavaVM * jvm_, const char * const methodName, int id, const ScilabStringStackAllocator & allocator)
736 {
737     JNIEnv * curEnv = NULL;
738     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
739     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
740     if (cls == NULL)
741     {
742         throw GiwsException::JniClassNotFoundException(curEnv, SCILABJAVAOBJECT);
743     }
744
745     jmethodID jobjectArray_getAccessibleMethodsjintID = curEnv->GetStaticMethodID(cls, methodName, "(I)[Ljava/lang/String;");
746     if (jobjectArray_getAccessibleMethodsjintID == NULL)
747     {
748         throw GiwsException::JniMethodNotFoundException(curEnv, methodName);
749     }
750
751     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, jobjectArray_getAccessibleMethodsjintID, id));
752     if (curEnv->ExceptionCheck())
753     {
754         throw GiwsException::JniCallMethodException(curEnv);
755     }
756     jint lenRow = curEnv->GetArrayLength(res);
757     jboolean isCopy = JNI_FALSE;
758
759     char **addr = new char*[lenRow];
760     jstring *resString = new jstring[lenRow];
761
762     for (jsize i = 0; i < lenRow; i++)
763     {
764         resString[i] = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i));
765         addr[i] = const_cast<char *>(curEnv->GetStringUTFChars(resString[i], &isCopy));
766     }
767     int lenCol = lenRow == 0 ? 0 : 1;
768     allocator.allocate(lenRow, lenCol, addr);
769     /*
770             SciErr err = createMatrixOfString(pvApiCtx, pos, lenCol, lenRow, addr);
771
772             for (jsize i = 0; i < lenRow; i++)
773             {
774                 curEnv->ReleaseStringUTFChars(resString[i], addr[i]);
775                 curEnv->DeleteLocalRef(resString[i]);
776                 }*/
777     delete[] addr;
778     delete[] resString;
779
780     // if (err.iErr)
781     // {
782     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
783     // }
784
785     curEnv->DeleteLocalRef(res);
786     curEnv->DeleteLocalRef(cls);
787     if (curEnv->ExceptionCheck())
788     {
789         throw GiwsException::JniCallMethodException(curEnv);
790     }
791 };
792
793 /*
794 template <typename T, typename U, class V>
795 void unwrapMat(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
796 {
797     SciErr err;
798     jint lenRow, lenCol;
799     jboolean isCopy = JNI_FALSE;
800     jarray oneDim;
801     JNIEnv * curEnv = NULL;
802     U *addr = NULL;
803
804     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
805     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
806
807     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMatMethodName(), V::getMatMethodSignature()) ;
808     if (id == NULL)
809     {
810         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMatMethodName());
811     }
812
813     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
814     if (curEnv->ExceptionCheck())
815     {
816         throw GiwsException::JniCallMethodException(curEnv);
817     }
818
819     lenRow = curEnv->GetArrayLength(res);
820     oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, 0));
821     lenCol = curEnv->GetArrayLength(oneDim);
822     curEnv->DeleteLocalRef(oneDim);
823
824 //    allocator.allocate(lenRow, lenCol, addr);
825
826     if (getMethodOfConv())
827     {
828         err = V::allocMatrix(pvApiCtx, pos, lenRow, lenCol, (void**) &addr);
829     }
830     else
831     {
832         err = V::allocMatrix(pvApiCtx, pos, lenCol, lenRow, (void**) &addr);
833     }
834
835     if (err.iErr)
836     {
837         curEnv->DeleteLocalRef(res);
838         throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
839     }
840
841     T *resultsArray;
842     for (int i = 0; i < lenRow; i++)
843     {
844         oneDim = reinterpret_cast<jarray>(curEnv->GetObjectArrayElement(res, i));
845         resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy));
846         if (getMethodOfConv())
847         {
848             for (int j = 0; j < lenCol; j++)
849             {
850                 addr[j * lenRow + i] = static_cast<U>(resultsArray[j]);
851             }
852         }
853         else
854         {
855             for (int j = 0; j < lenCol; j++)
856             {
857                 addr[i * lenCol + j] = static_cast<U>(resultsArray[j]);
858             }
859         }
860         curEnv->ReleasePrimitiveArrayCritical(oneDim, resultsArray, JNI_ABORT);
861         curEnv->DeleteLocalRef(oneDim);
862     }
863
864     curEnv->DeleteLocalRef(res);
865     if (curEnv->ExceptionCheck())
866     {
867         throw GiwsException::JniCallMethodException(curEnv);
868     }
869 }
870
871 template <typename T, typename U, class V>
872 void unwrapRow(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
873 {
874     SciErr err;
875     jint lenRow;
876     jboolean isCopy = JNI_FALSE;
877     JNIEnv * curEnv = NULL;
878     U *addr = NULL;
879
880     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
881     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
882
883     jmethodID id = curEnv->GetStaticMethodID(cls, V::getRowMethodName(), V::getRowMethodSignature());
884     if (id == NULL)
885     {
886         throw GiwsException::JniMethodNotFoundException(curEnv, V::getRowMethodName());
887     }
888
889     jobjectArray res = static_cast<jobjectArray>(curEnv->CallStaticObjectMethod(cls, id, javaID));
890     if (curEnv->ExceptionCheck())
891     {
892         curEnv->DeleteLocalRef(res);
893         throw GiwsException::JniCallMethodException(curEnv);
894     }
895
896     lenRow = curEnv->GetArrayLength(res);
897
898     // err = V::allocMatrix(pvApiCtx, pos, 1, lenRow, (void**) &addr);
899
900     // if (err.iErr)
901     // {
902     //     curEnv->DeleteLocalRef(res);
903     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
904     // }
905
906     T *resultsArray = static_cast<T *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy));
907     for (int i = 0; i < lenRow; i++)
908     {
909         addr[i] = static_cast<U>(resultsArray[i]);
910     }
911
912     allocator.allocate(lenRow, lenCol, addr);
913
914     curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT);
915     curEnv->DeleteLocalRef(res);
916     if (curEnv->ExceptionCheck())
917     {
918         throw GiwsException::JniCallMethodException(curEnv);
919     }
920 }
921
922 template <typename T, typename U, class V>
923 void unwrapSingle(JavaVM * jvm_, const bool methodOfConv, const int javaID, const ScilabStringStackAllocator & allocator)
924 {
925     SciErr err;
926     JNIEnv * curEnv = NULL;
927     U *addr = NULL;
928
929     jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL);
930     jclass cls = curEnv->FindClass(SCILABJAVAOBJECT);
931
932     jmethodID id = curEnv->GetStaticMethodID(cls, V::getMethodName(), V::getMethodSignature()) ;
933     if (id == NULL)
934     {
935         throw GiwsException::JniMethodNotFoundException(curEnv, V::getMethodName());
936     }
937
938     // err = V::allocMatrix(pvApiCtx, pos, 1, 1, (void**) &addr);
939
940     // if (err.iErr)
941     // {
942     //     throw org_scilab_modules_external_objects_java::NoMoreScilabMemoryException();
943     // }
944
945
946
947     *addr = static_cast<U>(V::getSingleVar(curEnv, cls, id, javaID));
948     allocator.allocate(lenRow, lenCol, addr);
949
950     if (curEnv->ExceptionCheck())
951     {
952         throw GiwsException::JniCallMethodException(curEnv);
953     }
954 */
955 }