From 17e63e965729e519d624245d92c0e3146316ecfe Mon Sep 17 00:00:00 2001
From: Stefano Borini <sborini@enthought.com>
Date: Wed, 19 Jul 2017 13:14:21 +0100
Subject: [PATCH] Separates bundle registry from the rest of the app

---
 force_bdss/base_core_driver.py       | 61 ++++---------------------
 force_bdss/bdss_application.py       |  3 +-
 force_bdss/bundle_registry.py        | 67 ++++++++++++++++++++++++++++
 force_bdss/core_evaluation_driver.py |  6 +--
 force_bdss/core_mco_driver.py        |  2 +-
 5 files changed, 81 insertions(+), 58 deletions(-)
 create mode 100644 force_bdss/bundle_registry.py

diff --git a/force_bdss/base_core_driver.py b/force_bdss/base_core_driver.py
index b3c2702..701180a 100644
--- a/force_bdss/base_core_driver.py
+++ b/force_bdss/base_core_driver.py
@@ -1,12 +1,10 @@
-from envisage.extension_point import ExtensionPoint
 from envisage.plugin import Plugin
-from traits.api import List
+from traits.trait_types import Instance
 
-from force_bdss.data_sources.i_data_source_bundle import (
-    IDataSourceBundle)
-from force_bdss.kpi.i_kpi_calculator_bundle import IKPICalculatorBundle
-from force_bdss.mco.i_multi_criteria_optimizer_bundle import (
-    IMultiCriteriaOptimizerBundle)
+from force_bdss.bundle_registry import (
+    BundleRegistryPlugin,
+    BUNDLE_REGISTRY_PLUGIN_ID
+)
 
 
 class BaseCoreDriver(Plugin):
