api.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #
  2. # Metrix++, Copyright 2009-2013, Metrix++ Project
  3. # Link: http://metrixplusplus.sourceforge.net
  4. #
  5. # This file is a part of Metrix++ Tool.
  6. #
  7. # Metrix++ is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, version 3 of the License.
  10. #
  11. # Metrix++ is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Metrix++. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. class Plugin(object):
  20. class Field(object):
  21. def __init__(self, name, ftype, non_zero=False):
  22. self.name = name
  23. self.type = ftype
  24. self.non_zero = non_zero
  25. class Property(object):
  26. def __init__(self, name, value):
  27. self.name = name
  28. self.value = value
  29. def initialize(self, namespace=None, support_regions=True, fields=[], properties=[]):
  30. self.is_updated = False
  31. db_loader = self.get_plugin_loader().get_database_loader()
  32. if namespace == None:
  33. namespace = self.get_name()
  34. if (len(fields) != 0 or len(properties) != 0):
  35. prev_version = db_loader.set_property(self.get_name() + ":version", self.get_version())
  36. if prev_version != self.get_version():
  37. self.is_updated = True
  38. for prop in properties:
  39. assert(prop.name != 'version')
  40. prev_prop = db_loader.set_property(self.get_name() + ":" + prop.name, prop.value)
  41. if prev_prop != prop.value:
  42. self.is_updated = True
  43. if len(fields) != 0:
  44. namespace_obj = db_loader.create_namespace(namespace,
  45. support_regions=support_regions,
  46. version=self.get_version())
  47. for field in fields:
  48. is_created = namespace_obj.add_field(field.name, field.type, non_zero=field.non_zero)
  49. assert(is_created != None)
  50. # if field is created (not cloned from the previous db),
  51. # mark the plug-in as updated in order to trigger full rescan
  52. self.is_updated = self.is_updated or is_created
  53. def terminate(self):
  54. pass
  55. def set_name(self, name):
  56. self.name = name
  57. def get_name(self):
  58. if hasattr(self, 'name') == False:
  59. return None
  60. return self.name
  61. def set_version(self, version):
  62. self.version = version
  63. def get_version(self):
  64. if hasattr(self, 'version') == False:
  65. return None
  66. return self.version
  67. def set_plugin_loader(self, loader):
  68. self.plugin_loader = loader
  69. def get_plugin_loader(self):
  70. if hasattr(self, 'plugin_loader') == False:
  71. return None
  72. return self.plugin_loader
  73. class InterfaceNotImplemented(Exception):
  74. def __init__(self, obj):
  75. import sys
  76. Exception.__init__(self, "Method '"
  77. + sys._getframe(1).f_code.co_name
  78. + "' has not been implemented for "
  79. + str(obj.__class__))
  80. class IConfigurable(object):
  81. def configure(self, options):
  82. raise InterfaceNotImplemented(self)
  83. def declare_configuration(self, optparser):
  84. raise InterfaceNotImplemented(self)
  85. class IRunable(object):
  86. def run(self, args):
  87. raise InterfaceNotImplemented(self)
  88. class IParser(object):
  89. def process(self, parent, data, is_updated):
  90. raise InterfaceNotImplemented(self)
  91. class CallbackNotImplemented(Exception):
  92. def __init__(self, obj, callback_name):
  93. Exception.__init__(self, "Callback '"
  94. + callback_name
  95. + "' has not been implemented for "
  96. + str(obj.__class__))
  97. class Child(object):
  98. def notify(self, parent, callback_name, *args):
  99. if hasattr(self, callback_name) == False:
  100. raise CallbackNotImplemented(self, callback_name)
  101. self.__getattribute__(callback_name)(parent, *args)
  102. class Parent(object):
  103. def init_Parent(self):
  104. if hasattr(self, 'children') == False:
  105. self.children = []
  106. def subscribe(self, obj, callback_name):
  107. self.init_Parent()
  108. if (isinstance(obj, Child) == False):
  109. raise TypeError()
  110. self.children.append((obj,callback_name))
  111. def unsubscribe(self, obj, callback_name):
  112. self.init_Parent()
  113. self.children.remove((obj, callback_name))
  114. def notify_children(self, *args):
  115. self.init_Parent()
  116. for child in self.children:
  117. child[0].notify(self, child[1], *args)
  118. def iterate_children(self):
  119. self.init_Parent()
  120. for child in self.children:
  121. yield child
  122. # TODO re-factor and remove this
  123. class ExitError(Exception):
  124. def __init__(self, plugin, reason):
  125. if plugin != None:
  126. Exception.__init__(self, "Plugin '"
  127. + plugin.get_name()
  128. + "' requested abnormal termination: "
  129. + reason)
  130. else:
  131. Exception.__init__(self, "'Abnormal termination requested: "
  132. + reason)
  133. def subscribe_by_parents_name(parent_name, child, callback_name='callback'):
  134. child.get_plugin_loader().get_plugin(parent_name).subscribe(child, callback_name)
  135. # interfaces for subscription
  136. class ICode(object):
  137. pass
  138. def subscribe_by_parents_interface(interface, child, callback_name='callback'):
  139. for plugin in child.get_plugin_loader().iterate_plugins():
  140. if isinstance(plugin, interface):
  141. plugin.subscribe(child, callback_name)
  142. class ITool(object):
  143. def run(self, tool_args):
  144. raise InterfaceNotImplemented(self)