@@ -5,7 +5,7 @@ class methods, fields, and source code URL.
5
5
6
6
from typing import Any , Dict , List
7
7
8
- from scyjava ._jvm import jimport
8
+ from scyjava ._jvm import jimport , jvm_version
9
9
from scyjava ._types import isjava , jinstance , jclass
10
10
11
11
@@ -78,34 +78,49 @@ def jreflect(data, aspect: str = "all") -> List[Dict[str, Any]]:
78
78
return table
79
79
80
80
81
- def jsource (data ):
81
+ def jsource (data ) -> str :
82
82
"""
83
- Try to find the source code using SciJava's SourceFinder.
83
+ Try to find the source code URL for the given Java object, class, or class name.
84
+ Requires org.scijava:scijava-search on the classpath.
84
85
:param data:
85
- The object or class or fully qualified class name to check for source code.
86
- :return: The URL of the java class
86
+ Object, class, or fully qualified class name for which to discern the source code location .
87
+ :return: URL of the class's source code.
87
88
"""
88
- Types = jimport ("org.scijava.util.Types" )
89
+
90
+ if not isjava (data ) and isinstance (data , str ):
91
+ try :
92
+ data = jimport (data ) # check if data can be imported
93
+ except Exception as err :
94
+ raise ValueError (f"Not a Java object { err } " )
95
+ jcls = data if jinstance (data , "java.lang.Class" ) else jclass (data )
96
+
97
+ if jcls .getClassLoader () is None :
98
+ # Class is from the Java standard library.
99
+ cls_path = str (jcls .getName ()).replace ("." , "/" )
100
+
101
+ # Discern the Java version.
102
+ java_version = jvm_version ()[0 ]
103
+
104
+ # Note: some classes (e.g. corba and jaxp) will not be located correctly before
105
+ # Java 10, because they fall under a different subtree than `jdk`. But Java 11+
106
+ # dispenses with such subtrees in favor of using only the module designations.
107
+ if java_version <= 7 :
108
+ return f"https://github.com/openjdk/jdk/blob/jdk7-b147/jdk/src/share/classes/{ cls_path } .java"
109
+ elif java_version == 8 :
110
+ return f"https://github.com/openjdk/jdk/blob/jdk8-b120/jdk/src/share/classes/{ cls_path } .java"
111
+ else : # java_version >= 9
112
+ module_name = jcls .getModule ().getName ()
113
+ # if module_name is null, it's in the unnamed module
114
+ if java_version == 9 :
115
+ suffix = "%2B181/jdk"
116
+ elif java_version == 10 :
117
+ suffix = "%2B46"
118
+ else :
119
+ suffix = "-ga"
120
+ return f"https://github.com/openjdk/jdk/blob/jdk-{ java_version } { suffix } /src/{ module_name } /share/classes/{ cls_path } .java"
121
+
122
+ # Ask scijava-search for the source location.
89
123
SourceFinder = jimport ("org.scijava.search.SourceFinder" )
90
- String = jimport ("java.lang.String" )
91
- try :
92
- if not isjava (data ) and isinstance (data , str ):
93
- try :
94
- data = jimport (data ) # check if data can be imported
95
- except Exception as err :
96
- raise ValueError (f"Not a Java object { err } " )
97
- jcls = data if jinstance (data , "java.lang.Class" ) else jclass (data )
98
- if Types .location (jcls ).toString ().startsWith (String ("jrt" )):
99
- # Handles Java RunTime (jrt) exceptions.
100
- raise ValueError ("Java Builtin: GitHub source code not available" )
101
- url = SourceFinder .sourceLocation (jcls , None )
102
- urlstring = url .toString ()
103
- return urlstring
104
- except jimport ("java.lang.IllegalArgumentException" ) as err :
105
- return f"Illegal argument provided { err = } , { type (err )= } "
106
- except ValueError as err :
107
- return f"{ err } "
108
- except TypeError :
109
- return f"Not
8000
a Java class { str (type (data ))} "
110
- except Exception as err :
111
- return f"Unexpected { err = } , { type (err )= } "
124
+ url = SourceFinder .sourceLocation (jcls , None )
125
+ urlstring = url .toString ()
126
+ return urlstring
0 commit comments