[Zope3-checkins] CVS: Zope3/src/zope/app/xml - w3cschemalocations.py:1.2

Philipp von Weitershausen philikon@philikon.de
Fri, 11 Apr 2003 10:44:28 -0400


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

Modified Files:
	w3cschemalocations.py 
Log Message:
Refactored dynamic interface settings based on XML schemas so it can be
used in other code.


=== Zope3/src/zope/app/xml/w3cschemalocations.py 1.1 => 1.2 ===
--- Zope3/src/zope/app/xml/w3cschemalocations.py:1.1	Thu Apr 10 06:33:29 2003
+++ Zope3/src/zope/app/xml/w3cschemalocations.py	Fri Apr 11 10:44:27 2003
@@ -17,6 +17,63 @@
 $Id$
 """
 from xml.parsers.expat import ParserCreate, ExpatError
+from zope.app.component.globalinterfaceservice import interfaceService
+
+def setInstanceInterfacesForXMLText(xmltext):
+    """
+    Sets the schema interfaces on an instance that implements IXMLText
+    according to the schemas locations the text refers to
+    """
+    schema_uris = getW3CXMLSchemaLocations(xmltext.source)
+    schema_interfaces = getInterfacesForXMLSchemaLocations(schema_uris)
+    setInstanceInterfaces(xmltext, schema_interfaces)
+
+def getInterfacesForXMLSchemaLocations(schema_uris):
+    """
+    Get interfaces for XML schema locations (URIs)
+    """
+    result = []
+    for uri in schema_uris:
+        interface = interfaceService.queryInterface(uri, None)
+        if interface is not None:
+            result.append(interface)
+    return result
+
+def setInstanceInterfaces(ob, interfaces):
+    #XXX this is really a hack. interfacegeddon will hopefully provide a better
+    # way to do this
+    
+    # if there are no interfaces, then we go back to whatever the class
+    # implements
+    if not interfaces:
+        try:
+            del ob.__implements__
+        except AttributeError:
+            pass
+        return
+
+    cls = ob.__class__
+    if isinstance(cls.__implements__, tuple):
+        implements = list(cls.__implements__)
+    else:
+        implements = [cls.__implements__]
+
+    orig_implements = implements[:]
+        
+    for interface in interfaces:
+        if 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 ob.__implements__
+        except AttributeError:
+            pass
+        return
+
+    ob.__implements__ = tuple(implements)    
 
 def getW3CXMLSchemaLocations(xml):
     """Give list of URIs of the schema an XML document promises to implement.