[Zope-Checkins] CVS: Packages/ZConfig - loader.py:1.1.2.1 ApacheStyle.py:1.9.2.1 Context.py:1.15.10.1

Fred L. Drake, Jr. fred@zope.com
Tue, 10 Dec 2002 10:57:50 -0500


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

Modified Files:
      Tag: zconfig-schema-devel-branch
	ApacheStyle.py Context.py 
Added Files:
      Tag: zconfig-schema-devel-branch
	loader.py 
Log Message:
Refactor the Context object to separate the config file syntax support
from resource handling.

Excise the "%import" stuff -- that will not make sense in the schema world.


=== Added File Packages/ZConfig/loader.py ===
"""Schema loader utility."""

import os.path
import urllib
import urllib2
import urlparse

import ZConfig

try:
    True
except NameError:
    True = 1
    False = 0


class BaseLoader:
    def __init__(self):
        pass

    def createResource(self, file, url):
        return Resource(file, url)

    def load(self, url):
        pass

    def loadfile(self, file, url=None):
        if not url:
            name = getattr(file, "name", None)
            if name and name[0] != "<" and name[-1] != ">":
                url = "file://" + urllib.pathname2url(os.path.abspath(name))

    # utilities

    def openResource(self, url):
        file = urllib2.urlopen(url)
        return self.createResource(file, url)

    def normalizeURL(self, url):
        if os.path.exists(url):
            url = "file://" + urllib.pathname2url(os.path.abspath(url))
        else:
            parts = urlparse.urlparse(url)
            if not parts[0]:
                raise ValueError("invalid URL, or file does not exist:\n"
                                 + repr(url))
        return url

    def _url_from_file(self, file):
        name = getattr(file, "name", None)
        if name and name[0] != "<" and name[-1] != ">":
            return "file://" + urllib.pathname2url(os.path.abspath(name))
        else:
            return None


class Resource:
    def __init__(self, file, url):
        self.file = file
        self.url = url

    def close(self):
        if self.file is not None:
            self.file.close()
            self.file = None
            self.closed = True

    def __getattr__(self, name):
        return getattr(self.file, name)


=== Packages/ZConfig/ApacheStyle.py 1.9 => 1.9.2.1 ===
--- Packages/ZConfig/ApacheStyle.py:1.9	Fri Dec  6 10:58:36 2002
+++ Packages/ZConfig/ApacheStyle.py	Tue Dec 10 10:57:19 2002
@@ -67,27 +67,20 @@
             continue
 
         if line[0] == "%":
-            # directive: import, include
+            # directive: define, include
             m = _keyvalue_rx.match(line, 1)
             if not m:
                 raise ConfigurationSyntaxError(
                     "missing or unrecognized directive", resource.url, lineno)
             name, arg = m.group('key', 'value')
-            if name not in ("define", "import", "include"):
+            if name not in ("define", "include"):
                 raise ConfigurationSyntaxError(
                     "unknown directive: " + `name`, resource.url, lineno)
             if not arg:
                 raise ConfigurationSyntaxError(
                     "missing argument to %%%s directive" % name,
                     resource.url, lineno)
-            if name == "import":
-                if stack:
-                    raise ConfigurationSyntaxError(
-                        "import only allowed at outermost level of a resource",
-                        resource.url, lineno)
-                newurl = urlparse.urljoin(resource.url, arg)
-                context.importConfiguration(section, newurl)
-            elif name == "include":
+            if name == "include":
                 newurl = urlparse.urljoin(resource.url, arg)
                 context.includeConfiguration(section, newurl)
             elif name == "define":


=== Packages/ZConfig/Context.py 1.15 => 1.15.10.1 ===
--- Packages/ZConfig/Context.py:1.15	Thu Dec  5 00:17:45 2002
+++ Packages/ZConfig/Context.py	Tue Dec 10 10:57:19 2002
@@ -1,23 +1,21 @@
 """Top-level configuration handle."""
 
-import os
-import urllib
-import urllib2
 import urlparse
 
 import ZConfig
 
