Commit 78e22a4d authored by 's avatar

merge from 2.3

parent 7927d85f
......@@ -85,8 +85,8 @@
__doc__='''Application support
$Id: Application.py,v 1.137 2001/01/18 21:45:03 shane Exp $'''
__version__='$Revision: 1.137 $'[11:-2]
$Id: Application.py,v 1.138 2001/01/19 20:12:21 brian Exp $'''
__version__='$Revision: 1.138 $'[11:-2]
import Globals,Folder,os,sys,App.Product, App.ProductRegistry, misc_
import time, traceback, os, string, Products
......@@ -294,35 +294,26 @@ class Application(Globals.ApplicationDefaultPermissions,
def getPhysicalRoot(self): return self
checkGlobalRegistry__roles__=()
def checkGlobalRegistry(self, rebuild=1):
"""Check the global (product) registry for problems, which can
be caused by disk-based products being deleted and other things
that Zope cannot know about. If rebuild is true, the global
registry will be rebuilt automatically if a problem is found.
The return value will be true if a problem was found (and fixed,
if rebuild is true). Returns 0 if no problems found."""
fixupZClassDependencies__roles__=()
def fixupZClassDependencies(self, rebuild=0):
# Note that callers should not catch exceptions from this method
# to ensure that the transaction gets aborted if the registry
# cannot be rebuilt for some reason. Returns true if any ZClasses
# were registered as a result of the call or the registry was
# rebuilt.
jar=self._p_jar
zg =jar.root()['ZGlobals']
result=0
try: keys=list(zg.keys())
except: result=1
if (not rebuild) or (not result):
return result
# A problem was found, so try to rebuild the registry. Note
# that callers should not catch exceptions from this method
# to ensure that the transaction gets aborted if the registry
# cannot be rebuilt for some reason.
LOG('Zope', WARNING, 'Rebuilding global product registry...')
if rebuild:
import BTree
jar.root()['ZGlobals']=BTree.BTree()
result=1
zglobals =jar.root()['ZGlobals']
reg_has_key=zglobals.has_key
products=self.Control_Panel.Products
for product in products.objectValues():
LOG('Zope', INFO, 'Searching in product: %s' % product.id)
items=list(product.objectItems())
finished=[]
idx=0
......@@ -334,9 +325,16 @@ class Application(Globals.ApplicationDefaultPermissions,
continue
finished.append(base)
try:
# Try to re-register ZClasses.
# Try to re-register ZClasses if they need it.
if hasattr(ob, '_register') and hasattr(ob, '_zclass_'):
class_id=getattr(ob._zclass_, '__module__', None)
if class_id and not reg_has_key(class_id):
ob._register()
result=1
if not rebuild:
LOG('Zope', INFO,
'Registered ZClass: %s' % ob.id
)
# Include subobjects.
if hasattr(ob, 'objectItems'):
m = list(ob.objectItems())
......@@ -352,8 +350,18 @@ class Application(Globals.ApplicationDefaultPermissions,
LOG('Zope', WARNING,
'Broken objects exist in product %s.' % product.id)
idx = idx + 1
LOG('Zope', INFO, 'Successfully rebuilt global product registry')
return 1
return result
checkGlobalRegistry__roles__=()
def checkGlobalRegistry(self):
"""Check the global (zclass) registry for problems, which can
be caused by things like disk-based products being deleted.
Return true if a problem is found"""
try: keys=list(self._p_jar.root()['ZGlobals'].keys())
except: return 1
return 0
class Expired(Globals.Persistent):
......@@ -434,21 +442,54 @@ def initialize(app):
install_products(app)
# Check the global product registry for problems. Note that if the
# check finds problems but fails to successfully rebuild the global
# Check for dangling pointers (broken zclass dependencies) in the
# global class registry. If found, rebuild the registry. Note that
# if the check finds problems but fails to successfully rebuild the
# registry we abort the transaction so that we don't leave it in an
# indeterminate state.
did_fixups=0
bad_things=0
try:
if app.checkGlobalRegistry():
app.fixupZClassDependencies(rebuild=1)
did_fixups=1
LOG('Zope', INFO,
'A broken ZClass dependency was found in the global ' \
'class registry. This is probably due to a product ' \
'being uninstalled. The registry has successfully ' \
'been rebuilt.')
get_transaction().note('Rebuilt global product registry')
get_transaction().commit()
except:
bad_things=1
LOG('Zope', ERROR,
'A problem was found in the global product registry but '
'the attempt to rebuild the registry failed.',
error=sys.exc_info())
get_transaction().abort()
# Now we need to see if any (disk-based) products were installed
# during intialization. If so (and the registry has no errors),
# there may still be zclasses dependent on a base class in the
# newly installed product that were previously broken and need to
# be fixed up. If any really Bad Things happened (dangling pointers
# were found in the registry but it couldn't be rebuilt), we don't
# try to do anything to avoid making the problem worse.
if (not did_fixups) and (not bad_things):
# App.Product.initializeProduct will set this if a disk-based
# product was added or updated and we are not a ZEO client.
if getattr(Globals, '__disk_product_installed__', 0):
try:
if app.fixupZClassDependencies():
get_transaction().commit()
except:
LOG('Zope', ERROR,
'Attempt to fixup ZClass dependencies after detecting ' \
'an updated disk-based product failed.',
error=sys.exc_info())
get_transaction().abort()
def import_products(_st=type('')):
# Try to import each product, checking for and catching errors.
......
......@@ -84,9 +84,9 @@
##############################################################################
__doc__="""Object Manager
$Id: ObjectManager.py,v 1.124 2001/01/17 19:17:05 shane Exp $"""
$Id: ObjectManager.py,v 1.125 2001/01/19 20:12:21 brian Exp $"""
__version__='$Revision: 1.124 $'[11:-2]
__version__='$Revision: 1.125 $'[11:-2]
import App.Management, Acquisition, Globals, CopySupport, Products
import os, App.FactoryDispatcher, ts_regex, Products
......@@ -545,6 +545,14 @@ class ObjectManager(
# locate a valid connection
connection=self._p_jar
obj=self
# store away the length of the ZGlobals registry to compare
# later to decide if dependency fixups are needed for ZClasses
zglobals=connection.root()['ZGlobals']
try: keys_len=len(zglobals.keys())
except: keys_len=None
while connection is None:
obj=obj.aq_parent
connection=obj._p_jar
......@@ -562,6 +570,26 @@ class ObjectManager(
ob=self._getOb(id)
ob.manage_changeOwnershipType(explicit=0)
# This is to ensure that dependencies between ZClasses are
# fixed up after imports - otherwise things like base class
# dependencies are never fixed if two separate imports are
# used to add 2 ZClasses with a dependency. Somewhat hacky,
# but we sniff the ZGlobals registry to see if any ZClasses
# were added on this import. If so, we run a fixup method.
#
# If the previous registry size is None, it means that there
# is something already broken :( That really shouldn't happen,
# since a cleaning will happen at startup if the reg has
# dead pointers in it, and any ZClass import should kick off
# this fixup code.
try: new_len=len(zglobals.keys())
except: new_len=None
if (keys_len is not None) and (new_len is not None):
if new_len > keys_len:
# Looks like one or more ZClasses registered themselves
# (in their manage_afterAdd called after the import).
self.getPhysicalRoot().fixupZClassDependencies()
if REQUEST is not None:
return MessageDialog(
title='Object imported',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment