Coverage Report - eu.simuline.octave.OctaveEngineFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
OctaveEngineFactory
64%
24/37
25%
2/8
1.5
 
 1  
 /*
 2  
  * Copyright 2008 Ange Optimization ApS
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 /**
 17  
  * @author Kim Hansen
 18  
  */
 19  
 package eu.simuline.octave;
 20  
 
 21  
 import java.io.File;
 22  
 import java.io.OutputStreamWriter;
 23  
 import java.io.Writer;
 24  
 
 25  
 import java.util.Arrays;
 26  
 
 27  
 /**
 28  
  * Factory that creates OctaveEngines. 
 29  
  * First of all, create an OctaveEngineFactory 
 30  
  * using the default constructor {@link #OctaveEngineFactory()} 
 31  
  * then, optionally, change parameters 
 32  
  * and finally create an Octave Engine using {@link #getScriptEngine()} 
 33  
  * with the current parameters. 
 34  
  * To set a parameter, use the various setter methods. 
 35  
  * In the documentation of each setter method, 
 36  
  * also the default value is documented 
 37  
  * which is used to create an {@link OctaveEngine} 
 38  
  * if the setter method is not invoked. 
 39  
  * 
 40  
  */
 41  
 public final class OctaveEngineFactory {
 42  
 
 43  
     /**
 44  
      * System property where the executable is found. 
 45  
      */
 46  
     public static final String PROPERTY_EXECUTABLE = 
 47  
         "eu.simuline.octave.executable";
 48  
 
 49  
     /**
 50  
      * If this is not <code>null</code>, the octave engine created 
 51  
      * writes the output to that log writer also. 
 52  
      * By default, this is <code>null</code>. 
 53  
      * The according setter method is {@link #setOctaveInputLog(Writer)}. 
 54  
      */
 55  104
     private Writer octaveInputLog = null;
 56  
 
 57  
     /**
 58  
      * The error writer for the octave process. 
 59  
      * By default, this is just {@link System#err}. 
 60  
      * The according setter method is {@link #setErrorWriter(Writer)}. 
 61  
      */
 62  104
     private Writer errWriter = new OutputStreamWriter(System.err, 
 63  104
                                                       OctaveUtils.getUTF8());
 64  
 
 65  
     /**
 66  
      * The file containing the octave program or is <code>null</code>. 
 67  
      * In the latter case, the name of the octave program command 
 68  
      * is determined as described for {@link #octaveProgramCmd}. 
 69  
      * By default, this is <code>null</code>. 
 70  
      */
 71  104
     private File octaveProgramFile = null;
 72  
 
 73  
     /**
 74  
      * The command which determines the octave executable 
 75  
      * if {@link #octaveProgramFile} is <code>null</code> 
 76  
      * and if the property {@link #PROPERTY_EXECUTABLE} is not set. 
 77  
      * By default, this is "<code>octave</code>". 
 78  
      */
 79  104
     private String octaveProgramCmd = "octave";
 80  
 
 81  
     /**
 82  
      * The array of arguments of the octave engines created. 
 83  
      * For details, see octave user manual, version 3.4.0.+, Section 2.2.1. 
 84  
      * <p>
 85  
      * Default value of this field is default value for octave engines created.
 86  
      * The default value consists of the following components: 
 87  
      * <ul>
 88  
      * <li>
 89  
      * <code>--silent</code>: 
 90  
      * prevents octave from printing the usual greeting and version message 
 91  
      * at startup. 
 92  
      * <li>
 93  
      * <code>--no-init-file</code>, <code>--no-site-file</code> 
 94  
      * prevents octave from reading the initialization files 
 95  
      * <code>~/.octaverc</code>, <code>.octaverc</code> and 
 96  
      * site-wide <code>octaverc</code>. 
 97  
      * <li>
 98  
      * </ul>
 99  
      *
 100  
      * The only mandatory argument is <code>--silent</code>: 
 101  
      * If not set this, octave's greeting message causes an exception. 
 102  
      * Option <code>--no-init-file</code> makes the result independent 
 103  
      * of user input, 
 104  
      * whereas <code>--no-init-file</code> and <code>--no-site-file</code> 
 105  
      * makes it independent of initialization files. 
 106  
      * Since this is used to create scripting engines, 
 107  
      * line editing and history seem superfluous 
 108  
      * and so <code>--no-line-editing</code> and <code>--no-history</code> 
 109  
      * seem appropriate. 
 110  
      * Note that <code>--no-init-file</code> and <code>--no-site-file</code> 
 111  
      * may be appropriate or not. 
 112  
      * ***** why not needed --no-gui? --no-window-system
 113  
      */
 114  104
     private String[] argsArray = {
 115  
             "--silent",          // greeting message causes exception **** 
 116  
             "--no-init-file",    // makes result depend on init file 
 117  
              "--no-site-file",    // see --no-init-file
 118  
            "--no-line-editing", // make independent of user input 
 119  
             "--no-history"       // superfluous, because commands come from scripts 
 120  
     };
 121  
 
 122  
 
 123  
     /**
 124  
      * An array of strings of the form <code>name=value</code> 
 125  
      * representing the environment, i.e. the set of environment variables 
 126  
      * or <code>null</code>. 
 127  
      * In the latter case, 
 128  
      * the environment is inherited from the current process. 
 129  
      * This field is initialized with <code>null</code>. 
 130  
      */
 131  104
      private String[] environment = null;
 132  
 
 133  
     /**
 134  
      * The file representing the working directory or <code>null</code>. 
 135  
      * In the latter case, 
 136  
      * the working directory is inherited from the current process. 
 137  
      * By default, this is <code>null</code>. 
 138  
      */
 139  104
     private File workingDir = null;
 140  
 
 141  
     /**
 142  
      * The number of threads to be reused or 
 143  
      * <code>-1</code> if there is no limit. 
 144  
      * By default, this is <code>2</code>. 
 145  
      */
 146  104
     private int numThreadsReuse = 2;
 147  
 
 148  
     /**
 149  
      * Default constructor creating a factory with default parameters. 
 150  
      */
 151  104
     public OctaveEngineFactory() {
 152  
         // Empty constructor
 153  104
     }
 154  
 
 155  
     /**
 156  
      * Returns a script engine with the parameters set for this factory. 
 157  
      *
 158  
      * @return 
 159  
      *    a new OctaveEngine with the current parameters. 
 160  
      */
 161  
     public OctaveEngine getScriptEngine() {
 162  
         // determine the command/path of the octave program 
 163  106
         String octaveProgramPathCmd = (this.octaveProgramFile == null)
 164  104
             ? System.getProperty(PROPERTY_EXECUTABLE, this.octaveProgramCmd)
 165  2
             : this.octaveProgramFile.getPath();
 166  
 
 167  
         // determine the command array 
 168  106
         final String[] cmdArray = new String[this.argsArray.length + 1];
 169  106
         cmdArray[0] = octaveProgramPathCmd;
 170  106
         System.arraycopy(this.argsArray, 0, cmdArray, 1, this.argsArray.length);
 171  
 
 172  106
         return new OctaveEngine(this, 
 173  
                                 this.numThreadsReuse,
 174  
                                 this.octaveInputLog, 
 175  
                                 this.errWriter,
 176  
                                 cmdArray,
 177  
                                 this.environment,
 178  
                                 this.workingDir);
 179  
     }
 180  
 
 181  
     /**
 182  
      * Setter method for {@link #octaveInputLog}. 
 183  
      *
 184  
      * @param octaveInputLog
 185  
      *    the octaveInputLog to set
 186  
      */
 187  
     public void setOctaveInputLog(final Writer octaveInputLog) {
 188  2
         this.octaveInputLog = octaveInputLog;
 189  2
     }
 190  
 
 191  
     /**
 192  
      * Setter method for {@link #errWriter}. 
 193  
      *
 194  
      * @param errWriter
 195  
      *    the errWriter to set
 196  
      */
 197  
     public void setErrorWriter(final Writer errWriter) {
 198  12
         this.errWriter = errWriter;
 199  12
     }
 200  
 
 201  
     /**
 202  
      * Setter method for {@link #octaveProgramFile}. 
 203  
      *
 204  
      * @param octaveProgramFile
 205  
      *    the octaveProgramFile to set or <code>null</code>. 
 206  
      */
 207  
     public void setOctaveProgramFile(final File octaveProgramFile) {
 208  2
         this.octaveProgramFile = octaveProgramFile;
 209  2
     }
 210  
 
 211  
     /**
 212  
      * Setter method for {@link #octaveProgramCmd}. 
 213  
      * This takes effect only, 
 214  
      * if {@link #octaveProgramFile} is <code>null</code> 
 215  
      * and if the property {@link #PROPERTY_EXECUTABLE} is not set. 
 216  
      *
 217  
      * @param octaveProgramCmd
 218  
      *    the octave program executable to set
 219  
      */
 220  
     public void setOctaveProgramCmd(final String octaveProgramCmd) {
 221  0
         this.octaveProgramCmd = octaveProgramCmd;
 222  0
     }
 223  
 
 224  
     /**
 225  
      * Sets an array of arguments <code>argsArray</code> 
 226  
      * used when creating an {@link OctaveEngine}. 
 227  
      * The validity of the argument string is not proved. 
 228  
      * Note that subsequent changes on the array <code>argsArray</code> 
 229  
      * do not have any influence on this factory. 
 230  
      * The default options 
 231  
      * and a discussion of necessary options are 
 232  
      * documented with {@link #argsArray}. 
 233  
      *
 234  
      * @param argsArray
 235  
      *    the arguments as an array to set
 236  
      */
 237  
     public void setArgsArray(final String[] argsArray) {
 238  0
         this.argsArray = Arrays.copyOf(argsArray, argsArray.length);
 239  0
     }
 240  
 
 241  
     /**
 242  
      * Setter method for {@link #environment}. 
 243  
      * Note that subsequent changes on the array <code>environment</code> 
 244  
      * do not have any influence on this factory. 
 245  
      * The details are documented with {@link #environment}. 
 246  
      *
 247  
      * @param environment
 248  
      *    the environment or <code>null</code>. 
 249  
      */
 250  
     public void setEnvironment(final String[] environment) {
 251  0
         this.environment = environment == null 
 252  
             ? null
 253  0
             : Arrays.copyOf(environment, environment.length);
 254  0
     }
 255  
 
 256  
     /**
 257  
      * Setter method for {@link #workingDir}. 
 258  
      *
 259  
      * @param workingDir
 260  
      *    the workingDir to set or <code>null</code>. 
 261  
      */
 262  
     public void setWorkingDir(final File workingDir) {
 263  0
         this.workingDir = workingDir;
 264  0
     }
 265  
 
 266  
     /**
 267  
      * Sets the number of threads to be reused or <code>-1</code> 
 268  
      * which indicates no limit. 
 269  
      * The default value is 2 but this can be speed optimized 
 270  
      * depending on the hardware. 
 271  
      * The number of threads to be created shall be positive 
 272  
      * or <code>-1</code> otherwise throwing an exception. 
 273  
      */
 274  
     // **** with -1 seems not to work: cached pool 
 275  
     public void setNumThreadsReuse(int numThreadsReuse) {
 276  0
         if (numThreadsReuse == 0 || numThreadsReuse < -1) {
 277  0
             throw new IllegalArgumentException();
 278  
         }
 279  0
         this.numThreadsReuse = numThreadsReuse;
 280  0
     }
 281  
 }