Source code for pyuseocl.model

# coding=utf-8

"""
Partial AST for USE OCL Model. The elements in this module are generated
by the "parser" module.
"""

import logging

logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger('test.' + __name__)

from collections import OrderedDict
import abc

[docs]class SourceElement(object): __metaclass__ = abc.ABCMeta def __init__(self, name, code=None): self.name = name self.source = code
[docs]class Model(SourceElement): def __init__(self, name, code=None): super(Model,self).__init__(name,code) self.isResolved = False self.enumerations = OrderedDict() #indexed by name self.classes = OrderedDict() #indexed by name self.associations = OrderedDict() #indexed by name self.associationClasses = OrderedDict() #indexed by name # indexed by operation full signatures. # e.g. 'Person::raiseSalary(rate : Real) : Real # This is useful for pre/post condition lookup self.operations = OrderedDict() #indexed by full signature # not indexed due to construction order. # The invariant are properties of classes and this is the normal # way to access them (just like attributes for instance) self.invariants = [] self.operationConditions = [] # populated during the resolution phase self.basicTypes = OrderedDict()
[docs] def findAssociationOrAssociationClass(self, name): log.debug('findAssociationOrAssociationClass:%s', name) if name in self.associations: return self.associations[name] elif name in self.associationClasses: return self.associationClasses[name] else: raise Exception('ERROR - %s : No association or association class' % name )
[docs] def findRole(self, associationOrAssociationClassName, roleName): log.debug('findRole: %s::%s', associationOrAssociationClassName, roleName) a = self.findAssociationOrAssociationClass( associationOrAssociationClassName) log.debug('findRole: %s ',a) log.debug('findRole: %s ',a.roles) if roleName in a.roles: return a.roles[roleName] else: raise Exception('ERROR - No "%s" role on association(class) %s' % (roleName, associationOrAssociationClassName) )
[docs] def findClassOrAssociationClass(self, name): if name in self.classes: return self.classes[name] elif name in self.associationClasses: return self.associationClasses[name] else: raise Exception('ERROR - %s : No class or association class' % name)
[docs] def findInvariant(self, classOrAssociationClassName, invariantName): c = self.findClassOrAssociationClass( classOrAssociationClassName) if invariantName in c.invariants: return c.invariants[invariantName] else: raise Exception('ERROR - No "%s" invariant on class %s' % (invariantName, classOrAssociationClassName))
def __str__(self): return \ 'model '+self.name+'\n' \ + 'enumerations :' \ + ','.join(self.enumerations.keys()) + '\n' \ + 'classes :' \ + ','.join(self.classes.keys()) + '\n' \ + 'associations :' \ + ','.join(self.associations.keys()) + '\n' \ + 'association classes :' \ + ','.join(self.associationClasses.keys()) + '\n' \ + 'operations :' \ + ','.join(self.operations.keys()) + '\n' \ + 'invariants :' \ + ','.join([i.name for i in self.invariants]) + '\n' \ + 'operation conditions:' \ + ','.join([i.name for i in self.operationConditions]) + '\n' \ + 'basic types :' \ + ','.join(self.basicTypes.keys()) + '\n'
[docs]class TopLevelElement(SourceElement): __metaclass__ = abc.ABCMeta def __init__(self, name, model, code=None): super(TopLevelElement,self).__init__(name,code=code) self.model = model
[docs]class SimpleType(object): # not in the source, but used after symbol resolution __metaclass__ = abc.ABCMeta
[docs]class BasicType(SimpleType): # not in sources, but used created during symbol resolution def __init__(self, name): self.name = name def __repr__(self): return self.name
[docs]class Enumeration(TopLevelElement,SimpleType): def __init__(self, name, model, code=None, literals=()): super(Enumeration, self).__init__(name, model, code) self.model.enumerations[name] = self self.literals = list(literals)
[docs] def addLiteral(self, name): self.literals.append(name)
def __repr__(self): return '%s(%s)' % (self.name,repr(self.literals))
[docs]class Class(TopLevelElement): def __init__(self, name, model, isAbstract=False, superclasses=()): super(Class, self).__init__(name, model) self.model.classes[name] = self self.isAbstract = isAbstract self.superclasses = superclasses # strings resolved as classes self.attributes = OrderedDict() self.operations = OrderedDict() self.invariants = OrderedDict() # after resolution
[docs]class Attribute(SourceElement): def __init__(self, name, class_, code=None, type=None): super(Attribute, self).__init__(name, code=code) self.class_ = class_ self.class_.attributes[name] = self self.type = type # string resolved as SimpleType
# class Parameter
[docs]class Operation(TopLevelElement): def __init__(self, name, model, class_, signature, code=None, expression=None): super(Operation, self).__init__(name, model, code) self.class_ = class_ self.class_.operations[name] = self self.signature = signature self.full_signature = '%s::%s' % (class_.name,self.signature) self.model.operations[self.full_signature] = self # self.parameters = parameters # self.return_type = return_type self.expression = expression self.conditions = OrderedDict()
[docs]class OperationCondition(TopLevelElement): __metaclass__ = abc.ABCMeta def __init__(self, name, model, operation, expression, code=None ): super(OperationCondition, self).__init__(name, model, code=code) self.model.operationConditions.append(self) operation.conditions[name] = self self.expression = expression
[docs]class PreCondition(OperationCondition): def __init__(self, name, model, operation, expression, code=None ): super(PreCondition, self).__init__( name, model, operation, expression, code=code)
[docs]class PostCondition(OperationCondition): def __init__(self, name, model, operation, expression, code=None): super(PostCondition, self).__init__( name, model, operation, expression, code=code)
[docs]class Invariant(TopLevelElement): def __init__(self, name, model, class_=None, code=None, variable='self', expression=None, additionalVariables = (), isExistential=False): super(Invariant, self).__init__(name, model, code=code) self.model.invariants.append(self) self.class_ = class_ # str resolved in Class self.expression = expression self.variable = variable self.additionalVariables = additionalVariables self.isExistential = isExistential def __str__(self): return '%s::%s' % (self.class_.name, self.name) def __repr__(self): return 'INV(%s::%s)' % (self.class_.name, self.name)
[docs]class Association(TopLevelElement): def __init__(self, name, model, kind=None): super(Association, self).__init__(name,model) self.model.associations[name] = self self.kind = kind self.roles = OrderedDict() # indexed by name self.arity = 0 # to be set self.isBinary = None # to be set
[docs]class Role(SourceElement): def __init__(self, name, association, code=None, cardMin=None, cardMax=None, type=None, isOrdered=False, qualifiers=None, subsets=None, isUnion=False, expression=None): # unamed role get the name of the class with lowercase for the first letter if name=='' or name is None: if type is not None: name = type[:1].lower() + type[1:] super(Role, self).__init__(name, code=code) self.association = association self.association.roles[name] = self self.cardinalityMin = cardMin self.cardinalityMax = cardMax self.type = type # string to be resolved in Class self.isOrdered = isOrdered # (str,str) to be resolved in (str,SimpleType) self.qualifiers = qualifiers self.subsets = subsets self.isUnion = isUnion self.expression = expression self.opposite = None # set for binary association only def __str__(self): return '%s::%s' % (self.association.name, self.name)
[docs]class AssociationClass(Class,Association): def __init__(self, name, model, isAbstract=False, superclasses=()): # Use multi-inheritance to initialize the association class Class.__init__(self, name, model, isAbstract, superclasses) Association.__init__(self, name, model, 'associationclass' ) # But register the association class apart and only once, to avoid # confusion and the duplicate in the associations and classes lists del self.model.classes[name] del self.model.associations[name] self.model.associationClasses[name] = self
# http://pythex.org # TODO # (self\.[\w.]+ |\w +::\w + |\$\w +\.\w + [\w.] * | \$\w +: \w +) # model
[docs]class ExpressionPath(object): def __init__(self, startClass, pathString): self.pathString = pathString self.startClass = startClass self.elements = self._evaluate(startClass, pathString.split('.')) def _evaluate(self, current, names): return NotImplementedError() # TODO