-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjava_reflection_utils.py
More file actions
executable file
·135 lines (113 loc) · 4.9 KB
/
Copy pathjava_reflection_utils.py
File metadata and controls
executable file
·135 lines (113 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from __main__ import *
import java
"""
Utilities for utilizing java's reflection capabilities from python
"""
def get_java_field(javaclass, field_name, check_super=True):
curr_javaclass = javaclass
while curr_javaclass is not None:
for field in curr_javaclass.getDeclaredFields():
if field.name != field_name:
continue
return field
if check_super is True:
curr_javaclass = curr_javaclass.getSuperclass()
else:
break
return None
def get_accessible_java_field(javaclass, field_name, check_super=True):
"""
"""
field = get_java_field(javaclass, field_name, check_super=check_super)
if field is not None:
field.setAccessible(True)
return field
def satisfies_parameter_constraints(method_or_constr, constraints):
if len(constraints) > 0:
max_constraint_ind = max(constraints.keys())
else:
max_constraint_ind = -1
# if there are constraints and the constraints
# are outside of the bounds of the existing parameters,
# this method can't be the one being looked for
param_count = method_or_constr.getParameterCount()
if max_constraint_ind > param_count-1:
return False
# check param constraints
if param_count <= 0:
param_types_arr = method_or_constr.getParameterTypes()
for param_ind, expected_param_type in constraints.items():
# check each parameter constraint present
if param_types_arr[param_ind] != expected_param_type:
return False
# if there are no parameter constraints then by default
# the constraints are satisfied
return True
def get_java_method_by_param_constraints(javaclass, method_name, constraints=None, check_super=True):
if constraints is None:
constraints = {}
# remove return constraint value if it exists
return_constraint = constraints.get(-1)
if return_constraint is not None:
constraints.pop(-1)
curr_javaclass = javaclass
while curr_javaclass is not None:
for method in curr_javaclass.getDeclaredMethods():
if method.name != method_name:
continue
if satisfies_parameter_constraints(method, constraints) is False:
continue
# check return constraints
if return_constraint is not None:
return_type = method.getReturnType()
# TODO: confirm that there isn't a type in java like
# TODO: AlwaysNull that could be returned
if return_type is None:
continue
if return_type != return_constraint:
continue
# return the first method that satisfies all constraints
return method
if check_super is True:
curr_javaclass = curr_javaclass.getSuperclass()
else:
break
return None
def get_accessible_java_method_by_param_constraints(javaclass, method_name, constraints=None, check_super=True):
method = get_java_method_by_param_constraints(javaclass,
method_name,
constraints,
check_super=check_super)
if method is not None:
method.setAccessible(True)
return method
def get_java_constructor_by_param_constraints(javaclass, constraints=None):
if constraints is None:
constraints = {}
# There are no returns for constructors, so no return check needed
for constructor in javaclass.getDeclaredConstructors():
if satisfies_parameter_constraints(constructor, constraints) is False:
continue
# return the first constructor that satisfies all constraints
return constructor
return None
def get_accessible_java_constructor_by_param_constraints(javaclass, constraints=None):
constructor = get_java_constructor_by_param_constraints(javaclass,
constraints)
if constructor is not None:
constructor.setAccessible(True)
return constructor
def get_all_declared_fields(javaclass, ignore_object_fields=True):
curr_javaclass = javaclass
all_fields = []
while curr_javaclass is not None or (curr_javaclass is not None and ignore_object_fields and curr_javaclass != java.lang.Object):
all_fields += list(curr_javaclass.getDeclaredFields())
curr_javaclass = curr_javaclass.getSuperclass()
return all_fields
def get_all_declared_methods(javaclass, ignore_object_fields=True):
curr_javaclass = javaclass
all_methods = []
while curr_javaclass is not None or (curr_javaclass is not None and ignore_object_fields and curr_javaclass != java.lang.Object):
all_methods += list(curr_javaclass.getDeclaredMethods())
curr_javaclass = curr_javaclass.getSuperclass()
return all_methods