2 # -*- coding: utf-8 -*-
3 from nepi.core.attributes import AttributesMap
5 class ConnectorType(object):
6 """A ConnectorType defines a kind of connector that can be used in an Object.
8 def __init__(self, connector_type_id, help, name, max = -1, min = 0):
9 super(ConnectorType, self).__init__()
11 ConnectorType(name, help, display_name, max, min):
12 - connector_type_id: (unique) identifier for this type.
13 Typically: testbed_id + factory_id + name
14 - name: descriptive name for the user
16 - max: amount of connections that this type support, -1 for no limit
17 - min: minimum amount of connections to this type of connector
23 'The maximum number of connections allowed need to be more than 0')
26 'The minimum number of connections allowed needs to be at least 0')
27 self._connector_type_id = connector_type_id
32 self._allowed_connections = list()
35 def connector_type_id(self):
36 return self._connector_type_id
54 def add_allowed_connection(self, connector_type_id):
55 self._allowed_connections.append(connector_type_id)
57 def can_connect(self, connector_type_id):
58 return connector_type_id in self._allowed_connections
60 class Connector(object):
61 """A Connector sepcifies the connection points in an Object"""
62 def __init__(self, element, connector_type):
63 super(Connector, self).__init__()
64 self._element = element
65 self._connector_type = connector_type
66 self._connections = dict()
73 def connector_type(self):
74 return self._connector_type
77 def connections(self):
78 return self._connections.values()
81 """Return True if the connector has the maximum number of connections"""
82 return len(self.connections) == self.connector_type.max
84 def is_complete(self):
85 """Return True if the connector has the minimum number of connections"""
86 return len(self.connections) >= self.connector_type.min
88 def connect(self, connector):
89 if self.is_full() or connector.is_full():
90 raise RuntimeError("Connector is full")
91 if not self.can_connect(connector) or not connector.can_connect(self):
92 raise RuntimeError("Could not connect.")
93 self._connections[connector._key] = connector
94 connector._connections[self._key] = self
96 def disconnect(self, connector):
97 if connector._key not in self._connections or
98 self._key not in connector._connections:
99 raise RuntimeError("Could not disconnect.")
100 del self._connections[connector._key]
101 del connector._connections[self._key]
103 def can_connect(self, connector):
104 connector_type_id = connector.connector_type.connector_type_id
105 self.connector_type.can_connect(connector_type_id)
108 for connector in self._connections:
109 self.disconnect(connector)
110 self._element = self._connectors = None
114 return "%d_%s" % (self.element.guid,
115 self.connector_type.connector_type_id)
117 class Trace(AttributesMap):
118 def __init__(self, name, help, enabled=False):
119 super(Trace, self).__init__()
122 self._enabled = enabled
133 def is_enabled(self):
140 self._enabled = False
142 class Element(AttributesMap):
143 def __init__(self, guid, testbed_id, factory, container = None):
144 super(Element, self).__init__()
147 # factory identifier or name
148 self._factory_id = factory.factory_id
149 # elements can be nested inside other 'container' elements
150 self._container = container
151 # traces for the element
152 self._traces = dict()
153 # connectors for the element
154 self._connectors = dict()
155 for connector_type in factory.connector_types:
156 connector = Connector(self, connector_type)
157 self._connectors[connector_type.connector_id] = connector
164 def factory_id(self):
165 return self._factory_id
169 return self._container
172 def connectors(self):
173 return self._connectors.values()
177 return self._traces.values()
179 def connector(self, name):
180 return self._connectors[name]
182 def trace(self, name):
183 return self._traces[name]
186 super(Element, self).destroy()
187 for c in self.connectors:
189 for t in self.traces:
191 self._connectors = self._traces = None
193 class Factory(AttributesMap):
194 def __init__(self, factory_id, help = None, category = None):
195 super(Factory, self).__init__()
196 self._factory_id = factory_id
198 self._category = category
199 self._connector_types = set()
202 def factory_id(self):
203 return self._factory_id
211 return self._category
214 def connector_types(self):
215 return self._connector_types
217 def add_connector_type(self, connector_id, help, name, max = -1, min = 0):
218 connector_type = ConnectorType(connector_id, help, name, max, min)
219 self._connector_types.add(connector_type)
221 def create(self, guid, testbed_design, container = None):
222 raise NotImplementedError
225 super(Factory, self).destroy()
226 self._connector_types = None
228 #TODO: Provide some way to identify that the providers and the factories
229 # belong to a specific testbed version
230 class Provider(object):
232 super(Provider, self).__init__()
233 self._factories = dict()
235 def factory(self, factory_id):
236 return self._factories[factory_id]
238 def add_factory(self, factory):
239 self._factories[factory.factory_id] = factory
241 def remove_factory(self, factory_id):
242 del self._factories[factory_id]
244 def list_factories(self):
245 return self._factories.keys()
247 class TestbedDescription(AttributeMap):
248 def __init__(self, guid_generator, testbed_id, testbed_version, provider):
249 super(TestbedDescription, self).__init__()
250 self._guid_generator = guid_generator
251 self._guid = guid_generator.next()
252 self._testbed_id = testbed_id
253 self._testbed_version = testbed_version
254 self._provider = provider
255 self._elements = dict()
262 def testbed_id(self):
263 return self._testbed_id
266 def testbed_version(self):
267 return self._testbed_version
275 return self._elements.values()
277 def create(self, factory_id):
278 guid = self.guid_generator.next()
279 factory = self._provider.factories(factory_id)
280 element = factory.create(guid, self)
281 self._elements[guid] = element
283 def delete(self, guid):
284 element = self._elements[guid]
285 del self._elements[guid]
289 for guid, element in self._elements.iteitems():
290 del self._elements[guid]
292 self._elements = None