[Zope3-checkins] CVS: Zope3/lib/python/Zope/App/DublinCore - General.py:1.2 ICMFDublinCore.py:1.2 IZopeDublinCore.py:1.2 IZopeDublinCoreAnnotatable.py:1.2 PropertySchemas.py:1.2 TimeAnnotators.py:1.2 ZDCAnnotatableAdapter.py:1.2 ZopeDublinCore.py:1.2 __init__.py:1.2 configure.zcml:1.2

Jim Fulton jim@zope.com
Fri, 4 Oct 2002 15:06:21 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/DublinCore
In directory cvs.zope.org:/tmp/cvs-serv26302/lib/python/Zope/App/DublinCore

Added Files:
	General.py ICMFDublinCore.py IZopeDublinCore.py 
	IZopeDublinCoreAnnotatable.py PropertySchemas.py 
	TimeAnnotators.py ZDCAnnotatableAdapter.py ZopeDublinCore.py 
	__init__.py configure.zcml 
Log Message:

Added initial Dublin-Core meta-data support. This inclused a number of
interfaces, including:

  - Low level interfaces for reading and writing dublin core data in
    it's full generality, including qualifiers and repeated values.

  - A clone of the CMF DublinCore query interface with a wart fixed
    (having to do with a method that Tres and I agreed should have a
    sequence value but that has a scalar value in the CMF).

  - A number of small interfaces defining properties for common
    fields. (e.g. title, description, modified, properties).
   
Also included:

  - An adapter for managing Dublin-Core data on annotatable objects.

  - A first cut at a view for editing DC data on annotatable objects.
    This needs more thought. For example, perhaps subjects should come
    from a centralized vocabulary.

    For now, it just lets you edit title and description.

  - A pair of global event subscribers that catch creation and
    modification events and set the DC created and modified
    properties.

There's still a good bit left to do, including:

  - Sorting out how elements like type, identifier, format should be
    gotten. 

  - There should be some sort of framework for instructing the DC
    adapter to get and set some elements from the content. For
    example, some meta-data, like title or type, could simply mirror
    content data or methods.




