coil.py :  » Network » Twisted » Twisted-1.0.3 » Twisted-1.0.3 » twisted » coil » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » Twisted 
Twisted » Twisted 1.0.3 » Twisted 1.0.3 » twisted » coil » coil.py
# Twisted, the Framework of Your Internet
# Copyright (C) 2001 Matthew W. Lefkowitz
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""Twisted COIL: COnfiguration ILlumination.

An end-user direct-manipulation interface to Twisted, accessible through the
web.

This is a work in progress.
"""

# System Imports
import types

# Twisted Imports
from twisted.python import log,components,reflect,roots


class InvalidConfiguration(Exception):
    """I am is raised in the case of an invalid configuration.
    """

# map between classes and their factories
factories = {}
# map between interfaces and a list of classes implementing them
interfaceImplementors = {}


# methods for coil

def registerConfigurator(configuratorClass, factory=None):
    """Register a configurator for a class."""
    configurableClass = configuratorClass.configurableClass
    components.registerAdapter(configuratorClass, configurableClass, IConfigurator)
    if factory is not None:
        registerFactory(configurableClass, factory)

def registerFactory(configurableClass, factory):
    """Register a factory for a class."""
    factories[configurableClass] = factory
    for i in components.getInterfaces(configurableClass):
        if interfaceImplementors.has_key(i):
            interfaceImplementors[i].append(configurableClass)
        else:
            interfaceImplementors[i] = [configurableClass]

def hasFactory(configurableClass):
    """Check if factory is available for this class."""
    return factories.has_key(configurableClass)

def createConfigurable(configurableClass, container, name):
    """Instantiate a configurable.

    First, I will find the factory for class configurableClass.
    Then I will call it, with 'container' and 'name' as arguments.
    """
    if not factories.has_key(configurableClass):
        raise TypeError("No configurator registered for %s" % configurableClass)
    return factories[configurableClass](container, name)

def getCollection(obj):
    """Get an object implementing ICollection for obj."""
    if components.implements(obj, IConfigurator):
        obj = obj.getInstance()
    return components.getAdapter(obj, ICollection, None)

def getConfigurator(obj):
    """Get an object implement IConfigurator for obj."""
    return components.getAdapter(obj, IConfigurator, None)

def getConfiguratorClass(klass):
    """Return an IConfigurator class for given class."""
    return components.getAdapterClass(klass, IConfigurator, None)

def getImplementors(interface):
    """Return list of registered classes that implement an interface."""
    return interfaceImplementors.get(interface, [])

def getConfiguratorsForTree(root):
    """Return iterator of Configurators for a config tree.

    This really ought to be implemented as a generator.
    """
    stack = [root]
    result = []

    while stack:
        obj = stack.pop()

        # add the configurator's dispensers to result
        cfg = getConfigurator(obj)
        if cfg is not None: result.append(cfg)

        # see if obj has children and if so add them to stack
        collection = getCollection(obj)
        if collection is not None:
            for name, entity in collection.listStaticEntities():
                stack.append(entity)

    return result


# interfaces for coil

class IConfigurator(components.Interface):
    """A configurator object.

    I have an attribute, configurableClass, which is the class of objects
    I can configure.

    I have a dictionary attribute, configTypes, that indicates what sort of
    objects I will allow to be configured.  It is a mapping of variable names
    to a list of [variable type, prompt, description].  Variable types may be
    either python type objects, classes, or objects describing a desired 'hint'
    to the interface (such as 'boolean' or ['choice', 'a', 'b', 'c']).
    (XXX Still in flux.)
    """

    def getInstance(self):
        """Return instance being configured."""
        raise NotImplementedError

    def getType(self, name):
        """Get the type of a configuration variable."""
        raise NotImplementedError

    def configDispensers(self):
        """Indicates what methods on me may be called with no arguments to create
        an instance of another configurable.  It returns a list of the form
        [(method name, interface, descString), ...].
        """
        raise NotImplementedError

    def configure(self, dict):
        """Configure our instance, given a dict of properties.

        Will raise a InvalidConfiguration exception on bad input.
        """
        raise NotImplementedError

    def getConfiguration(self):
        """Return a mapping of attribute to value.

        The returned key are the attributes mentioned in configTypes.
        """
        raise NotImplementedError


class ICollection(components.Interface):
    """A collection for coil."""


class IStaticCollection(ICollection):
    """A coil collection to which we can't add items."""

    def listStaticEntities(self):
        """Return list of children."""
        raise NotImplementedError

    def getStaticEntity(self, name):
        """Return a child given its name."""
        raise NotImplementedError


class IConfigCollection(ICollection):
    """A coil collection to which objects can be added.

    Must have an attribute entityType, which is either an Interface
    which added objects must implement, or a StringType, IntType or FloatType.
    """