@@ -14,50 +12,7 @@ class BaseCoreDriver(Plugin):
     or the evaluation.
     """
 
-    # Note: we are forced to declare these extensions points here instead
-    # of the application object, and this is why we have to use this plugin.
-    # It is a workaround to an envisage bug that does not find the extension
-    # points if declared on the application.
+    bundle_registry = Instance(BundleRegistryPlugin)
 
-    #: A List of the available Multi Criteria Optimizers.
-    #: This will be populated by MCO plugins.
-    mco_bundles = ExtensionPoint(
-        List(IMultiCriteriaOptimizerBundle),
-        id='force.bdss.mco.bundles')
-
-    #: A list of the available Data Sources.
-    #: It will be populated by plugins.
-    data_source_bundles = ExtensionPoint(
-        List(IDataSourceBundle),
-        id='force.bdss.data_sources.bundles')
-
-    #: A list of the available Key Performance Indicator calculators.
-    #: It will be populated by plugins.
-    kpi_calculator_bundles = ExtensionPoint(
-        List(IKPICalculatorBundle),
-        id='force.bdss.kpi_calculators.bundles')
-
-    def _data_source_bundle_by_id(self, id):
-        for ds in self.data_source_bundles:
-            if ds.id == id:
-                return ds
-
-        raise Exception("Requested data source {} but don't know "
-                        "to find it.".format(id))
-
-    def _kpi_calculator_bundle_by_id(self, id):
-        for kpic in self.kpi_calculator_bundles:
-            if kpic.id == id:
-                return kpic
-
-        raise Exception(
-            "Requested kpi calculator {} but don't know "
-            "to find it.".format(id))
-
-    def _mco_bundle_by_id(self, id):
-        for mco in self.mco_bundles:
-            if mco.id == id:
-                return mco
-
-        raise Exception("Requested MCO {} but it's not available"
-                        "to compute it.".format(id))
+    def _bundle_registry_default(self):
+        return self.application.get_plugin(BUNDLE_REGISTRY_PLUGIN_ID)
diff --git a/force_bdss/bdss_application.py b/force_bdss/bdss_application.py
index a0ac114..c87b81b 100644
--- a/force_bdss/bdss_application.py
+++ b/force_bdss/bdss_application.py
@@ -5,6 +5,7 @@ from stevedore.exception import NoMatches
 from envisage.api import Application
 from envisage.core_plugin import CorePlugin
 
+from force_bdss.bundle_registry import BundleRegistryPlugin
 from force_bdss.core_evaluation_driver import CoreEvaluationDriver
 from force_bdss.core_mco_driver import CoreMCODriver
 
@@ -33,7 +34,7 @@ class BDSSApplication(Application):
         self.evaluate = evaluate
         self.workflow_filepath = workflow_filepath
 
-        plugins = [CorePlugin()]
+        plugins = [CorePlugin(), BundleRegistryPlugin()]
 
         if self.evaluate:
             plugins.append(CoreEvaluationDriver())
diff --git a/force_bdss/bundle_registry.py b/force_bdss/bundle_registry.py
new file mode 100644
index 0000000..43ff067
--- /dev/null
+++ b/force_bdss/bundle_registry.py
@@ -0,0 +1,67 @@
+from envisage.extension_point import ExtensionPoint
+from envisage.plugin import Plugin
+from traits.api import List
+
+from force_bdss.data_sources.i_data_source_bundle import (
+    IDataSourceBundle)
+from force_bdss.kpi.i_kpi_calculator_bundle import IKPICalculatorBundle
+from force_bdss.mco.i_multi_criteria_optimizer_bundle import (
+    IMultiCriteriaOptimizerBundle)
+
+
+BUNDLE_REGISTRY_PLUGIN_ID = "force.bdss.plugins.bundle_registry"
+
+
+class BundleRegistryPlugin(Plugin):
+    """Main plugin that handles the execution of the MCO
+    or the evaluation.
+    """
+    id = BUNDLE_REGISTRY_PLUGIN_ID
+
+    # Note: we are forced to declare these extensions points here instead
+    # of the application object, and this is why we have to use this plugin.
+    # It is a workaround to an envisage bug that does not find the extension
+    # points if declared on the application.
+
+    #: A List of the available Multi Criteria Optimizers.
+    #: This will be populated by MCO plugins.
+    mco_bundles = ExtensionPoint(
+        List(IMultiCriteriaOptimizerBundle),
+        id='force.bdss.mco.bundles')
+
+    #: A list of the available Data Sources.
+    #: It will be populated by plugins.
+    data_source_bundles = ExtensionPoint(
+        List(IDataSourceBundle),
+        id='force.bdss.data_sources.bundles')
+
+    #: A list of the available Key Performance Indicator calculators.
+    #: It will be populated by plugins.
+    kpi_calculator_bundles = ExtensionPoint(
+        List(IKPICalculatorBundle),
+        id='force.bdss.kpi_calculators.bundles')
+
+    def data_source_bundle_by_id(self, id):
+        for ds in self.data_source_bundles:
+            if ds.id == id:
+                return ds
+
+        raise Exception("Requested data source {} but don't know "
+                        "to find it.".format(id))
+
+    def kpi_calculator_bundle_by_id(self, id):
+        for kpic in self.kpi_calculator_bundles:
+            if kpic.id == id:
+                return kpic
+
+        raise Exception(
+            "Requested kpi calculator {} but don't know "
+            "to find it.".format(id))
+
+    def mco_bundle_by_id(self, id):
+        for mco in self.mco_bundles:
+            if mco.id == id:
+                return mco
+
+        raise Exception("Requested MCO {} but it's not available"
+                        "to compute it.".format(id))
diff --git a/force_bdss/core_evaluation_driver.py b/force_bdss/core_evaluation_driver.py
index bf6c848..19e5666 100644
--- a/force_bdss/core_evaluation_driver.py
+++ b/force_bdss/core_evaluation_driver.py
@@ -13,7 +13,7 @@ class CoreEvaluationDriver(BaseCoreDriver):
         workflow = self.application.workflow
 
         mco_data = workflow.multi_criteria_optimizer
-        mco_bundle = self._mco_bundle_by_id(mco_data.id)
+        mco_bundle = self.bundle_registry.mco_bundle_by_id(mco_data.id)
         mco_model = mco_bundle.create_model(mco_data.model_data)
         mco_communicator = mco_bundle.create_communicator(
             self.application,
@@ -23,7 +23,7 @@ class CoreEvaluationDriver(BaseCoreDriver):
 
         ds_results = []
         for requested_ds in workflow.data_sources:
-            ds_bundle = self._data_source_bundle_by_id(
+            ds_bundle = self.bundle_registry.data_source_bundle_by_id(
                 requested_ds.id)
             ds_model = ds_bundle.create_model(requested_ds.model_data)
             data_source = ds_bundle.create_data_source(
@@ -32,7 +32,7 @@ class CoreEvaluationDriver(BaseCoreDriver):
 
         kpi_results = []
         for requested_kpic in workflow.kpi_calculators:
-            kpic_bundle = self._kpi_calculator_bundle_by_id(
+            kpic_bundle = self.bundle_registry.kpi_calculator_bundle_by_id(
                 requested_kpic.id)
             ds_model = kpic_bundle.create_model(
                 requested_kpic.model_data)
diff --git a/force_bdss/core_mco_driver.py b/force_bdss/core_mco_driver.py
index f1cb9b4..6a1321e 100644
--- a/force_bdss/core_mco_driver.py
+++ b/force_bdss/core_mco_driver.py
@@ -13,7 +13,7 @@ class CoreMCODriver(BaseCoreDriver):
         workflow = self.application.workflow
 
         mco_data = workflow.multi_criteria_optimizer
-        mco_bundle = self._mco_bundle_by_id(mco_data.id)
+        mco_bundle = self.bundle_registry.mco_bundle_by_id(mco_data.id)
         mco_model = mco_bundle.create_model(mco_data.model_data)
         mco = mco_bundle.create_optimizer(self.application, mco_model)
 
-- 
GitLab