[Zope3-checkins] CVS: Zope3/src/zope/app/content - xmldocument.py:1.2

Martijn Faassen m.faassen@vet.uu.nl
Thu, 10 Apr 2003 09:05:13 -0400


Update of /cvs-repository/Zope3/src/zope/app/content
In directory cvs.zope.org:/tmp/cvs-serv24220/zope/app/content

Modified Files:
	xmldocument.py 
Log Message:
Made XMLDocument instances dynamically modify their interfaces. If an
instance has XML content that refers to an XML schema (using schemaLocation)
then the instance will automatically implement the XML Schema Interface
for that. This way, Zope adapters and views can be associated with 
particular instances that conform to a particular schema.

Currently the manipulation of an instance's interfaces is done by 
a rather terrible hack. This should change after interfacegheddon.


=== Zope3/src/zope/app/content/xmldocument.py 1.1 => 1.2 ===
--- Zope3/src/zope/app/content/xmldocument.py:1.1	Wed Apr  9 07:47:52 2003
+++ Zope3/src/zope/app/content/xmldocument.py	Thu Apr 10 09:04:43 2003
@@ -15,16 +15,71 @@
 $Id$
 """
 from persistence import Persistent
-
-from zope.schema.fieldproperty import FieldProperty
-from zope.app.interfaces.annotation import IAnnotatable
+from zope.app.interfaces.annotation import IAttributeAnnotatable
 from zope.app.interfaces.content.xmldocument import IXMLDocument
+from zope.app.xml.w3cschemalocations import getW3CXMLSchemaLocations
+from zope.app.component.globalinterfaceservice import interfaceService
 
 class XMLDocument(Persistent):
 
-    __implements__ = IXMLDocument, IAnnotatable
-
-    source = FieldProperty(IXMLDocument['source'])
- 
+    __implements__ = IXMLDocument
+    
     def __init__(self, source='<doc/>'):
         self.source = source
+        
+    def _setSource(self, value):
+        self._source = value
+        
+        # XXX for now, parse the document and lift the W3C XML schema
+        # locations from it to identify which schemas are used
+        # this dependency on W3C XML schema should go away at some point,
+        # and it should also become possible to set schemas explicitly
+        # XML Schema interfaces are looked up for each mentioned schema,
+        # and if this interface exists, we manipulate this instance to
+        # state it has those interfaces.
+        
+        # XXX the interface manipulation is a hack, should be fixed after
+        # interfacegheddon
+        
+        schema_uris = getW3CXMLSchemaLocations(value)
+
+        # if there are no schemas, then we go back to whatever the class
+        # implements
+        if not schema_uris:
+            try:
+                del self.__implements__
+            except AttributeError:
+                pass
+            return
+
+        cls = self.__class__
+        if isinstance(cls.__implements__, tuple):
+            implements = list(cls.__implements__)
+        else:
+            implements = [cls.__implements__]
+
+        orig_implements = implements[:]
+        
+        for schema_uri in schema_uris:
+            interface = interfaceService.queryInterface(schema_uri, None)
+            if interface is not None and interface not in implements:
+                implements.append(interface)
+
+        # if there are no changes in the interfaces, go back to whatever
+        # the class implements
+        if implements == orig_implements:
+            try:
+                del self.__implements__
+            except AttributeError:
+                pass
+            return
+
+        self.__implements__ = tuple(implements)    
+
+    def _getSource(self):
+        return self._source
+    
+    source = property(_getSource, _setSource)
+
+    
+