1 /** 2 * Copyright (c) 2016-2019 JEP AUTHORS. 3 * 4 * This file is licensed under the the zlib/libpng License. 5 * 6 * This software is provided 'as-is', without any express or implied 7 * warranty. In no event will the authors be held liable for any 8 * damages arising from the use of this software. 9 * 10 * Permission is granted to anyone to use this software for any 11 * purpose, including commercial applications, and to alter it and 12 * redistribute it freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you 15 * must not claim that you wrote the original software. If you use 16 * this software in a product, an acknowledgment in the product 17 * documentation would be appreciated but is not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and 20 * must not be misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source 23 * distribution. 24 */ 25 package jep; 26 27 import java.io.File; 28 import java.util.HashSet; 29 import java.util.Set; 30 31 /** 32 * <p> 33 * A configuration object for constructing a Jep instance, corresponding to the 34 * configuration of the particular Python sub-interpreter. This class is 35 * intended to make constructing Jep instances easier while maintaining 36 * compatible APIs between releases. 37 * </p> 38 * 39 * @author Nate Jensen 40 * 41 * @since 3.5 42 */ 43 public class JepConfig { 44 45 protected boolean interactive = false; 46 47 protected StringBuilder includePath = null; 48 49 protected ClassLoader classLoader = null; 50 51 protected ClassEnquirer classEnquirer = null; 52 53 protected boolean redirectOutputStreams = false; 54 55 protected Set<String> sharedModules = null; 56 57 /** 58 * Sets whether <code>Jep.eval(String)</code> should support the slower 59 * behavior of potentially waiting for multiple statements 60 * 61 * @deprecated Interactive mode will be removed in a future release. See 62 * console.py for an example of how to interactively execute 63 * Python using the builtin compile() and exec() functions. 64 * 65 * @param interactive 66 * whether the Jep instance should be interactive 67 * @return a reference to this JepConfig 68 */ 69 @Deprecated setInteractive(boolean interactive)70 public JepConfig setInteractive(boolean interactive) { 71 this.interactive = interactive; 72 return this; 73 } 74 75 /** 76 * Sets a path of directories separated by File.pathSeparator that will be 77 * appended to the sub-intepreter's <code>sys.path</code> 78 * 79 * @param includePath 80 * directory or directories to include on sys.path 81 * @return a reference to this JepConfig 82 */ setIncludePath(String includePath)83 public JepConfig setIncludePath(String includePath) { 84 this.includePath = null; 85 if (includePath != null) { 86 this.includePath = new StringBuilder(includePath); 87 } 88 return this; 89 } 90 91 /** 92 * Adds a path of directories separated by File.pathSeparator that will be 93 * appended to the sub-intepreter's <code>sys.path</code> 94 * 95 * @param includePaths 96 * directories to include on sys.path 97 * @return a reference to this JepConfig 98 */ addIncludePaths(String... includePaths)99 public JepConfig addIncludePaths(String... includePaths) { 100 if (this.includePath == null) { 101 this.includePath = new StringBuilder(); 102 } 103 for (String path : includePaths) { 104 if (this.includePath.length() > 0) { 105 this.includePath.append(File.pathSeparator); 106 } 107 this.includePath.append(path); 108 } 109 return this; 110 } 111 112 /** 113 * Sets the ClassLoader to use when importing Java classes from Python 114 * 115 * @param classLoader 116 * the initial ClassLoader for the Jep instance 117 * @return a reference to this JepConfig 118 */ setClassLoader(ClassLoader classLoader)119 public JepConfig setClassLoader(ClassLoader classLoader) { 120 this.classLoader = classLoader; 121 return this; 122 } 123 124 /** 125 * Sets a ClassEnquirer to determine which imports are Python vs Java, or 126 * null for the default {@link ClassList} 127 * 128 * @param classEnquirer 129 * the ClassEnquirer for the Jep instance 130 * @return a reference to this JepConfig 131 */ setClassEnquirer(ClassEnquirer classEnquirer)132 public JepConfig setClassEnquirer(ClassEnquirer classEnquirer) { 133 this.classEnquirer = classEnquirer; 134 return this; 135 } 136 137 /** 138 * Sets whether to redirect the Python sys.stdout and sys.stderr streams to 139 * the Java System.out and System.err streams 140 * 141 * @param redirectOutputStreams 142 * whether to redirect Python streams to Java 143 * @return a reference to this JepConfig 144 */ setRedirectOutputStreams(boolean redirectOutputStreams)145 public JepConfig setRedirectOutputStreams(boolean redirectOutputStreams) { 146 this.redirectOutputStreams = redirectOutputStreams; 147 return this; 148 } 149 150 /** 151 * Sets the names of modules which should be shared with other Jep 152 * sub-interpreters. This can make it possible to use modules which are not 153 * designed for use from Python sub-interpreters. This should not be 154 * necessary for any module written in Python but is intended for extensions 155 * that use the c-api. For a complete discussion of the types of problems 156 * that can require shared modules see the documentation on 157 * shared_modules_hook.py. 158 * 159 * @param sharedModules 160 * a set of module names that should be shared 161 * @return a reference to this JepConfig 162 * 163 * @since 3.6 164 */ setSharedModules(Set<String> sharedModules)165 public JepConfig setSharedModules(Set<String> sharedModules) { 166 this.sharedModules = sharedModules; 167 return this; 168 } 169 170 /** 171 * Adds module names to the set of shared modules 172 * 173 * @param sharedModule 174 * a set of module names that should be shared 175 * @return a reference to this JepConfig 176 * @see #setSharedModules(Set) 177 * 178 * @since 3.6 179 */ addSharedModules(String... sharedModule)180 public JepConfig addSharedModules(String... sharedModule) { 181 if (sharedModules == null) { 182 sharedModules = new HashSet<>(); 183 } 184 for (String sm : sharedModule) { 185 sharedModules.add(sm); 186 } 187 return this; 188 } 189 190 /** 191 * Creates a new SubInterpreter instance and its associated sub-interpreter 192 * with this JepConfig. 193 * 194 * @deprecated Use {@link #createSubInterpreter()} instead. 195 * 196 * @return a new Jep instance 197 * @throws JepException 198 * if an error occurs 199 * @since 3.8 200 */ 201 @Deprecated createJep()202 public Jep createJep() throws JepException { 203 return createSubInterpreter(); 204 } 205 206 /** 207 * Creates a new Jep instance and its associated sub-interpreter with this 208 * JepConfig. 209 * 210 * @return a new SubInterpreter instance 211 * @throws JepException 212 * if an error occurs 213 * @since 3.9 214 */ createSubInterpreter()215 public SubInterpreter createSubInterpreter() throws JepException { 216 return new SubInterpreter(this); 217 } 218 219 } 220