34
34
35
35
/**
36
36
* {@link LibraryImporter} contributes the add_library function to processing.py.
37
- *
38
- * <p>add_library causes the given Processing library (all of its jar files and
39
- * library subdirectories potentially containing native code) to be added to the
40
- * system {@link ClassLoader}, the native code search path, and the Jython sys.path.
41
- * It then generates import statements bringing all top-level classes available
42
- * in the main library jar file into the sketch's namespace.
43
- *
44
- * <p>Note: Once jar files and directories have been added in this fashion to the
45
- * classloader and native lib search path, they're good and stuck there. In practice,
46
- * this hasn't presented any difficulty. But it's good to keep in mind.
37
+ *
38
+ * <p>add_library causes the given Processing library (all of its jar files and library
39
+ * subdirectories potentially containing native code) to be added to the system {@link ClassLoader},
40
+ * the native code search path, and the Jython sys.path. It then generates import statements
41
+ * bringing all top-level classes available in the main library jar file into the sketch's
42
+ * namespace.
43
+ *
44
+ * <p>Note: Once jar files and directories have been added in this fashion to the classloader and
45
+ * native lib search path, they're good and stuck there. In practice, this hasn't presented any
46
+ * difficulty. But it's good to keep in mind.
47
47
*/
48
48
class LibraryImporter {
49
49
private static void log (final String msg ) {
@@ -75,26 +75,27 @@ public LibraryImporter(final List<File> libdirs, final InteractiveConsole interp
75
75
this .interp = interp ;
76
76
77
77
// Define the add_library function in the sketch interpreter.
78
- final PyStringMap builtins = (PyStringMap )interp .getSystemState ().getBuiltins ();
79
- builtins .__setitem__ ("add_library" , new PyObject () {
80
- @ Override
81
- public PyObject __call__ (final PyObject [] args , final String [] kws ) {
82
- log ("Adding library " + args [0 ].asString ());
83
- addLibrary (args [0 ].asString ());
84
- return Py .None ;
85
- }
86
- });
78
+ final PyStringMap builtins = (PyStringMap ) interp .getSystemState ().getBuiltins ();
79
+ builtins .__setitem__ (
80
+ "add_library" ,
81
+ new PyObject () {
82
+ @ Override
83
+ public PyObject __call__ (final PyObject [] args , final String [] kws ) {
84
+ log ("Adding library " + args [0 ].asString ());
85
+ addLibrary (args [0 ].asString ());
86
+ return Py .None ;
87
+ }
88
+ });
87
89
}
88
90
89
91
/**
90
- * Locate the library in the library folder "libName", find what
91
- * it exports for the current platform, and add exports to the
92
- * system classpath, the system native library path, and jython's
92
+ * Locate the library in the library folder "libName", find what it exports for the current
93
+ * platform, and add exports to the system classpath, the system native library path, and jython's
93
94
* sys.path.
94
- *
95
- * Then, go through the main jar file of the library and import
96
- * all of its publicly exposed classes.
97
- *
95
+ *
96
+ * <p> Then, go through the main jar file of the library and import all of its publicly exposed
97
+ * classes.
98
+ *
98
99
* @param libName The name of the library to import
99
100
*/
100
101
protected void addLibrary (final String libName ) {
@@ -158,13 +159,12 @@ protected void addLibrary(final String libName) {
158
159
}
159
160
160
161
/**
161
- * Find all of the resources a library requires on this platform.
162
- * See https://github.com/processing/processing/wiki/Library-Basics.
163
- *
164
- * First, finds the library.
165
- * Second, tries to parse export.txt, and follow its instructions.
162
+ * Find all of the resources a library requires on this platform. See
163
+ * https://github.com/processing/processing/wiki/Library-Basics.
164
+ *
165
+ * <p>First, finds the library. Second, tries to parse export.txt, and follow its instructions.
166
166
* Third, tries to understand folder structure, and export according to that.
167
- *
167
+ *
168
168
* @param libName The name of the library to add.
169
169
* @return The list of files we need to import.
170
170
*/
@@ -215,8 +215,11 @@ private List<File> findResourcesFromExportTxt(final File contentsDir) {
215
215
if (resource .exists ()) {
216
216
resources .add (resource );
217
217
} else {
218
- log (resourceName + " is mentioned in " + exportTxt .getAbsolutePath ()
219
- + "but doesn't actually exist. Moving on." );
218
+ log (
219
+ resourceName
220
+ + " is mentioned in "
221
+ + exportTxt .getAbsolutePath ()
222
+ + "but doesn't actually exist. Moving on." );
220
223
continue ;
221
224
}
222
225
}
@@ -249,23 +252,25 @@ private List<File> findResourcesFromDirectoryStructure(final File contentsDir) {
249
252
}
250
253
251
254
// Find multi-platform stuff; always do this
252
- final File [] commonResources = contentsDir .listFiles (new FileFilter () {
253
- @ Override
254
- public boolean accept (final File file ) {
255
- return !file .isDirectory ();
256
- }
257
- });
255
+ final File [] commonResources =
256
+ contentsDir .listFiles (
257
+ new FileFilter () {
258
+ @ Override
259
+ public boolean accept (final File file ) {
260
+ return !file .isDirectory ();
261
+ }
262
+ });
258
263
for (final File resource : commonResources ) {
259
264
resources .add (resource );
260
265
}
261
266
return resources ;
262
267
}
263
268
264
269
/**
265
- * Parse an export.txt file to figure out what we need to load for this platform.
266
- * This is all duplicated from processing.app.Library / processing.app.Base,
267
- * but we don't have the PDE around at runtime so we can't use them.
268
- *
270
+ * Parse an export.txt file to figure out what we need to load for this platform. This is all
271
+ * duplicated from processing.app.Library / processing.app.Base, but we don't have the PDE around
272
+ * at runtime so we can't use them.
273
+ *
269
274
* @param exportTxt The export.txt file; must exist.
270
275
*/
271
276
private Map <String , String []> parseExportTxt (final File exportTxt ) throws Exception {
@@ -290,14 +295,14 @@ private Map<String, String[]> parseExportTxt(final File exportTxt) throws Except
290
295
}
291
296
292
297
/**
293
- * Use a brittle and egregious hack to forcibly add the given jar file to the
294
- * system classloader.
298
+ * Use a brittle and egregious hack to forcibly add the given jar file to the system classloader.
299
+ *
295
300
* @param jar The jar to add to the system classloader.
296
301
*/
297
302
private void addJarToClassLoader (final File jar ) {
298
303
try {
299
304
final URL url = jar .toURI ().toURL ();
300
- final URLClassLoader ucl = (URLClassLoader )ClassLoader .getSystemClassLoader ();
305
+ final URLClassLoader ucl = (URLClassLoader ) ClassLoader .getSystemClassLoader ();
301
306
// Linear search for url. It's ok for this to be slow.
302
307
for (final URL existing : ucl .getURLs ()) {
303
308
if (existing .equals (url )) {
@@ -308,28 +313,29 @@ private void addJarToClassLoader(final File jar) {
308
313
final Method addUrl = URLClassLoader .class .getDeclaredMethod ("addURL" , URL .class );
309
314
addUrl .setAccessible (true );
310
315
addUrl .invoke (ucl , url );
311
- } catch (NoSuchMethodException | SecurityException | IllegalAccessException
312
- | IllegalArgumentException | InvocationTargetException | MalformedURLException e ) {
316
+ } catch (NoSuchMethodException
317
+ | SecurityException
318
+ | IllegalAccessException
319
+ | IllegalArgumentException
320
+ | InvocationTargetException
321
+ | MalformedURLException e ) {
313
322
throw new RuntimeException (e );
314
323
}
315
324
}
316
325
317
326
/**
318
- * Add the given path to the list of paths searched for DLLs (as in those
319
- * loaded by loadLibrary). A hack, which depends on the presence of a
320
- * particular field in ClassLoader. Known to work on all recent Sun JVMs and
321
- * OS X.
327
+ * Add the given path to the list of paths searched for DLLs (as in those loaded by loadLibrary).
328
+ * A hack, which depends on the presence of a particular field in ClassLoader. Known to work on
329
+ * all recent Sun JVMs and OS X.
322
330
*
323
- * <p>
324
- * See <a href="http://forums.sun.com/thread.jspa?threadID=707176">this
325
- * thread</a>.
331
+ * <p>See <a href="http://forums.sun.com/thread.jspa?threadID=707176">this thread</a>.
326
332
*/
327
333
private void addDirectoryToNativeSearchPath (final File dllDir ) {
328
334
final String newPath = dllDir .getAbsolutePath ();
329
335
try {
330
336
final Field field = ClassLoader .class .getDeclaredField ("usr_paths" );
331
337
field .setAccessible (true );
332
- final String [] paths = (String [])field .get (null );
338
+ final String [] paths = (String []) field .get (null );
333
339
for (final String path : paths ) {
334
340
if (newPath .equals (path )) {
335
341
return ;
@@ -340,13 +346,16 @@ private void addDirectoryToNativeSearchPath(final File dllDir) {
340
346
field .set (null , tmp );
341
347
log ("Added " + newPath + " to java.library.path." );
342
348
} catch (final Exception e ) {
343
- System .err .println ("While attempting to add " + newPath
344
- + " to the processing.py library search path: " + e .getClass ().getSimpleName () + "--"
345
- + e .getMessage ());
349
+ System .err .println (
350
+ "While attempting to add "
351
+ + newPath
352
+ + " to the processing.py library search path: "
353
+ + e .getClass ().getSimpleName ()
354
+ + "--"
355
+ + e .getMessage ());
346
356
}
347
357
}
348
358
349
-
350
359
private static final Pattern validPythonIdentifier = Pattern .compile ("[a-zA-Z_][a-zA-Z0-9_]*" );
351
360
352
361
/*
@@ -357,9 +366,9 @@ private void addDirectoryToNativeSearchPath(final File dllDir) {
357
366
com.foo.Banana$1.class
358
367
com.foo.Banana$2.class
359
368
com.bar.Kiwi.class
360
-
369
+
361
370
then we'll generate these import statements:
362
-
371
+
363
372
from com.foo import Banana
364
373
from com.bar import Kiwi
365
374
*/
0 commit comments