[Zope3-checkins] CVS: Zope3/src/zope/app/process - __init__.py:1.1.2.1 bootstrap.py:1.1.2.1 component.xml:1.1.2.1 configure.zcml:1.1.2.1 datatypes.py:1.1.2.1 event.py:1.1.2.1 loghandlers.py:1.1.2.1 main.py:1.1.2.1 meta.zcml:1.1.2.1 metaconfigure.py:1.1.2.1 requestfactory.py:1.1.2.1 requestfactoryregistry.py:1.1.2.1 schema.xml:1.1.2.1 server.py:1.1.2.1 servertype.py:1.1.2.1 servertyperegistry.py:1.1.2.1 simpleregistry.py:1.1.2.1
Fred L. Drake, Jr.
fred@zope.com
Mon, 23 Jun 2003 18:08:00 -0400
Update of /cvs-repository/Zope3/src/zope/app/process
In directory cvs.zope.org:/tmp/cvs-serv24536/src/zope/app/process
Added Files:
Tag: fdrake-zconfig-in-zope-3-branch
__init__.py bootstrap.py component.xml configure.zcml
datatypes.py event.py loghandlers.py main.py meta.zcml
metaconfigure.py requestfactory.py requestfactoryregistry.py
schema.xml server.py servertype.py servertyperegistry.py
simpleregistry.py
Log Message:
Support ZConfig in Zope 3.
=== Added File Zope3/src/zope/app/process/__init__.py ===
# Make this a package.
=== Added File Zope3/src/zope/app/process/bootstrap.py ===
##############################################################################
#
# 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: bootstrap.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
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.servicenames import HubIds
from zope.app.services.servicenames import EventPublication, EventSubscription
from zope.app.services.servicenames import ErrorLogging
from zope.app.services.service import ServiceManager
from zope.app.services.service import ServiceRegistration
from zope.app.services.hub import ObjectHub
from zope.app.services.event import EventService
from zope.app.services.error import ErrorReportingService
from zope.app.services.principalannotation import PrincipalAnnotationService
from zope.proxy import removeAllProxies
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent
from zope.app.event import function
def bootstrapInstance(event):
"""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.
"""
db = event.database
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
publish(root_folder, ObjectCreatedEvent(root_folder))
get_transaction().commit()
connection.close()
bootstrapInstance = function.Subscriber(bootstrapInstance)
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)
# The EventService class implements two services
name = addConfigureService(root_folder, EventPublication, EventService)
configureService(root_folder, EventSubscription, name)
# Add the HubIds service, which subscribes itself to the event service
name = addService(root_folder, HubIds, ObjectHub)
configureService(root_folder, HubIds, name)
# Sundry other services
addConfigureService(root_folder, ErrorLogging,
ErrorReportingService, copy_to_zlog=True)
addConfigureService(root_folder, 'PrincipalAnnotation',
PrincipalAnnotationService)
def addConfigureService(root_folder, service_type, service_factory, **kw):
"""Add and configure a service to the root folder."""
name = addService(root_folder, service_type, service_factory, **kw)
configureService(root_folder, service_type, name)
return name
def addService(root_folder, service_type, service_factory, **kw):
"""Add 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.
Returns the name of the service implementation in the default package.
"""
# The code here is complicated by the fact that the registry
# calls at the end require a fully context-wrapped
# registration; hence all the traverse() and traverseName() calls.
package_name = '/++etc++site/default'
package = traverse(root_folder, package_name)
name = service_type + '-1'
service = service_factory()
service = removeAllProxies(service)
package.setObject(name, service)
# Set additional attributes on the service
for k, v in kw.iteritems():
setattr(service, k, v)
return name
def configureService(root_folder, service_type, name, initial_status='Active'):
"""Configure a service in the root folder."""
package_name = '/++etc++site/default'
package = traverse(root_folder, package_name)
registration_manager = package.getRegistrationManager()
registration = ServiceRegistration(service_type,
name,
registration_manager)
key = registration_manager.setObject("", registration)
registration = traverseName(registration_manager, key)
registration.status = initial_status
=== Added File Zope3/src/zope/app/process/component.xml ===
<component prefix="zope.app.process.datatypes">
<abstracttype name="logging.loghandler"/>
<sectiontype name="logging.base-log-handler">
<description>
Base type for most log handlers. This is cannot be used as a
loghandler directly since it doesn't implement the loghandler
abstract section type.
</description>
<key name="dateformat" default="%Y-%m-%dT%H:%M:%S"/>
<key name="level" default="notset" datatype=".logging_level"/>
</sectiontype>
<sectiontype name="logfile" datatype=".FileHandlerFactory"
implements="logging.loghandler"
extends="logging.base-log-handler">
<key name="path" required="yes"/>
<key name="format" default="------\n%(asctime)s %(message)s"
datatype=".log_format"/>
</sectiontype>
<sectiontype name="syslog" datatype=".SyslogHandlerFactory"
implements="logging.loghandler"
extends="logging.base-log-handler">
<key name="facility" default="user" datatype=".syslog_facility"/>
<key name="address" datatype="socket-address" default="localhost:514"/>
<key name="format" default="%(message)s"
datatype=".log_format"/>
</sectiontype>
<sectiontype name="win32-eventlog" datatype=".Win32EventLogFactory"
implements="logging.loghandler"
extends="logging.base-log-handler">
<key name="appname" default="Zope"/>
<key name="format" default="%(message)s"
datatype=".log_format"/>
</sectiontype>
<sectiontype name="http-logger" datatype=".HTTPHandlerFactory"
implements="logging.loghandler"
extends="logging.base-log-handler">
<key name="url" default="http://localhost/" datatype=".http_handler_url"/>
<key name="method" default="GET" datatype=".get_or_post"/>
<key name="format" default="%(asctime)s %(message)s"
datatype=".log_format"/>
</sectiontype>
<sectiontype name="email-notifier" datatype=".SMTPHandlerFactory"
implements="logging.loghandler"
extends="logging.base-log-handler">
<key name="from" required="yes" attribute="fromaddr"/>
<multikey name="to" required="yes" attribute="toaddrs"/>
<key name="subject" default="Message from Zope"/>
<key name="smtp-server" default="localhost" datatype="inet-address"/>
<key name="format" default="%(asctime)s %(message)s"
datatype=".log_format"/>
</sectiontype>
<sectiontype name="eventlog" datatype=".EventLogFactory">
<key name="level" datatype=".logging_level" default="info"/>
<multisection type="logging.loghandler" attribute="handlers" name="*"/>
</sectiontype>
</component>
=== Added File Zope3/src/zope/app/process/configure.zcml ===
<zopeConfigure
xmlns="http://namespaces.zope.org/zope"
xmlns:startup="http://namespaces.zope.org/startup"
xmlns:event="http://namespaces.zope.org/event">
<startup:registerRequestFactory
name="HTTPRequestFactory"
factory="zope.app.publication.httpfactory"
/>
<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="FTPRequestFactory"
publication = "zope.app.publication.ftp.FTPPublication"
request = "zope.publisher.ftp.FTPRequest"
/>
<startup:registerServerType
name = "HTTP"
factory = "zope.server.http.publisherhttpserver.PublisherHTTPServer"
requestFactory="HTTPRequestFactory"
logFactory = "zope.server.http.commonhitlogger.CommonHitLogger"
defaultPort="8080"
defaultVerbose="true" />
<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.publisher.PublisherFTPServer"
requestFactory="FTPRequestFactory"
logFactory = "zope.server.ftp.logger.CommonFTPActivityLogger"
defaultPort="8021"
defaultVerbose="true" />
<event:subscribe
subscriber=".bootstrap.bootstrapInstance"
event_types="zope.app.interfaces.event.IDatabaseOpenedEvent"
/>
</zopeConfigure>
=== Added File Zope3/src/zope/app/process/datatypes.py ===
##############################################################################
#
# 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.
#
##############################################################################
"""ZConfig datatypes for logging support."""
import sys
# log-related datatypes
_logging_levels = {
"critical": 50,
"fatal": 50,
"error": 40,
"warn": 30,
"warning": 30,
"info": 20,
"blather": 15,
"debug": 10,
"trace": 5,
"all": 1,
"notset": 0,
}
def logging_level(value):
s = str(value).lower()
if _logging_levels.has_key(s):
return _logging_levels[s]
else:
v = int(s)
if v < 0 or v > 50:
raise ValueError("log level not in range: " + `v`)
return v
_log_format_variables = {
'name': '',
'levelno': '3',
'levelname': 'DEBUG',
'pathname': 'apath',
'filename': 'afile',
'module': 'amodule',
'lineno': 1,
'created': 1.1,
'asctime': 'atime',
'msecs': 1,
'relativeCreated': 1,
'thread': 1,
'message': 'amessage',
}
def log_format(value):
value = ctrl_char_insert(value)
try:
# Make sure the format string uses only names that will be
# provided, and has reasonable type flags for each, and does
# not expect positional args.
value % _log_format_variables
except (ValueError, KeyError):
raise ValueError, 'Invalid log format string %s' % value
return value
_control_char_rewrites = {r'\n': '\n', r'\t': '\t', r'\b': '\b',
r'\f': '\f', r'\r': '\r'}.items()
def ctrl_char_insert(value):
for pattern, replacement in _control_char_rewrites:
value = value.replace(pattern, replacement)
return value
_marker = object()
class Factory:
"""Generic wrapper for instance construction.
Calling the factory causes the instance to be created if it hasn't
already been created, and returns the object. Calling the factory
multiple times returns the same object.
The instance is created using the factory's create() method, which
must be overriden by subclasses.
"""
def __init__(self):
self.instance = _marker
def __call__(self):
if self.instance is _marker:
self.instance = self.create()
return self.instance
def create(self):
raise NotImplementedError("subclasses need to override create()")
class HandlerFactory(Factory):
def __init__(self, section):
Factory.__init__(self)
self.section = section
def create_loghandler(self):
raise NotImplementedError(
"subclasses must override create_loghandler()")
def create(self):
import logging
logger = self.create_loghandler()
logger.setFormatter(logging.Formatter(self.section.format,
self.section.dateformat))
logger.setLevel(self.section.level)
return logger
class FileHandlerFactory(HandlerFactory):
def create_loghandler(self):
# XXX this implementation should change
from zope.app.process.loghandlers import StreamHandler, FileHandler
path = self.section.path
if path == "STDERR":
return StreamHandler(sys.stderr)
if path == "STDOUT":
return StreamHandler(sys.stdout)
return FileHandler(path)
_syslog_facilities = {
"auth": 1,
"authpriv": 1,
"cron": 1,
"daemon": 1,
"kern": 1,
"lpr": 1,
"mail": 1,
"news": 1,
"security": 1,
"syslog": 1,
"user": 1,
"uucp": 1,
"local0": 1,
"local1": 1,
"local2": 1,
"local3": 1,
"local4": 1,
"local5": 1,
"local6": 1,
"local7": 1,
}
def syslog_facility(value):
value = value.lower()
if not _syslog_facilities.has_key(value):
L = _syslog_facilities.keys()
L.sort()
raise ValueError("Syslog facility must be one of " + ", ".join(L))
return value
class SyslogHandlerFactory(HandlerFactory):
def create_loghandler(self):
from zope.app.process.loghandlers import SysLogHandler
return SysLogHandler(self.section.address.address,
self.section.facility)
class Win32EventLogFactory(HandlerFactory):
def create_loghandler(self):
from zope.app.process.loghandlers import Win32EventLogHandler
return Win32EventLogHandler(self.section.appname)
def http_handler_url(value):
import urlparse
scheme, netloc, path, param, query, fragment = urlparse.urlparse(value)
if scheme != 'http':
raise ValueError, 'url must be an http url'
if not netloc:
raise ValueError, 'url must specify a location'
if not path:
raise ValueError, 'url must specify a path'
q = []
if param:
q.append(';')
q.append(param)
if query:
q.append('?')
q.append(query)
if fragment:
q.append('#')
q.append(fragment)
return (netloc, path + ''.join(q))
def get_or_post(value):
value = value.upper()
if value not in ('GET', 'POST'):
raise ValueError('method must be "GET" or "POST", instead received: '
+ repr(value))
return value
class HTTPHandlerFactory(HandlerFactory):
def create_loghandler(self):
from zope.app.process.loghandlers import HTTPHandler
host, selector = self.section.url
return HTTPHandler(host, selector, self.section.method)
class SMTPHandlerFactory(HandlerFactory):
def create_loghandler(self):
from zope.app.process.loghandlers import SMTPHandler
host, port = self.section.smtp_server
if not port:
mailhost = host
else:
mailhost = host, port
return SMTPHandler(mailhost, self.section.fromaddr,
self.section.toaddrs, self.section.subject)
class EventLogFactory(Factory):
"""
A wrapper used to create loggers while delaying actual logger
instance construction. We need to do this because we may
want to reference a logger before actually instantiating it (for example,
to allow the app time to set an effective user).
An instance of this wrapper is a callable which, when called, returns a
logger object.
"""
def __init__(self, section):
Factory.__init__(self)
self.level = section.level
self.handler_factories = section.handlers
def create(self):
# set the logger up
import logging
logger = logging.getLogger("event")
logger.handlers = []
logger.propagate = 0
logger.setLevel(self.level)
if self.handler_factories:
for handler_factory in self.handler_factories:
handler = handler_factory()
logger.addHandler(handler)
else:
from zope.app.process.loghandlers import NullHandler
logger.addHandler(NullHandler())
return logger
=== Added File Zope3/src/zope/app/process/event.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Process-lifetime related events.
$Id: event.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.app.interfaces import event
from zope.interface import implements
class DatabaseOpened:
implements(event.IDatabaseOpenedEvent)
def __init__(self, database):
self.database = database
class ProcessStarting:
implements(event.IProcessStartingEvent)
=== Added File Zope3/src/zope/app/process/loghandlers.py ===
##############################################################################
#
# Copyright (c) 2001 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
#
##############################################################################
"""Handlers which can plug into a PEP 282 logger."""
import sys
from logging import Handler, StreamHandler
from logging.handlers import SysLogHandler
from logging.handlers import HTTPHandler, SMTPHandler
from logging.handlers import NTEventLogHandler as Win32EventLogHandler
class FileHandler(StreamHandler):
"""
A file handler which allows for reopening of logs in favor of the
'rollover' features of the standard PEP282 FileHandler.
"""
def __init__(self, filename, mode="a"):
StreamHandler.__init__(self, open(filename, mode))
self.baseFilename = filename
self.mode = mode
def close(self):
self.stream.close()
def reopen(self):
self.close()
self.stream = open(self.baseFilename, self.mode)
class NullHandler(Handler):
"""
A null handler. Does nothing.
"""
def emit(self, record):
pass
def handle(self, record):
pass
class StartupHandler(Handler):
"""
A handler which outputs messages to a stream but also buffers them until
they can be flushed to a target handler. Useful at startup before we can
know that we can safely write to a config-specified handler.
"""
def __init__(self, stream=None):
Handler.__init__(self)
if not stream:
stream = sys.stderr
self.stream = stream
self.buffer = []
def emit(self, record):
try:
self.buffer.append(record)
msg = self.format(record)
self.stream.write("%s\n" % msg)
self.flush()
except:
self.handleError()
def flush(self):
self.stream.flush()
def flushBufferTo(self, target):
for record in self.buffer:
target.handle(record)
self.buffer = []
=== Added File Zope3/src/zope/app/process/main.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""Functions that control how the Zope appserver knits itself together.
$Id: main.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
import logging
import os
import sys
import time
from zdaemon import zdoptions
from zodb.zeo import threadedasync
from zope.app import config
from zope.app.event import publish
from zope.app.process import event
from zope.server.taskthreads import ThreadedTaskDispatcher
def main(args=None):
# Record start times (real time and CPU time)
t0 = time.time()
c0 = time.clock()
setup(args)
t1 = time.time()
c1 = time.clock()
logging.info("Startup time: %.3f sec real, %.3f sec CPU", t1-t0, c1-c0)
run()
sys.exit(0)
def run():
try:
threadedasync.loop()
except KeyboardInterrupt:
# Exit without spewing an exception.
pass
def setup(args=None):
if args is None:
args = sys.argv[1:]
options = zdoptions.ZDOptions()
options.schemadir = os.path.dirname(os.path.abspath(__file__))
options.realize(args)
options = options.configroot
sys.setcheckinterval(options.check_interval)
options.eventlog()
config(options.site_definition)
db = options.database.open()
publish(None, event.DatabaseOpened(db))
task_dispatcher = ThreadedTaskDispatcher()
task_dispatcher.setThreadCount(options.threads)
for server in options.servers:
server.create(task_dispatcher, db)
publish(None, event.ProcessStarting())
=== Added File Zope3/src/zope/app/process/meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
<directives namespace="http://namespaces.zope.org/startup">
<directive name="registerRequestFactory"
attributes="name publication request"
handler="zope.app.process.metaconfigure.registerRequestFactory"
/>
<directive name="registerServerType"
attributes="name publication request"
handler="zope.app.process.metaconfigure.registerServerType"
/>
</directives>
</zopeConfigure>
=== Added File Zope3/src/zope/app/process/metaconfigure.py ===
##############################################################################
#
# 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: metaconfigure.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.configuration.action import Action
from zope.app.process import requestfactoryregistry
from zope.app.process import servertyperegistry
from zope.app.process.requestfactory import RequestFactory
from zope.app.process.servertype import ServerType
def registerRequestFactory(_context, name, request=None, publication=None,
factory=None):
if factory:
if request or publication:
raise ValuesError(
"""Can't provide a request or publication (factory) if you
provide a (request) factory""")
request_factory = _context.resolve(factory)
else:
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),
)
]
=== Added File Zope3/src/zope/app/process/requestfactory.py ===
##############################################################################
#
# 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 $
"""
import copy
from zope.app.interfaces.startup import IRequestFactory
from zope.interface import implements
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
=== Added File Zope3/src/zope/app/process/requestfactoryregistry.py ===
##############################################################################
#
# 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: requestfactoryregistry.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
from zope.app.process.simpleregistry import SimpleRegistry
from zope.app.interfaces.startup import IPublicationRequestFactoryFactory
from zope.interface import implements
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(
IPublicationRequestFactoryFactory)
registerRequestFactory = RequestFactoryRegistry.register
getRequestFactory = RequestFactoryRegistry.get
# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from zope.testing.cleanup import addCleanUp
addCleanUp(RequestFactoryRegistry._clear)
del addCleanUp
=== Added File Zope3/src/zope/app/process/schema.xml ===
<schema>
<!-- database and storage types -->
<import package="zodb" />
<!-- logging configuration -->
<import package="zope.app.process" />
<sectiontype name="server" datatype="zope.app.process.server.ServerFactory">
<key name="type" required="yes" />
<key name="address" datatype="inet-address" />
<key name="verbose" datatype="boolean" />
</sectiontype>
<section type="zodb.database" name="*" required="yes"
attribute="database" />
<section type="eventlog" attribute="eventlog" name="*" />
<multisection type="server" name="*" attribute="servers" />
<key name="site-definition" default="site.zcml" />
<key name="interrupt-check-interval" datatype="integer" default="120"
attribute="check_interval" />
<key name="threads" datatype="integer" default="4" />
</schema>
=== Added File Zope3/src/zope/app/process/server.py ===
##############################################################################
#
# Copyright (c) 2003 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.
#
##############################################################################
"""XXX short summary goes here.
XXX longer description goes here.
$Id: server.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.app.process.servertyperegistry import getServerType
class ServerFactory:
def __init__(self, section):
self.type = section.type
self.address = section.address
self.verbose = section.verbose
def create(self, task_dispatcher, database):
servertype = getServerType(self.type)
# The server object self-registers with the asyncore mainloop.
servertype.create(task_dispatcher, database,
self.address[1], # XXX maybe improve API
self.verbose)
=== Added File Zope3/src/zope/app/process/servertype.py ===
##############################################################################
#
# 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, implements
from zope.app.process.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()})
=== Added File Zope3/src/zope/app/process/servertyperegistry.py ===
##############################################################################
#
# 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: servertyperegistry.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
from zope.app.process.servertype import IServerType
from zope.app.process.simpleregistry import SimpleRegistry
from zope.interface import implements
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
=== Added File Zope3/src/zope/app/process/simpleregistry.py ===
##############################################################################
#
# 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: simpleregistry.py,v 1.1.2.1 2003/06/23 22:07:58 fdrake Exp $
"""
from zope.app.interfaces.startup.simpleregistry import ISimpleRegistry
from types import ListType, TupleType
from zope.interface import implements
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 _clear(self):
self.objects.clear()
def register(self, name, object):
'''See ISimpleRegistry'''
if name in self.objects.keys():
raise ZopeDuplicateRegistryEntryError(name)
if self.interface.isImplementedBy(object):
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