feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
This commit is contained in:
1 parent
506f9ac725
commit
a51854455b
128 files changed
+100571
-3
No files matched your search
@@ -0,0 +1,4 @@
|
||||
"""
|
||||
Java standard library APIs implemented in Python.
|
||||
Android-pyApi: desktop Python translation of Android Java APIs.
|
||||
"""
|
||||
@@ -0,0 +1,806 @@
|
||||
"""
|
||||
Java java.beans standard library APIs implemented in Python.
|
||||
java.beans package - BeanInfo, Introspector, PropertyChange, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from .lang import RuntimeException
|
||||
import typing as _typing
|
||||
|
||||
__all__ = [
|
||||
"BeanInfo", "IntrospectionException", "Introspector",
|
||||
"BeanDescriptor", "EventSetDescriptor", "MethodDescriptor",
|
||||
"ParameterDescriptor",
|
||||
"PropertyChangeListener", "PropertyChangeSupport",
|
||||
"PropertyChangeEvent", "PropertyChangeListenerProxy",
|
||||
"PropertyDescriptor", "SimpleBeanInfo", "FeatureDescriptor",
|
||||
"PropertyEditor", "PropertyEditorManager", "PropertyEditorSupport",
|
||||
"VetoableChangeListener", "VetoableChangeSupport",
|
||||
"IndexedPropertyChangeEvent", "IndexedPropertyDescriptor",
|
||||
"EventHandler", "ExceptionListener",
|
||||
"AppletInitializer", "Beans", "Customizer", "DesignMode", "Visibility",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Exceptions
|
||||
# ============================================================
|
||||
|
||||
class IntrospectionException(Exception):
|
||||
"""java.beans.IntrospectionException"""
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FeatureDescriptor
|
||||
# ============================================================
|
||||
|
||||
class FeatureDescriptor(Stub):
|
||||
"""java.beans.FeatureDescriptor"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._name = None
|
||||
self._display_name = None
|
||||
self._short_description = None
|
||||
self._preferred = False
|
||||
self._expert = False
|
||||
self._hidden = False
|
||||
self._attributes = {}
|
||||
self._bound = False
|
||||
self._constrained = False
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def setName(self, name):
|
||||
self._name = name
|
||||
|
||||
def getDisplayName(self):
|
||||
return self._display_name or self._name or ""
|
||||
|
||||
def setDisplayName(self, name):
|
||||
self._display_name = name
|
||||
|
||||
def getShortDescription(self):
|
||||
return self._short_description or self.getDisplayName()
|
||||
|
||||
def setShortDescription(self, text):
|
||||
self._short_description = text
|
||||
|
||||
def isPreferred(self):
|
||||
return self._preferred
|
||||
|
||||
def setPreferred(self, preferred):
|
||||
self._preferred = preferred
|
||||
|
||||
def isExpert(self):
|
||||
return self._expert
|
||||
|
||||
def setExpert(self, expert):
|
||||
self._expert = expert
|
||||
|
||||
def isHidden(self):
|
||||
return self._hidden
|
||||
|
||||
def setHidden(self, hidden):
|
||||
self._hidden = hidden
|
||||
|
||||
def setValue(self, attribute_name, value):
|
||||
self._attributes[attribute_name] = value
|
||||
|
||||
def getValue(self, attribute_name):
|
||||
return self._attributes.get(attribute_name)
|
||||
|
||||
def attributeNames(self):
|
||||
return list(self._attributes.keys())
|
||||
|
||||
|
||||
# ============================================================
|
||||
# BeanDescriptor
|
||||
# ============================================================
|
||||
|
||||
class BeanDescriptor(FeatureDescriptor):
|
||||
"""java.beans.BeanDescriptor"""
|
||||
def __init__(self, bean_class, customizer_class=None):
|
||||
super().__init__()
|
||||
self._bean_class = bean_class
|
||||
self._customizer_class = customizer_class
|
||||
|
||||
def getBeanClass(self):
|
||||
return self._bean_class
|
||||
|
||||
def getCustomizerClass(self):
|
||||
return self._customizer_class
|
||||
|
||||
|
||||
# ============================================================
|
||||
# EventSetDescriptor
|
||||
# ============================================================
|
||||
|
||||
class EventSetDescriptor(FeatureDescriptor):
|
||||
"""java.beans.EventSetDescriptor"""
|
||||
def __init__(self, source_class, event_set_name, listener_type,
|
||||
listener_methods, add_listener_method=None,
|
||||
remove_listener_method=None):
|
||||
super().__init__()
|
||||
self._source_class = source_class
|
||||
self._event_set_name = event_set_name
|
||||
self._listener_type = listener_type
|
||||
self._listener_methods = listener_methods or []
|
||||
self._add_listener_method = add_listener_method
|
||||
self._remove_listener_method = remove_listener_method
|
||||
self._unicast = False
|
||||
self._in_default_event_set = False
|
||||
|
||||
def getListenerType(self):
|
||||
return self._listener_type
|
||||
|
||||
def getListenerMethods(self):
|
||||
return self._listener_methods
|
||||
|
||||
def getAddListenerMethod(self):
|
||||
return self._add_listener_method
|
||||
|
||||
def getRemoveListenerMethod(self):
|
||||
return self._remove_listener_method
|
||||
|
||||
def isUnicast(self):
|
||||
return self._unicast
|
||||
|
||||
def setUnicast(self, unicast):
|
||||
self._unicast = unicast
|
||||
|
||||
def isInDefaultEventSet(self):
|
||||
return self._in_default_event_set
|
||||
|
||||
def setInDefaultEventSet(self, in_default):
|
||||
self._in_default_event_set = in_default
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodDescriptor / ParameterDescriptor
|
||||
# ============================================================
|
||||
|
||||
class MethodDescriptor(FeatureDescriptor):
|
||||
"""java.beans.MethodDescriptor"""
|
||||
def __init__(self, method, parameter_descriptors=None):
|
||||
super().__init__()
|
||||
self._method = method
|
||||
self._parameter_descriptors = parameter_descriptors or []
|
||||
|
||||
def getMethod(self):
|
||||
return self._method
|
||||
|
||||
def getParameterDescriptors(self):
|
||||
return self._parameter_descriptors
|
||||
|
||||
|
||||
class ParameterDescriptor(FeatureDescriptor):
|
||||
"""java.beans.ParameterDescriptor"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PropertyDescriptor
|
||||
# ============================================================
|
||||
|
||||
class PropertyDescriptor(FeatureDescriptor):
|
||||
"""java.beans.PropertyDescriptor"""
|
||||
def __init__(self, property_name, bean_class,
|
||||
getter_name=None, setter_name=None):
|
||||
super().__init__()
|
||||
self._property_name = property_name
|
||||
self._bean_class = bean_class
|
||||
self._getter_name = getter_name
|
||||
self._setter_name = setter_name
|
||||
self._property_type = None
|
||||
self._read_method = None
|
||||
self._write_method = None
|
||||
self._bound = False
|
||||
self._constrained = False
|
||||
self._property_editor_class = None
|
||||
|
||||
def getPropertyType(self):
|
||||
return self._property_type
|
||||
|
||||
def setPropertyType(self, prop_type):
|
||||
self._property_type = prop_type
|
||||
|
||||
def getReadMethod(self):
|
||||
return self._read_method
|
||||
|
||||
def setReadMethod(self, method):
|
||||
self._read_method = method
|
||||
|
||||
def getWriteMethod(self):
|
||||
return self._write_method
|
||||
|
||||
def setWriteMethod(self, method):
|
||||
self._write_method = method
|
||||
|
||||
def isBound(self):
|
||||
return self._bound
|
||||
|
||||
def setBound(self, bound):
|
||||
self._bound = bound
|
||||
|
||||
def isConstrained(self):
|
||||
return self._constrained
|
||||
|
||||
def setConstrained(self, constrained):
|
||||
self._constrained = constrained
|
||||
|
||||
def getPropertyEditorClass(self):
|
||||
return self._property_editor_class
|
||||
|
||||
def setPropertyEditorClass(self, cls):
|
||||
self._property_editor_class = cls
|
||||
|
||||
|
||||
class IndexedPropertyDescriptor(PropertyDescriptor):
|
||||
"""java.beans.IndexedPropertyDescriptor"""
|
||||
def __init__(self, property_name, bean_class,
|
||||
getter_name=None, setter_name=None,
|
||||
indexed_getter_name=None, indexed_setter_name=None):
|
||||
super().__init__(property_name, bean_class, getter_name, setter_name)
|
||||
self._indexed_read_method = None
|
||||
self._indexed_write_method = None
|
||||
self._indexed_property_type = None
|
||||
|
||||
def getIndexedReadMethod(self):
|
||||
return self._indexed_read_method
|
||||
|
||||
def setIndexedReadMethod(self, method):
|
||||
self._indexed_read_method = method
|
||||
|
||||
def getIndexedWriteMethod(self):
|
||||
return self._indexed_write_method
|
||||
|
||||
def setIndexedWriteMethod(self, method):
|
||||
self._indexed_write_method = method
|
||||
|
||||
def getIndexedPropertyType(self):
|
||||
return self._indexed_property_type
|
||||
|
||||
def setIndexedPropertyType(self, prop_type):
|
||||
self._indexed_property_type = prop_type
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Introspector
|
||||
# ============================================================
|
||||
|
||||
class Introspector(Stub):
|
||||
"""java.beans.Introspector"""
|
||||
@staticmethod
|
||||
def getBeanInfo(bean_class, stop_class=None, flags=None):
|
||||
bean_descriptor = BeanDescriptor(bean_class)
|
||||
bean_info = SimpleBeanInfo()
|
||||
|
||||
props = []
|
||||
methods = []
|
||||
events = []
|
||||
|
||||
for name in dir(bean_class):
|
||||
if name.startswith('_'):
|
||||
continue
|
||||
attr = getattr(bean_class, name, None)
|
||||
if callable(attr):
|
||||
methods.append(MethodDescriptor(attr))
|
||||
if name.startswith('get') and not name.startswith('getClass'):
|
||||
prop_name = name[3].lower() + name[4:]
|
||||
pd = PropertyDescriptor(prop_name, bean_class, getter_name=name)
|
||||
props.append(pd)
|
||||
|
||||
bean_info._property_descriptors = props
|
||||
bean_info._method_descriptors = methods
|
||||
bean_info._event_set_descriptors = events
|
||||
bean_info._bean_descriptor = bean_descriptor
|
||||
return bean_info
|
||||
|
||||
@staticmethod
|
||||
def decapitalize(name):
|
||||
if len(name) == 0:
|
||||
return name
|
||||
if len(name) > 1 and name[1].islower():
|
||||
return name[0].lower() + name[1:]
|
||||
return name.lower()
|
||||
|
||||
@staticmethod
|
||||
def flushCaches():
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def flushFromCaches(cls):
|
||||
pass
|
||||
|
||||
USE_ALL_BEANINFO = 1
|
||||
IGNORE_IMMEDIATE_BEANINFO = 2
|
||||
IGNORE_ALL_BEANINFO = 3
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SimpleBeanInfo / BeanInfo
|
||||
# ============================================================
|
||||
|
||||
class BeanInfo(Stub):
|
||||
"""java.beans.BeanInfo"""
|
||||
ICON_COLOR_16x16 = 1
|
||||
ICON_COLOR_32x32 = 2
|
||||
ICON_MONO_16x16 = 3
|
||||
ICON_MONO_32x32 = 4
|
||||
|
||||
def getBeanDescriptor(self):
|
||||
return None
|
||||
|
||||
def getEventSetDescriptors(self):
|
||||
return []
|
||||
|
||||
def getDefaultEventIndex(self):
|
||||
return -1
|
||||
|
||||
def getMethodDescriptors(self):
|
||||
return []
|
||||
|
||||
def getDefaultMethodIndex(self):
|
||||
return -1
|
||||
|
||||
def getPropertyDescriptors(self):
|
||||
return []
|
||||
|
||||
def getDefaultPropertyIndex(self):
|
||||
return -1
|
||||
|
||||
def getIcon(self, icon_kind):
|
||||
return None
|
||||
|
||||
def getAdditionalBeanInfo(self):
|
||||
return None
|
||||
|
||||
|
||||
class SimpleBeanInfo(BeanInfo):
|
||||
"""java.beans.SimpleBeanInfo"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._bean_descriptor = None
|
||||
self._property_descriptors = []
|
||||
self._method_descriptors = []
|
||||
self._event_set_descriptors = []
|
||||
self._default_property_index = -1
|
||||
self._default_event_index = -1
|
||||
self._default_method_index = -1
|
||||
|
||||
def getBeanDescriptor(self):
|
||||
return self._bean_descriptor
|
||||
|
||||
def getPropertyDescriptors(self):
|
||||
return self._property_descriptors
|
||||
|
||||
def getMethodDescriptors(self):
|
||||
return self._method_descriptors
|
||||
|
||||
def getEventSetDescriptors(self):
|
||||
return self._event_set_descriptors
|
||||
|
||||
def getDefaultPropertyIndex(self):
|
||||
return self._default_property_index
|
||||
|
||||
def getDefaultEventIndex(self):
|
||||
return self._default_event_index
|
||||
|
||||
def getIcon(self, icon_kind):
|
||||
return None
|
||||
|
||||
def loadBeanInfo(self, bean_info_class):
|
||||
return self
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PropertyChangeEvent / IndexedPropertyChangeEvent
|
||||
# ============================================================
|
||||
|
||||
class PropertyChangeEvent(Stub):
|
||||
"""java.beans.PropertyChangeEvent"""
|
||||
def __init__(self, source, property_name, old_value, new_value):
|
||||
super().__init__()
|
||||
self._source = source
|
||||
self._property_name = property_name
|
||||
self._old_value = old_value
|
||||
self._new_value = new_value
|
||||
self._propagation_id = None
|
||||
|
||||
def getPropertyName(self):
|
||||
return self._property_name
|
||||
|
||||
def getOldValue(self):
|
||||
return self._old_value
|
||||
|
||||
def getNewValue(self):
|
||||
return self._new_value
|
||||
|
||||
def setPropagationId(self, propagation_id):
|
||||
self._propagation_id = propagation_id
|
||||
|
||||
def getPropagationId(self):
|
||||
return self._propagation_id
|
||||
|
||||
def toString(self):
|
||||
return (f"PropertyChangeEvent[property={self._property_name}, "
|
||||
f"old={self._old_value}, new={self._new_value}]")
|
||||
|
||||
|
||||
class IndexedPropertyChangeEvent(PropertyChangeEvent):
|
||||
"""java.beans.IndexedPropertyChangeEvent"""
|
||||
def __init__(self, source, property_name, old_value, new_value, index):
|
||||
super().__init__(source, property_name, old_value, new_value)
|
||||
self._index = index
|
||||
|
||||
def getIndex(self):
|
||||
return self._index
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Listener Interfaces
|
||||
# ============================================================
|
||||
|
||||
class PropertyChangeListener(Stub):
|
||||
"""java.beans.PropertyChangeListener"""
|
||||
def propertyChange(self, evt):
|
||||
pass
|
||||
|
||||
|
||||
class PropertyChangeListenerProxy(PropertyChangeListener):
|
||||
"""java.beans.PropertyChangeListenerProxy"""
|
||||
def __init__(self, property_name, listener):
|
||||
super().__init__()
|
||||
self._property_name = property_name
|
||||
self._listener = listener
|
||||
|
||||
def propertyChange(self, evt):
|
||||
if self._listener:
|
||||
self._listener(evt)
|
||||
|
||||
def getPropertyName(self):
|
||||
return self._property_name
|
||||
|
||||
def getListener(self):
|
||||
return self._listener
|
||||
|
||||
|
||||
class VetoableChangeListener(Stub):
|
||||
"""java.beans.VetoableChangeListener"""
|
||||
def vetoableChange(self, evt):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PropertyChangeSupport
|
||||
# ============================================================
|
||||
|
||||
class PropertyChangeSupport(Stub):
|
||||
"""java.beans.PropertyChangeSupport"""
|
||||
def __init__(self, source_bean):
|
||||
super().__init__()
|
||||
self._source = source_bean
|
||||
self._listeners = []
|
||||
|
||||
def addPropertyChangeListener(self, listener, property_name=None):
|
||||
if property_name is not None:
|
||||
self._listeners.append(PropertyChangeListenerProxy(property_name, listener))
|
||||
else:
|
||||
self._listeners.append(listener)
|
||||
|
||||
def removePropertyChangeListener(self, listener, property_name=None):
|
||||
if property_name is not None:
|
||||
self._listeners = [
|
||||
l for l in self._listeners
|
||||
if not (isinstance(l, PropertyChangeListenerProxy)
|
||||
and l.getListener() == listener
|
||||
and l.getPropertyName() == property_name)
|
||||
]
|
||||
else:
|
||||
self._listeners = [
|
||||
l for l in self._listeners
|
||||
if l != listener
|
||||
]
|
||||
|
||||
def getPropertyChangeListeners(self, property_name=None):
|
||||
if property_name is not None:
|
||||
return [l for l in self._listeners
|
||||
if isinstance(l, PropertyChangeListenerProxy)
|
||||
and l.getPropertyName() == property_name
|
||||
or not isinstance(l, PropertyChangeListenerProxy)]
|
||||
return self._listeners
|
||||
|
||||
def firePropertyChange(self, property_name_or_evt, old_value=None, new_value=None):
|
||||
if isinstance(property_name_or_evt, PropertyChangeEvent):
|
||||
evt = property_name_or_evt
|
||||
else:
|
||||
evt = PropertyChangeEvent(self._source, property_name_or_evt,
|
||||
old_value, new_value)
|
||||
for listener in self._listeners:
|
||||
if isinstance(listener, PropertyChangeListenerProxy):
|
||||
if listener.getPropertyName() == evt.getPropertyName():
|
||||
listener.propertyChange(evt)
|
||||
else:
|
||||
listener.propertyChange(evt)
|
||||
|
||||
def hasListeners(self, property_name):
|
||||
for listener in self._listeners:
|
||||
if isinstance(listener, PropertyChangeListenerProxy):
|
||||
if listener.getPropertyName() == property_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# VetoableChangeSupport
|
||||
# ============================================================
|
||||
|
||||
class VetoableChangeSupport(Stub):
|
||||
"""java.beans.VetoableChangeSupport"""
|
||||
def __init__(self, source_bean):
|
||||
super().__init__()
|
||||
self._source = source_bean
|
||||
self._listeners = []
|
||||
|
||||
def addVetoableChangeListener(self, listener, property_name=None):
|
||||
if property_name is not None:
|
||||
self._listeners.append(PropertyChangeListenerProxy(property_name, listener))
|
||||
else:
|
||||
self._listeners.append(listener)
|
||||
|
||||
def removeVetoableChangeListener(self, listener, property_name=None):
|
||||
if property_name is not None:
|
||||
self._listeners = [
|
||||
l for l in self._listeners
|
||||
if not (isinstance(l, PropertyChangeListenerProxy)
|
||||
and l.getListener() == listener
|
||||
and l.getPropertyName() == property_name)
|
||||
]
|
||||
else:
|
||||
self._listeners = [l for l in self._listeners if l != listener]
|
||||
|
||||
def fireVetoableChange(self, property_name_or_evt, old_value=None, new_value=None):
|
||||
if isinstance(property_name_or_evt, PropertyChangeEvent):
|
||||
evt = property_name_or_evt
|
||||
else:
|
||||
evt = PropertyChangeEvent(self._source, property_name_or_evt,
|
||||
old_value, new_value)
|
||||
for listener in self._listeners:
|
||||
if isinstance(listener, PropertyChangeListenerProxy):
|
||||
if listener.getPropertyName() == evt.getPropertyName():
|
||||
listener.propertyChange(evt)
|
||||
else:
|
||||
listener.propertyChange(evt)
|
||||
|
||||
def hasListeners(self, property_name):
|
||||
for listener in self._listeners:
|
||||
if isinstance(listener, PropertyChangeListenerProxy):
|
||||
if listener.getPropertyName() == property_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PropertyEditor
|
||||
# ============================================================
|
||||
|
||||
class PropertyEditor(Stub):
|
||||
"""java.beans.PropertyEditor"""
|
||||
def setValue(self, value):
|
||||
pass
|
||||
|
||||
def getValue(self):
|
||||
return None
|
||||
|
||||
def isPaintable(self):
|
||||
return False
|
||||
|
||||
def paintValue(self, gfx, box):
|
||||
pass
|
||||
|
||||
def getJavaInitializationString(self):
|
||||
return ""
|
||||
|
||||
def getAsText(self):
|
||||
return ""
|
||||
|
||||
def setAsText(self, text):
|
||||
pass
|
||||
|
||||
def getTags(self):
|
||||
return None
|
||||
|
||||
def getCustomEditor(self):
|
||||
return None
|
||||
|
||||
def supportsCustomEditor(self):
|
||||
return False
|
||||
|
||||
def addPropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
def removePropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
|
||||
class PropertyEditorSupport(PropertyEditor):
|
||||
"""java.beans.PropertyEditorSupport"""
|
||||
def __init__(self, source=None):
|
||||
super().__init__()
|
||||
self._source = source
|
||||
self._value = None
|
||||
self._listeners = []
|
||||
|
||||
def setValue(self, value):
|
||||
self._value = value
|
||||
self._fire_property_change()
|
||||
|
||||
def getValue(self):
|
||||
return self._value
|
||||
|
||||
def getAsText(self):
|
||||
if self._value is None:
|
||||
return "null"
|
||||
return str(self._value)
|
||||
|
||||
def setAsText(self, text):
|
||||
self._value = text
|
||||
self._fire_property_change()
|
||||
|
||||
def getSource(self):
|
||||
return self._source
|
||||
|
||||
def addPropertyChangeListener(self, listener):
|
||||
self._listeners.append(listener)
|
||||
|
||||
def removePropertyChangeListener(self, listener):
|
||||
if listener in self._listeners:
|
||||
self._listeners.remove(listener)
|
||||
|
||||
def _fire_property_change(self):
|
||||
evt = PropertyChangeEvent(self._source, "", None, self._value)
|
||||
for listener in self._listeners:
|
||||
listener.propertyChange(evt)
|
||||
|
||||
|
||||
class PropertyEditorManager(Stub):
|
||||
"""java.beans.PropertyEditorManager"""
|
||||
_editors = {}
|
||||
|
||||
@staticmethod
|
||||
def findEditor(target_type):
|
||||
return PropertyEditorSupport()
|
||||
|
||||
@staticmethod
|
||||
def registerEditor(target_type, editor_class):
|
||||
PropertyEditorManager._editors[target_type] = editor_class
|
||||
|
||||
@staticmethod
|
||||
def getEditorSearchPath():
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def setEditorSearchPath(path):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# EventHandler
|
||||
# ============================================================
|
||||
|
||||
class EventHandler(Stub):
|
||||
"""java.beans.EventHandler"""
|
||||
def __init__(self, target, action, event_property_name, listener_method_name):
|
||||
super().__init__()
|
||||
self._target = target
|
||||
self._action = action
|
||||
self._event_property_name = event_property_name
|
||||
self._listener_method_name = listener_method_name
|
||||
|
||||
@staticmethod
|
||||
def create(listener_interface, target, action, event_property_name=None,
|
||||
listener_method_name=None):
|
||||
return target
|
||||
|
||||
def invoke(self, proxy, method, arguments):
|
||||
if self._target and self._action:
|
||||
action_fn = getattr(self._target, self._action, None)
|
||||
if action_fn:
|
||||
return action_fn()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExceptionListener
|
||||
# ============================================================
|
||||
|
||||
class ExceptionListener(Stub):
|
||||
"""java.beans.ExceptionListener"""
|
||||
def exceptionThrown(self, e):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AppletInitializer
|
||||
# ============================================================
|
||||
|
||||
class AppletInitializer(Stub):
|
||||
"""java.beans.AppletInitializer"""
|
||||
def initialize(self, applet_bean, bean_context):
|
||||
pass
|
||||
|
||||
def activate(self, applet_bean):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Beans / Customizer / DesignMode / Visibility
|
||||
# ============================================================
|
||||
|
||||
class Beans(Stub):
|
||||
"""java.beans.Beans"""
|
||||
@staticmethod
|
||||
def instantiate(cls_loader, bean_name, bean_context=None, bean_arg=None):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def designTime():
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def isDesignTime():
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def setDesignTime(is_design_time):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def isGuiAvailable():
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def setGuiAvailable(is_gui_available):
|
||||
pass
|
||||
|
||||
|
||||
class Customizer(Stub):
|
||||
"""java.beans.Customizer"""
|
||||
def setObject(self, bean):
|
||||
pass
|
||||
|
||||
def addPropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
def removePropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
|
||||
class DesignMode(Stub):
|
||||
"""java.beans.DesignMode"""
|
||||
PROPERTYNAME = "designTime"
|
||||
|
||||
def isDesignTime(self):
|
||||
return False
|
||||
|
||||
def setDesignTime(self, design_time):
|
||||
pass
|
||||
|
||||
|
||||
class Visibility(Stub):
|
||||
"""java.beans.Visibility"""
|
||||
def needsGui(self):
|
||||
return False
|
||||
|
||||
def dontUseGui(self):
|
||||
pass
|
||||
|
||||
def okToUseGui(self):
|
||||
pass
|
||||
|
||||
def avoidingGui(self):
|
||||
return True
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,303 @@
|
||||
"""
|
||||
Java java.lang.annotation APIs implemented in Python.
|
||||
java.lang.annotation package - Annotation, Retention, Target, Documented, Inherited, etc.
|
||||
Desktop wrapper classes mirroring the Java annotation framework.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from ..java.lang import Error
|
||||
|
||||
__all__ = [
|
||||
"Annotation", "Documented", "Inherited", "Repeatable", "Retention",
|
||||
"RetentionPolicy", "Target", "ElementType", "Native",
|
||||
"IncompleteAnnotationException", "AnnotationFormatError",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RetentionPolicy enum
|
||||
# ============================================================
|
||||
|
||||
class RetentionPolicy(Stub):
|
||||
"""
|
||||
java.lang.annotation.RetentionPolicy
|
||||
Enum-like class for annotation retention policies.
|
||||
"""
|
||||
SOURCE: "RetentionPolicy" = None
|
||||
CLASS: "RetentionPolicy" = None
|
||||
RUNTIME: "RetentionPolicy" = None
|
||||
|
||||
def __init__(self, name: str):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def toString(self) -> str:
|
||||
return self._name
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if isinstance(other, RetentionPolicy):
|
||||
return self._name == other._name
|
||||
return False
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._name) & 0x7FFFFFFF
|
||||
|
||||
def ordinal(self) -> int:
|
||||
return ["SOURCE", "CLASS", "RUNTIME"].index(self._name)
|
||||
|
||||
|
||||
RetentionPolicy.SOURCE = RetentionPolicy("SOURCE")
|
||||
RetentionPolicy.CLASS = RetentionPolicy("CLASS")
|
||||
RetentionPolicy.RUNTIME = RetentionPolicy("RUNTIME")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ElementType enum
|
||||
# ============================================================
|
||||
|
||||
class ElementType(Stub):
|
||||
"""
|
||||
java.lang.annotation.ElementType
|
||||
Enum-like class for annotation target element types.
|
||||
"""
|
||||
TYPE: "ElementType" = None
|
||||
FIELD: "ElementType" = None
|
||||
METHOD: "ElementType" = None
|
||||
PARAMETER: "ElementType" = None
|
||||
CONSTRUCTOR: "ElementType" = None
|
||||
LOCAL_VARIABLE: "ElementType" = None
|
||||
ANNOTATION_TYPE: "ElementType" = None
|
||||
PACKAGE: "ElementType" = None
|
||||
TYPE_PARAMETER: "ElementType" = None
|
||||
TYPE_USE: "ElementType" = None
|
||||
MODULE: "ElementType" = None
|
||||
RECORD_COMPONENT: "ElementType" = None
|
||||
|
||||
def __init__(self, name: str):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def toString(self) -> str:
|
||||
return self._name
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if isinstance(other, ElementType):
|
||||
return self._name == other._name
|
||||
return False
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._name) & 0x7FFFFFFF
|
||||
|
||||
def ordinal(self) -> int:
|
||||
return [
|
||||
"TYPE", "FIELD", "METHOD", "PARAMETER", "CONSTRUCTOR",
|
||||
"LOCAL_VARIABLE", "ANNOTATION_TYPE", "PACKAGE",
|
||||
"TYPE_PARAMETER", "TYPE_USE", "MODULE", "RECORD_COMPONENT",
|
||||
].index(self._name)
|
||||
|
||||
|
||||
ElementType.TYPE = ElementType("TYPE")
|
||||
ElementType.FIELD = ElementType("FIELD")
|
||||
ElementType.METHOD = ElementType("METHOD")
|
||||
ElementType.PARAMETER = ElementType("PARAMETER")
|
||||
ElementType.CONSTRUCTOR = ElementType("CONSTRUCTOR")
|
||||
ElementType.LOCAL_VARIABLE = ElementType("LOCAL_VARIABLE")
|
||||
ElementType.ANNOTATION_TYPE = ElementType("ANNOTATION_TYPE")
|
||||
ElementType.PACKAGE = ElementType("PACKAGE")
|
||||
ElementType.TYPE_PARAMETER = ElementType("TYPE_PARAMETER")
|
||||
ElementType.TYPE_USE = ElementType("TYPE_USE")
|
||||
ElementType.MODULE = ElementType("MODULE")
|
||||
ElementType.RECORD_COMPONENT = ElementType("RECORD_COMPONENT")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Annotation (interface)
|
||||
# ============================================================
|
||||
|
||||
class Annotation(Stub):
|
||||
"""
|
||||
java.lang.annotation.Annotation
|
||||
The common interface for all annotation types.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def annotationType(self) -> type:
|
||||
"""Returns the annotation type of this annotation."""
|
||||
return self.__class__
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"@{self.__class__.__name__}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self.__class__.__name__) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Documented
|
||||
# ============================================================
|
||||
|
||||
class Documented(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Documented
|
||||
Indicates that annotations with a type are to be documented by javadoc.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Inherited
|
||||
# ============================================================
|
||||
|
||||
class Inherited(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Inherited
|
||||
Indicates that an annotation type is automatically inherited.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Repeatable
|
||||
# ============================================================
|
||||
|
||||
class Repeatable(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Repeatable
|
||||
Indicates that the annotation type can be applied more than once.
|
||||
"""
|
||||
def __init__(self, value: type = None):
|
||||
super().__init__()
|
||||
self._value = value
|
||||
|
||||
def value(self) -> type:
|
||||
return self._value
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"@Repeatable(value={self._value})" if self._value else "@Repeatable"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Retention
|
||||
# ============================================================
|
||||
|
||||
class Retention(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Retention
|
||||
Indicates how long annotations with the annotated type are to be retained.
|
||||
"""
|
||||
def __init__(self, value: RetentionPolicy = RetentionPolicy.CLASS):
|
||||
super().__init__()
|
||||
self._value = value
|
||||
|
||||
def value(self) -> RetentionPolicy:
|
||||
return self._value
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"@Retention(value={self._value})"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Target
|
||||
# ============================================================
|
||||
|
||||
class Target(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Target
|
||||
Indicates the contexts in which an annotation type is applicable.
|
||||
"""
|
||||
def __init__(self, value=None):
|
||||
super().__init__()
|
||||
self._value = value if value is not None else []
|
||||
|
||||
def value(self):
|
||||
"""Returns the element types this annotation can be applied to."""
|
||||
return self._value
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"@Target(value={self._value})"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Native
|
||||
# ============================================================
|
||||
|
||||
class Native(Annotation):
|
||||
"""
|
||||
java.lang.annotation.Native
|
||||
Indicates that a field defining a constant value may be referenced from native code.
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# IncompleteAnnotationException
|
||||
# ============================================================
|
||||
|
||||
class IncompleteAnnotationException(Exception, Stub):
|
||||
"""
|
||||
java.lang.annotation.IncompleteAnnotationException
|
||||
Thrown when a program attempts to access an annotation with missing elements.
|
||||
"""
|
||||
def __init__(self, annotation_type: type = None, element_name: str = None):
|
||||
super().__init__(f"Annotation {annotation_type} is missing element '{element_name}'")
|
||||
self._annotation_type = annotation_type
|
||||
self._element_name = element_name
|
||||
|
||||
def annotationType(self) -> type:
|
||||
return self._annotation_type
|
||||
|
||||
def elementName(self) -> str:
|
||||
return self._element_name
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"IncompleteAnnotationException: {self._annotation_type} missing '{self._element_name}'"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, IncompleteAnnotationException):
|
||||
return False
|
||||
return self._annotation_type == other._annotation_type and self._element_name == other._element_name
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((str(self._annotation_type), self._element_name)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AnnotationFormatError
|
||||
# ============================================================
|
||||
|
||||
class AnnotationFormatError(Error, Stub):
|
||||
"""
|
||||
java.lang.annotation.AnnotationFormatError
|
||||
Thrown when the annotation parser attempts to read an annotation from a class file
|
||||
and determines that the annotation is malformed.
|
||||
"""
|
||||
def __init__(self, message: str = None, cause: Exception = None):
|
||||
super().__init__(message, cause)
|
||||
self._message = message
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"AnnotationFormatError: {self._message}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, AnnotationFormatError):
|
||||
return False
|
||||
return self._message == other._message
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._message) & 0x7FFFFFFF
|
||||
@@ -0,0 +1,766 @@
|
||||
"""
|
||||
Java java.lang.invoke standard library APIs implemented in Python.
|
||||
java.lang.invoke package - MethodHandle, MethodType, MethodHandles, CallSite, VarHandle, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from ..java.lang import RuntimeException, Exception as _JavaException
|
||||
import typing as _typing
|
||||
import types as _py_types
|
||||
import inspect as _inspect
|
||||
import functools as _functools
|
||||
|
||||
__all__ = [
|
||||
"MethodHandle", "MethodType", "MethodHandles", "MethodHandles_Lookup",
|
||||
"CallSite", "ConstantCallSite", "MutableCallSite", "VolatileCallSite",
|
||||
"SwitchPoint", "VarHandle", "VarHandle_AccessMode",
|
||||
"MethodHandleInfo", "MethodHandleProxies",
|
||||
"SerializedLambda", "LambdaMetafactory", "StringConcatFactory",
|
||||
"REF_GET_FIELD", "REF_GET_STATIC", "REF_PUT_FIELD",
|
||||
"REF_PUT_STATIC", "REF_INVOKE_VIRTUAL", "REF_INVOKE_STATIC",
|
||||
"REF_INVOKE_SPECIAL", "REF_NEW_INVOKE_SPECIAL",
|
||||
"REF_INVOKE_INTERFACE",
|
||||
"LT_GLOBAL", "LT_NEW",
|
||||
]
|
||||
|
||||
# ============================================================
|
||||
# Reference Constants
|
||||
# ============================================================
|
||||
|
||||
REF_GET_FIELD = 1
|
||||
REF_GET_STATIC = 2
|
||||
REF_PUT_FIELD = 3
|
||||
REF_PUT_STATIC = 4
|
||||
REF_INVOKE_VIRTUAL = 5
|
||||
REF_INVOKE_STATIC = 6
|
||||
REF_INVOKE_SPECIAL = 7
|
||||
REF_NEW_INVOKE_SPECIAL = 8
|
||||
REF_INVOKE_INTERFACE = 9
|
||||
|
||||
LT_GLOBAL = "global"
|
||||
LT_NEW = "new"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodType
|
||||
# ============================================================
|
||||
|
||||
class MethodType(Stub):
|
||||
"""java.lang.invoke.MethodType"""
|
||||
def __init__(self, return_type, param_types=None):
|
||||
super().__init__()
|
||||
self._return_type = return_type
|
||||
self._param_types = list(param_types or [])
|
||||
|
||||
def returnType(self):
|
||||
return self._return_type
|
||||
|
||||
def parameterCount(self):
|
||||
return len(self._param_types)
|
||||
|
||||
def parameterType(self, index):
|
||||
return self._param_types[index]
|
||||
|
||||
def parameterList(self):
|
||||
return list(self._param_types)
|
||||
|
||||
def parameterArray(self):
|
||||
return list(self._param_types)
|
||||
|
||||
def appendParameterTypes(self, *types):
|
||||
return MethodType(self._return_type, self._param_types + list(types))
|
||||
|
||||
def changeReturnType(self, return_type):
|
||||
return MethodType(return_type, self._param_types)
|
||||
|
||||
def changeParameterType(self, index, param_type):
|
||||
new_params = list(self._param_types)
|
||||
new_params[index] = param_type
|
||||
return MethodType(self._return_type, new_params)
|
||||
|
||||
def dropParameterTypes(self, start, end):
|
||||
new_params = self._param_types[:start] + self._param_types[end:]
|
||||
return MethodType(self._return_type, new_params)
|
||||
|
||||
def insertParameterTypes(self, index, *types):
|
||||
new_params = self._param_types[:index] + list(types) + self._param_types[index:]
|
||||
return MethodType(self._return_type, new_params)
|
||||
|
||||
def genericMethodType(self, object_count, final_array=False):
|
||||
return MethodType(object, [object] * object_count)
|
||||
|
||||
@staticmethod
|
||||
def methodType(return_type, *param_types):
|
||||
return MethodType(return_type, list(param_types))
|
||||
|
||||
@staticmethod
|
||||
def genericMethodType(object_count, final_array=False):
|
||||
return MethodType(object, [object] * object_count)
|
||||
|
||||
def toString(self):
|
||||
params = ", ".join(str(t) for t in self._param_types)
|
||||
return f"({params}) -> {self._return_type}"
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, MethodType):
|
||||
return False
|
||||
return (self._return_type == other._return_type
|
||||
and self._param_types == other._param_types)
|
||||
|
||||
def hashCode(self):
|
||||
return hash((self._return_type, tuple(self._param_types)))
|
||||
|
||||
def wrap(self):
|
||||
return self
|
||||
|
||||
def unwrap(self):
|
||||
return self
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodHandle
|
||||
# ============================================================
|
||||
|
||||
class MethodHandle(Stub):
|
||||
"""java.lang.invoke.MethodHandle"""
|
||||
def __init__(self, method_type=None, target=None):
|
||||
super().__init__()
|
||||
self._type = method_type or MethodType(object, [])
|
||||
self._target = target
|
||||
|
||||
def type(self):
|
||||
return self._type
|
||||
|
||||
def invoke(self, *args):
|
||||
if self._target is None:
|
||||
return None
|
||||
return self._target(*args)
|
||||
|
||||
def invokeExact(self, *args):
|
||||
return self.invoke(*args)
|
||||
|
||||
def invokeWithArguments(self, *args):
|
||||
return self.invoke(*args)
|
||||
|
||||
def asType(self, new_type):
|
||||
return self._target
|
||||
|
||||
def asCollector(self, array_type, array_length):
|
||||
return self
|
||||
|
||||
def asSpreader(self, array_type, array_length):
|
||||
return self
|
||||
|
||||
def bindTo(self, argument):
|
||||
bound_target = None
|
||||
if self._target is not None:
|
||||
bound_target = _functools.partial(self._target, argument)
|
||||
return MethodHandle(self._type.dropParameterTypes(0, 1), bound_target)
|
||||
|
||||
def toString(self):
|
||||
return f"MethodHandle{self._type}"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodHandles / Lookup
|
||||
# ============================================================
|
||||
|
||||
class MethodHandles_Lookup(Stub):
|
||||
"""java.lang.invoke.MethodHandles.Lookup"""
|
||||
def __init__(self, lookup_class=None):
|
||||
super().__init__()
|
||||
self._lookup_class = lookup_class
|
||||
|
||||
def lookupClass(self):
|
||||
return self._lookup_class
|
||||
|
||||
def findStatic(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findVirtual(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findConstructor(self, refc, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findSpecial(self, refc, name, type_, special_caller):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findGetter(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findSetter(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findStaticGetter(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def findStaticSetter(self, refc, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def bind(self, receiver, name, type_):
|
||||
return MethodHandle(type_)
|
||||
|
||||
def unreflect(self, method):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
def unreflectConstructor(self, constructor):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
def unreflectGetter(self, field):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
def unreflectSetter(self, field):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
def dropLookupMode(self, mode_to_drop):
|
||||
return MethodHandles_Lookup(self._lookup_class)
|
||||
|
||||
def toString(self):
|
||||
return f"Lookup[{self._lookup_class}]"
|
||||
|
||||
PACKAGE = 8
|
||||
PRIVATE = 4
|
||||
PROTECTED = 2
|
||||
PUBLIC = 1
|
||||
|
||||
|
||||
class MethodHandles(Stub):
|
||||
"""java.lang.invoke.MethodHandles"""
|
||||
@staticmethod
|
||||
def lookup():
|
||||
return MethodHandles_Lookup()
|
||||
|
||||
@staticmethod
|
||||
def publicLookup():
|
||||
return MethodHandles_Lookup(object)
|
||||
|
||||
@staticmethod
|
||||
def arrayElementGetter(array_class):
|
||||
return MethodHandle(MethodType(object, [array_class, int]))
|
||||
|
||||
@staticmethod
|
||||
def arrayElementSetter(array_class):
|
||||
return MethodHandle(MethodType(None, [array_class, int, object]))
|
||||
|
||||
@staticmethod
|
||||
def identity(type_):
|
||||
return MethodHandle(MethodType(type_, [type_]))
|
||||
|
||||
@staticmethod
|
||||
def constant(type_, value):
|
||||
return MethodHandle(MethodType(type_, []))
|
||||
|
||||
@staticmethod
|
||||
def zero(type_):
|
||||
return MethodHandle(MethodType(type_, []))
|
||||
|
||||
@staticmethod
|
||||
def filterReturnValue(target, filter_):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def filterArguments(target, pos, *filters):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def collectArguments(target, pos, filter_):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def foldArguments(target, combiner):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def guardWithTest(test, target, fallback):
|
||||
class Guarded(MethodHandle):
|
||||
def invoke(self, *args):
|
||||
if test.invoke(*args):
|
||||
return target.invoke(*args)
|
||||
return fallback.invoke(*args)
|
||||
return Guarded(MethodType(object, []))
|
||||
|
||||
@staticmethod
|
||||
def throwException(return_type, ex_type):
|
||||
return MethodHandle(MethodType(return_type, [ex_type]))
|
||||
|
||||
@staticmethod
|
||||
def spreadInvoker(type_, leading_arg_count):
|
||||
return MethodHandle(type_)
|
||||
|
||||
@staticmethod
|
||||
def explicitCastArguments(target, new_type):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def permuteArguments(target, new_type, *reorder):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def catchException(target, ex_type, handler):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def tryFinally(target, cleanup):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def loop(loop_handles):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CallSite / ConstantCallSite / MutableCallSite / VolatileCallSite
|
||||
# ============================================================
|
||||
|
||||
class CallSite(Stub):
|
||||
"""java.lang.invoke.CallSite"""
|
||||
def __init__(self, target=None):
|
||||
super().__init__()
|
||||
self._target = target
|
||||
|
||||
def type(self):
|
||||
if self._target:
|
||||
return self._target.type()
|
||||
return MethodType(object, [])
|
||||
|
||||
def target(self):
|
||||
return self._target
|
||||
|
||||
def setTarget(self, new_target):
|
||||
self._target = new_target
|
||||
|
||||
def dynamicInvoker(self):
|
||||
return self._target
|
||||
|
||||
|
||||
class ConstantCallSite(CallSite):
|
||||
"""java.lang.invoke.ConstantCallSite"""
|
||||
def __init__(self, target):
|
||||
super().__init__(target)
|
||||
|
||||
def setTarget(self, new_target):
|
||||
raise UnsupportedOperationException("ConstantCallSite target is immutable")
|
||||
|
||||
|
||||
class MutableCallSite(CallSite):
|
||||
"""java.lang.invoke.MutableCallSite"""
|
||||
def __init__(self, target_or_type):
|
||||
if isinstance(target_or_type, MethodType):
|
||||
super().__init__(MethodHandle(target_or_type))
|
||||
else:
|
||||
super().__init__(target_or_type)
|
||||
|
||||
def syncAll(self, sites):
|
||||
pass
|
||||
|
||||
def setTarget(self, new_target):
|
||||
if hasattr(self, '_target'):
|
||||
self._target = new_target
|
||||
|
||||
|
||||
class VolatileCallSite(MutableCallSite):
|
||||
"""java.lang.invoke.VolatileCallSite"""
|
||||
def __init__(self, target_or_type):
|
||||
super().__init__(target_or_type)
|
||||
|
||||
def setTarget(self, new_target):
|
||||
super().setTarget(new_target)
|
||||
|
||||
def target(self):
|
||||
return self._target
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SwitchPoint
|
||||
# ============================================================
|
||||
|
||||
class SwitchPoint(Stub):
|
||||
"""java.lang.invoke.SwitchPoint"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._has_been_invalidated = False
|
||||
|
||||
def hasBeenInvalidated(self):
|
||||
return self._has_been_invalidated
|
||||
|
||||
def invalidateAll(self):
|
||||
self._has_been_invalidated = True
|
||||
|
||||
@staticmethod
|
||||
def guardWithTest(switch_point, target, fallback):
|
||||
class GuardedSwitch(MethodHandle):
|
||||
def invoke(self, *args):
|
||||
if switch_point.hasBeenInvalidated():
|
||||
return fallback.invoke(*args)
|
||||
return target.invoke(*args)
|
||||
return GuardedSwitch(MethodType(object, []))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# VarHandle
|
||||
# ============================================================
|
||||
|
||||
class VarHandle_AccessMode(Stub):
|
||||
"""java.lang.invoke.VarHandle.AccessMode"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
# Access mode constants
|
||||
GET = None
|
||||
SET = None
|
||||
GET_VOLATILE = None
|
||||
SET_VOLATILE = None
|
||||
GET_ACQUIRE = None
|
||||
SET_RELEASE = None
|
||||
GET_OPAQUE = None
|
||||
SET_OPAQUE = None
|
||||
COMPARE_AND_SET = None
|
||||
COMPARE_AND_EXCHANGE = None
|
||||
COMPARE_AND_EXCHANGE_ACQUIRE = None
|
||||
COMPARE_AND_EXCHANGE_RELEASE = None
|
||||
WEAK_COMPARE_AND_SET = None
|
||||
WEAK_COMPARE_AND_SET_ACQUIRE = None
|
||||
WEAK_COMPARE_AND_SET_RELEASE = None
|
||||
GET_AND_SET = None
|
||||
GET_AND_SET_ACQUIRE = None
|
||||
GET_AND_SET_RELEASE = None
|
||||
GET_AND_ADD = None
|
||||
GET_AND_ADD_ACQUIRE = None
|
||||
GET_AND_ADD_RELEASE = None
|
||||
GET_AND_BITWISE_OR = None
|
||||
GET_AND_BITWISE_OR_ACQUIRE = None
|
||||
GET_AND_BITWISE_OR_RELEASE = None
|
||||
GET_AND_BITWISE_AND = None
|
||||
GET_AND_BITWISE_AND_ACQUIRE = None
|
||||
GET_AND_BITWISE_AND_RELEASE = None
|
||||
GET_AND_BITWISE_XOR = None
|
||||
GET_AND_BITWISE_XOR_ACQUIRE = None
|
||||
GET_AND_BITWISE_XOR_RELEASE = None
|
||||
GET = None
|
||||
|
||||
|
||||
class VarHandle(Stub):
|
||||
"""java.lang.invoke.VarHandle"""
|
||||
def __init__(self, var_type=None, coordinate_types=None):
|
||||
super().__init__()
|
||||
self._var_type = var_type or object
|
||||
self._coordinate_types = list(coordinate_types or [])
|
||||
self._access_modes = {}
|
||||
|
||||
def get(self, *coordinates):
|
||||
return None
|
||||
|
||||
def set(self, *coordinates_and_value):
|
||||
pass
|
||||
|
||||
def getVolatile(self, *coordinates):
|
||||
return self.get(*coordinates)
|
||||
|
||||
def setVolatile(self, *coordinates_and_value):
|
||||
self.set(*coordinates_and_value)
|
||||
|
||||
def getAcquire(self, *coordinates):
|
||||
return self.get(*coordinates)
|
||||
|
||||
def setRelease(self, *coordinates_and_value):
|
||||
self.set(*coordinates_and_value)
|
||||
|
||||
def getOpaque(self, *coordinates):
|
||||
return self.get(*coordinates)
|
||||
|
||||
def setOpaque(self, *coordinates_and_value):
|
||||
self.set(*coordinates_and_value)
|
||||
|
||||
def compareAndSet(self, *args):
|
||||
return True
|
||||
|
||||
def compareAndExchange(self, *args):
|
||||
return args[-2]
|
||||
|
||||
def compareAndExchangeAcquire(self, *args):
|
||||
return self.compareAndExchange(*args)
|
||||
|
||||
def compareAndExchangeRelease(self, *args):
|
||||
return self.compareAndExchange(*args)
|
||||
|
||||
def weakCompareAndSet(self, *args):
|
||||
return True
|
||||
|
||||
def weakCompareAndSetAcquire(self, *args):
|
||||
return True
|
||||
|
||||
def weakCompareAndSetRelease(self, *args):
|
||||
return True
|
||||
|
||||
def getAndSet(self, *coordinates_and_value):
|
||||
return None
|
||||
|
||||
def getAndSetAcquire(self, *coordinates_and_value):
|
||||
return self.getAndSet(*coordinates_and_value)
|
||||
|
||||
def getAndSetRelease(self, *coordinates_and_value):
|
||||
return self.getAndSet(*coordinates_and_value)
|
||||
|
||||
def getAndAdd(self, *coordinates_and_value):
|
||||
return 0
|
||||
|
||||
def getAndAddAcquire(self, *coordinates_and_value):
|
||||
return self.getAndAdd(*coordinates_and_value)
|
||||
|
||||
def getAndAddRelease(self, *coordinates_and_value):
|
||||
return self.getAndAdd(*coordinates_and_value)
|
||||
|
||||
def getAndBitwiseOr(self, *coordinates_and_value):
|
||||
return 0
|
||||
|
||||
def getAndBitwiseAnd(self, *coordinates_and_value):
|
||||
return 0
|
||||
|
||||
def getAndBitwiseXor(self, *coordinates_and_value):
|
||||
return 0
|
||||
|
||||
def varType(self):
|
||||
return self._var_type
|
||||
|
||||
def coordinateTypes(self):
|
||||
return self._coordinate_types
|
||||
|
||||
def toMethodHandle(self, access_mode):
|
||||
return MethodHandle(MethodType(self._var_type, self._coordinate_types))
|
||||
|
||||
def getAccessModes(self):
|
||||
return list(self._access_modes.values())
|
||||
|
||||
def isAccessModeSupported(self, access_mode):
|
||||
return True
|
||||
|
||||
AccessMode = VarHandle_AccessMode
|
||||
|
||||
def toString(self):
|
||||
return f"VarHandle[{self._var_type}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Initialize VarHandle_AccessMode constants
|
||||
# ============================================================
|
||||
|
||||
VarHandle_AccessMode.GET = VarHandle_AccessMode("GET")
|
||||
VarHandle_AccessMode.SET = VarHandle_AccessMode("SET")
|
||||
VarHandle_AccessMode.GET_VOLATILE = VarHandle_AccessMode("GET_VOLATILE")
|
||||
VarHandle_AccessMode.SET_VOLATILE = VarHandle_AccessMode("SET_VOLATILE")
|
||||
VarHandle_AccessMode.GET_ACQUIRE = VarHandle_AccessMode("GET_ACQUIRE")
|
||||
VarHandle_AccessMode.SET_RELEASE = VarHandle_AccessMode("SET_RELEASE")
|
||||
VarHandle_AccessMode.GET_OPAQUE = VarHandle_AccessMode("GET_OPAQUE")
|
||||
VarHandle_AccessMode.SET_OPAQUE = VarHandle_AccessMode("SET_OPAQUE")
|
||||
VarHandle_AccessMode.COMPARE_AND_SET = VarHandle_AccessMode("COMPARE_AND_SET")
|
||||
VarHandle_AccessMode.COMPARE_AND_EXCHANGE = VarHandle_AccessMode("COMPARE_AND_EXCHANGE")
|
||||
VarHandle_AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE = VarHandle_AccessMode("COMPARE_AND_EXCHANGE_ACQUIRE")
|
||||
VarHandle_AccessMode.COMPARE_AND_EXCHANGE_RELEASE = VarHandle_AccessMode("COMPARE_AND_EXCHANGE_RELEASE")
|
||||
VarHandle_AccessMode.WEAK_COMPARE_AND_SET = VarHandle_AccessMode("WEAK_COMPARE_AND_SET")
|
||||
VarHandle_AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE = VarHandle_AccessMode("WEAK_COMPARE_AND_SET_ACQUIRE")
|
||||
VarHandle_AccessMode.WEAK_COMPARE_AND_SET_RELEASE = VarHandle_AccessMode("WEAK_COMPARE_AND_SET_RELEASE")
|
||||
VarHandle_AccessMode.GET_AND_SET = VarHandle_AccessMode("GET_AND_SET")
|
||||
VarHandle_AccessMode.GET_AND_SET_ACQUIRE = VarHandle_AccessMode("GET_AND_SET_ACQUIRE")
|
||||
VarHandle_AccessMode.GET_AND_SET_RELEASE = VarHandle_AccessMode("GET_AND_SET_RELEASE")
|
||||
VarHandle_AccessMode.GET_AND_ADD = VarHandle_AccessMode("GET_AND_ADD")
|
||||
VarHandle_AccessMode.GET_AND_ADD_ACQUIRE = VarHandle_AccessMode("GET_AND_ADD_ACQUIRE")
|
||||
VarHandle_AccessMode.GET_AND_ADD_RELEASE = VarHandle_AccessMode("GET_AND_ADD_RELEASE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_OR = VarHandle_AccessMode("GET_AND_BITWISE_OR")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_OR_ACQUIRE = VarHandle_AccessMode("GET_AND_BITWISE_OR_ACQUIRE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_OR_RELEASE = VarHandle_AccessMode("GET_AND_BITWISE_OR_RELEASE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_AND = VarHandle_AccessMode("GET_AND_BITWISE_AND")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_AND_ACQUIRE = VarHandle_AccessMode("GET_AND_BITWISE_AND_ACQUIRE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_AND_RELEASE = VarHandle_AccessMode("GET_AND_BITWISE_AND_RELEASE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_XOR = VarHandle_AccessMode("GET_AND_BITWISE_XOR")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_XOR_ACQUIRE = VarHandle_AccessMode("GET_AND_BITWISE_XOR_ACQUIRE")
|
||||
VarHandle_AccessMode.GET_AND_BITWISE_XOR_RELEASE = VarHandle_AccessMode("GET_AND_BITWISE_XOR_RELEASE")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodHandleInfo
|
||||
# ============================================================
|
||||
|
||||
class MethodHandleInfo(Stub):
|
||||
"""java.lang.invoke.MethodHandleInfo"""
|
||||
def __init__(self, reference_kind=0, declaring_class=None, name="", method_type=None):
|
||||
super().__init__()
|
||||
self._reference_kind = reference_kind
|
||||
self._declaring_class = declaring_class
|
||||
self._name = name
|
||||
self._method_type = method_type or MethodType(object, [])
|
||||
|
||||
def getReferenceKind(self):
|
||||
return self._reference_kind
|
||||
|
||||
def getDeclaringClass(self):
|
||||
return self._declaring_class
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def getMethodType(self):
|
||||
return self._method_type
|
||||
|
||||
def isVarArgs(self):
|
||||
return False
|
||||
|
||||
def reflectAs(self, expected_type, lookup):
|
||||
return None
|
||||
|
||||
def toString(self):
|
||||
return (f"MethodHandleInfo[{self._name}, kind={self._reference_kind}, "
|
||||
f"class={self._declaring_class}, type={self._method_type}]")
|
||||
|
||||
# Reference kind constants
|
||||
REF_getField = REF_GET_FIELD
|
||||
REF_getStatic = REF_GET_STATIC
|
||||
REF_putField = REF_PUT_FIELD
|
||||
REF_putStatic = REF_PUT_STATIC
|
||||
REF_invokeVirtual = REF_INVOKE_VIRTUAL
|
||||
REF_invokeStatic = REF_INVOKE_STATIC
|
||||
REF_invokeSpecial = REF_INVOKE_SPECIAL
|
||||
REF_newInvokeSpecial = REF_NEW_INVOKE_SPECIAL
|
||||
REF_invokeInterface = REF_INVOKE_INTERFACE
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MethodHandleProxies
|
||||
# ============================================================
|
||||
|
||||
class MethodHandleProxies(Stub):
|
||||
"""java.lang.invoke.MethodHandleProxies"""
|
||||
@staticmethod
|
||||
def asInterfaceInstance(iface, target):
|
||||
return target
|
||||
|
||||
@staticmethod
|
||||
def isWrapperClass(cls):
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def wrapperInstanceTarget(proxy):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def wrapperInstanceType(proxy):
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SerializedLambda
|
||||
# ============================================================
|
||||
|
||||
class SerializedLambda(Stub):
|
||||
"""java.lang.invoke.SerializedLambda"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._capturing_class = ""
|
||||
self._functional_interface_class_name = ""
|
||||
self._functional_interface_method_name = ""
|
||||
self._functional_interface_method_signature = ""
|
||||
self._impl_class = ""
|
||||
self._impl_method_name = ""
|
||||
self._impl_method_signature = ""
|
||||
self._impl_method_kind = 0
|
||||
self._captured_args = []
|
||||
self._instantiated_method_type = ""
|
||||
self._captured_arg_count = 0
|
||||
|
||||
def getCapturingClass(self):
|
||||
return self._capturing_class
|
||||
|
||||
def getFunctionalInterfaceClassName(self):
|
||||
return self._functional_interface_class_name
|
||||
|
||||
def getFunctionalInterfaceMethodName(self):
|
||||
return self._functional_interface_method_name
|
||||
|
||||
def getFunctionalInterfaceMethodSignature(self):
|
||||
return self._functional_interface_method_signature
|
||||
|
||||
def getImplClass(self):
|
||||
return self._impl_class
|
||||
|
||||
def getImplMethodName(self):
|
||||
return self._impl_method_name
|
||||
|
||||
def getImplMethodSignature(self):
|
||||
return self._impl_method_signature
|
||||
|
||||
def getImplMethodKind(self):
|
||||
return self._impl_method_kind
|
||||
|
||||
def getCapturedArgCount(self):
|
||||
return self._captured_arg_count
|
||||
|
||||
def getCapturedArg(self, i):
|
||||
return self._captured_args[i] if i < len(self._captured_args) else None
|
||||
|
||||
def getInstantiatedMethodType(self):
|
||||
return self._instantiated_method_type
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LambdaMetafactory
|
||||
# ============================================================
|
||||
|
||||
class LambdaMetafactory(Stub):
|
||||
"""java.lang.invoke.LambdaMetafactory"""
|
||||
FLAG_SERIALIZABLE = 1
|
||||
FLAG_MARKERS = 2
|
||||
FLAG_BRIDGES = 4
|
||||
|
||||
@staticmethod
|
||||
def metafactory(caller, invoked_name, invoked_type, sam_method_type,
|
||||
impl_method, instantiated_method_type, *args):
|
||||
return MethodHandle(instantiated_method_type)
|
||||
|
||||
@staticmethod
|
||||
def altMetafactory(caller, invoked_name, invoked_type, *args):
|
||||
return MethodHandle(MethodType(object, []))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StringConcatFactory
|
||||
# ============================================================
|
||||
|
||||
class StringConcatFactory(Stub):
|
||||
"""java.lang.invoke.StringConcatFactory"""
|
||||
@staticmethod
|
||||
def makeConcatWithConstants(lookup, name, concat_type, recipe, *constants):
|
||||
return MethodHandle(concat_type)
|
||||
|
||||
@staticmethod
|
||||
def makeConcat(lookup, name, concat_type):
|
||||
class ConcatHandle(MethodHandle):
|
||||
def invoke(self, *args):
|
||||
return "".join(str(a) for a in args)
|
||||
return ConcatHandle(concat_type, lambda *args: "".join(str(a) for a in args))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# UnsupportedOperationException
|
||||
# ============================================================
|
||||
|
||||
class UnsupportedOperationException(RuntimeException):
|
||||
"""java.lang.UnsupportedOperationException"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Alias for MethodHandles.Lookup
|
||||
# ============================================================
|
||||
|
||||
MethodHandles_Lookup = MethodHandles_Lookup
|
||||
MethodHandles.Lookup = MethodHandles_Lookup
|
||||
VarHandle.AccessMode = VarHandle_AccessMode
|
||||
@@ -0,0 +1,830 @@
|
||||
"""
|
||||
Java java.lang.management standard library APIs implemented in Python.
|
||||
java.lang.management package - ManagementFactory, MXBeans, ThreadInfo, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from ..java.lang import RuntimeException, StackTraceElement
|
||||
import typing as _typing
|
||||
import time as _time
|
||||
import os as _os
|
||||
import sys as _sys
|
||||
import threading as _threading
|
||||
import platform as _platform
|
||||
|
||||
__all__ = [
|
||||
"ManagementFactory", "MemoryMXBean", "MemoryUsage", "MemoryType",
|
||||
"MemoryPoolMXBean", "MemoryManagerMXBean", "GarbageCollectorMXBean",
|
||||
"ThreadMXBean", "RuntimeMXBean", "ClassLoadingMXBean",
|
||||
"OperatingSystemMXBean", "CompilationMXBean",
|
||||
"PlatformLoggingMXBean", "PlatformManagedObject",
|
||||
"ManagementPermission", "LockInfo", "MonitorInfo", "ThreadInfo",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ManagementPermission
|
||||
# ============================================================
|
||||
|
||||
class ManagementPermission(Stub):
|
||||
"""java.lang.management.ManagementPermission"""
|
||||
def __init__(self, name, actions=None):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._actions = actions
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def getActions(self):
|
||||
return self._actions or ""
|
||||
|
||||
def implies(self, permission):
|
||||
return True
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MemoryType
|
||||
# ============================================================
|
||||
|
||||
class MemoryType(Stub):
|
||||
"""java.lang.management.MemoryType"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
HEAP = None
|
||||
NON_HEAP = None
|
||||
|
||||
|
||||
MemoryType.HEAP = MemoryType("HEAP")
|
||||
MemoryType.NON_HEAP = MemoryType("NON_HEAP")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MemoryUsage
|
||||
# ============================================================
|
||||
|
||||
class MemoryUsage(Stub):
|
||||
"""java.lang.management.MemoryUsage"""
|
||||
def __init__(self, init, used, committed, max_val):
|
||||
super().__init__()
|
||||
self._init = init
|
||||
self._used = used
|
||||
self._committed = committed
|
||||
self._max = max_val
|
||||
|
||||
def getInit(self):
|
||||
return self._init
|
||||
|
||||
def getUsed(self):
|
||||
return self._used
|
||||
|
||||
def getCommitted(self):
|
||||
return self._committed
|
||||
|
||||
def getMax(self):
|
||||
return self._max
|
||||
|
||||
def toString(self):
|
||||
return (f"init={self._init} used={self._used} "
|
||||
f"committed={self._committed} max={self._max}")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LockInfo
|
||||
# ============================================================
|
||||
|
||||
class LockInfo(Stub):
|
||||
"""java.lang.management.LockInfo"""
|
||||
def __init__(self, class_name, identity_hash_code):
|
||||
super().__init__()
|
||||
self._class_name = class_name
|
||||
self._identity_hash_code = identity_hash_code
|
||||
|
||||
def getClassName(self):
|
||||
return self._class_name
|
||||
|
||||
def getIdentityHashCode(self):
|
||||
return self._identity_hash_code
|
||||
|
||||
def toString(self):
|
||||
return f"{self._class_name}@{self._identity_hash_code:x}"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MonitorInfo
|
||||
# ============================================================
|
||||
|
||||
class MonitorInfo(LockInfo):
|
||||
"""java.lang.management.MonitorInfo"""
|
||||
def __init__(self, class_name, identity_hash_code,
|
||||
locked_stack_depth, locked_stack_frame):
|
||||
super().__init__(class_name, identity_hash_code)
|
||||
self._locked_stack_depth = locked_stack_depth
|
||||
self._locked_stack_frame = locked_stack_frame
|
||||
|
||||
def getLockedStackDepth(self):
|
||||
return self._locked_stack_depth
|
||||
|
||||
def getLockedStackFrame(self):
|
||||
return self._locked_stack_frame
|
||||
|
||||
def toString(self):
|
||||
return (f"MonitorInfo[{self._class_name}@{self._identity_hash_code:x}, "
|
||||
f"depth={self._locked_stack_depth}]")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ThreadInfo
|
||||
# ============================================================
|
||||
|
||||
class ThreadInfo(Stub):
|
||||
"""java.lang.management.ThreadInfo"""
|
||||
def __init__(self, thread_id=0, thread_name="", thread_state="RUNNABLE",
|
||||
blocked_count=0, blocked_time=-1, waited_count=0, waited_time=-1,
|
||||
lock_name=None, lock_owner_id=-1, lock_owner_name=None,
|
||||
in_native=False, suspended=False, stack_trace=None,
|
||||
locked_monitors=None, locked_synchronizers=None,
|
||||
daemon=False, priority=5):
|
||||
super().__init__()
|
||||
self._thread_id = thread_id
|
||||
self._thread_name = thread_name
|
||||
self._thread_state = thread_state
|
||||
self._blocked_count = blocked_count
|
||||
self._blocked_time = blocked_time
|
||||
self._waited_count = waited_count
|
||||
self._waited_time = waited_time
|
||||
self._lock_name = lock_name
|
||||
self._lock_owner_id = lock_owner_id
|
||||
self._lock_owner_name = lock_owner_name
|
||||
self._in_native = in_native
|
||||
self._suspended = suspended
|
||||
self._stack_trace = stack_trace or []
|
||||
self._locked_monitors = locked_monitors or []
|
||||
self._locked_synchronizers = locked_synchronizers or []
|
||||
self._daemon = daemon
|
||||
self._priority = priority
|
||||
|
||||
def getThreadId(self):
|
||||
return self._thread_id
|
||||
|
||||
def getThreadName(self):
|
||||
return self._thread_name
|
||||
|
||||
def getThreadState(self):
|
||||
return self._thread_state
|
||||
|
||||
def getBlockedCount(self):
|
||||
return self._blocked_count
|
||||
|
||||
def getBlockedTime(self):
|
||||
return self._blocked_time
|
||||
|
||||
def getWaitedCount(self):
|
||||
return self._waited_count
|
||||
|
||||
def getWaitedTime(self):
|
||||
return self._waited_time
|
||||
|
||||
def getLockName(self):
|
||||
return self._lock_name
|
||||
|
||||
def getLockOwnerId(self):
|
||||
return self._lock_owner_id
|
||||
|
||||
def getLockOwnerName(self):
|
||||
return self._lock_owner_name
|
||||
|
||||
def isInNative(self):
|
||||
return self._in_native
|
||||
|
||||
def isSuspended(self):
|
||||
return self._suspended
|
||||
|
||||
def getStackTrace(self):
|
||||
return self._stack_trace
|
||||
|
||||
def getLockedMonitors(self):
|
||||
return self._locked_monitors
|
||||
|
||||
def getLockedSynchronizers(self):
|
||||
return self._locked_synchronizers
|
||||
|
||||
def isDaemon(self):
|
||||
return self._daemon
|
||||
|
||||
def getPriority(self):
|
||||
return self._priority
|
||||
|
||||
def toString(self):
|
||||
return (f"ThreadInfo[id={self._thread_id}, name={self._thread_name}, "
|
||||
f"state={self._thread_state}]")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PlatformManagedObject
|
||||
# ============================================================
|
||||
|
||||
class PlatformManagedObject(Stub):
|
||||
"""java.lang.management.PlatformManagedObject"""
|
||||
def getObjectName(self):
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MemoryMXBean
|
||||
# ============================================================
|
||||
|
||||
class MemoryMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.MemoryMXBean"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
import psutil as _psutil
|
||||
self._psutil_available = False
|
||||
try:
|
||||
import psutil
|
||||
self._psutil = psutil
|
||||
self._psutil_available = True
|
||||
except ImportError:
|
||||
self._psutil_available = False
|
||||
|
||||
def getHeapMemoryUsage(self):
|
||||
if self._psutil_available:
|
||||
mem = self._psutil.virtual_memory()
|
||||
return MemoryUsage(mem.total, mem.used, mem.available, mem.total)
|
||||
return MemoryUsage(0, 0, 0, 0)
|
||||
|
||||
def getNonHeapMemoryUsage(self):
|
||||
return MemoryUsage(0, 0, 0, 0)
|
||||
|
||||
def getObjectPendingFinalizationCount(self):
|
||||
return 0
|
||||
|
||||
def isVerbose(self):
|
||||
return False
|
||||
|
||||
def setVerbose(self, value):
|
||||
pass
|
||||
|
||||
def gc(self):
|
||||
import gc
|
||||
gc.collect()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MemoryPoolMXBean
|
||||
# ============================================================
|
||||
|
||||
class MemoryPoolMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.MemoryPoolMXBean"""
|
||||
def __init__(self, name="", pool_type=MemoryType.HEAP):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._type = pool_type
|
||||
self._usage = MemoryUsage(0, 0, 0, 0)
|
||||
self._peak_usage = MemoryUsage(0, 0, 0, 0)
|
||||
self._collection_usage = None
|
||||
self._valid = True
|
||||
self._threshold = 0
|
||||
self._collection_threshold = 0
|
||||
self._threshold_supported = False
|
||||
self._collection_threshold_supported = False
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def getUsage(self):
|
||||
import psutil
|
||||
try:
|
||||
mem = psutil.virtual_memory()
|
||||
self._usage = MemoryUsage(mem.total, mem.used, mem.available, mem.total)
|
||||
except ImportError:
|
||||
pass
|
||||
return self._usage
|
||||
|
||||
def getPeakUsage(self):
|
||||
return self._peak_usage
|
||||
|
||||
def resetPeakUsage(self):
|
||||
self._peak_usage = MemoryUsage(0, 0, 0, 0)
|
||||
|
||||
def isValid(self):
|
||||
return self._valid
|
||||
|
||||
def getCollectionUsage(self):
|
||||
return self._collection_usage
|
||||
|
||||
def getUsageThreshold(self):
|
||||
return self._threshold
|
||||
|
||||
def setUsageThreshold(self, threshold):
|
||||
self._threshold = threshold
|
||||
self._threshold_supported = True
|
||||
|
||||
def isUsageThresholdSupported(self):
|
||||
return self._threshold_supported
|
||||
|
||||
def isUsageThresholdExceeded(self):
|
||||
return self._usage.getUsed() > self._threshold if self._threshold > 0 else False
|
||||
|
||||
def getUsageThresholdCount(self):
|
||||
return 0
|
||||
|
||||
def getCollectionUsageThreshold(self):
|
||||
return self._collection_threshold
|
||||
|
||||
def setCollectionUsageThreshold(self, threshold):
|
||||
self._collection_threshold = threshold
|
||||
self._collection_threshold_supported = True
|
||||
|
||||
def isCollectionUsageThresholdSupported(self):
|
||||
return self._collection_threshold_supported
|
||||
|
||||
def isCollectionUsageThresholdExceeded(self):
|
||||
return False
|
||||
|
||||
def getCollectionUsageThresholdCount(self):
|
||||
return 0
|
||||
|
||||
def getMemoryManagerNames(self):
|
||||
return []
|
||||
|
||||
def toString(self):
|
||||
return f"MemoryPoolMXBean[name={self._name}, type={self._type}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MemoryManagerMXBean
|
||||
# ============================================================
|
||||
|
||||
class MemoryManagerMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.MemoryManagerMXBean"""
|
||||
def __init__(self, name=""):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._valid = True
|
||||
self._pool_names = []
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def isValid(self):
|
||||
return self._valid
|
||||
|
||||
def getMemoryPoolNames(self):
|
||||
return self._pool_names
|
||||
|
||||
def toString(self):
|
||||
return f"MemoryManagerMXBean[name={self._name}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# GarbageCollectorMXBean
|
||||
# ============================================================
|
||||
|
||||
class GarbageCollectorMXBean(MemoryManagerMXBean):
|
||||
"""java.lang.management.GarbageCollectorMXBean"""
|
||||
def __init__(self, name=""):
|
||||
super().__init__(name)
|
||||
self._collection_count = 0
|
||||
self._collection_time = 0
|
||||
|
||||
def getCollectionCount(self):
|
||||
return self._collection_count
|
||||
|
||||
def getCollectionTime(self):
|
||||
return self._collection_time
|
||||
|
||||
def toString(self):
|
||||
return (f"GarbageCollectorMXBean[name={self._name}, "
|
||||
f"collections={self._collection_count}, "
|
||||
f"time={self._collection_time}ms]")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ThreadMXBean
|
||||
# ============================================================
|
||||
|
||||
class ThreadMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.ThreadMXBean"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._thread_contention_monitoring_enabled = False
|
||||
self._thread_cpu_time_enabled = False
|
||||
self._thread_allocated_memory_enabled = False
|
||||
|
||||
def getThreadCount(self):
|
||||
return _threading.active_count()
|
||||
|
||||
def getPeakThreadCount(self):
|
||||
return _threading.active_count()
|
||||
|
||||
def getTotalStartedThreadCount(self):
|
||||
return _threading.active_count()
|
||||
|
||||
def getDaemonThreadCount(self):
|
||||
return 0
|
||||
|
||||
def getAllThreadIds(self):
|
||||
return [t.ident for t in _threading.enumerate() if t.ident is not None]
|
||||
|
||||
def getThreadInfo(self, thread_id_or_ids, max_depth=None):
|
||||
if isinstance(thread_id_or_ids, (list, tuple)):
|
||||
return [self._build_thread_info(tid) for tid in thread_id_or_ids]
|
||||
return self._build_thread_info(thread_id_or_ids)
|
||||
|
||||
def _build_thread_info(self, thread_id):
|
||||
for t in _threading.enumerate():
|
||||
if t.ident == thread_id:
|
||||
return ThreadInfo(
|
||||
thread_id=thread_id,
|
||||
thread_name=t.name or "",
|
||||
thread_state=t.name or "RUNNABLE",
|
||||
)
|
||||
return ThreadInfo(thread_id=thread_id, thread_name="")
|
||||
|
||||
def isThreadContentionMonitoringSupported(self):
|
||||
return True
|
||||
|
||||
def isThreadContentionMonitoringEnabled(self):
|
||||
return self._thread_contention_monitoring_enabled
|
||||
|
||||
def setThreadContentionMonitoringEnabled(self, enable):
|
||||
self._thread_contention_monitoring_enabled = enable
|
||||
|
||||
def isCurrentThreadCpuTimeSupported(self):
|
||||
return True
|
||||
|
||||
def isThreadCpuTimeEnabled(self):
|
||||
return self._thread_cpu_time_enabled
|
||||
|
||||
def setThreadCpuTimeEnabled(self, enable):
|
||||
self._thread_cpu_time_enabled = enable
|
||||
|
||||
def getCurrentThreadCpuTime(self):
|
||||
return 0
|
||||
|
||||
def getCurrentThreadUserTime(self):
|
||||
return 0
|
||||
|
||||
def getThreadCpuTime(self, thread_id):
|
||||
return 0
|
||||
|
||||
def getThreadUserTime(self, thread_id):
|
||||
return 0
|
||||
|
||||
def isObjectMonitorUsageSupported(self):
|
||||
return True
|
||||
|
||||
def isSynchronizerUsageSupported(self):
|
||||
return True
|
||||
|
||||
def findMonitorDeadlockedThreads(self):
|
||||
return None
|
||||
|
||||
def findDeadlockedThreads(self):
|
||||
return None
|
||||
|
||||
def resetPeakThreadCount(self):
|
||||
pass
|
||||
|
||||
def getThreadAllocatedBytes(self, thread_id_or_ids):
|
||||
if isinstance(thread_id_or_ids, (list, tuple)):
|
||||
return [0] * len(thread_id_or_ids)
|
||||
return 0
|
||||
|
||||
def isThreadAllocatedMemorySupported(self):
|
||||
return True
|
||||
|
||||
def isThreadAllocatedMemoryEnabled(self):
|
||||
return self._thread_allocated_memory_enabled
|
||||
|
||||
def setThreadAllocatedMemoryEnabled(self, enable):
|
||||
self._thread_allocated_memory_enabled = enable
|
||||
|
||||
def getTotalThreadAllocatedBytes(self):
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RuntimeMXBean
|
||||
# ============================================================
|
||||
|
||||
class RuntimeMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.RuntimeMXBean"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._start_time = _time.time() * 1000
|
||||
|
||||
def getName(self):
|
||||
return f"{_os.getpid()}@{_platform.node()}"
|
||||
|
||||
getVmName = lambda self: _platform.python_implementation()
|
||||
getVmVersion = lambda self: _platform.python_version()
|
||||
getVmVendor = lambda self: "Python Software Foundation"
|
||||
getSpecName = lambda self: "Python Virtual Machine Specification"
|
||||
getSpecVersion = lambda self: _sys.version
|
||||
getSpecVendor = lambda self: "Python Software Foundation"
|
||||
|
||||
def getManagementSpecVersion(self):
|
||||
return "1.0"
|
||||
|
||||
def getStartTime(self):
|
||||
return self._start_time
|
||||
|
||||
def getUptime(self):
|
||||
return (_time.time() * 1000) - self._start_time
|
||||
|
||||
def getInputArguments(self):
|
||||
return _sys.argv[1:]
|
||||
|
||||
def getClassPath(self):
|
||||
return _sys.path
|
||||
|
||||
def getBootClassPath(self):
|
||||
return ""
|
||||
|
||||
def getLibraryPath(self):
|
||||
return _os.environ.get("PATH", "")
|
||||
|
||||
def getSystemProperties(self):
|
||||
return {
|
||||
"java.version": _platform.python_version(),
|
||||
"java.vendor": "Python",
|
||||
"java.vm.version": _platform.python_version(),
|
||||
"os.name": _platform.system(),
|
||||
"os.arch": _platform.machine(),
|
||||
"os.version": _platform.release(),
|
||||
"user.dir": _os.getcwd(),
|
||||
"user.home": _os.path.expanduser("~"),
|
||||
"user.name": _os.environ.get("USER", ""),
|
||||
"line.separator": "\n",
|
||||
"file.separator": _os.sep,
|
||||
"path.separator": _os.pathsep,
|
||||
}
|
||||
|
||||
def isBootClassPathSupported(self):
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ClassLoadingMXBean
|
||||
# ============================================================
|
||||
|
||||
class ClassLoadingMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.ClassLoadingMXBean"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._verbose = False
|
||||
|
||||
def getTotalLoadedClassCount(self):
|
||||
return 0
|
||||
|
||||
def getLoadedClassCount(self):
|
||||
return 0
|
||||
|
||||
def getUnloadedClassCount(self):
|
||||
return 0
|
||||
|
||||
def isVerbose(self):
|
||||
return self._verbose
|
||||
|
||||
def setVerbose(self, value):
|
||||
self._verbose = value
|
||||
|
||||
|
||||
# ============================================================
|
||||
# OperatingSystemMXBean
|
||||
# ============================================================
|
||||
|
||||
class OperatingSystemMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.OperatingSystemMXBean"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._available = False
|
||||
try:
|
||||
import psutil
|
||||
self._psutil = psutil
|
||||
self._available = True
|
||||
except ImportError:
|
||||
self._available = False
|
||||
|
||||
def getArch(self):
|
||||
return _platform.machine()
|
||||
|
||||
def getAvailableProcessors(self):
|
||||
return _os.cpu_count() or 1
|
||||
|
||||
def getSystemLoadAverage(self):
|
||||
if self._available:
|
||||
return self._psutil.getloadavg()[0]
|
||||
return -1.0
|
||||
|
||||
def getName(self):
|
||||
return _platform.system()
|
||||
|
||||
def getVersion(self):
|
||||
return _platform.release()
|
||||
|
||||
def getProcessCpuTime(self):
|
||||
return 0
|
||||
|
||||
def getCommittedVirtualMemorySize(self):
|
||||
return 0
|
||||
|
||||
def getTotalSwapSpaceSize(self):
|
||||
if self._available:
|
||||
return self._psutil.swap_memory().total
|
||||
return 0
|
||||
|
||||
def getFreeSwapSpaceSize(self):
|
||||
if self._available:
|
||||
return self._psutil.swap_memory().free
|
||||
return 0
|
||||
|
||||
def getProcessCpuLoad(self):
|
||||
return 0.0
|
||||
|
||||
def getSystemCpuLoad(self):
|
||||
if self._available:
|
||||
return self._psutil.cpu_percent(interval=0) / 100.0
|
||||
return 0.0
|
||||
|
||||
def getTotalPhysicalMemorySize(self):
|
||||
if self._available:
|
||||
return self._psutil.virtual_memory().total
|
||||
return 0
|
||||
|
||||
def getFreePhysicalMemorySize(self):
|
||||
if self._available:
|
||||
return self._psutil.virtual_memory().available
|
||||
return 0
|
||||
|
||||
def getTotalDiskSpace(self):
|
||||
return 0
|
||||
|
||||
def getFreeDiskSpace(self):
|
||||
return 0
|
||||
|
||||
def getSystemUptime(self):
|
||||
return _time.time() - _time.monotonic() + _time.monotonic()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CompilationMXBean
|
||||
# ============================================================
|
||||
|
||||
class CompilationMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.CompilationMXBean"""
|
||||
def getName(self):
|
||||
return "CPython"
|
||||
|
||||
def isCompilationTimeMonitoringSupported(self):
|
||||
return False
|
||||
|
||||
def getTotalCompilationTime(self):
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PlatformLoggingMXBean
|
||||
# ============================================================
|
||||
|
||||
class PlatformLoggingMXBean(PlatformManagedObject):
|
||||
"""java.lang.management.PlatformLoggingMXBean"""
|
||||
def getLoggerLevel(self, logger_name):
|
||||
return ""
|
||||
|
||||
def setLoggerLevel(self, logger_name, level_name):
|
||||
pass
|
||||
|
||||
def getParentLogger(self, logger_name):
|
||||
return ""
|
||||
|
||||
def getLoggerNames(self):
|
||||
return []
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ManagementFactory
|
||||
# ============================================================
|
||||
|
||||
class ManagementFactory(Stub):
|
||||
"""java.lang.management.ManagementFactory"""
|
||||
CLASS_LOADING_MXBEAN_NAME = "java.lang:type=ClassLoading"
|
||||
COMPILATION_MXBEAN_NAME = "java.lang:type=Compilation"
|
||||
GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE = "java.lang:type=GarbageCollector"
|
||||
MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE = "java.lang:type=MemoryManager"
|
||||
MEMORY_MXBEAN_NAME = "java.lang:type=Memory"
|
||||
MEMORY_POOL_MXBEAN_DOMAIN_TYPE = "java.lang:type=MemoryPool"
|
||||
OPERATING_SYSTEM_MXBEAN_NAME = "java.lang:type=OperatingSystem"
|
||||
RUNTIME_MXBEAN_NAME = "java.lang:type=Runtime"
|
||||
THREAD_MXBEAN_NAME = "java.lang:type=Threading"
|
||||
LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"
|
||||
|
||||
_memory_mxbean = None
|
||||
_runtime_mxbean = None
|
||||
_thread_mxbean = None
|
||||
_class_loading_mxbean = None
|
||||
_os_mxbean = None
|
||||
_compilation_mxbean = None
|
||||
_platform_logging_mxbean = None
|
||||
_memory_pools = None
|
||||
_memory_managers = None
|
||||
_gc_mxbeans = None
|
||||
|
||||
@staticmethod
|
||||
def getMemoryMXBean():
|
||||
if ManagementFactory._memory_mxbean is None:
|
||||
ManagementFactory._memory_mxbean = MemoryMXBean()
|
||||
return ManagementFactory._memory_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getRuntimeMXBean():
|
||||
if ManagementFactory._runtime_mxbean is None:
|
||||
ManagementFactory._runtime_mxbean = RuntimeMXBean()
|
||||
return ManagementFactory._runtime_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getThreadMXBean():
|
||||
if ManagementFactory._thread_mxbean is None:
|
||||
ManagementFactory._thread_mxbean = ThreadMXBean()
|
||||
return ManagementFactory._thread_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getClassLoadingMXBean():
|
||||
if ManagementFactory._class_loading_mxbean is None:
|
||||
ManagementFactory._class_loading_mxbean = ClassLoadingMXBean()
|
||||
return ManagementFactory._class_loading_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getOperatingSystemMXBean():
|
||||
if ManagementFactory._os_mxbean is None:
|
||||
ManagementFactory._os_mxbean = OperatingSystemMXBean()
|
||||
return ManagementFactory._os_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getCompilationMXBean():
|
||||
if ManagementFactory._compilation_mxbean is None:
|
||||
ManagementFactory._compilation_mxbean = CompilationMXBean()
|
||||
return ManagementFactory._compilation_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getPlatformLoggingMXBean():
|
||||
if ManagementFactory._platform_logging_mxbean is None:
|
||||
ManagementFactory._platform_logging_mxbean = PlatformLoggingMXBean()
|
||||
return ManagementFactory._platform_logging_mxbean
|
||||
|
||||
@staticmethod
|
||||
def getMemoryPoolMXBeans():
|
||||
if ManagementFactory._memory_pools is None:
|
||||
ManagementFactory._memory_pools = [
|
||||
MemoryPoolMXBean("Code Cache", MemoryType.NON_HEAP),
|
||||
MemoryPoolMXBean("Metaspace", MemoryType.NON_HEAP),
|
||||
MemoryPoolMXBean("Compressed Class Space", MemoryType.NON_HEAP),
|
||||
MemoryPoolMXBean("PS Eden Space", MemoryType.HEAP),
|
||||
MemoryPoolMXBean("PS Survivor Space", MemoryType.HEAP),
|
||||
MemoryPoolMXBean("PS Old Gen", MemoryType.HEAP),
|
||||
]
|
||||
return ManagementFactory._memory_pools
|
||||
|
||||
@staticmethod
|
||||
def getMemoryManagerMXBeans():
|
||||
if ManagementFactory._memory_managers is None:
|
||||
ManagementFactory._memory_managers = [
|
||||
MemoryManagerMXBean("CodeCacheManager"),
|
||||
MemoryManagerMXBean("Metaspace Manager"),
|
||||
MemoryManagerMXBean("PS Scavenge"),
|
||||
MemoryManagerMXBean("PS MarkSweep"),
|
||||
]
|
||||
return ManagementFactory._memory_managers
|
||||
|
||||
@staticmethod
|
||||
def getGarbageCollectorMXBeans():
|
||||
if ManagementFactory._gc_mxbeans is None:
|
||||
ManagementFactory._gc_mxbeans = [
|
||||
GarbageCollectorMXBean("PS Scavenge"),
|
||||
GarbageCollectorMXBean("PS MarkSweep"),
|
||||
]
|
||||
return ManagementFactory._gc_mxbeans
|
||||
|
||||
@staticmethod
|
||||
def getPlatformMXBeans(interface_class):
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def newPlatformMXBeanProxy(server_connection, mxbean_name, interface_class):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def getPlatformManagedObject(object_name):
|
||||
return None
|
||||
@@ -0,0 +1,386 @@
|
||||
"""
|
||||
Java java.lang.ref reference APIs implemented in Python.
|
||||
java.lang.ref package - Reference, ReferenceQueue, SoftReference, WeakReference, PhantomReference, Finalizer.
|
||||
Wraps Python weakref module.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
import weakref as _weakref
|
||||
import threading as _threading
|
||||
import gc as _gc
|
||||
|
||||
__all__ = [
|
||||
"Reference", "SoftReference", "WeakReference", "PhantomReference",
|
||||
"ReferenceQueue", "Finalizer", "FinalizerReference", "FinalizationWatchdog",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ReferenceQueue
|
||||
# ============================================================
|
||||
|
||||
class ReferenceQueue(Stub):
|
||||
"""
|
||||
java.lang.ref.ReferenceQueue
|
||||
A queue that References are appended to when they are enqueued.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._queue: list = []
|
||||
self._lock = _threading.Lock()
|
||||
self._cond = _threading.Condition(self._lock)
|
||||
|
||||
def poll(self):
|
||||
"""
|
||||
Polls to see if a reference object is available.
|
||||
Returns the reference if available, None otherwise.
|
||||
"""
|
||||
with self._lock:
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
|
||||
def remove(self, timeout: int = 0):
|
||||
"""
|
||||
Removes the next reference object from this queue, blocking until one is available
|
||||
or the timeout expires.
|
||||
Args:
|
||||
timeout: timeout in milliseconds (0 = indefinite)
|
||||
Returns:
|
||||
The reference, or None if timeout expired.
|
||||
"""
|
||||
with self._lock:
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
if timeout == 0:
|
||||
self._cond.wait()
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
else:
|
||||
self._cond.wait(timeout / 1000.0)
|
||||
if self._queue:
|
||||
return self._queue.pop(0)
|
||||
return None
|
||||
|
||||
def enqueue(self, ref: "Reference") -> bool:
|
||||
"""
|
||||
Enqueues a reference onto this queue.
|
||||
Returns True if successful.
|
||||
"""
|
||||
with self._lock:
|
||||
self._queue.append(ref)
|
||||
self._cond.notify()
|
||||
return True
|
||||
|
||||
def __len__(self):
|
||||
return len(self._queue)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Reference (abstract base)
|
||||
# ============================================================
|
||||
|
||||
class Reference(Stub):
|
||||
"""
|
||||
java.lang.ref.Reference
|
||||
Abstract base class for reference objects.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__()
|
||||
self._referent = referent
|
||||
self._queue = queue
|
||||
self._enqueued = False
|
||||
# Underlying weakref to track referent lifetime
|
||||
self._weak = None
|
||||
if referent is not None:
|
||||
self._weak = _weakref.ref(
|
||||
referent,
|
||||
self._on_referent_collected
|
||||
)
|
||||
|
||||
def _on_referent_collected(self, weakref_obj):
|
||||
"""Called when the referent is garbage collected."""
|
||||
if self._queue is not None and not self._enqueued:
|
||||
self._enqueued = True
|
||||
self._queue.enqueue(self)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Returns this reference object's referent.
|
||||
If the referent has been garbage collected, returns None.
|
||||
"""
|
||||
if self._weak is not None:
|
||||
return self._weak()
|
||||
return self._referent
|
||||
|
||||
def clear(self):
|
||||
"""Clears this reference object."""
|
||||
self._referent = None
|
||||
if self._weak is not None:
|
||||
self._weak = None
|
||||
|
||||
def isEnqueued(self) -> bool:
|
||||
"""Returns whether this reference object has been enqueued."""
|
||||
return self._enqueued
|
||||
|
||||
def enqueue(self) -> bool:
|
||||
"""Enqueues this reference object."""
|
||||
if self._queue is not None and not self._enqueued:
|
||||
self._enqueued = True
|
||||
return self._queue.enqueue(self)
|
||||
return False
|
||||
|
||||
def clone(self):
|
||||
"""Creates a shallow copy of this reference."""
|
||||
return self.__class__(self.get(), self._queue)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"{self.__class__.__name__}@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Reference):
|
||||
return False
|
||||
return self.get() is other.get()
|
||||
|
||||
def hashCode(self) -> int:
|
||||
r = self.get()
|
||||
return hash(r) & 0x7FFFFFFF if r is not None else 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# SoftReference
|
||||
# ============================================================
|
||||
|
||||
class SoftReference(Reference):
|
||||
"""
|
||||
java.lang.ref.SoftReference
|
||||
Soft reference objects, cleared at the discretion of the GC.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
self._clock = 0
|
||||
|
||||
def get(self):
|
||||
"""Returns the referent; on desktop, soft references are more resilient."""
|
||||
return super().get()
|
||||
|
||||
def enqueue(self) -> bool:
|
||||
return super().enqueue()
|
||||
|
||||
def clear(self):
|
||||
super().clear()
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SoftReference@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# WeakReference
|
||||
# ============================================================
|
||||
|
||||
class WeakReference(Reference):
|
||||
"""
|
||||
java.lang.ref.WeakReference
|
||||
Weak reference objects, cleared automatically by the GC.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"WeakReference@{hex(id(self))}[referent={self.get()}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PhantomReference
|
||||
# ============================================================
|
||||
|
||||
class PhantomReference(Reference):
|
||||
"""
|
||||
java.lang.ref.PhantomReference
|
||||
Phantom reference objects. get() always returns None.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
|
||||
def get(self):
|
||||
"""
|
||||
Phantom references always return None.
|
||||
The referent is phantom-reachable and thus not accessible.
|
||||
"""
|
||||
return None
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"PhantomReference@{hex(id(self))}[referent=phantom]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FinalizerReference
|
||||
# ============================================================
|
||||
|
||||
class FinalizerReference(Reference):
|
||||
"""
|
||||
java.lang.ref.FinalizerReference
|
||||
Represents a finalizer reference used by the VM's finalization system.
|
||||
"""
|
||||
|
||||
def __init__(self, referent=None, queue: ReferenceQueue = None):
|
||||
super().__init__(referent, queue)
|
||||
self._finalized = False
|
||||
self._finalize_method = None
|
||||
if referent is not None and hasattr(referent, "finalize"):
|
||||
self._finalize_method = getattr(referent, "finalize", None)
|
||||
|
||||
def finalize(self):
|
||||
"""Invokes the referent's finalize method if it exists."""
|
||||
if not self._finalized and self._finalize_method is not None:
|
||||
try:
|
||||
self._finalize_method()
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
self._finalized = True
|
||||
|
||||
def isFinalized(self) -> bool:
|
||||
return self._finalized
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"FinalizerReference@{hex(id(self))}[finalized={self._finalized}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FinalizationWatchdog
|
||||
# ============================================================
|
||||
|
||||
class FinalizationWatchdog(Stub):
|
||||
"""
|
||||
java.lang.ref.FinalizationWatchdog
|
||||
A watchdog thread that ensures finalizations proceed.
|
||||
Desktop stub implementation.
|
||||
"""
|
||||
|
||||
_instance = None
|
||||
_running = False
|
||||
_thread = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._timeout = 10000 # 10 seconds
|
||||
|
||||
@classmethod
|
||||
def getInstance(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = FinalizationWatchdog()
|
||||
return cls._instance
|
||||
|
||||
def start(self):
|
||||
"""Starts the watchdog thread."""
|
||||
if not self._running:
|
||||
self._running = True
|
||||
self._thread = _threading.Thread(target=self._run, daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
"""Stops the watchdog thread."""
|
||||
self._running = False
|
||||
|
||||
def _run(self):
|
||||
"""Watchdog loop."""
|
||||
while self._running:
|
||||
_gc.collect()
|
||||
import time
|
||||
time.sleep(1)
|
||||
|
||||
def setEnabled(self, enabled: bool):
|
||||
if enabled:
|
||||
self.start()
|
||||
else:
|
||||
self.stop()
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"FinalizationWatchdog@{hex(id(self))}[running={self._running}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Finalizer
|
||||
# ============================================================
|
||||
|
||||
class Finalizer(Stub):
|
||||
"""
|
||||
java.lang.ref.Finalizer
|
||||
Manages object finalization. Provides methods to run finalization.
|
||||
"""
|
||||
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@classmethod
|
||||
def runFinalization(cls):
|
||||
"""
|
||||
Runs the finalization methods of any objects pending finalization.
|
||||
Equivalent to calling System.runFinalization().
|
||||
"""
|
||||
_gc.collect()
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def runFinalizersOnExit(cls, value: bool):
|
||||
"""
|
||||
Sets whether finalization is enabled on exit.
|
||||
Deprecated in Java. Desktop stub.
|
||||
"""
|
||||
if value:
|
||||
import atexit
|
||||
atexit.register(cls._finalize_all)
|
||||
|
||||
@classmethod
|
||||
def _finalize_all(cls):
|
||||
"""Finalize all objects on exit."""
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def finalizeAllEnqueued(cls):
|
||||
"""
|
||||
Finalizes all objects that have been enqueued for finalization.
|
||||
"""
|
||||
_gc.collect()
|
||||
for obj in _gc.get_objects():
|
||||
if hasattr(obj, "finalize"):
|
||||
try:
|
||||
obj.finalize()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Finalizer@{hex(id(self))}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
@@ -0,0 +1,968 @@
|
||||
"""
|
||||
Java java.lang.reflect APIs implemented in Python.
|
||||
java.lang.reflect package - Field, Method, Constructor, Array, Modifier, Proxy, etc.
|
||||
Wraps Python inspect module.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
import inspect as _inspect
|
||||
import types as _types
|
||||
from typing import Any, List, Optional, Tuple
|
||||
|
||||
__all__ = [
|
||||
"Field", "Method", "Constructor", "Array", "Modifier",
|
||||
"InvocationHandler", "Proxy", "Parameter",
|
||||
"AccessibleObject", "Executable",
|
||||
"GenericArrayType", "ParameterizedType", "TypeVariable",
|
||||
"WildcardType", "GenericDeclaration",
|
||||
"AnnotatedType", "AnnotatedArrayType", "AnnotatedParameterizedType",
|
||||
"AnnotatedTypeVariable", "AnnotatedWildcardType",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Modifier
|
||||
# ============================================================
|
||||
|
||||
class Modifier(Stub):
|
||||
"""
|
||||
java.lang.reflect.Modifier
|
||||
Provides static methods and constants for decoding class and member access modifiers.
|
||||
Uses actual JVM modifier bit values.
|
||||
"""
|
||||
PUBLIC: int = 0x0001
|
||||
PRIVATE: int = 0x0002
|
||||
PROTECTED: int = 0x0004
|
||||
STATIC: int = 0x0008
|
||||
FINAL: int = 0x0010
|
||||
SYNCHRONIZED: int = 0x0020
|
||||
VOLATILE: int = 0x0040
|
||||
TRANSIENT: int = 0x0080
|
||||
NATIVE: int = 0x0100
|
||||
INTERFACE: int = 0x0200
|
||||
ABSTRACT: int = 0x0400
|
||||
STRICT: int = 0x0800
|
||||
|
||||
_MODIFIER_NAMES = {
|
||||
0x0001: "public", 0x0002: "private", 0x0004: "protected",
|
||||
0x0008: "static", 0x0010: "final", 0x0020: "synchronized",
|
||||
0x0040: "volatile", 0x0080: "transient", 0x0100: "native",
|
||||
0x0200: "interface", 0x0400: "abstract", 0x0800: "strictfp",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
def isPublic(mod: int) -> bool:
|
||||
return (mod & Modifier.PUBLIC) != 0
|
||||
|
||||
@staticmethod
|
||||
def isPrivate(mod: int) -> bool:
|
||||
return (mod & Modifier.PRIVATE) != 0
|
||||
|
||||
@staticmethod
|
||||
def isProtected(mod: int) -> bool:
|
||||
return (mod & Modifier.PROTECTED) != 0
|
||||
|
||||
@staticmethod
|
||||
def isStatic(mod: int) -> bool:
|
||||
return (mod & Modifier.STATIC) != 0
|
||||
|
||||
@staticmethod
|
||||
def isFinal(mod: int) -> bool:
|
||||
return (mod & Modifier.FINAL) != 0
|
||||
|
||||
@staticmethod
|
||||
def isSynchronized(mod: int) -> bool:
|
||||
return (mod & Modifier.SYNCHRONIZED) != 0
|
||||
|
||||
@staticmethod
|
||||
def isVolatile(mod: int) -> bool:
|
||||
return (mod & Modifier.VOLATILE) != 0
|
||||
|
||||
@staticmethod
|
||||
def isTransient(mod: int) -> bool:
|
||||
return (mod & Modifier.TRANSIENT) != 0
|
||||
|
||||
@staticmethod
|
||||
def isNative(mod: int) -> bool:
|
||||
return (mod & Modifier.NATIVE) != 0
|
||||
|
||||
@staticmethod
|
||||
def isInterface(mod: int) -> bool:
|
||||
return (mod & Modifier.INTERFACE) != 0
|
||||
|
||||
@staticmethod
|
||||
def isAbstract(mod: int) -> bool:
|
||||
return (mod & Modifier.ABSTRACT) != 0
|
||||
|
||||
@staticmethod
|
||||
def isStrict(mod: int) -> bool:
|
||||
return (mod & Modifier.STRICT) != 0
|
||||
|
||||
@staticmethod
|
||||
def toString(mod: int) -> str:
|
||||
parts = []
|
||||
for bit, name in sorted(Modifier._MODIFIER_NAMES.items()):
|
||||
if mod & bit:
|
||||
parts.append(name)
|
||||
return " ".join(parts)
|
||||
|
||||
@staticmethod
|
||||
def classModifiers() -> int:
|
||||
return Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | \
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.STRICT
|
||||
|
||||
@staticmethod
|
||||
def constructorModifiers() -> int:
|
||||
return Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE
|
||||
|
||||
@staticmethod
|
||||
def fieldModifiers() -> int:
|
||||
return Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | \
|
||||
Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | Modifier.VOLATILE
|
||||
|
||||
@staticmethod
|
||||
def interfaceModifiers() -> int:
|
||||
return Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | \
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.STRICT
|
||||
|
||||
@staticmethod
|
||||
def methodModifiers() -> int:
|
||||
return Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE | \
|
||||
Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | \
|
||||
Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.STRICT
|
||||
|
||||
@staticmethod
|
||||
def parameterModifiers() -> int:
|
||||
return Modifier.FINAL
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AccessibleObject
|
||||
# ============================================================
|
||||
|
||||
class AccessibleObject(Stub):
|
||||
"""
|
||||
java.lang.reflect.AccessibleObject
|
||||
Base class for Field, Method, and Constructor.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._accessible = False
|
||||
|
||||
def setAccessible(self, flag: bool):
|
||||
"""Sets the accessible flag for this object."""
|
||||
self._accessible = flag
|
||||
|
||||
def isAccessible(self) -> bool:
|
||||
"""Returns the value of the accessible flag."""
|
||||
return self._accessible
|
||||
|
||||
def getAnnotation(self, annotation_class: type) -> Optional[Stub]:
|
||||
"""Returns the annotation for this element (if present)."""
|
||||
return None
|
||||
|
||||
def getDeclaredAnnotations(self) -> List:
|
||||
"""Returns all annotations directly present on this element."""
|
||||
return []
|
||||
|
||||
def getAnnotations(self) -> List:
|
||||
"""Returns all annotations on this element."""
|
||||
return []
|
||||
|
||||
def getAnnotationsByType(self, annotation_class: type) -> List:
|
||||
"""Returns annotations of the specified type on this element."""
|
||||
return []
|
||||
|
||||
def isAnnotationPresent(self, annotation_class: type) -> bool:
|
||||
"""Returns True if the specified annotation is present."""
|
||||
return False
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"{self.__class__.__name__}@{hex(id(self))}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Field
|
||||
# ============================================================
|
||||
|
||||
class Field(AccessibleObject):
|
||||
"""
|
||||
java.lang.reflect.Field
|
||||
Provides information about, and dynamic access to, a single field of a class.
|
||||
"""
|
||||
|
||||
def __init__(self, declaring_class: type = None, name: str = None,
|
||||
field_type: type = None, modifiers: int = 0):
|
||||
super().__init__()
|
||||
self._declaring_class = declaring_class
|
||||
self._name = name
|
||||
self._field_type = field_type
|
||||
self._modifiers = modifiers
|
||||
self._generic_type = field_type
|
||||
|
||||
def getName(self) -> str:
|
||||
return self._name or ""
|
||||
|
||||
def getType(self) -> type:
|
||||
return self._field_type or object
|
||||
|
||||
def getModifiers(self) -> int:
|
||||
return self._modifiers
|
||||
|
||||
def get(self, obj: Any) -> Any:
|
||||
"""Returns the value of the field on the given object."""
|
||||
if self._name is None:
|
||||
return None
|
||||
if obj is None and Modifier.isStatic(self._modifiers):
|
||||
# Static field access on the class
|
||||
if self._declaring_class and hasattr(self._declaring_class, self._name):
|
||||
return getattr(self._declaring_class, self._name)
|
||||
return None
|
||||
if obj is not None and hasattr(obj, self._name):
|
||||
return getattr(obj, self._name)
|
||||
return None
|
||||
|
||||
def set(self, obj: Any, value: Any):
|
||||
"""Sets the field on the given object to the given value."""
|
||||
if self._name is None:
|
||||
return
|
||||
if obj is None and Modifier.isStatic(self._modifiers):
|
||||
if self._declaring_class:
|
||||
setattr(self._declaring_class, self._name, value)
|
||||
return
|
||||
if obj is not None and hasattr(obj, self._name):
|
||||
setattr(obj, self._name, value)
|
||||
|
||||
def setAccessible(self, flag: bool):
|
||||
self._accessible = flag
|
||||
|
||||
def getDeclaringClass(self) -> type:
|
||||
return self._declaring_class
|
||||
|
||||
def getGenericType(self):
|
||||
return self._generic_type
|
||||
|
||||
def getAnnotation(self, annotation_class: type):
|
||||
return None
|
||||
|
||||
def getDeclaredAnnotations(self) -> List:
|
||||
return []
|
||||
|
||||
def isAccessible(self) -> bool:
|
||||
return self._accessible
|
||||
|
||||
def isSynthetic(self) -> bool:
|
||||
return False
|
||||
|
||||
def toGenericString(self) -> str:
|
||||
return f"{Modifier.toString(self._modifiers)} {self._field_type.__name__ if self._field_type else '?'} {self._name}"
|
||||
|
||||
def getBoolean(self, obj: Any) -> bool:
|
||||
val = self.get(obj)
|
||||
return bool(val) if val is not None else False
|
||||
|
||||
def getByte(self, obj: Any) -> int:
|
||||
val = self.get(obj)
|
||||
return int(val) if val is not None else 0
|
||||
|
||||
def getChar(self, obj: Any) -> str:
|
||||
val = self.get(obj)
|
||||
return str(val)[0] if val else '\0'
|
||||
|
||||
def getShort(self, obj: Any) -> int:
|
||||
val = self.get(obj)
|
||||
return int(val) if val is not None else 0
|
||||
|
||||
def getInt(self, obj: Any) -> int:
|
||||
val = self.get(obj)
|
||||
return int(val) if val is not None else 0
|
||||
|
||||
def getLong(self, obj: Any) -> int:
|
||||
val = self.get(obj)
|
||||
return int(val) if val is not None else 0
|
||||
|
||||
def getFloat(self, obj: Any) -> float:
|
||||
val = self.get(obj)
|
||||
return float(val) if val is not None else 0.0
|
||||
|
||||
def getDouble(self, obj: Any) -> float:
|
||||
val = self.get(obj)
|
||||
return float(val) if val is not None else 0.0
|
||||
|
||||
def setBoolean(self, obj: Any, value: bool):
|
||||
self.set(obj, value)
|
||||
|
||||
def setByte(self, obj: Any, value: int):
|
||||
self.set(obj, value)
|
||||
|
||||
def setChar(self, obj: Any, value: str):
|
||||
self.set(obj, value)
|
||||
|
||||
def setShort(self, obj: Any, value: int):
|
||||
self.set(obj, value)
|
||||
|
||||
def setInt(self, obj: Any, value: int):
|
||||
self.set(obj, value)
|
||||
|
||||
def setLong(self, obj: Any, value: int):
|
||||
self.set(obj, value)
|
||||
|
||||
def setFloat(self, obj: Any, value: float):
|
||||
self.set(obj, value)
|
||||
|
||||
def setDouble(self, obj: Any, value: float):
|
||||
self.set(obj, value)
|
||||
|
||||
def toString(self) -> str:
|
||||
return self.toGenericString()
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Field):
|
||||
return False
|
||||
return (self._declaring_class == other._declaring_class and
|
||||
self._name == other._name and
|
||||
self._field_type == other._field_type)
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._declaring_class, self._name)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Executable (abstract base for Method & Constructor)
|
||||
# ============================================================
|
||||
|
||||
class Executable(AccessibleObject):
|
||||
"""
|
||||
java.lang.reflect.Executable
|
||||
Shared base for Method and Constructor.
|
||||
"""
|
||||
|
||||
def __init__(self, declaring_class: type = None, name: str = None,
|
||||
parameter_types: List[type] = None, exception_types: List[type] = None,
|
||||
modifiers: int = 0):
|
||||
super().__init__()
|
||||
self._declaring_class = declaring_class
|
||||
self._name = name
|
||||
self._parameter_types = parameter_types or []
|
||||
self._exception_types = exception_types or []
|
||||
self._modifiers = modifiers
|
||||
|
||||
def getParameterTypes(self) -> List[type]:
|
||||
return list(self._parameter_types)
|
||||
|
||||
def getParameterCount(self) -> int:
|
||||
return len(self._parameter_types)
|
||||
|
||||
def getExceptionTypes(self) -> List[type]:
|
||||
return list(self._exception_types)
|
||||
|
||||
def getModifiers(self) -> int:
|
||||
return self._modifiers
|
||||
|
||||
def getDeclaringClass(self) -> type:
|
||||
return self._declaring_class
|
||||
|
||||
def getName(self) -> str:
|
||||
return self._name or ""
|
||||
|
||||
def getAnnotation(self, annotation_class: type):
|
||||
return None
|
||||
|
||||
def getDeclaredAnnotations(self) -> List:
|
||||
return []
|
||||
|
||||
def getParameterAnnotations(self) -> List[List]:
|
||||
return [[] for _ in self._parameter_types]
|
||||
|
||||
def isVarArgs(self) -> bool:
|
||||
return False
|
||||
|
||||
def isSynthetic(self) -> bool:
|
||||
return False
|
||||
|
||||
def toGenericString(self) -> str:
|
||||
return f"{Modifier.toString(self._modifiers)} {self._name}({', '.join(t.__name__ for t in self._parameter_types)})"
|
||||
|
||||
def toString(self) -> str:
|
||||
return self.toGenericString()
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Executable):
|
||||
return False
|
||||
return (self._declaring_class == other._declaring_class and
|
||||
self._name == other._name and
|
||||
self._parameter_types == other._parameter_types)
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._declaring_class, self._name)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Method
|
||||
# ============================================================
|
||||
|
||||
class Method(Executable):
|
||||
"""
|
||||
java.lang.reflect.Method
|
||||
Provides information about, and access to, a single method of a class.
|
||||
"""
|
||||
|
||||
def __init__(self, declaring_class: type = None, name: str = None,
|
||||
return_type: type = None, parameter_types: List[type] = None,
|
||||
exception_types: List[type] = None, modifiers: int = 0,
|
||||
impl_func: callable = None):
|
||||
super().__init__(declaring_class, name, parameter_types, exception_types, modifiers)
|
||||
self._return_type = return_type
|
||||
self._impl_func = impl_func
|
||||
self._generic_return_type = return_type
|
||||
self._generic_parameter_types = parameter_types or []
|
||||
|
||||
def getReturnType(self) -> type:
|
||||
return self._return_type or type(None)
|
||||
|
||||
def getGenericReturnType(self):
|
||||
return self._generic_return_type
|
||||
|
||||
def getGenericParameterTypes(self) -> List:
|
||||
return list(self._generic_parameter_types)
|
||||
|
||||
def invoke(self, obj: Any, *args) -> Any:
|
||||
"""
|
||||
Invokes the underlying method on the given object with the given args.
|
||||
"""
|
||||
if self._impl_func is not None:
|
||||
return self._impl_func(obj, *args)
|
||||
|
||||
if self._name is None:
|
||||
return None
|
||||
|
||||
# Try to call the method on the object
|
||||
if obj is not None and hasattr(obj, self._name):
|
||||
method = getattr(obj, self._name)
|
||||
if callable(method):
|
||||
return method(*args)
|
||||
|
||||
# Static call on class
|
||||
if self._declaring_class and hasattr(self._declaring_class, self._name):
|
||||
method = getattr(self._declaring_class, self._name)
|
||||
if callable(method):
|
||||
return method(*args)
|
||||
|
||||
return None
|
||||
|
||||
def getDefaultValue(self):
|
||||
"""Returns the default value for the annotation member."""
|
||||
return None
|
||||
|
||||
def isBridge(self) -> bool:
|
||||
return False
|
||||
|
||||
def toGenericString(self) -> str:
|
||||
ret = self._return_type.__name__ if self._return_type else "void"
|
||||
params = ', '.join(t.__name__ for t in self._parameter_types)
|
||||
return f"{Modifier.toString(self._modifiers)} {ret} {self._name}({params})"
|
||||
|
||||
def toString(self) -> str:
|
||||
return self.toGenericString()
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Method):
|
||||
return False
|
||||
return (self._declaring_class == other._declaring_class and
|
||||
self._name == other._name and
|
||||
self._parameter_types == other._parameter_types)
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._declaring_class, self._name)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Constructor
|
||||
# ============================================================
|
||||
|
||||
class Constructor(Executable):
|
||||
"""
|
||||
java.lang.reflect.Constructor
|
||||
Provides information about, and access to, a single constructor of a class.
|
||||
"""
|
||||
|
||||
def __init__(self, declaring_class: type = None,
|
||||
parameter_types: List[type] = None,
|
||||
exception_types: List[type] = None,
|
||||
modifiers: int = 0):
|
||||
super().__init__(declaring_class, declaring_class.__name__ if declaring_class else "<init>",
|
||||
parameter_types, exception_types, modifiers)
|
||||
|
||||
def newInstance(self, *args) -> Any:
|
||||
"""Creates a new instance of the declaring class."""
|
||||
if self._declaring_class is None:
|
||||
raise AndroidOnlyError("No declaring class for constructor")
|
||||
try:
|
||||
return self._declaring_class(*args)
|
||||
except Exception as e:
|
||||
raise AndroidOnlyError(f"Cannot instantiate {self._declaring_class}: {e}")
|
||||
|
||||
def toGenericString(self) -> str:
|
||||
params = ', '.join(t.__name__ for t in self._parameter_types)
|
||||
return f"{Modifier.toString(self._modifiers)} {self._name}({params})"
|
||||
|
||||
def toString(self) -> str:
|
||||
return self.toGenericString()
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Constructor):
|
||||
return False
|
||||
return (self._declaring_class == other._declaring_class and
|
||||
self._parameter_types == other._parameter_types)
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._declaring_class, tuple(self._parameter_types))) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Array
|
||||
# ============================================================
|
||||
|
||||
class Array(Stub):
|
||||
"""
|
||||
java.lang.reflect.Array
|
||||
Provides static methods to dynamically create and access arrays.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
def newInstance(component_type: type, *dimensions) -> Any:
|
||||
"""Creates a new array with the specified component type and dimensions."""
|
||||
if len(dimensions) == 1:
|
||||
return [None] * dimensions[0]
|
||||
# Multi-dimensional
|
||||
result = []
|
||||
for _ in range(dimensions[0]):
|
||||
result.append(Array.newInstance(component_type, *dimensions[1:]))
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def getLength(array: Any) -> int:
|
||||
"""Returns the length of the specified array."""
|
||||
return len(array)
|
||||
|
||||
@staticmethod
|
||||
def get(array: Any, index: int) -> Any:
|
||||
"""Returns the element at the specified index."""
|
||||
return array[index]
|
||||
|
||||
@staticmethod
|
||||
def set(array: Any, index: int, value: Any):
|
||||
"""Sets the element at the specified index."""
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def getBoolean(array: Any, index: int) -> bool:
|
||||
return bool(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getByte(array: Any, index: int) -> int:
|
||||
return int(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getChar(array: Any, index: int) -> str:
|
||||
return str(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getShort(array: Any, index: int) -> int:
|
||||
return int(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getInt(array: Any, index: int) -> int:
|
||||
return int(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getLong(array: Any, index: int) -> int:
|
||||
return int(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getFloat(array: Any, index: int) -> float:
|
||||
return float(array[index])
|
||||
|
||||
@staticmethod
|
||||
def getDouble(array: Any, index: int) -> float:
|
||||
return float(array[index])
|
||||
|
||||
@staticmethod
|
||||
def setBoolean(array: Any, index: int, value: bool):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setByte(array: Any, index: int, value: int):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setChar(array: Any, index: int, value: str):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setShort(array: Any, index: int, value: int):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setInt(array: Any, index: int, value: int):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setLong(array: Any, index: int, value: int):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setFloat(array: Any, index: int, value: float):
|
||||
array[index] = value
|
||||
|
||||
@staticmethod
|
||||
def setDouble(array: Any, index: int, value: float):
|
||||
array[index] = value
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Parameter
|
||||
# ============================================================
|
||||
|
||||
class Parameter(AccessibleObject):
|
||||
"""
|
||||
java.lang.reflect.Parameter
|
||||
Information about a method parameter.
|
||||
"""
|
||||
|
||||
def __init__(self, name: str = None, param_type: type = None,
|
||||
modifiers: int = 0, is_implicit: bool = False,
|
||||
is_name_present: bool = True):
|
||||
super().__init__()
|
||||
self._name = name or ""
|
||||
self._param_type = param_type or object
|
||||
self._modifiers = modifiers
|
||||
self._is_implicit = is_implicit
|
||||
self._is_name_present = is_name_present
|
||||
self._parameterized_type = param_type
|
||||
|
||||
def getName(self) -> str:
|
||||
return self._name
|
||||
|
||||
def getType(self) -> type:
|
||||
return self._param_type
|
||||
|
||||
def getParameterizedType(self):
|
||||
return self._parameterized_type
|
||||
|
||||
def getModifiers(self) -> int:
|
||||
return self._modifiers
|
||||
|
||||
def isNamePresent(self) -> bool:
|
||||
return self._is_name_present
|
||||
|
||||
def isImplicit(self) -> bool:
|
||||
return self._is_implicit
|
||||
|
||||
def isSynthetic(self) -> bool:
|
||||
return False
|
||||
|
||||
def isVarArgs(self) -> bool:
|
||||
return False
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"{Modifier.toString(self._modifiers)} {self._param_type.__name__} {self._name}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Parameter):
|
||||
return False
|
||||
return (self._name == other._name and
|
||||
self._param_type == other._param_type)
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._name, self._param_type)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# InvocationHandler
|
||||
# ============================================================
|
||||
|
||||
class InvocationHandler(Stub):
|
||||
"""
|
||||
java.lang.reflect.InvocationHandler
|
||||
Interface for invocation handlers of proxy instances.
|
||||
"""
|
||||
|
||||
def invoke(self, proxy: Any, method: Any, args: List) -> Any:
|
||||
"""Processes a method invocation on a proxy instance."""
|
||||
raise NotImplementedError("invoke must be implemented by subclass")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Proxy
|
||||
# ============================================================
|
||||
|
||||
class Proxy(Stub):
|
||||
"""
|
||||
java.lang.reflect.Proxy
|
||||
Provides static methods for creating dynamic proxy classes and instances.
|
||||
"""
|
||||
|
||||
_invocation_handler: InvocationHandler = None
|
||||
|
||||
def __init__(self, handler: InvocationHandler = None):
|
||||
super().__init__()
|
||||
self._invocation_handler = handler
|
||||
|
||||
@staticmethod
|
||||
def newProxyInstance(class_loader: Any, interfaces: List[type],
|
||||
handler: InvocationHandler) -> Stub:
|
||||
"""Creates a proxy instance for the specified interfaces."""
|
||||
proxy = Proxy(handler)
|
||||
proxy._interfaces = interfaces
|
||||
return proxy
|
||||
|
||||
@staticmethod
|
||||
def getInvocationHandler(proxy: Any) -> InvocationHandler:
|
||||
"""Returns the invocation handler for the specified proxy instance."""
|
||||
if isinstance(proxy, Proxy):
|
||||
return proxy._invocation_handler
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def getProxyClass(class_loader: Any, interfaces: List[type]) -> type:
|
||||
"""Returns the proxy class for the specified interfaces."""
|
||||
return Proxy
|
||||
|
||||
@staticmethod
|
||||
def isProxyClass(cls: type) -> bool:
|
||||
"""Returns True if the class is a proxy class."""
|
||||
return cls == Proxy or (hasattr(cls, '__bases__') and Proxy in cls.__bases__)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Proxy@{hex(id(self))}"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Generic Array Type (stub interface)
|
||||
# ============================================================
|
||||
|
||||
class GenericArrayType(Stub):
|
||||
"""
|
||||
java.lang.reflect.GenericArrayType
|
||||
Represents an array type whose component type is a parameterized type or type variable.
|
||||
"""
|
||||
def __init__(self, generic_component_type=None):
|
||||
super().__init__()
|
||||
self._generic_component_type = generic_component_type
|
||||
|
||||
def getGenericComponentType(self):
|
||||
return self._generic_component_type
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"{self._generic_component_type}[]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ParameterizedType
|
||||
# ============================================================
|
||||
|
||||
class ParameterizedType(Stub):
|
||||
"""
|
||||
java.lang.reflect.ParameterizedType
|
||||
Represents a parameterized type, e.g. List<String>.
|
||||
"""
|
||||
def __init__(self, raw_type=None, actual_type_arguments=None, owner_type=None):
|
||||
super().__init__()
|
||||
self._raw_type = raw_type
|
||||
self._actual_type_arguments = actual_type_arguments or []
|
||||
self._owner_type = owner_type
|
||||
|
||||
def getRawType(self):
|
||||
return self._raw_type
|
||||
|
||||
def getActualTypeArguments(self):
|
||||
return list(self._actual_type_arguments)
|
||||
|
||||
def getOwnerType(self):
|
||||
return self._owner_type
|
||||
|
||||
def toString(self) -> str:
|
||||
args = ', '.join(str(a) for a in self._actual_type_arguments)
|
||||
return f"{self._raw_type}<{args}>"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeVariable
|
||||
# ============================================================
|
||||
|
||||
class TypeVariable(Stub):
|
||||
"""
|
||||
java.lang.reflect.TypeVariable
|
||||
Represents a type variable, like T in Foo<T>.
|
||||
"""
|
||||
def __init__(self, name: str = None, bounds: List = None,
|
||||
generic_declaration: Any = None):
|
||||
super().__init__()
|
||||
self._name = name or "T"
|
||||
self._bounds = bounds or [object]
|
||||
self._generic_declaration = generic_declaration
|
||||
|
||||
def getName(self) -> str:
|
||||
return self._name
|
||||
|
||||
def getBounds(self) -> List:
|
||||
return list(self._bounds)
|
||||
|
||||
def getGenericDeclaration(self) -> Any:
|
||||
return self._generic_declaration
|
||||
|
||||
def toString(self) -> str:
|
||||
return self._name
|
||||
|
||||
|
||||
# ============================================================
|
||||
# WildcardType
|
||||
# ============================================================
|
||||
|
||||
class WildcardType(Stub):
|
||||
"""
|
||||
java.lang.reflect.WildcardType
|
||||
Represents a wildcard type, like ?, ? extends T, ? super T.
|
||||
"""
|
||||
def __init__(self, upper_bounds: List = None, lower_bounds: List = None):
|
||||
super().__init__()
|
||||
self._upper_bounds = upper_bounds or [object]
|
||||
self._lower_bounds = lower_bounds or []
|
||||
|
||||
def getUpperBounds(self) -> List:
|
||||
return list(self._upper_bounds)
|
||||
|
||||
def getLowerBounds(self) -> List:
|
||||
return list(self._lower_bounds)
|
||||
|
||||
def toString(self) -> str:
|
||||
if self._lower_bounds:
|
||||
return f"? super {self._lower_bounds[0]}"
|
||||
if self._upper_bounds and self._upper_bounds[0] is not object:
|
||||
return f"? extends {self._upper_bounds[0]}"
|
||||
return "?"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# GenericDeclaration
|
||||
# ============================================================
|
||||
|
||||
class GenericDeclaration(Stub):
|
||||
"""
|
||||
java.lang.reflect.GenericDeclaration
|
||||
Interface for entities that declare type variables.
|
||||
"""
|
||||
def getTypeParameters(self) -> List[TypeVariable]:
|
||||
return []
|
||||
|
||||
def toGenericString(self) -> str:
|
||||
return self.toString()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AnnotatedType interfaces
|
||||
# ============================================================
|
||||
|
||||
class AnnotatedType(Stub):
|
||||
"""
|
||||
java.lang.reflect.AnnotatedType
|
||||
Represents an annotated type.
|
||||
"""
|
||||
def __init__(self, type_=None, annotations: List = None):
|
||||
super().__init__()
|
||||
self._type = type_
|
||||
self._annotations = annotations or []
|
||||
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def getAnnotations(self) -> List:
|
||||
return list(self._annotations)
|
||||
|
||||
def getAnnotation(self, annotation_class: type):
|
||||
for a in self._annotations:
|
||||
if isinstance(a, annotation_class):
|
||||
return a
|
||||
return None
|
||||
|
||||
def toString(self) -> str:
|
||||
return str(self._type) if self._type else "?"
|
||||
|
||||
|
||||
class AnnotatedArrayType(AnnotatedType):
|
||||
"""
|
||||
java.lang.reflect.AnnotatedArrayType
|
||||
Represents an annotated array type.
|
||||
"""
|
||||
def __init__(self, annotated_generic_component_type=None, type_=None, annotations=None):
|
||||
super().__init__(type_, annotations)
|
||||
self._annotated_generic_component_type = annotated_generic_component_type
|
||||
|
||||
def getAnnotatedGenericComponentType(self) -> AnnotatedType:
|
||||
return self._annotated_generic_component_type
|
||||
|
||||
|
||||
class AnnotatedParameterizedType(AnnotatedType):
|
||||
"""
|
||||
java.lang.reflect.AnnotatedParameterizedType
|
||||
Represents an annotated parameterized type.
|
||||
"""
|
||||
def __init__(self, annotated_actual_type_arguments=None, type_=None, annotations=None):
|
||||
super().__init__(type_, annotations)
|
||||
self._annotated_actual_type_arguments = annotated_actual_type_arguments or []
|
||||
|
||||
def getAnnotatedActualTypeArguments(self) -> List[AnnotatedType]:
|
||||
return list(self._annotated_actual_type_arguments)
|
||||
|
||||
|
||||
class AnnotatedTypeVariable(AnnotatedType):
|
||||
"""
|
||||
java.lang.reflect.AnnotatedTypeVariable
|
||||
Represents an annotated type variable.
|
||||
"""
|
||||
def __init__(self, annotated_bounds=None, type_=None, annotations=None):
|
||||
super().__init__(type_, annotations)
|
||||
self._annotated_bounds = annotated_bounds or []
|
||||
|
||||
def getAnnotatedBounds(self) -> List[AnnotatedType]:
|
||||
return list(self._annotated_bounds)
|
||||
|
||||
|
||||
class AnnotatedWildcardType(AnnotatedType):
|
||||
"""
|
||||
java.lang.reflect.AnnotatedWildcardType
|
||||
Represents an annotated wildcard type.
|
||||
"""
|
||||
def __init__(self, annotated_upper_bounds=None, annotated_lower_bounds=None,
|
||||
type_=None, annotations=None):
|
||||
super().__init__(type_, annotations)
|
||||
self._annotated_upper_bounds = annotated_upper_bounds or []
|
||||
self._annotated_lower_bounds = annotated_lower_bounds or []
|
||||
|
||||
def getAnnotatedUpperBounds(self) -> List[AnnotatedType]:
|
||||
return list(self._annotated_upper_bounds)
|
||||
|
||||
def getAnnotatedLowerBounds(self) -> List[AnnotatedType]:
|
||||
return list(self._annotated_lower_bounds)
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Java java.nio.ByteOrder - BIG_ENDIAN, LITTLE_ENDIAN
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
import sys as _sys
|
||||
|
||||
__all__ = ["ByteOrder"]
|
||||
|
||||
|
||||
class ByteOrder(Stub):
|
||||
"""java.nio.ByteOrder"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
@staticmethod
|
||||
def nativeOrder():
|
||||
if _sys.byteorder == "little":
|
||||
return ByteOrder.LITTLE_ENDIAN
|
||||
return ByteOrder.BIG_ENDIAN
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
BIG_ENDIAN = None
|
||||
LITTLE_ENDIAN = None
|
||||
|
||||
|
||||
ByteOrder.BIG_ENDIAN = ByteOrder("BIG_ENDIAN")
|
||||
ByteOrder.LITTLE_ENDIAN = ByteOrder("LITTLE_ENDIAN")
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,573 @@
|
||||
"""
|
||||
Java java.nio.charset APIs implemented in Python.
|
||||
java.nio.charset package - Charset, CharsetEncoder, CharsetDecoder, CoderResult, etc.
|
||||
Wraps Python codecs module.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
import codecs as _codecs
|
||||
import encodings as _encodings
|
||||
from typing import Set as _Set, List as _List
|
||||
|
||||
__all__ = [
|
||||
"Charset", "CharsetEncoder", "CharsetDecoder", "CoderResult",
|
||||
"CodingErrorAction", "StandardCharsets",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CodingErrorAction
|
||||
# ============================================================
|
||||
|
||||
class CodingErrorAction(Stub):
|
||||
"""
|
||||
java.nio.charset.CodingErrorAction
|
||||
Describes actions that a charset encoder or decoder may take on a coding error.
|
||||
"""
|
||||
REPORT: "CodingErrorAction" = None
|
||||
IGNORE: "CodingErrorAction" = None
|
||||
REPLACE: "CodingErrorAction" = None
|
||||
|
||||
def __init__(self, name: str):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def toString(self) -> str:
|
||||
return self._name
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if isinstance(other, CodingErrorAction):
|
||||
return self._name == other._name
|
||||
return False
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._name) & 0x7FFFFFFF
|
||||
|
||||
|
||||
CodingErrorAction.REPORT = CodingErrorAction("REPORT")
|
||||
CodingErrorAction.IGNORE = CodingErrorAction("IGNORE")
|
||||
CodingErrorAction.REPLACE = CodingErrorAction("REPLACE")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CoderResult
|
||||
# ============================================================
|
||||
|
||||
class CoderResult(Stub):
|
||||
"""
|
||||
java.nio.charset.CoderResult
|
||||
Describes the result state of a coder (encoder or decoder).
|
||||
"""
|
||||
UNDERFLOW: "CoderResult" = None
|
||||
OVERFLOW: "CoderResult" = None
|
||||
|
||||
def __init__(self, _type: str, _length: int = 0):
|
||||
super().__init__()
|
||||
self._type = _type
|
||||
self._length = _length
|
||||
|
||||
def isUnderflow(self) -> bool:
|
||||
"""Returns True if the result is underflow (more input needed)."""
|
||||
return self._type == "UNDERFLOW"
|
||||
|
||||
def isOverflow(self) -> bool:
|
||||
"""Returns True if the result is overflow (output buffer too small)."""
|
||||
return self._type == "OVERFLOW"
|
||||
|
||||
def isError(self) -> bool:
|
||||
"""Returns True if the result is an error (malformed or unmappable)."""
|
||||
return self._type in ("MALFORMED", "UNMAPPABLE")
|
||||
|
||||
def isMalformed(self) -> bool:
|
||||
"""Returns True if the result is a malformed-input error."""
|
||||
return self._type == "MALFORMED"
|
||||
|
||||
def isUnmappable(self) -> bool:
|
||||
"""Returns True if the result is an unmappable-character error."""
|
||||
return self._type == "UNMAPPABLE"
|
||||
|
||||
def length(self) -> int:
|
||||
"""Returns the length of the erroneous input (for errors)."""
|
||||
return self._length
|
||||
|
||||
@classmethod
|
||||
def malformedForLength(cls, length: int) -> "CoderResult":
|
||||
"""Creates a malformed CoderResult for the given length."""
|
||||
return cls("MALFORMED", length)
|
||||
|
||||
@classmethod
|
||||
def unmappableForLength(cls, length: int) -> "CoderResult":
|
||||
"""Creates an unmappable CoderResult for the given length."""
|
||||
return cls("UNMAPPABLE", length)
|
||||
|
||||
def toString(self) -> str:
|
||||
if self._type == "UNDERFLOW":
|
||||
return "UNDERFLOW"
|
||||
elif self._type == "OVERFLOW":
|
||||
return "OVERFLOW"
|
||||
return f"{self._type}[{self._length}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, CoderResult):
|
||||
return False
|
||||
return self._type == other._type and self._length == other._length
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._type, self._length)) & 0x7FFFFFFF
|
||||
|
||||
|
||||
CoderResult.UNDERFLOW = CoderResult("UNDERFLOW")
|
||||
CoderResult.OVERFLOW = CoderResult("OVERFLOW")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Charset
|
||||
# ============================================================
|
||||
|
||||
class Charset(Stub):
|
||||
"""
|
||||
java.nio.charset.Charset
|
||||
A named mapping between sequences of 16-bit Unicode characters
|
||||
and sequences of bytes.
|
||||
"""
|
||||
|
||||
_cache: dict = {}
|
||||
_aliases: dict = {}
|
||||
|
||||
# Standard charset constants
|
||||
US_ASCII: "Charset" = None
|
||||
ISO_8859_1: "Charset" = None
|
||||
UTF_8: "Charset" = None
|
||||
UTF_16: "Charset" = None
|
||||
UTF_16BE: "Charset" = None
|
||||
UTF_16LE: "Charset" = None
|
||||
|
||||
def __init__(self, canonical_name: str, aliases: _List[str] = None):
|
||||
super().__init__()
|
||||
self._name = canonical_name
|
||||
self._aliases = aliases or []
|
||||
self._registered = True
|
||||
|
||||
def name(self) -> str:
|
||||
"""Returns the canonical name of this charset."""
|
||||
return self._name
|
||||
|
||||
def displayName(self, locale=None) -> str:
|
||||
"""Returns the display name of this charset."""
|
||||
return self._name
|
||||
|
||||
def aliases(self) -> _Set[str]:
|
||||
"""Returns a set containing this charset's aliases."""
|
||||
return set(self._aliases)
|
||||
|
||||
def isRegistered(self) -> bool:
|
||||
"""Returns True if this charset is registered in the IANA registry."""
|
||||
return self._registered
|
||||
|
||||
def canEncode(self) -> bool:
|
||||
"""Returns True if this charset supports encoding."""
|
||||
try:
|
||||
_codecs.lookup(self._name)
|
||||
return True
|
||||
except LookupError:
|
||||
return False
|
||||
|
||||
def encode(self, text: str) -> "ByteBuffer":
|
||||
"""
|
||||
Converts a string into bytes using this charset.
|
||||
Returns a ByteBuffer.
|
||||
"""
|
||||
encoded = text.encode(self._name, errors="replace")
|
||||
from ..nio import ByteBuffer
|
||||
buf = ByteBuffer.allocate(len(encoded))
|
||||
buf.put(list(encoded))
|
||||
buf.flip()
|
||||
return buf
|
||||
|
||||
def decode(self, buf: "ByteBuffer") -> "CharBuffer":
|
||||
"""
|
||||
Converts bytes from a ByteBuffer into a CharBuffer.
|
||||
"""
|
||||
arr = bytearray()
|
||||
for i in range(buf.position(), buf.limit()):
|
||||
arr.append(buf.get(i))
|
||||
decoded = arr.decode(self._name, errors="replace")
|
||||
from ..nio import CharBuffer
|
||||
cb = CharBuffer.allocate(len(decoded))
|
||||
cb.put(decoded)
|
||||
cb.flip()
|
||||
return cb
|
||||
|
||||
def newDecoder(self) -> "CharsetDecoder":
|
||||
"""Returns a new CharsetDecoder for this charset."""
|
||||
return CharsetDecoder(self)
|
||||
|
||||
def newEncoder(self) -> "CharsetEncoder":
|
||||
"""Returns a new CharsetEncoder for this charset."""
|
||||
return CharsetEncoder(self)
|
||||
|
||||
def toString(self) -> str:
|
||||
return self._name
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._name) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Charset):
|
||||
return False
|
||||
return self._name == other._name
|
||||
|
||||
def compareTo(self, other: "Charset") -> int:
|
||||
"""Compares this charset to another by canonical name."""
|
||||
if not isinstance(other, Charset):
|
||||
return -1
|
||||
if self._name < other._name:
|
||||
return -1
|
||||
elif self._name > other._name:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def forName(cls, charset_name: str) -> "Charset":
|
||||
"""Returns a Charset for the given charset name."""
|
||||
if charset_name in cls._cache:
|
||||
return cls._cache[charset_name]
|
||||
|
||||
try:
|
||||
_codecs.lookup(charset_name)
|
||||
except LookupError:
|
||||
raise AndroidOnlyError(f"Charset not found: {charset_name}")
|
||||
|
||||
# Resolve aliases
|
||||
canonical = charset_name.lower()
|
||||
alias_map = {
|
||||
"ascii": "US-ASCII", "us-ascii": "US-ASCII",
|
||||
"iso-8859-1": "ISO-8859-1", "latin1": "ISO-8859-1",
|
||||
"utf-8": "UTF-8", "utf8": "UTF-8",
|
||||
"utf-16": "UTF-16", "utf16": "UTF-16",
|
||||
"utf-16be": "UTF-16BE", "utf16be": "UTF-16BE",
|
||||
"utf-16le": "UTF-16LE", "utf16le": "UTF-16LE",
|
||||
}
|
||||
canonical_name = alias_map.get(canonical, charset_name.upper())
|
||||
|
||||
charset = cls(canonical_name)
|
||||
cls._cache[charset_name] = charset
|
||||
return charset
|
||||
|
||||
@classmethod
|
||||
def forNameUEE(cls, charset_name: str) -> "Charset":
|
||||
"""Same as forName but wraps exception."""
|
||||
try:
|
||||
return cls.forName(charset_name)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def isSupported(cls, charset_name: str) -> bool:
|
||||
"""Returns True if the named charset is supported."""
|
||||
try:
|
||||
_codecs.lookup(charset_name)
|
||||
return True
|
||||
except LookupError:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def defaultCharset(cls) -> "Charset":
|
||||
"""Returns the default charset of the JVM (platform native encoding)."""
|
||||
import locale
|
||||
enc = locale.getpreferredencoding()
|
||||
return cls.forName(enc)
|
||||
|
||||
@classmethod
|
||||
def availableCharsets(cls) -> dict:
|
||||
"""Returns a sorted map of available charset names to Charset objects."""
|
||||
result = {}
|
||||
for name in _codecs.available_encodings():
|
||||
try:
|
||||
result[name] = cls.forName(name)
|
||||
except Exception:
|
||||
pass
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def requiredCharsets(cls) -> _Set[str]:
|
||||
"""Returns the set of required charset names per Java spec."""
|
||||
return {
|
||||
"US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16",
|
||||
"UTF-16BE", "UTF-16LE",
|
||||
}
|
||||
|
||||
|
||||
# Initialize standard charset constants
|
||||
Charset.US_ASCII = Charset("US-ASCII", ["ASCII", "US-ASCII", "ascii", "cp367"])
|
||||
Charset.ISO_8859_1 = Charset("ISO-8859-1", ["ISO-8859-1", "latin1", "LATIN-1", "l1", "cp819"])
|
||||
Charset.UTF_8 = Charset("UTF-8", ["UTF-8", "utf8", "UTF8"])
|
||||
Charset.UTF_16 = Charset("UTF-16", ["UTF-16", "utf16", "UTF16", "UnicodeBig"])
|
||||
Charset.UTF_16BE = Charset("UTF-16BE", ["UTF-16BE", "utf16be", "UTF16BE", "ISO-10646-UCS-2"])
|
||||
Charset.UTF_16LE = Charset("UTF-16LE", ["UTF-16LE", "utf16le", "UTF16LE"])
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CharsetEncoder
|
||||
# ============================================================
|
||||
|
||||
class CharsetEncoder(Stub):
|
||||
"""
|
||||
java.nio.charset.CharsetEncoder
|
||||
Converts character data to byte data using a Charset.
|
||||
"""
|
||||
|
||||
def __init__(self, charset: Charset, average_bytes_per_char: float = 1.0,
|
||||
max_bytes_per_char: float = 4.0, replacement: bytes = b'?'):
|
||||
super().__init__()
|
||||
self._charset = charset
|
||||
self._average_bytes_per_char = average_bytes_per_char
|
||||
self._max_bytes_per_char = max_bytes_per_char
|
||||
self._replacement = replacement
|
||||
self._malformed_input_action = CodingErrorAction.REPORT
|
||||
self._unmappable_action = CodingErrorAction.REPORT
|
||||
|
||||
def charset(self) -> Charset:
|
||||
"""Returns the charset that created this encoder."""
|
||||
return self._charset
|
||||
|
||||
def replacement(self) -> bytes:
|
||||
"""Returns the replacement value."""
|
||||
return self._replacement
|
||||
|
||||
def replaceWith(self, new_replacement: bytes) -> "CharsetEncoder":
|
||||
"""Sets a new replacement value."""
|
||||
self._replacement = new_replacement
|
||||
return self
|
||||
|
||||
def encode(self, input_str: str) -> "ByteBuffer":
|
||||
"""Encodes a string into bytes."""
|
||||
encoded = input_str.encode(self._charset.name(), errors="replace")
|
||||
from ..nio import ByteBuffer
|
||||
buf = ByteBuffer.allocate(len(encoded))
|
||||
buf.put(list(encoded))
|
||||
buf.flip()
|
||||
return buf
|
||||
|
||||
def encode(self, input: "CharBuffer", output: "ByteBuffer", end_of_input: bool) -> CoderResult:
|
||||
"""Encodes as much as possible from input to output."""
|
||||
in_str = ""
|
||||
for i in range(input.position(), input.limit()):
|
||||
in_str += chr(input.get(i))
|
||||
try:
|
||||
encoded = in_str.encode(self._charset.name())
|
||||
from ..nio import ByteBuffer
|
||||
out_arr = bytearray()
|
||||
for i in range(output.position(), output.limit()):
|
||||
if i < len(encoded):
|
||||
out_arr.append(encoded[i])
|
||||
return CoderResult.UNDERFLOW
|
||||
except UnicodeEncodeError:
|
||||
return CoderResult.unmappableForLength(1)
|
||||
|
||||
def encodeLoop(self, input: "CharBuffer", output: "ByteBuffer") -> CoderResult:
|
||||
"""The encoding loop (subclass hook)."""
|
||||
return self.encode(input, output, True)
|
||||
|
||||
def implReplaceWith(self, new_replacement: bytes):
|
||||
"""Hook for subclasses to react to replacement changes."""
|
||||
pass
|
||||
|
||||
def implOnMalformedInput(self, new_action: CodingErrorAction):
|
||||
"""Hook for subclasses to react to malformed input action changes."""
|
||||
pass
|
||||
|
||||
def implOnUnmappableCharacter(self, new_action: CodingErrorAction):
|
||||
"""Hook for subclasses to react to unmappable char action changes."""
|
||||
pass
|
||||
|
||||
def implReset(self):
|
||||
"""Hook for subclasses to reset internal state."""
|
||||
pass
|
||||
|
||||
def averageBytesPerChar(self) -> float:
|
||||
return self._average_bytes_per_char
|
||||
|
||||
def maxBytesPerChar(self) -> float:
|
||||
return self._max_bytes_per_char
|
||||
|
||||
def isLegalReplacement(self, repl: bytes) -> bool:
|
||||
"""Returns True if the replacement is a legal byte sequence."""
|
||||
return len(repl) > 0
|
||||
|
||||
def malformedInputAction(self) -> CodingErrorAction:
|
||||
return self._malformed_input_action
|
||||
|
||||
def unmappableCharacterAction(self) -> CodingErrorAction:
|
||||
return self._unmappable_action
|
||||
|
||||
def onMalformedInput(self, action: CodingErrorAction) -> "CharsetEncoder":
|
||||
self._malformed_input_action = action
|
||||
return self
|
||||
|
||||
def onUnmappableCharacter(self, action: CodingErrorAction) -> "CharsetEncoder":
|
||||
self._unmappable_action = action
|
||||
return self
|
||||
|
||||
def reset(self) -> "CharsetEncoder":
|
||||
"""Resets this encoder, clearing any internal state."""
|
||||
self.implReset()
|
||||
return self
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"CharsetEncoder@{hex(id(self))}[charset={self._charset.name()}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, CharsetEncoder):
|
||||
return False
|
||||
return self._charset == other._charset
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._charset.name()) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CharsetDecoder
|
||||
# ============================================================
|
||||
|
||||
class CharsetDecoder(Stub):
|
||||
"""
|
||||
java.nio.charset.CharsetDecoder
|
||||
Converts byte data to character data using a Charset.
|
||||
"""
|
||||
|
||||
def __init__(self, charset: Charset, average_chars_per_byte: float = 1.0,
|
||||
max_chars_per_byte: float = 2.0, replacement: str = '\ufffd'):
|
||||
super().__init__()
|
||||
self._charset = charset
|
||||
self._average_chars_per_byte = average_chars_per_byte
|
||||
self._max_chars_per_byte = max_chars_per_byte
|
||||
self._replacement = replacement
|
||||
self._malformed_input_action = CodingErrorAction.REPORT
|
||||
self._unmappable_action = CodingErrorAction.REPORT
|
||||
self._auto_detect = False
|
||||
self._detected_charset = None
|
||||
|
||||
def charset(self) -> Charset:
|
||||
"""Returns the charset that created this decoder."""
|
||||
return self._charset
|
||||
|
||||
def replacement(self) -> str:
|
||||
"""Returns the replacement value."""
|
||||
return self._replacement
|
||||
|
||||
def replaceWith(self, new_replacement: str) -> "CharsetDecoder":
|
||||
"""Sets a new replacement value."""
|
||||
self._replacement = new_replacement
|
||||
return self
|
||||
|
||||
def decode(self, buf: "ByteBuffer") -> "CharBuffer":
|
||||
"""Decodes bytes from a ByteBuffer into a CharBuffer."""
|
||||
arr = bytearray()
|
||||
for i in range(buf.position(), buf.limit()):
|
||||
arr.append(buf.get(i))
|
||||
decoded = arr.decode(self._charset.name(), errors="replace")
|
||||
from ..nio import CharBuffer
|
||||
cb = CharBuffer.allocate(len(decoded))
|
||||
cb.put(decoded)
|
||||
cb.flip()
|
||||
return cb
|
||||
|
||||
def decode(self, input: "ByteBuffer", output: "CharBuffer", end_of_input: bool) -> CoderResult:
|
||||
"""Decodes as much as possible from input to output."""
|
||||
arr = bytearray()
|
||||
for i in range(input.position(), input.limit()):
|
||||
arr.append(input.get(i))
|
||||
try:
|
||||
decoded = arr.decode(self._charset.name())
|
||||
return CoderResult.UNDERFLOW
|
||||
except UnicodeDecodeError:
|
||||
return CoderResult.malformedForLength(1)
|
||||
|
||||
def decodeLoop(self, input: "ByteBuffer", output: "CharBuffer") -> CoderResult:
|
||||
"""The decoding loop (subclass hook)."""
|
||||
return self.decode(input, output, True)
|
||||
|
||||
def implReplaceWith(self, new_replacement: str):
|
||||
"""Hook for subclasses."""
|
||||
pass
|
||||
|
||||
def implOnMalformedInput(self, new_action: CodingErrorAction):
|
||||
"""Hook for subclasses."""
|
||||
pass
|
||||
|
||||
def implOnUnmappableCharacter(self, new_action: CodingErrorAction):
|
||||
"""Hook for subclasses."""
|
||||
pass
|
||||
|
||||
def implReset(self):
|
||||
"""Hook for subclasses."""
|
||||
pass
|
||||
|
||||
def averageCharsPerByte(self) -> float:
|
||||
return self._average_chars_per_byte
|
||||
|
||||
def maxCharsPerByte(self) -> float:
|
||||
return self._max_chars_per_byte
|
||||
|
||||
def isCharsetDetected(self) -> bool:
|
||||
return self._detected_charset is not None
|
||||
|
||||
def isAutoDetect(self) -> bool:
|
||||
return self._auto_detect
|
||||
|
||||
def detectedCharset(self) -> Charset:
|
||||
if self._detected_charset is None:
|
||||
raise AndroidOnlyError("No charset detected")
|
||||
return self._detected_charset
|
||||
|
||||
def malformedInputAction(self) -> CodingErrorAction:
|
||||
return self._malformed_input_action
|
||||
|
||||
def unmappableCharacterAction(self) -> CodingErrorAction:
|
||||
return self._unmappable_action
|
||||
|
||||
def onMalformedInput(self, action: CodingErrorAction) -> "CharsetDecoder":
|
||||
self._malformed_input_action = action
|
||||
return self
|
||||
|
||||
def onUnmappableCharacter(self, action: CodingErrorAction) -> "CharsetDecoder":
|
||||
self._unmappable_action = action
|
||||
return self
|
||||
|
||||
def reset(self) -> "CharsetDecoder":
|
||||
self.implReset()
|
||||
return self
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"CharsetDecoder@{hex(id(self))}[charset={self._charset.name()}]"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, CharsetDecoder):
|
||||
return False
|
||||
return self._charset == other._charset
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._charset.name()) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StandardCharsets
|
||||
# ============================================================
|
||||
|
||||
class StandardCharsets(Stub):
|
||||
"""
|
||||
java.nio.charset.StandardCharsets
|
||||
Constant definitions for the standard charsets.
|
||||
"""
|
||||
US_ASCII: Charset = Charset.US_ASCII
|
||||
ISO_8859_1: Charset = Charset.ISO_8859_1
|
||||
UTF_8: Charset = Charset.UTF_8
|
||||
UTF_16: Charset = Charset.UTF_16
|
||||
UTF_16BE: Charset = Charset.UTF_16BE
|
||||
UTF_16LE: Charset = Charset.UTF_16LE
|
||||
@@ -0,0 +1,776 @@
|
||||
"""
|
||||
Java java.rmi standard library APIs implemented in Python.
|
||||
java.rmi package - Remote, Registry, Activation, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from .lang import RuntimeException, Exception as _JavaException
|
||||
import typing as _typing
|
||||
|
||||
__all__ = [
|
||||
"Remote", "RemoteException", "RMISecurityManager", "RMISecurityException",
|
||||
"MarshalledObject", "Naming", "NamingException",
|
||||
"NotBoundException", "AlreadyBoundException",
|
||||
"ConnectException", "ConnectIOException", "ServerException",
|
||||
"ServerError", "ServerRuntimeException", "StubNotFoundException",
|
||||
"UnexpectedException", "UnmarshalException", "UnknownHostException",
|
||||
"NoSuchObjectException", "AccessException", "MarshalException",
|
||||
"ExportException", "SocketSecurityException",
|
||||
"Registry", "RegistryHandler",
|
||||
"ActivationException", "UnknownObjectException",
|
||||
"Activatable", "ActivationDesc", "ActivationGroup",
|
||||
"ActivationGroupDesc", "ActivationGroupID", "ActivationID",
|
||||
"ActivationMonitor", "ActivationSystem", "Activator",
|
||||
"RMIClassLoader", "RMISocketFactory", "RMIFailureHandler",
|
||||
"LogStream", "RemoteCall", "RemoteRef", "ServerRef", "Operation",
|
||||
"RemoteObject", "RemoteServer", "UnicastRemoteObject", "Unreferenced",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Remote interface
|
||||
# ============================================================
|
||||
|
||||
class Remote(Stub):
|
||||
"""java.rmi.Remote"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Exception hierarchy
|
||||
# ============================================================
|
||||
|
||||
class RemoteException(_JavaException):
|
||||
"""java.rmi.RemoteException"""
|
||||
def __init__(self, message=None, cause=None):
|
||||
msg = message or ""
|
||||
super().__init__(msg)
|
||||
self._detail = message
|
||||
self._cause = cause
|
||||
|
||||
def getMessage(self):
|
||||
return self._detail or ""
|
||||
|
||||
def getCause(self):
|
||||
return self._cause
|
||||
|
||||
|
||||
class NamingException(RemoteException):
|
||||
"""java.rmi.NamingException"""
|
||||
pass
|
||||
|
||||
|
||||
class NotBoundException(RemoteException):
|
||||
"""java.rmi.NotBoundException"""
|
||||
pass
|
||||
|
||||
|
||||
class AlreadyBoundException(RemoteException):
|
||||
"""java.rmi.AlreadyBoundException"""
|
||||
pass
|
||||
|
||||
|
||||
class ConnectException(RemoteException):
|
||||
"""java.rmi.ConnectException"""
|
||||
pass
|
||||
|
||||
|
||||
class ConnectIOException(RemoteException):
|
||||
"""java.rmi.ConnectIOException"""
|
||||
pass
|
||||
|
||||
|
||||
class ServerException(RemoteException):
|
||||
"""java.rmi.ServerException"""
|
||||
pass
|
||||
|
||||
|
||||
class ServerError(RemoteException):
|
||||
"""java.rmi.ServerError"""
|
||||
pass
|
||||
|
||||
|
||||
class ServerRuntimeException(RemoteException):
|
||||
"""java.rmi.ServerRuntimeException"""
|
||||
pass
|
||||
|
||||
|
||||
class StubNotFoundException(RemoteException):
|
||||
"""java.rmi.StubNotFoundException"""
|
||||
pass
|
||||
|
||||
|
||||
class UnexpectedException(RemoteException):
|
||||
"""java.rmi.UnexpectedException"""
|
||||
pass
|
||||
|
||||
|
||||
class UnmarshalException(RemoteException):
|
||||
"""java.rmi.UnmarshalException"""
|
||||
pass
|
||||
|
||||
|
||||
class UnknownHostException(RemoteException):
|
||||
"""java.rmi.UnknownHostException"""
|
||||
pass
|
||||
|
||||
|
||||
class NoSuchObjectException(RemoteException):
|
||||
"""java.rmi.NoSuchObjectException"""
|
||||
pass
|
||||
|
||||
|
||||
class AccessException(RemoteException):
|
||||
"""java.rmi.AccessException"""
|
||||
pass
|
||||
|
||||
|
||||
class MarshalException(RemoteException):
|
||||
"""java.rmi.MarshalException"""
|
||||
pass
|
||||
|
||||
|
||||
class ExportException(RemoteException):
|
||||
"""java.rmi.ExportException"""
|
||||
pass
|
||||
|
||||
|
||||
class SocketSecurityException(ExportException):
|
||||
"""java.rmi.SocketSecurityException"""
|
||||
pass
|
||||
|
||||
|
||||
# java.lang.SecurityException (桌面模拟)
|
||||
class SecurityException(RuntimeException):
|
||||
def __init__(self, message=""):
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class RMISecurityException(SecurityException):
|
||||
"""java.rmi.RMISecurityException"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RMISecurityManager
|
||||
# ============================================================
|
||||
|
||||
class RMISecurityManager(Stub):
|
||||
"""java.rmi.RMISecurityManager"""
|
||||
def checkConnect(self, host, port):
|
||||
pass
|
||||
|
||||
def checkAccept(self, host, port):
|
||||
pass
|
||||
|
||||
def checkListen(self, port):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# MarshalledObject
|
||||
# ============================================================
|
||||
|
||||
class MarshalledObject(Stub):
|
||||
"""java.rmi.MarshalledObject"""
|
||||
def __init__(self, obj):
|
||||
super().__init__()
|
||||
self._obj = obj
|
||||
import pickle
|
||||
self._bytes = pickle.dumps(obj)
|
||||
|
||||
def get(self):
|
||||
import pickle
|
||||
try:
|
||||
return pickle.loads(self._bytes)
|
||||
except Exception:
|
||||
return self._obj
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._bytes)
|
||||
|
||||
def equals(self, obj):
|
||||
if not isinstance(obj, MarshalledObject):
|
||||
return False
|
||||
return self._bytes == obj._bytes
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Naming
|
||||
# ============================================================
|
||||
|
||||
class Naming(Stub):
|
||||
"""java.rmi.Naming"""
|
||||
_registry = {}
|
||||
|
||||
@staticmethod
|
||||
def lookup(name):
|
||||
if name in Naming._registry:
|
||||
return Naming._registry[name]
|
||||
raise NotBoundException(name)
|
||||
|
||||
@staticmethod
|
||||
def bind(name, obj):
|
||||
if name in Naming._registry:
|
||||
raise AlreadyBoundException(name)
|
||||
Naming._registry[name] = obj
|
||||
|
||||
@staticmethod
|
||||
def unbind(name):
|
||||
if name not in Naming._registry:
|
||||
raise NotBoundException(name)
|
||||
del Naming._registry[name]
|
||||
|
||||
@staticmethod
|
||||
def rebind(name, obj):
|
||||
Naming._registry[name] = obj
|
||||
|
||||
@staticmethod
|
||||
def list(name):
|
||||
return list(Naming._registry.keys())
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Registry
|
||||
# ============================================================
|
||||
|
||||
class Registry(Stub):
|
||||
"""java.rmi.registry.Registry"""
|
||||
def lookup(self, name):
|
||||
raise NotBoundException(name)
|
||||
|
||||
def bind(self, name, obj):
|
||||
raise AlreadyBoundException(name)
|
||||
|
||||
def unbind(self, name):
|
||||
raise NotBoundException(name)
|
||||
|
||||
def rebind(self, name, obj):
|
||||
pass
|
||||
|
||||
def list(self):
|
||||
return []
|
||||
|
||||
REGISTRY_PORT = 1099
|
||||
|
||||
|
||||
class RegistryHandler(Stub):
|
||||
"""java.rmi.registry.RegistryHandler"""
|
||||
def registryStub(self, host, port):
|
||||
return Registry()
|
||||
|
||||
def registryImpl(self, port):
|
||||
return Registry()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Activation Exceptions
|
||||
# ============================================================
|
||||
|
||||
class ActivationException(RemoteException):
|
||||
"""java.rmi.activation.ActivationException"""
|
||||
pass
|
||||
|
||||
|
||||
class UnknownObjectException(ActivationException):
|
||||
"""java.rmi.activation.UnknownObjectException"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ActivationID
|
||||
# ============================================================
|
||||
|
||||
class ActivationID(Stub):
|
||||
"""java.rmi.activation.ActivationID"""
|
||||
def __init__(self, activator=None):
|
||||
super().__init__()
|
||||
self._activator = activator
|
||||
|
||||
def activate(self, force):
|
||||
if self._activator:
|
||||
return self._activator.activate(self, force)
|
||||
return None
|
||||
|
||||
def hashCode(self):
|
||||
return hash(id(self))
|
||||
|
||||
def equals(self, obj):
|
||||
return self is obj
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ActivationDesc
|
||||
# ============================================================
|
||||
|
||||
class ActivationDesc(Stub):
|
||||
"""java.rmi.activation.ActivationDesc"""
|
||||
def __init__(self, class_name=None, location=None, marshalled_data=None,
|
||||
group_id=None, restart_mode=False):
|
||||
super().__init__()
|
||||
self._class_name = class_name
|
||||
self._location = location
|
||||
self._marshalled_data = marshalled_data
|
||||
self._group_id = group_id
|
||||
self._restart_mode = restart_mode
|
||||
|
||||
def getClassName(self):
|
||||
return self._class_name
|
||||
|
||||
def getLocation(self):
|
||||
return self._location
|
||||
|
||||
def getData(self):
|
||||
return self._marshalled_data
|
||||
|
||||
def getGroupID(self):
|
||||
return self._group_id
|
||||
|
||||
def getRestartMode(self):
|
||||
return self._restart_mode
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Activatable
|
||||
# ============================================================
|
||||
|
||||
class Activatable(Remote):
|
||||
"""java.rmi.activation.Activatable"""
|
||||
def __init__(self, activation_desc, port, obj_id=None, server_port=0,
|
||||
csf=None, ssf=None):
|
||||
super().__init__()
|
||||
self._activation_desc = activation_desc
|
||||
self._port = port
|
||||
self._group_id = ActivationGroupID()
|
||||
self._id = ActivationID()
|
||||
|
||||
@staticmethod
|
||||
def register(desc):
|
||||
return ActivationID()
|
||||
|
||||
@staticmethod
|
||||
def inactive(id_):
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def unregister(id_):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def exportObject(obj, desc, port):
|
||||
return Remote()
|
||||
|
||||
def getID(self):
|
||||
return self._id
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ActivationGroup / ActivationGroupDesc / ActivationGroupID
|
||||
# ============================================================
|
||||
|
||||
class ActivationGroupID(Stub):
|
||||
"""java.rmi.activation.ActivationGroupID"""
|
||||
def __init__(self, activation_system=None):
|
||||
super().__init__()
|
||||
self._activation_system = activation_system
|
||||
|
||||
def getSystem(self):
|
||||
return self._activation_system
|
||||
|
||||
def hashCode(self):
|
||||
return hash(id(self))
|
||||
|
||||
|
||||
class ActivationGroupDesc(Stub):
|
||||
"""java.rmi.activation.ActivationGroupDesc"""
|
||||
class CommandEnvironment(Stub):
|
||||
def __init__(self, cmd=None, props=None):
|
||||
super().__init__()
|
||||
self._command = cmd
|
||||
self._properties = props or []
|
||||
|
||||
def getCommandPath(self):
|
||||
return self._command
|
||||
|
||||
def getCommandProperties(self):
|
||||
return self._properties
|
||||
|
||||
def __init__(self, props=None, env=None, class_name=None,
|
||||
location=None, info=None):
|
||||
super().__init__()
|
||||
self._props = props or {}
|
||||
self._env = env or ActivationGroupDesc.CommandEnvironment()
|
||||
self._class_name = class_name
|
||||
self._location = location
|
||||
self._info = info
|
||||
|
||||
def getPropertyOverrides(self):
|
||||
return self._props
|
||||
|
||||
def getCommandEnvironment(self):
|
||||
return self._env
|
||||
|
||||
def getClassName(self):
|
||||
return self._class_name
|
||||
|
||||
def getLocation(self):
|
||||
return self._location
|
||||
|
||||
def getData(self):
|
||||
return self._info
|
||||
|
||||
|
||||
class ActivationGroup(Activatable):
|
||||
"""java.rmi.activation.ActivationGroup"""
|
||||
def __init__(self, group_id, desc, incarnation):
|
||||
super().__init__(None, 0)
|
||||
self._group_id = group_id
|
||||
self._desc = desc
|
||||
self._incarnation = incarnation
|
||||
|
||||
@staticmethod
|
||||
def createGroup(id_, desc, incarnation):
|
||||
return ActivationGroup(id_, desc, incarnation)
|
||||
|
||||
@staticmethod
|
||||
def currentGroupID():
|
||||
return ActivationGroupID()
|
||||
|
||||
@staticmethod
|
||||
def setGroup(group):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def activeGroup(id_, group, incarnation):
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def inactiveGroup(group_id):
|
||||
pass
|
||||
|
||||
def newInstance(self, desc):
|
||||
return None
|
||||
|
||||
def activeObject(self, id_, obj):
|
||||
pass
|
||||
|
||||
def inactiveObject(self, id_):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ActivationMonitor / ActivationSystem / Activator
|
||||
# ============================================================
|
||||
|
||||
class ActivationMonitor(Stub):
|
||||
"""java.rmi.activation.ActivationMonitor"""
|
||||
def inactiveObject(self, id_):
|
||||
pass
|
||||
|
||||
def activeObject(self, id_, obj):
|
||||
pass
|
||||
|
||||
def inactiveGroup(self, group_id, incarnation):
|
||||
pass
|
||||
|
||||
|
||||
class ActivationSystem(Stub):
|
||||
"""java.rmi.activation.ActivationSystem"""
|
||||
def registerActivationDesc(self, desc):
|
||||
return ActivationID()
|
||||
|
||||
def unregisterActivationDesc(self, id_):
|
||||
pass
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def setActivationMonitor(self, monitor):
|
||||
pass
|
||||
|
||||
def getActivationMonitor(self):
|
||||
return ActivationMonitor()
|
||||
|
||||
def activeGroup(self, id_, group, incarnation):
|
||||
return ActivationMonitor()
|
||||
|
||||
def registerGroup(self, desc):
|
||||
return ActivationGroupID()
|
||||
|
||||
def unregisterGroup(self, group_id):
|
||||
pass
|
||||
|
||||
SYSTEM_PORT = 1098
|
||||
|
||||
|
||||
class Activator(Stub):
|
||||
"""java.rmi.activation.Activator"""
|
||||
def activate(self, id_, force):
|
||||
return MarshalledObject(None)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RMIClassLoader
|
||||
# ============================================================
|
||||
|
||||
class RMIClassLoader(Stub):
|
||||
"""java.rmi.server.RMIClassLoader"""
|
||||
@staticmethod
|
||||
def loadClass(codebase, name, default_loader=None):
|
||||
import importlib
|
||||
try:
|
||||
return importlib.import_module(name)
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def getClassAnnotation(cls):
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def getClassLoader(codebase):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def getDefaultProviderInstance():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def loadProxyClass(codebase, interfaces, default_loader):
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RMISocketFactory / RMIFailureHandler
|
||||
# ============================================================
|
||||
|
||||
class RMISocketFactory(Stub):
|
||||
"""java.rmi.server.RMISocketFactory"""
|
||||
_factory = None
|
||||
_handler = None
|
||||
|
||||
@staticmethod
|
||||
def getDefaultSocketFactory():
|
||||
if RMISocketFactory._factory is None:
|
||||
RMISocketFactory._factory = RMISocketFactory()
|
||||
return RMISocketFactory._factory
|
||||
|
||||
@staticmethod
|
||||
def setSocketFactory(factory):
|
||||
RMISocketFactory._factory = factory
|
||||
|
||||
@staticmethod
|
||||
def getFailureHandler():
|
||||
return RMISocketFactory._handler
|
||||
|
||||
@staticmethod
|
||||
def setFailureHandler(handler):
|
||||
RMISocketFactory._handler = handler
|
||||
|
||||
def createSocket(self, host, port):
|
||||
import socket
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((host, port))
|
||||
return s
|
||||
|
||||
def getDefaultPort(self):
|
||||
return 0
|
||||
|
||||
|
||||
class RMIFailureHandler(Stub):
|
||||
"""java.rmi.server.RMIFailureHandler"""
|
||||
def failure(self, ex):
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LogStream
|
||||
# ============================================================
|
||||
|
||||
class LogStream(Stub):
|
||||
"""java.rmi.server.LogStream"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._stream = None
|
||||
|
||||
@staticmethod
|
||||
def log(name):
|
||||
return LogStream(name)
|
||||
|
||||
@staticmethod
|
||||
def getDefaultStream():
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def setDefaultStream(stream):
|
||||
pass
|
||||
|
||||
def getOutputStream(self):
|
||||
return self._stream
|
||||
|
||||
def setOutputStream(self, stream):
|
||||
self._stream = stream
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
SILENT = 0
|
||||
BRIEF = 10
|
||||
VERBOSE = 20
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RemoteCall / RemoteRef / ServerRef / Operation
|
||||
# ============================================================
|
||||
|
||||
class RemoteCall(Stub):
|
||||
"""java.rmi.server.RemoteCall"""
|
||||
def getInputStream(self):
|
||||
return None
|
||||
|
||||
def getOutputStream(self):
|
||||
return None
|
||||
|
||||
def getResultStream(self, success):
|
||||
return None
|
||||
|
||||
def executeCall(self):
|
||||
pass
|
||||
|
||||
def done(self):
|
||||
pass
|
||||
|
||||
def releaseInputStream(self):
|
||||
pass
|
||||
|
||||
def releaseOutputStream(self):
|
||||
pass
|
||||
|
||||
|
||||
class RemoteRef(Stub):
|
||||
"""java.rmi.server.RemoteRef"""
|
||||
def invoke(self, call):
|
||||
return None
|
||||
|
||||
def remoteEquals(self, obj):
|
||||
return False
|
||||
|
||||
def remoteHashCode(self):
|
||||
return 0
|
||||
|
||||
def remoteToString(self):
|
||||
return ""
|
||||
|
||||
def getRefClass(self, out):
|
||||
return ""
|
||||
|
||||
def newCall(self, obj, operations, opnum, hash_):
|
||||
return RemoteCall()
|
||||
|
||||
def invoke(self, call):
|
||||
pass
|
||||
|
||||
def done(self, call):
|
||||
pass
|
||||
|
||||
packagePrefix = "sun.rmi.server"
|
||||
|
||||
|
||||
class ServerRef(RemoteRef):
|
||||
"""java.rmi.server.ServerRef"""
|
||||
def exportObject(self, obj, data):
|
||||
return RemoteStub()
|
||||
|
||||
def getClientHost(self):
|
||||
return "localhost"
|
||||
|
||||
|
||||
class RemoteStub(Stub):
|
||||
"""java.rmi.server.RemoteStub"""
|
||||
def __init__(self, ref=None):
|
||||
super().__init__()
|
||||
self._ref = ref
|
||||
|
||||
|
||||
class Operation(Stub):
|
||||
"""java.rmi.server.Operation"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def getOperation(self):
|
||||
return self._name
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RemoteObject / RemoteServer / UnicastRemoteObject
|
||||
# ============================================================
|
||||
|
||||
class RemoteObject(Stub):
|
||||
"""java.rmi.server.RemoteObject"""
|
||||
def __init__(self, ref=None):
|
||||
super().__init__()
|
||||
self._ref = ref
|
||||
|
||||
def getRef(self):
|
||||
return self._ref
|
||||
|
||||
def toString(self):
|
||||
return "RemoteObject"
|
||||
|
||||
def hashCode(self):
|
||||
return super().hashCode()
|
||||
|
||||
def equals(self, obj):
|
||||
return super().equals(obj)
|
||||
|
||||
|
||||
class RemoteServer(RemoteObject):
|
||||
"""java.rmi.server.RemoteServer"""
|
||||
def __init__(self, ref=None):
|
||||
super().__init__(ref)
|
||||
|
||||
@staticmethod
|
||||
def getClientHost():
|
||||
return "localhost"
|
||||
|
||||
@staticmethod
|
||||
def setLog(output_stream):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def getLog():
|
||||
return None
|
||||
|
||||
|
||||
class UnicastRemoteObject(RemoteServer):
|
||||
"""java.rmi.server.UnicastRemoteObject"""
|
||||
def __init__(self, port=0, csf=None, ssf=None):
|
||||
super().__init__()
|
||||
self._port = port
|
||||
self._csf = csf
|
||||
self._ssf = ssf
|
||||
self._exported = False
|
||||
|
||||
@staticmethod
|
||||
def exportObject(obj, port=0, csf=None, ssf=None):
|
||||
return RemoteStub()
|
||||
|
||||
@staticmethod
|
||||
def unexportObject(obj, force):
|
||||
return True
|
||||
|
||||
def clone(self):
|
||||
return UnicastRemoteObject(self._port)
|
||||
|
||||
|
||||
class Unreferenced(Stub):
|
||||
"""java.rmi.server.Unreferenced"""
|
||||
def unreferenced(self):
|
||||
pass
|
||||
@@ -0,0 +1,907 @@
|
||||
"""
|
||||
Java security.cert standard library APIs implemented in Python.
|
||||
java.security.cert package - Certificate, CertPath, CRL, PKIX, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from .security import GeneralSecurityException, CertificateFactory as _OldCF
|
||||
from .lang import RuntimeException, String
|
||||
import datetime as _datetime
|
||||
import typing as _typing
|
||||
|
||||
__all__ = [
|
||||
"Certificate", "CertificateFactory", "X509Certificate",
|
||||
"X509CRL", "X509CRLEntry", "CertPath", "CertPathBuilder",
|
||||
"CertPathValidator", "CertStore", "CertificateNotYetValidException",
|
||||
"CertificateExpiredException", "CertificateEncodingException",
|
||||
"CertificateParsingException", "CertPathValidatorException",
|
||||
"CertPathBuilderException", "CRL", "CRLException",
|
||||
"PolicyQualifierInfo", "TrustAnchor", "Extension", "X509Extension",
|
||||
"CollectionCertStoreParameters", "LDAPCertStoreParameters",
|
||||
"CertStoreParameters", "PKIXParameters", "PKIXBuilderParameters",
|
||||
"PKIXCertPathBuilderResult", "PKIXCertPathValidatorResult",
|
||||
"CertPathBuilderResult", "CertPathValidatorResult", "CertPathParameters",
|
||||
"CRL_REASON_UNSPECIFIED", "CRL_REASON_KEY_COMPROMISE",
|
||||
"CRL_REASON_CA_COMPROMISE", "CRL_REASON_AFFILIATION_CHANGED",
|
||||
"CRL_REASON_SUPERSEDED", "CRL_REASON_CESSATION_OF_OPERATION",
|
||||
"CRL_REASON_CERTIFICATE_HOLD", "CRL_REASON_REMOVE_FROM_CRL",
|
||||
"CRL_REASON_PRIVILEGE_WITHDRAWN", "CRL_REASON_AA_COMPROMISE",
|
||||
]
|
||||
|
||||
# ============================================================
|
||||
# CRL Reason Constants
|
||||
# ============================================================
|
||||
|
||||
CRL_REASON_UNSPECIFIED = 0
|
||||
CRL_REASON_KEY_COMPROMISE = 1
|
||||
CRL_REASON_CA_COMPROMISE = 2
|
||||
CRL_REASON_AFFILIATION_CHANGED = 3
|
||||
CRL_REASON_SUPERSEDED = 4
|
||||
CRL_REASON_CESSATION_OF_OPERATION = 5
|
||||
CRL_REASON_CERTIFICATE_HOLD = 6
|
||||
CRL_REASON_REMOVE_FROM_CRL = 8
|
||||
CRL_REASON_PRIVILEGE_WITHDRAWN = 9
|
||||
CRL_REASON_AA_COMPROMISE = 10
|
||||
|
||||
# ============================================================
|
||||
# CertPathParameters
|
||||
# ============================================================
|
||||
|
||||
class CertPathParameters(Stub):
|
||||
"""java.security.cert.CertPathParameters"""
|
||||
def clone(self):
|
||||
return self.__class__()
|
||||
|
||||
|
||||
class CertPathBuilderResult(Stub):
|
||||
"""java.security.cert.CertPathBuilderResult"""
|
||||
def getCertPath(self):
|
||||
return CertPath("")
|
||||
|
||||
def clone(self):
|
||||
return self.__class__()
|
||||
|
||||
|
||||
class CertPathValidatorResult(Stub):
|
||||
"""java.security.cert.CertPathValidatorResult"""
|
||||
def clone(self):
|
||||
return self.__class__()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CertStoreParameters
|
||||
# ============================================================
|
||||
|
||||
class CertStoreParameters(Stub):
|
||||
"""java.security.cert.CertStoreParameters"""
|
||||
def clone(self):
|
||||
return self.__class__()
|
||||
|
||||
|
||||
class CollectionCertStoreParameters(CertStoreParameters):
|
||||
"""java.security.cert.CollectionCertStoreParameters"""
|
||||
def __init__(self, collection=None):
|
||||
super().__init__()
|
||||
if collection is None:
|
||||
self._collection = []
|
||||
else:
|
||||
self._collection = list(collection)
|
||||
|
||||
def getCollection(self):
|
||||
return self._collection
|
||||
|
||||
def clone(self):
|
||||
return CollectionCertStoreParameters(self._collection)
|
||||
|
||||
def toString(self):
|
||||
return f"CollectionCertStoreParameters: [collection: {len(self._collection)}]"
|
||||
|
||||
|
||||
class LDAPCertStoreParameters(CertStoreParameters):
|
||||
"""java.security.cert.LDAPCertStoreParameters"""
|
||||
def __init__(self, server_name="localhost", port=389):
|
||||
super().__init__()
|
||||
self._server_name = server_name
|
||||
self._port = port
|
||||
|
||||
def getServerName(self):
|
||||
return self._server_name
|
||||
|
||||
def getPort(self):
|
||||
return self._port
|
||||
|
||||
def clone(self):
|
||||
return LDAPCertStoreParameters(self._server_name, self._port)
|
||||
|
||||
def toString(self):
|
||||
return f"LDAPCertStoreParameters: [serverName: {self._server_name}, port: {self._port}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Exception Classes
|
||||
# ============================================================
|
||||
|
||||
class CertificateException(GeneralSecurityException):
|
||||
"""java.security.cert.CertificateException"""
|
||||
pass
|
||||
|
||||
class CertificateEncodingException(CertificateException):
|
||||
"""java.security.cert.CertificateEncodingException"""
|
||||
pass
|
||||
|
||||
class CertificateParsingException(CertificateException):
|
||||
"""java.security.cert.CertificateParsingException"""
|
||||
pass
|
||||
|
||||
class CertificateNotYetValidException(CertificateException):
|
||||
"""java.security.cert.CertificateNotYetValidException"""
|
||||
pass
|
||||
|
||||
class CertificateExpiredException(CertificateException):
|
||||
"""java.security.cert.CertificateExpiredException"""
|
||||
pass
|
||||
|
||||
class CRLException(GeneralSecurityException):
|
||||
"""java.security.cert.CRLException"""
|
||||
pass
|
||||
|
||||
class CertPathBuilderException(GeneralSecurityException):
|
||||
"""java.security.cert.CertPathBuilderException"""
|
||||
def __init__(self, message=None, cause=None):
|
||||
super().__init__()
|
||||
self._detail = message or ""
|
||||
self._cause = cause
|
||||
|
||||
def getMessage(self):
|
||||
return self._detail
|
||||
|
||||
def getCause(self):
|
||||
return self._cause
|
||||
|
||||
class CertPathValidatorException(GeneralSecurityException):
|
||||
"""java.security.cert.CertPathValidatorException"""
|
||||
class Reason(Stub):
|
||||
pass
|
||||
|
||||
def __init__(self, message=None, cause=None, cert_path=None, index=-1):
|
||||
super().__init__()
|
||||
self._detail = message or ""
|
||||
self._cause = cause
|
||||
self._cert_path = cert_path
|
||||
self._index = index
|
||||
|
||||
def getMessage(self):
|
||||
return self._detail
|
||||
|
||||
def getCause(self):
|
||||
return self._cause
|
||||
|
||||
def getCertPath(self):
|
||||
return self._cert_path
|
||||
|
||||
def getIndex(self):
|
||||
return self._index
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Certificate
|
||||
# ============================================================
|
||||
|
||||
class Certificate(Stub):
|
||||
"""java.security.cert.Certificate"""
|
||||
def __init__(self, type_name=""):
|
||||
super().__init__()
|
||||
self._type = type_name
|
||||
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def getEncoded(self):
|
||||
raise CertificateEncodingException("Certificate not encoded")
|
||||
|
||||
def verify(self, key):
|
||||
raise NotImplementedError
|
||||
|
||||
def toString(self):
|
||||
return f"Certificate type={self._type}"
|
||||
|
||||
def getPublicKey(self):
|
||||
from .security import PublicKey
|
||||
return PublicKey()
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, Certificate):
|
||||
return False
|
||||
return self._type == other._type
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._type)
|
||||
|
||||
|
||||
class X509Certificate(Certificate):
|
||||
"""java.security.cert.X509Certificate"""
|
||||
def __init__(self):
|
||||
super().__init__("X.509")
|
||||
self._encoded = b""
|
||||
self._subject = ""
|
||||
self._issuer = ""
|
||||
self._serial = 0
|
||||
self._not_before = _datetime.datetime.now()
|
||||
self._not_after = _datetime.datetime.now() + _datetime.timedelta(days=365)
|
||||
self._sig_alg = "SHA256withRSA"
|
||||
self._sig_alg_oid = "1.2.840.113549.1.1.11"
|
||||
self._version = 3
|
||||
self._public_key = None
|
||||
self._extensions = {}
|
||||
|
||||
def getEncoded(self):
|
||||
if not self._encoded:
|
||||
raise CertificateEncodingException("X509Cert not encoded")
|
||||
return self._encoded
|
||||
|
||||
def verify(self, key):
|
||||
return True
|
||||
|
||||
def getPublicKey(self):
|
||||
if self._public_key is None:
|
||||
from .security import PublicKey
|
||||
self._public_key = PublicKey()
|
||||
return self._public_key
|
||||
|
||||
def getSubjectX500Principal(self):
|
||||
from .security import Principal
|
||||
return Principal(self._subject)
|
||||
|
||||
def getIssuerX500Principal(self):
|
||||
from .security import Principal
|
||||
return Principal(self._issuer)
|
||||
|
||||
def getSerialNumber(self):
|
||||
return self._serial
|
||||
|
||||
def getNotBefore(self):
|
||||
return self._not_before
|
||||
|
||||
def getNotAfter(self):
|
||||
return self._not_after
|
||||
|
||||
def getSigAlgName(self):
|
||||
return self._sig_alg
|
||||
|
||||
def getSigAlgOID(self):
|
||||
return self._sig_alg_oid
|
||||
|
||||
def getVersion(self):
|
||||
return self._version
|
||||
|
||||
def checkValidity(self, date=None):
|
||||
if date is None:
|
||||
date = _datetime.datetime.now()
|
||||
if date < self._not_before:
|
||||
raise CertificateNotYetValidException(
|
||||
f"Certificate not valid until {self._not_before}"
|
||||
)
|
||||
if date > self._not_after:
|
||||
raise CertificateExpiredException(
|
||||
f"Certificate expired at {self._not_after}"
|
||||
)
|
||||
|
||||
def getExtendedKeyUsage(self):
|
||||
return None
|
||||
|
||||
def getBasicConstraints(self):
|
||||
return -1
|
||||
|
||||
def getSubjectAlternativeNames(self):
|
||||
return None
|
||||
|
||||
def getIssuerAlternativeNames(self):
|
||||
return None
|
||||
|
||||
def getKeyUsage(self):
|
||||
return None
|
||||
|
||||
def hasUnsupportedCriticalExtension(self):
|
||||
return False
|
||||
|
||||
def getCriticalExtensionOIDs(self):
|
||||
return list(self._extensions.keys())
|
||||
|
||||
def getNonCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getExtensionValue(self, oid):
|
||||
return self._extensions.get(oid)
|
||||
|
||||
def toString(self):
|
||||
return f"X509Certificate [subject={self._subject}, issuer={self._issuer}]"
|
||||
|
||||
def setEncoded(self, encoded):
|
||||
self._encoded = bytes(encoded)
|
||||
|
||||
def setSubject(self, subject):
|
||||
self._subject = subject
|
||||
|
||||
def setIssuer(self, issuer):
|
||||
self._issuer = issuer
|
||||
|
||||
def setSerialNumber(self, serial):
|
||||
self._serial = serial
|
||||
|
||||
def setNotBefore(self, dt):
|
||||
self._not_before = dt
|
||||
|
||||
def setNotAfter(self, dt):
|
||||
self._not_after = dt
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CRL / X509CRL / X509CRLEntry
|
||||
# ============================================================
|
||||
|
||||
class CRL(Stub):
|
||||
"""java.security.cert.CRL"""
|
||||
def __init__(self, type_name=""):
|
||||
super().__init__()
|
||||
self._type = type_name
|
||||
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def isRevoked(self, cert):
|
||||
return False
|
||||
|
||||
def toString(self):
|
||||
return f"CRL type={self._type}"
|
||||
|
||||
|
||||
class X509CRLEntry(Stub):
|
||||
"""java.security.cert.X509CRLEntry"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._serial_number = 0
|
||||
self._revocation_date = _datetime.datetime.now()
|
||||
self._extensions = {}
|
||||
|
||||
def getSerialNumber(self):
|
||||
return self._serial_number
|
||||
|
||||
def getRevocationDate(self):
|
||||
return self._revocation_date
|
||||
|
||||
def hasExtensions(self):
|
||||
return len(self._extensions) > 0
|
||||
|
||||
def toString(self):
|
||||
return f"X509CRLEntry serial={self._serial_number}"
|
||||
|
||||
def getCertificateIssuer(self):
|
||||
return None
|
||||
|
||||
def getEncoded(self):
|
||||
return b""
|
||||
|
||||
def getCriticalExtensionOIDs(self):
|
||||
return list(self._extensions.keys())
|
||||
|
||||
def getNonCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getExtensionValue(self, oid):
|
||||
return self._extensions.get(oid)
|
||||
|
||||
|
||||
class X509CRL(CRL):
|
||||
"""java.security.cert.X509CRL"""
|
||||
def __init__(self):
|
||||
super().__init__("X.509")
|
||||
self._encoded = b""
|
||||
self._issuer = ""
|
||||
self._this_update = _datetime.datetime.now()
|
||||
self._next_update = _datetime.datetime.now() + _datetime.timedelta(days=7)
|
||||
self._sig_alg = "SHA256withRSA"
|
||||
self._version = 2
|
||||
self._entries = []
|
||||
|
||||
def getEncoded(self):
|
||||
return self._encoded
|
||||
|
||||
def verify(self, key):
|
||||
return True
|
||||
|
||||
def getIssuerX500Principal(self):
|
||||
from .security import Principal
|
||||
return Principal(self._issuer)
|
||||
|
||||
def getThisUpdate(self):
|
||||
return self._this_update
|
||||
|
||||
def getNextUpdate(self):
|
||||
return self._next_update
|
||||
|
||||
def getSigAlgName(self):
|
||||
return self._sig_alg
|
||||
|
||||
def getSigAlgOID(self):
|
||||
return "1.2.840.113549.1.1.11"
|
||||
|
||||
def getVersion(self):
|
||||
return self._version
|
||||
|
||||
def isRevoked(self, cert):
|
||||
for entry in self._entries:
|
||||
if hasattr(cert, 'getSerialNumber'):
|
||||
if entry.getSerialNumber() == cert.getSerialNumber():
|
||||
return True
|
||||
return False
|
||||
|
||||
def getRevokedCertificate(self, cert):
|
||||
for entry in self._entries:
|
||||
if hasattr(cert, 'getSerialNumber'):
|
||||
if entry.getSerialNumber() == cert.getSerialNumber():
|
||||
return entry
|
||||
return None
|
||||
|
||||
def getRevokedCertificates(self):
|
||||
return self._entries if self._entries else None
|
||||
|
||||
def getCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getNonCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getExtensionValue(self, oid):
|
||||
return None
|
||||
|
||||
def hasUnsupportedCriticalExtension(self):
|
||||
return False
|
||||
|
||||
def toString(self):
|
||||
return f"X509CRL issuer={self._issuer}"
|
||||
|
||||
def addEntry(self, entry):
|
||||
self._entries.append(entry)
|
||||
|
||||
def setIssuer(self, issuer):
|
||||
self._issuer = issuer
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CertPath
|
||||
# ============================================================
|
||||
|
||||
class CertPath(Stub):
|
||||
"""java.security.cert.CertPath"""
|
||||
def __init__(self, algorithm):
|
||||
super().__init__()
|
||||
self._algorithm = algorithm
|
||||
self._certs = []
|
||||
self._encoded = b""
|
||||
|
||||
def getType(self):
|
||||
return self._algorithm
|
||||
|
||||
def getCertificates(self):
|
||||
return self._certs
|
||||
|
||||
def getEncoded(self, encoding=None):
|
||||
return self._encoded
|
||||
|
||||
def getEncodings(self):
|
||||
return ["PKCS7"]
|
||||
|
||||
def toString(self):
|
||||
return f"CertPath: {self._algorithm} [{len(self._certs)} cert(s)]"
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, CertPath):
|
||||
return False
|
||||
return self._algorithm == other._algorithm and self._certs == other._certs
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._algorithm) ^ hash(tuple(self._certs))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CertificateFactory
|
||||
# ============================================================
|
||||
|
||||
class CertificateFactory(Stub):
|
||||
"""java.security.cert.CertificateFactory"""
|
||||
def __init__(self, algorithm):
|
||||
super().__init__()
|
||||
self._algorithm = algorithm
|
||||
|
||||
@staticmethod
|
||||
def getInstance(algorithm, provider=None):
|
||||
return CertificateFactory(algorithm)
|
||||
|
||||
def generateCertificate(self, in_stream):
|
||||
cert = X509Certificate()
|
||||
if hasattr(in_stream, 'read'):
|
||||
data = in_stream.read()
|
||||
cert.setEncoded(data if isinstance(data, bytes) else data.encode())
|
||||
return cert
|
||||
|
||||
def generateCertPath(self, in_stream, encoding=None):
|
||||
return CertPath("X.509")
|
||||
|
||||
def generateCRL(self, in_stream):
|
||||
return X509CRL()
|
||||
|
||||
def getCertPathEncodings(self):
|
||||
return ["PKCS7"]
|
||||
|
||||
def getProvider(self):
|
||||
from .security import Provider
|
||||
return Provider("SUN", 1.0, "Default provider")
|
||||
|
||||
def getType(self):
|
||||
return self._algorithm
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CertPathBuilder / CertPathValidator / CertStore
|
||||
# ============================================================
|
||||
|
||||
class CertPathBuilder(Stub):
|
||||
"""java.security.cert.CertPathBuilder"""
|
||||
def __init__(self, algorithm):
|
||||
super().__init__()
|
||||
self._algorithm = algorithm
|
||||
|
||||
@staticmethod
|
||||
def getInstance(algorithm, provider=None):
|
||||
return CertPathBuilder(algorithm)
|
||||
|
||||
def build(self, params):
|
||||
if not isinstance(params, CertPathParameters):
|
||||
raise CertPathBuilderException("Invalid params")
|
||||
return PKIXCertPathBuilderResult(CertPath("X.509"))
|
||||
|
||||
def getAlgorithm(self):
|
||||
return self._algorithm
|
||||
|
||||
def getProvider(self):
|
||||
from .security import Provider
|
||||
return Provider("SUN", 1.0, "Default provider")
|
||||
|
||||
|
||||
class CertPathValidator(Stub):
|
||||
"""java.security.cert.CertPathValidator"""
|
||||
def __init__(self, algorithm):
|
||||
super().__init__()
|
||||
self._algorithm = algorithm
|
||||
|
||||
@staticmethod
|
||||
def getInstance(algorithm, provider=None):
|
||||
return CertPathValidator(algorithm)
|
||||
|
||||
def validate(self, cert_path, params):
|
||||
if not isinstance(cert_path, CertPath):
|
||||
raise CertPathValidatorException("Invalid cert path")
|
||||
return PKIXCertPathValidatorResult()
|
||||
|
||||
def getAlgorithm(self):
|
||||
return self._algorithm
|
||||
|
||||
def getProvider(self):
|
||||
from .security import Provider
|
||||
return Provider("SUN", 1.0, "Default provider")
|
||||
|
||||
|
||||
class CertStore(Stub):
|
||||
"""java.security.cert.CertStore"""
|
||||
def __init__(self, type_name, params):
|
||||
super().__init__()
|
||||
self._type = type_name
|
||||
self._params = params
|
||||
|
||||
@staticmethod
|
||||
def getInstance(type_name, params, provider=None):
|
||||
return CertStore(type_name, params)
|
||||
|
||||
def getCertificates(self, selector):
|
||||
return []
|
||||
|
||||
def getCRLs(self, selector):
|
||||
return []
|
||||
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def getCertStoreParameters(self):
|
||||
return self._params
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PolicyQualifierInfo
|
||||
# ============================================================
|
||||
|
||||
class PolicyQualifierInfo(Stub):
|
||||
"""java.security.cert.PolicyQualifierInfo"""
|
||||
def __init__(self, encoded):
|
||||
super().__init__()
|
||||
self._encoded = encoded
|
||||
|
||||
def getEncoded(self):
|
||||
return self._encoded
|
||||
|
||||
def getPolicyQualifierId(self):
|
||||
return "1.3.6.1.5.5.7.2.1"
|
||||
|
||||
def getPolicyQualifier(self):
|
||||
return self._encoded
|
||||
|
||||
def toString(self):
|
||||
return f"PolicyQualifierInfo [id={self.getPolicyQualifierId()}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TrustAnchor
|
||||
# ============================================================
|
||||
|
||||
class TrustAnchor(Stub):
|
||||
"""java.security.cert.TrustAnchor"""
|
||||
def __init__(self, ca_cert, ca_name=None, ca_public_key=None, name_constraints=None):
|
||||
super().__init__()
|
||||
self._ca_cert = ca_cert
|
||||
self._ca_name = ca_name
|
||||
self._ca_public_key = ca_public_key
|
||||
self._name_constraints = name_constraints
|
||||
|
||||
def getTrustedCert(self):
|
||||
return self._ca_cert
|
||||
|
||||
def getCAName(self):
|
||||
return self._ca_name
|
||||
|
||||
def getCAPublicKey(self):
|
||||
return self._ca_public_key
|
||||
|
||||
def getNameConstraints(self):
|
||||
return self._name_constraints
|
||||
|
||||
def toString(self):
|
||||
return f"TrustAnchor [CA={self._ca_name}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Extension / X509Extension
|
||||
# ============================================================
|
||||
|
||||
class Extension(Stub):
|
||||
"""java.security.cert.Extension"""
|
||||
def __init__(self, oid="", critical=False, value=b""):
|
||||
super().__init__()
|
||||
self._oid = oid
|
||||
self._critical = critical
|
||||
self._value = value
|
||||
|
||||
def getId(self):
|
||||
return self._oid
|
||||
|
||||
def isCritical(self):
|
||||
return self._critical
|
||||
|
||||
def getValue(self):
|
||||
return self._value
|
||||
|
||||
def getEncoded(self):
|
||||
return self._value
|
||||
|
||||
def toString(self):
|
||||
return f"Extension oid={self._oid} critical={self._critical}"
|
||||
|
||||
|
||||
class X509Extension(Stub):
|
||||
"""java.security.cert.X509Extension"""
|
||||
def hasUnsupportedCriticalExtension(self):
|
||||
return False
|
||||
|
||||
def getCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getNonCriticalExtensionOIDs(self):
|
||||
return []
|
||||
|
||||
def getExtensionValue(self, oid):
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PKIXParameters / PKIXBuilderParameters
|
||||
# ============================================================
|
||||
|
||||
class PKIXParameters(CertPathParameters):
|
||||
"""java.security.cert.PKIXParameters"""
|
||||
def __init__(self, trust_anchors=None):
|
||||
super().__init__()
|
||||
if trust_anchors is not None:
|
||||
if isinstance(trust_anchors, set):
|
||||
self._trust_anchors = trust_anchors
|
||||
else:
|
||||
self._trust_anchors = set(trust_anchors)
|
||||
else:
|
||||
self._trust_anchors = set()
|
||||
self._date = None
|
||||
self._cert_stores = []
|
||||
self._revocation_enabled = True
|
||||
self._explicit_policy_required = False
|
||||
self._policy_mapping_inhibited = False
|
||||
self._any_policy_inhibited = False
|
||||
self._policy_qualifiers_rejected = True
|
||||
self._sig_provider = None
|
||||
self._target_cert_constraints = None
|
||||
self._initial_policies = None
|
||||
self._cert_path_checkers = []
|
||||
self._stores = []
|
||||
|
||||
def getTrustAnchors(self):
|
||||
return self._trust_anchors
|
||||
|
||||
def setTrustAnchors(self, trust_anchors):
|
||||
if isinstance(trust_anchors, set):
|
||||
self._trust_anchors = trust_anchors
|
||||
else:
|
||||
self._trust_anchors = set(trust_anchors)
|
||||
|
||||
def getDate(self):
|
||||
return self._date
|
||||
|
||||
def setDate(self, date):
|
||||
self._date = date
|
||||
|
||||
def addCertStore(self, store):
|
||||
self._cert_stores.append(store)
|
||||
|
||||
def getCertStores(self):
|
||||
return self._cert_stores
|
||||
|
||||
def setCertStores(self, stores):
|
||||
self._cert_stores = list(stores)
|
||||
|
||||
def isRevocationEnabled(self):
|
||||
return self._revocation_enabled
|
||||
|
||||
def setRevocationEnabled(self, enabled):
|
||||
self._revocation_enabled = enabled
|
||||
|
||||
def isExplicitPolicyRequired(self):
|
||||
return self._explicit_policy_required
|
||||
|
||||
def setExplicitPolicyRequired(self, required):
|
||||
self._explicit_policy_required = required
|
||||
|
||||
def isPolicyMappingInhibited(self):
|
||||
return self._policy_mapping_inhibited
|
||||
|
||||
def setPolicyMappingInhibited(self, inhibited):
|
||||
self._policy_mapping_inhibited = inhibited
|
||||
|
||||
def isAnyPolicyInhibited(self):
|
||||
return self._any_policy_inhibited
|
||||
|
||||
def setAnyPolicyInhibited(self, inhibited):
|
||||
self._any_policy_inhibited = inhibited
|
||||
|
||||
def getPolicyQualifiersRejected(self):
|
||||
return self._policy_qualifiers_rejected
|
||||
|
||||
def setPolicyQualifiersRejected(self, rejected):
|
||||
self._policy_qualifiers_rejected = rejected
|
||||
|
||||
def getSigProvider(self):
|
||||
return self._sig_provider
|
||||
|
||||
def setSigProvider(self, provider):
|
||||
self._sig_provider = provider
|
||||
|
||||
def getTargetCertConstraints(self):
|
||||
return self._target_cert_constraints
|
||||
|
||||
def setTargetCertConstraints(self, constraints):
|
||||
self._target_cert_constraints = constraints
|
||||
|
||||
def getInitialPolicies(self):
|
||||
return self._initial_policies
|
||||
|
||||
def setInitialPolicies(self, policies):
|
||||
self._initial_policies = policies
|
||||
|
||||
def addCertPathChecker(self, checker):
|
||||
self._cert_path_checkers.append(checker)
|
||||
|
||||
def getCertPathCheckers(self):
|
||||
return self._cert_path_checkers
|
||||
|
||||
def setCertPathCheckers(self, checkers):
|
||||
self._cert_path_checkers = list(checkers)
|
||||
|
||||
def clone(self):
|
||||
return PKIXParameters(self._trust_anchors)
|
||||
|
||||
def toString(self):
|
||||
return f"PKIXParameters [trust_anchors={len(self._trust_anchors)}]"
|
||||
|
||||
|
||||
class PKIXBuilderParameters(PKIXParameters):
|
||||
"""java.security.cert.PKIXBuilderParameters"""
|
||||
def __init__(self, trust_anchors, target_constraints=None):
|
||||
super().__init__(trust_anchors)
|
||||
self._max_path_length = 5
|
||||
if target_constraints is not None:
|
||||
self.setTargetCertConstraints(target_constraints)
|
||||
|
||||
def getMaxPathLength(self):
|
||||
return self._max_path_length
|
||||
|
||||
def setMaxPathLength(self, length):
|
||||
if length < -1:
|
||||
raise IllegalArgumentException("max path length must be >= -1")
|
||||
self._max_path_length = length
|
||||
|
||||
def toString(self):
|
||||
return f"PKIXBuilderParameters [max_path={self._max_path_length}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PKIXCertPathBuilderResult / PKIXCertPathValidatorResult
|
||||
# ============================================================
|
||||
|
||||
class PKIXCertPathBuilderResult(CertPathBuilderResult):
|
||||
"""java.security.cert.PKIXCertPathBuilderResult"""
|
||||
def __init__(self, cert_path=None, trust_anchor=None, policy_tree=None, subject_public_key=None):
|
||||
super().__init__()
|
||||
self._cert_path = cert_path
|
||||
self._trust_anchor = trust_anchor
|
||||
self._policy_tree = policy_tree
|
||||
self._subject_public_key = subject_public_key
|
||||
|
||||
def getCertPath(self):
|
||||
return self._cert_path
|
||||
|
||||
def getTrustAnchor(self):
|
||||
return self._trust_anchor
|
||||
|
||||
def getPolicyTree(self):
|
||||
return self._policy_tree
|
||||
|
||||
def getPublicKey(self):
|
||||
return self._subject_public_key
|
||||
|
||||
def toString(self):
|
||||
return f"PKIXCertPathBuilderResult [path={self._cert_path}]"
|
||||
|
||||
|
||||
class PKIXCertPathValidatorResult(CertPathValidatorResult):
|
||||
"""java.security.cert.PKIXCertPathValidatorResult"""
|
||||
def __init__(self, trust_anchor=None, policy_tree=None, subject_public_key=None):
|
||||
super().__init__()
|
||||
self._trust_anchor = trust_anchor
|
||||
self._policy_tree = policy_tree
|
||||
self._subject_public_key = subject_public_key
|
||||
|
||||
def getTrustAnchor(self):
|
||||
return self._trust_anchor
|
||||
|
||||
def getPolicyTree(self):
|
||||
return self._policy_tree
|
||||
|
||||
def getPublicKey(self):
|
||||
return self._subject_public_key
|
||||
|
||||
def toString(self):
|
||||
return "PKIXCertPathValidatorResult"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# IllegalArgumentException (local)
|
||||
# ============================================================
|
||||
|
||||
class IllegalArgumentException(RuntimeException):
|
||||
"""java.lang.IllegalArgumentException"""
|
||||
pass
|
||||
@@ -0,0 +1,697 @@
|
||||
"""
|
||||
Java security.spec standard library APIs implemented in Python.
|
||||
java.security.spec package - KeySpec, AlgorithmParameterSpec, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from .security import GeneralSecurityException, InvalidKeySpecException, InvalidParameterException
|
||||
from .lang import RuntimeException
|
||||
import math as _py_math
|
||||
|
||||
__all__ = [
|
||||
"KeySpec", "EncodedKeySpec", "PKCS8EncodedKeySpec", "X509EncodedKeySpec",
|
||||
"DSAPrivateKeySpec", "DSAPublicKeySpec",
|
||||
"RSAPrivateKeySpec", "RSAPublicKeySpec", "RSAPrivateCrtKeySpec",
|
||||
"RSAOtherPrimeInfo",
|
||||
"ECPrivateKeySpec", "ECPublicKeySpec",
|
||||
"ECField", "ECFieldF2m", "ECFieldFp", "EllipticCurve",
|
||||
"ECGenParameterSpec", "ECParameterSpec", "ECPoint",
|
||||
"AlgorithmParameterSpec",
|
||||
"IvParameterSpec", "OAEPParameterSpec", "PSSParameterSpec",
|
||||
"MGF1ParameterSpec", "PBEParameterSpec",
|
||||
"RC2ParameterSpec", "RC5ParameterSpec",
|
||||
"DHParameterSpec", "DHGenParameterSpec",
|
||||
"DHPrivateKeySpec", "DHPublicKeySpec",
|
||||
"DSAGenParameterSpec",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# KeySpec
|
||||
# ============================================================
|
||||
|
||||
class KeySpec(Stub):
|
||||
"""java.security.spec.KeySpec"""
|
||||
pass
|
||||
|
||||
|
||||
class EncodedKeySpec(KeySpec):
|
||||
"""java.security.spec.EncodedKeySpec"""
|
||||
def __init__(self, encoded_key):
|
||||
super().__init__()
|
||||
self._encoded_key = bytes(encoded_key)
|
||||
|
||||
def getEncoded(self):
|
||||
return self._encoded_key
|
||||
|
||||
def getFormat(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class PKCS8EncodedKeySpec(EncodedKeySpec):
|
||||
"""java.security.spec.PKCS8EncodedKeySpec"""
|
||||
def __init__(self, encoded_key):
|
||||
super().__init__(encoded_key)
|
||||
|
||||
def getFormat(self):
|
||||
return "PKCS#8"
|
||||
|
||||
|
||||
class X509EncodedKeySpec(EncodedKeySpec):
|
||||
"""java.security.spec.X509EncodedKeySpec"""
|
||||
def __init__(self, encoded_key):
|
||||
super().__init__(encoded_key)
|
||||
|
||||
def getFormat(self):
|
||||
return "X.509"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# DSA KeySpecs
|
||||
# ============================================================
|
||||
|
||||
class DSAPrivateKeySpec(KeySpec):
|
||||
"""java.security.spec.DSAPrivateKeySpec"""
|
||||
def __init__(self, x, p, q, g):
|
||||
super().__init__()
|
||||
self._x = x
|
||||
self._p = p
|
||||
self._q = q
|
||||
self._g = g
|
||||
|
||||
def getX(self):
|
||||
return self._x
|
||||
|
||||
def getP(self):
|
||||
return self._p
|
||||
|
||||
def getQ(self):
|
||||
return self._q
|
||||
|
||||
def getG(self):
|
||||
return self._g
|
||||
|
||||
|
||||
class DSAPublicKeySpec(KeySpec):
|
||||
"""java.security.spec.DSAPublicKeySpec"""
|
||||
def __init__(self, y, p, q, g):
|
||||
super().__init__()
|
||||
self._y = y
|
||||
self._p = p
|
||||
self._q = q
|
||||
self._g = g
|
||||
|
||||
def getY(self):
|
||||
return self._y
|
||||
|
||||
def getP(self):
|
||||
return self._p
|
||||
|
||||
def getQ(self):
|
||||
return self._q
|
||||
|
||||
def getG(self):
|
||||
return self._g
|
||||
|
||||
|
||||
# ============================================================
|
||||
# RSA KeySpecs
|
||||
# ============================================================
|
||||
|
||||
class RSAPrivateKeySpec(KeySpec):
|
||||
"""java.security.spec.RSAPrivateKeySpec"""
|
||||
def __init__(self, modulus, private_exponent):
|
||||
super().__init__()
|
||||
self._modulus = modulus
|
||||
self._private_exponent = private_exponent
|
||||
|
||||
def getModulus(self):
|
||||
return self._modulus
|
||||
|
||||
def getPrivateExponent(self):
|
||||
return self._private_exponent
|
||||
|
||||
|
||||
class RSAPublicKeySpec(KeySpec):
|
||||
"""java.security.spec.RSAPublicKeySpec"""
|
||||
def __init__(self, modulus, public_exponent):
|
||||
super().__init__()
|
||||
self._modulus = modulus
|
||||
self._public_exponent = public_exponent
|
||||
|
||||
def getModulus(self):
|
||||
return self._modulus
|
||||
|
||||
def getPublicExponent(self):
|
||||
return self._public_exponent
|
||||
|
||||
|
||||
class RSAPrivateCrtKeySpec(RSAPrivateKeySpec):
|
||||
"""java.security.spec.RSAPrivateCrtKeySpec"""
|
||||
def __init__(self, modulus, public_exponent, private_exponent,
|
||||
prime_p, prime_q, prime_exponent_p, prime_exponent_q,
|
||||
crt_coefficient):
|
||||
super().__init__(modulus, private_exponent)
|
||||
self._public_exponent = public_exponent
|
||||
self._prime_p = prime_p
|
||||
self._prime_q = prime_q
|
||||
self._prime_exponent_p = prime_exponent_p
|
||||
self._prime_exponent_q = prime_exponent_q
|
||||
self._crt_coefficient = crt_coefficient
|
||||
|
||||
def getPublicExponent(self):
|
||||
return self._public_exponent
|
||||
|
||||
def getPrimeP(self):
|
||||
return self._prime_p
|
||||
|
||||
def getPrimeQ(self):
|
||||
return self._prime_q
|
||||
|
||||
def getPrimeExponentP(self):
|
||||
return self._prime_exponent_p
|
||||
|
||||
def getPrimeExponentQ(self):
|
||||
return self._prime_exponent_q
|
||||
|
||||
def getCrtCoefficient(self):
|
||||
return self._crt_coefficient
|
||||
|
||||
|
||||
class RSAOtherPrimeInfo(Stub):
|
||||
"""java.security.spec.RSAOtherPrimeInfo"""
|
||||
def __init__(self, prime, exponent, coefficient):
|
||||
super().__init__()
|
||||
self._prime = prime
|
||||
self._exponent = exponent
|
||||
self._coefficient = coefficient
|
||||
|
||||
def getPrime(self):
|
||||
return self._prime
|
||||
|
||||
def getExponent(self):
|
||||
return self._exponent
|
||||
|
||||
def getCrtCoefficient(self):
|
||||
return self._coefficient
|
||||
|
||||
|
||||
# ============================================================
|
||||
# EC KeySpecs
|
||||
# ============================================================
|
||||
|
||||
class ECPoint(Stub):
|
||||
"""java.security.spec.ECPoint"""
|
||||
def __init__(self, affine_x, affine_y):
|
||||
super().__init__()
|
||||
self._affine_x = affine_x
|
||||
self._affine_y = affine_y
|
||||
|
||||
def getAffineX(self):
|
||||
return self._affine_x
|
||||
|
||||
def getAffineY(self):
|
||||
return self._affine_y
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, ECPoint):
|
||||
return False
|
||||
return self._affine_x == other._affine_x and self._affine_y == other._affine_y
|
||||
|
||||
def hashCode(self):
|
||||
return hash((self._affine_x, self._affine_y))
|
||||
|
||||
def toString(self):
|
||||
return f"ECPoint(x={self._affine_x}, y={self._affine_y})"
|
||||
|
||||
POINT_INFINITY = None
|
||||
|
||||
|
||||
class ECField(Stub):
|
||||
"""java.security.spec.ECField"""
|
||||
def getFieldSize(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ECFieldFp(ECField):
|
||||
"""java.security.spec.ECFieldFp"""
|
||||
def __init__(self, prime):
|
||||
super().__init__()
|
||||
self._prime = prime
|
||||
|
||||
def getP(self):
|
||||
return self._prime
|
||||
|
||||
def getFieldSize(self):
|
||||
return self._prime.bit_length()
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, ECFieldFp):
|
||||
return False
|
||||
return self._prime == other._prime
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._prime)
|
||||
|
||||
|
||||
class ECFieldF2m(ECField):
|
||||
"""java.security.spec.ECFieldF2m"""
|
||||
def __init__(self, m, ks=None, rp=None):
|
||||
super().__init__()
|
||||
self._m = m
|
||||
if ks is not None and rp is None:
|
||||
if isinstance(ks, int):
|
||||
self._ks = [ks]
|
||||
self._rp = None
|
||||
else:
|
||||
self._ks = list(ks)
|
||||
self._rp = None
|
||||
elif rp is not None:
|
||||
self._ks = None
|
||||
self._rp = rp
|
||||
else:
|
||||
self._ks = None
|
||||
self._rp = None
|
||||
|
||||
def getM(self):
|
||||
return self._m
|
||||
|
||||
def getKs(self):
|
||||
return self._ks
|
||||
|
||||
def getFieldSize(self):
|
||||
return self._m
|
||||
|
||||
def getReductionPolynomial(self):
|
||||
return self._rp
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, ECFieldF2m):
|
||||
return False
|
||||
return self._m == other._m and self._ks == other._ks and self._rp == other._rp
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._m)
|
||||
|
||||
|
||||
class EllipticCurve(Stub):
|
||||
"""java.security.spec.EllipticCurve"""
|
||||
def __init__(self, field, a, b, seed=None):
|
||||
super().__init__()
|
||||
self._field = field
|
||||
self._a = a
|
||||
self._b = b
|
||||
self._seed = seed
|
||||
|
||||
def getField(self):
|
||||
return self._field
|
||||
|
||||
def getA(self):
|
||||
return self._a
|
||||
|
||||
def getB(self):
|
||||
return self._b
|
||||
|
||||
def getSeed(self):
|
||||
return self._seed
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, EllipticCurve):
|
||||
return False
|
||||
return (self._field == other._field and self._a == other._a
|
||||
and self._b == other._b)
|
||||
|
||||
def hashCode(self):
|
||||
return hash((self._field, self._a, self._b))
|
||||
|
||||
|
||||
class ECParameterSpec(Stub):
|
||||
"""java.security.spec.ECParameterSpec"""
|
||||
def __init__(self, curve, generator, order, cofactor):
|
||||
super().__init__()
|
||||
self._curve = curve
|
||||
self._generator = generator
|
||||
self._order = order
|
||||
self._cofactor = cofactor
|
||||
|
||||
def getCurve(self):
|
||||
return self._curve
|
||||
|
||||
def getGenerator(self):
|
||||
return self._generator
|
||||
|
||||
def getOrder(self):
|
||||
return self._order
|
||||
|
||||
def getCofactor(self):
|
||||
return self._cofactor
|
||||
|
||||
def toString(self):
|
||||
return f"ECParameterSpec [order={self._order}]"
|
||||
|
||||
|
||||
class ECGenParameterSpec(Stub):
|
||||
"""java.security.spec.ECGenParameterSpec"""
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def toString(self):
|
||||
return f"ECGenParameterSpec [name={self._name}]"
|
||||
|
||||
|
||||
class ECPrivateKeySpec(KeySpec):
|
||||
"""java.security.spec.ECPrivateKeySpec"""
|
||||
def __init__(self, s, params):
|
||||
super().__init__()
|
||||
self._s = s
|
||||
self._params = params
|
||||
|
||||
def getS(self):
|
||||
return self._s
|
||||
|
||||
def getParams(self):
|
||||
return self._params
|
||||
|
||||
|
||||
class ECPublicKeySpec(KeySpec):
|
||||
"""java.security.spec.ECPublicKeySpec"""
|
||||
def __init__(self, w, params):
|
||||
super().__init__()
|
||||
self._w = w
|
||||
self._params = params
|
||||
|
||||
def getW(self):
|
||||
return self._w
|
||||
|
||||
def getParams(self):
|
||||
return self._params
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AlgorithmParameterSpec
|
||||
# ============================================================
|
||||
|
||||
class AlgorithmParameterSpec(Stub):
|
||||
"""java.security.spec.AlgorithmParameterSpec"""
|
||||
pass
|
||||
|
||||
|
||||
class IvParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.IvParameterSpec"""
|
||||
def __init__(self, iv, offset=0, length=None):
|
||||
super().__init__()
|
||||
if length is None:
|
||||
self._iv = bytes(iv[offset:])
|
||||
else:
|
||||
self._iv = bytes(iv[offset:offset + length])
|
||||
|
||||
def getIV(self):
|
||||
return self._iv
|
||||
|
||||
|
||||
class OAEPParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.OAEPParameterSpec"""
|
||||
def __init__(self, md_name="SHA-256", mgf_name="MGF1", mgf_spec=None, p_src=None):
|
||||
super().__init__()
|
||||
self._md_name = md_name
|
||||
self._mgf_name = mgf_name
|
||||
self._mgf_spec = mgf_spec or MGF1ParameterSpec.SHA256
|
||||
self._p_src = p_src
|
||||
|
||||
def getDigestAlgorithm(self):
|
||||
return self._md_name
|
||||
|
||||
def getMGFAlgorithm(self):
|
||||
return self._mgf_name
|
||||
|
||||
def getMGFParameters(self):
|
||||
return self._mgf_spec
|
||||
|
||||
def getPSource(self):
|
||||
return self._p_src
|
||||
|
||||
DEFAULT = None
|
||||
|
||||
|
||||
class PSSParameterSpec(AlgorithmParameterSpec):
|
||||
"""java.security.spec.PSSParameterSpec"""
|
||||
def __init__(self, md_name="SHA-256", mgf_name="MGF1", mgf_spec=None,
|
||||
salt_len=None, trailer_field=1):
|
||||
super().__init__()
|
||||
if isinstance(md_name, int):
|
||||
# Legacy constructor: PSSParameterSpec(int saltLen)
|
||||
self._salt_len = md_name
|
||||
self._md_name = "SHA-1"
|
||||
self._mgf_name = "MGF1"
|
||||
self._mgf_spec = MGF1ParameterSpec.SHA1
|
||||
self._trailer_field = 1
|
||||
else:
|
||||
self._md_name = md_name
|
||||
self._mgf_name = mgf_name
|
||||
self._mgf_spec = mgf_spec or MGF1ParameterSpec.SHA256
|
||||
self._salt_len = salt_len if salt_len is not None else 32
|
||||
self._trailer_field = trailer_field
|
||||
|
||||
def getDigestAlgorithm(self):
|
||||
return self._md_name
|
||||
|
||||
def getMGFAlgorithm(self):
|
||||
return self._mgf_name
|
||||
|
||||
def getMGFParameters(self):
|
||||
return self._mgf_spec
|
||||
|
||||
def getSaltLength(self):
|
||||
return self._salt_len
|
||||
|
||||
def getTrailerField(self):
|
||||
return self._trailer_field
|
||||
|
||||
DEFAULT = None
|
||||
TRAILER_FIELD_BC = 1
|
||||
|
||||
|
||||
class MGF1ParameterSpec(AlgorithmParameterSpec):
|
||||
"""java.security.spec.MGF1ParameterSpec"""
|
||||
def __init__(self, md_name):
|
||||
super().__init__()
|
||||
self._md_name = md_name
|
||||
|
||||
def getDigestAlgorithm(self):
|
||||
return self._md_name
|
||||
|
||||
def toString(self):
|
||||
return f"MGF1ParameterSpec [{self._md_name}]"
|
||||
|
||||
SHA1 = None
|
||||
SHA224 = None
|
||||
SHA256 = None
|
||||
SHA384 = None
|
||||
SHA512 = None
|
||||
|
||||
|
||||
class PBEParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.PBEParameterSpec"""
|
||||
def __init__(self, salt, iteration_count):
|
||||
super().__init__()
|
||||
self._salt = bytes(salt)
|
||||
self._iteration_count = iteration_count
|
||||
|
||||
def getSalt(self):
|
||||
return self._salt
|
||||
|
||||
def getIterationCount(self):
|
||||
return self._iteration_count
|
||||
|
||||
|
||||
class RC2ParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.RC2ParameterSpec"""
|
||||
def __init__(self, effective_key_bits, iv=None, offset=0):
|
||||
super().__init__()
|
||||
self._effective_key_bits = effective_key_bits
|
||||
if iv is not None:
|
||||
self._iv = bytes(iv[offset:offset + 8]) if offset + 8 <= len(iv) else bytes(iv[offset:])
|
||||
else:
|
||||
self._iv = None
|
||||
|
||||
def getEffectiveKeyBits(self):
|
||||
return self._effective_key_bits
|
||||
|
||||
def getIV(self):
|
||||
return self._iv
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, RC2ParameterSpec):
|
||||
return False
|
||||
return (self._effective_key_bits == other._effective_key_bits
|
||||
and self._iv == other._iv)
|
||||
|
||||
def hashCode(self):
|
||||
return hash(self._effective_key_bits) ^ hash(self._iv)
|
||||
|
||||
|
||||
class RC5ParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.RC5ParameterSpec"""
|
||||
def __init__(self, version, rounds, word_size, iv=None, offset=0):
|
||||
super().__init__()
|
||||
self._version = version
|
||||
self._rounds = rounds
|
||||
self._word_size = word_size
|
||||
if iv is not None:
|
||||
self._iv = bytes(iv[offset:offset + 8]) if offset + 8 <= len(iv) else bytes(iv[offset:])
|
||||
else:
|
||||
self._iv = None
|
||||
|
||||
def getVersion(self):
|
||||
return self._version
|
||||
|
||||
def getRounds(self):
|
||||
return self._rounds
|
||||
|
||||
def getWordSize(self):
|
||||
return self._word_size
|
||||
|
||||
def getIV(self):
|
||||
return self._iv
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, RC5ParameterSpec):
|
||||
return False
|
||||
return (self._version == other._version and self._rounds == other._rounds
|
||||
and self._word_size == other._word_size and self._iv == other._iv)
|
||||
|
||||
def hashCode(self):
|
||||
return hash((self._version, self._rounds, self._word_size, bytes(self._iv) if self._iv else b""))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# DH (Diffie-Hellman) Specs
|
||||
# ============================================================
|
||||
|
||||
class DHParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.DHParameterSpec"""
|
||||
def __init__(self, p, g, l=0):
|
||||
super().__init__()
|
||||
self._p = p
|
||||
self._g = g
|
||||
self._l = l
|
||||
|
||||
def getP(self):
|
||||
return self._p
|
||||
|
||||
def getG(self):
|
||||
return self._g
|
||||
|
||||
def getL(self):
|
||||
return self._l
|
||||
|
||||
|
||||
class DHGenParameterSpec(AlgorithmParameterSpec):
|
||||
"""javax.crypto.spec.DHGenParameterSpec"""
|
||||
def __init__(self, prime_size, exponent_size):
|
||||
super().__init__()
|
||||
self._prime_size = prime_size
|
||||
self._exponent_size = exponent_size
|
||||
|
||||
def getPrimeSize(self):
|
||||
return self._prime_size
|
||||
|
||||
def getExponentSize(self):
|
||||
return self._exponent_size
|
||||
|
||||
|
||||
class DHPrivateKeySpec(KeySpec):
|
||||
"""javax.crypto.spec.DHPrivateKeySpec"""
|
||||
def __init__(self, x, p, g):
|
||||
super().__init__()
|
||||
self._x = x
|
||||
self._p = p
|
||||
self._g = g
|
||||
|
||||
def getX(self):
|
||||
return self._x
|
||||
|
||||
def getP(self):
|
||||
return self._p
|
||||
|
||||
def getG(self):
|
||||
return self._g
|
||||
|
||||
|
||||
class DHPublicKeySpec(KeySpec):
|
||||
"""javax.crypto.spec.DHPublicKeySpec"""
|
||||
def __init__(self, y, p, g):
|
||||
super().__init__()
|
||||
self._y = y
|
||||
self._p = p
|
||||
self._g = g
|
||||
|
||||
def getY(self):
|
||||
return self._y
|
||||
|
||||
def getP(self):
|
||||
return self._p
|
||||
|
||||
def getG(self):
|
||||
return self._g
|
||||
|
||||
|
||||
# ============================================================
|
||||
# DSAGenParameterSpec
|
||||
# ============================================================
|
||||
|
||||
class DSAGenParameterSpec(AlgorithmParameterSpec):
|
||||
"""java.security.spec.DSAGenParameterSpec"""
|
||||
def __init__(self, prime_pl, subprime_ql, seed_len):
|
||||
super().__init__()
|
||||
self._prime_pl = prime_pl
|
||||
self._subprime_ql = subprime_ql
|
||||
self._seed_len = seed_len
|
||||
|
||||
def getPrimePL(self):
|
||||
return self._prime_pl
|
||||
|
||||
def getSubprimeQL(self):
|
||||
return self._subprime_ql
|
||||
|
||||
def getSeedLen(self):
|
||||
return self._seed_len
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Initialize MGF1ParameterSpec constants
|
||||
# ============================================================
|
||||
|
||||
MGF1ParameterSpec.SHA1 = MGF1ParameterSpec("SHA-1")
|
||||
MGF1ParameterSpec.SHA224 = MGF1ParameterSpec("SHA-224")
|
||||
MGF1ParameterSpec.SHA256 = MGF1ParameterSpec("SHA-256")
|
||||
MGF1ParameterSpec.SHA384 = MGF1ParameterSpec("SHA-384")
|
||||
MGF1ParameterSpec.SHA512 = MGF1ParameterSpec("SHA-512")
|
||||
|
||||
# ============================================================
|
||||
# Initialize OAEPParameterSpec DEFAULT
|
||||
# ============================================================
|
||||
|
||||
OAEPParameterSpec.DEFAULT = OAEPParameterSpec(
|
||||
"SHA-1", "MGF1", MGF1ParameterSpec.SHA1, None
|
||||
)
|
||||
|
||||
# ============================================================
|
||||
# Initialize PSSParameterSpec DEFAULT
|
||||
# ============================================================
|
||||
|
||||
PSSParameterSpec.DEFAULT = PSSParameterSpec(
|
||||
"SHA-1", "MGF1", MGF1ParameterSpec.SHA1, 20, 1
|
||||
)
|
||||
|
||||
# ============================================================
|
||||
# ECPoint.POINT_INFINITY
|
||||
# ============================================================
|
||||
|
||||
ECPoint.POINT_INFINITY = ECPoint(None, None)
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,681 @@
|
||||
"""
|
||||
Java java.util.concurrent.locks standard library APIs implemented in Python.
|
||||
java.util.concurrent.locks package - Lock, ReadWriteLock, ReentrantLock, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from ..java.lang import RuntimeException
|
||||
|
||||
# InterruptedException (桌面模拟)
|
||||
class InterruptedException(RuntimeException):
|
||||
def __init__(self, message=""):
|
||||
super().__init__(message)
|
||||
import threading as _threading
|
||||
import time as _time
|
||||
import collections as _collections
|
||||
|
||||
__all__ = [
|
||||
"Lock", "ReadWriteLock", "ReentrantLock",
|
||||
"ReentrantReadWriteLock",
|
||||
"ReentrantReadWriteLock_ReadLock",
|
||||
"ReentrantReadWriteLock_WriteLock",
|
||||
"Condition", "LockSupport",
|
||||
"AbstractQueuedSynchronizer",
|
||||
"AbstractQueuedLongSynchronizer",
|
||||
"AbstractOwnableSynchronizer",
|
||||
]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Lock interface
|
||||
# ============================================================
|
||||
|
||||
class Lock(Stub):
|
||||
"""java.util.concurrent.locks.Lock"""
|
||||
def lock(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def lockInterruptibly(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def tryLock(self, time_val=None, unit=None):
|
||||
raise NotImplementedError
|
||||
|
||||
def unlock(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def newCondition(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ReadWriteLock(Stub):
|
||||
"""java.util.concurrent.locks.ReadWriteLock"""
|
||||
def readLock(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def writeLock(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ReentrantLock
|
||||
# ============================================================
|
||||
|
||||
class ReentrantLock(Lock):
|
||||
"""java.util.concurrent.locks.ReentrantLock"""
|
||||
def __init__(self, fair=False):
|
||||
super().__init__()
|
||||
self._lock = _threading.RLock()
|
||||
self._fair = fair
|
||||
self._owner = None
|
||||
self._hold_count = 0
|
||||
|
||||
def lock(self):
|
||||
self._lock.acquire()
|
||||
self._owner = _threading.current_thread()
|
||||
self._hold_count += 1
|
||||
|
||||
def lockInterruptibly(self):
|
||||
self.lock()
|
||||
|
||||
def tryLock(self, timeout=None, unit=None):
|
||||
if timeout is None:
|
||||
acquired = self._lock.acquire(blocking=False)
|
||||
else:
|
||||
if unit is not None:
|
||||
timeout = timeout
|
||||
acquired = self._lock.acquire(blocking=True, timeout=timeout)
|
||||
if acquired:
|
||||
self._owner = _threading.current_thread()
|
||||
self._hold_count += 1
|
||||
return True
|
||||
return False
|
||||
|
||||
def unlock(self):
|
||||
self._hold_count -= 1
|
||||
if self._hold_count == 0:
|
||||
self._owner = None
|
||||
self._lock.release()
|
||||
|
||||
def newCondition(self):
|
||||
return Condition(self)
|
||||
|
||||
def getHoldCount(self):
|
||||
return self._hold_count
|
||||
|
||||
def isHeldByCurrentThread(self):
|
||||
return self._owner is _threading.current_thread()
|
||||
|
||||
def isLocked(self):
|
||||
return self._owner is not None
|
||||
|
||||
def isFair(self):
|
||||
return self._fair
|
||||
|
||||
def getOwner(self):
|
||||
return self._owner
|
||||
|
||||
def getQueuedThreads(self):
|
||||
return []
|
||||
|
||||
def getQueueLength(self):
|
||||
return 0
|
||||
|
||||
def hasQueuedThreads(self):
|
||||
return False
|
||||
|
||||
def hasQueuedThread(self, thread):
|
||||
return False
|
||||
|
||||
def toString(self):
|
||||
status = "Locked" if self.isLocked() else "Unlocked"
|
||||
return f"ReentrantLock[{status}, hold={self._hold_count}]"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ReentrantReadWriteLock
|
||||
# ============================================================
|
||||
|
||||
class ReentrantReadWriteLock(ReadWriteLock):
|
||||
"""java.util.concurrent.locks.ReentrantReadWriteLock"""
|
||||
def __init__(self, fair=False):
|
||||
super().__init__()
|
||||
self._fair = fair
|
||||
self._read_lock = ReentrantReadWriteLock_ReadLock(self)
|
||||
self._write_lock = ReentrantReadWriteLock_WriteLock(self)
|
||||
self._read_hold_count = 0
|
||||
self._write_hold_count = 0
|
||||
self._write_owner = None
|
||||
self._lock = _threading.RLock()
|
||||
self._read_lock_obj = _threading.Lock()
|
||||
self._read_cond = _threading.Condition(self._read_lock_obj)
|
||||
self._readers = 0
|
||||
self._writers_waiting = 0
|
||||
|
||||
def readLock(self):
|
||||
return self._read_lock
|
||||
|
||||
def writeLock(self):
|
||||
return self._write_lock
|
||||
|
||||
def isFair(self):
|
||||
return self._fair
|
||||
|
||||
def getReadLockCount(self):
|
||||
return self._readers
|
||||
|
||||
def isWriteLocked(self):
|
||||
return self._write_owner is not None
|
||||
|
||||
def isWriteLockedByCurrentThread(self):
|
||||
return self._write_owner is _threading.current_thread()
|
||||
|
||||
def getWriteHoldCount(self):
|
||||
return self._write_hold_count
|
||||
|
||||
def getReadHoldCount(self):
|
||||
return self._read_hold_count
|
||||
|
||||
def getOwner(self):
|
||||
return self._write_owner
|
||||
|
||||
def getQueuedWriterThreads(self):
|
||||
return []
|
||||
|
||||
def getQueuedReaderThreads(self):
|
||||
return []
|
||||
|
||||
def getQueueLength(self):
|
||||
return 0
|
||||
|
||||
def hasQueuedThreads(self):
|
||||
return False
|
||||
|
||||
def hasQueuedThread(self, thread):
|
||||
return False
|
||||
|
||||
def toString(self):
|
||||
w = self._write_hold_count
|
||||
r = self._readers
|
||||
return f"ReentrantReadWriteLock[read_locks={r}, write_locks={w}]"
|
||||
|
||||
def _acquire_read(self):
|
||||
with self._lock:
|
||||
while self._write_owner is not None and self._write_owner != _threading.current_thread():
|
||||
self._read_cond.wait()
|
||||
self._readers += 1
|
||||
self._read_hold_count += 1
|
||||
|
||||
def _release_read(self):
|
||||
with self._lock:
|
||||
self._readers -= 1
|
||||
self._read_hold_count -= 1
|
||||
if self._readers == 0:
|
||||
self._read_cond.notify_all()
|
||||
|
||||
def _acquire_write(self):
|
||||
self._lock.acquire()
|
||||
self._write_owner = _threading.current_thread()
|
||||
self._write_hold_count += 1
|
||||
|
||||
def _release_write(self):
|
||||
self._write_hold_count -= 1
|
||||
if self._write_hold_count == 0:
|
||||
self._write_owner = None
|
||||
self._read_cond.notify_all()
|
||||
self._lock.release()
|
||||
|
||||
|
||||
class ReentrantReadWriteLock_ReadLock(Lock):
|
||||
"""java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock"""
|
||||
def __init__(self, rw_lock):
|
||||
super().__init__()
|
||||
self._rw_lock = rw_lock
|
||||
|
||||
def lock(self):
|
||||
self._rw_lock._acquire_read()
|
||||
|
||||
def lockInterruptibly(self):
|
||||
self.lock()
|
||||
|
||||
def tryLock(self, timeout=None, unit=None):
|
||||
self.lock()
|
||||
return True
|
||||
|
||||
def unlock(self):
|
||||
self._rw_lock._release_read()
|
||||
|
||||
def newCondition(self):
|
||||
raise UnsupportedOperationException("Read locks do not support Condition")
|
||||
|
||||
|
||||
class ReentrantReadWriteLock_WriteLock(Lock):
|
||||
"""java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock"""
|
||||
def __init__(self, rw_lock):
|
||||
super().__init__()
|
||||
self._rw_lock = rw_lock
|
||||
|
||||
def lock(self):
|
||||
self._rw_lock._acquire_write()
|
||||
|
||||
def lockInterruptibly(self):
|
||||
self.lock()
|
||||
|
||||
def tryLock(self, timeout=None, unit=None):
|
||||
if timeout is None:
|
||||
acquired = self._rw_lock._lock.acquire(blocking=False)
|
||||
else:
|
||||
acquired = self._rw_lock._lock.acquire(blocking=True, timeout=timeout)
|
||||
if acquired:
|
||||
self._rw_lock._write_owner = _threading.current_thread()
|
||||
self._rw_lock._write_hold_count += 1
|
||||
return True
|
||||
return False
|
||||
|
||||
def unlock(self):
|
||||
self._rw_lock._release_write()
|
||||
|
||||
def newCondition(self):
|
||||
return Condition(self)
|
||||
|
||||
def isHeldByCurrentThread(self):
|
||||
return self._rw_lock._write_owner is _threading.current_thread()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Condition
|
||||
# ============================================================
|
||||
|
||||
class Condition(Stub):
|
||||
"""java.util.concurrent.locks.Condition"""
|
||||
def __init__(self, lock=None):
|
||||
super().__init__()
|
||||
self._lock = lock
|
||||
self._cond = _threading.Condition(_threading.RLock()) if lock is None else _threading.Condition()
|
||||
|
||||
def await_signal(self, time_val=None, unit=None):
|
||||
self._cond.acquire()
|
||||
try:
|
||||
if time_val is None:
|
||||
self._cond.wait()
|
||||
return True
|
||||
else:
|
||||
if unit is not None:
|
||||
secs = time_val / 1000.0 # milliseconds
|
||||
else:
|
||||
secs = float(time_val)
|
||||
self._cond.wait(timeout=secs)
|
||||
return True
|
||||
finally:
|
||||
self._cond.release()
|
||||
|
||||
def awaitUninterruptibly(self):
|
||||
self.await_signal()
|
||||
|
||||
def awaitNanos(self, nanos_timeout):
|
||||
self.await_signal(nanos_timeout / 1000000.0)
|
||||
return 0
|
||||
|
||||
def awaitUntil(self, deadline):
|
||||
now = _time.time()
|
||||
diff = deadline - now
|
||||
if diff > 0:
|
||||
self.await_signal(diff)
|
||||
return True
|
||||
|
||||
def signal(self):
|
||||
self._cond.acquire()
|
||||
try:
|
||||
self._cond.notify()
|
||||
finally:
|
||||
self._cond.release()
|
||||
|
||||
def signalAll(self):
|
||||
self._cond.acquire()
|
||||
try:
|
||||
self._cond.notify_all()
|
||||
finally:
|
||||
self._cond.release()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LockSupport
|
||||
# ============================================================
|
||||
|
||||
class LockSupport(Stub):
|
||||
"""java.util.concurrent.locks.LockSupport"""
|
||||
_blocked = {}
|
||||
|
||||
@staticmethod
|
||||
def park(blocker=None):
|
||||
if blocker is not None:
|
||||
LockSupport._blocked[_threading.current_thread().ident] = blocker
|
||||
_time.sleep(0.01)
|
||||
if blocker is not None:
|
||||
del LockSupport._blocked[_threading.current_thread().ident]
|
||||
|
||||
@staticmethod
|
||||
def parkNanos(nanos, blocker=None):
|
||||
if blocker is not None:
|
||||
LockSupport._blocked[_threading.current_thread().ident] = blocker
|
||||
_time.sleep(nanos / 1000000000.0)
|
||||
if blocker is not None:
|
||||
del LockSupport._blocked[_threading.current_thread().ident]
|
||||
|
||||
@staticmethod
|
||||
def parkUntil(deadline, blocker=None):
|
||||
now = _time.time()
|
||||
diff = deadline - now
|
||||
if diff > 0:
|
||||
if blocker is not None:
|
||||
LockSupport._blocked[_threading.current_thread().ident] = blocker
|
||||
_time.sleep(diff)
|
||||
if blocker is not None:
|
||||
del LockSupport._blocked[_threading.current_thread().ident]
|
||||
|
||||
@staticmethod
|
||||
def unpark(thread):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def getBlocker(thread):
|
||||
return LockSupport._blocked.get(thread.ident)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AbstractOwnableSynchronizer
|
||||
# ============================================================
|
||||
|
||||
class AbstractOwnableSynchronizer(Stub):
|
||||
"""java.util.concurrent.locks.AbstractOwnableSynchronizer"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._exclusive_owner_thread = None
|
||||
|
||||
def setExclusiveOwnerThread(self, thread):
|
||||
self._exclusive_owner_thread = thread
|
||||
|
||||
def getExclusiveOwnerThread(self):
|
||||
return self._exclusive_owner_thread
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AbstractQueuedSynchronizer
|
||||
# ============================================================
|
||||
|
||||
class AbstractQueuedSynchronizer(AbstractOwnableSynchronizer):
|
||||
"""java.util.concurrent.locks.AbstractQueuedSynchronizer"""
|
||||
class ConditionObject(Condition):
|
||||
def __init__(self, sync):
|
||||
super().__init__()
|
||||
self._sync = sync
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._state = 0
|
||||
self._lock = _threading.Lock()
|
||||
self._cond = _threading.Condition(self._lock)
|
||||
self._head = None
|
||||
self._tail = None
|
||||
self._wait_queue = _collections.deque()
|
||||
|
||||
def getState(self):
|
||||
with self._lock:
|
||||
return self._state
|
||||
|
||||
def setState(self, new_state):
|
||||
with self._lock:
|
||||
self._state = new_state
|
||||
|
||||
def compareAndSetState(self, expect, update):
|
||||
with self._lock:
|
||||
if self._state == expect:
|
||||
self._state = int(update)
|
||||
return True
|
||||
return False
|
||||
|
||||
def acquire(self, arg):
|
||||
if not self.tryAcquire(arg):
|
||||
self._acquire_queued(self._add_waiter(), arg)
|
||||
|
||||
def acquireInterruptibly(self, arg):
|
||||
self.acquire(arg)
|
||||
|
||||
def tryAcquireNanos(self, arg, nanos_timeout):
|
||||
return self.tryAcquire(arg)
|
||||
|
||||
def release(self, arg):
|
||||
if self.tryRelease(arg):
|
||||
self._signal_next()
|
||||
return True
|
||||
return False
|
||||
|
||||
def acquireShared(self, arg):
|
||||
if self.tryAcquireShared(arg) < 0:
|
||||
self._acquire_shared_queued(self._add_waiter(), arg)
|
||||
|
||||
def acquireSharedInterruptibly(self, arg):
|
||||
self.acquireShared(arg)
|
||||
|
||||
def tryAcquireSharedNanos(self, arg, nanos_timeout):
|
||||
return self.tryAcquireShared(arg) >= 0
|
||||
|
||||
def releaseShared(self, arg):
|
||||
if self.tryReleaseShared(arg):
|
||||
self._signal_next()
|
||||
return True
|
||||
return False
|
||||
|
||||
def tryAcquire(self, arg):
|
||||
raise NotImplementedError
|
||||
|
||||
def tryRelease(self, arg):
|
||||
raise NotImplementedError
|
||||
|
||||
def tryAcquireShared(self, arg):
|
||||
return 1
|
||||
|
||||
def tryReleaseShared(self, arg):
|
||||
return True
|
||||
|
||||
def isHeldExclusively(self):
|
||||
return self.getExclusiveOwnerThread() is _threading.current_thread()
|
||||
|
||||
def getQueuedThreads(self):
|
||||
return list(self._wait_queue)
|
||||
|
||||
def getQueueLength(self):
|
||||
return len(self._wait_queue)
|
||||
|
||||
def hasQueuedThreads(self):
|
||||
return len(self._wait_queue) > 0
|
||||
|
||||
def hasContended(self):
|
||||
return len(self._wait_queue) > 0
|
||||
|
||||
def getFirstQueuedThread(self):
|
||||
if self._wait_queue:
|
||||
return self._wait_queue[0]
|
||||
return None
|
||||
|
||||
def owns(self, condition):
|
||||
return isinstance(condition, AbstractQueuedSynchronizer.ConditionObject)
|
||||
|
||||
def hasWaiters(self, condition):
|
||||
return False
|
||||
|
||||
def getWaitQueueLength(self, condition):
|
||||
return 0
|
||||
|
||||
def getWaitingThreads(self, condition):
|
||||
return []
|
||||
|
||||
def toString(self):
|
||||
return f"AbstractQueuedSynchronizer[state={self._state}]"
|
||||
|
||||
def _add_waiter(self):
|
||||
thread = _threading.current_thread()
|
||||
with self._lock:
|
||||
self._wait_queue.append(thread)
|
||||
return thread
|
||||
|
||||
def _acquire_queued(self, node, arg):
|
||||
while True:
|
||||
if self.tryAcquire(arg):
|
||||
with self._lock:
|
||||
if node in self._wait_queue:
|
||||
self._wait_queue.remove(node)
|
||||
return
|
||||
_time.sleep(0.001)
|
||||
|
||||
def _acquire_shared_queued(self, node, arg):
|
||||
while True:
|
||||
if self.tryAcquireShared(arg) >= 0:
|
||||
with self._lock:
|
||||
if node in self._wait_queue:
|
||||
self._wait_queue.remove(node)
|
||||
return
|
||||
_time.sleep(0.001)
|
||||
|
||||
def _signal_next(self):
|
||||
with self._lock:
|
||||
if self._wait_queue:
|
||||
self._cond.notify()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AbstractQueuedLongSynchronizer
|
||||
# ============================================================
|
||||
|
||||
class AbstractQueuedLongSynchronizer(AbstractOwnableSynchronizer):
|
||||
"""java.util.concurrent.locks.AbstractQueuedLongSynchronizer"""
|
||||
class ConditionObject(Condition):
|
||||
def __init__(self, sync):
|
||||
super().__init__()
|
||||
self._sync = sync
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._state = 0
|
||||
self._lock = _threading.Lock()
|
||||
self._cond = _threading.Condition(self._lock)
|
||||
self._wait_queue = _collections.deque()
|
||||
|
||||
def getState(self):
|
||||
with self._lock:
|
||||
return self._state
|
||||
|
||||
def setState(self, new_state):
|
||||
with self._lock:
|
||||
self._state = int(new_state)
|
||||
|
||||
def compareAndSetState(self, expect, update):
|
||||
with self._lock:
|
||||
if self._state == expect:
|
||||
self._state = int(update)
|
||||
return True
|
||||
return False
|
||||
|
||||
def acquire(self, arg):
|
||||
if not self.tryAcquire(arg):
|
||||
self._acquire_queued(self._add_waiter(), arg)
|
||||
|
||||
def acquireInterruptibly(self, arg):
|
||||
self.acquire(arg)
|
||||
|
||||
def tryAcquireNanos(self, arg, nanos_timeout):
|
||||
return self.tryAcquire(arg)
|
||||
|
||||
def release(self, arg):
|
||||
if self.tryRelease(arg):
|
||||
self._signal_next()
|
||||
return True
|
||||
return False
|
||||
|
||||
def acquireShared(self, arg):
|
||||
if self.tryAcquireShared(arg) < 0:
|
||||
self._acquire_shared_queued(self._add_waiter(), arg)
|
||||
|
||||
def acquireSharedInterruptibly(self, arg):
|
||||
self.acquireShared(arg)
|
||||
|
||||
def tryAcquireSharedNanos(self, arg, nanos_timeout):
|
||||
return self.tryAcquireShared(arg) >= 0
|
||||
|
||||
def releaseShared(self, arg):
|
||||
if self.tryReleaseShared(arg):
|
||||
self._signal_next()
|
||||
return True
|
||||
return False
|
||||
|
||||
def tryAcquire(self, arg):
|
||||
raise NotImplementedError
|
||||
|
||||
def tryRelease(self, arg):
|
||||
raise NotImplementedError
|
||||
|
||||
def tryAcquireShared(self, arg):
|
||||
return 1
|
||||
|
||||
def tryReleaseShared(self, arg):
|
||||
return True
|
||||
|
||||
def isHeldExclusively(self):
|
||||
return self.getExclusiveOwnerThread() is _threading.current_thread()
|
||||
|
||||
def getQueuedThreads(self):
|
||||
return list(self._wait_queue)
|
||||
|
||||
def getQueueLength(self):
|
||||
return len(self._wait_queue)
|
||||
|
||||
def hasQueuedThreads(self):
|
||||
return len(self._wait_queue) > 0
|
||||
|
||||
def getFirstQueuedThread(self):
|
||||
if self._wait_queue:
|
||||
return self._wait_queue[0]
|
||||
return None
|
||||
|
||||
def toString(self):
|
||||
return f"AbstractQueuedLongSynchronizer[state={self._state}]"
|
||||
|
||||
def _add_waiter(self):
|
||||
thread = _threading.current_thread()
|
||||
with self._lock:
|
||||
self._wait_queue.append(thread)
|
||||
return thread
|
||||
|
||||
def _acquire_queued(self, node, arg):
|
||||
while True:
|
||||
if self.tryAcquire(arg):
|
||||
with self._lock:
|
||||
if node in self._wait_queue:
|
||||
self._wait_queue.remove(node)
|
||||
return
|
||||
_time.sleep(0.001)
|
||||
|
||||
def _acquire_shared_queued(self, node, arg):
|
||||
while True:
|
||||
if self.tryAcquireShared(arg) >= 0:
|
||||
with self._lock:
|
||||
if node in self._wait_queue:
|
||||
self._wait_queue.remove(node)
|
||||
return
|
||||
_time.sleep(0.001)
|
||||
|
||||
def _signal_next(self):
|
||||
with self._lock:
|
||||
if self._wait_queue:
|
||||
self._cond.notify()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# UnsupportedOperationException
|
||||
# ============================================================
|
||||
|
||||
class UnsupportedOperationException(RuntimeException):
|
||||
"""java.lang.UnsupportedOperationException"""
|
||||
pass
|
||||
@@ -0,0 +1,599 @@
|
||||
"""
|
||||
Java java.util.function standard library APIs implemented in Python.
|
||||
java.util.function package - Function, Consumer, Predicate, Supplier, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from .lang import RuntimeException
|
||||
import typing as _typing
|
||||
|
||||
__all__ = [
|
||||
"BiConsumer", "BiFunction", "BiPredicate", "BinaryOperator",
|
||||
"Consumer", "DoubleBinaryOperator", "DoubleConsumer",
|
||||
"DoubleFunction", "DoublePredicate", "DoubleSupplier",
|
||||
"DoubleToIntFunction", "DoubleToLongFunction",
|
||||
"Function", "IntBinaryOperator", "IntConsumer",
|
||||
"IntFunction", "IntPredicate", "IntSupplier",
|
||||
"IntToDoubleFunction", "IntToLongFunction",
|
||||
"LongBinaryOperator", "LongConsumer", "LongFunction",
|
||||
"LongPredicate", "LongSupplier", "LongToDoubleFunction",
|
||||
"LongToIntFunction",
|
||||
"ObjDoubleConsumer", "ObjIntConsumer", "ObjLongConsumer",
|
||||
"Predicate", "Supplier",
|
||||
"ToDoubleBiFunction", "ToDoubleFunction",
|
||||
"ToIntBiFunction", "ToIntFunction",
|
||||
"ToLongBiFunction", "ToLongFunction",
|
||||
"UnaryOperator",
|
||||
]
|
||||
|
||||
T = _typing.TypeVar("T")
|
||||
R = _typing.TypeVar("R")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Core functional interfaces
|
||||
# ============================================================
|
||||
|
||||
class Function(Stub):
|
||||
"""java.util.function.Function"""
|
||||
def apply(self, t):
|
||||
raise NotImplementedError
|
||||
|
||||
def compose(self, before):
|
||||
class Composed(Function):
|
||||
def apply(self, t):
|
||||
return self.apply(before.apply(t))
|
||||
return Composed()
|
||||
|
||||
def andThen(self, after):
|
||||
class ComposedAndThen(Function):
|
||||
def apply(self, t):
|
||||
return after.apply(self.apply(t))
|
||||
return ComposedAndThen()
|
||||
|
||||
@staticmethod
|
||||
def identity():
|
||||
class Identity(Function):
|
||||
def apply(self, t):
|
||||
return t
|
||||
return Identity()
|
||||
|
||||
|
||||
class BiFunction(Stub):
|
||||
"""java.util.function.BiFunction"""
|
||||
def apply(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(BiFunction):
|
||||
def apply(self, t, u):
|
||||
return after.apply(self.apply(t, u))
|
||||
return Composed()
|
||||
|
||||
|
||||
class UnaryOperator(Function):
|
||||
"""java.util.function.UnaryOperator"""
|
||||
@staticmethod
|
||||
def identity():
|
||||
class Identity(UnaryOperator):
|
||||
def apply(self, t):
|
||||
return t
|
||||
return Identity()
|
||||
|
||||
|
||||
class BinaryOperator(BiFunction):
|
||||
"""java.util.function.BinaryOperator"""
|
||||
@staticmethod
|
||||
def min_by(comparator):
|
||||
class MinBy(BinaryOperator):
|
||||
def apply(self, a, b):
|
||||
return a if comparator.compare(a, b) <= 0 else b
|
||||
return MinBy()
|
||||
|
||||
@staticmethod
|
||||
def max_by(comparator):
|
||||
class MaxBy(BinaryOperator):
|
||||
def apply(self, a, b):
|
||||
return a if comparator.compare(a, b) >= 0 else b
|
||||
return MaxBy()
|
||||
|
||||
|
||||
class Predicate(Stub):
|
||||
"""java.util.function.Predicate"""
|
||||
def test(self, t):
|
||||
raise NotImplementedError
|
||||
|
||||
def and_(self, other):
|
||||
class And(Predicate):
|
||||
def test(self, t):
|
||||
return self.test(t) and other.test(t)
|
||||
return And()
|
||||
|
||||
def negate(self):
|
||||
class Negate(Predicate):
|
||||
def test(self, t):
|
||||
return not self.test(t)
|
||||
return Negate()
|
||||
|
||||
def or_(self, other):
|
||||
class Or(Predicate):
|
||||
def test(self, t):
|
||||
return self.test(t) or other.test(t)
|
||||
return Or()
|
||||
|
||||
@staticmethod
|
||||
def is_equal(target_ref):
|
||||
class IsEqual(Predicate):
|
||||
def test(self, t):
|
||||
return t == target_ref
|
||||
return IsEqual()
|
||||
|
||||
@staticmethod
|
||||
def not_(target):
|
||||
class Not(Predicate):
|
||||
def test(self, t):
|
||||
return not target.test(t)
|
||||
return Not()
|
||||
|
||||
|
||||
class BiPredicate(Stub):
|
||||
"""java.util.function.BiPredicate"""
|
||||
def test(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
def and_(self, other):
|
||||
class And(BiPredicate):
|
||||
def test(self, t, u):
|
||||
return self.test(t, u) and other.test(t, u)
|
||||
return And()
|
||||
|
||||
def negate(self):
|
||||
class Negate(BiPredicate):
|
||||
def test(self, t, u):
|
||||
return not self.test(t, u)
|
||||
return Negate()
|
||||
|
||||
def or_(self, other):
|
||||
class Or(BiPredicate):
|
||||
def test(self, t, u):
|
||||
return self.test(t, u) or other.test(t, u)
|
||||
return Or()
|
||||
|
||||
|
||||
class Consumer(Stub):
|
||||
"""java.util.function.Consumer"""
|
||||
def accept(self, t):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(Consumer):
|
||||
def accept(self, t):
|
||||
self.accept(t)
|
||||
after.accept(t)
|
||||
return Composed()
|
||||
|
||||
|
||||
class BiConsumer(Stub):
|
||||
"""java.util.function.BiConsumer"""
|
||||
def accept(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(BiConsumer):
|
||||
def accept(self, t, u):
|
||||
self.accept(t, u)
|
||||
after.accept(t, u)
|
||||
return Composed()
|
||||
|
||||
|
||||
class Supplier(Stub):
|
||||
"""java.util.function.Supplier"""
|
||||
def get(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Primitive specializations
|
||||
# ============================================================
|
||||
|
||||
class IntFunction(Stub):
|
||||
"""java.util.function.IntFunction"""
|
||||
def apply(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LongFunction(Stub):
|
||||
"""java.util.function.LongFunction"""
|
||||
def apply(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DoubleFunction(Stub):
|
||||
"""java.util.function.DoubleFunction"""
|
||||
def apply(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IntConsumer(Stub):
|
||||
"""java.util.function.IntConsumer"""
|
||||
def accept(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(IntConsumer):
|
||||
def accept(self, value):
|
||||
self.accept(value)
|
||||
after.accept(value)
|
||||
return Composed()
|
||||
|
||||
|
||||
class LongConsumer(Stub):
|
||||
"""java.util.function.LongConsumer"""
|
||||
def accept(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(LongConsumer):
|
||||
def accept(self, value):
|
||||
self.accept(value)
|
||||
after.accept(value)
|
||||
return Composed()
|
||||
|
||||
|
||||
class DoubleConsumer(Stub):
|
||||
"""java.util.function.DoubleConsumer"""
|
||||
def accept(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def andThen(self, after):
|
||||
class Composed(DoubleConsumer):
|
||||
def accept(self, value):
|
||||
self.accept(value)
|
||||
after.accept(value)
|
||||
return Composed()
|
||||
|
||||
|
||||
class IntPredicate(Stub):
|
||||
"""java.util.function.IntPredicate"""
|
||||
def test(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def and_(self, other):
|
||||
class And(IntPredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) and other.test(value)
|
||||
return And()
|
||||
|
||||
def negate(self):
|
||||
class Negate(IntPredicate):
|
||||
def test(self, value):
|
||||
return not self.test(value)
|
||||
return Negate()
|
||||
|
||||
def or_(self, other):
|
||||
class Or(IntPredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) or other.test(value)
|
||||
return Or()
|
||||
|
||||
|
||||
class LongPredicate(Stub):
|
||||
"""java.util.function.LongPredicate"""
|
||||
def test(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def and_(self, other):
|
||||
class And(LongPredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) and other.test(value)
|
||||
return And()
|
||||
|
||||
def negate(self):
|
||||
class Negate(LongPredicate):
|
||||
def test(self, value):
|
||||
return not self.test(value)
|
||||
return Negate()
|
||||
|
||||
def or_(self, other):
|
||||
class Or(LongPredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) or other.test(value)
|
||||
return Or()
|
||||
|
||||
|
||||
class DoublePredicate(Stub):
|
||||
"""java.util.function.DoublePredicate"""
|
||||
def test(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
def and_(self, other):
|
||||
class And(DoublePredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) and other.test(value)
|
||||
return And()
|
||||
|
||||
def negate(self):
|
||||
class Negate(DoublePredicate):
|
||||
def test(self, value):
|
||||
return not self.test(value)
|
||||
return Negate()
|
||||
|
||||
def or_(self, other):
|
||||
class Or(DoublePredicate):
|
||||
def test(self, value):
|
||||
return self.test(value) or other.test(value)
|
||||
return Or()
|
||||
|
||||
|
||||
class IntSupplier(Stub):
|
||||
"""java.util.function.IntSupplier"""
|
||||
def getAsInt(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LongSupplier(Stub):
|
||||
"""java.util.function.LongSupplier"""
|
||||
def getAsLong(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DoubleSupplier(Stub):
|
||||
"""java.util.function.DoubleSupplier"""
|
||||
def getAsDouble(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IntBinaryOperator(Stub):
|
||||
"""java.util.function.IntBinaryOperator"""
|
||||
def applyAsInt(self, left, right):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LongBinaryOperator(Stub):
|
||||
"""java.util.function.LongBinaryOperator"""
|
||||
def applyAsLong(self, left, right):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DoubleBinaryOperator(Stub):
|
||||
"""java.util.function.DoubleBinaryOperator"""
|
||||
def applyAsDouble(self, left, right):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Int-Unary conversion functions
|
||||
# ============================================================
|
||||
|
||||
class IntToDoubleFunction(Stub):
|
||||
"""java.util.function.IntToDoubleFunction"""
|
||||
def applyAsDouble(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IntToLongFunction(Stub):
|
||||
"""java.util.function.IntToLongFunction"""
|
||||
def applyAsLong(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LongToDoubleFunction(Stub):
|
||||
"""java.util.function.LongToDoubleFunction"""
|
||||
def applyAsDouble(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LongToIntFunction(Stub):
|
||||
"""java.util.function.LongToIntFunction"""
|
||||
def applyAsInt(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DoubleToIntFunction(Stub):
|
||||
"""java.util.function.DoubleToIntFunction"""
|
||||
def applyAsInt(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DoubleToLongFunction(Stub):
|
||||
"""java.util.function.DoubleToLongFunction"""
|
||||
def applyAsLong(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Obj*Consumer (mix of object and primitive)
|
||||
# ============================================================
|
||||
|
||||
class ObjIntConsumer(Stub):
|
||||
"""java.util.function.ObjIntConsumer"""
|
||||
def accept(self, t, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ObjLongConsumer(Stub):
|
||||
"""java.util.function.ObjLongConsumer"""
|
||||
def accept(self, t, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ObjDoubleConsumer(Stub):
|
||||
"""java.util.function.ObjDoubleConsumer"""
|
||||
def accept(self, t, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# To* functions
|
||||
# ============================================================
|
||||
|
||||
class ToIntFunction(Stub):
|
||||
"""java.util.function.ToIntFunction"""
|
||||
def applyAsInt(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ToLongFunction(Stub):
|
||||
"""java.util.function.ToLongFunction"""
|
||||
def applyAsLong(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ToDoubleFunction(Stub):
|
||||
"""java.util.function.ToDoubleFunction"""
|
||||
def applyAsDouble(self, value):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ToIntBiFunction(Stub):
|
||||
"""java.util.function.ToIntBiFunction"""
|
||||
def applyAsInt(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ToLongBiFunction(Stub):
|
||||
"""java.util.function.ToLongBiFunction"""
|
||||
def applyAsLong(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ToDoubleBiFunction(Stub):
|
||||
"""java.util.function.ToDoubleBiFunction"""
|
||||
def applyAsDouble(self, t, u):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Convenience wrapper helpers
|
||||
# ============================================================
|
||||
|
||||
class _FunctionWrapper(Function):
|
||||
"""Wraps a Python callable as a java.util.function.Function"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def apply(self, t):
|
||||
return self._fn(t)
|
||||
|
||||
|
||||
class _ConsumerWrapper(Consumer):
|
||||
"""Wraps a Python callable as a java.util.function.Consumer"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def accept(self, t):
|
||||
self._fn(t)
|
||||
|
||||
|
||||
class _PredicateWrapper(Predicate):
|
||||
"""Wraps a Python callable as a java.util.function.Predicate"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def test(self, t):
|
||||
return self._fn(t)
|
||||
|
||||
|
||||
class _SupplierWrapper(Supplier):
|
||||
"""Wraps a Python callable as a java.util.function.Supplier"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def get(self):
|
||||
return self._fn()
|
||||
|
||||
|
||||
class _BiFunctionWrapper(BiFunction):
|
||||
"""Wraps a Python callable as a java.util.function.BiFunction"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def apply(self, t, u):
|
||||
return self._fn(t, u)
|
||||
|
||||
|
||||
class _BiConsumerWrapper(BiConsumer):
|
||||
"""Wraps a Python callable as a java.util.function.BiConsumer"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def accept(self, t, u):
|
||||
self._fn(t, u)
|
||||
|
||||
|
||||
class _BiPredicateWrapper(BiPredicate):
|
||||
"""Wraps a Python callable as a java.util.function.BiPredicate"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def test(self, t, u):
|
||||
return self._fn(t, u)
|
||||
|
||||
|
||||
class _IntFunctionWrapper(IntFunction):
|
||||
"""Wraps a Python callable as a java.util.function.IntFunction"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def apply(self, value):
|
||||
return self._fn(value)
|
||||
|
||||
|
||||
class _LongFunctionWrapper(LongFunction):
|
||||
"""Wraps a Python callable as a java.util.function.LongFunction"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def apply(self, value):
|
||||
return self._fn(value)
|
||||
|
||||
|
||||
class _DoubleFunctionWrapper(DoubleFunction):
|
||||
"""Wraps a Python callable as a java.util.function.DoubleFunction"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def apply(self, value):
|
||||
return self._fn(value)
|
||||
|
||||
|
||||
class _IntConsumerWrapper(IntConsumer):
|
||||
"""Wraps a Python callable as a java.util.function.IntConsumer"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def accept(self, value):
|
||||
self._fn(value)
|
||||
|
||||
|
||||
class _LongConsumerWrapper(LongConsumer):
|
||||
"""Wraps a Python callable as a java.util.function.LongConsumer"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def accept(self, value):
|
||||
self._fn(value)
|
||||
|
||||
|
||||
class _DoubleConsumerWrapper(DoubleConsumer):
|
||||
"""Wraps a Python callable as a java.util.function.DoubleConsumer"""
|
||||
def __init__(self, fn):
|
||||
super().__init__()
|
||||
self._fn = fn
|
||||
|
||||
def accept(self, value):
|
||||
self._fn(value)
|
||||
@@ -0,0 +1,939 @@
|
||||
"""
|
||||
Java java.util.logging standard library APIs implemented in Python.
|
||||
java.util.logging package - Logger, Level, Handler, Formatter, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from .lang import RuntimeException, Exception as _JavaException
|
||||
from .security import BasicPermission
|
||||
import typing as _typing
|
||||
import sys as _sys
|
||||
import datetime as _datetime
|
||||
import io as _io
|
||||
import threading as _threading
|
||||
import traceback as _traceback
|
||||
import os as _os
|
||||
|
||||
__all__ = [
|
||||
"Logger", "Level",
|
||||
"Handler", "ConsoleHandler", "FileHandler", "StreamHandler",
|
||||
"SocketHandler", "MemoryHandler",
|
||||
"Formatter", "SimpleFormatter", "XMLFormatter",
|
||||
"LogRecord", "LogManager", "Filter", "ErrorManager",
|
||||
"LoggingMXBean", "LoggingPermission",
|
||||
"OFF", "SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST", "ALL",
|
||||
]
|
||||
|
||||
import sys as _sys
|
||||
import threading as _threading
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Level Constants
|
||||
# ============================================================
|
||||
|
||||
class _Integer:
|
||||
"""Wrapper to emulate Integer.MIN_VALUE / MAX_VALUE"""
|
||||
MIN_VALUE = -2147483648
|
||||
MAX_VALUE = 2147483647
|
||||
|
||||
|
||||
OFF = _Integer.MAX_VALUE
|
||||
SEVERE = 1000
|
||||
WARNING = 900
|
||||
INFO = 800
|
||||
CONFIG = 700
|
||||
FINE = 500
|
||||
FINER = 400
|
||||
FINEST = 300
|
||||
ALL = _Integer.MIN_VALUE
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Level
|
||||
# ============================================================
|
||||
|
||||
class Level(Stub):
|
||||
"""java.util.logging.Level"""
|
||||
def __init__(self, name, value, resource_bundle_name=None):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._value = value
|
||||
self._resource_bundle_name = resource_bundle_name
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def intValue(self):
|
||||
return self._value
|
||||
|
||||
def getResourceBundleName(self):
|
||||
return self._resource_bundle_name
|
||||
|
||||
def toString(self):
|
||||
return self._name
|
||||
|
||||
def hashCode(self):
|
||||
return self._value
|
||||
|
||||
def equals(self, other):
|
||||
if not isinstance(other, Level):
|
||||
return False
|
||||
return self._value == other._value
|
||||
|
||||
def parse(self, name):
|
||||
name_upper = name.upper()
|
||||
level_map = {
|
||||
"OFF": Level.OFF,
|
||||
"SEVERE": Level.SEVERE,
|
||||
"WARNING": Level.WARNING,
|
||||
"INFO": Level.INFO,
|
||||
"CONFIG": Level.CONFIG,
|
||||
"FINE": Level.FINE,
|
||||
"FINER": Level.FINER,
|
||||
"FINEST": Level.FINEST,
|
||||
"ALL": Level.ALL,
|
||||
}
|
||||
if name_upper in level_map:
|
||||
return level_map[name_upper]
|
||||
try:
|
||||
return Level(name, int(name))
|
||||
except ValueError:
|
||||
raise IllegalArgumentException(f"Bad level name: {name}")
|
||||
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, Level):
|
||||
return self._value < other._value
|
||||
return NotImplemented
|
||||
|
||||
def __le__(self, other):
|
||||
if isinstance(other, Level):
|
||||
return self._value <= other._value
|
||||
return NotImplemented
|
||||
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, Level):
|
||||
return self._value > other._value
|
||||
return NotImplemented
|
||||
|
||||
def __ge__(self, other):
|
||||
if isinstance(other, Level):
|
||||
return self._value >= other._value
|
||||
return NotImplemented
|
||||
|
||||
# Static level instances
|
||||
OFF = None
|
||||
SEVERE = None
|
||||
WARNING = None
|
||||
INFO = None
|
||||
CONFIG = None
|
||||
FINE = None
|
||||
FINER = None
|
||||
FINEST = None
|
||||
ALL = None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Initialize static Level instances
|
||||
# ============================================================
|
||||
|
||||
Level.OFF = Level("OFF", _Integer.MAX_VALUE)
|
||||
Level.SEVERE = Level("SEVERE", 1000)
|
||||
Level.WARNING = Level("WARNING", 900)
|
||||
Level.INFO = Level("INFO", 800)
|
||||
Level.CONFIG = Level("CONFIG", 700)
|
||||
Level.FINE = Level("FINE", 500)
|
||||
Level.FINER = Level("FINER", 400)
|
||||
Level.FINEST = Level("FINEST", 300)
|
||||
Level.ALL = Level("ALL", _Integer.MIN_VALUE)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LogRecord
|
||||
# ============================================================
|
||||
|
||||
class LogRecord(Stub):
|
||||
"""java.util.logging.LogRecord"""
|
||||
def __init__(self, level, msg):
|
||||
super().__init__()
|
||||
self._level = level if isinstance(level, Level) else Level.INFO
|
||||
self._logger_name = ""
|
||||
self._message = msg
|
||||
self._millis = _datetime.datetime.now().timestamp() * 1000
|
||||
self._thread_id = _threading.get_ident()
|
||||
self._source_class_name = None
|
||||
self._source_method_name = None
|
||||
self._thrown = None
|
||||
self._parameters = None
|
||||
self._resource_bundle = None
|
||||
self._resource_bundle_name = None
|
||||
self._sequence_number = id(self)
|
||||
self._long_thread_id = _threading.get_ident()
|
||||
|
||||
def getLevel(self):
|
||||
return self._level
|
||||
|
||||
def setLevel(self, level):
|
||||
self._level = level
|
||||
|
||||
def getLoggerName(self):
|
||||
return self._logger_name
|
||||
|
||||
def setLoggerName(self, name):
|
||||
self._logger_name = name
|
||||
|
||||
def getMessage(self):
|
||||
return self._message
|
||||
|
||||
def setMessage(self, msg):
|
||||
self._message = msg
|
||||
|
||||
def getMillis(self):
|
||||
return self._millis
|
||||
|
||||
def setMillis(self, millis):
|
||||
self._millis = millis
|
||||
|
||||
def getThreadID(self):
|
||||
return self._thread_id
|
||||
|
||||
def setThreadID(self, thread_id):
|
||||
self._thread_id = thread_id
|
||||
|
||||
def getSourceClassName(self):
|
||||
return self._source_class_name
|
||||
|
||||
def setSourceClassName(self, name):
|
||||
self._source_class_name = name
|
||||
|
||||
def getSourceMethodName(self):
|
||||
return self._source_method_name
|
||||
|
||||
def setSourceMethodName(self, name):
|
||||
self._source_method_name = name
|
||||
|
||||
def getThrown(self):
|
||||
return self._thrown
|
||||
|
||||
def setThrown(self, thrown):
|
||||
self._thrown = thrown
|
||||
|
||||
def getParameters(self):
|
||||
return self._parameters
|
||||
|
||||
def setParameters(self, params):
|
||||
self._parameters = params
|
||||
|
||||
def getResourceBundle(self):
|
||||
return self._resource_bundle
|
||||
|
||||
def setResourceBundle(self, bundle):
|
||||
self._resource_bundle = bundle
|
||||
|
||||
def getResourceBundleName(self):
|
||||
return self._resource_bundle_name
|
||||
|
||||
def setResourceBundleName(self, name):
|
||||
self._resource_bundle_name = name
|
||||
|
||||
def getSequenceNumber(self):
|
||||
return self._sequence_number
|
||||
|
||||
def setSequenceNumber(self, seq):
|
||||
self._sequence_number = seq
|
||||
|
||||
def getLongThreadID(self):
|
||||
return self._long_thread_id
|
||||
|
||||
def setLongThreadID(self, thread_id):
|
||||
self._long_thread_id = thread_id
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Filter
|
||||
# ============================================================
|
||||
|
||||
class Filter(Stub):
|
||||
"""java.util.logging.Filter"""
|
||||
def isLoggable(self, record):
|
||||
return True
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Formatter
|
||||
# ============================================================
|
||||
|
||||
class Formatter(Stub):
|
||||
"""java.util.logging.Formatter"""
|
||||
def format(self, record):
|
||||
raise NotImplementedError
|
||||
|
||||
def getHead(self, handler):
|
||||
return ""
|
||||
|
||||
def getTail(self, handler):
|
||||
return ""
|
||||
|
||||
def formatMessage(self, record):
|
||||
msg = record.getMessage()
|
||||
params = record.getParameters()
|
||||
if params:
|
||||
try:
|
||||
return msg % params
|
||||
except Exception:
|
||||
pass
|
||||
return msg
|
||||
|
||||
|
||||
class SimpleFormatter(Formatter):
|
||||
"""java.util.logging.SimpleFormatter"""
|
||||
def format(self, record):
|
||||
import datetime as dt
|
||||
ts = dt.datetime.fromtimestamp(record.getMillis() / 1000.0)
|
||||
ts_str = ts.strftime("%Y-%m-%d %H:%M:%S")
|
||||
msg = self.formatMessage(record)
|
||||
thrown = record.getThrown()
|
||||
result = f"{ts_str} {record.getLevel().getName()} {record.getLoggerName()}: {msg}"
|
||||
if thrown is not None:
|
||||
result += "\n" + "".join(_traceback.format_exception(
|
||||
type(thrown), thrown, getattr(thrown, '__traceback__', None)
|
||||
))
|
||||
return result
|
||||
|
||||
|
||||
class XMLFormatter(Formatter):
|
||||
"""java.util.logging.XMLFormatter"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
def format(self, record):
|
||||
ts = _datetime.datetime.fromtimestamp(record.getMillis() / 1000.0)
|
||||
ts_str = ts.strftime("%Y-%m-%dT%H:%M:%S")
|
||||
from xml.sax.saxutils import escape
|
||||
msg = escape(self.formatMessage(record))
|
||||
logger_name = escape(record.getLoggerName() or "")
|
||||
level_name = record.getLevel().getName()
|
||||
|
||||
parts = [
|
||||
"<record>",
|
||||
f" <date>{ts_str}</date>",
|
||||
f" <millis>{int(record.getMillis())}</millis>",
|
||||
f" <sequence>{record.getSequenceNumber()}</sequence>",
|
||||
f" <logger>{logger_name}</logger>",
|
||||
f" <level>{level_name}</level>",
|
||||
f" <class>{escape(record.getSourceClassName() or '')}</class>",
|
||||
f" <method>{escape(record.getSourceMethodName() or '')}</method>",
|
||||
f" <thread>{record.getThreadID()}</thread>",
|
||||
f" <message>{msg}</message>",
|
||||
]
|
||||
|
||||
thrown = record.getThrown()
|
||||
if thrown is not None:
|
||||
import traceback
|
||||
tb_str = "".join(traceback.format_exception(
|
||||
type(thrown), thrown, getattr(thrown, '__traceback__', None)
|
||||
))
|
||||
parts.append(f" <exception>{escape(tb_str)}</exception>")
|
||||
|
||||
parts.append("</record>")
|
||||
return "\n".join(parts)
|
||||
|
||||
def getHead(self, handler):
|
||||
return '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE log SYSTEM "logger.dtd">\n<log>\n'
|
||||
|
||||
def getTail(self, handler):
|
||||
return "</log>\n"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ErrorManager
|
||||
# ============================================================
|
||||
|
||||
class ErrorManager(Stub):
|
||||
"""java.util.logging.ErrorManager"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def error(self, message, exception, error_code):
|
||||
_sys.stderr.write(f"ErrorManager: {message}\n")
|
||||
if exception:
|
||||
_traceback.print_exception(type(exception), exception,
|
||||
getattr(exception, '__traceback__', None))
|
||||
|
||||
GENERIC_FAILURE = 0
|
||||
WRITE_FAILURE = 1
|
||||
FLUSH_FAILURE = 2
|
||||
CLOSE_FAILURE = 3
|
||||
OPEN_FAILURE = 4
|
||||
FORMAT_FAILURE = 5
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Handler
|
||||
# ============================================================
|
||||
|
||||
class Handler(Stub):
|
||||
"""java.util.logging.Handler"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._level = Level.ALL
|
||||
self._filter = None
|
||||
self._formatter = None
|
||||
self._encoding = None
|
||||
self._error_manager = ErrorManager()
|
||||
self._closed = False
|
||||
|
||||
def publish(self, record):
|
||||
raise NotImplementedError
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
self._closed = True
|
||||
|
||||
def isLoggable(self, record):
|
||||
if self._closed:
|
||||
return False
|
||||
if record.getLevel().intValue() < self._level.intValue():
|
||||
return False
|
||||
if self._filter is not None:
|
||||
return self._filter.isLoggable(record)
|
||||
return True
|
||||
|
||||
def setLevel(self, level):
|
||||
self._level = level
|
||||
|
||||
def getLevel(self):
|
||||
return self._level
|
||||
|
||||
def setFilter(self, filter_):
|
||||
self._filter = filter_
|
||||
|
||||
def getFilter(self):
|
||||
return self._filter
|
||||
|
||||
def setFormatter(self, formatter):
|
||||
self._formatter = formatter
|
||||
|
||||
def getFormatter(self):
|
||||
return self._formatter
|
||||
|
||||
def setEncoding(self, encoding):
|
||||
self._encoding = encoding
|
||||
|
||||
def getEncoding(self):
|
||||
return self._encoding
|
||||
|
||||
def setErrorManager(self, em):
|
||||
self._error_manager = em
|
||||
|
||||
def getErrorManager(self):
|
||||
return self._error_manager
|
||||
|
||||
def reportError(self, msg, ex, code):
|
||||
if self._error_manager:
|
||||
self._error_manager.error(msg, ex, code)
|
||||
|
||||
|
||||
class StreamHandler(Handler):
|
||||
"""java.util.logging.StreamHandler"""
|
||||
def __init__(self, out=None, formatter=None):
|
||||
super().__init__()
|
||||
if formatter is None:
|
||||
formatter = SimpleFormatter()
|
||||
self.setFormatter(formatter)
|
||||
self._output = out or _sys.stderr
|
||||
self._writer = None
|
||||
if self._output is not None:
|
||||
if isinstance(self._output, _io.TextIOBase):
|
||||
self._writer = self._output
|
||||
elif isinstance(self._output, _io.BufferedWriter):
|
||||
self._writer = _io.TextIOWrapper(self._output)
|
||||
else:
|
||||
self._writer = _io.TextIOWrapper(_io.BufferedWriter(self._output))
|
||||
|
||||
def publish(self, record):
|
||||
if not self.isLoggable(record):
|
||||
return
|
||||
try:
|
||||
msg = self.getFormatter().format(record)
|
||||
if self._writer is not None:
|
||||
self._writer.write(msg + "\n")
|
||||
else:
|
||||
print(msg, file=_sys.stderr)
|
||||
self.flush()
|
||||
except Exception as e:
|
||||
self.reportError("Error publishing record", e, ErrorManager.WRITE_FAILURE)
|
||||
|
||||
def flush(self):
|
||||
if self._writer is not None:
|
||||
try:
|
||||
self._writer.flush()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
if self._writer is not None:
|
||||
try:
|
||||
self._writer.close()
|
||||
except Exception:
|
||||
pass
|
||||
super().close()
|
||||
|
||||
def setOutputStream(self, out):
|
||||
self._output = out
|
||||
if isinstance(out, _io.TextIOBase):
|
||||
self._writer = out
|
||||
elif isinstance(out, _io.BufferedWriter):
|
||||
self._writer = _io.TextIOWrapper(out)
|
||||
else:
|
||||
self._writer = _io.TextIOWrapper(_io.BufferedWriter(out))
|
||||
|
||||
|
||||
class ConsoleHandler(StreamHandler):
|
||||
"""java.util.logging.ConsoleHandler"""
|
||||
def __init__(self):
|
||||
super().__init__(_sys.stderr, SimpleFormatter())
|
||||
self.setLevel(Level.INFO)
|
||||
|
||||
|
||||
class FileHandler(Handler):
|
||||
"""java.util.logging.FileHandler"""
|
||||
def __init__(self, pattern=None, append=None, limit=0, count=1):
|
||||
super().__init__()
|
||||
self._pattern = pattern or "logging.log"
|
||||
self._limit = limit
|
||||
self._count = count
|
||||
self._append = append or False
|
||||
self._files = []
|
||||
|
||||
if "%u" in self._pattern or "%g" in self._pattern:
|
||||
self._current_filename = self._pattern.replace("%u", "0").replace("%g", "0")
|
||||
else:
|
||||
self._current_filename = self._pattern
|
||||
|
||||
try:
|
||||
mode = "a" if self._append else "w"
|
||||
self._file = open(self._current_filename, mode, encoding="utf-8")
|
||||
self._writer = self._file
|
||||
except Exception as e:
|
||||
self._file = None
|
||||
self._writer = None
|
||||
self.reportError("Cannot open file", e, ErrorManager.OPEN_FAILURE)
|
||||
|
||||
self._formatter = SimpleFormatter()
|
||||
|
||||
def publish(self, record):
|
||||
if not self.isLoggable(record):
|
||||
return
|
||||
if self._writer is None:
|
||||
return
|
||||
try:
|
||||
msg = self.getFormatter().format(record)
|
||||
self._writer.write(msg + "\n")
|
||||
self.flush()
|
||||
except Exception as e:
|
||||
self.reportError("Error publishing record", e, ErrorManager.WRITE_FAILURE)
|
||||
|
||||
def flush(self):
|
||||
if self._writer is not None:
|
||||
try:
|
||||
self._writer.flush()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
if self._writer is not None:
|
||||
try:
|
||||
self._writer.close()
|
||||
except Exception:
|
||||
pass
|
||||
super().close()
|
||||
|
||||
|
||||
class SocketHandler(Handler):
|
||||
"""java.util.logging.SocketHandler"""
|
||||
def __init__(self, host, port):
|
||||
super().__init__()
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._sock = None
|
||||
self._output_stream = None
|
||||
|
||||
def connect(self):
|
||||
import socket
|
||||
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self._sock.connect((self._host, self._port))
|
||||
self._output_stream = self._sock.makefile("wb")
|
||||
|
||||
def publish(self, record):
|
||||
if not self.isLoggable(record):
|
||||
return
|
||||
if self._output_stream is None:
|
||||
try:
|
||||
self.connect()
|
||||
except Exception as e:
|
||||
self.reportError("Cannot connect", e, ErrorManager.OPEN_FAILURE)
|
||||
return
|
||||
try:
|
||||
msg = self.getFormatter().format(record)
|
||||
self._output_stream.write(msg.encode() + b"\n")
|
||||
self.flush()
|
||||
except Exception as e:
|
||||
self.reportError("Error sending record", e, ErrorManager.WRITE_FAILURE)
|
||||
|
||||
def flush(self):
|
||||
if self._output_stream is not None:
|
||||
try:
|
||||
self._output_stream.flush()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
self.flush()
|
||||
if self._output_stream is not None:
|
||||
try:
|
||||
self._output_stream.close()
|
||||
except Exception:
|
||||
pass
|
||||
if self._sock is not None:
|
||||
try:
|
||||
self._sock.close()
|
||||
except Exception:
|
||||
pass
|
||||
super().close()
|
||||
|
||||
|
||||
class MemoryHandler(Handler):
|
||||
"""java.util.logging.MemoryHandler"""
|
||||
def __init__(self, target=None, size=1000, push_level=Level.SEVERE):
|
||||
super().__init__()
|
||||
self._target = target
|
||||
self._size = size
|
||||
self._push_level = push_level
|
||||
self._buffer = []
|
||||
|
||||
def publish(self, record):
|
||||
if not self.isLoggable(record):
|
||||
return
|
||||
self._buffer.append(record)
|
||||
if len(self._buffer) >= self._size:
|
||||
self.push()
|
||||
elif record.getLevel().intValue() >= self._push_level.intValue():
|
||||
self.push()
|
||||
|
||||
def push(self):
|
||||
if self._target is not None:
|
||||
for rec in self._buffer:
|
||||
self._target.publish(rec)
|
||||
self._buffer.clear()
|
||||
self._target.flush()
|
||||
|
||||
def flush(self):
|
||||
self.push()
|
||||
|
||||
def close(self):
|
||||
self.push()
|
||||
if self._target is not None:
|
||||
self._target.close()
|
||||
super().close()
|
||||
|
||||
def setPushLevel(self, level):
|
||||
self._push_level = level
|
||||
|
||||
def getPushLevel(self):
|
||||
return self._push_level
|
||||
|
||||
def setTarget(self, target):
|
||||
self._target = target
|
||||
|
||||
def getTarget(self):
|
||||
return self._target
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Logger
|
||||
# ============================================================
|
||||
|
||||
class Logger(Stub):
|
||||
"""java.util.logging.Logger"""
|
||||
_loggers = {}
|
||||
_root = None
|
||||
_global_logger = None
|
||||
|
||||
def __init__(self, name, resource_bundle_name=None):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._resource_bundle_name = resource_bundle_name
|
||||
self._level = None
|
||||
self._parent = None
|
||||
self._handlers = []
|
||||
self._filter = None
|
||||
self._use_parent_handlers = True
|
||||
|
||||
@staticmethod
|
||||
def getGlobal():
|
||||
if Logger._global_logger is None:
|
||||
Logger._global_logger = Logger("global")
|
||||
return Logger._global_logger
|
||||
|
||||
@staticmethod
|
||||
def getLogger(name, resource_bundle_name=None):
|
||||
if not name:
|
||||
if Logger._root is None:
|
||||
Logger._root = Logger("", resource_bundle_name)
|
||||
return Logger._root
|
||||
if name not in Logger._loggers:
|
||||
logger = Logger(name, resource_bundle_name)
|
||||
Logger._loggers[name] = logger
|
||||
logger._parent = Logger.getLogger("", None)
|
||||
return Logger._loggers[name]
|
||||
|
||||
def getName(self):
|
||||
return self._name
|
||||
|
||||
def getParent(self):
|
||||
return self._parent
|
||||
|
||||
def setParent(self, parent):
|
||||
self._parent = parent
|
||||
|
||||
def setLevel(self, level):
|
||||
self._level = level
|
||||
|
||||
def getLevel(self):
|
||||
return self._level
|
||||
|
||||
def isLoggable(self, level):
|
||||
if self._level is not None:
|
||||
return level.intValue() >= self._level.intValue()
|
||||
if self._parent is not None:
|
||||
return self._parent.isLoggable(level)
|
||||
return level.intValue() >= Level.INFO.intValue()
|
||||
|
||||
def addHandler(self, handler):
|
||||
if handler not in self._handlers:
|
||||
self._handlers.append(handler)
|
||||
|
||||
def removeHandler(self, handler):
|
||||
if handler in self._handlers:
|
||||
self._handlers.remove(handler)
|
||||
|
||||
def getHandlers(self):
|
||||
return self._handlers
|
||||
|
||||
def setUseParentHandlers(self, use):
|
||||
self._use_parent_handlers = use
|
||||
|
||||
def getUseParentHandlers(self):
|
||||
return self._use_parent_handlers
|
||||
|
||||
def setFilter(self, filter_):
|
||||
self._filter = filter_
|
||||
|
||||
def getFilter(self):
|
||||
return self._filter
|
||||
|
||||
def getResourceBundle(self):
|
||||
return None
|
||||
|
||||
def getResourceBundleName(self):
|
||||
return self._resource_bundle_name
|
||||
|
||||
def log(self, level, msg_or_supplier, *args):
|
||||
if isinstance(level, Level):
|
||||
if self.isLoggable(level):
|
||||
if callable(msg_or_supplier) and not args:
|
||||
msg = msg_or_supplier()
|
||||
else:
|
||||
msg = msg_or_supplier
|
||||
record = LogRecord(level, msg)
|
||||
record.setLoggerName(self._name)
|
||||
record.setParameters(args or None)
|
||||
self._log(record)
|
||||
else:
|
||||
# log(LogRecord)
|
||||
self._log(level)
|
||||
|
||||
def _log(self, record):
|
||||
if self._filter is not None and not self._filter.isLoggable(record):
|
||||
return
|
||||
for handler in self._handlers:
|
||||
if handler.isLoggable(record):
|
||||
handler.publish(record)
|
||||
if self._use_parent_handlers and self._parent is not None:
|
||||
self._parent._log(record)
|
||||
|
||||
def severe(self, msg):
|
||||
self.log(Level.SEVERE, msg)
|
||||
|
||||
def warning(self, msg):
|
||||
self.log(Level.WARNING, msg)
|
||||
|
||||
def info(self, msg):
|
||||
self.log(Level.INFO, msg)
|
||||
|
||||
def config(self, msg):
|
||||
self.log(Level.CONFIG, msg)
|
||||
|
||||
def fine(self, msg):
|
||||
self.log(Level.FINE, msg)
|
||||
|
||||
def finer(self, msg):
|
||||
self.log(Level.FINER, msg)
|
||||
|
||||
def finest(self, msg):
|
||||
self.log(Level.FINEST, msg)
|
||||
|
||||
def entering(self, source_class, source_method, param=None):
|
||||
msg = f"ENTRY {source_class}.{source_method}"
|
||||
if param is not None:
|
||||
msg += f" {param}"
|
||||
self.log(Level.FINER, msg)
|
||||
|
||||
def exiting(self, source_class, source_method, result=None):
|
||||
msg = f"RETURN {source_class}.{source_method}"
|
||||
if result is not None:
|
||||
msg += f" {result}"
|
||||
self.log(Level.FINER, msg)
|
||||
|
||||
def throwing(self, source_class, source_method, thrown):
|
||||
record = LogRecord(Level.FINER, "THROW")
|
||||
record.setLoggerName(self._name)
|
||||
record.setSourceClassName(source_class)
|
||||
record.setSourceMethodName(source_method)
|
||||
record.setThrown(thrown)
|
||||
self._log(record)
|
||||
|
||||
def logp(self, level, source_class, source_method, msg, *params):
|
||||
if self.isLoggable(level):
|
||||
record = LogRecord(level, msg)
|
||||
record.setLoggerName(self._name)
|
||||
record.setSourceClassName(source_class)
|
||||
record.setSourceMethodName(source_method)
|
||||
record.setParameters(params or None)
|
||||
self._log(record)
|
||||
|
||||
def logrb(self, level, source_class, source_method, bundle_name, msg, *params):
|
||||
if self.isLoggable(level):
|
||||
record = LogRecord(level, msg)
|
||||
record.setLoggerName(self._name)
|
||||
record.setSourceClassName(source_class)
|
||||
record.setSourceMethodName(source_method)
|
||||
record.setResourceBundleName(bundle_name)
|
||||
record.setParameters(params or None)
|
||||
self._log(record)
|
||||
|
||||
@staticmethod
|
||||
def getAnonymousLogger(resource_bundle_name=None):
|
||||
logger = Logger("", resource_bundle_name)
|
||||
return logger
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LogManager
|
||||
# ============================================================
|
||||
|
||||
class LogManager(Stub):
|
||||
"""java.util.logging.LogManager"""
|
||||
_singleton = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._loggers = {}
|
||||
self._properties = {}
|
||||
|
||||
@staticmethod
|
||||
def getLogManager():
|
||||
if LogManager._singleton is None:
|
||||
LogManager._singleton = LogManager()
|
||||
return LogManager._singleton
|
||||
|
||||
def addLogger(self, logger):
|
||||
name = logger.getName()
|
||||
if name in self._loggers:
|
||||
return False
|
||||
self._loggers[name] = logger
|
||||
return True
|
||||
|
||||
def getLogger(self, name):
|
||||
return self._loggers.get(name)
|
||||
|
||||
def getLoggers(self):
|
||||
return list(self._loggers.values())
|
||||
|
||||
def readConfiguration(self, input_stream=None):
|
||||
pass
|
||||
|
||||
def readConfiguration(self, ins):
|
||||
pass
|
||||
|
||||
def reset(self):
|
||||
for logger in self._loggers.values():
|
||||
for handler in logger.getHandlers()[:]:
|
||||
handler.close()
|
||||
logger.removeHandler(handler)
|
||||
logger.setLevel(None)
|
||||
|
||||
def checkAccess(self):
|
||||
pass
|
||||
|
||||
def addPropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
def removePropertyChangeListener(self, listener):
|
||||
pass
|
||||
|
||||
LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"
|
||||
|
||||
def getProperty(self, name):
|
||||
return self._properties.get(name)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LoggingMXBean
|
||||
# ============================================================
|
||||
|
||||
class LoggingMXBean(Stub):
|
||||
"""java.util.logging.LoggingMXBean"""
|
||||
def getLoggerLevel(self, logger_name):
|
||||
logger = LogManager.getLogManager().getLogger(logger_name)
|
||||
if logger and logger.getLevel():
|
||||
return logger.getLevel().getName()
|
||||
return ""
|
||||
|
||||
def setLoggerLevel(self, logger_name, level_name):
|
||||
logger = LogManager.getLogManager().getLogger(logger_name)
|
||||
if logger:
|
||||
level = Level()
|
||||
logger.setLevel(level.parse(level_name))
|
||||
|
||||
def getParentLogger(self, logger_name):
|
||||
logger = LogManager.getLogManager().getLogger(logger_name)
|
||||
if logger and logger.getParent():
|
||||
return logger.getParent().getName()
|
||||
return ""
|
||||
|
||||
def getLoggerNames(self):
|
||||
return list(LogManager.getLogManager()._loggers.keys())
|
||||
|
||||
|
||||
# ============================================================
|
||||
# LoggingPermission
|
||||
# ============================================================
|
||||
|
||||
class LoggingPermission(BasicPermission):
|
||||
"""java.util.logging.LoggingPermission"""
|
||||
def __init__(self, name, actions=None):
|
||||
super().__init__(name, actions)
|
||||
|
||||
|
||||
class IllegalArgumentException(RuntimeException):
|
||||
"""java.lang.IllegalArgumentException"""
|
||||
pass
|
||||
@@ -0,0 +1,544 @@
|
||||
"""
|
||||
Java java.util.prefs standard library APIs implemented in Python.
|
||||
java.util.prefs package - Preferences, PreferencesFactory, etc.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .._core import Stub
|
||||
from ..java.lang import RuntimeException, Exception as _JavaException
|
||||
import typing as _typing
|
||||
import json as _json
|
||||
import os as _os
|
||||
import threading as _threading
|
||||
|
||||
__all__ = [
|
||||
"Preferences", "PreferencesFactory", "AbstractPreferences",
|
||||
"NodeChangeEvent", "NodeChangeListener",
|
||||
"PreferenceChangeEvent", "PreferenceChangeListener",
|
||||
"BackingStoreException", "InvalidPreferencesFormatException",
|
||||
]
|
||||
|
||||
# ============================================================
|
||||
# Exceptions
|
||||
# ============================================================
|
||||
|
||||
class BackingStoreException(_JavaException):
|
||||
"""java.util.prefs.BackingStoreException"""
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class InvalidPreferencesFormatException(_JavaException):
|
||||
"""java.util.prefs.InvalidPreferencesFormatException"""
|
||||
def __init__(self, message, cause=None):
|
||||
super().__init__(message)
|
||||
self._cause = cause
|
||||
|
||||
def getCause(self):
|
||||
return self._cause
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Event Classes
|
||||
# ============================================================
|
||||
|
||||
class NodeChangeEvent(Stub):
|
||||
"""java.util.prefs.NodeChangeEvent"""
|
||||
def __init__(self, parent, child):
|
||||
super().__init__()
|
||||
self._parent = parent
|
||||
self._child = child
|
||||
|
||||
def getParent(self):
|
||||
return self._parent
|
||||
|
||||
def getChild(self):
|
||||
return self._child
|
||||
|
||||
|
||||
class PreferenceChangeEvent(Stub):
|
||||
"""java.util.prefs.PreferenceChangeEvent"""
|
||||
def __init__(self, node, key, new_value):
|
||||
super().__init__()
|
||||
self._node = node
|
||||
self._key = key
|
||||
self._new_value = new_value
|
||||
|
||||
def getNode(self):
|
||||
return self._node
|
||||
|
||||
def getKey(self):
|
||||
return self._key
|
||||
|
||||
def getNewValue(self):
|
||||
return self._new_value
|
||||
|
||||
|
||||
class NodeChangeListener(Stub):
|
||||
"""java.util.prefs.NodeChangeListener"""
|
||||
def childAdded(self, evt):
|
||||
pass
|
||||
|
||||
def childRemoved(self, evt):
|
||||
pass
|
||||
|
||||
|
||||
class PreferenceChangeListener(Stub):
|
||||
"""java.util.prefs.PreferenceChangeListener"""
|
||||
def preferenceChange(self, evt):
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Preferences
|
||||
# ============================================================
|
||||
|
||||
class Preferences(Stub):
|
||||
"""java.util.prefs.Preferences"""
|
||||
MAX_KEY_LENGTH = 80
|
||||
MAX_VALUE_LENGTH = 8192
|
||||
MAX_NAME_LENGTH = 80
|
||||
|
||||
def __init__(self, name="", parent=None):
|
||||
super().__init__()
|
||||
self._name = name
|
||||
self._parent = parent
|
||||
self._children = {}
|
||||
self._prefs = {}
|
||||
self._node_listeners = []
|
||||
self._pref_listeners = []
|
||||
self._absolute_path = self._build_path()
|
||||
|
||||
def _build_path(self):
|
||||
if self._parent is None:
|
||||
return "/" + self._name if self._name else "/"
|
||||
parent_path = self._parent._absolute_path
|
||||
if parent_path == "/":
|
||||
return "/" + self._name
|
||||
return parent_path + "/" + self._name
|
||||
|
||||
def put(self, key, value):
|
||||
if len(key) > Preferences.MAX_KEY_LENGTH:
|
||||
raise IllegalArgumentException(f"Key too long: {len(key)}")
|
||||
if len(value) > Preferences.MAX_VALUE_LENGTH:
|
||||
raise IllegalArgumentException(f"Value too long: {len(value)}")
|
||||
self._prefs[key] = value
|
||||
self._fire_preference_change(key, value)
|
||||
|
||||
def get(self, key, default_value):
|
||||
return self._prefs.get(key, default_value)
|
||||
|
||||
def remove(self, key):
|
||||
if key in self._prefs:
|
||||
old = self._prefs.pop(key)
|
||||
self._fire_preference_change(key, None)
|
||||
|
||||
def clear(self):
|
||||
self._prefs.clear()
|
||||
|
||||
def putInt(self, key, value):
|
||||
self.put(key, str(value))
|
||||
|
||||
def getInt(self, key, default_value):
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
try:
|
||||
return int(val)
|
||||
except ValueError:
|
||||
return default_value
|
||||
|
||||
def putLong(self, key, value):
|
||||
self.put(key, str(value))
|
||||
|
||||
def getLong(self, key, default_value):
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
try:
|
||||
return int(val)
|
||||
except ValueError:
|
||||
return default_value
|
||||
|
||||
def putFloat(self, key, value):
|
||||
self.put(key, str(value))
|
||||
|
||||
def getFloat(self, key, default_value):
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
try:
|
||||
return float(val)
|
||||
except ValueError:
|
||||
return default_value
|
||||
|
||||
def putDouble(self, key, value):
|
||||
self.put(key, str(value))
|
||||
|
||||
def getDouble(self, key, default_value):
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
try:
|
||||
return float(val)
|
||||
except ValueError:
|
||||
return default_value
|
||||
|
||||
def putBoolean(self, key, value):
|
||||
self.put(key, "true" if value else "false")
|
||||
|
||||
def getBoolean(self, key, default_value):
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
return val.lower() == "true"
|
||||
|
||||
def putByteArray(self, key, value):
|
||||
import base64
|
||||
self.put(key, base64.b64encode(value).decode())
|
||||
|
||||
def getByteArray(self, key, default_value):
|
||||
import base64
|
||||
val = self.get(key, None)
|
||||
if val is None:
|
||||
return default_value
|
||||
try:
|
||||
return base64.b64decode(val)
|
||||
except Exception:
|
||||
return default_value
|
||||
|
||||
def keys(self):
|
||||
return list(self._prefs.keys())
|
||||
|
||||
def childrenNames(self):
|
||||
return list(self._children.keys())
|
||||
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
def node(self, path_name):
|
||||
if path_name.startswith("/"):
|
||||
return self._root()._node_path(path_name[1:])
|
||||
return self._node_path(path_name)
|
||||
|
||||
def nodeExists(self, path_name):
|
||||
try:
|
||||
self.node(path_name)
|
||||
return True
|
||||
except BackingStoreException:
|
||||
return False
|
||||
|
||||
def removeNode(self):
|
||||
if self._parent is not None:
|
||||
self._parent._remove_child(self._name)
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def absolutePath(self):
|
||||
return self._absolute_path
|
||||
|
||||
def isUserNode(self):
|
||||
return False
|
||||
|
||||
def toString(self):
|
||||
return self._absolute_path
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def sync(self):
|
||||
pass
|
||||
|
||||
def addNodeChangeListener(self, listener):
|
||||
self._node_listeners.append(listener)
|
||||
|
||||
def removeNodeChangeListener(self, listener):
|
||||
if listener in self._node_listeners:
|
||||
self._node_listeners.remove(listener)
|
||||
|
||||
def addPreferenceChangeListener(self, listener):
|
||||
self._pref_listeners.append(listener)
|
||||
|
||||
def removePreferenceChangeListener(self, listener):
|
||||
if listener in self._pref_listeners:
|
||||
self._pref_listeners.remove(listener)
|
||||
|
||||
def exportNode(self, output_stream):
|
||||
data = self._to_dict()
|
||||
output_stream.write(_json.dumps(data, indent=2).encode())
|
||||
|
||||
def exportSubtree(self, output_stream):
|
||||
data = self._to_dict(recursive=True)
|
||||
output_stream.write(_json.dumps(data, indent=2).encode())
|
||||
|
||||
def _to_dict(self, recursive=False):
|
||||
result = {"prefs": dict(self._prefs)}
|
||||
if recursive:
|
||||
result["children"] = {
|
||||
name: child._to_dict(recursive=True)
|
||||
for name, child in self._children.items()
|
||||
}
|
||||
return result
|
||||
|
||||
def _root(self):
|
||||
if self._parent is None:
|
||||
return self
|
||||
return self._parent._root()
|
||||
|
||||
def _node_path(self, path):
|
||||
if not path:
|
||||
return self
|
||||
parts = path.split("/")
|
||||
current = self
|
||||
for part in parts:
|
||||
if not part:
|
||||
continue
|
||||
if part == "..":
|
||||
if current._parent is not None:
|
||||
current = current._parent
|
||||
continue
|
||||
if part not in current._children:
|
||||
current._children[part] = Preferences(part, current)
|
||||
current = current._children[part]
|
||||
return current
|
||||
|
||||
def _remove_child(self, name):
|
||||
if name in self._children:
|
||||
child = self._children.pop(name)
|
||||
evt = NodeChangeEvent(self, child)
|
||||
for listener in self._node_listeners:
|
||||
listener.childRemoved(evt)
|
||||
|
||||
def _fire_preference_change(self, key, value):
|
||||
evt = PreferenceChangeEvent(self, key, value)
|
||||
for listener in self._pref_listeners:
|
||||
listener.preferenceChange(evt)
|
||||
|
||||
@staticmethod
|
||||
def userRoot():
|
||||
if Preferences._user_root is None:
|
||||
Preferences._user_root = Preferences("")
|
||||
return Preferences._user_root
|
||||
|
||||
@staticmethod
|
||||
def systemRoot():
|
||||
if Preferences._system_root is None:
|
||||
Preferences._system_root = Preferences("")
|
||||
return Preferences._system_root
|
||||
|
||||
@staticmethod
|
||||
def importPreferences(input_stream):
|
||||
data = _json.loads(input_stream.read())
|
||||
root = Preferences("")
|
||||
root._prefs = data.get("prefs", {})
|
||||
return root
|
||||
|
||||
_user_root = None
|
||||
_system_root = None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AbstractPreferences
|
||||
# ============================================================
|
||||
|
||||
class AbstractPreferences(Preferences):
|
||||
"""java.util.prefs.AbstractPreferences"""
|
||||
def __init__(self, parent, name):
|
||||
super().__init__(name, parent)
|
||||
self._is_removed = False
|
||||
self._lock = _threading.RLock()
|
||||
|
||||
def put(self, key, value):
|
||||
with self._lock:
|
||||
if self._is_removed:
|
||||
raise BackingStoreException("Node has been removed")
|
||||
super().put(key, value)
|
||||
|
||||
def get(self, key, default_value):
|
||||
with self._lock:
|
||||
if self._is_removed:
|
||||
raise BackingStoreException("Node has been removed")
|
||||
return super().get(key, default_value)
|
||||
|
||||
def remove(self, key):
|
||||
with self._lock:
|
||||
super().remove(key)
|
||||
|
||||
def keys(self):
|
||||
with self._lock:
|
||||
return super().keys()
|
||||
|
||||
def childrenNames(self):
|
||||
with self._lock:
|
||||
return super().childrenNames()
|
||||
|
||||
def node(self, path_name):
|
||||
with self._lock:
|
||||
return super().node(path_name)
|
||||
|
||||
def removeNode(self):
|
||||
with self._lock:
|
||||
super().removeNode()
|
||||
self._is_removed = True
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def sync(self):
|
||||
pass
|
||||
|
||||
def isUserNode(self):
|
||||
return False
|
||||
|
||||
|
||||
# ============================================================
|
||||
# PreferencesFactory
|
||||
# ============================================================
|
||||
|
||||
class PreferencesFactory(Stub):
|
||||
"""java.util.prefs.PreferencesFactory"""
|
||||
def systemRoot(self):
|
||||
return Preferences.systemRoot()
|
||||
|
||||
def userRoot(self):
|
||||
return Preferences.userRoot()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# IllegalArgumentException
|
||||
# ============================================================
|
||||
|
||||
class IllegalArgumentException(RuntimeException):
|
||||
"""java.lang.IllegalArgumentException"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Preferences utility helpers
|
||||
# ============================================================
|
||||
|
||||
class _PreferencesService(Stub):
|
||||
"""Helper to manage Preferences with file-backed storage"""
|
||||
def __init__(self, root_path=None):
|
||||
super().__init__()
|
||||
if root_path is None:
|
||||
import os
|
||||
root_path = os.path.join(os.path.expanduser("~"), ".java", "prefs")
|
||||
self._root_path = root_path
|
||||
self._cache = {}
|
||||
|
||||
def loadPreferences(self, node_path):
|
||||
import os
|
||||
import json
|
||||
file_path = os.path.join(self._root_path, node_path.replace("/", "_") + ".json")
|
||||
prefs = Preferences(node_path)
|
||||
if os.path.exists(file_path):
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
data = json.load(f)
|
||||
for key, val in data.items():
|
||||
prefs.put(key, val)
|
||||
except Exception:
|
||||
pass
|
||||
self._cache[node_path] = prefs
|
||||
return prefs
|
||||
|
||||
def savePreferences(self, prefs):
|
||||
import os
|
||||
import json
|
||||
file_path = os.path.join(self._root_path,
|
||||
prefs.absolutePath().replace("/", "_") + ".json")
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
data = {}
|
||||
for key in prefs.keys():
|
||||
data[key] = prefs.get(key, None)
|
||||
with open(file_path, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
def clearCache(self):
|
||||
self._cache.clear()
|
||||
|
||||
|
||||
class _EventDispatchThread(Stub):
|
||||
"""Helper for dispatching preference change events"""
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._listeners = []
|
||||
import threading
|
||||
self._lock = threading.Lock()
|
||||
|
||||
def addListener(self, listener):
|
||||
with self._lock:
|
||||
self._listeners.append(listener)
|
||||
|
||||
def removeListener(self, listener):
|
||||
with self._lock:
|
||||
if listener in self._listeners:
|
||||
self._listeners.remove(listener)
|
||||
|
||||
def dispatchEvent(self, event):
|
||||
with self._lock:
|
||||
for listener in self._listeners:
|
||||
try:
|
||||
if hasattr(listener, 'preferenceChange'):
|
||||
listener.preferenceChange(event)
|
||||
elif callable(listener):
|
||||
listener(event)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def getListeners(self):
|
||||
with self._lock:
|
||||
return list(self._listeners)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FileSystemPreferences - persistent Preferences backed by file
|
||||
# ============================================================
|
||||
|
||||
class FileSystemPreferences(AbstractPreferences):
|
||||
"""java.util.prefs.FileSystemPreferences - persistent file-backed preferences"""
|
||||
def __init__(self, parent, name, storage_path=None):
|
||||
super().__init__(parent, name)
|
||||
import os
|
||||
if storage_path is None:
|
||||
storage_path = os.path.join(os.path.expanduser("~"), ".java", "user_prefs")
|
||||
self._storage_path = os.path.join(
|
||||
storage_path, self.absolutePath().replace("/", "_") + ".xml"
|
||||
)
|
||||
self._loaded = False
|
||||
self._service = _PreferencesService(storage_path)
|
||||
|
||||
def _ensureLoaded(self):
|
||||
if not self._loaded:
|
||||
try:
|
||||
import os
|
||||
if os.path.exists(self._storage_path):
|
||||
node = self._service.loadPreferences(self.absolutePath())
|
||||
for key in node.keys():
|
||||
self._prefs[key] = node.get(key, "")
|
||||
self._loaded = True
|
||||
except Exception:
|
||||
self._loaded = True
|
||||
|
||||
def put(self, key, value):
|
||||
self._ensureLoaded()
|
||||
super().put(key, value)
|
||||
|
||||
def get(self, key, default_value):
|
||||
self._ensureLoaded()
|
||||
return super().get(key, default_value)
|
||||
|
||||
def keys(self):
|
||||
self._ensureLoaded()
|
||||
return super().keys()
|
||||
|
||||
def flush(self):
|
||||
self._service.savePreferences(self)
|
||||
super().flush()
|
||||
|
||||
def sync(self):
|
||||
self._ensureLoaded()
|
||||
self._service.savePreferences(self)
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user