bug fixing: addresses and routes
[nepi.git] / src / nepi / core / design.py
index f89c094..c4aa80d 100644 (file)
@@ -13,8 +13,6 @@ from nepi.util.guid import GuidGenerator
 from nepi.util.graphical_info import GraphicalInfo
 from nepi.util.parser._xml import XmlExperimentParser
 import sys
-    
-
 
 class ConnectorType(ConnectorTypeBase):
     def __init__(self, testbed_id, factory_id, name, help, max = -1, min = 0):
@@ -53,6 +51,9 @@ class Connector(object):
         self._connector_type = connector_type
         self._connections = list()
 
+    def __str__(self):
+        return "Connector(%s, %s)" % (self.box, self.connector_type)
+
     @property
     def box(self):
         return self._box
@@ -80,7 +81,7 @@ class Connector(object):
 
     def connect(self, connector):
         if not self.can_connect(connector) or not connector.can_connect(self):
-            raise RuntimeError("Could not connect.")
+            raise RuntimeError("Could not connect. %s to %s" % (self, connector))
         self._connections.append(connector)
         connector._connections.append(self)
 
@@ -112,7 +113,7 @@ class Trace(AttributesMap):
         super(Trace, self).__init__()
         self._trace_id = trace_id
         self._help = help       
-        self.enabled = enabled
+        self._enabled = enabled
     
     @property
     def trace_id(self):
@@ -122,6 +123,16 @@ class Trace(AttributesMap):
     def help(self):
         return self._help
 
+    @property
+    def enabled(self):
+        return self._enabled
+
+    def enable(self):
+        self._enabled = True
+
+    def disable(self):
+        self._enabled = False
+
 class Address(AttributesMap):
     def __init__(self):
         super(Address, self).__init__()
@@ -181,12 +192,14 @@ class Box(AttributesMap):
         self._container = container
         # traces -- list of available traces for the box
         self._traces = dict()
+        # tags -- list of tags for the box
+        self._tags = list()
         # connectors -- list of available connectors for the box
         self._connectors = dict()
         # factory_attributes -- factory attributes for box construction
         self._factory_attributes = dict()
         # graphical_info -- GUI position information
-        self.graphical_info = GraphicalInfo(str(self._guid))
+        self.graphical_info = GraphicalInfo()
 
         for connector_type in factory.connector_types:
             connector = Connector(self, connector_type)
@@ -194,14 +207,19 @@ class Box(AttributesMap):
         for trace in factory.traces:
             tr = Trace(trace.trace_id, trace.help, trace.enabled)
             self._traces[trace.trace_id] = tr
+        for tag_id in factory.tags:
+            self._tags.append(tag_id)
         for attr in factory.box_attributes.attributes:
             self.add_attribute(attr.name, attr.help, attr.type, attr.value, 
                     attr.range, attr.allowed, attr.flags, 
-                    attr.validation_function)
+                    attr.validation_function, attr.category)
         for attr in factory.attributes:
             if attr.modified:
                 self._factory_attributes[attr.name] = attr.value
 
+    def __str__(self):
+        return "Box(%s, %s, %s)" % (self.guid, self.factory_id, self.testbed_guid)
+
     @property
     def guid(self):
         return self._guid
@@ -227,7 +245,7 @@ class Box(AttributesMap):
         return self._traces.values()
 
     @property
-    def traces_name(self):
+    def trace_names(self):
         return self._traces.keys()
 
     @property
@@ -235,21 +253,20 @@ class Box(AttributesMap):
         return self._factory_attributes
 
     @property
-    def addresses(self):
-        return []
-
-    @property
-    def routes(self):
-        return []
+    def tags(self):
+        return self._tags
 
     def trace_help(self, trace_id):
         return self._traces[trace_id].help
 
     def enable_trace(self, trace_id):
-        self._traces[trace_id].enabled = True
+        self._traces[trace_id].enable()
 
     def disable_trace(self, trace_id):
-        self._traces[trace_id].enabled = False
+        self._traces[trace_id].disable()
+
+    def is_trace_enabled(self, trace_id):
+        return self._traces[trace_id].enabled
 
     def connector(self, name):
         return self._connectors[name]
@@ -320,7 +337,7 @@ class UserRoutableMixin(RoutableMixin):
         return route
 
     def delete_route(self, route):
-        self._route.remove(route)
+        self._routes.remove(route)
         del route
 
     def destroy(self):
