2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - INRIA - Sylvestre LEDRU
4 * Copyright (C) 2018 - ESI Group - Clement DAVID
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
16 package org.scilab.modules.javasci;
19 import java.io.FileNotFoundException;
21 import org.scilab.modules.types.ScilabType;
22 import org.scilab.modules.types.ScilabTypeEnum;
23 import org.scilab.modules.types.ScilabIntegerTypeEnum;
24 import org.scilab.modules.types.ScilabDouble;
25 import org.scilab.modules.types.ScilabList;
26 import org.scilab.modules.types.ScilabMList;
27 import org.scilab.modules.types.ScilabTList;
28 import org.scilab.modules.types.ScilabString;
29 import org.scilab.modules.types.ScilabBoolean;
30 import org.scilab.modules.types.ScilabBooleanSparse;
31 import org.scilab.modules.types.ScilabInteger;
32 import org.scilab.modules.types.ScilabPolynomial;
33 import org.scilab.modules.types.ScilabSparse;
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>
71 * @throws InitializationException when Scilab installation is not detected or the <pre>SCI</pre> variable is not setup correctly.
73 public Scilab() throws InitializationException {
78 * Creator of the Scilab Javasci object with a specific Scilab path.<BR>
79 * Advanced features are disabled (no Java nor TCL/TK features)
83 * Scilab sci = new Scilab("/path/to/Scilab/data/dir/");<BR>
86 * @param SCI provide the path to Scilab data
87 * @throws InitializationException when Scilab installation is not detected or the <pre>SCI</pre> variable is not setup correctly.
89 public Scilab(String SCI) throws InitializationException {
94 * Creator of the Scilab Javasci object in advanced mode<BR>
95 * Scilab data path is autodetected
99 * Scilab sci = new Scilab(true); // Starts in advanced mode<BR>
102 * @param advancedMode true enables the advanced mode (GUI, graphics, Tcl/Tk, sciNotes...). Smaller.
103 * @throws InitializationException when Scilab installation is not detected or the <pre>SCI</pre> variable is not setup correctly.
105 public Scilab(boolean advancedMode) throws InitializationException {
106 this(null, advancedMode);
110 * Creator of the Scilab Javasci object. <BR>
111 * Under GNU/Linux / Mac OS X, try to detect Scilab base path<BR>
112 * if the property SCI is set, use it<BR>
113 * if not, try with the global variable SCI<BR>
114 * if not, throws a new exception<BR>
115 * Under Windows, use also the registery<BR>
119 * Scilab sci = new Scilab("/path/to/Scilab/data/dir/",true); // Starts in advanced mode<BR>
122 * @param SCIPath the path to Scilab data
123 * @param advancedMode true enables the advanced mode (GUI, graphics, Tcl/Tk, sciNotes...). Smaller.
124 * @throws InitializationException when Scilab installation is not detected or the <pre>SCI</pre> variable is not setup correctly.
126 public Scilab(String SCIPath, boolean advancedMode) throws InitializationException {
127 String sci = SCIPath;
128 if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
132 sci = System.getProperty("SCI");
133 if (sci == null || sci.length() == 0) {
134 sci = System.getenv("SCI");
135 if (sci == null || sci.length() == 0) {
136 throw new InitializationException("Auto detection of SCI failed.\nSCI empty.");
139 } catch (Exception e) {
140 throw new InitializationException("Auto detection of SCI failed.\nCould not retrieve the variable SCI.", e);
144 this.advancedMode = advancedMode;
145 this.initScilab(sci);
150 private void initScilab(String SCI) throws InitializationException {
151 /* Let Scilab engine knows that he is run through the Javasci API */
152 Call_Scilab.SetFromJavaToON();
153 if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
154 File f = new File(SCI);
155 if (!f.isDirectory()) {
156 throw new InitializationException("Could not find directory " + f.getAbsolutePath());
163 * Open a connection to the Scilab engine<BR>
164 * This function is based on Call_ScilabOpen from call_scilab<BR>
165 * Note: For now, only one instance of Scilab can be launched<BR>
166 * A second launch will return FALSE<BR>
170 * Scilab sci = new Scilab();<BR>
174 * @return if the operation is successful
175 * @throws AlreadyRunningException Scilab is already running
176 * @throws JavasciException when the connection to Scilab encountered an issue.
178 public boolean open() throws JavasciException {
179 int res = Call_Scilab.Call_ScilabOpen(this.SCI, this.advancedMode, null, -1);
181 case 0: /* Success */
184 throw new AlreadyRunningException("Javasci already running.");
186 /* Should not occurd (processed before) */
187 throw new InitializationException("Could not find SCI.");
189 throw new InitializationException("No existing directory.");
191 throw new InitializationException("Stacksize failed (not enought memory ?).");
193 throw new InitializationException("Unknown startup error: " + res);
198 * Open a connection to the Scilab engine and run the command job<BR>
199 * This function is based on Call_ScilabOpen from call_scilab<BR>
200 * Note: For now, only one instance of Scilab can be launched<BR>
201 * A second launch will return FALSE<BR>
205 * Scilab sci = new Scilab();<BR>
206 * sci.open("a=%pi;");<BR>
209 * @param job The job to run on startup
210 * @return if the operation is successful
211 * @throws JavasciException when the connection to Scilab encountered an issue.
213 public boolean open(String job) throws JavasciException {
218 return this.exec(job);
222 * Open a connection to the Scilab engine and run commands job<BR>
223 * This function is based on Call_ScilabOpen from call_scilab<BR>
224 * Note: For now, only one instance of Scilab can be launched<BR>
225 * A second launch will return FALSE<BR>
229 * Scilab sci = new Scilab();<BR>
230 * sci.open(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
233 * @param jobs The serie of jobs to run on startup
234 * @return if the operation is successful
235 * @throws JavasciException when the connection to Scilab encountered an issue.
237 public boolean open(String jobs[]) throws JavasciException {
241 return this.exec(jobs);
246 * Open a connection to the Scilab engine and run thefile scriptFilename<BR>
247 * This function is based on Call_ScilabOpen from call_scilab<BR>
248 * Note: For now, only one instance of Scilab can be launched<BR>
249 * A second launch will return FALSE<BR>
253 * Scilab sci = new Scilab();<BR>
254 * sci.open(new File("/tmp/myscript.sce"));<BR>
257 * @param scriptFilename The script to execute on startup
258 * @return if the operation is successful
259 * @throws JavasciException when the connection to Scilab encountered an issue.
260 * @throws FileNotFoundException if the passed <code>scriptFilename</code> is not a valid Scilab file.
262 public boolean open(File scriptFilename) throws JavasciException, FileNotFoundException {
267 return this.exec(scriptFilename);
272 * Execute a single command in Scilab<BR>
273 * This function is based on SendScilabJob from call_scilab
277 * sci.exec("a=2*%pi");<BR>
280 * @param job the job to execute
281 * @return if the operation is successful
283 public boolean exec(String job) {
285 this.execException(job);
287 } catch (ScilabErrorException e) {
294 * Execute a single command in Scilab<BR>
295 * Returns a ScilabErrorException in case of Scilab problem<BR>
296 * This function is based on SendScilabJob from call_scilab
300 * sci.exec("a=2*%pi");<BR>
303 * @param job the job to execute
305 * @throws ScilabErrorException when the connection to Scilab or the Scilab execution encountered an issue.
307 public void execException(String job) throws ScilabErrorException {
308 int result = Call_Scilab.SendScilabJob(job);
310 throw new ScilabErrorException("A Scilab error occurred: " + this.getLastErrorMessage(), this.getLastErrorCode());
316 * Execute several commands in Scilab<BR>
317 * This function is based on SendScilabJob from call_scilab
321 * sci.exec(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
324 * @param jobs the serie of job to execute
325 * @return if the operation is successful
327 public boolean exec(String jobs[]) {
329 this.execException(jobs);
331 } catch (ScilabErrorException e) {
337 * Execute several commands in Scilab<BR>
338 * Returns a ScilabErrorException in case of Scilab problem<BR>
339 * This function is based on SendScilabJob from call_scilab
343 * sci.exec(new String[]{"a=42*2;","b=44*2", "c=(a==b)"});<BR>
346 * @param jobs the serie of job to execute
348 * @throws ScilabErrorException when the connection to Scilab or the Scilab execution encountered an issue.
350 public void execException(String jobs[]) throws ScilabErrorException {
351 int result = Call_Scilab.SendScilabJobs(jobs, jobs.length);
353 throw new ScilabErrorException("A Scilab error occurred: " + this.getLastErrorMessage(), this.getLastErrorCode());
358 * Execute a Scilab script .sce/.sci and throws an exception in case<BR>
359 * of a Scilab error<BR>
360 * Returns a ScilabErrorException in case of Scilab problem<BR>
361 * This function is based on SendScilabJob from call_scilab<BR>
362 * Note that this function is a direct call on the Scilab function exec:
363 * <code> this.exec("exec('" + scriptFilename + "');");</code>
367 * sci.exec(new File("/tmp/myscript.sci"));<BR>
370 * @param scriptFilename the script to execute
372 * @throws FileNotFoundException if the passed <code>scriptFilename</code> is not a valid Scilab file.
373 * @throws ScilabErrorException when the connection to Scilab or the Scilab execution encountered an issue.
375 public void execException(File scriptFilename) throws FileNotFoundException, ScilabErrorException {
376 if (!scriptFilename.exists()) {
377 throw new FileNotFoundException("Could not find " + scriptFilename);
379 this.execException("exec('" + scriptFilename + "');");
383 * Execute a Scilab script .sce/.sci and throws an exception in case<BR>
384 * the file is not found<BR>
385 * This function is based on SendScilabJob from call_scilab<BR>
386 * Note that this function is a direct call on the Scilab function exec:
387 * <code> this.exec("exec('" + scriptFilename + "');");</code>
391 * sci.exec(new File("/tmp/myscript.sci"));<BR>
394 * @param scriptFilename the script to execute
395 * @return if the operation is successful
396 * @throws FileNotFoundException if the passed <code>scriptFilename</code> is not a valid Scilab file.
398 public boolean exec(File scriptFilename) throws FileNotFoundException {
399 if (!scriptFilename.exists()) {
400 throw new FileNotFoundException("Could not find " + scriptFilename);
402 return this.exec("exec('" + scriptFilename + "');");
407 * Detect if a variable (varname) exists in Scilab
411 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
412 * ScilabDouble aOriginal = new ScilabDouble(a);<BR>
413 * sci.put("a",aOriginal);<BR>
414 * assert sci.isExistingVariable("a") == true;<BR>
417 * @param varname the variable to check
418 * @return if the variable exists or not
420 public boolean isExistingVariable(String varname) {
421 return Call_Scilab.isExistingVariable(varname);
426 * Shutdown Scilab<BR>
427 * This function is based on TerminateScilab from call_scilab
434 * @return if the operation is successful
436 public boolean close() {
437 return Call_Scilab.TerminateScilab(null);
442 * Return the last error code
446 * sci.open("a=1+"); // Wrong operation<BR>
447 * sci.getLastErrorCode() // Returns 2<BR>
450 * @return the error code
452 public int getLastErrorCode() {
453 return Call_Scilab.GetLastErrorCode();
458 * Return the last error message
462 * sci.open("a=1+");<BR>
463 * System.err.println(sci.getLastErrorMessage());<BR>
466 * @return the error message itself
468 public String getLastErrorMessage() {
469 return Call_Scilab.getLastErrorMessage();
474 * Detect if a Scilab graphic window is still opened<BR>
475 * This function is based on ScilabHaveAGraph from call_scilab
479 * sci.exec("plot3d();");<BR>
480 * sci.isGraphicOpened();<BR>
483 * @return if the graphic is open or not
485 public boolean isGraphicOpened() {
486 return Call_Scilab.isGraphicOpened();
490 * Return the code type of a variable varname
494 * sci.exec("a = 2*%pi");<BR>
495 * if (sci.getVariableType("a") == ScilabTypeEnum.sci_matrix) {<BR>
496 * System.out.println("a is a double matrix");<BR>
500 * @param varName the name of the variable
501 * @return the type of the variable
502 * @throws UndefinedVariableException The variable does not exist
503 * @throws UnknownTypeException Cannot find the type
505 public ScilabTypeEnum getVariableType(String varName) throws JavasciException {
506 return getVariableTypeInCurrentScilabSession(varName);
510 * Return the code type of a variable varname in the current Scilab session
514 * sci.exec("a = 2*%pi");<BR>
515 * if (sci.getVariableType("a") == ScilabTypeEnum.sci_matrix) {<BR>
516 * System.out.println("a is a double matrix");<BR>
520 * @param varName the name of the variable
521 * @return the type of the variable
522 * @throws UndefinedVariableException The variable does not exist
523 * @throws UnknownTypeException Cannot find the type
525 public static ScilabTypeEnum getVariableTypeInCurrentScilabSession(String varName) throws JavasciException {
526 ScilabTypeEnum variableType = null;
528 variableType = Call_Scilab.getVariableType(varName);
529 if (variableType == null ) {
530 throw new UndefinedVariableException("Could not find the type of the variable '" + varName + "'");
532 } catch (IllegalArgumentException e) {
533 String lastWord = e.getMessage().substring(e.getMessage().lastIndexOf(' ') + 1);
534 if (lastWord.equals("-2")) { /* Crappy workaround. Parse the exception */
535 throw new UndefinedVariableException("Could not find variable '" + varName + "'");
537 throw new UnknownTypeException("Type of " + varName + " unknown");
544 * Returns a variable named varname<BR>
545 * Throws an exception if the datatype is not managed or if the variable is not available
549 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
550 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
551 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
552 * sci.put("a",aOriginal);<BR>
553 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
556 * @param varname the name of the variable
557 * @return return the variable
558 * @throws UnsupportedTypeException Type not managed yet.
560 public ScilabType get(String varname) throws JavasciException {
561 return getInCurrentScilabSession(varname);
565 * Returns a reference variable named varname<BR>
566 * Throws an exception if the datatype is not managed or if the variable is not available
570 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
571 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
572 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
573 * sci.put("a",aOriginal);<BR>
574 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
577 * @param varname the name of the variable
578 * @return return the variable
579 * @throws UnsupportedTypeException Type not managed yet.
581 public ScilabType getByReference(String varname) throws JavasciException {
582 return getInCurrentScilabSession(varname, true);
586 * Returns a variable named varname in the current Scilab session<BR>
587 * Throws an exception if the datatype is not managed or if the variable is not available
591 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
592 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
593 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
594 * sci.put("a",aOriginal);<BR>
595 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
598 * @param varname the name of the variable
599 * @return return the variable
600 * @throws UnsupportedTypeException Type not managed yet.
602 public static ScilabType getInCurrentScilabSession(String varname) throws JavasciException {
603 return getInCurrentScilabSession(varname, false);
607 * Returns a variable named varname in the current Scilab session<BR>
608 * Throws an exception if the datatype is not managed or if the variable is not available
612 * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
613 * double [][]aImg={{212.2, 221.0, 423.0, 393.0},{234.2, 244.0, 441.0, 407.0}};<BR>
614 * ScilabDouble aOriginal = new ScilabDouble(a, aImg);<BR>
615 * sci.put("a",aOriginal);<BR>
616 * ScilabDouble aFromScilab = (ScilabDouble)sci.get("a");<BR>
619 * @param varname the name of the variable
620 * @param byref the data buffer is shared (not copied) between Scilab and the returned ScilabType value.
621 * @return return the variable
622 * @throws UnsupportedTypeException Type not managed yet.
624 public static ScilabType getInCurrentScilabSession(String varname, boolean byref) throws JavasciException {
625 ScilabTypeEnum sciType = getVariableTypeInCurrentScilabSession(varname);
633 case sci_boolean_sparse:
637 return ScilabVariablesJavasci.getScilabVariable(varname, true, byref);
639 ScilabIntegerTypeEnum typeInt = Call_Scilab.getIntegerPrecision(varname);
648 return ScilabVariablesJavasci.getScilabVariable(varname, true, byref);
651 // will be available in Scilab 6
652 throw new UnsupportedTypeException("64 bit (signed and unsigned) integer types not managed in Scilab 5.X");
657 throw new UnsupportedTypeException("Type not managed: " + sciType);
662 * Send to Scilab a variable theVariable named varname<BR>
663 * Throws an exception if the datatype is not managed or if the variable is not available
667 * boolean [][]a={{true, true, false, false},{true, false, true, false}};<BR>
668 * ScilabBoolean aOriginal = new ScilabBoolean(a);<BR>
669 * sci.put("a",aOriginal);<BR>
670 * ScilabBoolean aFromScilab = (ScilabBoolean)sci.get("a");<BR>
673 * @param varname the name of the variable
674 * @param theVariable the variable itself
675 * @return true if the operation is successful
676 * @throws UnsupportedTypeException Type not managed yet.
678 public boolean put(String varname, ScilabType theVariable) throws JavasciException {
679 return putInCurrentScilabSession(varname, theVariable);
683 * Send to the current Scilab session a variable theVariable named varname<BR>
684 * Throws an exception if the datatype is not managed or if the variable is not available
688 * boolean [][]a={{true, true, false, false},{true, false, true, false}};<BR>
689 * ScilabBoolean aOriginal = new ScilabBoolean(a);<BR>
690 * sci.put("a",aOriginal);<BR>
691 * ScilabBoolean aFromScilab = (ScilabBoolean)sci.get("a");<BR>
694 * @param varname the name of the variable
695 * @param theVariable the variable itself
696 * @return true if the operation is successful
697 * @throws UnsupportedTypeException Type not managed yet.
699 public static boolean putInCurrentScilabSession(String varname, ScilabType theVariable) throws JavasciException {
700 int err = notHandledError; /* -999: if the type is not handled */
702 switch (theVariable.getType()) {
704 ScilabDouble sciDouble = (ScilabDouble) theVariable;
705 if (sciDouble.isReal()) {
706 err = Call_Scilab.putDouble(varname, sciDouble.getRealPart());
708 err = Call_Scilab.putDoubleComplex(varname, sciDouble.getRealPart(), sciDouble.getImaginaryPart());
712 ScilabPolynomial sciPoly = (ScilabPolynomial) theVariable;
713 if (sciPoly.isReal()) {
714 err = Call_Scilab.putPolynomial(varname, sciPoly.getPolyVarName(), sciPoly.getRealPart());
716 err = Call_Scilab.putComplexPolynomial(varname, sciPoly.getPolyVarName(), sciPoly.getRealPart(), sciPoly.getImaginaryPart());
720 ScilabBoolean sciBoolean = (ScilabBoolean) theVariable;
721 err = Call_Scilab.putBoolean(varname, sciBoolean.getData());
724 ScilabSparse sciSparse = (ScilabSparse) theVariable;
725 if (sciSparse.isReal()) {
726 err = Call_Scilab.putSparse(varname, sciSparse.getHeight(), sciSparse.getWidth(), sciSparse.getNbItemRow(), sciSparse.getScilabColPos(), sciSparse.getRealPart());
728 err = Call_Scilab.putComplexSparse(varname, sciSparse.getHeight(), sciSparse.getWidth(), sciSparse.getNbItemRow(), sciSparse.getScilabColPos(), sciSparse.getRealPart(), sciSparse.getImaginaryPart());
731 case sci_boolean_sparse :
732 ScilabBooleanSparse sciBooleanSparse = (ScilabBooleanSparse) theVariable;
733 err = Call_Scilab.putBooleanSparse(varname, sciBooleanSparse.getHeight(), sciBooleanSparse.getWidth(), sciBooleanSparse.getNbItemRow(), sciBooleanSparse.getScilabColPos());
736 ScilabInteger sciInteger = (ScilabInteger) theVariable;
737 switch (sciInteger.getPrec()) {
739 err = Call_Scilab.putUnsignedByte(varname, sciInteger.getDataAsByte());
742 err = Call_Scilab.putByte(varname, sciInteger.getDataAsByte());
745 err = Call_Scilab.putUnsignedShort(varname, sciInteger.getDataAsShort());
748 err = Call_Scilab.putShort(varname, sciInteger.getDataAsShort());
751 err = Call_Scilab.putUnsignedInt(varname, sciInteger.getDataAsInt());
754 err = Call_Scilab.putInt(varname, sciInteger.getDataAsInt());
757 // err = Call_Scilab.putUnsignedLong(varname, sciInteger.getData_());
759 // err = Call_Scilab.putLong(varname, sciInteger.getData_());
764 ScilabString sciString = (ScilabString) theVariable;
765 err = Call_Scilab.putString(varname, sciString.getData());
768 ScilabList sciList = (ScilabList) theVariable;
769 err = Call_ScilabJNI.putList(varname, sciList.getSerializedObject(), 'l');
772 ScilabTList sciTList = (ScilabTList) theVariable;
773 err = Call_ScilabJNI.putList(varname, sciTList.getSerializedObject(), 't');
776 ScilabMList sciMList = (ScilabMList) theVariable;
777 err = Call_ScilabJNI.putList(varname, sciMList.getSerializedObject(), 'm');
781 if (err == notHandledError) {
782 throw new UnsupportedTypeException("Type not managed: " + theVariable.getClass());
785 throw new ScilabInternalException("Storage of the variable '" + varname + "' (" + theVariable.getClass() + ") failed.");