[Zope-Checkins] CVS: Packages/ZConfig - info.py:1.1.2.19 loader.py:1.1.2.22 schema.py:1.1.2.31

Fred L. Drake, Jr. fred@zope.com
Mon, 23 Dec 2002 10:56:41 -0500


Update of /cvs-repository/Packages/ZConfig
In directory cvs.zope.org:/tmp/cvs-serv21295

Modified Files:
      Tag: zconfig-schema-devel-branch
	info.py loader.py schema.py 
Log Message:
Add the ability to load specific types from a schema without re-parsing for
each request.  Also allow the top-level schema element represent a named
type.


=== Packages/ZConfig/info.py 1.1.2.18 => 1.1.2.19 ===
--- Packages/ZConfig/info.py:1.1.2.18	Fri Dec 20 17:32:51 2002
+++ Packages/ZConfig/info.py	Mon Dec 23 10:56:40 2002
@@ -322,10 +322,11 @@
 
 
 class SchemaType(TypeContainer, SectionType):
-    def __init__(self, keytype, valuetype, datatype, handler):
-        SectionType.__init__(self, None, keytype, valuetype, datatype)
+    def __init__(self, name, keytype, valuetype, datatype, handler, url):
+        SectionType.__init__(self, name, keytype, valuetype, datatype)
         TypeContainer.__init__(self)
         self.handler = handler
+        self.url = url
 
     def allowUnnamed(self):
         return True


=== Packages/ZConfig/loader.py 1.1.2.21 => 1.1.2.22 ===
--- Packages/ZConfig/loader.py:1.1.2.21	Sat Dec 21 03:00:18 2002
+++ Packages/ZConfig/loader.py	Mon Dec 23 10:56:40 2002
@@ -23,6 +23,11 @@
 from ZConfig import datatypes
 from ZConfig import matcher
 
+try:
+    True
+except NameError:
+    True = 1
+    False = 0
 
 def loadSchema(url):
     return SchemaLoader().loadURL(url)
@@ -41,8 +46,8 @@
     def __init__(self):
         pass
 
-    def createResource(self, file, url):
-        return Resource(file, url)
+    def createResource(self, file, url, fragment=None):
+        return Resource(file, url, fragment)
 
     def loadURL(self, url):
         url = self.normalizeURL(url)
@@ -69,8 +74,9 @@
         # resources.  The policy needs to support both re-retrieve on
         # change and provide the cached resource when the remote
         # resource is not accessible.
+        url, fragment = urlparse.urldefrag(url)
         file = urllib2.urlopen(url)
-        return self.createResource(file, url)
+        return self.createResource(file, url, fragment or None)
 
     def normalizeURL(self, url):
         if os.path.exists(url):
@@ -80,13 +86,16 @@
             if not parts[0]:
                 raise ValueError("invalid URL, or file does not exist:\n"
                                  + repr(url))
-        if url:
+        if url and not self.allowFragments():
             url, fragment = urlparse.urldefrag(url)
             if fragment:
                 raise ZConfig.ConfigurationError(
                     "fragment identifiers are not currently supported")
         return url
 
+    def allowFragments(self):
+        return False
+
     def _url_from_file(self, file):
         name = getattr(file, "name", None)
         if name and name[0] != "<" and name[-1] != ">":
@@ -96,18 +105,28 @@
 
 
 class SchemaLoader(BaseLoader):
-    _fragment = None
-
     def __init__(self, registry=None):
         if registry is None:
             registry = datatypes.Registry()
         self.registry = registry
+        self._cache = {}
         BaseLoader.__init__(self)
 
     def loadResource(self, resource):
-        from ZConfig.schema import SchemaParser
-        parser = SchemaParser(self.registry)
-        return parser.parseStream(resource.file)
+        if resource.url and self._cache.has_key(resource.url):
+            schema = self._cache[resource.url]
+        else:
+            from ZConfig.schema import SchemaParser
+            parser = SchemaParser(self.registry)
+            schema = parser.parseResource(resource)
+            self._cache[resource.url] = schema
+        if resource.fragment:
+            type = self.registry.get("basic-key")(resource.fragment)
+            schema = schema.gettype(type)
+        return schema
+
+    def allowFragments(self):
+        return True
 
 
 class ConfigLoader(BaseLoader):
@@ -189,15 +208,16 @@
 
 
 class Resource:
-    def __init__(self, file, url):
+    def __init__(self, file, url, fragment=None):
         self.file = file
         self.url = url
+        self.fragment = fragment
 
     def close(self):
         if self.file is not None:
             self.file.close()
             self.file = None
-            self.closed = not 0
+            self.closed = True
 
     def __getattr__(self, name):
         return getattr(self.file, name)


=== Packages/ZConfig/schema.py 1.1.2.30 => 1.1.2.31 ===
--- Packages/ZConfig/schema.py:1.1.2.30	Fri Dec 20 17:33:56 2002
+++ Packages/ZConfig/schema.py	Mon Dec 23 10:56:40 2002
@@ -14,6 +14,7 @@
 """Parser for ZConfig schemas."""
 
 import xml.sax
+import xml.sax.saxutils
 
 import ZConfig
 
@@ -53,8 +54,9 @@
         self._stack = []
         self._group = None
 
-    def parseStream(self, stream):
-        xml.sax.parse(stream, self)
+    def parseResource(self, resource):
+        self._url = resource.url
+        xml.sax.parse(resource.file, self)
         return self._schema
 
     # SAX 2 ContentHandler methods
@@ -155,7 +157,14 @@
         self.push_prefix(attrs)
         handler = self.get_handler(attrs)
         keytype, valuetype, datatype = self.get_sect_typeinfo(attrs)
-        self._schema = info.SchemaType(keytype, valuetype, datatype, handler)
+        name = attrs.get("type")
+        if name is not None:
+            name = self.basic_key(name)
+        self._schema = info.SchemaType(name, keytype, valuetype, datatype,
+                                       handler, self._url)
+        if name is not None:
+            # XXX circular reference
+            self._schema.addtype(self._schema)
         self._schema.registry = self._registry
         self._stack = [self._schema]
 
@@ -166,9 +175,8 @@
     def start_sectiontype(self, attrs):
         name = attrs.get("type")
         if not name:
-            self.error(
-                "sectiontype name must not be omitted or empty")
-        name = self.identifier(name)
+            self.error("sectiontype type must not be omitted or empty")
+        name = self.basic_key(name)
         self.push_prefix(attrs)
         keytype, valuetype, datatype = self.get_sect_typeinfo(attrs)
         sectinfo = info.SectionType(name, keytype, valuetype, datatype)