[Zope3-checkins] CVS: Zope3/src/zope/app - __init__.py:1.1.2.1 _app.py:1.1.2.1 attributeannotations.py:1.1.2.1 configure.zcml:1.1.2.1 content_types.py:1.1.2.1 datetime.py:1.1.2.1 dependable.py:1.1.2.1 introspector.py:1.1.2.1 meta.zcml:1.1.2.1 package_home.py:1.1.2.1 rdb.py:1.1.2.1 undo.py:1.1.2.1 undo_log.pt:1.1.2.1

Jim Fulton jim@zope.com
Mon, 23 Dec 2002 14:30:58 -0500


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

Added Files:
      Tag: NameGeddon-branch
	__init__.py _app.py attributeannotations.py configure.zcml 
	content_types.py datetime.py dependable.py introspector.py 
	meta.zcml package_home.py rdb.py undo.py undo_log.pt 
Log Message:
Initial renaming before debugging

=== Added File Zope3/src/zope/app/__init__.py ===
#
# This file is necessary to make this directory a package.


=== Added File Zope3/src/zope/app/_app.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.
# 
##############################################################################
"""Code to initialize the application server

$Id: _app.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""

import base64
from StringIO import StringIO
from zope.publisher.publish import publish as _publish

__metaclass__ = type

_configured = 0
def config(file):
    "Configure site globals"
    global _configured

    if _configured:
        return

    from zope.configuration.xmlconfig import XMLConfig

    # Set user to system_user, so we can do anything we want
    from zope.security.securitymanagement import system_user
    from zope.security.securitymanagement import newSecurityManager
    newSecurityManager(system_user)

    # Load server-independent site config
    XMLConfig(file)()

    # Reset user
    from zope.security.securitymanagement import noSecurityManager
    noSecurityManager()

    _configured = 1

def database(db):
    if type(db) is str:
        # Database name
        if db.endswith('.py'):
            # Python source, exec it
            globals = {}
            execfile(db, globals)
            if 'DB' in globals:
                db = globals['DB']
            else:
                storage = globals['Storage']
                from zodb.db import DB
                db = DB(storage)
        elif db.endswith(".fs"):
            from zodb.storage.file import FileStorage
            from zodb.db import DB
            storage = FileStorage(db)
            db = DB(storage)

    # XXX When bootstrapping a new database, the following will fail
    #     while trying to add services when no config_file was passed
    #     to Application() below.  So, don't do that. :-)
    from Zope.App.StartUp import bootstrap
    bootstrap.bootstrapInstance(db)

    return db

class Application:

    def __init__(self, db, config_file=None):
        if config_file is not None:
            config(config_file)
        self.db = database(db)

    def __call__(self):
        from zope.app.publication.zopepublication import ZopePublication
        return self.db.open().root()[ZopePublication.root_name]

    __browser_pub = None
    __TestRequest = None

    def _request(self,
                 path='/', stdin='', stdout=None, basic=None,
                 environment = None, form=None):


        env = {}

        if stdout is None:
            stdout = StringIO()

        if type(stdin) is str:
            stdin = StringIO(stdin)

        p=path.split('?')
        if len(p)==1:
            env['PATH_INFO'] = p[0]
        elif len(p)==2:
            env['PATH_INFO'], env['QUERY_STRING'] = p
        else:
            raise ValueError("Too many ?s in path", path)

        if environment is not None:
            env.update(environment)

        if basic:
            env['HTTP_AUTHORIZATION']="Basic %s" % base64.encodestring(basic)

        if self.__TestRequest is None:
            from zope.publisher.browser import TestRequest
            from zope.app.publication.browser \
                 import BrowserPublication
            from zope.app.publication.zopepublication \
                 import DebugPublication

            class BrowserPublication(DebugPublication, BrowserPublication):
                pass
            
            self.__TestRequest = TestRequest
            self.__browser_pub = BrowserPublication(self.db)

        request = self.__TestRequest(stdin, stdout, env)
        request.setPublication(self.__browser_pub)
        if form:
            request.update(form)

        return request

    def publish(self, path='/', stdin='', stdout=None, *args, **kw):
        
        if stdout is None:
            stdout = StringIO()

        request = self._request(path, stdin, stdout, *args, **kw)
        _publish(request)
        stdout.seek(0)
        print stdout.read()

    def run(self, *args, **kw):
        request = self._request(*args, **kw)
        _publish(request, handle_errors = 0)

    def debug(self, *args, **kw):
        
        import pdb

        class Pdb(pdb.Pdb):
            def do_pub(self,arg):
                if hasattr(self,'done_pub'):
                    print 'pub already done.'
                else:
                    self.do_s('')
                    self.do_s('')
                    self.do_c('')
                    self.done_pub=1
            def do_ob(self,arg):
                if hasattr(self,'done_ob'):
                    print 'ob already done.'
                else:
                    self.do_pub('')
                    self.do_c('')
                    self.done_ob=1

        db=Pdb()

        def fbreak(db, meth):
            try:
                meth = meth.im_func
            except AttributeError:
                pass
            code = meth.func_code
            lineno = getlineno(code)
            filename = code.co_filename
            db.set_break(filename,lineno)

        request = self._request(*args, **kw)
        fbreak(db, _publish)
        fbreak(db, request.publication.call_wrapper.__call__)

##         dbdata = {'breakpoints':(), 'env':env, 'extra': extra}
##         b=''
##         try: b=open('.bobodb','r').read()
##         except: pass
##         if b:
##             exec b in dbdata

##         for b in dbdata['breakpoints']:
##             if isinstance(b, TupleType):
##                 apply(db.set_break, b)
##             else:
##                 fbreak(db,b)

        db.prompt='pdb> '

        print '* Type c<cr> to jump to published object call.'
        db.runcall(_publish, request)

try:
    from codehack import getlineno
except:
    def getlineno(code):
        return code.co_firstlineno


=== Added File Zope3/src/zope/app/attributeannotations.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: attributeannotations.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""

from zodb.btrees.OOBTree import OOBTree
from zope.app.interfaces.annotation import IAnnotations
from zope.proxy.introspection import removeAllProxies
from zope.proxy.context.context import ContextWrapper

class AttributeAnnotations:
    """
    Store annotations in the __annotations__ attribute on a
    IAttributeAnnotatable object.
    """
    
    __implements__ = IAnnotations

    def __init__(self, obj):
        # We could remove all proxies from obj at this point, but
        # for now, we'll leave it to users of annotations to do that.
        # Users of annotations will typically need to do their own
        # unwrapping anyway.
        
        self.wrapped_obj = obj
        self.unwrapped_obj = removeAllProxies(obj)
        
    def __getitem__(self, key):
        annotations = getattr(self.unwrapped_obj, '__annotations__', {})
        return ContextWrapper(annotations[key], self.wrapped_obj)
        
    def get(self, key, default=None):
        try:
            value = self.unwrapped_obj.__annotations__.get(key, default)
        except AttributeError:
            # I guess default shouldn't be wrapped.
            return default
        else:
            return ContextWrapper(value, self.wrapped_obj)

    def __getattr__(self, name):
        # this method is for getting methods and attributes of the
        # mapping object used to store annotations.
        try:
            attr = getattr(self.unwrapped_obj.__annotations__, name)
        except AttributeError:
            if not hasattr(self.unwrapped_obj, '__annotations__'):
                annotations = self.unwrapped_obj.__annotations__ = OOBTree()
                attr = getattr(annotations, name)
            else:
                raise
        return ContextWrapper(attr, self.wrapped_obj)


=== Added File Zope3/src/zope/app/configure.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope' >

  <include file="meta.zcml" />

  <include package=".ComponentArchitecture" />
  <include package="zope.app.event" />
  <include package=".i18n" />
  <include package=".Security" />
  <include package=".Publisher" />
  <include package=".ZMI" />
  <include package=".OFS" />
  <include package=".RDB" />
  <include package=".Traversing" />
  <include package=".ZopePublication" />
  <include package=".Undo" />
  <include package=".Forms" />
  <include package=".Caching" />
  <include package=".DublinCore" />
  <include package=".DependencyFramework" />
  <include package=".StartUp" />
  <include package=".index" />

</zopeConfigure>

<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:browser='http://namespaces.zope.org/browser'
>

<browser:view
    permission="Zope.ManageContent"
    factory="Zope.App.Undo." >

   <browser:page name="undoForm.html" attribute="index" />
   <browser:page name="undo.html" attribute="action" />
</browser:view>

</zopeConfigure>

<zopeConfigure
     xmlns='http://namespaces.zope.org/zope'>

<serviceType id="SQLDatabaseConnections" interface="zope.app.interfaces.rdb.IConnectionService" />

<content class="zope.app.rdb.ZopeConnection">
  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.rdb.IZopeConnection" />
</content>

<content class="zope.app.rdb.ZopeCursor">
  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.rdb.IZopeCursor" />
</content>

<content class="zope.app.rdb.ResultSet">
  <require
      permission="Zope.ManageContent"
      interface="zope.app.interfaces.rdb.IResultSet" />
</content>

<content class="zope.app.rdb.Row">
  <require
      permission="Zope.ManageContent"
      attributes="__getattr__" />
</content>

<include package=".GadflyDA" />

<include package=".Browser" />

</zopeConfigure>

<zopeConfigure
    xmlns='http://namespaces.zope.org/zope'
>

  <adapter
      factory="zope.app.attributeannotations.AttributeAnnotations"
      provides="zope.app.interfaces.annotation.IAnnotations"
      for="zope.app.interfaces.annotation.IAttributeAnnotatable" />

</zopeConfigure>

<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

<include package=".Container" />
<include package=".Content" />
<include package=".Services" />
<include package=".Introspector" />
<include package=".ApplicationControl" />

<include package=".Annotation" />


</zopeConfigure>

<zopeConfigure 
   xmlns='http://namespaces.zope.org/zope'
   xmlns:browser='http://namespaces.zope.org/browser'>

  <adapter
      factory="Zope.App.OFS.Introspector."
      permission="Zope.View"
      provides="zope.app.interfaces.introspector.IIntrospector" />

  <include package=".Browser" />

</zopeConfigure>


<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

  <adapter
      factory="zope.app.dependable.Dependable"
      provides="zope.app.interfaces.dependable.IDependable"
      for="zope.app.interfaces.annotation.IAnnotatable" />


</zopeConfigure>


=== Added File Zope3/src/zope/app/content_types.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
# 
##############################################################################
"""A utility module for content-type handling."""
__version__='$Revision: 1.1.2.1 $'[11:-2]

import re, mimetypes

find_binary=re.compile('[\0-\7]').search

def text_type(s):
    # Yuk. See if we can figure out the type by content.
    s=s.strip()
    if (s[:6].lower() == '<html>' or s.find('</') > 0):
        return 'text/html'

    elif s.startswith('<?xml'):
        return 'text/xml'

    else:
        return 'text/plain'



# This gives us a hook to add content types that
# aren't currently listed in the mimetypes module.
_addtypes=(
    ('.mp3', 'audio/mpeg'),
    ('.ra', 'audio/x-pn-realaudio'),
    ('.pdf', 'application/pdf'),
    ('.c', 'text/plain'),
    ('.bat', 'text/plain'),
    ('.h', 'text/plain'),
    ('.pl', 'text/plain'),
    ('.ksh', 'text/plain'),
    ('.ram', 'application/x-pn-realaudio'),
    ('.cdf', 'application-x-cdf'),
    ('.doc', 'application/msword'),
    ('.dot', 'application/msword'),
    ('.wiz', 'application/msword'),
    ('.xlb', 'application/vnd.ms-excel'),
    ('.xls', 'application/vnd.ms-excel'),
    ('.ppa', 'application/vnd.ms-powerpoint'),
    ('.ppt', 'application/vnd.ms-powerpoint'),
    ('.pps', 'application/vnd.ms-powerpoint'),
    ('.pot', 'application/vnd.ms-powerpoint'),
    ('.pwz', 'application/vnd.ms-powerpoint'),
    ('.eml',   'message/rfc822'),
    ('.nws',   'message/rfc822'),
    ('.mht',   'message/rfc822'),
    ('.mhtml', 'message/rfc822'),
    ('.css', 'text/css'),
    ('.p7c', 'application/pkcs7-mime'),
    ('.p12', 'application/x-pkcs12'),
    ('.pfx', 'application/x-pkcs12'),
    ('.js',  'application/x-javascript'),
    ('.pct', 'image/pict'),
    ('.pic', 'image/pict'),
    ('.pict', 'image/pict'),
    ('.m1v', 'video/mpeg'),
    ('.mpa', 'video/mpeg'),
    ('.vcf', 'text/x-vcard'),
    ('.xml', 'text/xml'),
    ('.xsl', 'text/xsl'),
    ('.xul', 'text/xul'),
    )
for name, val in _addtypes:
    mimetypes.types_map[name] = val

def guess_content_type(name='', body='', default=None):
    # Attempt to determine the content type (and possibly
    # content-encoding) based on an an object's name and
    # entity body.
    type, enc = mimetypes.guess_type(name)
    if type is None:
        if body:
            if find_binary(body) is not None:
                type = default or 'application/octet-stream'
            else:
                type = (default or text_type(body) 
                      or 'text/x-unknown-content-type')
        else:
                type = default or 'text/x-unknown-content-type'
        
    return type.lower(), enc and enc.lower() or None

if __name__=='__main__':
    items=mimetypes.types_map.items()
    items.sort()
    for item in items: print "%s:\t%s" % item



=== Added File Zope3/src/zope/app/datetime.py === (889/989 lines abridged)
##############################################################################
#
# 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.
# 
##############################################################################
"""Commonly used utility functions.