+from ZConfig import loader
+
 from Config import Configuration, ImportingConfiguration
 from Substitution import isname, substitute
 
 
-class Context:
+class Context(loader.BaseLoader):
 
     def __init__(self):
-        self._imports = []         # URL  -> Configuration
+        loader.BaseLoader.__init__(self)
         self._named_sections = {}  # name -> Configuration
         self._needed_names = {}    # name -> [needy Configuration, ...]
-        self._current_imports = []
         self._all_sections = []
 
     # subclass-support API
@@ -34,7 +32,7 @@
         return ImportingConfiguration(url)
 
     def createResource(self, file, url):
-        return Resource(file, url)
+        return DefiningResource(file, url)
 
     def getDelegateType(self, type):
         # Applications must provide delegation typing information by
@@ -45,66 +43,36 @@
         from ApacheStyle import Parse
         Parse(resource, self, section)
 
-    def _normalize_url(self, url):
-        if os.path.exists(url):
-            url = "file://" + urllib.pathname2url(os.path.abspath(url))
-        else:
-            parts = urlparse.urlparse(url)
-            if not parts[0]:
-                raise ValueError("invalid URL, or file does not exist:\n"
-                                 + repr(url))
-        return url
-
     # public API
 
     def load(self, url):
         """Load a resource from a URL or pathname."""
-        url = self._normalize_url(url)
+        url = self.normalizeURL(url)
         top = self.createToplevelSection(url)
         self._all_sections.append(top)
-        self._imports = [top]
         self._parse_url(url, top)
         self._finish()
         return top
 
     def loadfile(self, file, url=None):
         if not url:
-            name = getattr(file, "name", None)
-            if name and name[0] != "<" and name[-1] != ">":
-                url = "file://" + urllib.pathname2url(os.path.abspath(name))
+            url = self._url_from_file(file)
         top = self.createToplevelSection(url)
         self._all_sections.append(top)
-        self._imports = [top]
-        self._current_imports.append(top)
         r = self.createResource(file, url)
-        try:
-            self.parse(r, top)
-        finally:
-            del self._current_imports[-1]
+        self.parse(r, top)
         self._finish()
         return top
 
 
     # interface for parser
 
-    def importConfiguration(self, section, url):
-        for config in self._imports:
-            if config.url == url:
-                return config
-        newsect = self.createImportedSection(section, url)
-        self._all_sections.append(newsect)
-        self._imports.append(newsect)
-        section.addImport(newsect)
-        self._parse_url(url, newsect)
-
     def includeConfiguration(self, section, url):
-        # XXX we always re-parse, unlike import
-        file = urllib2.urlopen(url)
-        r = self.createResource(file, url)
+        r = self.openResource(url)
         try:
             self.parse(r, section)
         finally:
-            file.close()
+            r.close()
 
     def nestSection(self, section, type, name, delegatename):
         if name:
@@ -135,13 +103,6 @@
         section.addChildSection(newsect)
         if name:
             self._named_sections[name] = newsect
-            current = self._current_imports[-1]
-            if section is not current:
-                current.addNamedSection(newsect)
-            for config in self._current_imports[:-1]:
-                # XXX seems very painful
-                if not config._sections_by_name.has_key((type, name)):
-                    config.addNamedSection(newsect)
         return newsect
 
     # internal helpers
@@ -151,14 +112,11 @@
         if fragment:
             raise ZConfig.ConfigurationError(
                 "fragment identifiers are not currently supported")
-        file = urllib2.urlopen(url)
-        self._current_imports.append(section)
-        r = self.createResource(file, url)
+        r = self.openResource(url)
         try:
             self.parse(r, section)
         finally:
-            del self._current_imports[-1]
-            file.close()
+            r.close()
 
     def _finish(self):
         # Resolve section delegations
@@ -197,10 +155,9 @@
         self._all_sections = None
 
 
-class Resource:
+class DefiningResource(loader.Resource):
     def __init__(self, file, url):
-        self.file = file
-        self.url = url
+        loader.Resource.__init__(self, file, url)
         self._definitions = {}
 
     def define(self, name, value):