=== Zope3/lib/python/Zope/App/DublinCore/General.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/General.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,209 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""Interfaces for getting standard dublin core data in it's full generality
+
+$Id$
+"""
+
+from Interface import Interface
+from Zope.Schema import Text
+
+class IDublinCoreElementItem(Interface):
+    """A qualified sublin core element"""
+
+    qualification = Text(title = u"Qualification",
+                         description = u"The element qualification"
+                         )
+
+    value = Text(title = u"Value",
+                 description = u"The element value",
+                 )
+    
+
+class IGeneralDublinCore(Interface):
+    """Dublin-core data access interface
+
+    The Dublin Core, http://dublincore.org/, is a meta data standard
+    that specifies a set of standard data elements. It provides
+    flexibility of interpretation of these elements by providing for
+    element qualifiers that specialize the meaning of specific
+    elements. For example, a date element might have a qualifier, like
+    "creation" to indicate that the date is a creation date. In
+    addition, any element may be repeated. For some elements, like
+    subject, and contributor, this is obviously necessary, but for
+    other elements, like title and description, allowing repetitions
+    is not very useful and adds complexity.
+
+    This interface provides methods for retrieving data in full
+    generality, to be complient with the dublin core standard.
+    Other interfaces will provide more convenient access methods
+    tailored to specific element usage patterns.
+    """
+
+    def getQualifiedTitles():
+        """Return a sequence of Title IDublinCoreElementItem. 
+        """
+
+    def getQualifiedCreators():
+        """Return a sequence of Creator IDublinCoreElementItem. 
+        """
+
+    def getQualifiedSubjects():
+        """Return a sequence of Subject IDublinCoreElementItem. 
+        """
+
+    def getQualifiedDescriptions():
+        """Return a sequence of Description IDublinCoreElementItem. 
+        """
+
+    def getQualifiedPublishers():
+        """Return a sequence of Publisher IDublinCoreElementItem. 
+        """
+
+    def getQualifiedContributors():
+        """Return a sequence of Contributor IDublinCoreElementItem. 
+        """
+
+    def getQualifiedDates():
+        """Return a sequence of Date IDublinCoreElementItem. 
+        """
+
+    def getQualifiedTypes():
+        """Return a sequence of Type IDublinCoreElementItem. 
+        """
+
+    def getQualifiedFormats():
+        """Return a sequence of Format IDublinCoreElementItem. 
+        """
+
+    def getQualifiedIdentifiers():
+        """Return a sequence of Identifier IDublinCoreElementItem. 
+        """
+
+    def getQualifiedSources():
+        """Return a sequence of Source IDublinCoreElementItem. 
+        """
+
+    def getQualifiedLanguages():
+        """Return a sequence of Language IDublinCoreElementItem. 
+        """
+
+    def getQualifiedRelations():
+        """Return a sequence of Relation IDublinCoreElementItem. 
+        """
+
+    def getQualifiedCoverages():
+        """Return a sequence of Coverage IDublinCoreElementItem. 
+        """
+
+    def getQualifiedRights():
+        """Return a sequence of Rights IDublinCoreElementItem. 
+        """
+
+class IWritableGeneralDublinCore(Interface):
+    """Provide write access to dublin core data
+
+    This interface augments IStandardDublinCore with methods for
+    writing elements.
+    """
+    
+    def setQualifiedTitles(qualified_titles):
+        """Set the qualified Title elements.
+
+        The argument must be a sequence of IDublinCoreElementItem.
+        """
+
+    def setQualifiedCreators(qualified_creators):
+        """Set the qualified Creator elements.
+        
+        The argument must be a sequence of Creator IDublinCoreElementItem. 
+        """
+
+    def setQualifiedSubjects(qualified_subjects): 
+        """Set the qualified Subjects elements.
+
+        The argument must be a sequence of Subject IDublinCoreElementItem. 
+        """
+
+    def setQualifiedDescriptions(qualified_descriptions):
+        """Set the qualified Descriptions elements.
+
+        The argument must be a sequence of Description IDublinCoreElementItem. 
+        """
+
+    def setQualifiedPublishers(qualified_publishers):
+        """Set the qualified Publishers elements.
+
+        The argument must be a sequence of Publisher IDublinCoreElementItem. 
+        """
+
+    def setQualifiedContributors(qualified_contributors):
+        """Set the qualified Contributors elements.
+
+        The argument must be a sequence of Contributor IDublinCoreElementItem. 
+        """
+
+    def setQualifiedDates(qualified_dates):
+        """Set the qualified Dates elements.
+
+        The argument must be a sequence of Date IDublinCoreElementItem. 
+        """
+
+    def setQualifiedTypes(qualified_types):
+        """Set the qualified Types elements.
+
+        The argument must be a sequence of Type IDublinCoreElementItem. 
+        """
+
+    def setQualifiedFormats(qualified_formats):
+        """Set the qualified Formats elements.
+
+        The argument must be a sequence of Format IDublinCoreElementItem. 
+        """
+
+    def setQualifiedIdentifiers(qualified_identifiers):
+        """Set the qualified Identifiers elements.
+
+        The argument must be a sequence of Identifier IDublinCoreElementItem. 
+        """
+
+    def setQualifiedSources(qualified_sources):
+        """Set the qualified Sources elements.
+
+        The argument must be a sequence of Source IDublinCoreElementItem. 
+        """
+
+    def setQualifiedLanguages(qualified_languages):
+        """Set the qualified Languages elements.
+
+        The argument must be a sequence of Language IDublinCoreElementItem. 
+        """
+
+    def setQualifiedRelations(qualified_relations):
+        """Set the qualified Relations elements.
+
+        The argument must be a sequence of Relation IDublinCoreElementItem. 
+        """
+
+    def setQualifiedCoverages(qualified_coverages):
+        """Set the qualified Coverages elements.
+
+        The argument must be a sequence of Coverage IDublinCoreElementItem. 
+        """
+
+    def setQualifiedRights(qualified_rights):
+        """Set the qualified Rights elements.
+
+        The argument must be a sequence of Rights IDublinCoreElementItem. 
+        """


=== Zope3/lib/python/Zope/App/DublinCore/ICMFDublinCore.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/ICMFDublinCore.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,180 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+from Interface import Interface
+
+class ICMFDublinCore(Interface):
+    """This interface duplicates the CMF dublinc core interface.
+    """
+    
+    def Title():
+        """Return the resource title.
+
+        The first unqualified Dublin Core 'Title' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned.
+        """
+            
+    def Creator():
+        """Return the resource creators.
+
+        Return the full name(s) of the author(s) of the content
+        object.
+
+        The unqualified Dublin Core 'Creator' element values are
+        returned as a sequence of unicode strings.
+        """
+
+    def Subject():
+        """Return the resource subjects.
+
+        The unqualified Dublin Core 'Subject' element values are
+        returned as a sequence of unicode strings.
+        """
+
+    def Description():
+        """Return the resource description
+
+        Return a natural language description of this object.
+
+        The first unqualified Dublin Core 'Description' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned.
+        """
+
+    def Publisher():
+        """Dublin Core element - resource publisher
+
+        Return full formal name of the entity or person responsible
+        for publishing the resource.
+
+        The first unqualified Dublin Core 'Publisher' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned.        
+        """
+
+    def Contributors():
+        """Return the resource contributors
+
+        Return any additional collaborators.
+        
+        The unqualified Dublin Core 'Contributor' element values are
+        returned as a sequence of unicode strings.
+        """
+    
+    def Date():
+        """Return the default date
+
+        The first unqualified Dublin Core 'Date' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned. The
+        string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.    
+        """
+    
+    def CreationDate():
+        """Return the creation date.
+
+        The value of the first Dublin Core 'Date' element qualified by
+        'creation' is returned as a unicode string if a qualified
+        element is defined, otherwise, an empty unicode string is
+        returned. The string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.
+        """
+    
+    def EffectiveDate():
+        """Return the effective date
+
+        The value of the first Dublin Core 'Date' element qualified by
+        'effective' is returned as a unicode string if a qualified
+        element is defined, otherwise, an empty unicode string is
+        returned. The string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.
+        """
+    
+    def ExpirationDate():
+        """Date resource expires.
+
+        The value of the first Dublin Core 'Date' element qualified by
+        'expiration' is returned as a unicode string if a qualified
+        element is defined, otherwise, an empty unicode string is
+        returned. The string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.
+        """
+    
+    def ModificationDate():
+        """Date resource last modified.
+
+        The value of the first Dublin Core 'Date' element qualified by
+        'modification' is returned as a unicode string if a qualified
+        element is defined, otherwise, an empty unicode string is
+        returned. The string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.
+        """
+
+    def Type():
+        """Return the resource type
+
+        Return a human-readable type name for the resource.
+
+        The first unqualified Dublin Core 'Type' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned. The
+        string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.    
+        """
+
+    def Format():
+        """Return the resource format.
+
+        Return the resource's MIME type (e.g., 'text/html',
+        'image/png', etc.).
+
+        The first unqualified Dublin Core 'Format' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned. The
+        string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.    
+        """
+
+    def Identifier():
+        """Return the URL of the resource.
+
+        This value is computed. It is included in the output of
+        qualifiedIdentifiers with the qualification 'url'.
+        """
+
+    def Language():
+        """Return the resource language.
+
+        Return the RFC language code (e.g., 'en-US', 'pt-BR')
+        for the resource.
+
+        The first unqualified Dublin Core 'Language' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned. The
+        string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.    
+        """
+
+    def Rights():
+        """Return the resource rights.
+
+        Return a string describing the intellectual property status,
+        if any, of the resource.  for the resource.
+
+        The first unqualified Dublin Core 'Rights' element value is
+        returned as a unicode string if an unqualified element is
+        defined, otherwise, an empty unicode string is returned. The
+        string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.    
+        """
+
+    
+
+__doc__ = ICMFDublinCore.__doc__ + __doc__


=== Zope3/lib/python/Zope/App/DublinCore/IZopeDublinCore.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/IZopeDublinCore.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,37 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+from Zope.App.DublinCore.General \
+     import IGeneralDublinCore, IWritableGeneralDublinCore
+from Zope.App.DublinCore.ICMFDublinCore import ICMFDublinCore
+from Zope.App.DublinCore.PropertySchemas \
+     import IDCDescriptiveProperties, IDCTimes, IDCPublishing, IDCExtended
+
+
+class IZopeDublinCore(
+    IGeneralDublinCore,
+    IWritableGeneralDublinCore,
+    ICMFDublinCore,
+    IDCDescriptiveProperties,
+    IDCTimes,
+    IDCPublishing,
+    IDCExtended,
+    ):
+    """Zope Dublin Core properties
+    """
+
+__doc__ = IZopeDublinCore.__doc__ + __doc__


=== Zope3/lib/python/Zope/App/DublinCore/IZopeDublinCoreAnnotatable.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/IZopeDublinCoreAnnotatable.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+from Zope.App.OFS.Annotation.IAnnotatable import IAnnotatable
+
+class IZopeDublinCoreAnnotatable(IAnnotatable):
+    """Objects that can be annotated with Zope Dublin-Core meta data
+
+    This is a marker interface that indicates the intent to have
+    Zope Dublin-Core meta data associated with an object.
+
+    """
+
+__doc__ = IZopeDublinCoreAnnotatable.__doc__ + __doc__


=== Zope3/lib/python/Zope/App/DublinCore/PropertySchemas.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/PropertySchemas.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+from Interface import Interface
+from Zope.Schema import Text, Datetime, Sequence
+
+# XXX This will need to be filled out more.
+
+class IDCDescriptiveProperties(Interface):
+    """Basic descriptive meta-data properties
+    """
+
+    title = Text(
+        title = u'Title',
+        description =
+        u"The first unqualified Dublin Core 'Title' element value."
+        )
+
+    description = Text(
+        title = u'Description',
+        description =
+        u"The first unqualified Dublin Core 'Description' element value.",
+        )
+
+class IDCTimes(Interface):
+    """Time properties
+    """
+
+    created = Datetime(
+        title = u'Creation Date',
+        description =
+        u"The date and time that an object is created. "
+        u"\nThis is normally set automatically."
+        )
+    
+    modified = Datetime(
+        title = u'Modification Date',
+        description =
+        u"The date and time that the object was last modified in a\n"
+        u"meaningful way."
+        )
+
+class IDCPublishing(Interface):
+    """Publishing properties
+    """
+
+    effective = Datetime(
+        title = u'Effective Date',
+        description =
+        u"The date and time that an object should be published. "
+        )
+    
+
+    expires = Datetime(
+        title = u'Expiration Date',
+        description =
+        u"The date and time that the object should become unpublished."
+        )
+
+class IDCExtended(Interface):
+    """Extended properties
+
+    This is a mized bag of properties we want but that we probably haven't
+    quite figured out yet.
+    """
+
+
+    creators = Sequence(
+        title = u'Creators',
+        description = u"The unqualified Dublin Core 'Creator' element values",
+        value_types = (Text(),),
+        )
+
+    subjects = Sequence(
+        title = u'Subjects',
+        description = u"The unqualified Dublin Core 'Subject' element values",
+        value_types = (Text(),),
+        )
+
+    publisher = Text(
+        title = u'Publisher',
+        description =
+        u"The first unqualified Dublin Core 'Publisher' element value.",
+        )
+
+    contributors = Sequence(
+        title = u'Contributors',
+        description =
+        u"The unqualified Dublin Core 'Contributor' element values",
+        value_types = (Text(),),
+        )
+    
+


=== Zope3/lib/python/Zope/App/DublinCore/TimeAnnotators.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/TimeAnnotators.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""Objects that take care of annotating dublin core meta data times
+
+$Id$
+"""
+__metaclass__ = type
+
+from datetime import datetime
+from Zope.ComponentArchitecture import queryAdapter
+from Zope.App.DublinCore.IZopeDublinCore import IZopeDublinCore
+
+class DCTimeAnnotatorClass:
+    """Update Dublin-Core time property
+    """
+
+    def __init__(self, property):
+        self.property = property
+
+    def notify(self, modified_event):
+        dc = queryAdapter(modified_event.object, IZopeDublinCore)
+        if dc is not None:
+            setattr(dc, self.property, datetime.utcnow())
+
+ModifiedAnnotator = DCTimeAnnotatorClass('modified')
+CreatedAnnotator = DCTimeAnnotatorClass('created')
+    
+        
+        


