Author: jmorliaguet
Date: Thu May 25 23:29:35 2006
New Revision: 3220

Added:
   cpsskins/branches/paris-sprint-2006/storage/configure.zcml   (contents, 
props changed)
   cpsskins/branches/paris-sprint-2006/storage/displays.py   (contents, props 
changed)
   cpsskins/branches/paris-sprint-2006/storage/formats.py   (contents, props 
changed)
   cpsskins/branches/paris-sprint-2006/storage/portlets.py   (contents, props 
changed)
   cpsskins/branches/paris-sprint-2006/storage/relations.py   (contents, props 
changed)
   cpsskins/branches/paris-sprint-2006/storage/snapshots.py   (contents, props 
changed)
Removed:
   cpsskins/branches/paris-sprint-2006/portlets/
   cpsskins/branches/paris-sprint-2006/relations/storage.py
   cpsskins/branches/paris-sprint-2006/setup/storage.py
   cpsskins/branches/paris-sprint-2006/standard/displays/storage.py
   cpsskins/branches/paris-sprint-2006/standard/formats/storage.py
Modified:
   cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py
   cpsskins/branches/paris-sprint-2006/browser/tree/slot.py
   cpsskins/branches/paris-sprint-2006/configure.zcml
   cpsskins/branches/paris-sprint-2006/doc/local-portlets.txt
   cpsskins/branches/paris-sprint-2006/elements/display.py
   cpsskins/branches/paris-sprint-2006/elements/format.py
   cpsskins/branches/paris-sprint-2006/elements/slot.py
   cpsskins/branches/paris-sprint-2006/relations/configure.zcml
   cpsskins/branches/paris-sprint-2006/relations/interfaces.py
   cpsskins/branches/paris-sprint-2006/setup/configure.zcml
   cpsskins/branches/paris-sprint-2006/standard/displays/configure.zcml
   cpsskins/branches/paris-sprint-2006/standard/filters/style/README.txt
   cpsskins/branches/paris-sprint-2006/standard/filters/style/css.py
   cpsskins/branches/paris-sprint-2006/standard/filters/style/style_editor.js
   cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml
   cpsskins/branches/paris-sprint-2006/storage/interfaces.py
   cpsskins/branches/paris-sprint-2006/tests/setup.py
   cpsskins/branches/paris-sprint-2006/tests/test_relations.py
   cpsskins/branches/paris-sprint-2006/thememanager.py
   cpsskins/branches/paris-sprint-2006/ui/screens/common/configure.zcml

Log:

- moved all storages to cpsskins.storage



Modified: cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py     
(original)
+++ cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py     Thu May 
25 23:29:35 2006
@@ -29,11 +29,11 @@
 
 from cpsskins.browser.negotiation.interfaces import INegotiation
 from cpsskins.browser.rendering.context import ContextInfo
-from cpsskins.browser.rendering.interfaces import (
-    IUpdateData, IViewer, IRendererView, IViewNodeEvent)
-from cpsskins.elements.interfaces import (
-    INodeTraverser, INode, IElement, ISlot, IDisplayable)
-from cpsskins.relations.interfaces import IRelationStorage
+from cpsskins.browser.rendering.interfaces import IUpdateData, IViewer
+from cpsskins.browser.rendering.interfaces import IRendererView, IViewNodeEvent
+from cpsskins.elements.interfaces import INodeTraverser, INode, IElement, ISlot
+from cpsskins.elements.interfaces import IDisplayable
+from cpsskins.storage.relations import IRelationStorage
 from cpsskins.utils import getThemeManager
 
 logger = logging.getLogger("cpsskins")

Modified: cpsskins/branches/paris-sprint-2006/browser/tree/slot.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/browser/tree/slot.py    (original)
+++ cpsskins/branches/paris-sprint-2006/browser/tree/slot.py    Thu May 25 
23:29:35 2006
@@ -25,14 +25,15 @@
 from zope.interface import implements
 
 from cpsskins.browser.negotiation.interfaces import INegotiation
+from cpsskins.browser.tree.interfaces import INodeAdding, INodeRemoving
+from cpsskins.browser.tree.interfaces import INodeOrdering, INodeMoving
+from cpsskins.browser.tree.interfaces import INodeDuplicating
 from cpsskins.elements.interfaces import IPortlet, IDisplayable
 from cpsskins.ontology import hasPortlet, hasPortletFromPerspective
 from cpsskins.relations import DyadicRelation, TriadicRelation