$Id: datetime.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""

__version__='$Revision: 1.1.2.1 $'[11:-2]

import time

# These are needed because the various date formats below must
# be in english per the RFCs. That means we can't use strftime,
# which is affected by different locale settings.
weekday_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
weekday_full = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
                'Friday', 'Saturday', 'Sunday']
monthname    = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']


def iso8601_date(ts=None):
    # Return an ISO 8601 formatted date string, required
    # for certain DAV properties.
    # '2000-11-10T16:21:09-08:00
    if ts is None: ts=time.time()
    return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts))

def rfc850_date(ts=None):
    # Return an HTTP-date formatted date string.
    # 'Friday, 10-Nov-00 16:21:09 GMT'
    if ts is None: ts=time.time()
    year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts)
    return "%s, %02d-%3s-%2s %02d:%02d:%02d GMT" % (
            weekday_full[wd],
            day, monthname[month],
            str(year)[2:],
            hh, mm, ss)


[-=- -=- -=- 889 lines omitted -=- -=- -=-]


        if s.find('T')>-1:
            fields = timereg.split(s[s.find('T')+1:])

            if fields[1]:   hour     = int(fields[1])
            if fields[3]:   minute   = int(fields[3])
            if fields[5]:   seconds  = int(fields[5])
            if fields[6]:   seconds  = seconds+float(fields[6])

            if fields[8]:   tzsign   = fields[8]
            if fields[9]:   hour_off = int(fields[9])
            if fields[11]:  min_off  = int(fields[11])

        return (year,month,day,hour,minute,seconds,
                '%s%02d%02d' % (tzsign,hour_off,min_off))