=== Zope3/lib/python/Zope/App/DublinCore/ZDCAnnotatableAdapter.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/ZDCAnnotatableAdapter.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+__metaclass__ = type
+
+from Zope.ComponentArchitecture import getAdapter
+from Zope.App.OFS.Annotation.IAnnotations import IAnnotations
+from Zope.App.OFS.Annotation.IAnnotatable import IAnnotatable
+from Zope.App.DublinCore.ZopeDublinCore import ZopeDublinCore
+from Persistence.PersistentDict import PersistentDict
+
+DCkey = "Zope.App.DublinCore.ZopeDublinCore"
+
+class ZDCAnnotatableAdapter(ZopeDublinCore):
+    """Adapt annotatable objects to Zope Dublin Core
+    """
+
+    __used_for__ = IAnnotatable
+
+    annotations = None
+
+    def __init__(self, context):
+        annotations = getAdapter(context, IAnnotations)
+        dcdata = annotations.get(DCkey)
+        if not dcdata:
+            self.annotations = annotations
+            dcdata = PersistentDict()
+
+        super(ZDCAnnotatableAdapter, self).__init__(dcdata)
+
+    def _changed(self):
+        if self.annotations is not None:
+            self.annotations[DCkey] = self._mapping
+            self.annotations = None
+
+__doc__ = ZDCAnnotatableAdapter.__doc__ + __doc__
+


