graphical information added to boxes and testbed descriptions
[nepi.git] / src / nepi / core / description.py
index 536ee49..baae03f 100644 (file)
@@ -3,6 +3,9 @@
 
 from nepi.core.attributes import AttributesMap, Attribute
 from nepi.util import validation
+from nepi.util.guid import GuidGenerator
+from nepi.util.graphical_info import GraphicalInfo
+from nepi.util.parser._xml import XmlExperimentParser
 import sys
 
 AF_INET = 0
@@ -91,7 +94,10 @@ class Connector(object):
 
     def is_complete(self):
         """Return True if the connector has the minimum number of connections"""
-        return len(self.connections) >= self.connector_type.min 
+        return len(self.connections) >= self.connector_type.min
+
+    def is_connected(self, connector):
+        return connector._key in self._connections
 
     def connect(self, connector):
         if self.is_full() or connector.is_full():
@@ -110,7 +116,7 @@ class Connector(object):
 
     def can_connect(self, connector):
         connector_type_id = connector.connector_type.connector_type_id
-        self.connector_type.can_connect(connector_type_id) 
+        return self.connector_type.can_connect(connector_type_id) 
 
     def destroy(self):
         for connector in self._connections:
@@ -160,7 +166,7 @@ class Address(AttributesMap):
         self.add_attribute(name = "NetPrefix",
                 help = "Network prefix for the address", 
                 type = Attribute.INTEGER, 
-                prefix_range = prefix_range,
+                range = prefix_range,
                 validation_function = validation.is_integer)
         if family == AF_INET:
             self.add_attribute(name = "Broadcast",
@@ -213,9 +219,11 @@ class Box(AttributesMap):
         # factory attributes for box construction
         self._factory_attributes = list()
 
+        self.graphical_info = GraphicalInfo(str(self._guid))
+
         for connector_type in factory.connector_types:
             connector = Connector(self, connector_type)
-            self._connectors[connector_type.connector_id] = connector
+            self._connectors[connector_type.name] = connector
         for trace in factory.traces:
             tr = Trace(trace.name, trace.help, trace.enabled)
             self._traces[trace.name] = tr
@@ -223,7 +231,7 @@ class Box(AttributesMap):
             self.add_attribute(attr.name, attr.help, attr.type, attr.value, 
                     attr.range, attr.allowed, attr.readonly, 
                     attr.validation_function)
-        for attr in factory._attributes:
+        for attr in factory.attributes:
             self._factory_attributes.append(attr)
 
     @property
@@ -277,7 +285,7 @@ class AddressableBox(Box):
         super(AddressableBox, self).__init__(guid, factory, container)
         self._family = family
         # maximum number of addresses this box can have
-        self._max_addresses = max_addressess
+        self._max_addresses = max_addresses
         self._addresses = list()
 
     @property
@@ -408,11 +416,25 @@ class RoutingTableBoxFactory(BoxFactory):
     def create(self, guid, testbed_description):
         return RoutingTableBox(guid, self)
 
-class FactoriesProvider(object):
-    def __init__(self):
-        super(FactoriesProvider, self).__init__()
+class TestbedFactoriesProvider(object):
+    def __init__(self, testbed_id, testbed_version):
+        super(TestbedFactoriesProvider, self).__init__()
+        self._testbed_id = testbed_id
+        self._testbed_version = testbed_version
         self._factories = dict()
 
+    @property
+    def testbed_id(self):
+        return self._testbed_id
+
+    @property
+    def testbed_version(self):
+        return self._testbed_version
+
+    @property
+    def factories(self):
+        return self._factories.values()
+
     def factory(self, factory_id):
         return self._factories[factory_id]
 
@@ -422,44 +444,36 @@ class FactoriesProvider(object):
     def remove_factory(self, factory_id):
         del self._factories[factory_id]
 
-    def list_factories(self):
-        return self._factories.keys()
-
 class TestbedDescription(AttributesMap):
-    def __init__(self, guid_generator, testbed_id, testbed_version, provider):
+    def __init__(self, guid_generator, provider):
         super(TestbedDescription, self).__init__()
         self._guid_generator = guid_generator
         self._guid = guid_generator.next()
-        self._testbed_id = testbed_id
-        self._testbed_version = testbed_version
         self._provider = provider
         self._boxes = dict()
+        self.graphical_info = GraphicalInfo(str(self._guid))
 
     @property
     def guid(self):
         return self._guid
 
-    @property
-    def testbed_id(self):
-        return self._testbed_id
-
-    @property
-    def testbed_version(self):
-        return self._testbed_version
-
     @property
     def provider(self):
-        return provider
+        return self._provider
 
     @property
     def boxes(self):
         return self._boxes.values()
 
+    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()
-        factory = self._provider.factories(factory_id)
+        guid = self._guid_generator.next()
+        factory = self._provider.factory(factory_id)
         box = factory.create(guid, self)
         self._boxes[guid] = box
+        return box
 
     def delete(self, guid):
         box = self._boxes[guid]
@@ -472,3 +486,41 @@ class TestbedDescription(AttributesMap):
             box.destroy()
         self._boxes = None
 
+class ExperimentDescription(object):
+    def __init__(self, guid = 0):
+        self._guid_generator = GuidGenerator(guid)
+        self._testbed_descriptions = dict()
+
+    @property
+    def testbed_descriptions(self):
+        return self._testbed_descriptions.values()
+
+    def to_xml(self):
+        parser = XmlExperimentParser()
+        return parser.to_xml(self)
+
+    def from_xml(self, xml):
+        parser = XmlExperimentParser()
+        parser.from_xml(self, xml)
+
+    def testbed_description(self, guid):
+        return self._testbed_descriptions[guid] \
+                if guid in self._testbed_descriptions else None
+
+    def box(self, 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):
+        testbed_description = TestbedDescription(self._guid_generator, 
+                provider)
+        guid = testbed_description.guid
+        self._testbed_descriptions[guid] = testbed_description
+        return testbed_description
+
+    def remove_testbed_description(self, testbed_description):
+        guid = testbed_description.guid
+        del self._testbed_descriptions[guid]
+