Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 134 lines (103 sloc) 5.043 kb
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
"""
The Sanitize module is dedicated to adapters (stuff) that keeps
the model clean and in sync with diagrams.
"""

from zope import interface
from zope import component

from logging import getLogger
from gaphor import UML
from gaphor.UML.interfaces import IAssociationDeleteEvent, IAssociationSetEvent
from gaphor.interfaces import IService
from gaphor.core import inject
from gaphor.diagram import items

class SanitizerService(object):
    """
Does some background cleanup jobs, such as removing elements from the
model that have no presentations (and should have some).
"""
    interface.implements(IService)

    logger = getLogger('Sanitizer')

    component_registry = inject('component_registry')
    element_factory = inject('element_factory')
    property_dispatcher = inject('property_dispatcher')

    def __init__(self):
        pass

    def init(self, app=None):
        self.component_registry.register_handler(self._unlink_on_presentation_delete)
        self.component_registry.register_handler(self._unlink_on_stereotype_delete)
        self.component_registry.register_handler(self._unlink_on_extension_delete)
        self.component_registry.register_handler(self._disconnect_extension_end)

    def shutdown(self):
        self.component_registry.unregister_handler(self._unlink_on_presentation_delete)
        self.component_registry.unregister_handler(self._unlink_on_stereotype_delete)
        self.component_registry.unregister_handler(self._unlink_on_extension_delete)
        self.component_registry.unregister_handler(self._disconnect_extension_end)
        

    @component.adapter(IAssociationDeleteEvent)
    def _unlink_on_presentation_delete(self, event):
        """
Unlink the model element if no more presentations link to the `item`'s
subject or the deleted item was the only item currently linked.
"""
        
        self.logger.debug('Handling IAssociationDeleteEvent')
        #self.logger.debug('Property is %s' % event.property.name)
        #self.logger.debug('Element is %s' % event.element)
        #self.logger.debug('Old value is %s' % event.old_value)
        
        if event.property is UML.Element.presentation:
            old_presentation = event.old_value
            if old_presentation and not event.element.presentation:
                event.element.unlink()

    def perform_unlink_for_instances(self, st, meta):
        
        self.logger.debug('Performing unlink for instances')
        #self.logger.debug('Stereotype is %s' % st)
        #self.logger.debug('Meta is %s' % meta)
                
        inst = UML.model.find_instances(self.element_factory, st)

        for i in list(inst):
            for e in i.extended:
                if not meta or isinstance(e, meta):
                    i.unlink()


    @component.adapter(IAssociationDeleteEvent)
    def _unlink_on_extension_delete(self, event):
        """
Remove applied stereotypes when extension is deleted.
"""
        
        self.logger.debug('Handling IAssociationDeleteEvent')
        #self.logger.debug('Property is %s' % event.property.name)
        #self.logger.debug('Element is %s' % event.element)
        #self.logger.debug('Old value is %s' % event.old_value)
        
        if isinstance(event.element, UML.Extension) and \
                event.property is UML.Association.memberEnd and \
                event.element.memberEnd:
            p = event.element.memberEnd[0]
            ext = event.old_value
            if isinstance(p, UML.ExtensionEnd):
                p, ext = ext, p
            st = ext.type
            meta = p.type and getattr(UML, p.type.name)
            self.perform_unlink_for_instances(st, meta)


    @component.adapter(IAssociationSetEvent)
    def _disconnect_extension_end(self, event):
        
        self.logger.debug('Handling IAssociationSetEvent')
        #self.logger.debug('Property is %s' % event.property.name)
        #self.logger.debug('Element is %s' % event.element)
        #self.logger.debug('Old value is %s' % event.old_value)
        
        if event.property is UML.ExtensionEnd.type and event.old_value:
            ext = event.element
            p = ext.opposite
            if not p:
                return
            st = event.old_value
            meta = getattr(UML, p.type.name)
            self.perform_unlink_for_instances(st, meta)


    @component.adapter(IAssociationDeleteEvent)
    def _unlink_on_stereotype_delete(self, event):
        """
Remove applied stereotypes when stereotype is deleted.
"""
        
        self.logger.debug('Handling IAssociationDeleteEvent')
        #self.logger.debug('Property is %s' % event.property)
        #self.logger.debug('Element is %s' % event.element)
        #self.logger.debug('Old value is %s' % event.old_value)
        
        if event.property is UML.InstanceSpecification.classifier:
            if isinstance(event.old_value, UML.Stereotype):
                event.element.unlink()


# vim:sw=4:et:ai
Something went wrong with that request. Please try again.