=== Zope3/lib/python/Zope/App/DublinCore/ZopeDublinCore.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/ZopeDublinCore.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,360 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+$Id$
+"""
+
+__metaclass__ = type
+
+from Zope.App.DublinCore.IZopeDublinCore import IZopeDublinCore
+from Zope.Misc.DateTimeParse import parseDatetimetz
+from datetime import datetimetz
+from datetime import datetime
+
+class SimpleProperty:
+
+    def __init__(self, name):
+        self.__name__ = name
+
+class ScalarProperty(SimpleProperty):
+        
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+        data = inst._mapping.get(self.__name__, ())
+        if data:
+            return data[0]
+        else:
+            return u''
+
+    def __set__(self, inst, value):
+        if not isinstance(value, unicode):
+            raise TypeError("Element must be unicode")
+
+        dict = inst._mapping
+        __name__ = self.__name__
+        inst._changed()
+        dict[__name__] = (value, ) + dict.get(__name__, ())[1:]
+
+def _scalar_get(inst, name):
+    data = inst._mapping.get(name, ())
+    if data:
+        return data[0]
+    else:
+        return u''
+    
+class DateProperty(ScalarProperty):
+        
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+        data = inst._mapping.get(self.__name__, ())
+        if data:
+            return parseDatetimetz(data[0])
+        else:
+            return None
+
+    def __set__(self, inst, value):
+        if not isinstance(value, datetime):
+            raise TypeError("Element must be %s", datetimetz)
+
+        value = unicode(value.isoformat('T'), 'ascii')
+
+        super(DateProperty, self).__set__(inst, value)
+
+        
+class SequenceProperty(SimpleProperty):
+        
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+
+        return inst._mapping.get(self.__name__, ())
+
+    def __set__(self, inst, value):
+        value = tuple(value)
+        for v in value:
+            if not isinstance(v, unicode):
+                raise TypeError("Elements must be unicode")
+        inst._changed()
+        inst._mapping[self.__name__] = value
+    
+class ZopeDublinCore:
+    """Zope Dublin Core Mixin
+
+    Subclasses should define either _changed() or _p_changed.
+
+    Just mix with Persistence to get a persistent version.
+    """
+
+
+    __implements__ =  IZopeDublinCore
+
+    def __init__(self, mapping=None):
+        if mapping is None:
+            mapping = {}
+        self._mapping = mapping
+
+    def _changed(self):
+        self._p_changed = 1
+
+    title = ScalarProperty(u'Title')
+    
+    def Title(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.title
+
+    creators = SequenceProperty(u'Creator')
+    
+    def Creator(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.creators
+
+    subjects = SequenceProperty(u'Subject')
+
+    def Subject(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.subjects
+
+    description = ScalarProperty(u'Description')
+
+    def Description(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.description
+
+    publisher = ScalarProperty(u'Publisher')
+
+    def Publisher(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.publisher
+
+    contributors = SequenceProperty(u'Contributor')
+
+    def Contributors(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.contributors
+
+    def Date(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return _scalar_get(self, u'Date')
+
+    created = DateProperty(u'Date.Created')
+
+    def CreationDate(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return _scalar_get(self, u'Date.Created')
+
+    effective = DateProperty(u'Date.Effective')
+
+    def EffectiveDate(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return _scalar_get(self, u'Date.Effective')
+
+    expires = DateProperty(u'Date.Expires')
+
+    def ExpirationDate(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return _scalar_get(self, u'Date.Expires')
+
+    modified = DateProperty(u'Date.Modified')
+
+    def ModificationDate(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return _scalar_get(self, u'Date.Modified')
+
+    type = ScalarProperty(u'Type')
+
+    def Type(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        # XXX what is this?
+        return self.type
+
+    format = ScalarProperty(u'Format')
+
+    def Format(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        # XXX what is this?
+        return self.format
+
+    identifier = ScalarProperty(u'Identifier')
+
+    def Identifier(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        # XXX what is this?
+        return self.identifier
+
+    language = ScalarProperty(u'Language')
+
+    def Language(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.language
+
+    rights = ScalarProperty(u'Rights')
+
+    def Rights(self):
+        "See Zope.App.DublinCore.IZopeDublinCore.IZopeDublinCore"
+        return self.rights
+
+    def setQualifiedTitles(self, qualified_titles):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Title', qualified_titles)
+
+    def setQualifiedCreators(self, qualified_creators):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Creator', qualified_creators)
+
+    def setQualifiedSubjects(self, qualified_subjects):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Subject', qualified_subjects)
+
+    def setQualifiedDescriptions(self, qualified_descriptions):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Description', qualified_descriptions)
+
+    def setQualifiedPublishers(self, qualified_publishers):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Publisher', qualified_publishers)
+
+    def setQualifiedContributors(self, qualified_contributors):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Contributor', qualified_contributors)
+
+    def setQualifiedDates(self, qualified_dates):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Date', qualified_dates)
+
+    def setQualifiedTypes(self, qualified_types):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Type', qualified_types)
+
+    def setQualifiedFormats(self, qualified_formats):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Format', qualified_formats)
+
+    def setQualifiedIdentifiers(self, qualified_identifiers):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Identifier', qualified_identifiers)
+
+    def setQualifiedSources(self, qualified_sources):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Source', qualified_sources)
+
+    def setQualifiedLanguages(self, qualified_languages):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Language', qualified_languages)
+
+    def setQualifiedRelations(self, qualified_relations):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Relation', qualified_relations)
+
+    def setQualifiedCoverages(self, qualified_coverages):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Coverage', qualified_coverages)
+
+    def setQualifiedRights(self, qualified_rights):
+        "See Zope.App.DublinCore.IWritableDublinCore.IWritableDublinCore"
+        return _set_qualified(self, u'Rights', qualified_rights)
+
+    def getQualifiedTitles(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Title')
+
+    def getQualifiedCreators(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Creator')
+
+    def getQualifiedSubjects(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Subject')
+
+    def getQualifiedDescriptions(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Description')
+
+    def getQualifiedPublishers(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Publisher')
+
+    def getQualifiedContributors(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Contributor')
+
+    def getQualifiedDates(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Date')
+
+    def getQualifiedTypes(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Type')
+
+    def getQualifiedFormats(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Format')
+
+    def getQualifiedIdentifiers(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Identifier')
+
+    def getQualifiedSources(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Source')
+
+    def getQualifiedLanguages(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Language')
+
+    def getQualifiedRelations(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Relation')
+
+    def getQualifiedCoverages(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Coverage')
+
+    def getQualifiedRights(self):
+        "See Zope.App.DublinCore.IStandardDublinCore.IStandardDublinCore"
+        return _get_qualified(self, u'Rights')
+
+
+def _set_qualified(self, name, qvalue):
+    data = {}
+    dict = self._mapping
+    
+    for qualification, value in qvalue:
+        data[qualification] = data.get(qualification, ()) + (value, )
+
+    self._changed()
+    for qualification, values in data.iteritems():
+        qname = qualification and (name + '.' + qualification) or name
+        dict[qname] = values
+
+def _get_qualified(self, name):
+    result = []
+    for aname, avalue in self._mapping.iteritems():
+
+        if aname == name:
+            qualification = u''
+            for value in avalue:
+                result.append((qualification, value))
+            
+        elif aname.startswith(name):
+            qualification = aname[len(name)+1:]
+            for value in avalue:
+                result.append((qualification, value))
+
+    return tuple(result)
+                              
+
+__doc__ = ZopeDublinCore.__doc__ + __doc__
+


=== Zope3/lib/python/Zope/App/DublinCore/__init__.py 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/__init__.py	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################


=== Zope3/lib/python/Zope/App/DublinCore/configure.zcml 1.1 => 1.2 ===
--- /dev/null	Fri Oct  4 15:06:21 2002
+++ Zope3/lib/python/Zope/App/DublinCore/configure.zcml	Fri Oct  4 15:05:50 2002
@@ -0,0 +1,23 @@
+<zopeConfigure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:event="http://namespaces.zope.org/event"
+>
+
+  <adapter
+      factory=".ZDCAnnotatableAdapter."
+      provides=".IZopeDublinCore."
+      for="Zope.App.OFS.Annotation.IAnnotatable." />
+
+  <event:subscribe 
+      subscriber = ".TimeAnnotators.ModifiedAnnotator"
+      event_types = "Zope.Event.IObjectEvent.IObjectModifiedEvent"
+      />
+
+  <event:subscribe 
+      subscriber = ".TimeAnnotators.CreatedAnnotator"
+      event_types = "Zope.Event.IObjectEvent.IObjectCreatedEvent"
+      />
+
+  <include package=".Browser" />
+
+</zopeConfigure>