# -*- coding: utf-8 -*-
#
# Copyright (c) 2009 Olivier Guilyardi <olivier@samalyse.com>
#
# This file is part of TimeSide.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


# This file defines a generic object interface mechanism and
# a way to determine which components implements a given interface.
#
# For example, the following defines the Music class as implementing the
# listenable interface.
#
# class Listenable(Interface):
#     pass
#
# class Music(Component):
#    implements(Listenable)
#
# Several class can implements a such interface, and it is possible to
# discover which class implements it with implementations():
#
# list_of_classes = implementations(Listenable)
#
# This mechanism support inheritance of interfaces: a class implementing a given
# interface is also considered to implement all the ascendants of this interface.
#
# However, inheritance is not supported for components. The descendants of a class
# implementing a given interface are not automatically considered to implement this
# interface too.

__all__ = ['Component', 'MetaComponent', 'implements', 'abstract',
           'interfacedoc', 'Interface', 'implementations', 'ComponentError']


class Interface(object):

    """Marker base class for interfaces."""


def implements(*interfaces):
    """Registers the interfaces implemented by a component when placed in the
    class header"""
    MetaComponent.implements.extend(interfaces)


def abstract():
    """Declare a component as abstract when placed in the class header"""
    MetaComponent.abstract = True


def implementations(interface, recurse=True, abstract=False):
    """Returns the components implementing interface, and if recurse, any of
    the descendants of interface. If abstract is True, also return the
    abstract implementations."""
    result = []
    find_implementations(interface, recurse, abstract, result)
    return result


def interfacedoc(func):
    if isinstance(func, staticmethod):
        raise ComponentError(
            "@interfacedoc can't handle staticmethod (try to put @staticmethod above @interfacedoc)")

    if not func.__doc__:
        func.__doc__ = "@interfacedoc"
        func._interfacedoc = True
    return func


class MetaComponent(type):

    """Metaclass of the Component class, used mainly to register the interface
    declared to be implemented by a component."""

    implementations = []
    implements = []
    abstract = False

    def __new__(cls, name, bases, d):
        new_class = super(MetaComponent, cls).__new__(cls, name, bases, d)

        # Register implementations
        if MetaComponent.implements:
            for i in MetaComponent.implements:
                MetaComponent.implementations.append({
                    'interface': i,
                    'class': new_class,
                    'abstract': MetaComponent.abstract})

        # Propagate @interfacedoc
        for name in new_class.__dict__:
            member = new_class.__dict__[name]
            if isinstance(member, staticmethod):
                member = getattr(new_class, name)

            if member.__doc__ == "@interfacedoc":
                if_member = None
                for i in MetaComponent.implements:
                    if hasattr(i, name):
                        if_member = getattr(i, name)
                if not if_member:
                    raise ComponentError("@interfacedoc: %s.%s: no such member in implemented interfaces: %s"
                                         % (new_class.__name__, name, str(MetaComponent.implements)))
                member.__doc__ = if_member.__doc__

        MetaComponent.implements = []
        MetaComponent.abstract = False

        return new_class


class Component(object):

    """Base class of all components"""
    __metaclass__ = MetaComponent


def extend_unique(list1, list2):
    """Extend list1 with list2 as list.extend(), but doesn't append duplicates
    to list1"""
    for item in list2:
        if item not in list1:
            list1.append(item)


def find_implementations(interface, recurse, abstract, result):
    """Find implementations of an interface or of one of its descendants and
    extend result with the classes found."""
    for item in MetaComponent.implementations:
        if (item['interface'] == interface and (abstract or not item['abstract'])):
            extend_unique(result, [item['class']])

    if recurse:
        subinterfaces = interface.__subclasses__()
        if subinterfaces:
            for i in subinterfaces:
                find_implementations(i, recurse, abstract, result)


class ComponentError(Exception):
    pass

@@ -19,16 +19,182 @@
 8 -*-%0A#%0A
+# Copyright (C) 2003-2018 Edgewall Software%0A# Copyright (C) 2003-2004 Jonas Borgstr%C3%B6m %3Cjonas@edgewall.com%3E%0A# Copyright (C) 2004-2005 Christopher Lenz %3Ccmlenz@gmx.de%3E%0A
 # Copyri
@@ -247,17 +247,39 @@
 se.com%3E%0A
-#
+%0A# All rights reserved.
 %0A# This 

Add authors