-from cpsskins.portlets.storage import IPortletStorage
-from cpsskins.relations.interfaces import IRelationStorage, IRelationTool
-from cpsskins.browser.tree.interfaces import (
-    INodeAdding, INodeRemoving, INodeOrdering, INodeMoving, INodeDuplicating
-    )
+from cpsskins.relations.interfaces import IRelationTool
+from cpsskins.storage.portlets import IPortletStorage
+from cpsskins.storage.relations import IRelationStorage
 from cpsskins.utils import getThemeManager
 
 class SlotAdding(Adding):

Modified: cpsskins/branches/paris-sprint-2006/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/configure.zcml  (original)
+++ cpsskins/branches/paris-sprint-2006/configure.zcml  Thu May 25 23:29:35 2006
@@ -80,18 +80,18 @@
 
   <include package=".browser" />
 
-  <include package=".portlets" />
+  <include package=".ui" />
 
   <include package=".standard" />
 
   <include package=".relations" />
 
-  <include package=".ui" />
-
   <include package=".configuration" />
 
   <include package=".setup" />
 
+  <include package=".storage" />
+
   <include package=".lib" />
 
 </configure>

Modified: cpsskins/branches/paris-sprint-2006/doc/local-portlets.txt
==============================================================================
--- cpsskins/branches/paris-sprint-2006/doc/local-portlets.txt  (original)
+++ cpsskins/branches/paris-sprint-2006/doc/local-portlets.txt  Thu May 25 
23:29:35 2006
@@ -34,7 +34,7 @@
 
 and add them to the storage:
 
-    >>> from cpsskins.relations.storage import RelationStorage
+    >>> from cpsskins.storage.relations import RelationStorage
     >>> storage = RelationStorage()
 
     >>> storage[u'some_id'] = relation

Modified: cpsskins/branches/paris-sprint-2006/elements/display.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/elements/display.py     (original)
+++ cpsskins/branches/paris-sprint-2006/elements/display.py     Thu May 25 
23:29:35 2006
@@ -32,7 +32,7 @@
 from cpsskins.relations.interfaces import IRelationTool
 from cpsskins.ontology import hasDisplay, hasDisplayFromPerspective
 from cpsskins.setup.interfaces import IType
-from cpsskins.standard.displays.storage import IDisplayStorage
+from cpsskins.storage.displays import IDisplayStorage
 from cpsskins.utils import getThemeManager
 
 class Display(Element):

Modified: cpsskins/branches/paris-sprint-2006/elements/format.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/elements/format.py      (original)
+++ cpsskins/branches/paris-sprint-2006/elements/format.py      Thu May 25 
23:29:35 2006
@@ -29,7 +29,7 @@
 from cpsskins.relations import DyadicRelation
 from cpsskins.relations.interfaces import IRelationTool
 from cpsskins.setup.interfaces import IResource, ISetting, IType
-from cpsskins.standard.formats.storage import IFormatStorage
+from cpsskins.storage.formats import IFormatStorage
 from cpsskins.utils import getThemeManager
 
 class Format(Element):

Modified: cpsskins/branches/paris-sprint-2006/elements/slot.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/elements/slot.py        (original)
+++ cpsskins/branches/paris-sprint-2006/elements/slot.py        Thu May 25 
23:29:35 2006
@@ -25,7 +25,7 @@
 from cpsskins.elements.interfaces import ISlot, INode, INodeTraverser
 from cpsskins.ontology import hasPortlet, hasPortletFromPerspective
 from cpsskins.relations.interfaces import IRelatable, IRelationTool
