def setUp(self):
        """
        Create two stereotypes and extend component UML metaclass using
        them.
        """
        super(StereotypesAttributesTestCase, self).setUp()
        factory = self.element_factory
        cls = factory.create(uml2.Class)
        cls.name = 'Component'
        st1 = self.st1 = factory.create(uml2.Stereotype)
        st1.name = 'st1'
        st2 = self.st2 = factory.create(uml2.Stereotype)
        st2.name = 'st2'

        attr = factory.create(uml2.Property)
        attr.name = 'st1_attr_1'
        st1.ownedAttribute = attr
        attr = factory.create(uml2.Property)
        attr.name = 'st1_attr_2'
        st1.ownedAttribute = attr

        attr = factory.create(uml2.Property)
        attr.name = 'st2_attr_1'
        st2.ownedAttribute = attr

        self.ext1 = modelfactory.extend_with_stereotype(factory, cls, st1)
        self.ext2 = modelfactory.extend_with_stereotype(factory, cls, st2)
    def test_getting_stereotypes(self):
        """Test getting possible stereotypes
        """
        cls = self.factory.create(uml2.Class)
        cls.name = 'Class'
        st1 = self.factory.create(uml2.Stereotype)
        st1.name = 'st1'
        st2 = self.factory.create(uml2.Stereotype)
        st2.name = 'st2'

        # first extend with st2, to check sorting
        modelfactory.extend_with_stereotype(self.factory, cls, st2)
        modelfactory.extend_with_stereotype(self.factory, cls, st1)

        c1 = self.factory.create(uml2.Class)
        result = tuple(st.name for st in modelfactory.get_stereotypes(self.factory, c1))
        self.assertEquals(('st1', 'st2'), result)
    def connect_subject(self, handle):
        element = self.element
        line = self.line

        c1 = self.get_connected(line.head)
        c2 = self.get_connected(line.tail)
        if c1 and c2:
            head_type = c1.subject
            tail_type = c2.subject

            # First check if we do not already contain the right subject:
            if line.subject:
                end1 = line.subject.memberEnd[0]
                end2 = line.subject.memberEnd[1]
                if (end1.type is head_type and end2.type is tail_type) \
                   or (end2.type is head_type and end1.type is tail_type):
                    return

            # TODO: make element at head end update!
            c1.request_update()

            # Find all associations and determine if the properties on
            # the association ends have a type that points to the class.
            for assoc in self.element_factory.select():
                if isinstance(assoc, uml2.Extension):
                    end1 = assoc.memberEnd[0]
                    end2 = assoc.memberEnd[1]
                    if (end1.type is head_type and end2.type is tail_type) \
                       or (end2.type is head_type and end1.type is tail_type):
                        # check if this entry is not yet in the diagram
                        # Return if the association is not (yet) on the canvas
                        for item in assoc.presentation:
                            if item.canvas is element.canvas:
                                break
                        else:
                            line.subject = assoc
                            return
            else:
                # Create a new Extension relationship
                relation = modelfactory.extend_with_stereotype(
                    self.element_factory, head_type, tail_type)
                line.subject = relation
    def test_getting_stereotypes_unique(self):
        """Test if possible stereotypes are unique
        """
        cls1 = self.factory.create(uml2.Class)
        cls1.name = 'Class'
        cls2 = self.factory.create(uml2.Class)
        cls2.name = 'Component'
        st1 = self.factory.create(uml2.Stereotype)
        st1.name = 'st1'
        st2 = self.factory.create(uml2.Stereotype)
        st2.name = 'st2'

        # first extend with st2, to check sorting
        modelfactory.extend_with_stereotype(self.factory, cls1, st2)
        modelfactory.extend_with_stereotype(self.factory, cls1, st1)

        modelfactory.extend_with_stereotype(self.factory, cls2, st1)
        modelfactory.extend_with_stereotype(self.factory, cls2, st2)

        c1 = self.factory.create(uml2.Component)
        result = tuple(st.name for st in modelfactory.get_stereotypes(self.factory, c1))
        self.assertEquals(('st1', 'st2'), result)
