Skip to content
This repository has been archived by the owner on May 13, 2020. It is now read-only.

Commit

Permalink
An initial stab at implementing annotations and dublin core for Mongo.
Browse files Browse the repository at this point in the history
Instead of storing annotations in an attribute "__annotations__", we'll
store annotations directly on the object, which makes for a much nicer
Mongo document.

I changed the dublin core implementation to not even worry about
annotations and just store an attribute directly on the object.
  • Loading branch information
strichter committed May 30, 2013
1 parent 89388cb commit 622599b
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
92 changes: 92 additions & 0 deletions src/mongopersist/zope/annotation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
##############################################################################
#
# Copyright (c) 2013 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Mongo Annotations Implementation."""
from persistent.dict import PersistentDict
from zope import component, interface
from zope.annotation import interfaces

try:
from UserDict import DictMixin
except ImportError:
from collections import MutableMapping as DictMixin

class IMongoAttributeAnnotatable(interfaces.IAnnotatable):
"""Marker indicating that annotations can be stored on an attribute.
This is a marker interface giving permission for an `IAnnotations`
adapter to store data in an attribute named `__annotations__`.
"""

def normalize_key(key):
return key.replace('.', '_')

@interface.implementer(interfaces.IAnnotations)
@component.adapter(IMongoAttributeAnnotatable)
class AttributeAnnotations(DictMixin):
"""Store annotations on an object
Store annotations in the `__annotations__` attribute on a
`IAttributeAnnotatable` object.
"""

def __init__(self, obj, context=None):
self.obj = obj

def __bool__(self):
return True

__nonzero__ = __bool__

def get(self, key, default=None):
"""See zope.annotation.interfaces.IAnnotations"""
key = normalize_key(key)
return getattr(self.obj, key, default)

def __getitem__(self, key):
key = normalize_key(key)
try:
return getattr(self.obj, key)
except AttributeError:
raise KeyError(key)

def keys(self):
annotations = getattr(self.obj, self.ATTR_NAME, None)
if annotations is None:
return []

return annotations.keys()

def __iter__(self):
annotations = getattr(self.obj, self.ATTR_NAME, None)
if annotations is None:
return iter([])

return iter(annotations)

def __len__(self):
raise NotImplementedError

def __setitem__(self, key, value):
"""See zope.annotation.interfaces.IAnnotations"""
key = normalize_key(key)
setattr(self.obj, key, value)

def __delitem__(self, key):
"""See zope.app.interfaces.annotation.IAnnotations"""
key = normalize_key(key)
try:
delattr(self.obj, key)
except AttributeError:
raise KeyError(key)
56 changes: 56 additions & 0 deletions src/mongopersist/zope/dublincore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
##############################################################################
#
# Copyright (c) 2011 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Zope Dublin Core Mongo Backend Storage"""
from UserDict import DictMixin

import zope.interface
from zope.location import Location
from zope.dublincore.interfaces import IWriteZopeDublinCore
from zope.dublincore.zopedublincore import ZopeDublinCore
from zope.security.proxy import removeSecurityProxy

class DCDataWrapper(DictMixin):

def __init__(self, data):
self.data = data

def __getitem__(self, key):
return self.data[key.replace('.', '_')]

def __setitem__(self, key, value):
self.data[key.replace('.', '_')] = value

def __delitem__(self, key):
del self.data[key.replace('.', '_')]

def keys(self):
return [k.replace('_', '.') for k in self.data.keys()]


@zope.interface.implementer(IWriteZopeDublinCore)
class ZDCAnnotatableAdapter(ZopeDublinCore, Location):
"""Adapt annotatable objects to Zope Dublin Core."""
DCKEY = 'dc'

def __init__(self, context):
self.__parent__ = context
self.__name__ = self.DCKEY
naked = removeSecurityProxy(context)
if not hasattr(naked, self.__name__):
setattr(naked, self.__name__, {})
dcdata = DCDataWrapper(getattr(naked, self.__name__))
super(ZDCAnnotatableAdapter, self).__init__(dcdata)

def _changed(self):
self.__parent__._p_changed = True

0 comments on commit 622599b

Please sign in to comment.