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)
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