Commit by: vajda Modified files: chandler/application/Parcel.py 1.40 1.41 chandler/parcels/osaf/framework/sharing/ICalendar.py 1.4 1.5 chandler/parcels/osaf/framework/sharing/Sharing.py 1.47 1.48 chandler/repository/item/Item.py 1.187 1.188 chandler/repository/item/ItemHandler.py 1.63 1.64 chandler/repository/item/ItemIO.py 1.2 1.3 chandler/repository/persistence/DBItemIO.py 1.4 1.5 chandler/repository/schema/Kind.py 1.97 1.98 chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr 1.8 1.9
Log message: - added checking of 'required' aspect to Item.check() - added Kind.instantiateItem() to replace Parcel.NewItem() ViewCVS links: http://cvs.osafoundation.org/index.cgi/chandler/application/Parcel.py.diff?r1=text&tr1=1.40&r2=text&tr2=1.41 http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/sharing/ICalendar.py.diff?r1=text&tr1=1.4&r2=text&tr2=1.5 http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/sharing/Sharing.py.diff?r1=text&tr1=1.47&r2=text&tr2=1.48 http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Item.py.diff?r1=text&tr1=1.187&r2=text&tr2=1.188 http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemHandler.py.diff?r1=text&tr1=1.63&r2=text&tr2=1.64 http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemIO.py.diff?r1=text&tr1=1.2&r2=text&tr2=1.3 http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/DBItemIO.py.diff?r1=text&tr1=1.4&r2=text&tr2=1.5 http://cvs.osafoundation.org/index.cgi/chandler/repository/schema/Kind.py.diff?r1=text&tr1=1.97&r2=text&tr2=1.98 http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr.diff?r1=text&tr1=1.8&r2=text&tr2=1.9 Index: chandler/application/Parcel.py diff -u chandler/application/Parcel.py:1.40 chandler/application/Parcel.py:1.41 --- chandler/application/Parcel.py:1.40 Tue Jan 25 12:40:39 2005 +++ chandler/application/Parcel.py Tue Jan 25 19:03:33 2005 @@ -1565,26 +1565,6 @@ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def NewItem(view, name, parent, kind, uuid): - """ Create an item of a given UUID """ - - cls = kind.getItemClass() - values = repository.item.Values.Values(None) - refs = repository.item.Values.References(None) - item = cls.__new__(cls) - item._fillItem(name, parent, kind, uuid=uuid, version=0L, values=values, - references=refs) - values._setItem(item) - refs._setItem(item) - item._status |= Item.NEW - kind.getInitialValues(item, item._values, item._references) - kind._setupClass(cls) - if hasattr(cls, 'onItemLoad'): - item.onItemLoad(view) - return item - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def PrintItem(path, rep, recursive=False, level=0): """ A pretty-printer for repository items. Index: chandler/parcels/osaf/framework/sharing/ICalendar.py diff -u chandler/parcels/osaf/framework/sharing/ICalendar.py:1.4 chandler/parcels/osaf/framework/sharing/ICalendar.py:1.5 --- chandler/parcels/osaf/framework/sharing/ICalendar.py:1.4 Tue Jan 25 13:49:38 2005 +++ chandler/parcels/osaf/framework/sharing/ICalendar.py Tue Jan 25 19:03:33 2005 @@ -199,9 +199,8 @@ uuid = UUID() # @@@MOR This needs to use the new defaultParent framework # to determine the parent - eventItem = application.Parcel.NewItem(self.itsView, - None, self.itsView.findPath("//userdata"), - eventKind, uuid) + parent = self.findPath("//userdata") + eventItem = eventKind.instantiateItem(None, parent, uuid) countNew += 1 eventItem.displayName = displayName @@ -241,4 +240,4 @@ """Treat multiple events as different resources.""" def fileStyle(self): - return self.STYLE_DIRECTORY \ No newline at end of file + return self.STYLE_DIRECTORY Index: chandler/repository/persistence/DBItemIO.py diff -u chandler/repository/persistence/DBItemIO.py:1.4 chandler/repository/persistence/DBItemIO.py:1.5 --- chandler/repository/persistence/DBItemIO.py:1.4 Tue Jan 25 12:40:45 2005 +++ chandler/repository/persistence/DBItemIO.py Tue Jan 25 19:03:34 2005 @@ -1,6 +1,6 @@ -__revision__ = "$Revision: 1.4 $" -__date__ = "$Date: 2005/01/25 20:40:45 $" +__revision__ = "$Revision: 1.5 $" +__date__ = "$Date: 2005/01/26 03:03:34 $" __copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" @@ -32,7 +32,7 @@ self.values = [] - if not item.isNew(): + if not (item.isNew() or item._version == 0): self.oldValues = self.store._items.getItemValues(item._version, item._uuid) else: @@ -137,12 +137,12 @@ self.moduleName = moduleName self.className = className - def _children(self, item, version, isNew): + def _children(self, item, version, all): if item._children is not None: item._children._saveValues(version) - def _acls(self, item, version, isNew): + def _acls(self, item, version, all): if item._status & Item.ADIRTY: store = self.store @@ -150,13 +150,13 @@ for name, acl in item._acls.iteritems(): store.saveACL(version, uuid, name, acl) - def _values(self, item, version, withSchema, isNew): + def _values(self, item, version, withSchema, all): - item._values._writeValues(self, version, withSchema, isNew) + item._values._writeValues(self, version, withSchema, all) - def _references(self, item, version, withSchema, isNew): + def _references(self, item, version, withSchema, all): - item._references._writeValues(self, version, withSchema, isNew) + item._references._writeValues(self, version, withSchema, all) def _value(self, item, name, value, version, flags, withSchema, attribute): @@ -379,12 +379,12 @@ elif isinstance(value, ItemValue): value._setItem(item, name) - if hasattr(cls, 'onItemLoad'): - afterLoadHooks.append(item.onItemLoad) - if kind is not None: afterLoadHooks.append(lambda view: kind._setupClass(cls)) + if hasattr(cls, 'onItemLoad'): + afterLoadHooks.append(item.onItemLoad) + return item def readString(self, offset, data): Index: chandler/parcels/osaf/framework/sharing/Sharing.py diff -u chandler/parcels/osaf/framework/sharing/Sharing.py:1.47 chandler/parcels/osaf/framework/sharing/Sharing.py:1.48 --- chandler/parcels/osaf/framework/sharing/Sharing.py:1.47 Tue Jan 25 16:23:42 2005 +++ chandler/parcels/osaf/framework/sharing/Sharing.py Tue Jan 25 19:03:33 2005 @@ -1,5 +1,5 @@ -__version__ = "$Revision: 1.47 $" -__date__ = "$Date: 2005/01/26 00:23:42 $" +__version__ = "$Revision: 1.48 $" +__date__ = "$Date: 2005/01/26 03:03:33 $" __copyright__ = "Copyright (c) 2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" @@ -1219,8 +1219,9 @@ if uuid: # @@@MOR This needs to use the new defaultParent framework # to determine the parent - item = application.Parcel.NewItem(self.itsView, None, - self.itsView.findPath("//userdata"), kind, uuid) + parent = self.findPath("//userdata") + item = kind.instantiateItem(None, parent, uuid, + withInitialValues=True) else: item = kind.newItem(None, None) # print "created item", item.itsPath, item.itsKind Index: chandler/repository/item/ItemIO.py diff -u chandler/repository/item/ItemIO.py:1.2 chandler/repository/item/ItemIO.py:1.3 --- chandler/repository/item/ItemIO.py:1.2 Tue Jan 18 15:31:17 2005 +++ chandler/repository/item/ItemIO.py Tue Jan 25 19:03:34 2005 @@ -1,6 +1,6 @@ -__revision__ = "$Revision: 1.2 $" -__date__ = "$Date: 2005/01/18 23:31:17 $" +__revision__ = "$Revision: 1.3 $" +__date__ = "$Date: 2005/01/26 03:03:34 $" __copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" @@ -28,11 +28,11 @@ self._className(None, None) if status & Item.DELETED == 0: - isNew = (status & Item.NEW) != 0 - self._values(item, version, withSchema, isNew) - self._references(item, version, withSchema, isNew) - self._children(item, version, isNew) - self._acls(item, version, isNew) + all = (status & Item.NEW) != 0 or item._version == 0 + self._values(item, version, withSchema, all) + self._references(item, version, withSchema, all) + self._children(item, version, all) + self._acls(item, version, all) def writeString(self, buffer, value): raise NotImplementedError, "%s.writeString" %(type(self)) @@ -76,7 +76,7 @@ def _className(self, moduleName, className): raise NotImplementedError, "%s._className" %(type(self)) - def _values(self, item, version, withSchema, isNew): + def _values(self, item, version, withSchema, all): raise NotImplementedError, "%s._values" %(type(self)) def _value(self, item, name, value, version, flags, withSchema, attribute): @@ -85,13 +85,13 @@ def _unchangedValue(self, item, name): raise NotImplementedError, "%s._unchangedValue" %(type(self)) - def _references(self, item, version, withSchema, isNew): + def _references(self, item, version, withSchema, all): raise NotImplementedError, "%s._references" %(type(self)) - def _children(self, item, version, isNew): + def _children(self, item, version, all): raise NotImplementedError, "%s._children" %(type(self)) - def _acls(self, item, version, isNew): + def _acls(self, item, version, all): raise NotImplementedError, "%s._acls" %(type(self)) @@ -144,16 +144,16 @@ self.generator.characters(parent.itsUUID.str16()) self.generator.endElement('parent') - def _values(self, item, version, withSchema, isNew): + def _values(self, item, version, withSchema, all): item._values._xmlValues(self.generator, withSchema, version) - def _references(self, item, version, withSchema, isNew): + def _references(self, item, version, withSchema, all): item._references._xmlValues(self.generator, withSchema, version) - def _children(self, item, version, isNew): + def _children(self, item, version, all): pass - def _acls(self, item, version, isNew): + def _acls(self, item, version, all): pass Index: chandler/repository/item/Item.py diff -u chandler/repository/item/Item.py:1.187 chandler/repository/item/Item.py:1.188 --- chandler/repository/item/Item.py:1.187 Tue Jan 25 12:40:42 2005 +++ chandler/repository/item/Item.py Tue Jan 25 19:03:34 2005 @@ -1,6 +1,6 @@ -__revision__ = "$Revision: 1.187 $" -__date__ = "$Date: 2005/01/25 20:40:42 $" +__revision__ = "$Revision: 1.188 $" +__date__ = "$Date: 2005/01/26 03:03:34 $" __copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" @@ -28,13 +28,12 @@ Construct an Item. @param name: The name of the item. It must be unique among the names - this item's siblings. C{name} be C{None} in which case the base64 - string representation of this item's C{UUID} becomes its name. + this item's siblings. C{name} may be C{None}. @type name: a string or C{None} to create an anonymous item. @param parent: The parent of this item. All items require a parent unless they are a repository root in which case the parent argument is the repository. - @type parent: an item + @type parent: an item or the item's repository view @param kind: The kind for this item. This kind has definitions for all the Chandler attributes that are to be used with this item. This parameter can be C{None} for Chandler attribute-less operation. @@ -720,6 +719,14 @@ checkValues = self._values.check() checkRefs = self._references.check() result = checkValues and checkRefs + + kind = self._kind + if kind is not None: + for name, desc in kind._getDescriptors(type(self)).iteritems(): + attrDict, required = desc.isValueRequired(self) + if required and name not in attrDict: + self.itsView.logger.error("Required value for attribute %s on %s is missing", name, self._repr_()) + result = False if recursive and self._children is not None: l = len(self._children) Index: chandler/repository/item/ItemHandler.py diff -u chandler/repository/item/ItemHandler.py:1.63 chandler/repository/item/ItemHandler.py:1.64 --- chandler/repository/item/ItemHandler.py:1.63 Tue Jan 25 12:40:42 2005 +++ chandler/repository/item/ItemHandler.py Tue Jan 25 19:03:34 2005 @@ -1,6 +1,6 @@ -__revision__ = "$Revision: 1.63 $" -__date__ = "$Date: 2005/01/25 20:40:42 $" +__revision__ = "$Revision: 1.64 $" +__date__ = "$Date: 2005/01/26 03:03:34 $" __copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" @@ -576,9 +576,9 @@ else: refArgs._setValue(self.repository) + self.afterLoadHooks.append(self.setupClass) if hasattr(cls, 'onItemLoad'): self.afterLoadHooks.append(item.onItemLoad) - self.afterLoadHooks.append(self.setupClass) def setupClass(self, view): Index: chandler/repository/schema/Kind.py diff -u chandler/repository/schema/Kind.py:1.97 chandler/repository/schema/Kind.py:1.98 --- chandler/repository/schema/Kind.py:1.97 Tue Jan 25 12:40:46 2005 +++ chandler/repository/schema/Kind.py Tue Jan 25 19:03:35 2005 @@ -1,13 +1,13 @@ -__revision__ = "$Revision: 1.97 $" -__date__ = "$Date: 2005/01/25 20:40:46 $" +__revision__ = "$Revision: 1.98 $" +__date__ = "$Date: 2005/01/26 03:03:35 $" __copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation" __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm" from new import classobj from repository.item.Item import Item -from repository.item.Values import ItemValue +from repository.item.Values import ItemValue, Values, References from repository.item.PersistentCollections import PersistentCollection from repository.item.ItemError import NoSuchAttributeError, SchemaError from repository.persistence.RepositoryError import RecursiveLoadItemError @@ -94,17 +94,27 @@ kinds[uuid].remove(cls) classes[cls].remove(uuid) - def _setupDescriptors(self, cls, sync=False): + def _getDescriptors(self, cls): + + return Kind._descriptors.get(cls, {}) + + def _setupDescriptors(self, cls, sync=None): try: descriptors = Kind._descriptors[cls] except KeyError: descriptors = Kind._descriptors[cls] = {} - if sync: - attributes = self.getAttributeValue('attributes', - _attrDict=self._references, - default=[]) + if sync is not None: + if sync == 'attributes': + attributes = self.getAttributeValue('attributes', + _attrDict=self._references, + default=[]) + elif sync == 'superKinds': + attributes = set([a._uuid for n, a, k in self.iterAttributes()]) + else: + raise AssertionError, sync + for name, descriptor in descriptors.items(): attr = descriptor.getAttribute(self) if not (attr is None or attr[0] in attributes): @@ -123,15 +133,86 @@ else: self.itsView.logger.warn("Not installing attribute descriptor for '%s' since it would shadow already existing descriptor: %s", name, descriptor) - def newItem(self, name, parent): + def newItem(self, name, parent, cls=None): """ - Create an item of this kind. + Create an new item of this kind. The python class instantiated is taken from the Kind's classes attribute if it is set. The Item class is used otherwise. + + The item's constructor is invoked. + + @param name: The name of the item. It must be unique among the names + this item's siblings. C{name} may be C{None}. + @type name: a string or C{None} to create an anonymous item. + @param parent: The parent of this item. All items require a parent + unless they are a repository root in which case the parent argument + is the repository. + @type parent: an item or the item's repository view + @param cls: an optional python class to instantiate the item with, + defaults to the class set on this kind. + @type cls: a python new style class, that is, a type instance """ + + if cls is None: + cls = self.getItemClass() - return self.getItemClass()(name, parent, self) + return cls(name, parent, self) + + def instantiateItem(self, name, parent, uuid, + cls=None, version=0, withInitialValues=False): + """ + Instantiate an existing item of this kind. + + This method is intended to help in instantiating an existing item, + that is an item in this or another repository for which there + already exists a UUID. + + The item's constructor is not invoked, the item's onItemLoad + method is invoked if defined. + + @param name: The name of the item. It must be unique among the names + this item's siblings. C{name} may be C{None}. + @type name: a string or C{None} to create an anonymous item. + @param parent: The parent of this item. All items require a parent + unless they are a repository root in which case the parent argument + is the repository. + @type parent: an item or the item's repository view + @param uuid: The uuid for the item. + @type uuid: L{UUID<chandlerdb.util.UUID.UUID>} + @param cls: an optional python class to instantiate the item with, + defaults to the class set on this kind. + @type cls: a python new style class, that is, a type instance + @param version: the optional version of this item instance, zero by + default. + @type version: integer + @param withInitialValues: optionally set the initial values for + attributes as specified in this Kind's attribute definitions. + @type withInitialValues: boolean + """ + + if cls is None: + cls = self.getItemClass() + + values = Values(None) + references = References(None) + + item = cls.__new__(cls) + item._fillItem(name, parent, self, + uuid=uuid, version=version, + values=values, references=references) + + values._setItem(item) + references._setItem(item) + self._setupClass(cls) + + if withInitialValues: + self.getInitialValues(item, values, references) + + if hasattr(cls, 'onItemLoad'): + item.onItemLoad(self.itsView) + + return item def getItemClass(self): """ @@ -654,13 +735,18 @@ def registerAttribute(self, kind, attribute): - if 'otherName' in attribute._values: + values = attribute._values + + if 'otherName' in values: flags = Descriptor.REF - elif 'redirectTo' in attribute._values: + elif 'redirectTo' in values: flags = Descriptor.REDIRECT else: flags = Descriptor.VALUE + if values.get('required', False): + flags |= Descriptor.REQUIRED + self.attrs[kind._uuid] = (attribute._uuid, flags) def unregisterAttribute(self, kind): @@ -672,6 +758,17 @@ return self.attrs.get(kind._uuid, None) + def isValueRequired(self, item): + + try: + attrID, flags = self.attrs[item._kind._uuid] + except KeyError: + return None, False + else: + attrDict = self.getAttrDict(item, flags) + return attrDict, (attrDict is not None and + flags & Descriptor.REQUIRED != 0) + def getName(self): return self.name @@ -753,7 +850,8 @@ VALUE = 0x0001 REF = 0x0002 REDIRECT = 0x0004 - + REQUIRED = 0x0008 + class SchemaMonitor(Monitor): @@ -764,4 +862,4 @@ logger = kind.itsView.logger for cls in Kind._kinds.get(kind._uuid, []): logger.warning('Change in %s caused syncing of attribute descriptors on class %s.%s for Kind %s', attrName, cls.__module__, cls.__name__, kind.itsPath) - kind._setupDescriptors(cls, True) + kind._setupDescriptors(cls, attrName) Index: chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr diff -u chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr:1.8 chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr:1.9 --- chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr:1.8 Tue Oct 14 10:47:18 2003 +++ chandler/repository/tests/data/packs/cineguide/schema/attributes/FrenchTitle.attr Tue Jan 25 19:03:35 2005 @@ -6,6 +6,5 @@ <ref name="type" type="path">//Schema/Core/String</ref> <attribute name="cardinality">single</attribute> - <attribute name="required">True</attribute> <attribute name="inheritFrom">title</attribute> </item> _______________________________________________ Commits mailing list Commits@osafoundation.org http://lists.osafoundation.org/mailman/listinfo/commits