engine.py
draft!
import types from BTrees.IIBTree import IIBTree, intersection as IIintersection, IISet from BTrees.OIBTree import OIBTree from BTrees.IOBTree import IOBTree #from BTrees.OOBTree import OOBTree, intersection as OOintersection, OOSet from config import * from utils import mkintuid, getAttribute, getRelURL, unique from objectinformation import ObjectInformation from reference import Reference class ReferenceEngine: def __init__(self): self._sids = IIBTree() # source id -> reference id self._tids = IIBTree() # target id -> reference id self._rids = IOBTree() # reference id -> reference object self._data = IOBTree() # sid/tid -> data object containing zodb path and # other informations ... def registerObject(self, obj): if not ISimpleReferenceable.isImplementedBy(obj): raise Exception # XXX uid = self.getUidOf(obj) data = DataContainer(uid, physical_path = obj.getPhysicalPath(), id = obj.getId(), Type = getAttribute(obj, 'Type'), Title = getAttribute(obj, 'Title'), portal_name = getAttribute(obj, 'portal_name'), ) self._data[uid] = data self._sids[uid] = IISet() self._tids[uid] = IIset() def unregisterObject(self, obj_or_uid): if not isinstance(obj_or_uid, int) or not \ ISimpleReferenceable.isImplementedBy(obj_or_uid): raise Exception # XXX uid = self.getUidOf(obj_or_uid, generate=False) self.deleteReferences(uid) assert not self._sids.has_key(uid) assert not self._tids.has_key(uid) del self._data[uid] def getUidOf(self, obj_or_uid, generate=True): if isinstance(obj_or_uid, int) and self._data.has_key(obj_or_uid): return obj_or_uid uid = getattr(obj_or_uid, UID_ATTR, _marker) if uid is _marker and generate: uid = mdintuid() while self._data.has_key(uid): uid = mdintuid() setattr(obj, UID_ATTR, uid) if not isinstance(uid, int): raise Exception # XXX return uid def lookupObject(self, uid): data = self._data.get(uid, None) if data is None: raise Exception # XXX ppath = data.physical_path self.unrestrictedTraverse(ppath) def addReference(self, source, target, relationship, referenceClass=Reference, **kwargs): sid = self.getUidOf(source) tid = self.getUidOf(target) if not isinstance(relationship, types.StringTypes): raise Exception # XXX if not ISimpleReference.isImplementedByInstancesOf(referenceClass): raise Exception # XXX # XXX already existing reference? rid = mkintuid(sid, tid) ref = referenceClass(sid, tid, relationship, **kwargs) if ISimpleHookableReference.isImplementedByInstancesOf(referenceClass): sobj = self.lookupObject(sid) tobj = self.lookupObject(tid) ref.addHook(sobj, tobj) self._sids[sid].insert(rid) self._tids[tid].insert(rid) self._rids[rid] = ref def getReferenceIds(self, source, target, relationship=None): sid = self.getUidOf(source) tid = self.getUidOf(target) if not relationship is None or not isinstance(relationship, types.StringTypes): raise Exception # XXX def deleteReference(self, source, target, relationship=None): sid = self.getUidOf(source) tid = self.getUidOf(target) if not relationship is None or not isinstance(relationship, types.StringTypes): raise Exception # XXX # XXX TODO def deleteReferences(self, obj_or_uid, relationship=None): # XXX pass