1 #=======================================================================
3 __version__
= '''0.1.47'''
4 __sub_version__
= '''20061124145351'''
5 __copyright__
= '''(c) Alex A. Naanou 2003'''
8 #-----------------------------------------------------------------------
10 ##from __future__ import generators
13 import pli
.functional
as func
14 from pli
.functional
import curry
15 ##!!! this might change in the future...
16 import pli
.objutils
as objutils
27 #-----------------------------------------------------------------------
28 #-----------------------------------------------------------isinstore---
31 this function will return a predicate that will check if an object
32 exists in a given store (to be used mainly for auto type checking).
34 return lambda oid
: oid
in store
37 #---------------------------------------------------------r_isinstore---
38 def r_isinstore(store
, excep
=None, msg
=None):
40 this will cunstruct a test function that will test if an object exists
41 in a given store or raise an exception.
43 name
= hasattr(store
, '__name__') and store
.__name
__ or store
.__class
__.__name
__
44 return func
.raise_on_false(isinstore(store
), 'r_isin' + name
,\
45 excep
!= None and NameError \
47 msg
!= None and ('object not found in store %s.' % store
) \
51 #----------------------------------------------isinstore_and_isoftype---
52 def isinstore_and_isoftype(store
):
54 this will generate a function (takes store as argument) that will in turn
55 construct a function (takes object type as argument) that will test if
56 obj (key) is in store and is (value) of a given type...
59 NOTE: sorry, but this might not be the most obvios of functions (atleast
60 at the first sight!) :)
62 return lambda otype
: \
63 lambda obj
: isinstore(store
)(obj
) and type(store
[obj
]) == otype
67 #-----------------------------------------------------------------------
68 # TODO rework this into mixins....
69 #------------------------------------------StaticStoreClientWithOwner---
71 class OwnedStaticStoreClient(storeclient
.StaticStoreClient
):
75 __ignore_nonexistant_filter_attrs__
= True
77 def __init__(self
, owner
, flags
=0):
80 self
._store
_flags
= flags
81 self
.__owner
__ = owner
82 store
.StaticStoreClient
.__init
__(self
, filters
={'__owner__':owner
})
83 def __getattr__(self
, name
):
86 # deligate the call to the original store object
89 cls
= store
.StaticStoreClient
.__getattr
__(self
, name
)
90 if issubclass(cls
, OwnedStoredObjectWithAttrs
):
91 return curry(cls
, owner
=self
.__owner
__)
93 def isaccessible(self
, key
):
96 obj
= self
._store
_data
[key
]
98 if self
._store
_flags
& SHOW_ALL
:
100 ## if hasattr(obj, '__store_public__') and obj.__store_public__:
102 ##!!! is this needed...
103 if not hasattr(self
, '__owner__') or self
.__owner
__ in ('', None):
105 # this might be a litle slower, but it is more flexible...
106 return super(OwnedStaticStoreClient
, self
).isaccessible(key
)
108 ## for attr, val in self._store_filters.items():
110 ## res += [getattr(obj, attr) == val]
111 ## except AttributeError:
113 ## if False not in res:
119 #-----------------------------------------------------------------------
120 #-----------------------------------------------StoredObjectWithAttrs---
121 class StoredObjectWithAttrs(objutils
.ObjectWithAttrs
, stored
.StoredObject
):
123 a generic stored object class with attribute creation an update automation.
125 this class checks attribute format.
128 # this will restrict the attribute that can be created for this
129 # object to the ones mentioned in the list (DO NOT SET HERE!).
130 ## __attr_format__ = ()
131 # this defines a list of attributes that must be defined on object
133 ## __essential_attrs__ = ()
134 # this defines the callbacks for attr update... (RPC only at the
136 ## __attr_update_callbacks__ = {}
137 # this will enable attribute type checking...
138 __check_attr_types__
= True
139 # this defines the values to be considered as no-vals...
140 __none_values__
= ('', 'None', None)
143 __readonly_attrs__
= ()
145 ##!! temporary -- this is a fix to allow zodbs special attrs... !!##
146 def __setattr__(self
, name
, val
):
149 return object.__setattr
__(self
, name
, val
)
152 #------------------------------------------OwnedStoredObjectWithAttrs---
153 class OwnedStoredObjectWithAttrs(StoredObjectWithAttrs
):
156 __store_public__
= False
158 def __init__(self
, name
, attrs
={}, owner
=''):
161 super(OwnedStoredObjectWithAttrs
, self
).__init
__(name
, attrs
)
162 if not hasattr(self
, '__owner__'):
163 self
.__owner
__ = owner
167 #-----------------------------------------------------------------------
168 #-----------------------------------------------------------TreeStore---
169 class TreeStore(store
.BaseStore
):
172 def __delitem__(self
, key
):
176 if hasattr(obj
, 'children') and len(obj
.children
) != 0:
177 raise TypeError, 'can\'t remove, not empty object "%s"' % key
178 if obj
.parent
!= None:
179 self
[obj
.parent
].children
.remove(key
)
180 super(TreeStore
, self
).__delitem
__(key
)
181 # TODO make this non-recursive...
182 def get_tree_dict(self
, node_id
=None):
184 this will return a nested dict of the form:
185 {<node_id>: <children>[, ...]}
186 where <children> is a dict of the same format.
189 if node_id
not in self
:
190 raise KeyError, 'object "%s" is not in store "%s".' % (node_id
, self
.__name
__)
194 root_obj
= self
[root
]
196 return dict([(n
, self
.get_tree_dict(n
)) for n
in (hasattr(root_obj
, 'children') and root_obj
.children
or [])])
197 def get_tree(self
, node_id
=None):
199 this will return a nested tuple of the form:
200 ((<node_id>, <children>)[, ...])
201 where <children> is a dict of the same format.
204 if node_id
not in self
:
205 raise KeyError, 'object "%s" is not in store "%s".' % (node_id
, self
.__name
__)
209 root_obj
= self
[root
]
211 return [[n
, self
.get_tree(n
)] for n
in (hasattr(root_obj
, 'children') and root_obj
.children
or ())]
214 #------------------------------------------------------------TreeNode---
215 # Q: is it posible to make this store.StoredObject subclass???
216 class TreeNode(StoredObjectWithAttrs
):
220 # this will automatcly register the class as a store type...
221 __auto_register_type__
= False
223 __essential_attrs__
= (
224 'parent', # str (parent folder id)
226 ## __attr_format__ = __essential_attrs__ + \
230 __readonly_attrs__
= StoredObjectWithAttrs
.__readonly
_attrs
__ + \
235 def __init__(self
, *p
, **n
):
238 super(TreeNode
, self
).__init
__(*p
, **n
)
240 ## if self.parent not in ('None', None):
241 ## if self.parent not in self.__store__:
242 ## raise TypeError, 'can\'t attach to a non-existant object "%s".' % self.parent
244 self
.__readonly
_attrs
__ = self
.__readonly
_attrs
__ + ('parent',)
245 def update(self
, data
):
249 parent
= data
['parent']
251 if parent
not in ('None', None):
252 if parent
not in self
.__store
__:
253 raise TypeError, 'can\'t attach to a non-existant object "%s".' % parent
254 if hasattr(self
, 'parent'):
255 # detach from old parent... (on move)
256 self
.__store
__[self
.parent
].children
.remove(self
.__name
__)
258 res
= super(TreeNode
, self
).update(data
)
259 # atach to new parent...
260 self
.__store
__[parent
].children
+= [self
.__name
__]
264 return super(TreeNode
, self
).update(data
)
268 ###-----------------------------------------------------------------------
269 ##class CallproxyWrapper(object):
274 ## def __getattr__(self, name):
277 ## return self.__proxy__(super(Wrapper, self).__getattr__(name))
280 ##class CallproxyWrapperStore(store.BaseStore):
284 ## __wrapper__ = Wrapper
286 ## def __getitem__(self, name):
289 ## return super(CallproxyWrapperStore, self).__getitem__(name)
293 #=======================================================================
294 # vim:set ts=4 sw=4 nowrap :