-from cpsskins.portlets.storage import IPortletStorage
+from cpsskins.storage.portlets import IPortletStorage
 
 class Slot(InnerNode):
     """Slot

Modified: cpsskins/branches/paris-sprint-2006/relations/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/relations/configure.zcml        
(original)
+++ cpsskins/branches/paris-sprint-2006/relations/configure.zcml        Thu May 
25 23:29:35 2006
@@ -101,17 +101,6 @@
   />
 
 
-  <!-- Relation storage -->
-
-  <cpsskins:storage
-      id="relations"
-      title="Relation storage"
-      description="A relation storage contains relations between objects"
-      class="cpsskins.relations.storage.RelationStorage"
-      interface="cpsskins.relations.interfaces.IRelationStorage"
-      contains="cpsskins.relations.interfaces.IRelation"
-  />
-
   <!-- Relation tool -->
 
   <adapter

Modified: cpsskins/branches/paris-sprint-2006/relations/interfaces.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/relations/interfaces.py (original)
+++ cpsskins/branches/paris-sprint-2006/relations/interfaces.py Thu May 25 
23:29:35 2006
@@ -87,31 +87,6 @@
     def third():
         """The third relate"""
 
-class IRelationStorage(IStorage):
-
-    contains(IRelation)
-
-    def search(predicate, first, second, third):
-        """ """
-
-    def list():
-        """ """
-
-    def clear():
-        """ """
-
-    def getFirsts():
-        """ """
-
-    def getSeconds():
-        """ """
-
-    def getThirds():
-        """ """
-
-    def __delitem__(item):
-        """ """
-
 # Tool
 class IRelationTool(Interface):
     """Relation tool."""

Modified: cpsskins/branches/paris-sprint-2006/setup/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/setup/configure.zcml    (original)
+++ cpsskins/branches/paris-sprint-2006/setup/configure.zcml    Thu May 25 
23:29:35 2006
@@ -85,16 +85,6 @@
 
   </class>
 
-  <!-- snapshot storage -->
-  <cpsskins:storage
-      id="snapshots"
-      title="Snapshot storage"
-      description="A snapshot storage contains site snapshots"
-      class="cpsskins.setup.storage.SnapshotStorage"
-      interface="cpsskins.setup.storage.ISnapshotStorage"
-      contains="cpsskins.setup.snapshot.ISnapshot"
-  />
-
 
   <class class="cpsskins.setup.snapshot.Snapshot">
 

Modified: cpsskins/branches/paris-sprint-2006/standard/displays/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/standard/displays/configure.zcml        
(original)
+++ cpsskins/branches/paris-sprint-2006/standard/displays/configure.zcml        
Thu May 25 23:29:35 2006
@@ -4,16 +4,6 @@
     i18n_domain="cpsskins"
     >
 
-  <!-- Display storage -->
-
-  <cpsskins:storage
-      id="displays"
-      title="Display storage"
-      description="A display storage"
-      class=".storage.DisplayStorage"
-      contains="cpsskins.elements.interfaces.IDisplay"
-  />
-
   <!-- Area display -->
 
   <cpsskins:display
@@ -30,7 +20,6 @@
       class=".box.Box"
   />
 
-
   <!-- Box group display -->
 
   <cpsskins:display

Modified: cpsskins/branches/paris-sprint-2006/standard/filters/style/README.txt
==============================================================================
--- cpsskins/branches/paris-sprint-2006/standard/filters/style/README.txt       
(original)
+++ cpsskins/branches/paris-sprint-2006/standard/filters/style/README.txt       
Thu May 25 23:29:35 2006
@@ -106,3 +106,4 @@
     >>> s[u'p'] = {'background-image': 'cpsskins://[EMAIL PROTECTED]'}
 
     >>> print CSSRenderer(s)()
+    p.style12345  {background-image:url(++image++image1)}

Modified: cpsskins/branches/paris-sprint-2006/standard/filters/style/css.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/standard/filters/style/css.py   
(original)
+++ cpsskins/branches/paris-sprint-2006/standard/filters/style/css.py   Thu May 
25 23:29:35 2006
@@ -23,10 +23,10 @@
 from cpsskins.relations.interfaces import IRelatable
 from cpsskins.setup.interfaces import ISetting, IResource, IResourceManager
 from cpsskins.setup.interfaces import IIdentifiable
-from cpsskins.standard.formats.storage import IFormatStorage
 from cpsskins.standard.formats.style import IStyle
 from cpsskins.standard.fields.color import IWebColor
 from cpsskins.standard.fields.image import IWebImage
+from cpsskins.storage.formats import IFormatStorage
 from cpsskins.utils import getThemeManager
 
 class IStylesheetView(Interface):

Modified: 
cpsskins/branches/paris-sprint-2006/standard/filters/style/style_editor.js
==============================================================================
--- cpsskins/branches/paris-sprint-2006/standard/filters/style/style_editor.js  
(original)
+++ cpsskins/branches/paris-sprint-2006/standard/filters/style/style_editor.js  
Thu May 25 23:29:35 2006
@@ -16,13 +16,9 @@
     var x = Event.pointerX(info);
     var y = Event.pointerY(info);
     var box = $('labelInfo');
+    var label = info.target.getAttribute("label") || '';
     var tagname = info.target.tagName.toLowerCase();
-    var label = info.target.getAttribute("label");
-    if (label) {
-      label += ' (&lt;' + tagname + '&gt;)';
-    } else {
-      label = '&lt;' + tagname + '&gt;';
-    }
+    label += ' &lt;' + tagname + '&gt;';
     box.innerHTML = label ;
     box.setStyle({left: x+'px', top: y+15+'px'});
     box.show();

Modified: cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml 
(original)
+++ cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml Thu May 
25 23:29:35 2006
@@ -3,15 +3,6 @@
     xmlns:browser="http://namespaces.zope.org/browser";
     xmlns:cpsskins="http://namespaces.zope.org/cpsskins";>
 
-  <!-- Format storage -->
-  <cpsskins:storage
-      id="formats"
-      title="Format storage"
-      description="A format storage"
-      class=".storage.FormatStorage"
-      contains="cpsskins.elements.interfaces.IFormat"
-  />
-
   <!-- Layout -->
   <cpsskins:format
       name="layout"

Added: cpsskins/branches/paris-sprint-2006/storage/configure.zcml
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/configure.zcml  Thu May 25 
23:29:35 2006
@@ -0,0 +1,53 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope";
+    xmlns:cpsskins="http://namespaces.zope.org/cpsskins";>
+
+  <!-- Portlet storage -->
+  <cpsskins:storage
+      id="portlets"
+      title="Portlet storage"
+      description="A portlet storage contains local portlets"
+      class=".portlets.PortletStorage"
+      contains="cpsskins.elements.interfaces.IPortlet"
+  />
+
+  <!-- snapshot storage -->
+  <cpsskins:storage
+      id="snapshots"
+      title="Snapshot storage"
+      description="A snapshot storage contains site snapshots"
+      class=".snapshots.SnapshotStorage"
+      interface=".snapshots.ISnapshotStorage"
+      contains="cpsskins.setup.snapshot.ISnapshot"
+  />
+
+  <!-- Display storage -->
+  <cpsskins:storage
+      id="displays"
+      title="Display storage"
+      description="A display storage"
+      class=".displays.DisplayStorage"
+      contains="cpsskins.elements.interfaces.IDisplay"
+  />
+
+  <!-- Format storage -->
+  <cpsskins:storage
+      id="formats"
+      title="Format storage"
+      description="A format storage"
+      class=".formats.FormatStorage"
+      contains="cpsskins.elements.interfaces.IFormat"
+  />
+
+  <!-- Relation storage -->
+  <cpsskins:storage
+      id="relations"
+      title="Relation storage"
+      description="A relation storage contains relations between objects"
+      class=".relations.RelationStorage"
+      interface=".relations.IRelationStorage"
+      contains="cpsskins.relations.interfaces.IRelation"
+  />
+
+</configure>
+

Added: cpsskins/branches/paris-sprint-2006/storage/displays.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/displays.py     Thu May 25 
23:29:35 2006
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.app.container.constraints import contains
+from zope.interface import implements
+
+from cpsskins.elements.interfaces import IDisplay
+from cpsskins.storage import Storage
+from cpsskins.storage.interfaces import IStorage
+
+class IDisplayStorage(IStorage):
+    contains(IDisplay)
+
+class DisplayStorage(Storage):
+    """A BTree-based display container"""
+    implements(IDisplayStorage)
+

Added: cpsskins/branches/paris-sprint-2006/storage/formats.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/formats.py      Thu May 25 
23:29:35 2006
@@ -0,0 +1,33 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.app.container.constraints import contains
+from zope.interface import implements
+
+from cpsskins.elements.interfaces import IFormat
+from cpsskins.storage import Storage
+from cpsskins.storage.interfaces import IStorage
+
+class IFormatStorage(IStorage):
+    contains(IFormat)
+
+class FormatStorage(Storage):
+    """A BTree-based display container"""
+    implements(IFormatStorage)
+

Modified: cpsskins/branches/paris-sprint-2006/storage/interfaces.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/storage/interfaces.py   (original)
+++ cpsskins/branches/paris-sprint-2006/storage/interfaces.py   Thu May 25 
23:29:35 2006
@@ -34,6 +34,3 @@
     def purge():
         """Purge the storage."""
 
-    def __setitem__(item):
-        """ """
-

Added: cpsskins/branches/paris-sprint-2006/storage/portlets.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/portlets.py     Thu May 25 
23:29:35 2006
@@ -0,0 +1,35 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.app.container.constraints import contains
+from zope.interface import implements
+
+from cpsskins.elements.interfaces import IPortlet
+from cpsskins.storage import Storage
+from cpsskins.storage.interfaces import IStorage
+
+class IPortletStorage(IStorage):
+
+    contains(IPortlet)
+
+class PortletStorage(Storage):
+    """A BTree-based display container"""
+
+    implements(IPortletStorage)
+

Added: cpsskins/branches/paris-sprint-2006/storage/relations.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/relations.py    Thu May 25 
23:29:35 2006
@@ -0,0 +1,416 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import logging
+
+from pprint import pprint
+from BTrees.OOBTree import OOBTree
+
+from zope.app import zapi
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.constraints import contains
+from zope.app.container.interfaces import INameChooser
+from zope.location.traversing import LocationPhysicallyLocatable
+from zope.interface import implements
+from zope.proxy import isProxy
+from zope.security.proxy import removeSecurityProxy
+
+from cpsskins.relations.interfaces import IRelation, IRelatable, IPredicate
+from cpsskins.relations.interfaces import IProxyPredicate
+from cpsskins.storage import Storage
+from cpsskins.storage.interfaces import IStorage
+
+DEBUG = logging.DEBUG
+logger = logging.getLogger()
+
+# Wildcards are used to index the relates of a relation.
+WILDCARDS = {
+    1: (
+         ('',),
+       ),
+    2: (
+         ('', ''),
+         ('*', ''), ('', '*'),
+       ),
+    3: (
+         ('', '', ''),
+         ('*', '', ''), ('', '*', ''), ('', '', '*'),
+         ('*', '*', ''), ('', '*', '*'), ('*', '', '*'),
+       ),
+    }
+
+class IRelationStorage(IStorage):
+
+    contains(IRelation)
+
+    def search(predicate, first, second, third):
+        """ """
+
+    def list():
+        """ """
+
+    def clear():
+        """ """
+
+    def getFirsts():
+        """ """
+
+    def getSeconds():
+        """ """
+
+    def getThirds():
+        """ """
+
+    def __delitem__(item):
+        """ """
+
+class RelationStorage(Storage):
+    """A BTree-based relation container with a relation indexer.
+
+    >>> from zope.interface.verify import verifyClass
+    >>> verifyClass(IRelationStorage, RelationStorage)
+    True
+
+    >>> storage = RelationStorage()
+    >>> from cpsskins.relations import TestRelate as Relate, \
+        Predicate, MonadicRelation, DyadicRelation, TriadicRelation
+    >>> from cpsskins.relations.interfaces import IRelatable
+
+    >>> first = Relate(u'this')
+    >>> second = Relate(u'that')
+    >>> predicate = Predicate('_ depends on _')
+    >>> r = DyadicRelation(predicate, first, second)
+
+    >>> r
+    <Dyadic relation: 'this depends on that'>
+
+    >>> list(storage._relates.keys())
+    []
+
+    We add a relation to the storage
+    >>> storage[u'dependency'] = r
+
+    The relates are indexed:
+    in the 'dependency' relation 'this' is a first and 'that' is a second:
+    >>> items = list(storage._relates.items())
+    >>> ('*,that', [u'dependency']) in items
+    True
+    >>> ('this,*', [u'dependency']) in items
+    True
+    >>> ('this,that', [u'dependency']) in items
+    True
+
+
+    Indexation
+    ----------
+    Let us clear and rebuild the index.
+    >>> storage._clearIndexes()
+    >>> list(storage._relates.items())
+    []
+    >>> storage.reindex()
+
+    The index is now rebuilt
+    >>> items = list(storage._relates.items())
+    >>> ('*,that', [u'dependency']) in items
+    True
+    >>> ('this,*', [u'dependency']) in items
+    True
+    >>> ('this,that', [u'dependency']) in items
+    True
+
+
+    Queries
+    --------------
+    During a search the predicate must be specified:
+    >>> storage.search()
+    Traceback (most recent call last):
+    ...
+    ValueError: Must specify a predicate in the query.
+
+    At least one relate must be specified:
+    >>> storage.search(predicate=predicate)
+    Traceback (most recent call last):
+    ...
+    ValueError: At least one relate must be specified in the query
+
+    If we do a search on the relates, we get a list of relations in which the
+    relate in involved:
+    >>> storage.search(predicate=predicate, first=first)
+    [u'dependency']
+    >>> storage.search(predicate=predicate, second=second)
+    [u'dependency']
+
+    Each relate has a role in the relation; "a depends on b" is not the same
+    as "b depends on a"
+    >>> storage.search(predicate=predicate, first=second)
+    []
+    >>> storage.search(predicate=predicate, second=first)
+    []
+
+    To get the list of all relations in the storage use:
+    >>> storage.list()
+    [u'dependency']
+
+    To get the list of relates matching a given query use:
+    >>> firsts = storage.getFirsts(predicate=predicate, first=first)
+    >>> [unicode(e) for e in firsts]
+    [u'this']
+
+    >>> seconds = storage.getSeconds(predicate=predicate, first=first)
+    >>> [unicode(e) for e in seconds]
+    [u'that']
+
+    Finally we destroy the relation:
+    >>> del storage[u'dependency']
+
+    The indexes get cleared and the keys get removed:
+    >>> list(storage._relates.keys())
+    []
+
+    >>> list(storage.items())
+    []
+
+
+    Compound predicates
+    -------------------
+    The storage can be searched using compound predicates.
+    A compound predicate is a collection of predicates written as a tuple.
+
+    For instance:
+    >>> is_black = '_ is black'
+    >>> is_white = '_ is white'
+
+    >>> from cpsskins.relations.predicates import CompoundPredicate
+    >>> is_black_or_white = is_black, is_white
+    >>> CP = CompoundPredicate(is_black_or_white)
+    >>> CP
+    <Compound Predicate: '_ is black OR _ is white'>
+
+    >>> a = Relate('snow')
+    >>> b = Relate('ebony')
+    >>> a_is_white = MonadicRelation(Predicate(is_white), a)
+    >>> b_is_black = MonadicRelation(Predicate(is_black), b)
+    >>> storage[u'some_white'] = a_is_white
+    >>> storage[u'some_black'] = b_is_black
+
+    The relations matching '_ is white' are:
+    >>> pprint([repr(storage[r]) for r in storage.list(Predicate(is_white))])
+    ["<Monadic relation: 'snow is white'>"]
+
+    The relations matching '_ is black' are:
+    >>> pprint([repr(storage[r]) for r in storage.list(Predicate(is_black))])
+    ["<Monadic relation: 'ebony is black'>"]
+
+    Relations matching the compound ('_ is black', '_is white') are:
+    >>> res = storage.list(CompoundPredicate(is_black_or_white))
+    >>> pprint([repr(storage[r]) for r in res])
+    ["<Monadic relation: 'ebony is black'>", "<Monadic relation: 'snow is 
white'>"]
+
+    Finally, we clear the storage:
+    >>> list(storage.keys())
+    [u'some_black', u'some_white']
+
+    >>> storage.clear()
+
+    >>> list(storage.keys())
+    []
+
+    """
+    implements(IRelationStorage)
+
+    __btree__setitem__ = BTreeContainer.__setitem__
+    __btree__delitem__ = BTreeContainer.__delitem__
+
+    def __init__(self, **kw):
+        super(RelationStorage, self).__init__()
+        self._relates = OOBTree()
+
+    def __setitem__(self, key, object):
+        if not IRelation.providedBy(object):
+            raise ValueError, "Only objects implementing IRelation are allowed"
+        self.__btree__setitem__(key, object)
+        self._indexRelates(relation=object, id=key)
+        self._p_changed = True
+
+    def __delitem__(self, key):
+        self.__btree__delitem__(key)
+        # Unregister the relation from the relates catalog.
+        self._unindexRelates(key)
+        self._p_changed = True
+
+    def add(self, relation):
+        """Choose a name and add the relation to the store.
+        """
+        chooser = INameChooser(self)
+        name = unicode(relation).replace('_', '').replace(' ', '')
+        relation_name = chooser.chooseName(name, relation)
+        self[relation_name] = relation
+        logger.debug("Added a relation '%s': '%s'", relation_name,
+                     repr(relation))
+
+    def remove(self, ids=[]):
+        """Remove relations for the storage.
+        """
+        if isinstance(ids, basestring):
+            ids = [ids]
+        for id in ids:
+            if id not in self:
+                raise KeyError, "No such relation (%s) in the storage." % id
+            del self[id]
+        logger.debug("Removed the relations with ids: '%s'", ids)
+
+    # Relation index
+    def reindex(self):
+        """Reindex the relations.
+        """
+        self._clearIndexes()
+        for relation in list(self.values()):
+            id = zapi.name(LocationPhysicallyLocatable(relation))
+            self._indexRelates(relation, id)
+        self._p_changed = True
+
+    def _indexRelates(self, relation, id):
+        """Index the relation in the relates catalog.
+        relations are refered to by their id (their name in the container)
+        """
+        id = unicode(id)
+        relates = self._relates
+        for r in self._analyse(relation):
+            key = self._computeKey(r)
+            try:
+                relates[key].append(id)
+            except KeyError:
+                relates[key] = [id]
+
+    def _unindexRelates(self, id):
+        """Remove all references to the relation in the relates catalog.
+        """
+        for k, v in list(self._relates.items()):
+            if id not in v:
+                continue
+            self._relates[k].remove(id)
+            if self._relates[k]:
+                continue
+            del self._relates[k]
+
+    def _analyse(self, relation):
+        relations = []
+        arity = len(relation)
+
+        def f(v, w):
+            if w == '*':
+                return '*'
+            return unicode(IRelatable(v, v))
+
+        for w in WILDCARDS[arity]:
+            relations.append(
+                tuple([f(relation[i], w[i]) for i in range(arity)])
+            )
+        return relations
+
+    def _computeKey(self, relates):
+        """Build a key for doing index lookups.
+        e.g. ('a', 'b', None) will be converted into ('a', 'b', '*')
+        """
+        def f(v):
+            if v is None:
+                return '*'
+            return unicode(IRelatable(v, v))
+        return ','.join([f(r) for r in relates])
+
+    def _lookup(self, relates):
+        """Do a lookup among the indexed relates.
+        """
+        return self._relates.get(self._computeKey(relates), [])
+
+    def _clearIndexes(self):
+        for k in list(self._relates.keys()):
+            del self._relates[k]
+
+    # storage search
+    def search(self, predicate=None, first=None, second=None, third=None):
+        """Search the storage.
+
+        - at least one relate (first, second, or third) must be specified.
+
+        - the predicate can be a compound predicate.
+
+        - predicates can be proxy predicates that refer to other predicates.
+
+        """
+
+        if predicate is None:
+            raise ValueError, "Must specify a predicate in the query."
+
+        if isProxy(predicate):
+            predicate = removeSecurityProxy(predicate)
+
+        if not IPredicate.providedBy(predicate):
+            raise TypeError("This type of predicate is not supported.")
+
+        if IProxyPredicate.providedBy(predicate):
+            predicate = predicate()
+
+        arity = len(predicate)
+        relates = (first, second, third)[:arity]
+
+        if relates == (None, None, None)[:arity]:
+            raise ValueError, \
+                "At least one relate must be specified in the query"
+
+        result = self._lookup(relates)
+        return [r for r in result if unicode(self.get(r)) in predicate]
+
+    def _getRelate(self, position, **kw):
+        relates = []
+        for id in self.search(**kw):
+            r = self.get(id)[position-1]
+            if r in relates:
+                continue
+            relates.append(r)
+        return relates
+
+    def getFirsts(self, **kw):
+        return self._getRelate(1, **kw)
+
+    def getSeconds(self, **kw):
+        return self._getRelate(2, **kw)
+
+    def getThirds(self, **kw):
+        return self._getRelate(3, **kw)
+
+    def list(self, predicate=None):
+        """Return the list of relations in the storage.
+        A predicate or a compound predicate can be specified as a filter.
+        This method is not optimized for doing queries.
+        """
+        if predicate is None:
+            return list(self)
+
+        if not IPredicate.providedBy(predicate):
+            raise TypeError, "This type of predicate is not supported."
+
+        return [r for r in self if unicode(self.get(r)) in predicate]
+
+    def clear(self):
+        """Remove all relations from the storage.
+        """
+        for k in list(self.keys()):
+            del self[k]
+

Added: cpsskins/branches/paris-sprint-2006/storage/snapshots.py
==============================================================================
--- (empty file)
+++ cpsskins/branches/paris-sprint-2006/storage/snapshots.py    Thu May 25 
23:29:35 2006
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.app.container.constraints import contains
+from zope.interface import implements
+
+from cpsskins.setup.snapshot import ISnapshot
+from cpsskins.storage import Storage
+from cpsskins.storage.interfaces import IStorage
+
+class ISnapshotStorage(IStorage):
+    """ """
+    contains(ISnapshot)
+
+class SnapshotStorage(Storage):
+    """A BTree-based snapshot container"""
+    implements(ISnapshotStorage)
+
+
+

Modified: cpsskins/branches/paris-sprint-2006/tests/setup.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/tests/setup.py  (original)
+++ cpsskins/branches/paris-sprint-2006/tests/setup.py  Thu May 25 23:29:35 2006
@@ -33,16 +33,16 @@
 from cpsskins.elements.interfaces import IElement, IDisplay
 from cpsskins.perspectives import perspective
 from cpsskins.perspectives.interfaces import IPerspective
-from cpsskins.relations.interfaces import IRelationTool, IRelationStorage
+from cpsskins.relations.interfaces import IRelationTool
 from cpsskins.relations.interfaces import IRelatable
 from cpsskins.relations.tool import RelationTool
-from cpsskins.relations.storage import RelationStorage
 from cpsskins.setup.adapters import Type, Identifiable
 from cpsskins.setup.interfaces import IType, IIdentifiable, IResourceManager
 from cpsskins.setup.interfaces import ISetting
 from cpsskins.setup.manager import ResourceManager
 from cpsskins.standard.filters.style import CSSRenderer, ICSSRenderer
 from cpsskins.standard.formats.style import IStyle
+from cpsskins.storage.relations import RelationStorage, IRelationStorage
 from cpsskins.thememanager import IThemeManagementFolder, ThemeManagementFolder
 
 def setUp(test):

Modified: cpsskins/branches/paris-sprint-2006/tests/test_relations.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/tests/test_relations.py (original)
+++ cpsskins/branches/paris-sprint-2006/tests/test_relations.py Thu May 25 
23:29:35 2006
@@ -25,7 +25,7 @@
 from cpsskins.relations import Predicate, TestRelate as Relate
 from cpsskins.relations import MonadicRelation as Monad
 from cpsskins.relations import DyadicRelation as Dyad, TriadicRelation as Triad
-from cpsskins.relations.storage import RelationStorage
+from cpsskins.storage.relations import RelationStorage
 
 class TestRelationStorage(PlacelessSetup, unittest.TestCase):
     def makeTestObject(self):
@@ -200,9 +200,9 @@
 def test_suite():
     return unittest.TestSuite((
         DocTestSuite('cpsskins.relations'),
-        DocTestSuite('cpsskins.relations.storage'),
         DocTestSuite('cpsskins.relations.predicates'),
         DocTestSuite('cpsskins.relations.tool'),
+        DocTestSuite('cpsskins.storage.relations'),
         unittest.makeSuite(TestRelationStorage),
         ))
 

Modified: cpsskins/branches/paris-sprint-2006/thememanager.py
==============================================================================
--- cpsskins/branches/paris-sprint-2006/thememanager.py (original)
+++ cpsskins/branches/paris-sprint-2006/thememanager.py Thu May 25 23:29:35 2006
@@ -35,15 +35,15 @@
 from cpsskins.ontology import isDefault, hasFormat, hasDisplay
 from cpsskins.perspectives import Perspective
 from cpsskins.perspectives.interfaces import IPerspective
-from cpsskins.portlets.storage import PortletStorage, IPortletStorage
 from cpsskins.relations import MonadicRelation
-from cpsskins.relations.interfaces import IRelationStorage, IRelationTool
-from cpsskins.relations.storage import RelationStorage
+from cpsskins.relations.interfaces import IRelationTool
 from cpsskins.setup.interfaces import IResourceManager, IResource
 from cpsskins.setup.settings import Settings, ISettings
-from cpsskins.setup.storage import ISnapshotStorage, SnapshotStorage
-from cpsskins.standard.displays.storage import DisplayStorage, IDisplayStorage
-from cpsskins.standard.formats.storage import FormatStorage, IFormatStorage
+from cpsskins.storage.displays import DisplayStorage, IDisplayStorage
+from cpsskins.storage.formats import FormatStorage, IFormatStorage
+from cpsskins.storage.portlets import PortletStorage, IPortletStorage
+from cpsskins.storage.relations import RelationStorage, IRelationStorage
+from cpsskins.storage.snapshots import ISnapshotStorage, SnapshotStorage
 from cpsskins.uids import IUids, Uids
 
 logger = logging.getLogger("cpsskins")

Modified: cpsskins/branches/paris-sprint-2006/ui/screens/common/configure.zcml
==============================================================================
--- cpsskins/branches/paris-sprint-2006/ui/screens/common/configure.zcml        
(original)
+++ cpsskins/branches/paris-sprint-2006/ui/screens/common/configure.zcml        
Thu May 25 23:29:35 2006
@@ -6,6 +6,11 @@
 
   <include package=".images" />
 
+  <menu
+      id="cpsskins_add_portlet"
+      title="Add a portlet"
+  />
+
   <resource
       name="authoring.css" file="authoring.css"
       layer="cpsskins.browser.skin.cpsskins" />
-- 
http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins

Reply via email to