Package spade :: Module DF
[hide private]
[frames] | no frames]

Source Code for Module spade.DF

   1   
   2  # encoding: utf-8 
   3   
   4  from Agent import PlatformAgent 
   5  import AID 
   6  import Behaviour 
   7  import BasicFipaDateTime 
   8  from SL0Parser import * 
   9  from content import ContentObject 
  10  import xmpp 
  11  import copy 
  12  import thread 
  13   
14 -class DF(PlatformAgent):
15 """ 16 Directory Facilitator Agent 17 """ 18
19 - class DefaultBehaviour(Behaviour.Behaviour):
20
21 - def __init__(self):
22 Behaviour.Behaviour.__init__(self) 23 self.sl0parser = SL0Parser()
24
25 - def _process(self):
26 error = False 27 msg = self._receive(True) 28 if msg != None: 29 if msg.getPerformative().lower() == 'request': 30 if msg.getOntology().lower() == "fipa-agent-management": 31 if msg.getLanguage().lower() == "fipa-sl0": 32 content = self.sl0parser.parse(msg.getContent()) 33 ACLtemplate = Behaviour.ACLTemplate() 34 ACLtemplate.setConversationId(msg.getConversationId()) 35 #ACLtemplate.setSender(msg.getSender()) 36 template = (Behaviour.MessageTemplate(ACLtemplate)) 37 38 if "action" in content: 39 if "register" in content.action or "deregister" in content.action: 40 self.myAgent.addBehaviour(DF.RegisterBehaviour(msg,content), template) 41 self.myAgent.DEBUG("Received REGISTER action: "+str(content)) 42 elif "search" in content.action: 43 self.myAgent.addBehaviour(DF.SearchBehaviour(msg,content), template) 44 self.myAgent.DEBUG("Received SEARCH action: "+str(content)) 45 elif "modify" in content.action: 46 self.myAgent.addBehaviour(DF.ModifyBehaviour(msg,content), template) 47 self.myAgent.DEBUG("Received MODIFY action: "+str(content)) 48 else: 49 reply = msg.createReply() 50 reply.setSender(self.myAgent.getAID()) 51 reply.setPerformative("refuse") 52 reply.setContent("( "+msg.getContent() +"(unsuported-function "+ content.keys()[0] +"))") 53 self.myAgent.send(reply) 54 self.myAgent.DEBUG("Received message with no action. Refusing: "+str(content),'warn') 55 56 return -1 57 58 59 elif "rdf" in msg.getLanguage().lower(): 60 co = msg.getContentObject() 61 ACLtemplate = Behaviour.ACLTemplate() 62 ACLtemplate.setConversationId(msg.getConversationId()) 63 #ACLtemplate.setSender(msg.getSender()) 64 template = (Behaviour.MessageTemplate(ACLtemplate)) 65 66 if co and co.has_key("fipa:action") and co["fipa:action"].has_key("fipa:act"): 67 if co["fipa:action"]["fipa:act"] in ["register","deregister"]: 68 self.myAgent.addBehaviour(DF.RegisterBehaviour(msg,co), template) 69 self.myAgent.DEBUG("Received REGISTER action: "+str(co)) 70 elif co["fipa:action"]["fipa:act"] == "search": 71 self.myAgent.addBehaviour(DF.SearchBehaviour(msg,co), template) 72 self.myAgent.DEBUG("Received SEARCH action: "+str(co)) 73 elif co["fipa:action"]["fipa:act"] == "modify": 74 self.myAgent.addBehaviour(DF.ModifyBehaviour(msg,co), template) 75 self.myAgent.DEBUG("Received MODIFY action: "+str(co)) 76 else: 77 reply = msg.createReply() 78 reply.setSender(self.myAgent.getAID()) 79 reply.setPerformative("refuse") 80 co2 = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 81 co2["unsuported-function"] = co["fipa:action"]["fipa:act"] 82 reply.setContentObject(co2) 83 self.myAgent.send(reply) 84 self.myAgent.DEBUG("Received message with no action. Refusing: "+str(co),'warn') 85 return -1 86 87 88 else: error = "(unsupported-language "+msg.getLanguage()+")" 89 else: error = "(unsupported-ontology "+msg.getOntology()+")" 90 91 92 elif msg.getPerformative().lower() not in ['failure','refuse']: 93 error = "(unsupported-act " + msg.getPerformative() + ")" 94 if error: 95 reply = msg.createReply() 96 reply.setSender(self.myAgent.getAID()) 97 reply.setPerformative("not-understood") 98 reply.setContent("( "+msg.getContent() + error+")") 99 self.myAgent.send(reply) 100 self.myAgent.DEBUG("NOT-UNDERSTOOD: Could not process message. Error is:"+str(error),'error') 101 return -1
102 103 #TODO: delete old services 104 105
106 - class RegisterBehaviour(Behaviour.OneShotBehaviour):
107
108 - def __init__(self,msg,content):
109 Behaviour.OneShotBehaviour.__init__(self) 110 self.msg = msg 111 self.content = content
112
113 - def _process(self):
114 #The DF agrees and then informs dummy of the successful execution of the action 115 error = False 116 117 # Check if the content language is RDF/XML 118 if "rdf" not in self.msg.getLanguage(): 119 rdf = False 120 try: 121 if self.content.action == "register": 122 dad = DfAgentDescription(self.content.action.register['df-agent-description']) 123 else: 124 dad = DfAgentDescription(self.content.action.deregister['df-agent-description']) 125 except KeyError: #Exception,err: 126 error = "(missing-argument df-agent-description)" 127 self.myAgent.DEBUG("REFUSE: Register Behaviour could not extract DfAgentDescription "+error,'error') 128 129 130 if error: 131 reply = self.msg.createReply() 132 reply.setSender(self.myAgent.getAID()) 133 reply.setPerformative("refuse") 134 reply.setContent("( "+self.msg.getContent() + error + ")") 135 self.myAgent.send(reply) 136 137 return -1 138 139 else: 140 reply = self.msg.createReply() 141 reply.setSender(self.myAgent.getAID()) 142 reply.setPerformative("agree") 143 reply.setContent("(" + str(self.msg.getContent()) + " true)") 144 self.myAgent.send(reply) 145 146 147 if self.content.action == "register": 148 149 if not self.myAgent.servicedb.has_key(dad.getAID().getName()): 150 self.myAgent.db_mutex.acquire() 151 self.myAgent.servicedb[dad.getAID().getName()] = dad 152 self.myAgent.db_mutex.release() 153 else: 154 #check if already-registered 155 for ss in dad.getServices(): 156 found = False 157 for s in self.myAgent.servicedb[dad.getAID().getName()].getServices(): 158 if s.match(ss): 159 found=True 160 if found: 161 reply.setPerformative("failure") 162 reply.setContent("("+self.msg.getContent() + "(already-registered))") 163 self.myAgent.send(reply) 164 self.myAgent.DEBUG("FAILURE: Service was already registered! Could not register "+str(dad),'warn') 165 return -1 166 167 168 try: 169 for s in dad.getServices(): 170 self.myAgent.db_mutex.acquire() 171 self.myAgent.servicedb[dad.getAID().getName()].addService(s) 172 self.myAgent.db_mutex.release() 173 self.myAgent.DEBUG("Service successfully registered: "+str(s),'ok') 174 except Exception, err: 175 reply.setPerformative("failure") 176 reply.setContent("("+self.msg.getContent() + "(internal-error))") 177 self.myAgent.send(reply) 178 self.myAgent.DEBUG("FAILURE: Service could not be registered: "+str(err),'error') 179 return -1 180 181 182 self.DEBUG("Service succesfully deregistered: "+ str(dad),'ok') 183 reply.setPerformative("inform") 184 reply.setContent("(done "+self.msg.getContent() + ")") 185 self.myAgent.send(reply) 186 187 #publish event 188 s = Service(dad=dad).asContentObject() 189 node = xmpp.Node(node=str(s)) 190 self.myAgent.publishEvent("DF:Service:Register",node) 191 192 return 1 193 194 195 elif self.content.action == "deregister": 196 197 if not self.myAgent.servicedb.has_key(dad.getAID().getName()): 198 reply.setPerformative("failure") 199 reply.setContent("("+self.msg.getContent() + "(not-registered))") 200 self.myAgent.send(reply) 201 self.myAgent.DEBUG("FAILURE: Agent has no registered services! Could not deregister "+str(dad),'warn') 202 return -1 203 204 #check if service is not registered 205 for ss in dad.getServices(): 206 found=False 207 for s in self.myAgent.servicedb[dad.getAID().getName()].getServices(): 208 if s.match(ss): 209 found = True 210 if not found: 211 reply.setPerformative("failure") 212 reply.setContent("("+self.msg.getContent() + "(not-registered))") 213 self.myAgent.send(reply) 214 self.myAgent.DEBUG("FAILURE: Service is not registered! Could not deregister "+str(dad),'warn') 215 return -1 216 217 try: 218 services = copy.copy(self.myAgent.servicedb[dad.getAID().getName()]) 219 if dad.getServices() == []: 220 self.myAgent.db_mutex.acquire() 221 del self.myAgent.servicedb[dad.getAID().getName()] 222 self.myAgent.db_mutex.release() 223 else: 224 for ss in dad.getServices(): 225 for s in services.getServices(): 226 if ss.match(s): 227 self.myAgent.db_mutex.acquire() 228 self.myAgent.servicedb[dad.getAID().getName()].delService(s) 229 self.myAgent.db_mutex.release() 230 except Exception, err: 231 reply.setPerformative("failure") 232 reply.setContent("("+self.msg.getContent() + '(internal-error "could not deregister service"))') 233 self.myAgent.send(reply) 234 self.myAgent.DEBUG("FAILURE: Service could not be deregistered: "+str(err),'error') 235 return -1 236 237 self.DEBUG("Service succesfully deregistered: "+ str(dad),'ok') 238 reply.setPerformative("inform") 239 reply.setContent("(done "+self.msg.getContent() + ")") 240 self.myAgent.send(reply) 241 242 #publish event 243 s = Service(dad=dad).asContentObject() 244 node = xmpp.Node(node=str(s)) 245 self.myAgent.publishEvent("DF:Service:UnRegister",node) 246 247 return 1 248 249 250 elif "rdf" in self.msg.getLanguage(): 251 # Content in RDF/XML (ContentObject capable) 252 rdf = True 253 co_error = None 254 try: 255 co = self.msg.getContentObject() 256 self.myAgent.DEBUG("Content processed "+str(co),'info') 257 dad = DfAgentDescription(co = co.action.argument) 258 self.myAgent.DEBUG("DfAgentDescription extracted "+str(dad.asRDFXML()),'info') 259 except KeyboardInterrupt,err: 260 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 261 co_error["fipa:error"] = "missing-argument df-agent-description" 262 self.myAgent.DEBUG("REFUSE: "+str(co_error) + ": "+str(err),'error') 263 264 if co_error: 265 reply = self.msg.createReply() 266 reply.setSender(self.myAgent.getAID()) 267 reply.setPerformative("refuse") 268 reply.setContentObject(co_error) 269 self.myAgent.send(reply) 270 return -1 271 272 else: 273 reply = self.msg.createReply() 274 reply.setSender(self.myAgent.getAID()) 275 reply.setPerformative("agree") 276 co["fipa:done"] = "true" 277 reply.setContentObject(co) 278 self.myAgent.send(reply) 279 280 if co["fipa:action"]["fipa:act"] == "register": 281 if not self.myAgent.servicedb.has_key(dad.getAID().getName()): 282 self.myAgent.db_mutex.acquire() 283 self.myAgent.servicedb[dad.getAID().getName()] = dad 284 self.myAgent.db_mutex.release() 285 else: 286 #check if already-registered 287 for ss in dad.getServices(): 288 found = False 289 for s in self.myAgent.servicedb[dad.getAID().getName()].getServices(): 290 if s.match(ss): 291 found=True 292 break 293 if found: 294 reply.setPerformative("failure") 295 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 296 co_error["fipa:error"] = "already-registered" 297 reply.setContentObject(co_error) 298 self.myAgent.send(reply) 299 self.myAgent.DEBUG("FAILURE: Service already registered! ",'warn') 300 return -1 301 302 303 try: 304 for s in dad.getServices(): 305 self.myAgent.db_mutex.acquire() 306 self.myAgent.servicedb[dad.getAID().getName()].addService(s) 307 self.myAgent.db_mutex.release() 308 self.myAgent.DEBUG("Service successfully registered: "+str(s),'ok') 309 except Exception, err: 310 reply.setPerformative("failure") 311 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 312 co_error["fipa:error"] = "internal-error" 313 reply.setContentObject(co_error) 314 self.myAgent.send(reply) 315 self.myAgent.DEBUG("FAILURE: Service could not be registered: "+str(err),'error') 316 return -1 317 318 319 self.DEBUG("Service succesfully registered: "+ str(dad),'ok') 320 reply.setPerformative("inform") 321 co_rep = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 322 co_rep["fipa:done"] = "true" 323 reply.setContentObject(co_rep) 324 self.myAgent.send(reply) 325 326 #publish event 327 self.myAgent.DEBUG("Publishing Event: "+str(dad)) 328 s = Service(dad=dad).asContentObject() 329 node = xmpp.Node(node=str(s)) 330 self.myAgent.publishEvent("DF:Service:Register",node) 331 332 return 1 333 334 elif co["fipa:action"]["fipa:act"] == "deregister": 335 if not self.myAgent.servicedb.has_key(dad.getAID().getName()): 336 reply.setPerformative("failure") 337 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 338 co_error["fipa:error"] = 'not-registered' 339 reply.setContentObject(co_error) 340 self.myAgent.send(reply) 341 self.myAgent.DEBUG("FAILURE: Agent has no registered services",'warn') 342 return -1 343 344 #check if service is not registered 345 for ss in dad.getServices(): 346 found=False 347 for s in self.myAgent.servicedb[dad.getAID().getName()].getServices(): 348 if s.match(ss): 349 found = True 350 if not found: 351 reply.setPerformative("failure") 352 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 353 co_error["fipa:error"] = 'not-registered' 354 reply.setContentObject(co_error) 355 self.myAgent.send(reply) 356 self.myAgent.DEBUG("FAILURE: Service is not registered! Could not deregister "+str(dad),'warn') 357 return -1 358 359 try: 360 services = copy.copy(self.myAgent.servicedb[dad.getAID().getName()]) 361 self.myAgent.DEBUG("Deregistering "+str(services) + " AND " + str(dad.getServices())) 362 if dad.getServices() == []: 363 self.myAgent.db_mutex.acquire() 364 del self.myAgent.servicedb[dad.getAID().getName()] 365 self.DEBUG("Deleting all agent entries: " + str(not self.myAgent.servicedb.has_key(dad.getAID().getName()))) 366 self.myAgent.db_mutex.release() 367 else: 368 for ss in dad.getServices(): 369 for s in services.getServices(): 370 if ss.match(s): 371 self.myAgent.db_mutex.acquire() 372 self.myAgent.servicedb[dad.getAID().getName()].delService(s) 373 self.myAgent.db_mutex.release() 374 except Exception, err: 375 reply.setPerformative("failure") 376 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 377 co_error["fipa:error"] = 'internal-error "could not deregister service"' 378 reply.setContentObject(co_error) 379 self.myAgent.send(reply) 380 self.myAgent.DEBUG("FAILURE: internal-error 'could not deregister service': "+str(err),'error') 381 return -1 382 383 self.DEBUG("Service succesfully deregistered: "+ str(dad),'ok') 384 reply.setPerformative("inform") 385 co_rep = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 386 co_rep["fipa:done"] = "true" 387 reply.setContentObject(co_rep) 388 self.myAgent.send(reply) 389 390 #publish event 391 s = Service(dad=dad).asContentObject() 392 node = xmpp.Node(node=str(s)) 393 self.myAgent.publishEvent("DF:Service:UnRegister",node) 394 395 return 1
396 397 398
399 - class SearchBehaviour(Behaviour.OneShotBehaviour):
400
401 - def __init__(self,msg,content):
402 Behaviour.OneShotBehaviour.__init__(self) 403 self.msg = msg 404 self.content = content
405
406 - def _process(self):
407 408 error = False 409 410 reply = self.msg.createReply() 411 reply.setSender(self.myAgent.getAID()) 412 reply.setPerformative("agree") 413 if "rdf" in self.msg.getLanguage(): 414 rdf = True 415 reply.setContent("(" + str(self.msg.getContent()) + " true)") 416 else: 417 rdf = False 418 self.myAgent.send(reply) 419 420 if not rdf: 421 max = 50 422 if "search-constraints" in self.content.action.search: 423 if "max-results" in self.content.action.search["search-constraints"]: 424 try: 425 max_str = str(self.content.action.search["search-constraints"]["max-results"]).strip("[']") 426 max = int(max_str) 427 except Exception, err: 428 error = '(internal-error "max-results is not an integer")' 429 self.myAgent.DEBUG("FAILURE: internal-error 'max-results is not an integer' "+str(err),'error') 430 if error: 431 reply = self.msg.createReply() 432 reply.setSender(self.myAgent.getAID()) 433 reply.setPerformative("failure") 434 reply.setContent("( "+self.msg.getContent() + error+")") 435 self.myAgent.send(reply) 436 return -1 437 438 439 result = [] 440 441 if "df-agent-description" in self.content.action.search: 442 try: 443 dad = DfAgentDescription(self.content.action.search["df-agent-description"]) 444 except Exception, err: 445 self.myAgent.DEBUG("FAILURE: Could not extract DfAgentDescription from content: "+str(err),'error') 446 447 self.myAgent.db_mutex.acquire() 448 if max in [-1, 0]: 449 # No limit 450 for agentid,dads in self.myAgent.servicedb.items(): 451 if dads.match(dad): 452 d = copy.copy(dads) 453 if dad.services == []: 454 d.services = dads.getServices() 455 else: 456 d.services=[] 457 for ss in dad.getServices(): 458 for s in dads.getServices(): 459 if s.match(ss): 460 d.addService(s) 461 result.append(d) 462 else: 463 max = abs(max) 464 for agentid,dads in self.myAgent.servicedb.items(): 465 if max >= 0: 466 if dads.match(dad): 467 d = copy.copy(dads) 468 if dad.services == []: 469 d.services = dads.getServices() 470 else: 471 d.services=[] 472 for ss in dad.getServices(): 473 for s in dads.getServices(): 474 if s.match(ss): 475 d.addService(s) 476 result.append(d) 477 max -= 1 478 else: break 479 480 self.myAgent.db_mutex.release() 481 content = "((result " + self.msg.getContent().strip("\n")[1:-1] 482 if len(result)>0: 483 content += " (sequence " 484 for i in result: 485 content += str(i) + " " 486 content += ")" 487 else: 488 pass 489 content += "))" 490 self.myAgent.DEBUG("Found " +str(len(result)) + " services",'ok') 491 for d in result: 492 self.myAgent.DEBUG(str(d),'ok') 493 494 495 reply.setPerformative("inform") 496 reply.setContent(content) 497 self.myAgent.send(reply) 498 499 recvs = "" 500 for r in reply.getReceivers(): 501 recvs += str(r.getName()) 502 503 return 1 504 505 else: 506 # Content is in RDF/XML 507 max = 50 508 if self.content.action.argument.max_results: 509 try: 510 max_str = str(self.content.action.argument.max_results) 511 max = int(max_str) 512 except Exception, err: 513 # Ignoring the exception 514 self.myAgent.DEBUG("FAILURE: (internal-error) max-results is not an integer! ",'error') 515 #co_error = ContentObject() 516 #co_error["error"] = '(internal-error "max-results is not an integer")' 517 518 result = [] 519 520 if self.content.action.argument.df_agent_description: 521 try: 522 dad = DfAgentDescription(co = self.content.action.argument.df_agent_description) 523 self.myAgent.DEBUG("Searching for: " +str(dad) + " in ServiceDB: " + str(map(lambda s: str(s), self.myAgent.servicedb.values())) ) 524 except Exception, err: 525 self.myAgent.DEBUG("FAILURE: Could not extract DfAgentDescription from content: "+str(err),'error') 526 527 self.myAgent.db_mutex.acquire() 528 if max in [-1, 0]: 529 # No limit 530 for agentid,dads in self.myAgent.servicedb.items(): 531 self.myAgent.DEBUG("Comparing " + str(dad) + " WITH " + str(dads) + " ==> " + str(dads.match(dad)),'ok') 532 if dads.match(dad): 533 d = copy.copy(dads) 534 if dad.services == []: 535 d.services = dads.getServices() 536 else: 537 d.services=[] 538 for ss in dad.getServices(): 539 for s in dads.getServices(): 540 if s.match(ss): 541 d.addService(s) 542 result.append(d) 543 else: 544 max = abs(max) 545 for agentid,dads in self.myAgent.servicedb.items(): 546 if max >= 0: 547 if dads.match(dad): 548 d = copy.copy(dads) 549 if dad.services == []: 550 d.services = dads.getServices() 551 else: 552 d.services=[] 553 for ss in dad.getServices(): 554 for s in dads.getServices(): 555 if s.match(ss): 556 d.addService(s) 557 result.append(d) 558 max -= 1 559 else: break 560 self.myAgent.db_mutex.release() 561 562 content = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 563 content["fipa:result"] = [] 564 for i in result: 565 content["fipa:result"].append(i.asContentObject()) 566 self.myAgent.DEBUG(str(i),'ok') 567 self.myAgent.DEBUG("Found "+str(len(result)) + " services.",'ok') 568 reply.setPerformative("inform") 569 reply.setContentObject(content) 570 self.myAgent.send(reply) 571 572 #recvs = "" 573 #for r in reply.getReceivers(): 574 # recvs += str(r.getName()) 575 576 return 1
577 578 579
580 - class ModifyBehaviour(Behaviour.OneShotBehaviour):
581
582 - def __init__(self,msg,content):
583 Behaviour.OneShotBehaviour.__init__(self) 584 self.msg = msg 585 self.content = content
586
587 - def _process(self):
588 589 #The DF agrees and then informs dummy of the successful execution of the action 590 error = False 591 co_error = False 592 dad = None 593 if "rdf" in self.msg.getLanguage(): 594 595 try: 596 co = self.msg.getContentObject() 597 dad = DfAgentDescription(co = co.action.argument) 598 except KeyboardInterrupt,err: 599 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 600 co_error["fipa:error"] = "missing-argument df-agent-description" 601 602 reply = self.msg.createReply() 603 reply.setSender(self.myAgent.getAID()) 604 reply.setPerformative("refuse") 605 reply.setContentObject(co_error) 606 self.myAgent.send(reply) 607 self.myAgent.DEBUG("FAILURE: Could not extract DfAgentDescription from content: "+str(err),'error') 608 return -1 609 610 if dad and (dad.getAID().getName() != self.msg.getSender().getName()): 611 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 612 co_error["fipa:error"] = "unauthorised" 613 614 if co_error: 615 reply = self.msg.createReply() 616 reply.setSender(self.myAgent.getAID()) 617 reply.setPerformative("refuse") 618 reply.setContentObject(co_error) 619 self.myAgent.send(reply) 620 self.myAgent.DEBUG("FAILURE: "+self.msg.getSender().getName()+" is UNAUTHORISED to modify service "+str(dad),'warn') 621 622 return -1 623 624 625 reply = self.msg.createReply() 626 reply.setSender(self.myAgent.getAID()) 627 reply.setPerformative("agree") 628 co = self.msg.getContentObject() 629 co["fipa:done"] = "true" 630 reply.setContentObject(co) 631 self.myAgent.send(reply) 632 633 634 if self.myAgent.servicedb.has_key(dad.getAID().getName()): 635 636 try: 637 for ss in dad.getServices(): 638 self.myAgent.db_mutex.acquire() 639 result=self.myAgent.servicedb[dad.getAID().getName()].updateService(ss) 640 self.myAgent.db_mutex.release() 641 if not result: 642 reply.setPerformative("failure") 643 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 644 co_error["fipa:error"] = "not-registered" 645 reply.setContentObject(co_error) 646 self.myAgent.send(reply) 647 self.myAgent.DEBUG("FAILURE: Could not modify service "+str(ss)+". Service is NOT registered.",'warn') 648 except Exception, err: 649 reply.setPerformative("failure") 650 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 651 co_error["fipa:error"] = "internal-error" 652 reply.setContentObject(co_error) 653 self.myAgent.send(reply) 654 self.myAgent.DEBUG("FAILURE: internal-error: "+str(err),'error') 655 return -1 656 657 658 659 reply.setPerformative("inform") 660 co = self.msg.getContentObject() 661 co["fipa:done"] = "true" 662 reply.setContentObject(co) 663 self.myAgent.send(reply) 664 665 return 1 666 667 else: 668 reply.setPerformative("failure") 669 co_error = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 670 co_error["fipa:error"] = "not-registered" 671 reply.setContentObject(co_error) 672 self.myAgent.send(reply) 673 self.myAgent.DEBUG("FAILURE: Could not modify service "+str(dad)+". Agent has no registered services.",'warn') 674 return -1 675 676 else: 677 #language is sl-0 678 try: 679 dad = DF.DfAgentDescription(self.content.action.modify[0][1]) 680 except Exception,err: 681 error = "(missing-argument ams-agent-description)" 682 self.myAgent.DEBUG("FAILURE: Could not extract DfAgentDescription from content: "+str(err),'error') 683 684 if dad and (dad.getAID().getName() != self.msg.getSender().getName()): 685 error = "(unauthorised)" 686 self.myAgent.DEBUG("REFUSE: "+self.msg.getSender().getName()+" is not AUTHORISED to modify service "+str(dad),'warn') 687 688 if error: 689 reply = self.msg.createReply() 690 reply.setSender(self.myAgent.getAID()) 691 reply.setPerformative("refuse") 692 reply.setContent("( "+self.msg.getContent() + error + ")") 693 self.myAgent.send(reply) 694 695 return -1 696 697 else: 698 699 reply = self.msg.createReply() 700 reply.setSender(self.myAgent.getAID()) 701 reply.setPerformative("agree") 702 reply.setContent("(" + str(self.msg.getContent()) + " true)") 703 self.myAgent.send(reply) 704 705 if self.myAgent.servicedb.has_key(dad.getAID().getName()): 706 707 try: 708 for ss in dad.getServices(): 709 self.myAgent.db_mutex.acquire() 710 result=self.myAgent.servicedb[dad.getAID().getName()].updateService(ss) 711 self.myAgent.db_mutex.release() 712 if not result: 713 reply.setPerformative("failure") 714 reply.setContent("("+self.msg.getContent() + "(not-registered))") 715 self.myAgent.send(reply) 716 self.myAgent.DEBUG("FAILURE: Could not modify service "+str(ss)+". Service is NOT registered.",'warn') 717 except Exception, err: 718 reply.setPerformative("failure") 719 reply.setContent("("+self.msg.getContent() + "(internal-error))") 720 self.myAgent.send(reply) 721 self.myAgent.DEBUG("FAILURE: (internal-error) Modifying service: "+str(err),'error') 722 return -1 723 724 725 726 reply.setPerformative("inform") 727 reply.setContent("(done "+self.msg.getContent() + ")") 728 self.myAgent.send(reply) 729 730 return 1 731 732 else: 733 reply.setPerformative("failure") 734 reply.setContent("("+self.msg.getContent() + "(not-registered))") 735 self.myAgent.send(reply) 736 self.myAgent.DEBUG("FAILURE: Could not modify service "+str(dad)+". Agent has no registered services.",'warn') 737 return -1
738 739
740 - def __init__(self,node,passw,server="localhost",port=5347, config={}):
741 PlatformAgent.__init__(self,node,passw,server,port, config)
742 #self.addAddress("http://"+self.getDomain()+":2099/acc") # HACK 743
744 - def _setup(self):
745 746 self.wui.start() 747 self.servicedb = dict() 748 self.db_mutex = thread.allocate_lock() 749 750 #self.setDefaultBehaviour() 751 db = self.DefaultBehaviour() 752 mt = Behaviour.ACLTemplate() 753 mt.setOntology("FIPA-Agent-Management") 754 mt.setPerformative("request") 755 mt.setProtocol('fipa-request') 756 self.addBehaviour(db,Behaviour.MessageTemplate(mt)) 757 758 #create service events 759 self.createEvent("DF:Service:Register") 760 self.createEvent("DF:Service:UnRegister")
761 762
763 -class DfAgentDescription:
764
765 - def __init__(self, content = None, co = None):
766 #self.name = AID.aid() 767 self.name = None 768 self.services = [] 769 self.protocols = [] 770 self.ontologies = [] 771 self.languages = [] 772 self.lease_time = None 773 self.scope = [] 774 775 if content: 776 self.loadSL0(content) 777 778 if co: 779 if co.has_key("df-agent-description"): 780 co = co["df-agent-description"] 781 if co.name: 782 self.name = AID.aid(co = co.name) 783 if co.services: 784 self.services = [] 785 if "ContentObject" in str(type(co.services)): 786 self.services.append(ServiceDescription(co = co.services)) 787 else: 788 # List 789 for s in co.services: 790 self.services.append(ServiceDescription(co = s)) 791 if co.lease_time: 792 self.lease_time = co.lease_time 793 if co.has_key("lease-time"): 794 self.lease_time = co["lease-time"] 795 if co.protocols: 796 self.protocols = copy.copy(co.protocols) 797 if co.ontologies: 798 self.ontologies = copy.copy(co.ontologies) 799 if co.languages: 800 self.languages = copy.copy(co.languages) 801 if co.scope: 802 self.scope = copy.copy(co.scope)
803 804
805 - def asContentObject(self):
806 """ 807 Returns a version of the DAD in ContentObject format 808 """ 809 co = ContentObject(namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 810 if self.name: 811 co["name"] = self.name.asContentObject() 812 else: 813 co["name"] = AID.aid().asContentObject() 814 if self.lease_time: 815 co["lease-time"] = str(self.lease_time) 816 if self.protocols: 817 co["protocols"] = copy.copy(self.protocols) 818 if self.services: 819 co["services"] = [] 820 for s in self.services: 821 co["services"].append(s.asContentObject()) 822 if self.ontologies: 823 co["ontologies"] = copy.copy(self.ontologies) 824 if self.languages: 825 co["languages"] = copy.copy(self.languages) 826 if self.scope: 827 co["scope"] = copy.copy(self.scope) 828 829 return co
830 831
832 - def asRDFXML(self):
833 """ 834 returns a printable version of the DAD in RDF/XML format 835 """ 836 return str(self.asContentObject())
837
838 - def getAID(self):
839 return self.name
840
841 - def getName(self):
842 if self.name != None: 843 return self.name.getName() 844 else: return AID.aid()
845
846 - def setAID(self, a):
847 self.name = a
848
849 - def getServices(self):
850 return self.services
851
852 - def addService(self, s):
853 #FIX 854 for ss in self.services: 855 assert not ss.match(s) 856 self.services.append(s) 857 for p in s.getProtocols(): 858 if p not in self.protocols: self.addProtocol(p) 859 for o in s.getOntologies(): 860 if o not in self.ontologies: self.addOntologies(o) 861 for l in s.getLanguages(): 862 if l not in self.languages: self.addLanguage(l)
863
864 - def delService(self,s):
865 index=None 866 for i in range(len(self.services)): 867 if self.services[i].match(s): 868 index = i 869 break 870 if index!=None: self.services.pop(i) 871 else: return False 872 for p in s.getProtocols(): 873 if p in self.protocols: 874 self.protocols.remove(p) 875 for p in s.getOntologies(): 876 if p in self.ontologies: self.ontologies.remove(p) 877 for p in s.getLanguages(): 878 if p in self.languages: self.languages.remove(p) 879 return True
880
881 - def updateService(self,s):
882 found = False 883 for ss in self.services: 884 if s.getName() == ss.getName(): 885 found = True 886 if s.getType(): ss.setType(s.getType()) 887 if s.getProtocols(): 888 ss.protocols = s.getProtocols() 889 for p in s.getProtocols(): 890 if p not in self.protocols: self.addProtocol(p) 891 if s.getOntologies(): 892 ss.ontologies = s.getOntologies() 893 for o in s.getOntologies(): 894 if o not in self.ontologies: self.addOntologies(o) 895 if s.getLanguages(): 896 ss.languages = s.getLanguages() 897 for l in s.getLanguages(): 898 if l not in self.languages: self.addLanguage(l) 899 if s.getOwnership(): ss.setOwnership(s.getOwnership()) 900 for k,v in s.getProperties().items(): 901 ss.addProperty(k,v) 902 return found
903
904 - def getProtocols(self):
905 return self.protocols
906
907 - def addProtocol(self, p):
908 if p not in self.protocols: 909 self.protocols.append(p)
910
911 - def getOntologies(self):
912 return self.ontologies
913
914 - def addOntologies(self, o):
915 if o not in self.ontologies: 916 self.ontologies.append(o)
917
918 - def getLanguages(self):
919 return self.languages
920
921 - def addLanguage(self, l):
922 if l not in self.languages: 923 self.languages.append(l)
924
925 - def getLeaseTime(self):
926 return self.lease_time
927
928 - def setLeaseTime(self, lt):
929 self.lease_time = lt
930
931 - def getScope(self):
932 return self.scope
933
934 - def addScope(self, s):
935 self.scope = s
936 937 #def __eq__(self,y):
938 - def match(self,y):
939 940 if y.name: 941 if not self.getAID().match(y.name): 942 return False 943 if y.protocols: 944 for p in y.protocols: 945 if not (p in self.protocols): 946 return False 947 if y.ontologies: 948 for o in y.ontologies: 949 if not (o in self.ontologies): 950 return False 951 if y.languages: 952 for l in y.languages: 953 if not (l in self.languages): 954 return False 955 if y.lease_time: 956 if self.lease_time != y.getLeaseTime(): 957 return False 958 if y.scope: 959 if self.scope != y.getScope(): 960 return False 961 962 if len(self.services)>0 and len(y.getServices())>0: 963 for i in y.services: 964 matched = False 965 for j in self.getServices(): 966 #if i == j: 967 if j.match(i): 968 matched=True 969 break 970 if not matched: return False 971 return True 972 else: 973 return True
974
975 - def __ne__(self,y):
976 return not self == y
977
978 - def loadSL0(self,content):
979 if content != None: 980 if "name" in content: 981 self.name = AID.aid() 982 self.name.loadSL0(content.name) 983 984 if "services" in content: 985 #TODO: the parser only detects 1 service-description!!! 986 self.services = [] #ServiceDescription() 987 #self.services.loadSL0(content.services.set['service-description']) 988 for i in content.services.set: 989 sd = ServiceDescription(i[1]) 990 self.services.append(sd) 991 992 if "protocols" in content: 993 self.protocols = content.protocols.set.asList() 994 995 if "ontologies" in content: 996 self.ontologies = content.ontologies.set.asList() 997 998 if "languages" in content: 999 self.languages = content.languages.set.asList() 1000 1001 if "lease-time" in content: 1002 self.lease_time = BasicFipaDateTime.BasicFipaDateTime() 1003 #self.lease_time.fromString(content["lease-time"]) 1004 self.lease_time = content["lease-time"][0] 1005 1006 if "scope" in content: 1007 self.scope = content["scope"][0]
1008
1009 - def __str__(self):
1010 return self.asRDFXML()
1011
1012 - def asSL0(self):
1013 1014 sb = '' 1015 if self.name != None: 1016 sb = sb + ":name " + str(self.name) + "\n" 1017 1018 if len(self.protocols) > 0: 1019 sb = sb + ":protocols \n(set\n" 1020 for i in self.protocols: 1021 sb = sb + str(i) + '\n' 1022 sb = sb + ")\n" 1023 1024 if len(self.ontologies) > 0: 1025 sb = sb + ":ontologies \n(set\n" 1026 for i in self.ontologies: 1027 sb = sb + str(i) + '\n' 1028 sb = sb + ")\n" 1029 1030 if len(self.languages) > 0: 1031 sb = sb + ":languages \n(set\n" 1032 for i in self.languages: 1033 sb = sb + str(i) + '\n' 1034 sb = sb + ")\n" 1035 1036 if self.lease_time != None: 1037 sb = sb + ":lease-time " + str(self.lease_time) + '\n' 1038 1039 if self.scope != None: 1040 sb = sb + ":scope " + str(self.scope) + '\n' 1041 1042 if len(self.services) > 0: 1043 sb = sb + ":services \n(set\n" 1044 for i in self.services: 1045 sb = sb + str(i.asSL0()) +'\n' 1046 sb = sb + ")\n" 1047 1048 sb = "(df-agent-description \n" + sb + ")\n" 1049 return sb
1050
1051 -class ServiceDescription:
1052
1053 - def __init__(self, content = None, co = None):
1054 1055 self.name = None 1056 self.type = None 1057 self.protocols = [] 1058 self.ontologies = [] 1059 self.languages = [] 1060 self.ownership = None 1061 self.properties = {} 1062 1063 if content != None: 1064 self.loadSL0(content) 1065 1066 if co: 1067 #print "SD:",co.pprint() 1068 if co.name: 1069 self.name = co.name 1070 if co.type: 1071 self.type = co.type 1072 if co.protocols: 1073 self.protocols = copy.copy(co.protocols) 1074 if co.ontologies: 1075 self.ontologies = copy.copy(co.ontologies) 1076 if co.languages: 1077 self.languages = copy.copy(co.languages) 1078 if co.ownership: 1079 self.ownership = co.ownership 1080 if co.properties: 1081 #print co.properties 1082 for k,v in co.properties.items(): 1083 if ":" in k: ns,key = k.split(":") 1084 else: key=k 1085 self.properties[key]=v
1086 1087
1088 - def getName(self):
1089 return self.name
1090
1091 - def setName(self, name):
1092 self.name = name
1093
1094 - def getType(self):
1095 return self.type
1096
1097 - def setType(self, t):
1098 self.type = t
1099
1100 - def getProtocols(self):
1101 return self.protocols
1102
1103 - def addProtocol(self, p):
1104 if p not in self.protocols: 1105 self.protocols.append(p)
1106
1107 - def getOntologies(self):
1108 return self.ontologies
1109
1110 - def addOntologies(self, o):
1111 if o not in self.ontologies: 1112 self.ontologies.append(o)
1113
1114 - def getLanguages(self):
1115 return self.languages
1116
1117 - def addLanguage(self, l):
1118 if l not in self.languages: 1119 self.languages.append(l)
1120
1121 - def getOwnership(self):
1122 return self.ownership
1123
1124 - def setOwnership(self, o):
1125 self.ownership = o #.lower()
1126
1127 - def getProperties(self):
1128 return self.properties
1129
1130 - def getProperty(self, prop):
1131 if prop in self.properties.keys(): 1132 return self.properties[prop] 1133 return None
1134
1135 - def addProperty(self, k,value):
1136 if ":" in k: ns,key = k.split(":") 1137 else: key=k 1138 self.properties[key]=value
1139
1140 - def __eq__(self,y):
1141 return self.match(y)
1142
1143 - def match(self,y):
1144 1145 if y.name: 1146 if self.name != y.getName(): 1147 return False 1148 if y.type: 1149 if self.type != y.getType(): 1150 return False 1151 if y.protocols: 1152 for p in y.protocols: 1153 if not (p in self.protocols): 1154 return False 1155 if y.ontologies: 1156 for o in y.ontologies: 1157 if not (o in self.ontologies): 1158 return False 1159 if y.languages: 1160 for l in y.languages: 1161 if not (l in self.languages): 1162 return False 1163 if y.ownership: 1164 if self.ownership != y.getOwnership(): 1165 return False 1166 #properties 1167 for k,v in y.properties.items(): 1168 if self.getProperties().has_key(k): 1169 if y.getProperty(k) != v: return False 1170 else: return False 1171 return True
1172
1173 - def __ne__(self,y):
1174 return not self == y
1175
1176 - def loadSL0(self,content):
1177 if content != None: 1178 if "name" in content: 1179 self.name = str(content.name[0]).lower() 1180 1181 if "type" in content: 1182 self.type = str(content.type[0]).lower() 1183 1184 if "protocols" in content: 1185 self.protocols = content.protocols.set.asList() 1186 1187 if "ontologies" in content: 1188 self.ontologies = content.ontologies.set.asList() 1189 1190 if "languages" in content: 1191 self.languages = content.languages.set.asList() 1192 1193 if "ownership" in content: 1194 self.ownership = content.ownership 1195 1196 if "properties" in content: 1197 for p in content.properties.set.asDict().values(): 1198 self.properties[str(p['name']).lower().strip("[']")] = str(p['value']).lower().strip("[']")
1199
1200 - def __str__(self):
1201 return self.asRDFXML()
1202
1203 - def asSL0(self):
1204 1205 sb = "" 1206 if self.name != None: 1207 sb += ":name " + str(self.name) + "\n" 1208 if self.type: 1209 sb += ":type " + str(self.type) + "\n" 1210 1211 if len(self.protocols) > 0: 1212 sb += ":protocols \n(set\n" 1213 for i in self.protocols: 1214 sb += str(i) + " " 1215 sb = sb + ")\n" 1216 1217 if len(self.ontologies) > 0: 1218 sb = sb + ":ontologies \n(set\n" 1219 for i in self.ontologies: 1220 sb += str(i) + " " 1221 sb = sb + ")\n" 1222 1223 if len(self.languages) > 0: 1224 sb = sb + ":languages \n(set\n" 1225 for i in self.languages: 1226 sb += str(i) + " " 1227 sb += ")\n" 1228 1229 if self.ownership: 1230 sb += ":ownership " + str(self.ownership) + "\n" 1231 1232 if len(self.properties) > 0: 1233 sb += ":properties \n (set\n" 1234 for k,v in self.properties.items(): 1235 sb += " (property :name " + str(k) + " :value " + str(v) +")\n" 1236 sb += ")\n" 1237 1238 1239 if sb != "": 1240 sb = "(service-description\n" + sb + ")\n" 1241 return sb
1242
1243 - def asContentObject(self):
1244 """ 1245 Returns a version of the SD in ContentObject format 1246 """ 1247 co = ContentObject()#namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 1248 if self.name: 1249 co["name"] = str(self.name) 1250 else: 1251 co["name"] = "" 1252 if self.type: 1253 co["type"] = str(self.type) 1254 else: 1255 co["type"] = "" 1256 if self.protocols: 1257 co["protocols"] = copy.copy(self.protocols) 1258 if self.ontologies: 1259 co["ontologies"] = copy.copy(self.ontologies) 1260 if self.languages: 1261 co["languages"] = copy.copy(self.languages) 1262 if self.ownership: 1263 co["ownership"] = self.ownership 1264 if self.properties != {}: 1265 co["properties"] = ContentObject()#namespaces={"http://www.fipa.org/schemas/fipa-rdf0#":"fipa:"}) 1266 for k,v in self.properties.items(): 1267 if ":" in k: ns,key = k.split(":") 1268 else: key=k 1269 co["properties"][str(key)] = v 1270 return co
1271
1272 - def asRDFXML(self):
1273 """ 1274 returns a printable version of the SD in RDF/XML format 1275 """ 1276 return str(self.asContentObject())
1277
1278 -class Service:
1279
1280 - def __init__(self, name=None, owner=None, P=[], Q=[], inputs=[], outputs=[], description= None, ontology=None, dad = None, co = None):
1281 1282 self.name = name 1283 self.owner = owner 1284 self.dad = DfAgentDescription() 1285 sd = ServiceDescription() 1286 1287 self.inputs = inputs 1288 self.outputs = outputs 1289 1290 if co and co.has_key("service"): 1291 if co.service.name: name = co.service.name 1292 if co.service.owner: owner = AID.aid(co=co.service.owner) 1293 if co.service.ontology: ontology = co.service.ontology 1294 if co.service.P: P = co.service.P 1295 if co.service.Q: Q = co.service.Q 1296 if co.service.description: description = co.service.description 1297 1298 #self.name = name 1299 #self.owner = owner 1300 #self.dad = DfAgentDescription() 1301 if owner: self.dad.setAID(owner) 1302 if ontology: self.dad.addOntologies(ontology) 1303 1304 1305 1306 if name!=None: 1307 sd.setName(name) 1308 if owner!=None: sd.setOwnership(owner.getName()) 1309 if P!=[]: sd.addProperty("P",P) 1310 if Q!=[]: sd.addProperty("Q",Q) 1311 if inputs!=[]: sd.addProperty("inputs",inputs) 1312 if outputs!=[]: sd.addProperty("outputs",outputs) 1313 if ontology!=None: sd.addOntologies(str(ontology)) 1314 if description!=None: sd.addProperty("description",str(description)) 1315 1316 self.dad.addService(sd) 1317 1318 if dad: self.setDAD(dad)
1319
1320 - def setName(self,name):
1321 self.name = name 1322 if self.dad.getServices() == []: 1323 self.dad.addService(ServiceDescription()) 1324 services = [] 1325 for s in self.dad.getServices(): 1326 s.setName(name) 1327 services.append(s) 1328 self.dad.services = services
1329
1330 - def getName(self):
1331 return self.name
1332
1333 - def setOwner(self,owner):
1334 self.owner = owner 1335 self.dad.setAID(owner) 1336 if self.dad.getServices() != []: 1337 services = [] 1338 for s in self.dad.getServices(): 1339 s.setOwnership(owner.getName()) 1340 services.append(s) 1341 self.dad.services = services
1342
1343 - def getOwner(self):
1344 return self.owner
1345
1346 - def setOntology(self,ontology):
1347 self.dad.addOntologies(ontology) 1348 if self.dad.getServices() == []: 1349 self.dad.addService(ServiceDescription()) 1350 services = [] 1351 for s in self.dad.getServices(): 1352 s.addOntologies(ontology) 1353 services.append(s) 1354 self.dad.services = services
1355
1356 - def getOntology(self): return self.dad.getOntologies()
1357
1358 - def addP(self,P):
1359 if self.dad.getServices() == []: 1360 self.dad.addService(ServiceDescription()) 1361 services = [] 1362 for s in self.dad.getServices(): 1363 p = s.getProperty("P") 1364 if not p: p=[] 1365 p.append(P) 1366 s.addProperty('P',p) 1367 services.append(s) 1368 self.dad.services = services
1369
1370 - def getP(self):
1371 if self.dad.getServices()==[]: return [] 1372 p = self.dad.getServices()[0].getProperty("P") 1373 if p==None: return [] 1374 else: return p
1375
1376 - def addQ(self,Q):
1377 if self.dad.getServices() == []: 1378 self.dad.addService(ServiceDescription()) 1379 services = [] 1380 for s in self.dad.getServices(): 1381 q = s.getProperty("Q") 1382 if not q: q=[] 1383 q.append(Q) 1384 s.addProperty('Q',q) 1385 services.append(s) 1386 self.dad.services = services
1387
1388 - def getQ(self):
1389 if self.dad.getServices()==[]: return [] 1390 q = self.dad.getServices()[0].getProperty("Q") 1391 if q==None: return [] 1392 else: return q
1393
1394 - def setInputs(self,inputs):
1395 if self.dad.getServices() == []: 1396 self.dad.addService(ServiceDescription()) 1397 services = [] 1398 for s in self.dad.getServices(): 1399 s.properties['inputs']=inputs 1400 services.append(s) 1401 self.dad.services = services
1402
1403 - def getInputs(self):
1404 if self.dad.getServices()==[]: return [] 1405 return self.dad.getServices()[0].getProperty("inputs")
1406
1407 - def setOutputs(self,outputs):
1408 if self.dad.getServices() == []: 1409 self.dad.addService(ServiceDescription()) 1410 services = [] 1411 for s in self.dad.getServices(): 1412 s.properties['outputs']=outputs 1413 services.append(s) 1414 self.dad.services = services
1415
1416 - def getOutputs(self):
1417 if self.dad.getServices()==[]: return [] 1418 return self.dad.getServices()[0].getProperty("outputs")
1419
1420 - def setDescription(self,description):
1421 if self.dad.getServices() == []: 1422 self.dad.addService(ServiceDescription()) 1423 services = [] 1424 for s in self.dad.getServices(): 1425 s.properties['description']=description 1426 services.append(s) 1427 self.dad.services = services
1428
1429 - def getDescription(self):
1430 if self.dad.getServices()==[]: return [] 1431 return self.dad.getServices()[0].getProperty("description")
1432
1433 - def getType(self):
1434 if self.dad.getServices()==[]: return [] 1435 return self.dad.getServices()[0].getType()
1436
1437 - def setType(self, typ):
1438 if self.dad.getServices()==[]: return [] 1439 self.dad.getServices()[0].setType(typ)
1440
1441 - def setDAD(self,dad):
1442 sd = dad.getServices() 1443 if len(sd)==1: sd = sd[0] 1444 else: return None 1445 self.name = sd.getName() 1446 self.owner = dad.getAID() 1447 self.ontology = dad.getOntologies() 1448 1449 self.dad = dad
1450
1451 - def getDAD(self):
1452 return self.dad
1453
1454 - def match(self,y):
1455 return y.dad.match(self.dad)
1456
1457 - def __eq__(self,y):
1458 if y==None: return False 1459 return y.match(self)
1460
1461 - def __ne__(self,y):
1462 return not self==y
1463
1464 - def __str__(self):
1465 return str(self.dad)
1466
1467 - def __repr__(self):
1468 return str(self.asContentObject())
1469
1470 - def asContentObject(self):
1471 1472 co = ContentObject() 1473 co["service"]=ContentObject() 1474 if self.getName()!=None: co.service["name"] = self.getName() 1475 if self.getOwner()!=None: co.service["owner"] = self.getOwner().asContentObject() 1476 if self.getOntology()!=[]: co.service["ontology"] = self.getOntology() 1477 if self.getP()!=[]: co.service["P"] = self.getP() 1478 if self.getQ()!=[]: co.service["Q"] = self.getQ() 1479 if self.getDescription()!=None: co.service["description"] = self.getDescription() 1480 1481 return co
1482
1483 - def asHTML(self):
1484 s = '<table class="servicesT" cellspacing="0">' 1485 s += '<tr><td class="servHd">Name</td><td class="servBodL">'+self.getName()+'</td></tr>' 1486 s += '<tr><td class="servHd">Owner</td><td class="servBodL">'+self.getOwner().getName()+'</td></tr>' 1487 if self.getType(): 1488 s += '<tr><td class="servHd">Type</td><td class="servBodL">'+str(self.getType())+'</td></tr>' 1489 if self.getDescription(): 1490 s += '<tr><td class="servHd">Description</td><td class="servBodL">'+str(self.getDescription())+'</td></tr>' 1491 if self.getOntology(): 1492 s += '<tr><td class="servHd">Ontologies</td><td class="servBodL">'+str(self.getOntology())+'</td></tr>' 1493 if self.getP(): 1494 s += '<tr><td class="servHd">Preconditions</td><td class="servBodL">'+str(self.getP())+'</td></tr>' 1495 if self.getQ(): 1496 s += '<tr><td class="servHd">Postconditions</td><td class="servBodL">'+str(self.getQ())+'</td></tr>' 1497 if self.getInputs(): 1498 s += '<tr><td class="servHd">Inputs</td><td class="servBodL">'+str(self.getInputs())+'</td></tr>' 1499 if self.getOutputs(): 1500 s += '<tr><td class="servHd">Outputs</td><td class="servBodL">'+str(self.getOutputs())+'</td></tr>' 1501 s+='</table>' 1502 1503 return s
1504