parser = DateTimeParser()
parse = parser.parse
time = parser.time

from datetime import tzinfo as _tzinfo
class tzinfo(_tzinfo):

    __slots__ = ('offset', )

    def __init__(self, offset):
        self.offset = offset

    def utcoffset(self, dt=None):
        return self.offset

    __getstate__ = utcoffset
    __setstate__ = __init__

    def dst(self, dt): return 0
    def tzname(self, dt): return ''

    def __repr__(self):
        return 'tzinfo(%d)' % self.offset


from datetime import datetimetz as _datetimetz
def parseDatetimetz(string):
    y, mo, d, h, m, s, tz = parse(string)
    s, micro = divmod(s, 1.0)
    micro = round(micro * 1000000)
    offset = _tzoffset(tz, None) / 60
    return _datetimetz(y, mo, d, h, m, s, micro, tzinfo(offset))

_iso_tz_re = re.compile("[-+]\d\d:\d\d$")


=== Added File Zope3/src/zope/app/dependable.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.
# 
##############################################################################
"""
$Id: dependable.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""

__metaclass__ = type

from zope.app.interfaces.dependable import IDependable
from zope.app.interfaces.annotation \
     import IAnnotations
from zope.component import getAdapter

key = 'Zope.App.DependencyFramework.Dependents'

class Dependable:
    __doc__ = IDependable.__doc__

    __implements__ =  IDependable

    def __init__(self, context):
        self.context = context
        

    def addDependent(self, location):
        "See Zope.App.DependencyFramework.IDependable.IDependable"
        annotations = getAdapter(self.context, IAnnotations)
        annotations [key] = annotations.get(key, ()) + (location, )

    def removeDependent(self, location):
        "See Zope.App.DependencyFramework.IDependable.IDependable"
        annotations = getAdapter(self.context, IAnnotations)
        annotations[key] = tuple([loc
                                  for loc in annotations.get(key, ())
                                  if loc != location])

    def dependents(self):
        "See Zope.App.DependencyFramework.IDependable.IDependable"
        annotations = getAdapter(self.context, IAnnotations)
        return annotations.get(key, ())


=== Added File Zope3/src/zope/app/introspector.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.
# 
##############################################################################
from zope.interface import Interface, IInterface
from zope.interface.implements import implements, getImplements
from zope.app.interfaces.introspector import IIntrospector
from zope.proxy.introspection import removeAllProxies
from zope.component import getServiceManager, getAdapter, \
     queryServiceManager, getServiceDefinitions
from zope.app.interfaces.services.service import INameResolver
import string


class Introspector:
    """Introspecs an object"""
    __implements__ = IIntrospector
    

    def __init__(self, context):
        self.context = context
        self.request = None
        self.currentclass = None
        
    def isInterface(self):
        "Checks if the context is class or interface"
        try:
            ck = self.context.namesAndDescriptions()
            return 1
        except:
            return 0
    
    def setRequest(self, request):
        """sets the request"""
        self.request = request
        if 'PATH_INFO' in request:
            path = self.request['PATH_INFO']
        else:
            path = ''
        name = path[string.rfind(path, '++module++')+len('++module++'):]
        name = string.split(name, '/')[0]
        if string.find(path, '++module++') != -1:
            if (self.context == Interface and
                name != 'Interface._Interface.Interface'):
                servicemanager = getServiceManager(self.context)
                adapter = getAdapter(servicemanager, INameResolver)
                self.currentclass = adapter.resolve(name)
                self.context = self.currentclass
            else:
                self.currentclass = self.context
        else:
            self.currentclass = self.context.__class__
            

    def _unpackTuple(self, tuple_obj):
        res = []
        for item in tuple_obj:
            if type(item)==tuple:
                res.extend(self._unpackTuple(item))
            else: res.append(item)
        return tuple(res)
    
    def getClass(self):
        """Returns the class name"""
        return (self.currentclass).__name__

    def getBaseClassNames(self):
        """Returns the names of the classes"""
        bases = self.getExtends()
        base_names = []
        for base in bases:
            base_names.append(base.__module__+'.'+base.__name__)
        return base_names
    
    def getModule(self):
        """Returns the module name of the class"""
        return (self.currentclass).__module__
       
    def getDocString(self):
        """Returns the description of the class"""
        return removeAllProxies(self.currentclass).__doc__
        
    def getInterfaces(self):
        """Returns interfaces implemented by this class"""
        interfaces = removeAllProxies(self.currentclass).__implements__
        if type(interfaces) != tuple:
            interfaces = (interfaces,)
        else:
            interfaces = self._unpackTuple(interfaces)
        return interfaces

    def getInterfaceNames(self):
        names = []
        try:
            for intObj in self.getInterfaces():
                names.append(intObj.__module__ + '.' + intObj.__name__)
            names.sort()
            return names
        except:
            return []
    
        
    def getInterfaceDetails(self):
        """Returns the entire documentation in the interface"""
        interface = self.context
        Iname = interface.__name__
        bases = []
        desc = ''
        methods = []
        attributes = []
        if interface is not None:
            namesAndDescriptions = interface.namesAndDescriptions()
            namesAndDescriptions.sort()
            for name, desc in namesAndDescriptions:
                if hasattr(desc, 'getSignatureString'):
                    methods.append((desc.getName(),
                                    desc.getSignatureString(),
                                    desc.getDoc()))
                else:
                    attributes.append((desc.getName(), desc.getDoc()))
                
            for base in interface.getBases():
                bases.append(base.__module__+'.'+base.__name__)
            desc = str(interface.__doc__)
        return [Iname, bases, desc, methods, attributes]
            

    def getExtends(self):
        """Returns all the class extended up to the top most level"""
        bases = self._unpackTuple((self.currentclass).__bases__)
        return bases

    def getInterfaceConfiguration(self):
        """Returns details for a interface configuration"""
        #sm = queryServiceManager(self.context)
        service = []
        for name, interface in getServiceDefinitions(self.context):
            if self.context.extends(interface):
                service.append(str(name))
        print service
        return service
        


=== Added File Zope3/src/zope/app/meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

<!-- Standard configuration directives -->
<include package="zope.configuration" file="meta.zcml" />

<include package=".ComponentArchitecture" file="meta.zcml" />
<include package=".Publisher" file="meta.zcml" />
<include package=".Traversing" file="meta.zcml" />
<include package=".Security" file="meta.zcml" />
<include package=".Forms.Browser" file="meta.zcml" />
<include package=".OFS" file="meta.zcml" />
<include package=".ContentDirective" file="meta.zcml" />
<include package="zope.app.event" file="meta.zcml" />
<include package=".i18n" file="meta.zcml" />
<include package=".StartUp" file="meta.zcml" />

</zopeConfigure>

<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

  <include package=".ApplicationControl" file="meta.zcml" />

</zopeConfigure>


=== Added File Zope3/src/zope/app/package_home.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.
# 
##############################################################################
"""Function for deducing a package file-system location from global data

