File: element.py

package info (click to toggle)
gaphor 0.13.0-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 3,692 kB
  • ctags: 2,971
  • sloc: python: 19,981; xml: 247; makefile: 54; sh: 40
file content (118 lines) | stat: -rw-r--r-- 3,406 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
# vim:sw=4:et
"""
Base class for UML model elements.
"""

__all__ = [ 'Element' ]

import types, mutex
from zope import component
from event import ElementDeleteEvent
from gaphor.misc import uniqueid
from properties import umlproperty, association

class Element(object):
    """
    Base class for UML data classes.
    """

    def __init__(self, id=None, factory=None):
        """
        Create an element. As optional parameters an id and factory can be
        given.

        Id is a serial number for the element. The default id is None and will
        result in an automatic creation of an id. An existing id (such as an
        int or string) can be provided as well. An id False will result in no
        id being  given (for "transient" or helper classes).

        Factory can be provided to refer to the class that maintains the
        lifecycle of the element.
        """
        self._id = id or (id is not False and uniqueid.generate_id() or False)
        # The factory this element belongs to.
        self._factory = factory
        self._observers = dict()
        self.__in_unlink = mutex.mutex()

    id = property(lambda self: self._id, doc='Id')

    factory = property(lambda self: self._factory,
                       doc="The factory that created this element")

    def umlproperties(self):
        """
        Iterate over all UML properties 
        """
        umlprop = umlproperty
        class_ = type(self)
        for propname in dir(class_):
            if not propname.startswith('_'):
                prop = getattr(class_, propname)
                if isinstance(prop, umlprop):
                    yield prop

    def save(self, save_func):
        """
        Save the state by calling save_func(name, value).
        """
        for prop in self.umlproperties():
            prop.save(self, save_func)

    def load(self, name, value):
        """
        Loads value in name. Make sure that for every load postload()
        should be called.
        """
        try:
            prop = getattr(type(self), name)
        except AttributeError, e:
            raise AttributeError, "'%s' has no property '%s'" % \
                                        (type(self).__name__, name)
        else:
            prop.load(self, value)

    def postload(self):
        """
        Fix up the odds and ends.
        """
        for prop in self.umlproperties():
            prop.postload(self)

    def unlink(self):
        """
        Unlink the element. All the elements references are destroyed.
        """
        # Uses a mutex to make sure it is not called recursively
        if self.__in_unlink.testandset():
            component.handle(ElementDeleteEvent(self._factory, self))
            try:
                for prop in self.umlproperties():
                    prop.unlink(self)
            finally:
                self.__in_unlink.unlock()


    # OCL methods: (from SMW by Ivan Porres (http://www.abo.fi/~iporres/smw))

    def isKindOf(self, class_):
        """
        Returns true if the object is an instance of class_.
        """
        return isinstance(self, class_)

    def isTypeOf(self, other):
        """
        Returns true if the object is of the same type as other.
        """
        return type(self) == type(other)


try:
    import psyco
except ImportError:
    pass
else:
    psyco.bind(Element)