207 lines
6.1 KiB
Python
207 lines
6.1 KiB
Python
# *****************************************************************************
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
# See NOTICE file for details.
|
|
#
|
|
# *****************************************************************************
|
|
import _jpype
|
|
from . import _jcustomizer
|
|
|
|
|
|
__all__ = ['JArray']
|
|
|
|
|
|
class JArray(_jpype._JObject, internal=True): # type: ignore[call-arg]
|
|
""" Creates a Java array class for a Java type of a given dimension.
|
|
|
|
This serves as a base type and factory for all Java array classes.
|
|
The resulting Java array class can be used to construct a new
|
|
array with a given size or specified members.
|
|
|
|
JPype arrays support Python operators for iterating, length, equals,
|
|
not equals, subscripting, and slicing. They also support Java
|
|
object methods, clone, and length property. Java arrays may not
|
|
be resized, and as such elements cannot be added nor deleted. Currently,
|
|
applying the slice operator produces a new Python sequence.
|
|
|
|
Example:
|
|
.. code-block:: python
|
|
|
|
# Define a new array class for ``int[]``
|
|
IntArrayCls = JArray(JInt)
|
|
|
|
# Create an array holding 10 elements
|
|
# equivalent to Java ``int[] x=new int[10]``
|
|
x = IntArrayCls(10)
|
|
|
|
# Create a length 3 array initialized with [1,2,3]
|
|
# equivalent to Java ``int[] x = new int[]{1,2,3};``
|
|
x = IntArrayCls([1,2,3])
|
|
|
|
# Operate on an array
|
|
print(len(x))
|
|
print(x[0])
|
|
print(x[:-2])
|
|
x[1:]=(5,6)
|
|
|
|
if isinstance(x, JArray):
|
|
print("object is a java array")
|
|
|
|
if issubclass(IntArrayCls, JArray):
|
|
print("class is a java array type.")
|
|
|
|
Args:
|
|
javaClass (str,type): Is the type of element to hold in
|
|
the array.
|
|
ndims (Optional,int): the number of dimensions of the array
|
|
(default=1)
|
|
|
|
Returns:
|
|
A new Python class that representing a Java array class.
|
|
|
|
Raises:
|
|
TypeError: if the component class is invalid or could not be found.
|
|
|
|
Note:
|
|
javaClass can be specified in three ways:
|
|
|
|
- as a string with the name of a java class.
|
|
- as a Java primitive type such as ``jpype.JInt``.
|
|
- as a Java class type such as ``java.lang.String``.
|
|
|
|
|
|
"""
|
|
def __new__(cls, tp, dims=1):
|
|
if cls != JArray:
|
|
raise TypeError("Arrays factory can't be used as type")
|
|
jc = _toJavaClass(tp)
|
|
return _jpype._newArrayType(jc, dims)
|
|
|
|
@classmethod
|
|
def of(cls, array, dtype=None):
|
|
return _jpype.arrayFromBuffer(array, dtype)
|
|
|
|
|
|
class _JArrayProto(object):
|
|
|
|
def __str__(self):
|
|
return str(list(self))
|
|
|
|
def __iter__(self):
|
|
return _JavaArrayIter(self)
|
|
|
|
def __reversed__(self):
|
|
for elem in self[::-1]:
|
|
yield elem
|
|
|
|
def clone(self):
|
|
""" Clone the Java array.
|
|
|
|
Create a "shallow" copy of a Java array. For a
|
|
single dimensional array of primitives, the cloned array is
|
|
complete independent copy of the original. For objects or
|
|
multidimensional arrays, the new array is a copy which points
|
|
to the same members as the original.
|
|
|
|
To obtain a deep copy of a Java array, use Java serialize and
|
|
deserialize operations to duplicate the entire array and
|
|
contents. In order to deep copy, the objects must be
|
|
Serializable.
|
|
|
|
Returns:
|
|
A shallow copy of the array.
|
|
"""
|
|
return _jpype.JClass("java.util.Arrays").copyOf(self, len(self))
|
|
|
|
|
|
def _toJavaClass(tp):
|
|
"""(internal) Converts a class type in python into a internal java class.
|
|
|
|
Used mainly to support JArray.
|
|
|
|
The type argument will operate on:
|
|
- (str) lookup by class name or fail if not found.
|
|
- (JClass) just returns the java type.
|
|
- (type) uses a lookup table to find the class.
|
|
"""
|
|
# if it a string than we lookup the class by name.
|
|
if isinstance(tp, str):
|
|
return _jpype._java_lang_Class.forName(tp)
|
|
|
|
# if is a java.lang.Class instance, then no coversion required
|
|
if isinstance(tp, _jpype._JClass):
|
|
return tp
|
|
|
|
# Okay then it must be a type
|
|
try:
|
|
return _jpype._type_classes[tp].class_
|
|
except KeyError:
|
|
pass
|
|
|
|
# See if it a class type
|
|
try:
|
|
return tp.class_
|
|
except AttributeError:
|
|
pass
|
|
|
|
raise TypeError("Unable to find class for '%s'" % tp.__name__)
|
|
|
|
|
|
# FIXME are these not sequences? They act like sequences but are they
|
|
# connected to collections.abc.Sequence
|
|
# has: __len__, __iter__, __getitem__
|
|
# missing: __contains__ (required for in)
|
|
# Cannot be Mutable because java arrays are fixed in length
|
|
|
|
|
|
class _JavaArrayIter(object):
|
|
def __init__(self, a):
|
|
self._array = a
|
|
self._ndx = -1
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
self._ndx += 1
|
|
if self._ndx >= len(self._array):
|
|
raise StopIteration
|
|
return self._array[self._ndx]
|
|
|
|
next = __next__
|
|
|
|
# **********************************************************
|
|
# Char array customizer
|
|
|
|
|
|
@_jcustomizer.JImplementationFor("byte[]")
|
|
@_jcustomizer.JImplementationFor("char[]")
|
|
class _JCharArray(object):
|
|
def __str__(self):
|
|
return str(_jpype.JString(self))
|
|
|
|
def __eq__(self, other):
|
|
if isinstance(other, str):
|
|
return str(self) == other
|
|
try:
|
|
return self.equals(self.__class__(other))
|
|
except TypeError:
|
|
return False
|
|
__hash__ = _jpype._JObject.__hash__
|
|
|
|
|
|
# Install module hooks
|
|
_jcustomizer._applyCustomizerPost(_jpype._JArray, _JArrayProto)
|
|
_jpype.JArray = JArray
|