$Id: package_home.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""

import os

def package_home(gdict):
    filename = gdict["__file__"]
    return os.path.dirname(filename)
    


=== Added File Zope3/src/zope/app/rdb.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.
#
##############################################################################
"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from zope.app.interfaces.rdb import IResultSet


class ResultSet(list):
    """Database Result Set.

    Currently we don't do lazy instantation of rows.
    """

    __implements__ = IResultSet
    __slots__ = ('columns',)

    def __init__(self, columns, rows):
        self.columns = tuple(columns)
        row_class = RowClassFactory(columns)
        super(ResultSet, self).__init__(map(row_class, rows))

    def __setstate__(self, data):
        self.columns, rows = data
        row_class = RowClassFactory(self.columns)
        self.extend(map(row_class, rows))

    __safe_for_unpickling__ = True

    def __reduce__(self):
        cols = self.columns
        return (ResultSet, None,
                (self.columns,
                 [[getattr(row, col) for col in cols]
                  for row in self]
                ))

    # XXX __basicnew__ is deprecated in Python 2.3.
    #     What to do instead?
    def __basicnew__():
        return ResultSet((), ())
    __basicnew__ = staticmethod(__basicnew__)

    def __cmp__(self, other):
        if not isinstance(other, ResultSet):
            return super(ResultSet, self).__cmp__(other)
        c = cmp(self.columns, other.columns)
        if c:
            return c
        for row, other_row in zip(self, other):
            c = cmp(row, other_row)
            if c:
                return c
        return cmp(len(self), len(other))





