# This program is free software; you can redistribute it and/or modify it under # the terms of the (LGPL) GNU Lesser General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # 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 Library Lesser General Public License # for more details at ( http://www.gnu.org/licenses/lgpl.html ). # # You should have received a copy of the GNU Lesser 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. # written by: Jeff Ortel ( jortel@redhat.com ) """ The plugin module provides suds plugin implementation classes. """ from suds import * from logging import getLogger log = getLogger(__name__) class Context(object): """Plugin context.""" pass class InitContext(Context): """ Init Context. @ivar wsdl: The WSDL. @type wsdl: L{wsdl.Definitions} """ pass class DocumentContext(Context): """ The XML document load context. @ivar url: The URL. @type url: str @ivar document: Either the XML text or the B{parsed} document root. @type document: (str|L{sax.element.Element}) """ pass class MessageContext(Context): """ The context for sending the SOAP envelope. @ivar envelope: The SOAP envelope to be sent. @type envelope: (str|L{sax.element.Element}) @ivar reply: The reply. @type reply: (str|L{sax.element.Element}|object) """ pass class Plugin: """Plugin base.""" pass class InitPlugin(Plugin): """Base class for all suds I{init} plugins.""" def initialized(self, context): """ Suds client initialization. Called after WSDL the has been loaded. Provides the plugin with the opportunity to inspect/modify the WSDL. @param context: The init context. @type context: L{InitContext} """ pass class DocumentPlugin(Plugin): """Base class for suds I{document} plugins.""" def loaded(self, context): """ Suds has loaded a WSDL/XSD document. Provides the plugin with an opportunity to inspect/modify the unparsed document. Called after each WSDL/XSD document is loaded. @param context: The document context. @type context: L{DocumentContext} """ pass def parsed(self, context): """ Suds has parsed a WSDL/XSD document. Provides the plugin with an opportunity to inspect/modify the parsed document. Called after each WSDL/XSD document is parsed. @param context: The document context. @type context: L{DocumentContext} """ pass class MessagePlugin(Plugin): """Base class for suds I{SOAP message} plugins.""" def marshalled(self, context): """ Suds is about to send the specified SOAP envelope. Provides the plugin with the opportunity to inspect/modify the envelope Document before it is sent. @param context: The send context. The I{envelope} is the envelope document. @type context: L{MessageContext} """ pass def sending(self, context): """ Suds is about to send the specified SOAP envelope. Provides the plugin with the opportunity to inspect/modify the message text before it is sent. @param context: The send context. The I{envelope} is the envelope text. @type context: L{MessageContext} """ pass def received(self, context): """ Suds has received the specified reply. Provides the plugin with the opportunity to inspect/modify the received XML text before it is SAX parsed. @param context: The reply context. The I{reply} is the raw text. @type context: L{MessageContext} """ pass def parsed(self, context): """ Suds has SAX parsed the received reply. Provides the plugin with the opportunity to inspect/modify the SAX parsed DOM tree for the reply before it is unmarshalled. @param context: The reply context. The I{reply} is DOM tree. @type context: L{MessageContext} """ pass def unmarshalled(self, context): """ Suds has unmarshalled the received reply. Provides the plugin with the opportunity to inspect/modify the unmarshalled reply object before it is returned. @param context: The reply context. The I{reply} is unmarshalled suds object. @type context: L{MessageContext} """ pass class PluginContainer: """ Plugin container provides easy method invocation. @ivar plugins: A list of plugin objects. @type plugins: [L{Plugin},] @cvar ctxclass: A dict of plugin method / context classes. @type ctxclass: dict """ domains = { 'init': (InitContext, InitPlugin), 'document': (DocumentContext, DocumentPlugin), 'message': (MessageContext, MessagePlugin)} def __init__(self, plugins): """ @param plugins: A list of plugin objects. @type plugins: [L{Plugin},] """ self.plugins = plugins def __getattr__(self, name): domain = self.domains.get(name) if not domain: raise Exception('plugin domain (%s), invalid' % (name,)) ctx, pclass = domain plugins = [p for p in self.plugins if isinstance(p, pclass)] return PluginDomain(ctx, plugins) class PluginDomain: """ The plugin domain. @ivar ctx: A context. @type ctx: L{Context} @ivar plugins: A list of plugins (targets). @type plugins: list """ def __init__(self, ctx, plugins): self.ctx = ctx self.plugins = plugins def __getattr__(self, name): return Method(name, self) class Method: """ Plugin method. @ivar name: The method name. @type name: str @ivar domain: The plugin domain. @type domain: L{PluginDomain} """ def __init__(self, name, domain): """ @param name: The method name. @type name: str @param domain: A plugin domain. @type domain: L{PluginDomain} """ self.name = name self.domain = domain def __call__(self, **kwargs): ctx = self.domain.ctx() ctx.__dict__.update(kwargs) for plugin in self.domain.plugins: method = getattr(plugin, self.name, None) if method and callable(method): method(ctx) return ctx