"""Module Documentation here
"""
#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (http://www.ccpn.ac.uk) 2014 - 2017"
__credits__ = ("Wayne Boucher, Ed Brooksbank, Rasmus H Fogh, Luca Mureddu, Timothy J Ragan & Geerten W Vuister")
__licence__ = ("CCPN licence. See http://www.ccpn.ac.uk/v3-software/downloads/license",
"or ccpnmodel.ccpncore.memops.Credits.CcpnLicense for licence text")
__reference__ = ("For publications, please use reference from http://www.ccpn.ac.uk/v3-software/downloads/license",
"or ccpnmodel.ccpncore.memops.Credits.CcpNmrReference")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: CCPN $"
__dateModified__ = "$dateModified: 2017-07-07 16:33:24 +0100 (Fri, July 07, 2017) $"
__version__ = "$Revision: 3.0.0 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2017-04-07 10:28:48 +0000 (Fri, April 07, 2017) $"
#=========================================================================================
# Start of code
#=========================================================================================
""" Python-specific version of ModelAdapt
"""
from ccpnmodel.ccpncore.memops.scripts.core.ModelAdapt import ModelAdapt
from ccpnmodel.ccpncore.memops.metamodel import MetaModel
from ccpnmodel.ccpncore.memops.metamodel import Constants as metaConstants
import copy
[docs]class PyModelAdapt(ModelAdapt):
""" Python-specific version of ModelAdapt
"""
def __init__(self):
"""Class constructor.
Automatically processes model.
"""
# model flavour (must be done first)
self.addModelFlavour('language','python')
# superclass init call
super(PyModelAdapt, self).__init__()
# adapt variableName data.
# NB this variable is used in handcode
self.varNames['other'] = 'value'
# MetaModelElement corresponding to class
self.varNames['metaclass'] = '_metaclass'
self.varNames['packageName'] = '_packageName'
self.varNames['fieldNames'] = '_fieldNames'
self.varNames['packageShortName'] = '_packageShortName'
# new variable - used for dataDict optimisation
# NB this variable is used in handcode
self.varNames['dataDict'] = 'dataDict'
# adapt opData
operationData = self.operationData
# new, init
operationData['init']['name'] = '__init__'
###########################################################################
###########################################################################
###
### functions overriding ModelAdapt
###
###########################################################################
###########################################################################
[docs] def initComplexDataType(self, complexDataType):
""" processing actions for class
"""
# super function call
ModelAdapt.initComplexDataType(self, complexDataType)
# add metaclass attribute
if complexDataType.qualifiedName() == self.rootClassName:
self.addMetaClassAttr(complexDataType)
initClass = initComplexDataType
initDataObjType = initComplexDataType
###########################################################################
###########################################################################
###########################################################################
###########################################################################
[docs] def addDataObjTypeOperations(self, inClass):
""" Add operations not linked to an element (e.g. init, delete, checkValid)
"""
ModelAdapt.addDataObjTypeOperations(self, inClass)
if inClass.isAbstract and not inClass.supertypes:
# constructor (will be abstact and will raise an exception)
self.makeOperations(inClass, 'init', inClass)
###########################################################################
###########################################################################
[docs] def addClassOperations(self, inClass):
""" Add operations not linked to an element (e.g. init, delete, checkValid)
"""
ModelAdapt.addClassOperations(self, inClass)
if inClass.isAbstract and not inClass.supertypes:
# constructor (will be abstact and will raise an exception)
self.makeOperations(inClass, 'init', inClass)
if inClass.qualifiedName() == self.baseClassName:
# special case
# getByNavigation
params = {
'opType':'otherQuery',
'isQuery':True,
'name':'getByNavigation',
'isImplicit':True,
'documentation':"""Return object or element given a navigation sequence, or None if none found
Intended to provide fast, one-function-call access to
long range navigation, mainly for UML-embedded code.
NB there is no error checking on the input.
The function may fail without proper warning for incorrect input.
Also the function bypasses the API on get commands, so that load is
not triggered on MemopsRoot->TopObject links or partially filled
interpackage crosslinks
Programmer beware!
Navigation starts at self and follows the navigation sequence,
which consists of either string tags, or (tag,key) tuples.
- For a string tag the function gets the corresponding element.
Except at the end of the navigation sequence, this assumes that
the element has hicard==1, and is a link or complex data type attribute.
If the result evaluates false, a getattr is done instead.
This may trigger loading and follow derived links.
- For a (tag,key) tuple this assumes that the tag is the name of a
child link, and gets the child with the given key.
If no children are found and the object has an attribute isLoaded==False,
object.load() is tried.
- If at any stage in the lookup no object is found, None is returned
""",
'codeStubs':{'python':"""
isa = isinstance
result = self
for xx in navigation:
dd = result.__dict__
if isa(xx,str):
# xx is a role name - get the link
result = dd.get(xx) or getattr(result,xx)
else:
# xx must be a (childlink,key) tuple.
tag,key = xx
dd2 = dd[tag]
if not dd2 and dd.get('isLoaded') == False:
# we might need to load this
try:
result.load()
except AttributeError:
pass
# Now get the child
result = dd2.get(key)
if result is None:
break
else:
# freeze internal representations
if isa(result, list):
result = tuple(result)
elif isa(result, set):
result = frozenset(result)
elif isa(result, dict):
result = frozenset(result.values())"""}
}
op = self.newElement(MetaModel.MetaOperation, container=inClass, **params)
op.target = op
anyType = inClass.metaObjFromQualName('memops.Implementation.Any')
params = {'name':'result', 'direction':metaConstants.return_direction,
'isImplicit':True, 'valueType':anyType}
self.newElement(MetaModel.MetaParameter, container=op, **params)
params = {'name':'navigation', 'direction':metaConstants.in_direction,
'isImplicit':True, 'valueType':anyType,
'locard':0, 'hicard':metaConstants.infinity,
'taggedValues':{'isSubdivided':'True'},}
self.newElement(MetaModel.MetaParameter, container=op, **params)
###########################################################################
# ###########################################################################
#
# def getOpData(self, target, opType, inClass=None):
# """ Get opData for opType, taking special cases into account
#
# NB should probably be removed. Try it.
# """
#
# return ModelAdapt.getOpData(self, target, opType, inClass)
#
# if (opType == 'init' and isinstance(target, MetaModel.MetaClass)
# and not target.isAbstract and target.parentRole is None):
# # Project init - must have optional parent to avoid
# # validity problems if the number of parameters change
# result = copy.deepcopy(self.operationData[opType])
# result['opType'] = opType
# result['target'] = target
# for subData in result['subOps'].values():
# subData['parameters'][0]['defaultValue'] = None
#
# else:
# result = ModelAdapt.getOpData(self, target, opType, inClass)
#
# #
# return result
#
###########################################################################
###########################################################################
[docs] def getOpDocumentation(self, opData, inClass, opSubType=None,
copyElemDoc=False):
""" get documentation for generated operation
copyElemDoc defaults to False in Python
we have the element documentation on the properties
"""
return ModelAdapt.getOpDocumentation(self, opData, inClass, opSubType,
copyElemDoc)
###########################################################################
###########################################################################
###
### internal code
###
###########################################################################