2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - INRIA - Sylvestre LEDRU
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
15 package org.scilab.modules.javasci;
18 import java.io.FileNotFoundException;
20 import org.scilab.modules.types.ScilabType;
21 import org.scilab.modules.types.ScilabTypeEnum;
22 import org.scilab.modules.types.ScilabIntegerTypeEnum;
23 import org.scilab.modules.types.ScilabDouble;
24 import org.scilab.modules.types.ScilabList;
25 import org.scilab.modules.types.ScilabMList;
26 import org.scilab.modules.types.ScilabTList;
27 import org.scilab.modules.types.ScilabString;
28 import org.scilab.modules.types.ScilabBoolean;
29 import org.scilab.modules.types.ScilabBooleanSparse;
30 import org.scilab.modules.types.ScilabInteger;
31 import org.scilab.modules.types.ScilabPolynomial;
32 import org.scilab.modules.types.ScilabSparse;
33 import org.scilab.modules.javasci.Call_Scilab;
34 import org.scilab.modules.javasci.JavasciException.AlreadyRunningException;
35 import org.scilab.modules.javasci.JavasciException.InitializationException;
36 import org.scilab.modules.javasci.JavasciException.UnsupportedTypeException;
37 import org.scilab.modules.javasci.JavasciException.UndefinedVariableException;
38 import org.scilab.modules.javasci.JavasciException.UnknownTypeException;
39 import org.scilab.modules.javasci.JavasciException.ScilabInternalException;
40 import org.scilab.modules.javasci.JavasciException.ScilabErrorException;
43 * This class provides the capability to access to the Scilab engine from
44 * a Java application.<BR>
48 * Scilab sci = new Scilab();<BR>
49 * if (sci.open()) {<BR>
50 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
51 * ScilabDouble aOriginal = new ScilabDouble(a);<BR>
52 * sci.put("a",aOriginal);<BR>
53 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
56 * @see org.scilab.modules.types
60 private static int notHandledError = -999;
62 private String SCI = null;
63 private boolean advancedMode = false;
66 * Creator of the Scilab Javasci object. <BR>
68 * <LI>Scilab data path is autodetected (SCI) </LI>
69 * <LI>advanced features are disabled (no Java nor TCL/TK features) </LI>
72 public Scilab() throws InitializationException {
77 * Creator of the Scilab Javasci object with a specific Scilab path.<BR>
78 * Advanced features are disabled (no Java nor TCL/TK features)
82 * Scilab sci = new Scilab("/path/to/Scilab/data/dir/");<BR>
85 * @param SCI provide the path to Scilab data
87 public Scilab(String SCI) throws InitializationException {
92 * Creator of the Scilab Javasci object in advanced mode<BR>
93 * Scilab data path is autodetected
97 * Scilab sci = new Scilab(true); // Starts in advanced mode<BR>
100 * @param advancedMode true enables the advanced mode (GUI, graphics, Tcl/Tk, sciNotes...). Smaller.
102 public Scilab(boolean advancedMode) throws InitializationException {
103 this(null, advancedMode);
107 * Creator of the Scilab Javasci object. <BR>
108 * Under GNU/Linux / Mac OS X, try to detect Scilab base path<BR>
109 * if the property SCI is set, use it<BR>
110 * if not, try with the global variable SCI<BR>
111 * if not, throws a new exception<BR>
112 * Under Windows, use also the registery<BR>
116 * Scilab sci = new Scilab("/path/to/Scilab/data/dir/",true); // Starts in advanced mode<BR>
119 * @param SCIPath the path to Scilab data
120 * @param advancedMode true enables the advanced mode (GUI, graphics, Tcl/Tk, sciNotes...). Smaller.
122 public Scilab(String SCIPath, boolean advancedMode) throws InitializationException {
123 String SCI = SCIPath;
124 if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
128 SCI = System.getProperty("SCI");
129 if (SCI == null || SCI.length() == 0) {
130 SCI = System.getenv("SCI");
131 if (SCI == null || SCI.length() == 0) {
132 throw new InitializationException("Auto detection of SCI failed.\nSCI empty.");
135 } catch (Exception e) {
136 throw new InitializationException("Auto detection of SCI failed.\nCould not retrieve the variable SCI.", e);
140 this.advancedMode = advancedMode;
141 this.initScilab(SCI);
146 private void initScilab(String SCI) throws InitializationException {
147 /* Let Scilab engine knows that he is run through the Javasci API */
148 Call_Scilab.SetFromJavaToON();
149 if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
150 File f = new File(SCI);
151 if (!f.isDirectory()) {
152 throw new InitializationException("Could not find directory " + f.getAbsolutePath());
159 * Open a connection to the Scilab engine<BR>
160 * This function is based on Call_ScilabOpen from call_scilab<BR>
161 * Note: For now, only one instance of Scilab can be launched<BR>
162 * A second launch will return FALSE<BR>
166 * Scilab sci = new Scilab();<BR>
170 * @return if the operation is successful
171 * @throws AlreadyRunningException Scilab is already running
172 * @throws InitializationException Cannot start Scilab
174 public boolean open() throws JavasciException {
175 int res = Call_Scilab.Call_ScilabOpen(this.SCI, this.advancedMode, null, -1);
177 case 0: /* Success */
180 throw new AlreadyRunningException("Javasci already running.");
182 /* Should not occurd (processed before) */
183 throw new InitializationException("Could not find SCI.");
185 throw new InitializationException("No existing directory.");
187 throw new InitializationException("Stacksize failed (not enought memory ?).");
189 throw new InitializationException("Unknown startup error: " + res);
194 * Open a connection to the Scilab engine and run the command job<BR>
195 * This function is based on Call_ScilabOpen from call_scilab<BR>
196 * Note: For now, only one instance of Scilab can be launched<BR>
197 * A second launch will return FALSE<BR>
201 * Scilab sci = new Scilab();<BR>
202 * sci.open("a=%pi;");<BR>
205 * @param job The job to run on startup
206 * @return if the operation is successful
208 public boolean open(String job) throws JavasciException {
213 return this.exec(job);
217 * Open a connection to the Scilab engine and run commands job<BR>
218 * This function is based on Call_ScilabOpen from call_scilab<BR>
219 * Note: For now, only one instance of Scilab can be launched<BR>
220 * A second launch will return FALSE<BR>
224 * Scilab sci = new Scilab();<BR>
225 * sci.open(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
228 * @param jobs The serie of jobs to run on startup
229 * @return if the operation is successful
231 public boolean open(String jobs[]) throws JavasciException {
235 return this.exec(jobs);
240 * Open a connection to the Scilab engine and run thefile scriptFilename<BR>
241 * This function is based on Call_ScilabOpen from call_scilab<BR>
242 * Note: For now, only one instance of Scilab can be launched<BR>
243 * A second launch will return FALSE<BR>
247 * Scilab sci = new Scilab();<BR>
248 * sci.open(new File("/tmp/myscript.sce"));<BR>
251 * @param scriptFilename The script to execute on startup
252 * @return if the operation is successful
254 public boolean open(File scriptFilename) throws JavasciException, FileNotFoundException {
259 return this.exec(scriptFilename);
264 * Execute a single command in Scilab<BR>
265 * This function is based on SendScilabJob from call_scilab
269 * sci.exec("a=2*%pi");<BR>
272 * @param job the job to execute
273 * @return if the operation is successful
275 public boolean exec(String job) {
277 this.execException(job);
279 } catch (Exception e) {
286 * Execute a single command in Scilab<BR>
287 * Returns a ScilabErrorException in case of Scilab problem<BR>
288 * This function is based on SendScilabJob from call_scilab
292 * sci.exec("a=2*%pi");<BR>
295 * @param job the job to execute
298 public void execException(String job) throws ScilabErrorException {
299 int result = Call_Scilab.SendScilabJob(job);
301 throw new ScilabErrorException("A Scilab error occurred: " + this.getLastErrorMessage(), this.getLastErrorCode());
307 * Execute several commands in Scilab<BR>
308 * This function is based on SendScilabJob from call_scilab
312 * sci.exec(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
315 * @param jobs the serie of job to execute
316 * @return if the operation is successful
318 public boolean exec(String jobs[]) {
320 this.execException(jobs);
322 } catch (Exception e) {
328 * Execute several commands in Scilab<BR>
329 * Returns a ScilabErrorException in case of Scilab problem<BR>
330 * This function is based on SendScilabJob from call_scilab
334 * sci.exec(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
337 * @param jobs the serie of job to execute
340 public void execException(String jobs[]) throws ScilabErrorException {
341 int result = Call_Scilab.SendScilabJobs(jobs, jobs.length);
343 throw new ScilabErrorException("A Scilab error occurred: " + this.getLastErrorMessage(), this.getLastErrorCode());
348 * Execute a Scilab script .sce/.sci and throws an exception in case<BR>
349 * of a Scilab error<BR>
350 * Returns a ScilabErrorException in case of Scilab problem<BR>
351 * This function is based on SendScilabJob from call_scilab<BR>
352 * Note that this function is a direct call on the Scilab function exec:
353 * <code> this.exec("exec('" + scriptFilename + "');");</code>
357 * sci.exec(new File("/tmp/myscript.sci"));<BR>
360 * @param scriptFilename the script to execute
363 public void execException(File scriptFilename) throws FileNotFoundException, ScilabErrorException {
364 if (!scriptFilename.exists()) {
365 throw new FileNotFoundException("Could not find " + scriptFilename);
367 this.execException("exec('" + scriptFilename + "');");
371 * Execute a Scilab script .sce/.sci and throws an exception in case<BR>
372 * the file is not found<BR>
373 * This function is based on SendScilabJob from call_scilab<BR>
374 * Note that this function is a direct call on the Scilab function exec:
375 * <code> this.exec("exec('" + scriptFilename + "');");</code>
379 * sci.exec(new File("/tmp/myscript.sci"));<BR>
382 * @param scriptFilename the script to execute
383 * @return if the operation is successful
385 public boolean exec(File scriptFilename) throws FileNotFoundException {
386 if (!scriptFilename.exists()) {
387 throw new FileNotFoundException("Could not find " + scriptFilename);
389 return this.exec("exec('" + scriptFilename + "');");
394 * Detect if a variable (varname) exists in Scilab
398 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
399 * ScilabDouble aOriginal = new ScilabDouble(a);<BR>
400 * sci.put("a",aOriginal);<BR>
401 * assert sci.isExistingVariable("a") == true;<BR>
404 * @param varname the variable to check
405 * @return if the variable exists or not
407 public boolean isExistingVariable(String varname) {
408 return Call_Scilab.isExistingVariable(varname);
413 * Shutdown Scilab<BR>
414 * This function is based on TerminateScilab from call_scilab
421 * @return if the operation is successful
423 public boolean close() {
424 return Call_Scilab.TerminateScilab(null);
429 * Return the last error code
433 * sci.open("a=1+"); // Wrong operation<BR>
434 * sci.getLastErrorCode() // Returns 2<BR>
437 * @return the error code
439 public int getLastErrorCode() {
440 return Call_Scilab.GetLastErrorCode();
445 * Return the last error message
449 * sci.open("a=1+");<BR>
450 * System.err.println(sci.getLastErrorMessage());<BR>
453 * @return the error message itself
455 public String getLastErrorMessage() {
456 return Call_Scilab.getLastErrorMessage();
461 * Detect if a Scilab graphic window is still opened<BR>
462 * This function is based on ScilabHaveAGraph from call_scilab
466 * sci.exec("plot3d();");<BR>
467 * sci.isGraphicOpened();<BR>
470 * @return if the graphic is open or not
472 public boolean isGraphicOpened() {
473 return Call_Scilab.isGraphicOpened();
477 * Return the code type of a variable varname
481 * sci.exec("a = 2*%pi");<BR>
482 * if (sci.getVariableType("a") == ScilabTypeEnum.sci_matrix) {<BR>
483 * System.out.println("a is a double matrix");<BR>
487 * @param varName the name of the variable
488 * @return the type of the variable
489 * @throws UndefinedVariableException The variable does not exist
490 * @throws UnknownTypeException Cannot find the type
492 public ScilabTypeEnum getVariableType(String varName) throws JavasciException {
493 return getVariableTypeInCurrentScilabSession(varName);
497 * Return the code type of a variable varname in the current Scilab session
501 * sci.exec("a = 2*%pi");<BR>
502 * if (sci.getVariableType("a") == ScilabTypeEnum.sci_matrix) {<BR>
503 * System.out.println("a is a double matrix");<BR>
507 * @param varName the name of the variable
508 * @return the type of the variable
509 * @throws UndefinedVariableException The variable does not exist
510 * @throws UnknownTypeException Cannot find the type
512 public static ScilabTypeEnum getVariableTypeInCurrentScilabSession(String varName) throws JavasciException {
513 ScilabTypeEnum variableType = null;
515 variableType = Call_Scilab.getVariableType(varName);
516 if (variableType == null ) {
517 throw new UndefinedVariableException("Could not find the type of the variable '" + varName + "'");
519 } catch (IllegalArgumentException e) {
520 String lastWord = e.getMessage().substring(e.getMessage().lastIndexOf(' ') + 1);
521 if (lastWord.equals("-2")) { /* Crappy workaround. Parse the exception */
522 throw new UndefinedVariableException("Could not find variable '" + varName + "'");
524 throw new UnknownTypeException("Type of " + varName + " unknown");
531 * Returns a variable named varname<BR>
532 * Throws an exception if the datatype is not managed or if the variable is not available
536 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
537 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
538 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
539 * sci.put("a",aOriginal);<BR>
540 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
543 * @param varname the name of the variable
544 * @return return the variable
545 * @throws UnsupportedTypeException Type not managed yet.
547 public ScilabType get(String varname) throws JavasciException {
548 return getInCurrentScilabSession(varname);
552 * Returns a reference variable named varname<BR>
553 * Throws an exception if the datatype is not managed or if the variable is not available
557 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
558 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
559 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
560 * sci.put("a",aOriginal);<BR>
561 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
564 * @param varname the name of the variable
565 * @return return the variable
566 * @throws UnsupportedTypeException Type not managed yet.
568 public ScilabType getByReference(String varname) throws JavasciException {
569 return getInCurrentScilabSession(varname, true);
573 * Returns a variable named varname in the current Scilab session<BR>
574 * Throws an exception if the datatype is not managed or if the variable is not available
578 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
579 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
580 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
581 * sci.put("a",aOriginal);<BR>
582 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
585 * @param varname the name of the variable
586 * @return return the variable
587 * @throws UnsupportedTypeException Type not managed yet.
589 public static ScilabType getInCurrentScilabSession(String varname) throws JavasciException {
590 return getInCurrentScilabSession(varname, false);
594 * Returns a variable named varname in the current Scilab session<BR>
595 * Throws an exception if the datatype is not managed or if the variable is not available
599 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
600 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
601 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
602 * sci.put("a",aOriginal);<BR>
603 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
606 * @param varname the name of the variable
607 * @return return the variable
608 * @throws UnsupportedTypeException Type not managed yet.
610 public static ScilabType getInCurrentScilabSession(String varname, boolean byref) throws JavasciException {
611 ScilabTypeEnum sciType = getVariableTypeInCurrentScilabSession(varname);
619 case sci_boolean_sparse:
623 return ScilabVariablesJavasci.getScilabVariable(varname, true, byref);
625 ScilabIntegerTypeEnum typeInt = Call_Scilab.getIntegerPrecision(varname);
634 return ScilabVariablesJavasci.getScilabVariable(varname, true, byref);
637 // will be available in Scilab 6
638 throw new UnsupportedTypeException("64 bit (signed and unsigned) integer types not managed in Scilab 5.X");
643 throw new UnsupportedTypeException("Type not managed: " + sciType);
648 * Send to Scilab a variable theVariable named varname<BR>
649 * Throws an exception if the datatype is not managed or if the variable is not available
653 * boolean [][]a={{true, true, false, false},{true, false, true, false}};<BR>
654 * ScilabBoolean aOriginal = new ScilabBoolean(a);<BR>
655 * sci.put("a",aOriginal);<BR>
656 * ScilabBoolean aFromScilab = (ScilabBoolean)sci.get("a");<BR>
659 * @param varname the name of the variable
660 * @param theVariable the variable itself
661 * @return true if the operation is successful
662 * @throws UnsupportedTypeException Type not managed yet.
664 public boolean put(String varname, ScilabType theVariable) throws JavasciException {
665 return putInCurrentScilabSession(varname, theVariable);
669 * Send to the current Scilab session a variable theVariable named varname<BR>
670 * Throws an exception if the datatype is not managed or if the variable is not available
674 * boolean [][]a={{true, true, false, false},{true, false, true, false}};<BR>
675 * ScilabBoolean aOriginal = new ScilabBoolean(a);<BR>
676 * sci.put("a",aOriginal);<BR>
677 * ScilabBoolean aFromScilab = (ScilabBoolean)sci.get("a");<BR>
680 * @param varname the name of the variable
681 * @param theVariable the variable itself
682 * @return true if the operation is successful
683 * @throws UnsupportedTypeException Type not managed yet.
685 public static boolean putInCurrentScilabSession(String varname, ScilabType theVariable) throws JavasciException {
686 int err = notHandledError; /* -999: if the type is not handled */
688 switch (theVariable.getType()) {
690 ScilabDouble sciDouble = (ScilabDouble) theVariable;
691 if (sciDouble.isReal()) {
692 err = Call_Scilab.putDouble(varname, sciDouble.getRealPart());
694 err = Call_Scilab.putDoubleComplex(varname, sciDouble.getRealPart(), sciDouble.getImaginaryPart());
698 ScilabPolynomial sciPoly = (ScilabPolynomial) theVariable;
699 if (sciPoly.isReal()) {
700 err = Call_Scilab.putPolynomial(varname, sciPoly.getPolyVarName(), sciPoly.getRealPart());
702 err = Call_Scilab.putComplexPolynomial(varname, sciPoly.getPolyVarName(), sciPoly.getRealPart(), sciPoly.getImaginaryPart());
706 ScilabBoolean sciBoolean = (ScilabBoolean) theVariable;
707 err = Call_Scilab.putBoolean(varname, sciBoolean.getData());
710 ScilabSparse sciSparse = (ScilabSparse) theVariable;
711 if (sciSparse.isReal()) {
712 err = Call_Scilab.putSparse(varname, sciSparse.getHeight(), sciSparse.getWidth(), sciSparse.getNbItemRow(), sciSparse.getScilabColPos(), sciSparse.getRealPart());
714 err = Call_Scilab.putComplexSparse(varname, sciSparse.getHeight(), sciSparse.getWidth(), sciSparse.getNbItemRow(), sciSparse.getScilabColPos(), sciSparse.getRealPart(), sciSparse.getImaginaryPart());
717 case sci_boolean_sparse :
718 ScilabBooleanSparse sciBooleanSparse = (ScilabBooleanSparse) theVariable;
719 err = Call_Scilab.putBooleanSparse(varname, sciBooleanSparse.getHeight(), sciBooleanSparse.getWidth(), sciBooleanSparse.getNbItemRow(), sciBooleanSparse.getScilabColPos());
722 ScilabInteger sciInteger = (ScilabInteger) theVariable;
723 switch (sciInteger.getPrec()) {
725 err = Call_Scilab.putUnsignedByte(varname, sciInteger.getDataAsByte());
728 err = Call_Scilab.putByte(varname, sciInteger.getDataAsByte());
731 err = Call_Scilab.putUnsignedShort(varname, sciInteger.getDataAsShort());
734 err = Call_Scilab.putShort(varname, sciInteger.getDataAsShort());
737 err = Call_Scilab.putUnsignedInt(varname, sciInteger.getDataAsInt());
740 err = Call_Scilab.putInt(varname, sciInteger.getDataAsInt());
743 // err = Call_Scilab.putUnsignedLong(varname, sciInteger.getData_());
745 // err = Call_Scilab.putLong(varname, sciInteger.getData_());
750 ScilabString sciString = (ScilabString) theVariable;
751 err = Call_Scilab.putString(varname, sciString.getData());
754 ScilabList sciList = (ScilabList) theVariable;
755 err = Call_ScilabJNI.putList(varname, sciList.getSerializedObject(), 'l');
758 ScilabTList sciTList = (ScilabTList) theVariable;
759 err = Call_ScilabJNI.putList(varname, sciTList.getSerializedObject(), 't');
762 ScilabMList sciMList = (ScilabMList) theVariable;
763 err = Call_ScilabJNI.putList(varname, sciMList.getSerializedObject(), 'm');
767 if (err == notHandledError) {
768 throw new UnsupportedTypeException("Type not managed: " + theVariable.getClass());
771 throw new ScilabInternalException("Storage of the variable '" + varname + "' (" + theVariable.getClass() + ") failed.");