# utility classes for coil

class Configurator:
    """A configurator object implementing default behaviour.

    Custom handling of configuration-item-setting can be had by adding
    configure_%s(self, value) methods to my subclass. The default is to set
    an attribute on the instance that will be configured.

    A method getConfiguration should return a mapping of attribute to value, for
    attributes mentioned in configTypes. The default is to get the attribute from
    the instance that is being configured.
    """

    __implements__ = IConfigurator

    # Change this attribute in subclasses.
    configurableClass = None

    configTypes = {}

    configName = None

    def __init__(self, instance):
        """Initialize this configurator with the instance it will be configuring."""
        if not isinstance(instance, self.configurableClass):
            raise TypeError, "%s is not a %s" % (instance, self.configurableClass)
        self.instance = instance

    def configDispensers(self):
        """Return list of dispensers."""
        return []

    def getInstance(self):
        """Return the instance being configured."""
        return self.instance

    def getType(self, name):
        """Get the type of a configuration variable."""
        if self.configTypes.has_key(name):
            return self.configTypes[name][0]
        else:
            return None

    def configure(self, dict):
        """Set a list of configuration variables."""
        items = dict.items()

        for name, value in items:
            t = self.getType(name)
            if isinstance(t, types.TypeType):
                if not isinstance(value, t) or (value is None):
                    raise InvalidConfiguration("type mismatch")
            elif isinstance(t, types.ClassType) and issubclass(t, components.Interface):
                if not components.implements(value, t) or (value is None):
                    raise InvalidConfiguration("type mismatch")
            elif t == 'boolean':
                try:
                    if value: pass
                except:
                    raise InvalidConfiguration("non-boolean for boolean type")
            else:
                raise InvalidConfiguration("Configuration item '%s' has "
                                           "unknown type '%s'" % (name, t))

        for name, value in items:
            func = getattr(self, "config_%s" % name, None)
            if func:
                func(value)
            else:
                setattr(self.instance, name, value)

    def getConfiguration(self):
        """Return a mapping of key/value tuples describing my configuration.

        By default gets the attributes from the instance being configured,
        override in subclasses if necessary.
        """
        result = {}
        for k in self.configTypes.keys():
            result[k] = getattr(self.instance, k)
        return result


class StaticCollection(roots.Locked):
    """A roots.Locked that implement IStaticCollection."""

    __implements__ = IStaticCollection


class ConfigCollection(roots.Constrained):
    """A default implementation of IConfigCollection."""

    __implements__ = IConfigCollection

    # override in subclasses
    entityType = components.Interface

    def entityConstraint(self, entity):
        if isinstance(self.entityType, types.TypeType) and isinstance(entity, self.entityType):
            return 1
        elif components.implements(entity, self.entityType):
            return 1
        else:
            raise roots.ConstraintViolation("%s of incorrect type (%s)" %
                                      (entity, self.entityType))

    def getNameType(self):
        return "Name"

    def getEntityType(self):
        return self.entityType.__name__


class CollectionWrapper:
    """Wrap an existing roots.Collection as a IConfigCollection."""

    __implements__ = IConfigCollection

    def __init__(self, collection):
        self._collection = collection

    def __getattr__(self, attr):
        return getattr(self._collection, attr)


class DispenserStorage:
    """A mini-database of dispensers.

    When first created, traverses the tree of configcollections and
    configurators and loads all dispensers.
    """

    def __init__(self, root):
        # self.dispensers is a mapping:
        # <interface> --> <list of (instance, functionName, description) tuples>
        #
        # The functionName is a string, the name of a method of the configurator
        # for the given instance.
        self.dispensers = {}
        self.addObject(root)

    def addObject(self, object):
        """Add the dispensers for an object and its config children."""
        dispensers = self.dispensers

        for cfg in getConfiguratorsForTree(object):
            obj = cfg.getInstance()
            for funcName, interface, desc in cfg.configDispensers():
                if not dispensers.has_key(interface): dispensers[interface] = []
                dispensers[interface].append((obj, funcName, desc))

    def removeObject(self, object):
        """Remove an object and its config children."""
        dispensers = self.dispensers

        for cfg in getConfiguratorsForTree(object):
            obj = cfg.getInstance()
            for funcName, interface, desc in cfg.configDispensers():
                if dispensers.has_key(interface):
                    dispensers[interface].remove((obj, funcName, desc))
                if not dispensers[interface]:
                    del dispensers[interface]

    def getDispensers(self, interface):
        """Return a list of dispensers for a given interface.

        List items are in the form (instance, functionName, description).
        """
        return self.dispensers.get(interface, [])
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.