@@ -368,6 +385,7 @@ class Factory(AttributesMap):
         self._category = category
         self._connector_types = list()
         self._traces = list()
+        self._tags = list()
         self._box_attributes = AttributesMap()
         
         if not self._has_addresses and not self._has_routes:
@@ -435,6 +453,10 @@ class Factory(AttributesMap):
     def traces(self):
         return self._traces
 
+    @property
+    def tags(self):
+        return self._tags
+    
     @property
     def box_attributes(self):
         return self._box_attributes
@@ -446,10 +468,14 @@ class Factory(AttributesMap):
         trace = Trace(trace_id, help, enabled)
         self._traces.append(trace)
 
+    def add_tag(self, tag_id):
+        self._tags.append(tag_id)
+
     def add_box_attribute(self, name, help, type, value = None, range = None,
-        allowed = None, flags = Attribute.NoFlags, validation_function = None):
+        allowed = None, flags = Attribute.NoFlags, validation_function = None,
+        category = None):
         self._box_attributes.add_attribute(name, help, type, value, range,
-                allowed, flags, validation_function)
+                allowed, flags, validation_function, category)
 
     def create(self, guid, testbed_description):
         return self._factory(guid, self, testbed_description.guid)
@@ -491,19 +517,19 @@ class FactoriesProvider(object):
         del self._factories[factory_id]
 
 class TestbedDescription(AttributesMap):
-    def __init__(self, guid_generator, provider):
+    def __init__(self, guid_generator, provider, guid = None):
         super(TestbedDescription, self).__init__()
         self._guid_generator = guid_generator
-        self._guid = guid_generator.next()
+        self._guid = guid_generator.next(guid)
         self._provider = provider
         self._boxes = dict()
-        self.graphical_info = GraphicalInfo(str(self._guid))
+        self.graphical_info = GraphicalInfo()
 
         metadata = Metadata(provider.testbed_id, provider.testbed_version)
         for attr in metadata.testbed_attributes().attributes:
             self.add_attribute(attr.name, attr.help, attr.type, attr.value, 
                     attr.range, attr.allowed, attr.flags, 
-                    attr.validation_function)
+                    attr.validation_function, attr.category)
 
     @property
     def guid(self):
@@ -520,8 +546,8 @@ class TestbedDescription(AttributesMap):
     def box(self, guid):
         return self._boxes[guid] if guid in self._boxes else None
 
-    def create(self, factory_id):
-        guid = self._guid_generator.next()
+    def create(self, factory_id, guid = None):
+        guid = self._guid_generator.next(guid)
         factory = self._provider.factory(factory_id)
         box = factory.create(guid, self)
         self._boxes[guid] = box
@@ -538,8 +564,8 @@ class TestbedDescription(AttributesMap):
         self._boxes = None
 
 class ExperimentDescription(object):
-    def __init__(self, guid = 0):
-        self._guid_generator = GuidGenerator(guid)
+    def __init__(self):
+        self._guid_generator = GuidGenerator()
         self._testbed_descriptions = dict()
 
     @property
@@ -564,30 +590,28 @@ class ExperimentDescription(object):
             if box: return box
         return None
 
-    def add_testbed_description(self, provider):
+    def get_element(self, guid):
+        if guid in self._testbed_descriptions:
+            return self._testbed_descriptions[guid]
+        for testbed_description in self._testbed_descriptions.values():
+            box = testbed_description.box(guid)
+            if box: return box
+        return None
+
+    def add_testbed_description(self, provider, guid = None):
         testbed_description = TestbedDescription(self._guid_generator, 
-                provider)
+                provider, guid)
         guid = testbed_description.guid
         self._testbed_descriptions[guid] = testbed_description
         return testbed_description
 
-    def remove_testbed_description(self, testbed_description):
-        guid = testbed_description.guid
+    def remove_testbed_description(self, guid):
+        testbed_description = self._testbed_descriptions[guid]
         del self._testbed_descriptions[guid]
+        testbed_description.destroy()
 
     def destroy(self):
         for testbed_description in self.testbed_descriptions:
             testbed_description.destroy()
 
-# TODO: When the experiment xml is passed to the controller to execute it
-# NetReferences in the xml need to be solved
-#
-#targets = re.findall(r"%target:(.*?)%", command)
-#for target in targets:
-#   try:
-#      (family, address, port) = resolve_netref(target, AF_INET, 
-#          self.server.experiment )
-#      command = command.replace("%%target:%s%%" % target, address.address)
-#   except:
-#       continue