"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from zope.app.component.nextservice import getNextService

from zope.app.interfaces.rdb import ISQLCommand



class SQLCommand:
    """A simple version of a SQL Command."""

    __implements__ = ISQLCommand

    def __init__(self, connection_name='', sql=''):
        self.connectionName = connection_name
        self.sql = sql

    ############################################################
    # Implementation methods for interface
    # Zope.App.RDB.ISQLCommand.

    def getConnection(self):
        'See Zope.App.RDB.ISQLCommand.ISQLCommand'
        connection_service = getNextService(self, "SQLDatabaseConnections")
        connection = connection_service.getConnection(self.connectionName)
        return connection

    def __call__(self):
        return queryForResults(self.getConnection(), self.sql)

    #
    ############################################################


"""The connection adapters contained by ConnectionService.

$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from types import StringTypes
from persistence import Persistent
from zope.app.interfaces.rdb import IZopeDatabaseAdapter



class DatabaseAdapterError(Exception):
    pass


class ZopeDatabaseAdapter(Persistent):

    __implements__ = IZopeDatabaseAdapter
    _v_connection =  None

    def __init__(self, dsn):
        self.setDSN(dsn)

    def _connection_factory(self):
        """This method should be overwritten by all subclasses"""
        conn_info = parseDSN(self.dsn)

    ############################################################
    # Implementation methods for interface
    # Zope.App.RDB.IZopeDatabaseAdapter.

    def setDSN(self, dsn):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        assert dsn.startswith('dbi://'), "The DSN has to start with 'dbi://'"
        self.dsn = dsn

    def getDSN(self):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        return self.dsn

    def connect(self):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        if not self.isConnected():
            self._v_connection = ZopeConnection(self._connection_factory(),
                                                self)

    def disconnect(self):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        if self.isConnected():
           self._v_connection.close()
           self._v_connection = None

    def isConnected(self):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        return hasattr(self, '_v_connection') and \
               self._v_connection is not None

    def __call__(self):
        'See Zope.App.RDB.IZopeDatabaseAdapter.IZopeDatabaseAdapter'
        self.connect()
        return self._v_connection

    #
    ############################################################

    ############################################################
    # Implementation methods for interface
    # Zope.App.RDB.IDBITypeInfo.IDBITypeInfo

    # Pessimistic defaults
    paramstyle = 'pyformat'
    threadsafety = 0

    def getConverter(self, type):
        'See Zope.App.RDB.IDBITypeInfo.IDBITypeInfo'
        return identity

    #
    ############################################################

def identity(x):
    return x

def parseDSN(dsn):
    """Parses a database connection string.

    We could have the following cases:

       dbi://dbname
       dbi://dbname;param1=value...
       dbi://user:passwd/dbname
       dbi://user:passwd/dbname;param1=value...
       dbi://user:passwd@host:port/dbname
       dbi://user:passwd@host:port/dbname;param1=value...

    Return value is a mapping with the following keys:

       username     username (if given) or an empty string
       password     password (if given) or an empty string
       host         host (if given) or an empty string
       port         port (if given) or an empty string
       dbname       database name
       parameters   a mapping of additional parameters to their values
    """
    assert isinstance(dsn, StringTypes), 'The dsn is not a string.'
    assert dsn.startswith('dbi://'), 'Invalid DSN; must start with "dbi://"'

    result = {}

    dsn = dsn[6:]
    # Get parameters (dict) from DSN
    raw_params = dsn.split(';')
    dsn = raw_params[0]
    raw_params = raw_params[1:]

    parameters = dict([param.split('=') for param in raw_params])

    result['parameters'] = parameters

    # Get the dbname from the DSN
    if dsn.find('/') > 0:
        dsn, dbname = dsn.split('/')
    else:
        dbname = dsn
        dsn = ''

    result['dbname'] = dbname

    # Get host and port from DSN
    if dsn and dsn.find('@') > 0:
        dsn, host_port = dsn.split('@')
        host, port = host_port.split(':')
    else:
        host, port = '', ''

    result['host'] = host
    result['port'] = port

    # Get username and password from DSN
    if dsn:
        username, password = dsn.split(':')
    else:
        username, password = '', ''

    result['username'] = username
    result['password'] = password

    return result


"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from types import UnicodeType
from zope.app.interfaces.rdb import IZopeCursor

class ZopeCursor:
    __implements__ = IZopeCursor

    def __init__(self, cursor, connection):
        self.cursor = cursor
        self.connection = connection

    def execute(self, operation, parameters=None):
        """Executes an operation, registering the underlying
        connection with the transaction system.  """

        if isinstance(operation, UnicodeType):
            operation = operation.encode('UTF-8')
        if parameters is None:
            parameters = {}
        self.connection.registerForTxn()
        return self.cursor.execute(operation, parameters)

    def __getattr__(self, key):
        return getattr(self.cursor, key)

    def fetchone(self):
        results = self.cursor.fetchone()
        return self._convertTypes(results)

    def fetchmany(self, *args, **kw):
        results = self.cursor.fetchmany(*args, **kw)
        return self._convertTypes(results)

    def fetchall(self):
        results = self.cursor.fetchall()
        return self._convertTypes(results)

    def _convertTypes(self, results):
        "Perform type conversion on query results"
        getConverter = self.connection.getTypeInfo().getConverter
        converters = [getConverter(col_info[1])
                      for col_info in self.cursor.description]
## A possible optimization -- need benchmarks to check if it is worth it
##      if filter(lambda x: x is not ZopeDatabaseAdapter.identity, converters):
##          return results  # optimize away
        def convertRow(row):
            return map(lambda converter, value: converter(value),
                       converters, row)
        return map(convertRow, results)


"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from zope.app.interfaces.rdb import IZopeConnection
from zope.app.interfaces.rdb import IZopeCursor


from transaction import get_transaction


class ZopeConnection:

    __implements__ =  IZopeConnection

    def __init__(self, conn, typeinfo):
        self.conn = conn
        self._txn_registered = False
        self._type_info = typeinfo

    def __getattr__(self, key):
        # The IDBIConnection interface is hereby implemented
        return getattr(self.conn, key)

    def cursor(self):
        'See Zope.App.RDB.IZopeConnection.IZopeConnection'
        return ZopeCursor(self.conn.cursor(), self)

    def registerForTxn(self):
        'See Zope.App.RDB.IZopeConnection.IZopeConnection'
        if not self._txn_registered:
            tm = ZopeDBTransactionManager(self)
            get_transaction().join(tm)
            self._txn_registered = True

    def commit(self):
        'See Zope.App.RDB.IDBIConnection.IDBIConnection'
        self._txn_registered = False
        self.conn.commit()

        
    def rollback(self):
        'See Zope.App.RDB.IDBIConnection.IDBIConnection'
        self._txn_registered = False
        self.conn.rollback()

    def getTypeInfo(self):
        'See Zope.App.RDB.IDBITypeInfoProvider.IDBITypeInfoProvider'
        return self._type_info


"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from zope.app.interfaces.rdb import DatabaseException



def queryForResults(conn, query):
    """Convenience function to quickly execute a query."""

    # XXX need to do typing
    cursor = conn.cursor()

    try:
        cursor.execute(query)
    except Exception, error:
        raise DatabaseException(str(error))

    if cursor.description is not None:
        columns = [c[0] for c in cursor.description]
        results = cursor.fetchall()
    else:
        # Handle the case that the query was not a SELECT
        columns = []
        results = []

    return ResultSet(columns, results)











""" Zope RDBMS Transaction Integration.

