[Zope3-checkins] CVS: Zope3/src/zope/app/startup - __init__.py:1.2 bootstrap.py:1.2 configure.zcml:1.2 initzodb.py:1.2 meta.zcml:1.2 metaconfigure.py:1.2 requestfactory.py:1.2 requestfactoryregistry.py:1.2 servertype.py:1.2 servertyperegistry.py:1.2 simpleregistry.py:1.2 sitedefinition.py:1.2 startup.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:13:57 -0500
Update of /cvs-repository/Zope3/src/zope/app/startup
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/app/startup
Added Files:
__init__.py bootstrap.py configure.zcml initzodb.py meta.zcml
metaconfigure.py requestfactory.py requestfactoryregistry.py
servertype.py servertyperegistry.py simpleregistry.py
sitedefinition.py startup.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/app/startup/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/__init__.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
=== Zope3/src/zope/app/startup/bootstrap.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/bootstrap.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,98 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Bootstrap code.
+
+This module contains code to bootstrap a Zope3 instance. For example
+it makes sure a root folder exists and creates and configures some
+essential services.
+
+$Id$
+"""
+from transaction import get_transaction
+
+from zope.app.traversing import traverse, traverseName
+from zope.app.publication.zopepublication import ZopePublication
+from zope.app.content.folder import RootFolder
+from zope.app.services.service import ServiceManager
+from zope.app.services.service import \
+ ServiceConfiguration
+from zope.app.services.hub import ObjectHub
+from zope.app.services.event import \
+ LocalEventService
+from zope.app.services.errorr import \
+ ErrorReportingService
+
+
+def bootstrapInstance(db):
+ """Bootstrap a Zope3 instance given a database object.
+
+ This first checks if the root folder exists. If it exists, nothing
+ is changed. If no root folder exists, one is added, and several
+ essential services are added and configured.
+ """
+ connection = db.open()
+ root = connection.root()
+ root_folder = root.get(ZopePublication.root_name, None)
+
+ if root_folder is None:
+ # Bootstrap code
+
+ root_folder = RootFolder()
+ addEssentialServices(root_folder)
+ root[ZopePublication.root_name] = root_folder
+
+ get_transaction().commit()
+
+ connection.close()
+
+
+def addEssentialServices(root_folder):
+ """Add essential services.
+
+ XXX This ought to be configurable. For now, hardcode some
+ services we know we all need.
+ """
+ service_manager = ServiceManager()
+ root_folder.setServiceManager(service_manager)
+ addService(root_folder, 'Events', LocalEventService)
+ addService(root_folder, 'ObjectHub', ObjectHub)
+ addService(root_folder, 'ErrorReportingService', ErrorReportingService,
+ copy_to_zlog=True)
+
+
+def addService(root_folder, service_type, service_factory,
+ initial_status='Active', **kw):
+ """Add and configure a service to the root folder.
+
+ The service is added to the default package and activated.
+ This assumes the root folder already has a service manager,
+ and that we add at most one service of each type.
+ """
+ # The code here is complicated by the fact that the registry
+ # calls at the end require a fully context-wrapped
+ # configuration; hence all the traverse[Name]() calls.
+ package_name = ('', '++etc++Services', 'Packages', 'default')
+ package = traverse(root_folder, package_name)
+ name = service_type + '-1'
+ service = service_factory()
+ package.setObject(name, service)
+ configuration_manager = traverseName(package, 'configure')
+ configuration = ServiceConfiguration(service_type,
+ package_name + (name,))
+ key = configuration_manager.setObject(None, configuration)
+ configuration = traverseName(configuration_manager, key)
+ configuration.status = initial_status
+ # Set additional attributes on the service
+ for k, v in kw.iteritems():
+ setattr(service, k, v)
=== Zope3/src/zope/app/startup/configure.zcml 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/configure.zcml Wed Dec 25 09:13:24 2002
@@ -0,0 +1,55 @@
+<zopeConfigure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:startup="http://namespaces.zope.org/startup">
+
+
+ <startup:registerRequestFactory name="BrowserRequestFactory"
+ publication =
+ "zope.app.publication.browser.BrowserPublication"
+ request = "zope.publisher.browser.BrowserRequest"
+ />
+
+
+ <startup:registerRequestFactory name="XMLRPCRequestFactory"
+ publication =
+ "zope.app.publication.xmlrpc.XMLRPCPublication"
+ request = "zope.publisher.xmlrpc.XMLRPCRequest"
+ />
+
+
+ <startup:registerRequestFactory name="VFSRequestFactory"
+ publication =
+ "zope.app.publication.vfs.VFSPublication"
+ request = "zope.publisher.vfs.VFSRequest"
+ />
+
+
+ <startup:registerServerType
+ name = "Browser"
+ factory = "zope.server.http.publisherhttpserver.PublisherHTTPServer"
+ requestFactory="BrowserRequestFactory"
+ logFactory = "zope.server.http.commonhitlogger.CommonHitLogger"
+ defaultPort="8080"
+ defaultVerbose="true" />
+
+
+ <startup:registerServerType
+ name = "XML-RPC"
+ factory = "zope.server.http.publisherhttpserver.PublisherHTTPServer"
+ requestFactory="XMLRPCRequestFactory"
+ logFactory = "zope.server.http.commonhitlogger.CommonHitLogger"
+ defaultPort="8081"
+ defaultVerbose="true" />
+
+
+ <startup:registerServerType
+ name = "FTP"
+ factory = "zope.server.ftp.publisherftpserver.PublisherFTPServer"
+ requestFactory="VFSRequestFactory"
+ logFactory =
+ "zope.server.ftp.commonftpactivitylogger.CommonFTPActivityLogger"
+ defaultPort="8021"
+ defaultVerbose="true" />
+
+
+</zopeConfigure>
=== Zope3/src/zope/app/startup/initzodb.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/initzodb.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
=== Zope3/src/zope/app/startup/meta.zcml 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/meta.zcml Wed Dec 25 09:13:24 2002
@@ -0,0 +1,33 @@
+<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
+
+ <directives namespace="http://namespaces.zope.org/startup">
+
+ <directive name="defineSite"
+ attributes="name threads"
+ handler="zope.app.startup.metaconfigure.defineSite">
+
+ <subdirective name="useFileStorage"
+ attributes="file" />
+
+ <subdirective name="useMappingStorage" />
+
+ <subdirective name="useLog" attributes="file level" />
+
+ <subdirective name="addServer"
+ attributes="type port verbose logClass" />
+
+ </directive>
+
+ <directive name="registerRequestFactory"
+ attributes="name publication request"
+ handler="zope.app.startup.metaconfigure.registerRequestFactory"
+ />
+
+ <directive name="registerServerType"
+ attributes="name publication request"
+ handler="zope.app.startup.metaconfigure.registerServerType"
+ />
+
+ </directives>
+
+</zopeConfigure>
=== Zope3/src/zope/app/startup/metaconfigure.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/metaconfigure.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+This module handles the :startup directives.
+
+$Id$
+"""
+
+from zope.app.startup.sitedefinition import SiteDefinition
+from zope.configuration.action import Action
+from zope.app.startup import requestfactoryregistry
+from zope.app.startup import servertyperegistry
+from zope.app.startup.requestfactory import RequestFactory
+from zope.app.startup.servertype import ServerType
+
+defineSite = SiteDefinition
+
+
+def registerRequestFactory(_context, name, publication, request):
+ publication = _context.resolve(publication)
+ request = _context.resolve(request)
+ request_factory = RequestFactory(publication, request)
+
+ return [
+ Action(
+ discriminator = name,
+ callable = requestfactoryregistry.registerRequestFactory,
+ args = (name, request_factory,),
+ )
+ ]
+
+
+def registerServerType(_context, name, factory, requestFactory, logFactory,
+ defaultPort, defaultVerbose):
+ factory = _context.resolve(factory)
+ logFactory = _context.resolve(logFactory)
+
+ if defaultVerbose.lower() == 'true':
+ defaultVerbose = True
+ else:
+ defaultVerbose = False
+
+ defaultPort = int(defaultPort)
+
+ server_type = ServerType(name, factory, requestFactory, logFactory,
+ defaultPort, defaultVerbose)
+
+ return [
+ Action(
+ discriminator = name,
+ callable = servertyperegistry.registerServerType,
+ args = (name, server_type),
+ )
+ ]
=== Zope3/src/zope/app/startup/requestfactory.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/requestfactory.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""ctory.py,v 1.1.2.2 2002/04/02 02:20:40 srichter Exp $
+"""
+
+from zope.interface import Interface
+import copy
+
+
+class IRequestFactory(Interface):
+ """This is a pure read-only interface, since the values are set through
+ a ZCML directive and we shouldn't be able to change them.
+ """
+
+ def realize(db):
+ """Realize the factory by initalizing the publication.
+
+ The method returns the realized object.
+ """
+
+
+ def __call__(input_stream, output_steam, env):
+ """Call the Request Factory"""
+
+
+
+
+
+class RequestFactory:
+ """This class will generically create RequestFactories. This way I do
+ not have to create a method for each Server Type there is.
+ """
+
+ __implements__ = IRequestFactory
+
+ def __init__(self, publication, request):
+ """Initialize Request Factory"""
+ self._pubFactory = publication
+ self._publication = None
+ self._request = request
+
+
+ def realize(self, db):
+ 'See IRequestFactory'
+ realized = copy.copy(self)
+ realized._publication = realized._pubFactory(db)
+ return realized
+
+
+ def __call__(self, input_stream, output_steam, env):
+ 'See IRequestFactory'
+ request = self._request(input_stream, output_steam, env)
+ request.setPublication(self._publication)
+ return request
=== Zope3/src/zope/app/startup/requestfactoryregistry.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/requestfactoryregistry.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,40 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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$
+"""
+from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
+from zope.app.startup.simpleregistry import SimpleRegistry
+from zope.app.startup.requestfactory import IRequestFactory
+
+
+class IRequestFactoryRegistry(ISimpleRegistry):
+ """
+ The RequestFactory Registry manages a list of all the fields
+ available in Zope. A registry is useful at this point, since
+ fields can be initialized and registered by many places.
+
+ Note that it does not matter whether we have classes or instances as
+ fields. If the fields are instances, they must implement
+ IInstanceFactory.
+ """
+
+
+class RequestFactoryRegistry(SimpleRegistry):
+ __implements__ = (IRequestFactoryRegistry,)
+
+
+RequestFactoryRegistry = RequestFactoryRegistry(IRequestFactory)
+registerRequestFactory = RequestFactoryRegistry.register
+getRequestFactory = RequestFactoryRegistry.get
=== Zope3/src/zope/app/startup/servertype.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/servertype.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""e.py,v 1.1.2.2 2002/04/02 02:20:40 srichter Exp $
+"""
+
+from zope.interface import Interface
+from zope.app.startup.requestfactoryregistry import getRequestFactory
+
+
+class IServerType(Interface):
+ """This is a pure read-only interface, since the values are set through
+ a ZCML directive and we shouldn't be able to change them.
+ """
+
+ def create(task_dispatcher, db, port=None, verbose=None):
+ """Create the server knowing the port, task dispatcher and the ZODB.
+ """
+
+
+class ServerType:
+
+ __implements__ = IServerType
+
+
+ def __init__(self, name, factory, requestFactory, logFactory,
+ defaultPort, defaultVerbose):
+ """ """
+ self._name = name
+ self._factory = factory
+ self._requestFactory = requestFactory
+ self._logFactory = logFactory
+ self._defaultPort = defaultPort
+ self._defaultVerbose = defaultVerbose
+
+
+ def create(self, task_dispatcher, db, port=None, verbose=None):
+ 'See IServerType'
+
+ request_factory = getRequestFactory(self._requestFactory)
+ request_factory = request_factory.realize(db)
+
+ if port is None:
+ port = self._defaultPort
+
+ if verbose is None:
+ verbose = self._defaultVerbose
+
+ apply(self._factory,
+ (request_factory, self._name, '', port),
+ {'task_dispatcher': task_dispatcher,
+ 'verbose': verbose,
+ 'hit_log': self._logFactory()})
=== Zope3/src/zope/app/startup/servertyperegistry.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/servertyperegistry.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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$
+"""
+from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
+from zope.app.startup.servertype import IServerType
+from zope.app.startup.simpleregistry import SimpleRegistry
+
+
+class IServerTypeRegistry(ISimpleRegistry):
+ """
+ The ServerType Registry manages a list of all the fields
+ available in Zope. A registry is useful at this point, since
+ fields can be initialized and registered by many places.
+
+ Note that it does not matter whether we have classes or instances as
+ fields. If the fields are instances, they must implement
+ IInstanceFactory.
+ """
+
+
+class ServerTypeRegistry(SimpleRegistry):
+ """Registry for the various Server types"""
+ __implements__ = (IServerTypeRegistry,)
+
+
+ServerTypeRegistry = ServerTypeRegistry(IServerType)
+registerServerType = ServerTypeRegistry.register
+getServerType = ServerTypeRegistry.get
=== Zope3/src/zope/app/startup/simpleregistry.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:56 2002
+++ Zope3/src/zope/app/startup/simpleregistry.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,96 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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$
+"""
+from zope.configuration.name import resolve
+from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
+from types import StringTypes, ListType, TupleType
+ListTypes = (TupleType, ListType)
+
+
+class ZopeDuplicateRegistryEntryError(Exception):
+ """
+ This Error is raised when the user tries to add an object with
+ a name that already exists in the registry. Therefore,
+ overwriting is not allowed.
+ """
+
+ def __init__(self, name):
+ """Initializes Error"""
+ self.name = name
+
+ def __str__(self):
+ """Returns string representation of Error"""
+ return "The name '%s' is already defined in this registry." \
+ %self.name
+
+
+class ZopeIllegalInterfaceError(Exception):
+ """This Error is thrown, when the passed object does not implement
+ the specified interface."""
+
+ def __init__(self, name, interface):
+ """Initalize Error"""
+ self.name = name
+ self.interface = interface
+
+ def __str__(self):
+ """Returns string representation of Error"""
+ return ( "The object with name " + self.name + " does not implement "
+ "the interface " + self.interface.__name__ + "." )
+
+
+
+class SimpleRegistry:
+ """ """
+
+ __implements__ = (ISimpleRegistry,)
+
+
+ def __init__(self, interface):
+ """Initialize registry"""
+ self.objects = {}
+ self.interface = interface
+
+
+ def register(self, name, object):
+ '''See ISimpleRegistry'''
+
+ if name in self.objects.keys():
+ raise ZopeDuplicateRegistryEntryError(name)
+
+ # XXX Find the right Interface tools to do that; unfortunately,
+ # I have not found them
+ # Check whether the object implements the right interface.
+ # Note, that we do *not* know whether the object is an instance
+ # or a class (or worse a Persistent class)
+ if hasattr(object, '__implements__') and \
+ ( self.interface == object.__implements__ or \
+ ( type(object.__implements__) in ListTypes and
+ self.interface in object.__implements__ ) ):
+ self.objects[name] = object
+
+ else:
+ raise ZopeIllegalInterfaceError(name, self.interface)
+
+ return []
+
+
+ def get(self, name):
+ '''See ISimpleRegistry'''
+ if name in self.objects.keys():
+ return self.objects[name]
+ else:
+ return None
=== Zope3/src/zope/app/startup/sitedefinition.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:57 2002
+++ Zope3/src/zope/app/startup/sitedefinition.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,202 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+This module handles the :startup directives.
+
+$Id$
+"""
+
+import logging
+import sys
+
+# Importing zlogintegration redirects asyncore's logging to the
+# logging module
+from zope.server import zlogintegration
+
+# Import Configuration-related classes
+from zope.configuration.action import Action
+from zope.interfaces.configuration import INonEmptyDirective
+from zope.interfaces.configuration import ISubdirectiveHandler
+
+from zope.app.startup.servertyperegistry import getServerType
+
+# Import Undo-related classes
+from zope.app.content.folder import RootFolder
+from zope.app.interfaces.undo import IUndoManager
+from zope.app.publication.zopepublication import ZopePublication
+from zope.app.browser.undo import ZODBUndoManager
+from zope.component import getService
+from zope.server.taskthreads import ThreadedTaskDispatcher
+
+from zodb.code.module import PersistentModuleImporter
+
+DEFAULT_STORAGE_FILE = 'Data.fs'
+DEFAULT_LOG_FILE = 'STDERR'
+DEFAULT_LOG_LEVEL = 'INFO'
+
+
+class SiteDefinition:
+
+ __class_implements__ = INonEmptyDirective
+ __implements__ = ISubdirectiveHandler
+
+ # Some special file names for log files
+ _special_log_files = {'STDERR': sys.stderr,
+ 'STDOUT': sys.stdout}
+
+ # Mapping from log level names to numeric log levels
+ _log_levels = {
+ 'CRITICAL' : logging.CRITICAL,
+ 'ERROR' : logging.ERROR,
+ 'WARN' : logging.WARN,
+ 'INFO' : logging.INFO,
+ 'DEBUG' : logging.DEBUG,
+ 'NOTSET' : logging.NOTSET,
+ }
+
+
+ def __init__(self, _context, name="default", threads=4):
+ """Initialize is called when defineSite directive is invoked."""
+ self._name = name
+ self._threads = int(threads)
+
+ self._zodb = None
+ self.useLog(_context)
+ self._servers = {}
+
+ self._started = 0
+
+ def close(self):
+ if self._zodb is not None:
+ self._zodb.close()
+ self._zodb = None
+
+ def useFileStorage(self, _context, file=DEFAULT_STORAGE_FILE):
+ """Lets you specify the ZODB to use."""
+ from zodb.storage.file import DB
+ if self._zodb is not None:
+ raise RuntimeError("Database already open")
+ self._zodb = DB(file)
+ return []
+
+
+ def useMappingStorage(self, _context):
+ """Lets you specify the ZODB to use."""
+ from zodb.storage.mapping import DB
+ if self._zodb is not None:
+ raise RuntimeError("Database already open")
+ self._zodb = DB()
+ return []
+
+
+ def useLog(self, _context, file=DEFAULT_LOG_FILE, level=DEFAULT_LOG_LEVEL):
+ """Lets you specify the log file and level to use"""
+
+ # Translate the level to logging
+ loglevel = self._log_levels.get(level.upper())
+ if loglevel is None:
+ raise ValueError, "unknown log level %r" % level
+
+ # Get the root logger and set its logging level
+ root = logging.root
+ root.setLevel(loglevel)
+
+ # Remove previous handlers
+ for h in root.handlers[:]:
+ root.removeHandler(h)
+
+ # Create the new handler
+ if file in self._special_log_files.keys():
+ file = self._special_log_files[file]
+ handler = logging.StreamHandler(file)
+ else:
+ handler = logging.FileHandler(file)
+
+ # Create a standard Zope-style formatter and set it
+ formatter = logging.Formatter(
+ "------\n"
+ "%(asctime)s %(levelname)s %(name)s %(message)s",
+ datefmt="%Y-%m-%dT%H:%M:%S")
+ handler.setFormatter(formatter)
+
+ # Set the handler
+ root.addHandler(handler)
+
+ # Return empty sequence to satisfy API
+ return []
+
+
+ def addServer(self, _context, type, port=None, verbose=None):
+ """Add a new server for this site."""
+
+ if port is not None:
+ port = int(port)
+
+ if verbose is not None:
+ if verbose.lower() == 'true': verbose = 1
+ else: verbose = 0
+
+ if type is not None:
+ self._servers[type] = {'port': port,
+ 'verbose': verbose}
+ else:
+ sys.stderr.out('Warning: Server of Type %s does not exist. ' +
+ 'Directive neglected.')
+ return []
+
+
+ def start(self):
+ """Now start all the servers"""
+
+ sys.stderr.write('\nStarting Site: %s\n\n' %self._name)
+
+ sys.setcheckinterval(120)
+
+ # setup undo fnctionality
+ getService(None,"Utilities").provideUtility(
+ IUndoManager,
+ ZODBUndoManager(self._zodb)
+ )
+
+ # Setup the task dispatcher
+ td = ThreadedTaskDispatcher()
+ td.setThreadCount(self._threads)
+
+ # check whether a root was already specified for this ZODB; if
+ # not create one.
+ self._initDB()
+
+ # Start the servers
+ for type, server_info in self._servers.items():
+
+ server = getServerType(type)
+ server.create(td, self._zodb, server_info['port'],
+ server_info['verbose'])
+
+ def _initDB(self):
+ """Initialize the ZODB and persistence module importer."""
+
+ from zope.app.startup import bootstrap
+ bootstrap.bootstrapInstance(self._zodb)
+
+ imp = PersistentModuleImporter()
+ imp.install()
+
+
+ def __call__(self):
+ "Handle empty/simple declaration."
+ return [ Action(discriminator = 'Start Servers',
+ callable = self.start,
+ args = ()),
+ ]
=== Zope3/src/zope/app/startup/startup.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:13:57 2002
+++ Zope3/src/zope/app/startup/startup.py Wed Dec 25 09:13:24 2002
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################