Exemple #5
0
def version_0_15_0_post(elements, factory, gaphor_version):
    """
    Part two: create stereotypes and what more for the elements that have a
    taggedvalue property.
    """

    def update_elements(element):
        e = elements[element.id] = parser.element(element.id, element.__class__.__name__)
        e.element = element

    if version_lower_than(gaphor_version, (0, 14, 99)):
        stereotypes = {}
        profile = None
        for e in elements.values():
            if hasattr(e, 'taggedvalue'):
                if not profile:
                    profile = factory.create(uml2.Profile)
                    profile.name = 'version 0.15 conversion'
                    update_elements(profile)
                st = stereotypes.get(e.type)
                if not st:
                    st = stereotypes[e.type] = factory.create(uml2.Stereotype)
                    st.name = 'Tagged'
                    st.package = profile
                    update_elements(st)
                    cl = factory.create(uml2.Class)
                    cl.name = str(e.type)
                    cl.package = profile
                    update_elements(cl)
                    ext = modelfactory.extend_with_stereotype(factory, cl, st)
                    update_elements(ext)
                    for me in ext.memberEnd:
                        update_elements(me)
                # Create instance specification for the stereotype:
                instspec = modelfactory.apply_stereotype(factory, e.element, st)
                update_elements(instspec)

                def create_slot(key, val):
                    for attr in st.ownedAttribute:
                        if attr.name == key:
                            break
                    else:
                        attr = st.ownedAttribute = factory.create(uml2.Property)
                        attr.name = str(key)
                        update_elements(attr)
                    slot = modelfactory.add_slot(factory, instspec, attr)
                    slot.value.value = str(val)
                    update_elements(slot)

                tviter = iter(e.taggedvalue or [])
                for tv in tviter:
                    try:
                        try:
                            key, val = tv.split('=', 1)
                            key = key.strip()
                        except ValueError:
                            log.info('Tagged value "%s" has no key=value format, trying key_value ' % tv)
                            try:
                                key, val = tv.split(' ', 1)
                                key = key.strip()
                            except ValueError:
                                # Fallback, deal with it as if it were a boolean
                                key = tv.strip()
                                val = 'true'

                            # This syntax is used with the uml2 meta model:
                            if key in ('subsets', 'redefines'):
                                rest = ', '.join(tviter)
                                val = ', '.join([val, rest]) if rest else val
                                val = val.replace('\n', ' ')
                                log.info('Special case: UML metamodel "%s %s"' % (key, val))
                        create_slot(key, val)
                    except Exception as e:
                        log.warning('Unable to process tagged value "%s" as key=value pair' % tv, exc_info=True)

        def find(messages, attr):
            occurrences = set(getattr(m, attr) for m in messages
                              if hasattr(m, attr) and getattr(m, attr))
            assert len(occurrences) <= 1
            if occurrences:
                return occurrences.pop()
            else:
                return None

        def update_msg(msg, sl, rl):
            if sl:
                s = factory.create(uml2.MessageOccurrenceSpecification)
                s.covered = sl
                m.sendEvent = s
            if rl:
                r = factory.create(uml2.MessageOccurrenceSpecification)
                r.covered = rl
                m.receiveEvent = r

        for e in elements.values():
            if e.type == 'MessageItem':
                msg = e.element
                send = msg.subject.sendEvent
                receive = msg.subject.receiveEvent

                if not send:
                    send = find(list(msg._messages.keys()), 'sendEvent')
                if not receive:
                    receive = find(list(msg._messages.keys()), 'receiveEvent')
                if not send:
                    send = find(list(msg._inverted_messages.keys()), 'reveiveEvent')
                if not receive:
                    receive = find(list(msg._inverted_messages.keys()), 'sendEvent')

                sl = send.covered if send else None
                rl = receive.covered if receive else None

                for m in msg._messages:
                    update_msg(m, sl, rl)
                for m in msg._inverted_messages:
                    update_msg(m, rl, sl)
                msg.subject.sendEvent = send
                msg.subject.receiveEvent = receive