Provides a proxy for interaction between the zope transaction
framework and the db-api connection. Databases which want to support
sub transactions need to implement their own proxy.

$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from transaction.interfaces import IDataManager

class ZopeDBTransactionManager:

    __implements__ =  IDataManager

    def __init__(self, dbconn):
        self._dbconn = dbconn

    def prepare(self, txn):
        return True

    def abort(self, txn):
        self._dbconn.rollback()

    def commit(self, txn):
        self._dbconn.commit()

    # XXX Do any of the Python DB-API implementations support
    # two-phase commit?

    def savepoint(self, txn):
        return None


"""
$Id: rdb.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from Zope.Security import Checker

class Row(object):
    """Represents a row in a ResultSet"""

    def __init__(self, data):
        for k, v in zip(self.__slots__, data):
            setattr(self, k, v)

    def __str__(self):
        return "row class %s" % str(self.__slots__)

    def __cmp__(self, other):
        if not isinstance(other, Row):
            return super(Row, self).__cmp__(other)
        c = cmp(self.__slots__, other.__slots__)
        if c:
            return c
        for column in self.__slots__:
            c = cmp(getattr(self, column), getattr(other, column))
            if c:
                return c
        return 0

def RowClassFactory(columns):
    """Creates a Row object"""
    klass_namespace = {}

    klass_namespace['__Security_checker__'] = Checker.NamesChecker(columns)
    klass_namespace['__slots__'] = tuple(columns)

    return type('GeneratedRowClass', (Row,), klass_namespace)



=== Added File Zope3/src/zope/app/undo.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.
# 
##############################################################################
"""

