dcal.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. '''This file is part of AToMPM - A Tool for Multi-Paradigm Modelling
  2. Copyright 2011 by the AToMPM team and licensed under the LGPL
  3. See COPYING.lesser and README.md in the root of this project for full details'''
  4. import sys
  5. from .tconstants import TConstants as TC
  6. from .dapi import DesignerAPI
  7. try :
  8. import spidermonkey
  9. except ImportError as ex :
  10. pass
  11. '''
  12. this class abstracts away the fact that designer code may be specified in
  13. more than one programming language '''
  14. class DesignerCodeAbstractionLayer :
  15. def __init__(self,username,aswid,mtwid) :
  16. self._dAPI = DesignerAPI(username,aswid,mtwid)
  17. self._execContexts = {}
  18. self._execContext = None
  19. '''
  20. configure this instance of DesignerCodeAbstractionLayer and its instance
  21. of DesignerAPI
  22. 1. lazy load an ExecutionContext given the specified programming language
  23. 2. configure DesignerAPI instance '''
  24. def configure(
  25. self,lang,graph,type,pl2gi,ex,pLabel=None,attr=None,journal=None) :
  26. if lang not in self._execContexts :
  27. if lang == TC.PYTHON :
  28. self._execContexts[lang] = PythonExecutionContext(self._dAPI)
  29. elif lang == TC.JAVASCRIPT and 'spidermonkey' in sys.modules :
  30. self._execContexts[lang] = JavaScriptExecutionContext(self._dAPI)
  31. else :
  32. assert False, 'unsupported designer code language :: '+str(lang)
  33. self._execContext = self._execContexts[lang]
  34. self._dAPI.configure(graph,type,pl2gi,ex,pLabel,attr,journal)
  35. '''
  36. have the given code evaluated by the current ExecutionContext and return
  37. its output '''
  38. def eval(self,code) :
  39. return self._execContext.eval(code)
  40. '''
  41. identify the language in which the given snippet of designer code is
  42. written in '''
  43. @staticmethod
  44. def identifyLanguage(code) :
  45. if code.startswith('"[JAVASCRIPT]"\n') :
  46. return TC.JAVASCRIPT
  47. elif code.startswith('"[PYTHON]"\n') :
  48. return TC.PYTHON
  49. return None
  50. '''
  51. this class provides means to evaluate javascript code that makes use of the
  52. DesignerAPI '''
  53. class JavaScriptExecutionContext :
  54. '''
  55. setup a spidermonkey javascript execution context such that evaluated
  56. javascript code will have access to DesignerAPI functions '''
  57. def __init__(self,dAPI) :
  58. self._context = spidermonkey.Runtime().new_context()
  59. self._context.bind_callable("getAttr",dAPI._getAttr)
  60. self._context.bind_callable("hasAttr",dAPI._hasAttr)
  61. self._context.bind_callable("setAttr",dAPI._setAttr)
  62. self._context.bind_callable("getAllNodes",dAPI._getAllNodes)
  63. self._context.bind_callable("getNeighbors",dAPI._getNeighbors)
  64. self._context.bind_callable("isConnectionType",dAPI._isConnectionType)
  65. self._context.bind_callable("httpReq",dAPI._httpReq)
  66. self._context.bind_callable("print",dAPI._print)
  67. self._context.bind_callable("printToDevCon",dAPI._printToDevCon)
  68. self._context.bind_callable("session_get",dAPI._session_get)
  69. self._context.bind_callable("session_put",dAPI._session_put)
  70. self._context.bind_callable("sys_call",dAPI._sys_call)
  71. self._context.bind_callable("sys_mkdir",dAPI._sys_mkdir)
  72. self._context.bind_callable("sys_readf",dAPI._sys_readf)
  73. self._context.bind_callable("sys_writef",dAPI._sys_writef)
  74. self._context.bind_callable("pauseTransformation",dAPI._pauseTransformation)
  75. self._context.bind_callable("resumeTransformation",dAPI._resumeTransformation)
  76. self._context.bind_callable("stopTransformation",dAPI._stopTransformation)
  77. '''
  78. evaluate a string of javascript code and return its output '''
  79. def eval(self,code) :
  80. return self._context.eval_script(code)
  81. '''
  82. this class provides means to evaluate python code that makes use of the
  83. DesignerAPI '''
  84. class PythonExecutionContext :
  85. '''
  86. setup a python execution context such that evaluated python code will have
  87. access to DesignerAPI class '''
  88. def __init__(self,dAPI) :
  89. self._context = \
  90. {'getAttr' : dAPI._getAttr,
  91. 'hasAttr' : dAPI._hasAttr,
  92. 'getAttrNames' : dAPI._getAttrNames,
  93. 'setAttr' : dAPI._setAttr,
  94. 'getAllNodes' : dAPI._getAllNodes,
  95. 'getNodesFromLabels' : dAPI._getNodesFromLabels,
  96. 'getNeighbors' : dAPI._getNeighbors,
  97. 'isConnectionType' : dAPI._isConnectionType,
  98. 'httpReq' : dAPI._httpReq,
  99. 'printToDevCon' : dAPI._printToDevCon,
  100. 'session_get' : dAPI._session_get,
  101. 'session_put' : dAPI._session_put,
  102. 'sys_call' : dAPI._sys_call,
  103. 'sys_mkdir' : dAPI._sys_mkdir,
  104. 'sys_readf' : dAPI._sys_readf,
  105. 'sys_writef' : dAPI._sys_writef,
  106. 'pauseTransformation' : dAPI._pauseTransformation,
  107. 'resumeTransformation' : dAPI._resumeTransformation,
  108. 'stopTransformation' : dAPI._stopTransformation}
  109. '''
  110. evaluate a string of python code and return its output
  111. NOTE:: before evaluating, we clear past results, if any '''
  112. def eval(self,code) :
  113. if 'result' in self._context :
  114. del self._context['result']
  115. if sys.version_info[0] < 3:
  116. exec(code) in self._context
  117. else:
  118. exec((code), self._context)
  119. if 'result' not in self._context :
  120. return None
  121. return self._context['result']