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:
shuiyu1123 committed 2026-06-24 14:15:56 +00:00
1 parent 506f9ac725
commit a51854455b
128 files changed
+100571 -3

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
"""
Java standard library APIs implemented in Python.
Android-pyApi: desktop Python translation of Android Java APIs.
"""
+806
View File
@@ -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
+303
View File
@@ -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
+766
View File
@@ -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
+830
View File
@@ -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
+386
View File
@@ -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
+968
View File
@@ -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)
+33
View File
@@ -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
+573
View File
@@ -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
+776
View File
@@ -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
+907
View File
@@ -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
+697
View File
@@ -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
+681
View File
@@ -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
+599
View File
@@ -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)
+939
View File
@@ -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
+544
View File
@@ -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