Revision information:
$Id: undo.py,v 1.1.2.1 2002/12/23 19:30:56 jim Exp $
"""
from zope.app.interfaces.undo import IUndoManager


class ZODBUndoManager:
    """Implement the basic undo management api for a single ZODB database.
    """
    
    __implements__ =  IUndoManager

    def __init__(self, db):
        self.__db = db

    ############################################################
    # Implementation methods for interface
    # Zope.App.Undo.IUndoManager.

    def getUndoInfo(self):
        '''See interface IUndoManager'''
        
        return self.__db.undoInfo()

    def undoTransaction(self, id_list):
        '''See interface IUndoManager'''

        for id in id_list:
            self.__db.undo(id)

    #
    ############################################################




from zope.component import getUtility
from zope.publisher.browser import BrowserView
from Zope.App.PageTemplate import ViewPageTemplateFile
from zope.app.interfaces.undo import IUndoManager


class Undo(BrowserView):
    " Undo View "

    def __init__(self, *args):
        super(Undo, self).__init__(*args)
        self.utility = getUtility(self.context, IUndoManager)
        
    index = ViewPageTemplateFile('undo_log.pt')


    def action (self, id_list, REQUEST=None):
        """
        processes undo form and redirects to form again (if possible)
        """
        self.utility.undoTransaction(id_list)
        
        if REQUEST is not None:
            REQUEST.response.redirect('index.html')
            


    def getUndoInfo(self):
        return self.utility.getUndoInfo()



=== Added File Zope3/src/zope/app/undo_log.pt ===
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html metal:use-macro="views/standard_macros/page">

<head>
<title>Undo Title</title>
<link rel="stylesheet" type="text/css" href="/manage_page_style.css">
</head>

<body>
<div metal:fill-slot="body">

<form action="@@undo.html" method="post">

<p class="form-help">
This application's transactional feature allows you to easily undo changes 
made to the application's settings or data. You can revert the application 
to a &quot;snapshot&quot; of it's state at a previous point in time.
</p>

<p class="form-help">
Select one or more transactions below and then click on the &quot;Undo&quot;
button to undo those transactions.  Note that even though a transaction
is shown below, you may not be able to undo it if later transactions
modified objects that were modified by a selected transaction.
</p>



<a name="t_list" />

<table width="100%" cellspacing="0" cellpadding="2" border="0">

  <span tal:define="global undoInfo view/getUndoInfo" />
  <div tal:repeat="undoitem undoInfo">
  <span tal:condition="repeat/undoitem/odd" ><span tal:define="global rowclass string:row-hilite"/> </span>
  <span tal:condition="repeat/undoitem/even" ><span tal:define="global rowclass string:row-normal"/> </span>

  <tr tal:attributes="class rowclass">
    <td width="16" align="left" valign="top">
      <input type=checkbox name="id_list:list" value="-1" tal:attributes="value undoitem/id"/>
    </td>
    <td align="left" valign="top">
    <div class="list-item">
     
     <span tal:content="undoitem/description"> description </span>
     by
     <strong><span tal:content="undoitem/user_name"> user_name </span></strong>
 
    </div>
    </td>
<!--
    <td align="right" valign="top" colspan="2" nowrap>
    <div class="list-item" tal:content="undoitem/time">
      blah date
    </div>
    </td>
-->
  </tr>


<!--

  <tr class="row-hilite">
    <td width="16" align="left" valign="top">
    <input type="checkbox" name="transaction_info:list" 
     value="QTBOekEwdWl6ZmNBQUFBQUV2M0RDdw==
 2002/03/17 00:23:17.7272 US/Eastern /test_area/chumphries/devis_internal_site/people/addDTMLMethod " />
    </td>
    <td align="left" valign="top">
    <div class="list-item">
    /test_area/chumphries/devis_internal_site/people/addDTMLMethod by <strong> chumphries</strong>
    </div>
    </td>
    <td align="right" valign="top" colspan="2" nowrap>
    <div class="list-item">
    2002-03-17 12:23:17 AM
    </div>
    </td>
  </tr>

  </div>

  <tr class="row-normal">
    <td width="16" align="left" valign="top">
    <input type="checkbox" name="transaction_info:list"
     value="QTBOeTQzWURnOVVBQUFBQUV2M0FkUQ==
 2002/03/16 23:51:27.6595 US/Eastern /test_area/chumphries/devis_internal_site/manage_renameObjects " />
    </td>
    <td align="left" valign="top">
    <div class="list-item">
    /test_area/chumphries/devis_internal_site/manage_renameObjects by <strong> chumphries</strong>
    </div>
    </td>
    <td align="right" valign="top" colspan="2" nowrap>
    <div class="list-item">
    2002-03-16 11:51:27 PM
    </div>
    </td>
  </tr>

-->


</div>
<tr><td><input type="submit" value="Undo"></td></tr>
</table>
</form>

</div>
</body>
</html>