# Copyright (c) 2005-2006 # Authors: # Godefroid Chapelle # Tarek Ziade # Balazs Ree # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # '''\ AZAX Base view class All the implementations should create a specialization of this class when building their browser views. The policy is that a method should build up a command set on available methods and then return self.render(). The default command set is implemented in the base class as well. ''' try: from Products.Five import BrowserView except ImportError: from zope.app.publisher.browser import BrowserView from commands import AzaxCommands from events import AzaxEvent from interfaces import IAzaxEvent, IAzaxView, ICommandSet from pluginregistry.commandset import getRegisteredCommandSet from zope import app, component, interface from zope.component import getSiteManager from zope.component.globalregistry import BaseGlobalComponents from zope.component.persistentregistry import PersistentAdapterRegistry from zope.component.interfaces import IComponentLookup from zope.component.interfaces import ComponentLookupError from zope.event import notify from zope.interface import implements, Interface from zope.publisher.browser import BrowserView from zope.app.publication.interfaces import IEndRequestEvent class ViewSiteManager(BaseGlobalComponents): def _init_registries(self): self.adapters = PersistentAdapterRegistry() self.utilities = PersistentAdapterRegistry() class SiteView(BrowserView): """A browser view that is its own site """ def __init__(self, context, request): super(SiteView, self).__init__(context, request) _next_sitemanager = component.getSiteManager() self._sitemanager = ViewSiteManager('siteview') self._sitemanager.__bases__ = (_next_sitemanager, ) # On Five, we should wrap it in the acquisition context # see, if self has aq_parent, it is done obligatoraly try: self.context.aq_parent except AttributeError: # Zope3 - No problem. wrapped_view = self else: wrapped_view = self.__of__(self.context) # register object event handler self._sitemanager.registerHandler(wrapped_view._eventRedispatcher) # first get a reference to the old implementation before making # ourselves the new default site manager self._getSiteManagerHook = getSiteManager.implementation getSiteManager.sethook(self.getSiteManager) def getSiteManager(self, context=None): return self._sitemanager @component.adapter(Interface) def _eventRedispatcher(self, event): if IEndRequestEvent.providedBy(event): # If this happens, we must finish activity self.stopEventListening() return if not IAzaxEvent.providedBy(event): azaxevent = AzaxEvent(self, event) notify(azaxevent) def stopEventListening(self): # reset the site manager to its original one getSiteManager.sethook(self._getSiteManagerHook) def render(self): self.stopEventListening() class AzaxBaseView(SiteView): """ Base kss view this allows setting up the content of the response, and then generate it out. """ implements(IAzaxView) def __init__(self, context, request): super(AzaxBaseView, self).__init__(context, request) self._initcommands() def _initcommands(self): self.commands = AzaxCommands() def _set_context(self, context): self._context = [context] def _get_context(self): return self._context[0] context = property(_get_context, _set_context) def render(self): '''All methods must use this to return their command set ''' commands = self.commands.render(self.request) super(AzaxBaseView, self).render() return commands def cancelRedirect(self): if self.request.RESPONSE.getStatus() == 302: # Try to not redirect if requested self.request.RESPONSE.setStatus(200) def getCommands(self): return self.commands def getCommandSet(self, name): commandset = getRegisteredCommandSet(name) # return the adapted view return commandset.provides(self) class CommandSet: implements(ICommandSet) # XXX This is really bad. Is is needed for restricted access? # If not, it has to go. If no, it needs an alternate solution. # also we need test for this. __allow_access_to_unprotected_subobjects__ = True def __init__(self, view): self.view = view self.context = self.view.context self.request = self.view.request self.commands = self.view.commands def getCommandSet(self, name): return self.view.getCommandSet(name) # XXX to be deprecated AzaxViewAdapter = CommandSet