blob: 859e0f94b52113389d566419fb238781b2c68f3b [file] [log] [blame]
# Copyright (c) The PyAMF Project.
# See LICENSE.txt for details.
"""
Compatibility classes/functions for Flex.
@note: Not available in ActionScript 1.0 and 2.0.
@see: U{Flex on Wikipedia<http://en.wikipedia.org/wiki/Adobe_Flex>}
@since: 0.1
"""
import pyamf
__all__ = ['ArrayCollection', 'ObjectProxy']
class ArrayCollection(list):
"""
I represent the ActionScript 3 based class
C{flex.messaging.io.ArrayCollection} used in the Flex framework.
The C{ArrayCollection} class is a wrapper class that exposes an Array
as a collection that can be accessed and manipulated using the
methods and properties of the `ICollectionView` or `IList`
interfaces in the Flex framework.
@see: U{ArrayCollection on Livedocs <http://
livedocs.adobe.com/flex/201/langref/mx/collections/ArrayCollection.html>}
@note: This class does not implement the RemoteObject part of the
documentation.
@ivar length: [read-only] The number of items in this collection.
Introduced in 0.4.
@type length: C{int}
"""
class __amf__:
external = True
amf3 = True
exclude = ('length',)
def __init__(self, source=None):
if source is not None:
if isinstance(source, dict):
raise TypeError('Cannot convert dicts to ArrayCollection')
if hasattr(source, '__iter__'):
self.extend(source)
def __repr__(self):
return "<flex.messaging.io.ArrayCollection %s>" % list.__repr__(self)
def __readamf__(self, input):
data = input.readObject()
if hasattr(data, 'source'):
data = data.source
else:
if not hasattr(data, '__iter__'):
raise pyamf.DecodeError('Unable to read a list when decoding '
'ArrayCollection')
self.extend(data)
def __writeamf__(self, output):
# meh, this needs to be re-thought out
output.encoder.writeList(list(self), is_proxy=True)
def _get_length(self):
return len(self)
def _set_length(self, length):
raise AttributeError("Property length is read-only")
length = property(_get_length, _set_length)
def addItem(self, item):
"""
Adds the specified item to the end of the list.
@param item: The object to add to the collection.
@since: 0.4
"""
self.append(item)
def addItemAt(self, item, index):
"""
Adds the item at the specified index.
@param item: The object to add to the collection.
@param index: The index at which to place the item.
@raise IndexError: If index is less than 0 or greater than the length
of the list.
@since: 0.4
"""
if index < 0 or index > len(self):
raise IndexError
self.insert(index, item)
def getItemAt(self, index, prefetch=0):
"""
Gets the item at the specified index.
@param index: The index in the list from which to retrieve the item.
@type index: C{int}
@param prefetch: This param is ignored and is only here as part of the
interface.
@raise IndexError: if `index < 0` or `index >= length`
@since: 0.4
"""
if index < 0:
raise IndexError
if index > len(self):
raise IndexError
return self.__getitem__(index)
def getItemIndex(self, item):
"""
Returns the index of the item if it is in the list such that
C{getItemAt(index) == item}.
@return: The index of the item or C{-1} if the item is not in the list.
@since: 0.4
"""
try:
return self.index(item)
except ValueError:
return -1
def removeAll(self):
"""
Removes all items from the list.
@since: 0.4
"""
while len(self) > 0:
self.pop()
def removeItemAt(self, index):
"""
Removes the item at the specified index and returns it. Any items that
were after this index are now one index earlier.
@param index: The index from which to remove the item.
@return: The item that was removed.
@raise IndexError: If index is less than 0 or greater than length.
@since: 0.4
"""
if index < 0 or index > len(self):
raise IndexError
x = self[index]
del self[index]
return x
def setItemAt(self, item, index):
"""
Places the item at the specified index. If an item was already at that
index the new item will replace it and it will be returned.
@return: The item that was replaced, or C{None}.
@raise IndexError: If index is less than 0 or greater than length.
@since: 0.4
"""
if index < 0 or index > len(self):
raise IndexError
tmp = self.__getitem__(index)
self.__setitem__(index, item)
return tmp
def toArray(self):
"""
Returns an Array that is populated in the same order as the C{IList}
implementation.
@return: The array.
@rtype: C{list}
"""
return self
class ObjectProxy(object):
"""
I represent the ActionScript 3 based class C{flex.messaging.io.ObjectProxy}
used in the Flex framework. Flex's C{ObjectProxy} class allows an anonymous,
dynamic ActionScript Object to be bindable and report change events.
@see: U{ObjectProxy on Livedocs<http://
livedocs.adobe.com/flex/201/langref/mx/utils/ObjectProxy.html>}
"""
class __amf__:
external = True
amf3 = True
def __init__(self, object=None):
if object is None:
self._amf_object = pyamf.ASObject()
else:
self._amf_object = object
def __repr__(self):
return "<flex.messaging.io.ObjectProxy %r>" % self._amf_object
def __getattr__(self, name):
if name == '_amf_object':
return self.__dict__['_amf_object']
return getattr(self.__dict__['_amf_object'], name)
def __setattr__(self, name, value):
if name == '_amf_object':
self.__dict__['_amf_object'] = value
else:
setattr(self._amf_object, name, value)
def __readamf__(self, input):
self._amf_object = input.readObject()
def __writeamf__(self, output):
output.encoder.writeObject(self._amf_object, is_proxy=True)
def unproxy_object(obj):
"""
Returns the unproxied version of the object.
"""
if isinstance(obj, ArrayCollection):
return list(obj)
elif isinstance(obj, ObjectProxy):
return obj._amf_object
return obj
def proxy_object(obj):
"""
Returns a proxied representation of C{obj}
Conversion
==========
- C{list}: L{ArrayCollection}
- C{dict}: L{ObjectProxy}
- Everything else: C{obj}
@since: 0.6
"""
if type(obj) in (list, tuple):
return ArrayCollection(obj)
if isinstance(obj, dict):
return ObjectProxy(obj)
return obj
pyamf.register_package(globals(), package='flex.messaging.io')