C:/mesDocs/QT_confDbVis_canvas/objectclasses.py

Go to the documentation of this file.
00001 import platform # to detect the OS
00002 import string
00003 import os
00004 import copy
00005 
00006 #from wxPython.wx import wxColour # wxColour object for storing device type colour
00007 
00008 from cdbVisCore import *
00009 
00010 if OS_VERSION == LINUX:
00011         from libconfDBpython import *
00012 elif OS_VERSION == WINDOWS:
00013         from confDBpython import *
00014 else:
00015         from confDBpython import * #linux distro..or linux "compatible" with *.so's
00016 
00017 from MyExceptions import *
00018 import Validation
00019 from helper import *
00020 import pdb
00021 import cx_Oracle
00022 
00023 # Global variables
00024 configfile = None # Reference to the configuration file for CdbVis
00025 appmain = None # Reference to the running instance of MainWindow, created first time when connecting to ConfDB
00026 cfDB = None # Reference to the ConfDB Library instance that is responsible for keeping the persistent connection to ConfDB
00027 cfDB2 = None # to store the cursor of the connexion established using cx_Oracle module.  // Added by walid 
00028 oracle = None
00029 # Global functions
00030 def GetConfig():
00031         return configfile #to get config file reference in other object classes
00032 def GetAppWin():
00033         return appmain  #to get an instance of the MainWindow object, to be able to get the dirty list etc.
00034         
00035 ##
00036 #  this fonction take as argument a string like "(r,g,b)" and return a QColor object
00037 def Color(string):
00038         if(isinstance(string,QColor)):
00039                 return string
00040         string = string.strip('(').strip(')').split(',')
00041         return QColor(int(string[0]),int(string[1]),int(string[2]))
00042 def ColorToTuple(color):
00043         return ( color.red(), color.green(), color.blue() )
00044 
00045 '''def connectLink(deviceFrom,deviceTo,portFrom,portTo):
00046         """ connect deviceFrom to deviceTo using the ports numbers : portFrom and portTo.
00047         if the port does not exist in the confDB they will be created.
00048         """
00049         global cfDB2
00050         
00051         # get the deviceFrom and deviceTo IDs.
00052         cfDB2.execute("SELECT DEVICENAME,DEVICEID FROM LHCB_LG_DEVICES WHERE DEVICENAME='"+deviceFrom+"' OR DEVICENAME='"deviceTo"' ")
00053         res = cfDB2.fetchall()
00054         if len(res)<2:
00055                 GetAppWin().ShowError("One of the two devices does not existe in the Configuration Database!",ERR_ERROR)
00056                 return False
00057         if res[0][0]=deviceFrom:
00058                 deviceIdFrom = res[0][1]
00059                 deviceIdTo = res[1][1]
00060         else:
00061                 deviceIdFrom = res[1][1]
00062                 deviceIdTo = res[0][1]
00063         
00064         #get ports id 
00065         cfDB2.execute("SELECT DEVICEID,PORTID FROM LHCB_PORT_PROPERTIES WHERE \
00066         ( DEVICEID="+str(deviceIdFrom)+" AND PORT_NBR="+portFrom+" AND PORT_WAY=2) OR (DEVICEID="+str(deviceIdTo)+" AND PORT_NBR="+portTo+" AND PORT_WAY=1) ")
00067         res = cfDB2.fetchall()
00068         if len(res)>3:
00069                 GetAppWin().ShowError("Incoherent entries in ConfDB !",ERR_ERROR)
00070         elif len(res)<2:
00071                 GetAppWin().ShowError("Corresponding port doesnot exist !",ERR_ERROR)
00072                 # TODO :   + validate the ports number by checking the Device_Type informations.
00073                 #       + Create the corresponding ports if they do not exist
00074         else:
00075                 cfDB2.execute("INSERT INTO LHCB_MACROSCOPIC_CONNECTIVITY \
00076                 (PORTIDFROM, PORTIDTO, LINKTYPE, BIDIRECTIONAL_LINK_USED, LINK_WEIGHT, LINK_USED, SYSTEM_NAME, LINK_INFO, CREATED, AUTHOR, TERMINAL_NAME, LAST_UPDATE, USER_UPDATE) \
00077                 VALUES ("+deviceIdFrom+", "+deviceIdTo+", "+linkType+", )")
00078         
00079 '''     
00080 ##
00081 #  Abstract class with common varibles and functions for all db objects. All db objects inherit from this class.
00082 #           This is actually what you in Java would call an interface. All classes that implement (inherit) this class MUST have
00083 #           all variables and functions this class has.
00084 #       
00085 class DBInfo(dbUpdate):
00086 
00087         def __init__(self):
00088                 self.__errormessage = "" # Variable to store the last set error message; so that it can be retrieved by calling code
00089                 
00090         ##
00091         #  Set the error message so that it can be looked up.
00092         #               @msg - the message string
00093         #               
00094         def SetErrorMessage(self,msg):
00095                 
00096                 self.__errormessage = msg
00097                 
00098         ##
00099         #  Get the error message that was set most recently.
00100         # 
00101         #               !return - the error message string
00102         #               
00103         def GetErrorMessage(self):
00104                 
00105                 return self.__errormessage
00106 
00107         ##
00108         #  Create a new instance of the object in the database. This actually only sets the save status of the object to CREATE, and adds the
00109         #               object to the dirty objects list so that it can be stored in ConfDB later on.
00110         #               
00111         def Create(self):
00112                 pass
00113 
00114         ##
00115         #  Modify a data object; sets actually the save status of the object to MODIFY; and adds an instance of it to the
00116         #               dirty objects list so that it can be stored in ConfDB later.
00117         #               
00118         def Modify(self):
00119                 pass
00120 
00121         ##
00122         #  Delete a data object; sets actually the save status of the object to DELETE; and adds an instance of it to the
00123         #               dirty objects list so that it can be stored in ConfDB later.
00124         #               
00125         def Delete(self):
00126                 pass
00127         
00128         ##
00129         #  This function is to update the object with the most recent information that the user has set to it. It may be stored in ConfDB
00130         #               or retrieved from an object in the dirty objects list.
00131         #               
00132         def Update(self):
00133                 pass
00134 
00135         ##
00136         #  This function retrieves information/properties from the object as it is stored in the ConfDB or in the dirty objects list, and
00137         #               sends a dictionary with all this information back to the caller. This function is almost equal to Update(...), but this function
00138         #               may contain the most recent information about the object itself, and hence not look in the dirty objects list or ConfDB for the most
00139         #               recent information.
00140         #               
00141         def GetObjectInfo(self):
00142                 pass
00143         
00144         ##
00145         #  A call to this information actually tries to store changes in the ConfDB, what it does depends on the save and modify status set
00146         #               for this object. The change are not necessarily commited immediately.
00147         #               
00148         def Save(self):
00149                 pass
00150 
00151         
00152 
00153 ##
00154 #  This is the overall general class, all other classes are a part of this class, or a part of a class that is a part of this class. 
00155 #       The classes in this class hierarchy do NOT inherit from each other, but a simply objects in the other classes.
00156 # 
00157 #       This class is like a class for all subsystems in the ConfDB, it is responsible to connect and disconnect to and from the ConfDB,
00158 #       retrieving subsystem info from the configuration file, setting global variables and retrieving info about available subsystems.
00159 #       
00160 class DBSystem:
00161 
00162         ##
00163         #  Constructor
00164         # 
00165         #                   Parameters:
00166         #                   @cfgFile - a reference to the program configuration file
00167         #                   @main - a reference to the program instance (MainWindow), for communication purposes
00168         #               
00169         def __init__(self,cfgFile,main):
00170                 
00171                 self.__cfg = cfgFile
00172                 
00173                 global configfile
00174                 configfile = cfgFile    #to make it visible to other object classes in this module
00175 
00176                 self.__connected = False
00177                 global appmain
00178                 appmain = main # global reference to MainWindow; accessible from every instance of objects in this module
00179                 self.__main = None
00180                 self.__rootDir = None # Root directory of the configuration file, usually; db/confdb
00181 
00182                 self.__subsystems = []  #list of subsystem objects (references), filled later when we connect to ConfDB
00183                 self.__functions=[]
00184                 self.__errormessage = ""
00185 
00186         ##
00187         #  Set configuration file.
00188         # 
00189         #               @settingsfile - reference to the configuration file
00190         #               
00191         def __setSettingsFile(self,settingsfile):
00192                 self.__cfg = settingsfile
00193 
00194         ##
00195         #  Return the reference to the configuration file.
00196         # 
00197         #               !return - reference to the configuration file.
00198         #               
00199         def __getSettingsFile(self):
00200                 return self.__cfg
00201 
00202         def SetErrorMessage(self,msg):
00203                 self.__errormessage = msg
00204                 
00205         def GetErrorMessage(self):
00206                 return self.__errormessage
00207 
00208         def GetSubSystems(self):
00209                 #TODO: Set up try-catch for configuration file reading
00210                 
00211                 if not self.__cfg:
00212                         self.__errormessage = "Configuration file not yet loaded. This file must either exist as settings.cfg in the root folder of the running program, or loaded before you connect to the database by choosing File > Load Settings... from the menu."
00213                         return False
00214 
00215                 if not self.__connected:
00216                         self.__errormessage = "The connection to the database was lost. If this problem continues, there is probably a problem with the database or database connection."
00217                         return False
00218 
00219                 validsystems = allvalidsystems #retrieved from global variable allvalidsystems in cdbVisCore module
00220                 self.__subsystems = []
00221                 mysystem = ""
00222                 for mysystem in validsystems:
00223                         obj = SubSystem(self.__cfg,mysystem) # Create SubSystem object for each subsystem found
00224                         self.__subsystems.append(obj)    #append systems to the list, which exist in the configuration file
00225 
00226 
00227                 return self.__subsystems
00228 
00229         ##
00230         #  Return whether we are connected to the ConfDB or not.
00231         # 
00232         #               !return - True if we are connected, False otherwise
00233         #               
00234         def __isConnected(self):
00235                 
00236                 return self.__connected
00237 
00238 
00239         ##
00240         #  Connect and set up a persistent connection to the ConfDB. Set the connection object to be available
00241         #               for every other object; as a global variable.
00242         # 
00243         #               @rootDir - The root directory of where we will start to search in the configuration file (set file cursor)
00244         #               
00245         def Connect(self,rootDir):
00246 
00247                 try:
00248                         if self.__connected:
00249                                 self.__errormessage = "Cannot connect to the ConfDB. Reason: Already connected!"
00250                                 return False
00251 
00252                         self.__rootDir = rootDir
00253                                                                                                                 
00254                         # Read user, pwd and database name from the configuration file
00255                         dsn = self.__cfg.get(self.__rootDir,"dsn")
00256                         user = self.__cfg.get(self.__rootDir,"user")
00257                         password = self.__cfg.get(self.__rootDir,"password")            
00258                         # Connect to ConfDB and set up global ConfDB object
00259                         global cfDB
00260                         cfDB = CONFDB(dsn,user,password)
00261                         DBSystem.cfDB = cfDB #Added by walid just for debugging !
00262                         cfDB.DBConnexion()
00263 
00264                         self.__connected = True # Connected!
00265                         
00266                         ##return True
00267 
00268                 except RuntimeError,err:
00269                     self.__errormessage = "Failed to connect to ConfDB using confDBpython. Reason: \n" + str(err)
00270                     return False #on error
00271                 
00272                 # Connect using cx_Oracle module  // Added by walid because there are some functions missing in the confDBpython library.
00273                 try:
00274                         self.__rootDir = rootDir
00275                         # Read user, pwd and database name from the configuration file
00276                         dsn = self.__cfg.get(self.__rootDir,"dsn")
00277                         user = self.__cfg.get(self.__rootDir,"user")
00278                         password = self.__cfg.get(self.__rootDir,"password")            
00279                         # Connect to ConfDB and set up global ConfDB object
00280                         
00281                         global oracle
00282                         oracle = cx_Oracle.connect(user+'/'+password+'@'+dsn)
00283                         global cfDB2
00284                         cfDB2 = oracle.cursor()
00285                         DBSystem.cfDB2 = cfDB2 #Added by walid just for debugging !
00286                         return True
00287 
00288                 except RuntimeError,err:
00289                     self.__errormessage = "Failed to connect to ConfDB using cx_Oracle module. Reason: \n" + str(err)
00290                     return False #on error
00291 
00292         ##
00293         #  Disconnect from the ConfDB. Destroy the persistent connection.
00294         #               
00295         def Disconnect(self):
00296                 
00297                 try:
00298                         if not self.__connected:
00299                             self.__errormessage = "Error disconnecting from ConfDB. Reason: Not connected"
00300                             return False
00301                                                                                                                                      
00302                         cfDB.DBDeconnexion()
00303                         self.__connected = False
00304                         self.__rootDir = None
00305                         self.__cfg = None
00306                         self.__main = None
00307                         
00308                         global oracle
00309                         oracle.commit()
00310 
00311                         # Get error that cfDB is not declared yet if we set this. Strange.
00312                         #global cfDB
00313                         #cfDB = None
00314                 
00315                         return True
00316 
00317                 except RuntimeError,err:
00318                     self.__errormessage = "Error disconnecting from ConfDB. Reason: " + str(err)
00319                     return False #on error
00320 
00321         #added by Lana
00322 
00323         ##
00324         #  Get all the available funcitons
00325         # 
00326         #               !return - a list of device functions available if successful, an empty list if
00327         #               none found, and False if an error occurs.
00328         #               
00329         def GetAllDeviceFunctions(self):
00330 
00331                 #TODO: Also look in dirty objects list.
00332                 try:
00333                         
00334                         my_functions= cfDB.GetAvailableFunctions()# Get list of functions from the confdb
00335                         my_functions.append("none")
00336                         return my_functions
00337 
00338                 except ValidationError,err:
00339                         self.__errormessage = str(err)
00340                         return False
00341                 except RuntimeError,err:
00342                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00343                         self.__errormessage = "No devices found in the selected subsystem " + str(self.__name)
00344                         return [] #none found
00345                     else:
00346                         self.__errormessage = str(err)
00347                     return False #on error  
00348  
00349         ##
00350         #  Get all the available funcitons
00351         # 
00352         #               !return - a list of device functions available if successful, an empty list if
00353         #               none found, and False if an error occurs.
00354         #               
00355         def GetAllSpareHWTypes(self):
00356 
00357                 #TODO: Also look in dirty objects list.
00358                 try:
00359 
00360                         my_functions= cfDB.GetSpareHWTypeList()# Get list of functions from the confdb
00361                         return my_functions
00362 
00363                 except ValidationError,err:
00364                         self.__errormessage = str(err)
00365                         return False
00366                 except RuntimeError,err:
00367                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00368                         self.__errormessage = "No devices found in the selected subsystem " + str(self.__name)
00369                         return [] #none found
00370                     else:
00371                         self.__errormessage = str(err)
00372                     return False #on error  
00373 
00374         ##
00375         #  General get a device at a given location.
00376         #                   TODO: should also be moved to SubSystem class.
00377         #                   NB! This function does not look for devices that are not yet stored in the ConfDB.
00378         # 
00379         #                   @location_string - the location string which looks for devices with the same location
00380         #                   string set.
00381         #               
00382         def GetDevicesByLocation(self,location_string):
00383 
00384                 try:
00385 
00386                     res = cfDB.GetDeviceNamesPerLocation(location_string)
00387                     devices = res
00388 
00389                     i = 0 #reset
00390                     my_devices = []
00391                     while i < len(devices):
00392                         my_devices.append(devices[i])
00393                         i += 1
00394 
00395                     return my_devices
00396 
00397                 except RuntimeError,err:
00398                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00399                                         self.__errormessage = "No devices found at the given location."
00400                                         return [] #none found
00401                         else:
00402                                 self.__errormessage = str(err)
00403                         return False #on error
00404 
00405         
00406 
00407 #end added
00408 
00409 ##
00410 #  Class for properties and methods for individual subsystems such as Muon and TFC. Valid subsystems are given in
00411 #       CdbVisCore module in the allvalidsystems global variable.
00412 #       
00413 class SubSystem(DBInfo):
00414 
00415         ##
00416         #  Constructor.
00417         # 
00418         #               Parameters:
00419         #               @configFile - instance of the configurations file that we have loaded
00420         #               @subsystemname - name of the subsystem this instance will contain information about and act on
00421         #               
00422         def __init__(self,configFile,subsystemname=""):
00423                 
00424                 self.__name = subsystemname     # The subsystem name is unique and identifies the subsystem we work on/in
00425                 self.__cfg = configFile
00426                 self.__deviceTypes = []
00427                 self.__devices = []
00428                 self.__linkTypes = []
00429 
00430                 #dictionaries of linkids/names linkid : linkname, and linkname: linkid
00431                 self.__linkTypeTable = {}
00432                 self.__deviceTable = {}
00433                 
00434                 self.__created = False
00435                 self.__description = ""
00436 
00437                 # Obsolete information retrieved from configuration file; where the subsystems were positioned in the visual window.
00438                 # May be useful to use.
00439                 self.__xPos = 0
00440                 self.__yPos = 0
00441                 self.__width = 0
00442                 self.__height = 0
00443                 self.__colour = None
00444                 self.__rotate = 0
00445 
00446                 self.__errormessage = ""
00447 
00448         ### GET ###
00449         def GetLinkTypeTable(self):
00450                 return self.__linkTypeTable
00451         def GetDeviceTable(self):
00452                 return self.__deviceTable
00453 
00454         def GetName(self):
00455                 return self.__name
00456         def GetDescription(self):
00457                 return self.__description
00458         def GetXPos(self):
00459                 return float(self.__xPos)
00460         def GetYPos(self):
00461                 return float(self.__yPos)
00462         def GetWidth(self):
00463                 return float(self.__width)
00464         def GetHeight(self):
00465                 return float(self.__height)
00466         def GetColour(self):
00467                 return self.__colour
00468         def GetRotate(self):
00469                 return float(self.__rotate)
00470 
00471         def GetErrorMessage(self):
00472                 return self.__errormessage
00473 
00474         ### SET ###
00475         def SetName(self,name):
00476                 self.__name = name
00477         def SetColour(self,colour):
00478                 self.__colour = colour
00479         def SetErrorMessage(self,msg):
00480                 self.__errormessage = msg
00481         
00482         ##
00483         #  Get all information needed about a subsystem. The information is stored in the configuration file.
00484         #               
00485         def GetObjectInfo(self):
00486                 return []       
00487         
00488         ##
00489         #  We can disable a subsystem (not visible to the user) by setting created=False in the
00490         #               configuration file. This function checks whether this variable is set to True or False.
00491         # 
00492         #               !return - True if the subsystem is created and available, False otherwise.
00493         #               
00494         def IsCreated(self):
00495 
00496                 # TODO: exception handling
00497                 path = "/db/devdb/data/systems/" + str(self.__name)
00498                 if self.__cfg.Exists(path):
00499                     self.__cfg.SetPath(path)
00500                     if self.__cfg.Read("created") == "True":
00501                         return True
00502                     else:
00503                         return False
00504 
00505 
00506         ##
00507         #  Get all devices in the given subsystem.
00508         # 
00509         #               !return - a list of devices available in a subsystem if successful, an empty list if
00510         #               none found, and False if an error occurs.
00511         #               
00512         def GetAllDevices(self):
00513 
00514                 #TODO: Also look in dirty objects list.
00515                 try:
00516                         Validation.ValidateSystem("Active subsystem",self.__name)
00517 
00518                         my_devices = []
00519                         tmp = cfDB.MatchDeviceIDDeviceName(self.__name) # Get both IDs and Names from the ConfDB of devices in the given subsystem
00520                         result = tmp
00521                 
00522                         i=0
00523                         self.__deviceTable = {}
00524                         while i < len(result):
00525                                 tmp_device = result[i].split("|")
00526                                 my_devices.append(tmp_device[1])
00527 
00528                                 # Set up a mapping dictionary: device name - device id and vice versa
00529                                 # TODO: IS this necessary?
00530                                 self.__deviceTable[int(tmp_device[0])] = tmp_device[1]
00531                                 self.__deviceTable[tmp_device[1]] = int(tmp_device[0])
00532                                 i += 1
00533 
00534                         return my_devices
00535 
00536                 except ValidationError,err:
00537                         self.__errormessage = str(err)
00538                         return False
00539                 except RuntimeError,err:
00540                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00541                         self.__errormessage = "No devices found in the selected subsystem " + str(self.__name)
00542                         return [] #none found
00543                     else:
00544                         self.__errormessage = str(err)
00545                     return False #on error                                                                                                                             
00546         ##
00547         #  Return list of device types found in the given subsystem.
00548         # 
00549         #               Parameters:
00550         #               @onlyfromdb - If true we only look for device types in the ConfDB
00551         #               @onlyfromdl - If true we only look for device types in the Dirty Objects List
00552         # 
00553         #               Only one of the parameters can be true, both can be false.
00554         # 
00555         #               !return - list of device types (string names) if successful, an empty list if none found
00556         #               and False if an error occurs,
00557         #               
00558         def GetDeviceTypes(self,onlyfromdb=False,onlyfromdl=False):
00559                                                                                                                              
00560                 try:
00561                         Validation.ValidateSystem("Active System",self.__name)
00562 
00563                         if onlyfromdb and onlyfromdl: #it is like saying, do not look anywhere
00564                                 return []
00565 
00566                         my_devicetypes = []
00567                         dirty_objs_devtypes = []
00568                         tbd = [] # = to be deleted
00569                         if not onlyfromdb: # If not only from db, we have a look in the dirty objects list if creation mode
00570                                 if GetAppWin().GetUserMode() == ID_CREATION_MODE:
00571                                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
00572                                         for obj in tmp_dirtyobjs:
00573                                                 if string.find(obj.GetSystem(),self.__name,0) != -1: # if data object is available in this system
00574                                                         if obj.__class__ == DeviceType: # IF device type
00575                                                                 if obj.GetSaveStatus() != DELETE: # if it is not set for deletion
00576                                                                         if obj.GetName() not in my_devicetypes: # and not already added to our list
00577                                                                                 my_devicetypes.append(obj.GetName()) # Add it!
00578                                                                                 dirty_objs_devtypes.append(obj.GetName())
00579                                                                 elif obj.GetSaveStatus() == DELETE: # if set for deletion
00580                                                                         if obj.GetName() in my_devicetypes: # if we already added an object of this device
00581                                                                                 #type to the list; remove it.
00582                                                                                 my_devicetypes.remove(obj.GetName())
00583                                                                                 dirty_objs_devtypes.remove(obj.GetName())
00584 
00585                                                                         tbd.append(obj.GetName()) # Object set for deletion; later if we find an object in
00586                                                                         #ConfDB with the same name, do not add it since it is set for deletion in dirty
00587                                                                         #objects list
00588 
00589                         result = cfDB.LoadDeviceTypeTable(self.__name) # Get device types in subsystem from ConfDB
00590                         
00591                         i = 0
00592                         tmp_devtypes = []
00593                         while i < len(result):
00594                                 tmp_devtypes.append(result[i].split("|")[1]) # device types given as ID|NAME
00595                                 i += 1
00596 
00597                         if not onlyfromdb and not onlyfromdl and GetAppWin().GetUserMode() == ID_CREATION_MODE:
00598                                 for obj in tmp_devtypes:
00599                                         # Do not add to list if:
00600                                         # a. already added
00601                                         # b. set for deletion in dirty objects list
00602                                         # c. the device type has changed name and already added to the list
00603                                         if obj not in dirty_objs_devtypes and obj not in tbd and obj not in GetAppWin().GetOldNames():
00604                                                 my_devicetypes.append(obj)
00605                         elif not onlyfromdl:
00606                                 for obj in tmp_devtypes:
00607                                         # Only add to list if device type has not changed name
00608                                         if obj not in GetAppWin().GetOldNames():
00609                                                 my_devicetypes.append(obj)
00610 
00611                         self.__deviceTypes = my_devicetypes
00612 
00613                         return self.__deviceTypes
00614 
00615                 except ValidationError,err:
00616                         self.__errormessage = str(err)
00617                         return False
00618                 except RuntimeError,err:
00619                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1: # No device types found in ConfDB; but we may have found some in dirty obj list
00620                         if my_devicetypes != []:
00621                                 self.__deviceTypes = my_devicetypes
00622                                 return self.__deviceTypes
00623                         else:
00624                                 self.__errormessage = "No devices types found in the selected subsystem " + str(self.__name)
00625                                 return [] #none found
00626                     else:
00627                         self.__errormessage = str(err)
00628                     return False #on error
00629 
00630         ##
00631         #  Return list of link types found in the given subsystem. (Obsolete: actually we look for link types in the LHCb system
00632         #               because there are not that many different link types).
00633         #               
00634         #               Parameters:
00635         #               @onlyfromdb - If true we only look for link types in the ConfDB
00636         #               @onlyfromdl - If true we only look for link types in the Dirty Objects List
00637         # 
00638         #               Only one of the parameters can be true, both can be false.
00639         # 
00640         #               !return - list of link types (string names) if successful, an empty list if none found
00641         #               and False if an error occurs,           
00642         #               
00643         def GetLinkTypes(self,onlyfromdb=False,onlyfromdl=False):
00644 
00645                 
00646                 try:
00647                         Validation.ValidateSystem("Active subsystem:",self.__name)
00648 
00649                         if onlyfromdb and onlyfromdl: #it is like saying, do not look anywhere
00650                                 return []
00651                 
00652                         
00653                         # Same as for GetDeviceTypes, look there for explanation.
00654                         my_linktypes = []
00655                         dirty_objs_linktypes = []
00656                         tbd = [] #to be deleted
00657                         if not onlyfromdb:
00658                                 if GetAppWin().GetUserMode() == ID_CREATION_MODE:
00659                                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
00660                                         for obj in tmp_dirtyobjs:
00661                                                 if string.find(obj.GetSystem(),self.__name,0) != -1:
00662                                                         if obj.__class__ == LinkType:
00663                                                                 if obj.GetSaveStatus() != DELETE:
00664                                                                         if obj.GetName() not in my_linktypes:
00665                                                                                 my_linktypes.append(obj.GetName())
00666                                                                                 dirty_objs_linktypes.append(obj.GetName())
00667                                                                 elif obj.GetSaveStatus() == DELETE:
00668                                                                         if obj.GetName() in my_linktypes:
00669                                                                                 my_linktypes.remove(obj.GetName())
00670                                                                                 dirty_objs_linktypes.remove(obj.GetName())
00671 
00672                                                                         tbd.append(obj.GetName())
00673 
00674                         tmp_linktypes = []
00675                         result = cfDB.LoadLinkTypeTable() #
00676                         i = 0
00677                         self.__linkTypeTable = {} #reset, so that we do not show deleted linktypes
00678                         while i < len(result):
00679                                 tmp_link = result[i].split("|") #because we get name + nr #we will use names for the user, and use nrs to save
00680 
00681                                 # Set up link type name and nr mapping..necessary? TODO.
00682                                 self.__linkTypeTable[int(tmp_link[0])] = tmp_link[1]
00683                                 self.__linkTypeTable[tmp_link[1]] = int(tmp_link[0])
00684                                 tmp_linktypes.append(tmp_link[1])
00685                                 i += 1
00686                         
00687                         GetAppWin().SetLinkTypeTable(self.__linkTypeTable) #lookup in this table on main class
00688                 
00689                         # For explanation; look in GetDeviceTypes above
00690                         if not onlyfromdb and not onlyfromdl and GetAppWin().GetUserMode() == ID_CREATION_MODE:
00691                                 for obj in tmp_linktypes:
00692                                         if obj not in dirty_objs_linktypes and obj not in tbd and obj not in GetAppWin().GetOldNames():
00693                                                 my_linktypes.append(obj)
00694                         elif not onlyfromdl:
00695                                 for obj in tmp_linktypes:
00696                                         if obj not in GetAppWin().GetOldNames():
00697                                                 my_linktypes.append(obj)
00698          
00699                         self.__linkTypes = my_linktypes
00700 
00701                         return self.__linkTypes
00702 
00703                 except ValidationError,err:
00704                         self.__errormessage = str(err)
00705                         return False
00706                 except RuntimeError,err:
00707                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1: # None found in ConfDB; but we may have something in the dirty objects list
00708                         if my_linktypes != []:
00709                                 self.__linkTypes = my_linktypes
00710                                 return self.__linkTypes
00711                         else:
00712                                 self.__errormessage = "No  link types found in the selected subsystem " + str(self.__name)
00713                                 return [] #none found
00714                     else:
00715                         self.__errormessage = str(err)
00716                     return False #on error
00717 
00718         ##
00719         # Modify an already created sub system
00720         #               
00721         def Modify(self):
00722 
00723                 return self.Create() # We will never modify systems through the GUI (can be done manually)
00724 
00725         ##
00726         #  Kind of obsolete.
00727         # 
00728         #               Sets some settings in the configuration database for a newly created subsystem in CdbVis. But this feature
00729         #               is no longer accessible for the user. Should only be done manually through editing the configuration file
00730         #               in a text editor
00731         #               
00732         def Create(self):
00733 
00734                 #TODO: exception handling for IO configuration file..if we decide to use this function
00735                 
00736                 try:
00737                         Validation.ValidateSystem("Subsystem name",self.__name)
00738                                                                                                                              
00739                         #We continue to write to config file (should also be errorchecking here)
00740                         self.__cfg.SetPath("/db/devdb/data/systems/" + self.__name)
00741                         self.__cfg.Write("created","True")
00742 
00743                         my_colour = str(self.__colour.Red()) + "," + str(self.__colour.Green()) + "," + str(self.__colour.Blue())
00744                         self.__cfg.Write("colour",my_colour)
00745 
00746                         return True
00747 
00748                 except ValidationError,err:
00749                         self.__errormessage = str(err)
00750                         return False
00751                 except DBError,err:
00752                         self.__errormessage = str(err)
00753                         return False
00754         
00755 ##
00756 #  There are several device types, and each device is of only one device type.
00757 #       A device type contains information that is common for devices of the same type.
00758 #       It is not a physical object itself.
00759 #       
00760 class DeviceType(DBInfo):
00761 
00762         ##
00763         #  Constructor.
00764         # 
00765         #               Parameters:
00766         #               @systemname - name of the subsystem(s) the device type is available in
00767         #               @deviceType - device type name set by the user; which identifies a device type
00768         #               @new        - if True, this device type is newly created, not stored in ConfDB yet
00769         #               if False, this is a device type that is already created, and hence we can retrieve
00770         #               information for the object from ConfDB or dirty objects list. That is done by calling
00771         #               the Update(...) function in the constructor.
00772         #               
00773         def __init__(self,systemname,deviceType="",new=True):
00774                 self.__errormessage = ""
00775                 self._deviceTypeInfo = {}       #all device type info that is common for all device types in this dictionary
00776                 self._deviceTypeInfo[DEV_PORTS_IN] = 0
00777                 self._deviceTypeInfo[DEV_PORTS_OUT] = 0
00778                 self._deviceTypeInfo[DEV_TYPE_DESCRIPTION] = ""
00779                 self._deviceTypeInfo[DEV_SYSTEM] = systemname
00780                 self._deviceTypeInfo[DEV_TYPE] = deviceType
00781                 self._deviceTypeInfo[DEV_TYPEID] = "" #id in ConfDB (auto number from sequence)
00782 
00783                 self._deviceTypeInfo[DEV_COLOUR] = None # wxColour object
00784                 self._deviceTypeInfo[OLD_NAME] = "" # If we renamed the object we have the previous name stored here
00785 
00786                 self.__devices = []     #a list of devices of this device type (if retrieved)
00787 
00788                 self._deviceTypeInfo[SAVE_STATUS] = NO_STATUS #NO_STATUS : not in dirty objectslist, CREATE - insert
00789                                                                #MODIFY - update, DELETE - delete, RENAME - rename
00790 
00791                 self.__cfg = GetConfig() # Get the configuration file from global method (May be not needed)
00792 
00793                 if new == False:
00794                         self.Update() #Force an update, retrieve info from db or dl
00795 
00796         ###### GET ######
00797         def GetOldName(self):
00798                 return self._deviceTypeInfo[OLD_NAME]
00799         def GetDeviceTypeID(self):
00800                 return self._deviceTypeInfo[DEV_TYPEID]
00801         def GetDeviceTable(self):
00802                 return self.__deviceTable
00803         def GetSaveStatus(self):
00804                 return self._deviceTypeInfo[SAVE_STATUS]
00805         def GetName(self):
00806                 return self._deviceTypeInfo[DEV_TYPE]
00807         def GetPortsIn(self):
00808                 return self._deviceTypeInfo[DEV_PORTS_IN]
00809         def GetPortsOut(self):
00810                 return self._deviceTypeInfo[DEV_PORTS_OUT]
00811         def GetDescription(self):
00812                 return self._deviceTypeInfo[DEV_TYPE_DESCRIPTION]
00813         def GetSystem(self):
00814                 return self._deviceTypeInfo[DEV_SYSTEM]
00815         def GetColour(self):
00816                 return self._deviceTypeInfo[DEV_COLOUR]
00817         def GetErrorMessage(self):
00818                 return self.__errormessage
00819 
00820         ###### SET ######
00821         def SetOldName(self,oldname):
00822                 self._deviceTypeInfo[OLD_NAME] = oldname
00823         def SetDeviceTypeID(self,id):
00824                 Validation.ValidateNumber("DeviceTypeID",id,0)
00825                 self._deviceTypeInfo[DEV_TYPEID] = int(id)
00826         def SetErrorMessage(self,msg):
00827                 self.__errormessage = msg
00828         def SetName(self,name):
00829                 Validation.ValidateString("devicetype name",name,100,False)
00830                 self._deviceTypeInfo[DEV_TYPE] = name
00831         def SetPortsIn(self,nbr):
00832                 Validation.ValidateNumber("nbr ports in",nbr,0,10000)
00833                 self._deviceTypeInfo[DEV_PORTS_IN] = nbr
00834         def SetPortsOut(self,nbr):
00835                 Validation.ValidateNumber("nbr ports out",nbr,0,10000)
00836                 self._deviceTypeInfo[DEV_PORTS_OUT] = nbr
00837         def SetDescription(self,descr):
00838                 Validation.ValidateString("device type description",descr,500,True)
00839                 self._deviceTypeInfo[DEV_TYPE_DESCRIPTION] = descr
00840         def SetColour(self,colour): 
00841                 #will always be a valid value/wxcolour object as the user cannot set it directly
00842                 self._deviceTypeInfo[DEV_COLOUR] = colour
00843         def SetSystem(self,name):
00844                 Validation.ValidateSystem("system name",name)
00845                 self._deviceTypeInfo[DEV_SYSTEM] = name
00846         def SetDict(self,newdict): 
00847                 # Copy all the contents of the dictionary: just like a object copy except some variables.
00848                 # This is implemented because the deepcopy of objects itself caused segmentation faults.
00849                 #self._deviceTypeInfo = copy.deepcopy(newdict)
00850                 for entry in newdict:
00851                         self._deviceTypeInfo[entry] = newdict[entry]
00852         def SetSaveStatus(self,status):
00853                 self._deviceTypeInfo[SAVE_STATUS] = status
00854         def SetDictInfo(self,dict):
00855                 # Almost the same as SetDict(...) but this is more safe. As actually use of deepcopy
00856                 # sometimes causes segmentation faults, even the one above.
00857                 for item in dict:
00858                         self._deviceTypeInfo[item] = dict[item]
00859 
00860         ##
00861         #  Get all info about a device type in a subsystem, when given the name of a device type in the constructor.
00862         #               Here we can set up to check different statuses (TODO), f.ex. if it is the most recent version of an object;
00863         #               then just return the contents; else look in dl and db.
00864         # 
00865         #               @doNotLookUp - whether we should look for more recent information in dirty objects list or ConfDB.
00866         # 
00867         #               !return - a dictionary with all the parameters set.
00868         #               
00869         def GetObjectInfo(self,doNotLookUp=True):
00870 
00871                 if doNotLookUp == True:
00872                         return self._deviceTypeInfo
00873                 else:
00874                         return self.Update()
00875 
00876         ##
00877         #  Check first in dirty objects list for most recent version of this object; if in creation mode.
00878         #               If in navigation mode or alredy looked in dirty objects list and not found; check in ConfDB.
00879         # 
00880         #               @doNotCheckInDirtyList - if True, we skip the check in the dirty list, else we check. But only in
00881         #               creation mode
00882         # 
00883         #               !return - a dictionary with all the parameters set.
00884         #               
00885         def Update(self,doNotCheckInDirtyList=False):
00886 
00887                 if not doNotCheckInDirtyList:
00888                         # Dirty Objects List
00889                         if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Creation Mode
00890                                 # We look for dirty object of same name (unique within type) and type (device type)
00891                                 tmp_obj = GetAppWin().GetDirtyObject(self._deviceTypeInfo[DEV_TYPE],DeviceType)
00892                                 if tmp_obj != False: # Found an object of same type
00893                                         self._deviceTypeInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
00894                                         return self._deviceTypeInfo # return what we found after we set it to this object
00895                 
00896                 try:
00897                     # ConfDB
00898                     Validation.ValidateString("DeviceType name",self._deviceTypeInfo[DEV_TYPE],100)
00899  
00900                     result = cfDB.GetDeviceTypeRow(self._deviceTypeInfo[DEV_TYPE]) # Get device type info from ConfDB
00901 
00902                     result = result[1:] #skip first '|' character
00903                     infolist = result.split("|")        #split string to a list; each entry is a parameter name and value
00904 
00905                     i = 0
00906                     deviceTypeInfo = {DEV_OBJECT : obj_NODE}    #To identify this as a devicenode (as opposite to a linknode)
00907                     deviceTypeInfo[DEV_SYSTEM] = self._deviceTypeInfo[DEV_SYSTEM] # Not stored in ConfDB
00908                     for i in range(len(infolist)-1):
00909                         tmp = infolist[i].split(":")    #split each property, name on left site, value on right side
00910                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
00911                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
00912                         if datatype == 'I': #integer
00913                                 tmp[1] = int(tmp[1])
00914                         elif datatype == 'C': #string
00915                                 tmp[1] = tmp[1].strip()
00916 
00917                         deviceTypeInfo[tmp0] = tmp[1]
00918                         i += 1
00919 
00920                     #convert rgbcolour to wxColour object
00921                     if deviceTypeInfo[DEV_COLOUR] in ["none","None","","(0,0,0)"]:
00922                             deviceTypeInfo[DEV_COLOUR] = GetAppWin().GetTempDeviceTypeColour(deviceTypeInfo[DEV_TYPE])
00923                     else:
00924                             rgbcolour = deviceTypeInfo[DEV_COLOUR].split(",")
00925                             deviceTypeInfo[DEV_COLOUR] = "( " + rgbcolour[0] + ", " + rgbcolour[1] + ", " + rgbcolour[2] + " )"  #wxColour(red=int(rgbcolour[0]),green=int(rgbcolour[1]),blue=int(rgbcolour[2]))
00926                 
00927                 
00928                     self._deviceTypeInfo = deviceTypeInfo
00929 
00930                     return self._deviceTypeInfo                                                                                                         
00931                                                                                                                              
00932                 except ValidationError,err:
00933                         self.__errormessage = str(err)
00934                         return False
00935                 except ValueError,err:
00936                         self.__errormessage = "Could not convert data, found wrong datatype: " + str(err)
00937                         return False
00938                 except DBError,err:
00939                         self.__errormessage = str(err)
00940                         return False
00941                 except RuntimeError,err:
00942                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00943                                 self.__errormessage = "No information found in the database on the given devicetype: " + str(self._deviceTypeInfo[DEV_TYPE])
00944                                 return {}
00945                         else:
00946                                 self.__errormessage = str(err)
00947 
00948                         return False #on error
00949 
00950         ##
00951         #  _MUON Specific_, may be changed to fit for other systems later.
00952         #               TODO: Move this to SubSystem class
00953         #               
00954         #               Given a location of a _chamber or an FEE board_, return object at given
00955         #               location with all parameters set.
00956         # 
00957         #               Parameters:
00958         #               @quadrant  - quadrant number, 1-4, where the device is located
00959         #               @chamber_x - the x position of the chamber or FE board
00960         #               @chamber_y - the y position of the chamber or FE board
00961         #               @fee_x     - the fee X position of a fee board on a chamber
00962         #               @fee_y     - the fee Y position of a fee board on a chamber
00963         #               
00964         def GetMuonDevicesByLocation(self,quadrant,chamber_x,chamber_y,fee_x="",fee_y=""):
00965 
00966                 #Location syntax: QiMjRkCxCyFExFEy
00967                 location_string = "Q" + str(quadrant) + self.GetName() + "C" + str(chamber_x) + "C" + str(chamber_y)
00968                 if fee_x != "" and fee_y != "":
00969                         location_string += "FE" + str(fee_x) + "FE" + str(fee_y)
00970                 #location_string = location_string.lower() #perhaps, perhaps not?
00971 
00972                 return self.GetDevicesByLocation(location_string) #All error handling handled in GetDevicesByLocation
00973 
00974         ##
00975         #  General get a device at a given location.
00976         #                   TODO: should also be moved to SubSystem class.
00977         #                   NB! This function does not look for devices that are not yet stored in the ConfDB.
00978         # 
00979         #                   @location_string - the location string which looks for devices with the same location
00980         #                   string set.
00981         #               
00982         def GetDevicesByLocation(self,location_string):
00983 
00984                 try:
00985 
00986                     res = cfDB.GetDeviceNamesPerLocation(location_string)
00987                     devices = res
00988 
00989                     i = 0 #reset
00990                     my_devices = []
00991                     while i < len(devices):
00992                         my_devices.append(devices[i])
00993                         i += 1
00994 
00995                     return my_devices
00996 
00997                 except RuntimeError,err:
00998                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
00999                                         self.__errormessage = "No devices found at the given location."
01000                                         return [] #none found
01001                         else:
01002                                 self.__errormessage = str(err)
01003                         return False #on error
01004         ##
01005         #  Get all _device_names_ for a given device type; each device name is unique. Looks both in 
01006         #               dirty objects list and ConfDB.
01007         #               !Return - list of device names; both in db and in dirtylist
01008         #         
01009         def GetDevices(self):
01010 
01011                 devices_in_dirtylist = []
01012                 my_devices = []
01013                 dirty_objs_devs = []
01014                 tbd = [] #to be deleted
01015                 #tbd_objs = -[]
01016                 if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Only if creation mode
01017                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
01018                         for obj in tmp_dirtyobjs:
01019                                 # If type is: DEVICE
01020                                 if obj.__class__ == Device:
01021                                         # If not set to be deleted, and that the device type is correct (this type)
01022                                         if obj.GetSaveStatus() != DELETE and obj.GetType() == self._deviceTypeInfo[DEV_TYPE]:
01023                                                 if obj.GetName() not in my_devices: # If not already added; ADD!
01024                                                         my_devices.append(obj.GetName())
01025                                                         dirty_objs_devs.append(obj.GetName())
01026                                         #if set to be deleted and correct type
01027                                         elif obj.GetSaveStatus() == DELETE and obj.GetType() == self._deviceTypeInfo[DEV_TYPE]:
01028                                                 # if already added; remove
01029                                                 if obj.GetName() in my_devices:
01030                                                         my_devices.remove(obj.GetName())
01031                                                         dirty_objs_devs.remove(obj.GetName())
01032                                                 # set to the tbd list, in case we find same device in ConfDB, but set for
01033                                                 # delete in dirty objects list
01034                                                 tbd.append(obj.GetName())
01035 
01036                 #First check if this device type has been renamed, cause the name in DB will be the prev one:
01037                 if self.GetName() in GetAppWin().GetNewNames():
01038                         old_name = GetAppWin().GetOldNamesOfRenamed()[self.GetName()]
01039                 else:
01040                         old_name = self._deviceTypeInfo[DEV_TYPE]
01041                         
01042                 try:
01043                     Validation.ValidateSystem("System Name",self._deviceTypeInfo[DEV_SYSTEM])
01044                                           
01045                     tmp = cfDB.GetDeviceNamesPerType(old_name)
01046                         
01047                     devices = tmp                                                                                                                    
01048                     i = 0 #reset
01049                     if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Need to do some checks if creation mode
01050                         while i < len(devices):
01051                                 dev_tmp = devices[i].split("|")
01052                                 # do add to list if:
01053                                 # a. not already added
01054                                 # b. not set for deletion
01055                                 # c. not already added under a new name (renamed)
01056                                 if (dev_tmp[0] not in dirty_objs_devs) and (dev_tmp[0] not in tbd) and dev_tmp[0] not in GetAppWin().GetOldNames():
01057                                         my_devices.append(str(dev_tmp[0]))
01058                                 i += 1
01059 
01060 
01061                     else: #navigation mode
01062                         while i < len(devices):
01063                                         dev_tmp = devices[i].split("|")
01064                                         if  dev_tmp[0] not in GetAppWin().GetOldNames(): #TODO: this is wrong? do not need 
01065                                                                                         #to do this in navigation mode?
01066                                                 my_devices.append(str(dev_tmp[0]))
01067                                                 i += 1
01068 
01069                     self.__devices = my_devices
01070                                 
01071                     return self.__devices
01072 
01073                 except ValidationError,err:
01074                         self.__errormessage = str(err)
01075                         return False
01076                 except DBError,err:
01077                         self.__errormessage = str(err)
01078                         return False
01079                 except RuntimeError,err:
01080                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01081                                 if len(my_devices) == 0:
01082                                         self.__errormessage = "No devices found for the given device type " + str(self._deviceTypeInfo[DEV_TYPE])
01083                                         return [] #none found
01084                                 else: #none found in db, but we found in dirty list
01085                                         self.__devices = my_devices
01086                                         return self.__devices
01087                         else:
01088                                 self.__errormessage = str(err)
01089                         return False #on error
01090         ##
01091         #  Get all _sparedevice_names_ for a given device type; each device name is unique. Looks both in 
01092         #               dirty objects list and ConfDB.
01093         #               
01094         #               !Return - list of device names; both in db and in dirtylist
01095         #               
01096         def GetSpareDevices(self):  #should be called only for spare devices
01097 
01098                 devices_in_dirtylist = []
01099                 my_devices = []
01100                 dirty_objs_devs = []
01101                 tbd = [] #to be deleted
01102                 #tbd_objs = -[]
01103                 if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Only if creation mode
01104                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
01105                         for obj in tmp_dirtyobjs:
01106                                 # If type is: DEVICE
01107                                 if obj.__class__ == Device:
01108                                         # If not set to be deleted, and that the device type is correct (this type)
01109                                         if obj.GetSaveStatus() != DELETE and obj.GetType() == self._deviceTypeInfo[DEV_TYPE]:
01110                                                 if obj.GetName() not in my_devices: # If not already added; ADD!
01111                                                         my_devices.append(obj.GetName())
01112                                                         dirty_objs_devs.append(obj.GetName())
01113                                         #if set to be deleted and correct type
01114                                         elif obj.GetSaveStatus() == DELETE and obj.GetType() == self._deviceTypeInfo[DEV_TYPE]:
01115                                                 # if already added; remove
01116                                                 if obj.GetName() in my_devices:
01117                                                         my_devices.remove(obj.GetName())
01118                                                         dirty_objs_devs.remove(obj.GetName())
01119                                                 # set to the tbd list, in case we find same device in ConfDB, but set for
01120                                                 # delete in dirty objects list
01121                                                 tbd.append(obj.GetName())
01122 
01123                 #First check if this device type has been renamed, cause the name in DB will be the prev one:
01124                 if self.GetName() in GetAppWin().GetNewNames():
01125                         old_name = GetAppWin().GetOldNamesOfRenamed()[self.GetName()]
01126                 else:
01127                         old_name = self._deviceTypeInfo[DEV_TYPE]
01128                         
01129                 try:
01130                     Validation.ValidateSystem("System Name",self._deviceTypeInfo[DEV_SYSTEM])
01131                                           
01132                     tmp = cfDB.GetSpareHWPerType(old_name)
01133                         
01134                     devices = tmp                                                                                                                    
01135                     i = 0 #reset
01136                     if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Need to do some checks if creation mode
01137                         while i < len(devices):
01138                                 dev_tmp = devices[i].split("|")
01139                                 # do add to list if:
01140                                 # a. not already added
01141                                 # b. not set for deletion
01142                                 # c. not already added under a new name (renamed)
01143                                 if (dev_tmp[0] not in dirty_objs_devs) and (dev_tmp[0] not in tbd) and dev_tmp[0] not in GetAppWin().GetOldNames():
01144                                         my_devices.append(str(dev_tmp[0]))
01145                                 i += 1
01146 
01147 
01148                     else: #navigation mode
01149                         while i < len(devices):
01150                                         dev_tmp = devices[i].split("|")
01151                                         if  dev_tmp[0] not in GetAppWin().GetOldNames(): #TODO: this is wrong? do not need 
01152                                                                                         #to do this in navigation mode?
01153                                                 my_devices.append(str(dev_tmp[0]))
01154                                                 i += 1
01155 
01156                     self.__devices = my_devices
01157                                 
01158                     return self.__devices
01159 
01160                 except ValidationError,err:
01161                         self.__errormessage = str(err)
01162                         return False
01163                 except DBError,err:
01164                         self.__errormessage = str(err)
01165                         return False
01166                 except RuntimeError,err:
01167                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01168                                 if len(my_devices) == 0:
01169                                         self.__errormessage = "No devices found for the given device type " + str(self._deviceTypeInfo[DEV_TYPE])
01170                                         return [] #none found
01171                                 else: #none found in db, but we found in dirty list
01172                                         self.__devices = my_devices
01173                                         return self.__devices
01174                         else:
01175                                 self.__errormessage = str(err)
01176                         return False #on error
01177 
01178 
01179         ##
01180         #  A function that returns the string to the function that will be called in the
01181         #               ConfDBLibrary for the given save and modify status of this data object, as well as
01182         #               use of single or multiple insert.
01183         # 
01184         #               Parameters:
01185         #               Same as for Save(...)
01186         # 
01187         #               !return - returns a String with the function name as well as all set parameters
01188         #               
01189         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
01190                 
01191                 save_status = self._deviceTypeInfo[SAVE_STATUS]
01192                 my_colour = str(self._deviceTypeInfo[DEV_COLOUR][0]) + "," + str(self._deviceTypeInfo[DEV_COLOUR][1]) + "," + str(self._deviceTypeInfo[DEV_COLOUR][2])
01193                 if save_status == CREATE:
01194                         if insertmany:
01195                                 return 'cfDB.InsertMultipleDeviceType("%s","%s",%i,%i,"%s","%s",%i,%i)' \
01196                                         %(str(self._deviceTypeInfo[DEV_SYSTEM]),str(self._deviceTypeInfo[DEV_TYPE]),self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],str(self._deviceTypeInfo[DEV_TYPE_DESCRIPTION]),str(my_colour),first,commit)
01197                                         
01198                         else:
01199                                 print '1 : "%s"'%str(self._deviceTypeInfo[DEV_SYSTEM])
01200                                 print '2 : "%s"'%str(self._deviceTypeInfo[DEV_TYPE])
01201                                 print '3 : %i'%self._deviceTypeInfo[DEV_PORTS_IN]
01202                                 print '4 : %i'%self._deviceTypeInfo[DEV_PORTS_OUT]
01203                                 print '5 : "%s"'%str(self._deviceTypeInfo[DEV_TYPE_DESCRIPTION])
01204                                 print '6 : "%s"'%str(my_colour)
01205                                 print '7 : %i'%first
01206                                 print '8 : %i'%commit
01207                                 #print 'cfDB.InsertDeviceType("%s","%s",%i,%i,"%s","%s",%i)'%(str(self._deviceTypeInfo[DEV_SYSTEM]),str(self._deviceTypeInfo[DEV_TYPE]),self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],str(self._deviceTypeInfo[DEV_TYPE_DESCRIPTION]),str(my_colour),first,commit)
01208                                 return 'cfDB.InsertDeviceType("%s","%s",%i,%i,"%s","%s",%i)' \
01209                                         %(str(self._deviceTypeInfo[DEV_SYSTEM]),str(self._deviceTypeInfo[DEV_TYPE]),self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],str(self._deviceTypeInfo[DEV_TYPE_DESCRIPTION]),str(my_colour),first) #,commit)
01210 
01211                 elif save_status == MODIFY:
01212                         #modify_status = self._deviceTypeInfo[MODIFY_STATUS]
01213                         return 'cfDB.UpdateMultipleDeviceTypeAttributes("%s","%s",%i,%i,"%s",%i,%i)' \
01214                                 %(str(self._deviceTypeInfo[DEV_TYPE]),str(self._deviceTypeInfo[DEV_TYPE_DESCRIPTION]),self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],str(my_colour),first,commit)
01215         
01216                 elif save_status == DELETE:
01217                     return 'cfDB.DeleteFunctionalDeviceType("%s")'\
01218                            %s(str(self._deviceTypeInfo[DEV_TYPE]))
01219                 
01220                 elif save_status == RENAME:
01221                                 return 'cfDB.UpdateMultipleDeviceTypes("%s","%s",%i,%i)' \
01222                                 %(str(self._deviceTypeInfo[OLD_NAME]),str(self._deviceTypeInfo[DEV_TYPE]),first,commit)
01223 
01224                 else: #invalid status
01225                         return ""
01226 
01227         ##
01228         #  Save the changes made on this object in the ConfDB;
01229         #               deletion, modification/update or insertion of the object in the database.
01230         #               The methods Delete, Modify and Create only set/change the variables in this object, 
01231         #               this method makes things happen in the db (committed)
01232         # 
01233         #               Parameters:
01234         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
01235         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
01236         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
01237         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
01238         #               insert function will be used, which is optimized for multiple inserts (use of cache)
01239         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
01240         #               commit is set to true, all data that are put on hold in the cache will be commited.
01241         #               
01242         def Save(self,first=False,insertmany=False,commit=True):
01243 
01244                 try:
01245                         if self._deviceTypeInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE,RENAME]:
01246                                 raise RuntimeError,"Wrong save status set, can not do any database action on: " + str(self.GetName())
01247 
01248 
01249                         if self._deviceTypeInfo[SAVE_STATUS] == DELETE:
01250                                 Validation.ValidateString("Device Type name",self._deviceTypeInfo[DEV_TYPE],100)
01251                                 
01252                         if self._deviceTypeInfo[SAVE_STATUS] == CREATE or self._deviceTypeInfo[SAVE_STATUS] == MODIFY:
01253                                 Validation.ValidateSystem("Saving devicetype, system name",self._deviceTypeInfo[DEV_SYSTEM])
01254                                 Validation.ValidateString("Device Type name",self._deviceTypeInfo[DEV_TYPE],100)
01255                                 Validation.ValidateNumber("Nbr ports in",self._deviceTypeInfo[DEV_PORTS_IN],0,10000)
01256                                 Validation.ValidateNumber("Nbr ports out",self._deviceTypeInfo[DEV_PORTS_OUT],0,10000)
01257                                 Validation.ValidateString("Device Type Description",self._deviceTypeInfo[DEV_TYPE_DESCRIPTION],500,True)
01258                                 my_colour = str(self._deviceTypeInfo[DEV_COLOUR][0]) + "," + str(self._deviceTypeInfo[DEV_COLOUR][1]) + "," + str(self._deviceTypeInfo[DEV_COLOUR][2])
01259                         if self._deviceTypeInfo[SAVE_STATUS] == RENAME:
01260                                 Validation.ValidateString("Device Type name",self._deviceTypeInfo[DEV_TYPE],100)
01261 
01262                         if self._deviceTypeInfo[SAVE_STATUS] == CREATE:
01263                                 if insertmany:
01264                                         success = cfDB.InsertMultipleDeviceType(self._deviceTypeInfo[DEV_SYSTEM],self._deviceTypeInfo[DEV_TYPE],self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],self._deviceTypeInfo[DEV_TYPE_DESCRIPTION],my_colour,first,commit)
01265                                 else:
01266                                         success = cfDB.InsertDeviceType(self._deviceTypeInfo[DEV_SYSTEM],self._deviceTypeInfo[DEV_TYPE],self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],self._deviceTypeInfo[DEV_TYPE_DESCRIPTION],my_colour,commit)
01267 
01268                                 # If an error occurs, an exception will be thrown.
01269                                 if commit: #has to be commited before added to db
01270                                         self.Update(True) #retrieve new data from database, also new devicetypeid
01271 
01272                         elif self._deviceTypeInfo[SAVE_STATUS] == MODIFY:
01273                                 success = cfDB.UpdateMultipleDeviceTypeAttributes(self._deviceTypeInfo[DEV_TYPE],self._deviceTypeInfo[DEV_TYPE_DESCRIPTION],self._deviceTypeInfo[DEV_PORTS_IN],self._deviceTypeInfo[DEV_PORTS_OUT],my_colour,first,commit)
01274                                 if commit: #has to be commited before added to db
01275                                         self.Update(True) #retrieve new data from database, also new devicetypeid
01276                                 
01277                         elif self._deviceTypeInfo[SAVE_STATUS] == DELETE:
01278                                 success=cfDB.DeleteFunctionalDeviceType(self._deviceTypeInfo[DEV_TYPE])
01279                                 
01280                         elif self._deviceTypeInfo[SAVE_STATUS] == RENAME:
01281                                 success = cfDB.UpdateMultipleDeviceTypes(self._deviceTypeInfo[OLD_NAME],self._deviceTypeInfo[DEV_TYPE],first,commit)
01282                                 # No update needed, but TODO: update names in visual window on devices affected.
01283 
01284                         return True
01285 
01286                 except ValidationError,err:
01287                         self.__errormessage = str(err)
01288                         return False
01289                 except DBError,err:
01290                         self.__errormessage = str(err)
01291                         return False
01292                 except RuntimeError,err: #error on insertion
01293                         self.__errormessage = str(err)
01294                         return False
01295 
01296         ##
01297         #  Delete this object. This object is put in the dirty list and set for deletion. 
01298         #               Sets the save status to deletion.
01299         #               
01300         def Delete(self):
01301                 
01302                 self._deviceTypeInfo[SAVE_STATUS] = DELETE
01303                 GetAppWin().AddToDirtyObjects(self) #possible to send an instance of itself?
01304 
01305         ##
01306         #  Modifies a device type with new values set by the user through the set functions. The modify status
01307         #               is set through SetModifyStatus(...) if needed.
01308         #               Sets the save status to modify, and adds the object to the dirty objects list.
01309         #               
01310         def Modify(self):
01311                 self._deviceTypeInfo[SAVE_STATUS] = MODIFY
01312                 GetAppWin().AddToDirtyObjects(self)
01313 
01314         ##
01315         #  Create a device type. Set save status to creation, and adds the object to the
01316         #               dirty objects list.
01317         #               
01318         def Create(self):
01319                 
01320                 self._deviceTypeInfo[SAVE_STATUS] = CREATE
01321                 GetAppWin().AddToDirtyObjects(self)
01322         
01323 ##
01324 # Class for storing information about a device. A device is a physical device in the LHCb
01325 #       detector that is usually connected to other devices with links.
01326 #       
01327 class Device(DBInfo):
01328 
01329         ##
01330         #  Constructor.
01331         # 
01332         #               Parameters:
01333         #               @systemname - the subsystem(s) the device will be a part of (stored in)
01334         #               @devicename - the unique name of the device, given by the user
01335         #               @new        - whether the device is about to be created, or is already created.
01336         #               True if it is being created, False if not. If it is already created, we will
01337         #               fill the object with goods. (names and values)
01338         #               
01339         def __init__(self,systemname,deviceName="",new=True):
01340                 
01341                 self.__errormessage = ""
01342 
01343                 self._deviceInfo = {}   #all device info that is common for all devices
01344                 self._deviceInfo[DEV_OBJECT] = obj_NODE
01345                 self._deviceInfo[DEV_SYSTEM] = systemname
01346                 self._deviceInfo[DEV_NAME] = deviceName
01347                 self._deviceInfo[DEV_ID] = "" # unique ID set in ConfDB
01348 
01349                 self._deviceInfo[DEV_PORTS_IN] = 0
01350                 self._deviceInfo[DEV_PORTS_OUT] = 0
01351                 self._deviceInfo[DEV_TYPE] = "" #name of the device type it is
01352                 self._deviceInfo[DEV_NODE] = 0 # node or not; a node is a device at one of the ends of a path
01353                 self._deviceInfo[DEV_PROMMODE] = 0 #promoscous mode..
01354                 self._deviceInfo[DEV_SERIAL] = "" # serial number
01355                 self._deviceInfo[DEV_HWTYPE] = "" # hardware type
01356                 self._deviceInfo[DEV_RESPONSIBLE] = "" # responsible for the device
01357                 self._deviceInfo[DEV_LOCATION] = "" # location string
01358                 self._deviceInfo[DEV_COMMENTS] = "" # comments/description
01359                 self._deviceInfo[DEV_COLOUR] = (255, 255, 255) #wxColour(255,255,255)
01360                 self._deviceInfo[OLD_NAME] = "" # if device has been renamed, we store the old/previous name here
01361                 self._deviceInfo[DEV_FUNCTION]="none" #added by Lana, function of the device
01362                 # We need to keep track of some parameters; whether they have been changed when the user modified the object
01363                 # or not because we have different modify functions for different parameters.
01364                 self._deviceInfo[NODE_CHANGED] = 0 #set to 1 if DEV_NODE was changed; 
01365                                                     #if changed all paths have to be recalculated in ConfDB Library.
01366                 self._deviceInfo[SYSTEM_CHANGED] = 0
01367                 self._deviceInfo[MODIFY_STATUS] = NO_STATUS #0 - standard modify, 1 - change system list, NO_STATUS: not set
01368 
01369                 self._deviceInfo[SAVE_STATUS] = NO_STATUS
01370 
01371                 self.__deviceType = None #devicetype object
01372                 self.__ports = [] # ports retrieved, of this device
01373                 self.__links = [] # links retrieved, to/from this device
01374                 self.__cfg = GetConfig() # configuration file reference
01375 
01376                 self.__listofpaths = {} # paths this device is a part of
01377 
01378                 if new == False:
01379                         self.Update()
01380                         self.UpdateDeviceType()
01381 
01382         ### GET ###
01383         def GetModifyStatus(self):
01384                 return self._deviceInfo[MODIFY_STATUS]
01385         def GetComments(self):
01386                 return self._deviceInfo[DEV_COMMENTS]
01387         def GetLocation(self):
01388                 return self._deviceInfo[DEV_LOCATION]
01389         def GetResponsible(self):
01390                 return self._deviceInfo[DEV_RESPONSIBLE]
01391         def GetHWType(self):
01392                 return self._deviceInfo[DEV_HWTYPE]
01393         def GetSerial(self):
01394                 return self._deviceInfo[DEV_SERIAL]
01395         def GetOldName(self):
01396                 return self._deviceInfo[OLD_NAME]
01397         def GetSaveStatus(self):
01398                 return self._deviceInfo[SAVE_STATUS] #set INSERT, DELETE and UPDATE as constants
01399         def GetName(self):
01400                 return self._deviceInfo[DEV_NAME]
01401         def GetID(self):
01402                 return self._deviceInfo[DEV_ID]
01403         def GetType(self):
01404                 return self._deviceInfo[DEV_TYPE]
01405         #added by Lana
01406         def GetDeviceFunction(self):
01407                 return self._deviceInfo[DEV_FUNCTION]
01408         def GetNode(self):
01409                 return self._deviceInfo[DEV_NODE]
01410         def GetPromMode(self):
01411                 return self._deviceInfo[DEV_PROMMODE]
01412         def GetSystem(self):
01413                 return self._deviceInfo[DEV_SYSTEM]
01414         def GetColour(self):
01415                 return self._deviceInfo[DEV_COLOUR]
01416         def GetTheDict(self):
01417                 return self._deviceInfo
01418         def GetErrorMessage(self):
01419                 return self.__errormessage
01420         def IsSystemChanged(self):
01421                 return self._deviceInfo[SYSTEM_CHANGED]
01422         def IsNodeChanged(self):
01423                 return self._deviceInfo[NODE_CHANGED]
01424 
01425         # DevType properties
01426         def GetPortsIn(self):
01427                 return self._deviceInfo[DEV_PORTS_IN]
01428         def GetPortsOut(self):
01429                 return self._deviceInfo[DEV_PORTS_OUT]
01430         def GetTypeDescription(self):
01431                 return self._deviceInfo[DEV_TYPE_DESCRIPTION]
01432 
01433         # Other
01434         def GetSavedFreePorts(self):
01435                 return (self.totalp,self.inp,self.outp)
01436 
01437         def GetURL(self,update=False):
01438                 if not update:
01439                         return self._deviceInfo[DEV_URL]
01440                 else:           
01441                         cfDB2.execute("SELECT url FROM LHCB_DEVICES_URL WHERE DEVICENAME='"+self._deviceInfo[DEV_NAME]+"' ")
01442                         res = cfDB2.fetchone()
01443                         if res:
01444                                 return res[0]
01445                         else:
01446                                 return None
01447         ### SET ###
01448         def SetPortsOut(self,nbr):
01449                 self._deviceInfo[DEV_PORTS_OUT]=nbr
01450                 
01451         def SetPortsIn(self,nbr):
01452                 self._deviceInfo[DEV_PORTS_IN]=nbr
01453 
01454         def GetPortsOut(self):
01455                 return self._deviceInfo[DEV_PORTS_OUT]
01456         def SetURL(self,url):
01457                 self._deviceInfo[DEV_URL]=url
01458         def SetModifyStatus(self,status):
01459                 self._deviceInfo[MODIFY_STATUS] = status
01460         def SetComments(self,comments):
01461                 Validation.ValidateString("User comments",comments,1000,True)
01462                 self._deviceInfo[DEV_COMMENTS] = comments
01463         def SetLocation(self,location):
01464                 Validation.ValidateString("Location",location,200,True)
01465                 self._deviceInfo[DEV_LOCATION] = location
01466         def SetResponsible(self,responsible):
01467                 Validation.ValidateString("Responsible",responsible,100,True)
01468                 self._deviceInfo[DEV_RESPONSIBLE] = responsible
01469         def SetFunction(self,function):
01470                 Validation.ValidateString("Function",function,100,True)
01471                 self._deviceInfo[DEV_FUNCTION] = function
01472         def SetHWType(self,hwtype):
01473                 Validation.ValidateString("Hardware type",hwtype,200,True)
01474                 self._deviceInfo[DEV_HWTYPE] = hwtype
01475         def SetSerial(self,serial):
01476                 Validation.ValidateString("Serial number",serial,500)
01477                 self._deviceInfo[DEV_SERIAL] = serial
01478         def SetOldName(self,oldname):
01479                 self._deviceInfo[OLD_NAME] = oldname
01480         def SetSaveStatus(self,state):
01481                 self._deviceInfo[SAVE_STATUS] = state
01482         def SetName(self,name):
01483                 Validation.ValidateString("Device name",name,100,False)
01484                 self._deviceInfo[DEV_NAME] = name
01485         def SetID(self,id):
01486                 self._deviceInfo[DEV_ID] = id #not set by user, given in db
01487         def SetErrorMessage(self,msg):
01488                 self.__errormessage = msg
01489         ##
01490         #  Sets the device type of this device.
01491         # 
01492         #               @devtype - the unique device type name
01493         #               @update - whether we also should update this devices dictionary with
01494         #               device type parameters (ports, colour)
01495         #               
01496         def SetType(self,devtype,update=True):
01497                 #TODO: check if there is exception handling in the calling code for this method
01498                 try:
01499                         Validation.ValidateString("Device type",devtype,100,False)
01500                         self._deviceInfo[DEV_TYPE] = devtype
01501 
01502                         if update:
01503                                 tmp_devtype = DeviceType(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_TYPE],False)
01504 
01505                                 self._deviceInfo[DEV_PORTS_IN] = tmp_devtype.GetPortsIn()
01506                                 self._deviceInfo[DEV_PORTS_OUT] = tmp_devtype.GetPortsOut()
01507                                 self._deviceInfo[DEV_TYPE_DESCRIPTION] = tmp_devtype.GetDescription()
01508                                 self._deviceInfo[DEV_COLOUR] = tmp_devtype.GetColour()
01509 
01510                         return True
01511                                 
01512                 except ValidationError,err:
01513                         self.__errormessage = str(err)
01514                         return False
01515 
01516         ##
01517         #  We check whether the user changed the value of the node property.
01518         #               @node - the value of the node property
01519         #               @changed - if the node property was changed set to True, False otherwise
01520         #               
01521         def SetNode(self,node,changed=True):
01522                 Validation.ValidateNumber("Node?",node,0,1)
01523                 if changed:
01524                         self._deviceInfo[NODE_CHANGED] = 1
01525                 self._deviceInfo[DEV_NODE] = node
01526         def SetPromMode(self,prommode):
01527                 Validation.ValidateNumber("Promiscuous mode",prommode,0,1)
01528                 self._deviceInfo[DEV_PROMMODE] = prommode
01529         def SetSystem(self,system,changed=True):
01530                 Validation.ValidateSystem("System",system)
01531                 self._deviceInfo[DEV_SYSTEM] = system
01532                 if changed:
01533                         self._deviceInfo[SYSTEM_CHANGED] = 1
01534 
01535         def SetDict(self,newdict):
01536                 for entry in newdict:
01537                         self._deviceInfo[entry] = newdict[entry]
01538                 #self._deviceInfo = copy.deepcopy(newdict)
01539 
01540         ##
01541         #  Copy device info from one device to another (this one).
01542         #               
01543         def SetAllInfoDict(self,devinfo):
01544                 my_name = self._deviceInfo[DEV_NAME]
01545                 my_id = self._deviceInfo[DEV_ID]
01546                 self._deviceInfo = {}
01547                 for item in devinfo:
01548                         self._deviceInfo[item] = devinfo[item]
01549                 self._deviceInfo[DEV_NAME] = my_name
01550                 if my_id != "":
01551                         self._deviceInfo[DEV_ID] = my_id
01552 
01553         ##
01554         #  If we need to update the information about the device type this device is, we use this method.
01555         #               The method fills the property dictionary with device type parameters and values.
01556         #               
01557         def UpdateDeviceType(self):
01558                 
01559                 tmp_devtype = DeviceType(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_TYPE],False)
01560 
01561                 self._deviceInfo[DEV_PORTS_IN] = tmp_devtype.GetPortsIn()
01562                 self._deviceInfo[DEV_PORTS_OUT] = tmp_devtype.GetPortsOut()
01563                 self._deviceInfo[DEV_TYPE_DESCRIPTION] = tmp_devtype.GetDescription()
01564                 self._deviceInfo[DEV_COLOUR] = tmp_devtype.GetColour()
01565 
01566         ##
01567         #  Get all info about a device in a subsystem, given the unique name of a device.
01568         #               
01569         #               Here we do some check where to get the properies information from, f.ex. whether
01570         #               this device object is the most recent object in dirty list; if so we can just return
01571         #               this objects dictionary. TODO.
01572         # 
01573         #               @doNotLookUp - whether we should look for information about this object in dirty objects
01574         #               list and ConfDB (False) or not(True).
01575         #               
01576         def GetObjectInfo(self,doNotLookUp=True):
01577                 if doNotLookUp == True:
01578                         return self._deviceInfo
01579                 else:
01580                         self.Update()
01581                         self.UpdateDeviceType()
01582                         
01583                 return self._deviceInfo
01584 
01585         ##
01586         #  Here we update the device with the most recent information about the device witht the
01587         #               given information; either in dirty objects list (if found and in creation mode), or from
01588         #               ConfDB.
01589         # 
01590         #               @doNotCheckInDirtyList - if True, we do not check in dirty objects list, but go straight
01591         #               forward to the ConfDB and look for information about this device there.
01592         #               
01593         def Update(self,doNotCheckInDirtyList=False):
01594         
01595                 # Dirty Objects List
01596                 if not doNotCheckInDirtyList:
01597                         ##if GetAppWin().GetUserMode() == ID_CREATION_MODE:
01598                         tmp_obj = GetAppWin().GetDirtyObject(self._deviceInfo[DEV_NAME],Device)
01599                         if tmp_obj != False:
01600                                 self._deviceInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
01601                                 return self._deviceInfo
01602                 # ConfDB
01603                 try:
01604                         Validation.ValidateString("Device name",self._deviceInfo[DEV_NAME],100)
01605                         result = cfDB.GetDeviceRow_devicename(self._deviceInfo[DEV_NAME])
01606 
01607                         result = result[1:]     #skip first | character
01608                         infolist = result.split("|")    #split string in list
01609                         i = 0
01610                         deviceInfo = {DEV_OBJECT : obj_NODE}    #To identify this as a devicenode (as opposite to a linknode)
01611                         deviceInfo[DEV_SYSTEM] = self._deviceInfo[DEV_SYSTEM]   #should be retrieved from db? IS retrieved from db!!
01612                         deviceInfo[DEV_COLOUR] = "(255, 255, 255)" #wxColour(red=255,green=255,blue=255) #changed to device type
01613                         deviceInfo[NODE_CHANGED] = 0
01614                         deviceInfo[SYSTEM_CHANGED] = 0
01615                         deviceInfo[DEV_HWTYPE] = ""
01616                         deviceInfo[DEV_RESPONSIBLE] = ""
01617                         deviceInfo[DEV_FUNCTION] = ""
01618                         deviceInfo[DEV_COMMENTS] = ""
01619                         deviceInfo[MODIFY_STATUS] = NO_STATUS
01620                         deviceInfo[DEV_URL] = ""
01621                 
01622                         for i in range(len(infolist)-1):
01623                                 tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
01624                                 tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
01625                                 datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
01626                                 if datatype == 'I': #integer
01627                                         tmp[1] = int(tmp[1])
01628                                 elif datatype == 'C': #string
01629                                         tmp[1] = tmp[1].strip()
01630                                 deviceInfo[tmp0] = tmp[1]
01631                                 i += 1
01632                                 
01633                         # Get the URL of the web page associated to our device
01634                         # Added By Walid, Here we will not use the ConfDBpython  and we will connect directely to the database
01635                         DBSystem.cfDB2.execute("SELECT url FROM LHCB_DEVICES_URL WHERE DEVICENAME='"+self._deviceInfo[DEV_NAME]+"' ")
01636                         res = cfDB2.fetchone()
01637                         if res:
01638                                 deviceInfo[DEV_URL] = res[0]
01639 
01640                         '''### Added by Walid   
01641                         try:
01642                                 result = cfDB.GetHWDeviceRow_serialnb(deviceInfo[DEV_SERIAL]) # Get device type info from ConfDB
01643                                 if result:
01644                                     result = result[1:] #skip first '|' character
01645                                     infolist = result.split("|")        #split string to a list; each entry is a parameter name and value
01646 
01647                                     i = 0
01648                                     for i in range(len(infolist)-1):
01649                                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
01650                                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
01651                                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
01652                                         if datatype == 'I': #integer
01653                                                 tmp[1] = int(tmp[1])
01654                                         elif datatype == 'C': #string
01655                                                 tmp[1] = tmp[1].strip()
01656                                         deviceInfo[tmp0] = tmp[1]
01657                                         i += 1
01658                                 
01659                         except:
01660                                 print "Unable to update HW part"
01661                         #########'''
01662                                 
01663                         self._deviceInfo = deviceInfo
01664                         
01665 
01666                         # If device type has been renamed and not stored in ConfDB yet
01667                         if self._deviceInfo[DEV_TYPE] in GetAppWin().GetOldNames():
01668                                 self._deviceInfo[DEV_TYPE] = GetAppWin().GetNewNamesOfRenamed()[self._deviceInfo[DEV_TYPE]]
01669 
01670                         self.UpdateDeviceType() #colour, ports etc
01671                         
01672                         return self._deviceInfo
01673                                                                                                                              
01674                 except ValidationError,err:
01675                     self.__errormessage = str(err)
01676                     return False
01677                 except DBError,err:
01678                     self.__errormessage = str(err)
01679                     return False
01680                 except RuntimeError,err:
01681                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01682                         self.__errormessage = "No information found in the database on the given device: " + str(self._deviceInfo[DEV_NAME])
01683                         return {}
01684                     else:
01685                         self.__errormessage = str(err)
01686                         return False #on error
01687 
01688         ##
01689         #  Method to check whether the device has any connections at all to other devices.
01690         #               If this is true (all ports are free, no connections to other devices), the given device 
01691         #               can be deleted, else it can not. 
01692         # 
01693         #               !return - True if all ports are free, -1 if not all are free.
01694         #               False if an error occurs
01695         #               
01696         def IsAllPortsFree(self):
01697 
01698                 try:
01699                         freeports,free_in,free_out = self.GetFreePorts()
01700 
01701                         if freeports == False and free_in == False and free_out == False:
01702                                 raise RuntimeError,"An error occured when checking the ports for this device: " + str(self.GetErrorMessage())
01703 
01704                         devtype_tmp = DeviceType(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_TYPE],False)
01705                         nr_of_ports = devtype_tmp.GetPortsIn() + devtype_tmp.GetPortsOut()
01706 
01707                         if freeports != nr_of_ports:
01708                                 return -1
01709                         
01710                         return True
01711 
01712                 except ValidationError,err:
01713                     self.__errormessage = str(err)
01714                     return False
01715                 except DBError,err:
01716                     self.__errormessage = str(err)
01717                     return False
01718                 except RuntimeError,err:
01719                     self.__errormessage = str(err)
01720                     return False #on error
01721 
01722         ##
01723         #  Nr of ports on a device is nr of input + nr of output for the given device type it is.
01724         #               We find all the taken ports; subtract them from the list of all ports; and return the list
01725         #               of free ports (actually as a 3-tuple; number of free ports in total, and then 1 list for each
01726         #               direction; IN and OUT)
01727         # 
01728         #               !return - 3 tuple:
01729         #               integer    - number of free ports in total
01730         #               list *port name* - a list of port numbers that are free; TO the device
01731         #               list *port name* - a list of port numbers that are free; FROM the device
01732         # 
01733         #               False is returned if an error occurs
01734         #               
01735         def GetFreePorts(self):
01736 
01737                 try:
01738                         devtype_tmp = DeviceType(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_TYPE],False)
01739                         free_ports_in = devtype_tmp.GetPortsIn()
01740                         free_ports_out = devtype_tmp.GetPortsOut()
01741                         nr_of_ports = free_ports_in + free_ports_out
01742 
01743 
01744                         #First we look for links connected to the current device object in the dirty objects list
01745                         my_links = [] #link objects
01746                         dirty_objs_links = [] #link names
01747                         tbd = [] #to be deleted
01748                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
01749                                 tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
01750                                 for obj in tmp_dirtyobjs:
01751                                         if obj.__class__ == Link:
01752                                                 if obj.GetSaveStatus() != DELETE:
01753                                                         if obj.GetNodeFrom() == self._deviceInfo[DEV_NAME] or obj.GetNodeTo() == self._deviceInfo[DEV_NAME]:
01754                                                                 if obj.GetName() in dirty_objs_links:
01755                                                                         i = 0
01756                                                                         for lnk in my_links:
01757                                                                                 if lnk.GetName() == obj.GetName(): #if name in list already, overwrite cause this is newer
01758                                                                                         my_links.pop(i)
01759                                                                                 i += 1
01760                                                                                         
01761                                                                 my_links.append(obj)
01762                                                                 dirty_objs_links.append(obj.GetName())
01763                                                 else: # if DELETE status
01764                                                         tbd.append(obj.GetName())
01765 
01766                                 #if any links set for deletion, it does not count as a link any more, 
01767                                 #remove previous create/modify info for this link connection
01768                                 i = 0
01769                                 for obj in my_links:
01770                                         if obj.GetName() in tbd:
01771                                                 my_links.pop(i)
01772                                         else:
01773                                                 i += 1
01774 
01775                         # If the ID is set..it can be found in ConfDB, then we look there; if not we skip looking in ConfDB
01776                         if self._deviceInfo[DEV_ID] != "": 
01777                                 try:
01778                                         tmp1 = cfDB.GetLkFromDevID(self._deviceInfo[DEV_ID])
01779                                 except RuntimeError,err:
01780                                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01781                                                 tmp1 = [] #none found
01782         
01783                                 try:
01784                                         tmp2 = cfDB.GetLkToDevID(self._deviceInfo[DEV_ID])
01785                                 except RuntimeError,err:
01786                                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01787                                                 tmp2 = [] #none found
01788                                 
01789                                 #temporary list of linknames (IDs)
01790                                 #It is necessary to do it as below because the garbage collector will collect 
01791                                 #the tmp1 and tmp2 right after retrieval        
01792                                 links = []
01793                                 i = 0
01794                                 while i < len(tmp1):
01795                                         links.append(tmp1[i])
01796                                         i += 1
01797                                 i = 0
01798                                 while i < len(tmp2):
01799                                         links.append(tmp2[i])
01800                                         i += 1
01801 
01802                                 #add link objects to my_links from ConfDB, if not set for deletion or modified in dl
01803                                 i = 0
01804                                 if GetAppWin().GetUserMode() == ID_CREATION_MODE:
01805                                         while i < len(links):
01806                                                 my_tmp_link = str(links[i]) #convert to string, because all linksnames (IDs)
01807                                                                             #are converted to strings in dl
01808                                                 if my_tmp_link not in dirty_objs_links and my_tmp_link not in tbd:
01809                                                         link_tmp = Link(self._deviceInfo[DEV_SYSTEM],my_tmp_link,reverseLink=False,new=False)   #create link object
01810                                                         my_links.append(link_tmp)
01811                                                 i += 1
01812                                 else:
01813                                         while i < len(links):
01814                                                 link_tmp = Link(self._deviceInfo[DEV_SYSTEM],str(links[i]),reverseLink=False,new=False) #create link object
01815                                                 my_links.append(link_tmp)
01816                                                 i += 1
01817 
01818 
01819                         #Add names of taken ports to a list
01820                         takenports_in = []
01821                         takenports_out = []
01822                         for lnk in my_links:
01823                                 if lnk.GetNodeFrom() == self.GetName():
01824                                         tmp_port = lnk.GetNodeFrom() + ": " + lnk.GetPortFrom() + " : " + lnk.GetPortTypeFrom() + " : " + "OUT"
01825                                         takenports_out.append(tmp_port)
01826                                 elif lnk.GetNodeTo() == self.GetName():
01827                                         tmp_port = lnk.GetNodeTo() + ": " + lnk.GetPortTo() + " : " + lnk.GetPortTypeTo() + " : " + "IN"
01828                                         takenports_in.append(tmp_port)
01829 
01830 
01831                         # Now we will have to find all port names available on this device, 
01832                         # and then subtract the taken ones found above
01833                         portlist = self.GetPorts() #finds all port objects belonging to the current device
01834 
01835                         # If no ports found or wrong number; error, cause ports should be created on device creation
01836                         if portlist == []:
01837                                 raise RuntimeError,"Found that no ports are created for this device, cannot continue."
01838                         elif len(portlist) != nr_of_ports:
01839                                 #raise RuntimeError,"Found that an incorrect number of ports are created for this device, all the ports must always be created when a device is created."
01840                                 GetAppWin().ShowError("An incorrect number of ports are created for this device; either too many or too few considering the port number given for the device type, as a cause of this the result of the action may not be what you expect.",ERR_INFORMATION)
01841 
01842                         #Find free ports, for both in and out
01843                         freeports_in = []
01844                         freeports_out = []
01845                         for port in portlist:
01846                                 if port.GetPortWay() == 1: #1 IN, 2 OUT
01847                                         if port.GetName() not in takenports_in:
01848                                                 freeports_in.append(port.GetPortNbr() + " : " + port.GetPortType())
01849                                 else: # == 2
01850                                         if port.GetName() not in takenports_out:
01851                                                 freeports_out.append(port.GetPortNbr() + " : " + port.GetPortType())
01852                         
01853                         free_ports_total = len(freeports_in) + len(freeports_out) #number of free ports
01854                         self.totalp = free_ports_total
01855                         self.inp = freeports_in #list of names of free input ports
01856                         self.outp = freeports_out #list of names of free output ports
01857 
01858                         return (free_ports_total,freeports_in,freeports_out)
01859 
01860                 except ValidationError,err:
01861                     self.__errormessage = str(err)
01862                     return False,False,False
01863                 except DBError,err:
01864                     self.__errormessage = str(err)
01865                     return False,False,False
01866                 except RuntimeError,err:
01867                     self.__errormessage = str(err)
01868                     return False,False,False
01869 
01870         ### GetLinks ###
01871         ##
01872         #  Get all links (objects) that start or end in the given device.
01873         # 
01874         #               Parameters:
01875         #                 @nodefrom - if nodefrom is set to true, then all links that start (FROM) in the given device is returned
01876         #               if nodefrom is set to false, then all links that end (TO) in the given device is returned
01877         #                 
01878         #               !return - a list of link objects that either start or end at the current device.
01879         #               
01880         def GetLinks(self,nodefrom=True):
01881                 links_in_dirtylist = []
01882                 my_links = []
01883                 dirty_objs_links = []
01884                 tbd = [] #to be deleted
01885                 tbd_objs = []
01886                 if GetAppWin().GetUserMode() == ID_CREATION_MODE:
01887                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
01888                         for obj in tmp_dirtyobjs:
01889                                 if obj.__class__ == Link:
01890                                         if GetAppWin().IsLinkTypeRestricted():
01891                                                 if obj.GetType() != GetAppWin().GetRestrictedLinkType():
01892                                                         continue #skip this link, check next
01893                                         if obj.GetSaveStatus() != DELETE:
01894                                                 if (nodefrom == True and obj.GetNodeFrom() == self._deviceInfo[DEV_NAME]) or (nodefrom == False and obj.GetNodeTo() == self._deviceInfo[DEV_NAME]):
01895                                                         if obj.GetName() in dirty_objs_links:
01896                                                                 i = 0
01897                                                                 for lnk in my_links:
01898                                                                         if lnk.GetName() == obj.GetName():
01899                                                                                 my_links.pop(i)
01900                                                                         i += 1
01901                                                                 
01902                                                         my_links.append(obj)
01903                                                         dirty_objs_links.append(obj.GetName())
01904                                                 else:   
01905                                                         links_in_dirtylist.append(obj.GetName())
01906                                         elif obj.GetSaveStatus() == DELETE: # We delete instances before the delete object
01907                                                 # We do not delete instances after the delete of course
01908                                                 # Remember that a modify of link connection (node or port from or to) 
01909                                                 # is actually a DELETE+CREATE
01910                                                 i = 0
01911                                                 while i < len(my_links):
01912                                                         if my_links[i].GetName() == obj.GetName():
01913                                                                 my_links.pop(i)
01914                                                         else:
01915                                                                 i += 1
01916                                                 tbd.append(obj.GetName())
01917                                 elif obj.__class__ == Device: #to handle deleted devices
01918                                         if obj.GetSaveStatus() == DELETE: #set for deletion
01919                                                 tbd_objs.append(obj)
01920 
01921                 try:
01922                     Validation.ValidateSystem("DeviceClickGetLinkIDs",self._deviceInfo[DEV_SYSTEM])
01923                     
01924                     if not self._deviceInfo[DEV_ID]: # We need to set device ID to get links from ConfDB
01925                         raise RuntimeError, str("NO_ROWS_SELECTED") # pretend as if we didnt get any rows from db
01926 
01927                     if nodefrom:
01928                         tmp = cfDB.GetLkFromDevID(self._deviceInfo[DEV_ID])
01929                     else:
01930                         tmp = cfDB.GetLkToDevID(self._deviceInfo[DEV_ID])
01931                     links = tmp                                                                                                     
01932                     if links[0] == -1 and links[1] == -1:
01933                         raise DBError, "Error retrieving information about the links from the given device."
01934                     else:
01935                         i = 0
01936 
01937                         if GetAppWin().GetUserMode() == ID_CREATION_MODE: #Creation mode
01938                                 if nodefrom:    name = "Loading Output links..."
01939                                 else:   name = "loading Input links..."
01940                                 progress=QProgressDialog(name, "Abort", len(links), GetAppWin(), "progress", True) #Progress dialog
01941                                 while i < len(links):
01942                                         progress.setProgress(i)
01943                                         if progress.wasCanceled():      
01944                                                 break
01945                                         my_tmplink = str(links[i]) #convert int linkid to string linkid!!
01946                                         if my_tmplink not in dirty_objs_links and my_tmplink not in tbd and my_tmplink not in links_in_dirtylist:
01947                                                 link_tmp = Link(self._deviceInfo[DEV_SYSTEM],my_tmplink,reverseLink=False,new=False)    #create link object
01948 
01949                                                 if link_tmp.GetNodeFrom() in tbd_objs:
01950                                                         raise DBError,"The link " + str(link_tmp) + " is connected to the deleted device " + str(link_tmp.GetNodeFrom())
01951                                                 elif link_tmp.GetNodeTo() in tbd_objs:
01952                                                         raise DBError,"The link " + str(link_tmp) + " is connected to the deleted device " + str(link_tmp.GetNodeTo())
01953                                                 
01954                                                 if GetAppWin().IsLinkTypeRestricted(): # Only get links of set link type
01955                                                         if link_tmp.GetType() != GetAppWin().GetRestrictedLinkType():
01956                                                                 i += 1
01957                                                                 continue # check next link, because of wrong link type
01958                                                         
01959                                                 my_links.append(link_tmp)
01960                                         i += 1
01961                                 progress.setProgress(len(links))
01962                         else: # Navigation mode
01963                                 while i < len(links):
01964                                         my_tmplink = str(links[i])
01965                                         link_tmp = Link(self._deviceInfo[DEV_SYSTEM],my_tmplink,reverseLink=False,new=False)
01966                                         if GetAppWin().IsLinkTypeRestricted(): # Only link of set link type
01967                                                 if link_tmp.GetType() != GetAppWin().GetRestrictedLinkType():
01968                                                         i += 1
01969                                                         continue # check next link, because wrong link type
01970                                                 
01971                                         my_links.append(link_tmp)
01972                                         i += 1
01973                         #for tst in my_links:
01974                         #print "Link found: " + str(tst.GetName())
01975                         self.__links = my_links
01976                         return self.__links
01977                 except ValidationError,err:
01978                     self.__errormessage = str(err)
01979                     return False
01980                 except DBError,err:
01981                     self.__errormessage = str(err)
01982                     return False
01983                 except RuntimeError,err:
01984                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
01985                         if my_links == []:
01986                                 self.__errormessage = "No links found for the selected device " + str(self._deviceInfo[DEV_NAME])
01987                                 return [] #none found
01988                         else: #didnt find links in db, but we found in dirty list
01989                                 self.__links = my_links
01990                                 return self.__links
01991                     else:
01992                         self.__errormessage = str(err)
01993                     return False #on error
01994 
01995         ##
01996         #  Get all portids of the current device. This is the IDs set automatically
01997         #               to ports in the ConfDB. Usually used as a helper function to GetPorts(...).
01998         # 
01999         #               !return - list of portIDs (ints) of ports on this device
02000         #               
02001         def GetPortIDs(self):
02002                                                                                                                              
02003                 try:
02004                     Validation.ValidateNumber("DeviceID",self._deviceInfo[DEV_ID],0)
02005                                                                                                                              
02006                     tmp = cfDB.GetPortIDPerDevID(self._deviceInfo[DEV_ID])
02007                                                                                                                              
02008                     ports = tmp
02009                     i = 0
02010                     portlist = []
02011                     while i < len(ports):
02012                         portlist.append(ports[i])
02013                         i += 1
02014 
02015                     return portlist
02016                                                                                                                              
02017                 except ValidationError,err:
02018                     self.__errormessage = str(err)
02019                     return False
02020                 except DBError,err:
02021                     self.__errormessage = str(err)
02022                     return False
02023                 except RuntimeError,err:
02024                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
02025                                 self.__errormessage = "No ports found for the selected device " + str(self._deviceInfo[DEV_NAME])
02026                                 return [] #none found
02027                     else:
02028                         self.__errormessage = str(err)
02029                     return False #on error
02030 
02031         ##
02032         #  Get all ports assigned to a device as port objects in a list.
02033         #               Look for ports in both dirty objects list and ConfDB.
02034         # 
02035         #               !return - list of port objects for the ports of a device.
02036         #               
02037         def GetPorts(self):
02038 
02039                 # 1. Get all ports assigned to this device in dirty objects list; if in creation mode
02040                 # 2. Get all portIDs assigned to this device from ConfDB; filter out those that were already found in dirty
02041                 # objects list
02042                 # 3. Retrieve all info for each port; from ConfDB or dirty objects list.
02043                 # 4. Return the port objects in a list.
02044 
02045                 try:
02046                         my_ports = [] #port objects
02047                         dirty_objs_ports = [] #port names
02048                         tbd = [] #names on ports to be deleted
02049 
02050                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
02051                                 print "Check"
02052                                 tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
02053                                 for obj in tmp_dirtyobjs:
02054                                         if obj.__class__ == Port:
02055                                                 if obj.GetDevice() == self.GetName(): #port of this device
02056                                                         if obj.GetSaveStatus() != DELETE:
02057                                                                 if obj.GetName() in dirty_objs_ports:
02058                                                                         i = 0
02059                                                                         for port in my_ports:
02060                                                                                 if port.GetName() == obj.GetName():
02061                                                                                         # Newer version found; replace
02062                                                                                         my_ports.pop(i)
02063                                                                                 i += 1
02064                                                                                                 
02065                                                                 my_ports.append(obj)
02066                                                                 dirty_objs_ports.append(obj.GetName())
02067                                                         else: #found port that is set to deleted, look for identical in dl
02068                                                                 print "infodel: " + str(obj.GetObjectInfo(True))
02069                                                                 print "Deleted obj: " + str(obj.GetName())
02070                                                                 if obj.GetName() in dirty_objs_ports:
02071                                                                         # del port found, del port if found in dirty objs
02072                                                                         i = 0
02073                                                                         while i < len(my_ports):
02074                                                                                 if my_ports[i].GetName() == obj.GetName():
02075                                                                                         my_ports.pop(i)
02076                                                                                         break
02077                                                                                 i += 1
02078                                                                                 
02079                                                                 tbd.append(obj.GetName())
02080 
02081                         # We do not have to check whether this device has been renamed or not because
02082                         # we retrieve ports in the ConfDB by looking for ports assigned to the deviceID
02083                         # which will never change.
02084 
02085                         if self.GetID() == "" or self.GetID() == -1:
02086                                 self._deviceInfo[DEV_ID] = cfDB.GetDeviceID_devicename(self.GetName()) 
02087                                 #if this fails we do not have this device in ConfDB, and thus not any ports either.
02088                         if self._deviceInfo[DEV_ID] == -1:
02089                                 if self._deviceInfo[DEV_NAME] in GetAppWin().GetNewNames():
02090                                         tmp_name = GetAppWin().GetOldNamesOfRenamed()[self._deviceInfo[DEV_NAME]]
02091                                         self._deviceInfo[DEV_ID] = cfDB.GetDeviceID_devicename(tmp_name)
02092                                         
02093                         if self._deviceInfo[DEV_ID] != -1:
02094                                 portids = self.GetPortIDs()
02095                                 if portids == False:
02096                                         raise RuntimeError,str(self.GetErrorMessage())
02097 
02098                                 for port in portids:
02099                                         tmp_port = Port(self.GetSystem(),"","",PORT_IN,"",True) #will not update
02100                                         tmp_port.SetPortID(port)
02101                                         tmp_port.UpdateByPortID()
02102 
02103                                         if tmp_port.GetName() not in dirty_objs_ports and tmp_port.GetName() not in tbd: 
02104                                                 #in case we have a newer version in the dirty objects list
02105                                                 #or the port is set to be deleted in dl
02106                                                 my_ports.append(tmp_port)
02107                                                 
02108                         self.__ports = my_ports
02109                         return self.__ports
02110 
02111                 except ValidationError,err:
02112                     self.__errormessage = str(err)
02113                     return False
02114                 except DBError,err:
02115                     self.__errormessage = str(err)
02116                     return False
02117                 except RuntimeError,err:
02118                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
02119                         if my_ports == []:
02120                                 self.__errormessage = "No ports found for the selected device " + str(self._deviceInfo[DEV_NAME])
02121                                 return [] #none found
02122                         else: #didnt find ports in db, but we found in dirty list
02123                                 self.__ports = my_ports
02124                                 return self.__ports
02125                     else:
02126                         self.__errormessage = str(err)
02127                     return False #on error #NB! Change when error is fixed in DB moduel !!!!!
02128 
02129         ##
02130         #  Get all the paths this device is a part of. We set the paths found to a
02131         #               member variable dictionary, and what we return is actually a list with 
02132         #               descriptions (start and end nodes) of each path. Each index in this list
02133         #               corresponds to an entry in the member variable dictionary we have set.
02134         #               
02135         #               !return - a list with string description of each path
02136         #               
02137         def GetPaths(self):
02138                 
02139                 try:
02140                         Validation.ValidateSystem("Systemname",self._deviceInfo[DEV_SYSTEM])
02141                         progress=QProgressDialog( "Loading paths from the ConfDB...", "Abort", 2, GetAppWin(), "progress", True) #Progress dialog
02142                         #Paths for a given device
02143                         result = cfDB.GetAllPathsPerDevice(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_NAME],1,1)
02144                         del progress
02145                         # First we collect all info in a list of lists, integers instead of strings etc.
02146                         # For information of what this ConfDB Library returns (syntax etc), look in the ConfDB Library
02147                         # documentation.
02148                         i = 0
02149                         #pathof0s = []
02150                         pathlisttmp = {}
02151                         nrofpaths = 0           #number of paths, not included the first 0 part
02152                         #nrof0s = 0             #number of common parts of a path for all the paths
02153                         lastpathid = -1
02154                         
02155                         while i < len(result):
02156                                 #print "Path: " + str(result[i])
02157                                 pathtmp = result[i].split("|")
02158                                 pathtmp[0] = int(pathtmp[0])
02159                                 pathtmp[1] = int(pathtmp[1])
02160                                 pathtmp[2] = int(pathtmp[2])
02161 
02162                                 #if pathtmp[0] == 0:
02163                                 #       pathof0s.append(pathtmp[2])
02164                                 #       nrof0s += 1
02165                                 #else:
02166                                 if pathtmp[0] != lastpathid:
02167                                         pathlisttmp[pathtmp[0]] = []
02168 
02169                                 pathlisttmp[pathtmp[0]].append(pathtmp[2])
02170 
02171                                 if pathtmp[0] != lastpathid: # and pathtmp[0] != 0:
02172                                         nrofpaths += 1
02173 
02174                                 i += 1
02175                                 lastpathid = pathtmp[0]
02176 
02177                         # how many alternative paths will we have to choose from for this device
02178                         nrofpathsintotal = nrofpaths #* nrof0s 
02179 
02180                         pathdict = {}
02181                         j = 1
02182                         #for path0 in pathof0s: #walk through the 0 paths
02183                         for path in pathlisttmp:
02184                                 pathdict[j] = []
02185                                 #pathdict[j].append(path0)
02186                                 pathdict[j].append(pathlisttmp[path])
02187                                 pathdict[j] = flatten(pathdict[j]) #the flatten function in helper
02188                                 j += 1
02189                         
02190                         if j == 1:
02191                                 self.__listofpaths = pathlisttmp
02192                         else:
02193                                 self.__listofpaths = pathdict
02194                                 
02195 
02196                         # self.__listofpaths = {1: [-212,-232], 2: [232,-232], ... } # dict with pathid, then linkids in path
02197 
02198                         # Find first and last node for each path
02199                         # Connections given the linkid (every link between two devices has a linkid)
02200                         # TODO: This should be done in GetSpecificPathInfo()
02201                         result = cfDB.LoadConnectivityTable(self._deviceInfo[DEV_SYSTEM])
02202                         j = 0
02203                         linkstmp = {} #dictionary of lists
02204                         while j < len(result):
02205                                 linktmp = result[j].split("|")
02206                                 linkstmp[int(linktmp[0])] = linktmp #search key indexed on linkid
02207                                 j += 1
02208 
02209                         # the user will see strings in the pathlist with the first and last nodes in the path
02210                         userpathlist = [] 
02211                         
02212                         for path in self.__listofpaths:
02213                                 mystring = ""
02214                                 tmparray = self.__listofpaths[path]
02215                                 
02216                                 # from-node
02217                                 if tmparray[0] < 0:
02218                                         mystring1 = linkstmp[-tmparray[0]][2]
02219                                 else:
02220                                         mystring1 = linkstmp[tmparray[0]][1]
02221                                         
02222                                 # to-node
02223                                 if tmparray[-1] < 0:
02224                                         mystring2 = linkstmp[-tmparray[-1]][1]
02225                                 else:
02226                                         mystring2 = linkstmp[tmparray[-1]][2]
02227 
02228                                 mystring1 = cfDB.GetDeviceName_deviceid(int(mystring1))
02229                                 if mystring1 == -1:
02230                                         raise DBError,"The Device name was not found in the database."
02231                                 mystring2 = cfDB.GetDeviceName_deviceid(int(mystring2))
02232                                 if mystring2 == -1:
02233                                         raise DBError,"The Device name was not found in the database."
02234                                 
02235                                 mystring = mystring1 + " --> " + mystring2 + " (" + str(len(tmparray)) + ")" 
02236 
02237                                 userpathlist.append(mystring)
02238                         
02239                         return userpathlist
02240                         #return self.__listofpaths
02241                         
02242                 except ValidationError,err:
02243                     self.__errormessage = str(err)
02244                     return False
02245                 except DBError,err:
02246                     self.__errormessage = str(err)
02247                     return False
02248                 except RuntimeError,err:
02249                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
02250                         self.__errormessage = "No paths found for the selected device " + str(self._deviceInfo[DEV_NAME])
02251                         return [] #none found
02252                     else:
02253                         self.__errormessage = str(err)
02254                     print self.__errormessage
02255                     return False #on error
02256                         
02257         ##
02258         #  Return all path information necessary to display a path for a given path(ID).
02259         #               
02260         #               A path from the list of paths for a device was selected; the entry index of that list
02261         #               corresponds to entries in our member variable dictionary.
02262         # 
02263         #               Parameters:
02264         #               @pathid - the ID of the path chosen to get path information for. The path ID is the index
02265         #               of the entry in the list returned by the GetPaths(...) function.
02266         # 
02267         #               !return - an ordered list of member variable dictionaries for the devices in the given path.
02268         #               
02269         def GetSpecificPathInfo(self,pathid):
02270                 try:
02271                         if self.__listofpaths == {}:
02272                                 self.GetPaths()
02273 
02274                         # We need to get information about the connections in this system
02275                         # TODO: We cannot load the whole connectivity table every time!!!
02276                         # Alt. 1: Fill a list with the info, and use that on second retrieval
02277                         # Alt. 2: Only find necessary info on some given links
02278                         #result = cfDB.LoadConnectivityTable(self._deviceInfo[DEV_SYSTEM])
02279                         
02280                         #j = 0
02281                         #links = {} #dictionary of lists of links (connectivity information)
02282                         #while j < len(result):
02283                         #linktmp = result[j].split("|")
02284                         #links[int(linktmp[0])] = linktmp #search key on linkid
02285                         #j += 1
02286                         
02287 
02288                         linkdevinfolist = []
02289                         linksadded = []
02290                         my_path = self.__listofpaths[pathid] #the pathid set in the parameter list
02291                         print "Path: " + str(my_path)
02292                         # We will then set up each link/device in this path, and return it.
02293                         for link in my_path:
02294                                 my_reverseLink = False
02295                                 # if a linkID is negative; it means that the data flow is in the opposite direction
02296                                 # of what you get from the ConfDB; reversed link
02297                                 if link < 0: 
02298                                         link *= -1
02299                                         my_reverseLink = True
02300                                 
02301                                 link_tmp = Link(self._deviceInfo[DEV_SYSTEM],link,reverseLink=my_reverseLink,new=False)
02302                                 devinfotmp = link_tmp.GetObjectInfo(True)
02303                                 devinfotmp["reversed"] = my_reverseLink
02304                                 
02305                                 # we dont want to draw the same link two times; bidirectional links are retrieved two times
02306                                 # from the ConfDB
02307                                 if link not in linksadded: 
02308                                         #bidirectional link
02309                                         linkdevinfolist.append(devinfotmp) #objects
02310                                         linksadded.append(link)
02311                                         
02312                         return linkdevinfolist
02313                 
02314                 except ValidationError,err:
02315                     self.__errormessage = str(err)
02316                     return False
02317                 except DBError,err:
02318                     self.__errormessage = str(err)
02319                     return False
02320                 except RuntimeError,err:
02321                     self.__errormessage = str(err)
02322                     return False #on error
02323             
02324         ##
02325         #  A function that returns the string to the function that will be called in the
02326         #               ConfDBLibrary for the given save and modify status of this data object, as well as
02327         #               use of single or multiple insert.
02328         # 
02329         #               Parameters:
02330         #               Same as for Save(...)
02331         # 
02332         #               !return - returns a String with the function name as well as all set parameters
02333         #               
02334         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
02335         
02336                 save_status = self._deviceInfo[SAVE_STATUS]
02337         
02338                 if save_status == CREATE:
02339                         if insertmany:
02340                                 tofile = 'cfDB.InsertMultipleFunctionalDevices("%s","%s","%s",%i,%i,"%s","%s","%s","%s","%s","%s",%i,%i)' \
02341                                 %(str(self._deviceInfo[DEV_SYSTEM]),str(self._deviceInfo[DEV_NAME]),str(self._deviceInfo[DEV_TYPE]),int(self._deviceInfo[DEV_NODE]),int(self._deviceInfo[DEV_PROMMODE]),str(self._deviceInfo[DEV_SERIAL]),str(self._deviceInfo[DEV_HWTYPE]),str(self._deviceInfo[DEV_RESPONSIBLE]),str(self._deviceInfo[DEV_LOCATION]),str(self._deviceInfo[DEV_COMMENTS]),str(self._deviceInfo[DEV_FUNCTION]),first,commit)
02342                         else:
02343                                 tofile = 'cfDB.InsertFunctionalDevice("%s","%s","%s",%i,%i,"%s","%s","%s","%s","%s","%s",%i)' \
02344                                 %(str(self._deviceInfo[DEV_SYSTEM]),str(self._deviceInfo[DEV_NAME]),str(self._deviceInfo[DEV_TYPE]),self._deviceInfo[DEV_NODE],self._deviceInfo[DEV_PROMMODE],str(self._deviceInfo[DEV_SERIAL]),str(self._deviceInfo[DEV_HWTYPE]),str(self._deviceInfo[DEV_RESPONSIBLE]),str(self._deviceInfo[DEV_LOCATION]),str(self._deviceInfo[DEV_COMMENTS]),str(self._deviceInfo[DEV_FUNCTION]),commit)
02345                         
02346                         if self._deviceInfo[DEV_URL]!="":
02347                                 tofile += '\ncfDB2.execute(\"INSERT INTO LHCB_DEVICES_URL (DEVICENAME, URL) VALUES (\''+self._deviceInfo[DEV_NAME]+'\',\''+self._deviceInfo[DEV_URL]+'\') \")\n'
02348                         return tofile
02349                         
02350                 elif save_status == MODIFY:
02351                         modify_status = self._deviceInfo[MODIFY_STATUS]
02352                         
02353                         if modify_status == 0: # Change Node
02354                                 try:
02355                                         if self._deviceInfo[NODE_CHANGED] == 1:
02356                                                 node = self._deviceInfo[DEV_NODE]
02357                                         else:
02358                                                 node = -1
02359                                 except KeyError,err:
02360                                         node = -1
02361 
02362                                 #devicename, node, promiscuous_mode, location, function_list, frist, commit
02363                                 tofile = 'cfDB.UpdateMultipleAttributesDevices("%s",%i,%i,"%s","%s",%i,%i)' \
02364                                 %(str(self._deviceInfo[DEV_NAME]),node,self._deviceInfo[DEV_PROMMODE],str(self._deviceInfo[DEV_LOCATION]),"none",first,commit)
02365                                 tofile += '\ncfDB2.execute(\"UPDATE LHCB_DEVICES_URL SET URL=\''+self._deviceInfo[DEV_URL]+'\' WHERE DEVICENAME=\''+self._deviceInfo[DEV_NAME]+'\' \")'
02366                                 return tofile
02367                                 
02368                         elif modify_status == 1: # Change System
02369                                 return '\ncfDB.UpdateMultipleDeviceSystemList("%s","%s",%i,%i)' \
02370                                 %(str(self._deviceInfo[DEV_NAME]),str(self._deviceInfo[DEV_SYSTEM]),first,commit)
02371 
02372                 elif save_status == DELETE:
02373                         tofile = 'cfDB.DeleteFunctionalDevice("%i")'\
02374                         %(int(self._deviceInfo[DEV_ID]))
02375                         tofile += '\ncfDB2.execute(\"DELETE FROM LHCB_DEVICES_URL WHERE DEVICENAME=\''+self._deviceInfo[DEV_NAME]+'\' \")'
02376                         return tofile
02377                         
02378                 elif save_status == RENAME:
02379                         tofile = 'cfDB.UpdateMultipleDevNamesDevices("%s","%s",%i,%i)' \
02380                         %(str(self._deviceInfo[OLD_NAME]),str(self._deviceInfo[DEV_NAME]),first,commit)
02381                         tofile += '\ncfDB2.execute(\"UPDATE LHCB_DEVICES_URL SET DEVICENAME=\''+self._deviceInfo[DEV_NAME]+'\' WHERE DEVICENAME=\''+self._deviceInfo[OLD_NAME]+'\' \")'
02382                         return tofile
02383                         
02384                 else: #invalid status
02385                         return ""
02386 
02387 
02388         ##
02389         #  Update changes to the ConfDB for this object.
02390         # 
02391         #               Parameters:
02392         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
02393         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
02394         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
02395         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
02396         #               insert function will be used, which is optimized for multiple inserts (use of cache)
02397         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
02398         #               commit is set to true, all data that are put on hold in the cache will be commited.
02399         #               
02400         def Save(self,first=False,insertmany=False,commit=True):
02401                 try:
02402                         if self._deviceInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE,RENAME]:
02403                                 raise ValidationError,"This object should not be in the dirty list or has incorrect savestatus setting"
02404 
02405                         if self._deviceInfo[SAVE_STATUS] == RENAME:
02406                                 Validation.ValidateString("Device name",self._deviceInfo[DEV_NAME],100)
02407 
02408                         if self._deviceInfo[SAVE_STATUS] == CREATE or self._deviceInfo[SAVE_STATUS] == MODIFY:
02409                                 Validation.ValidateSystem("Create Device",self._deviceInfo[DEV_SYSTEM])
02410                                 Validation.ValidateNumber("Node",self._deviceInfo[DEV_NODE],0,1)
02411                                 Validation.ValidateNumber("Promiscous mode",self._deviceInfo[DEV_PROMMODE],0,1)
02412                                 Validation.ValidateString("Device name",self._deviceInfo[DEV_NAME],100)
02413                                 # TODO: Check that the device type exists in the ConfDB?
02414                                 Validation.ValidateString("Device type",self._deviceInfo[DEV_TYPE],100)
02415                                 Validation.ValidateString("Serial number",self._deviceInfo[DEV_SERIAL],500)
02416                                 Validation.ValidateString("Hardware type",self._deviceInfo[DEV_HWTYPE],200,True)
02417                                 Validation.ValidateString("Responsible",self._deviceInfo[DEV_RESPONSIBLE],100,True)
02418                                 Validation.ValidateString("Location",self._deviceInfo[DEV_LOCATION],200,True)
02419                                 Validation.ValidateString("Comments",self._deviceInfo[DEV_COMMENTS],1000,True)
02420                                 Validation.ValidateString("Function",self._deviceInfo[DEV_FUNCTION],100,True)
02421 
02422                         if self._deviceInfo[SAVE_STATUS] == CREATE:
02423                                 if insertmany:
02424                                         success = cfDB.InsertMultipleFunctionalDevices(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_NAME],self._deviceInfo[DEV_TYPE],self._deviceInfo[DEV_NODE],self._deviceInfo[DEV_PROMMODE],self._deviceInfo[DEV_SERIAL],self._deviceInfo[DEV_HWTYPE],self._deviceInfo[DEV_RESPONSIBLE],self._deviceInfo[DEV_LOCATION],self._deviceInfo[DEV_COMMENTS],self._deviceInfo[DEV_FUNCTION],first,commit)
02425                                 else:
02426                                         print (self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_NAME],self._deviceInfo[DEV_TYPE],self._deviceInfo[DEV_NODE],self._deviceInfo[DEV_PROMMODE],self._deviceInfo[DEV_SERIAL],self._deviceInfo[DEV_HWTYPE],self._deviceInfo[DEV_RESPONSIBLE],self._deviceInfo[DEV_LOCATION],self._deviceInfo[DEV_COMMENTS],self._deviceInfo[DEV_FUNCTION],commit)
02427                                         success = cfDB.InsertFunctionalDevice(self._deviceInfo[DEV_SYSTEM],self._deviceInfo[DEV_NAME],self._deviceInfo[DEV_TYPE],self._deviceInfo[DEV_NODE],self._deviceInfo[DEV_PROMMODE],self._deviceInfo[DEV_SERIAL],self._deviceInfo[DEV_HWTYPE],self._deviceInfo[DEV_RESPONSIBLE],self._deviceInfo[DEV_LOCATION],self._deviceInfo[DEV_COMMENTS],self._deviceInfo[DEV_FUNCTION],commit)
02428                                 
02429                                 # Add entry in the LHCB_DEVICES_URL:
02430                                 if success and self._deviceInfo[DEV_URL]!="":
02431                                         cfDB2.execute("INSERT INTO LHCB_DEVICES_URL (DEVICENAME, URL) VALUES ('"+self._deviceInfo[DEV_NAME]+"','"+self._deviceInfo[DEV_URL]+"') ")
02432                                 if commit:
02433                                         oracle.commit()
02434                                         self.Update(True)
02435 
02436                         elif self._deviceInfo[SAVE_STATUS] == MODIFY:
02437                                 if self._deviceInfo[MODIFY_STATUS] == 0: # Change Node
02438                                         try:
02439                                                 if self._deviceInfo[NODE_CHANGED] == 1:
02440                                                         node = self._deviceInfo[DEV_NODE]
02441                                                 else:
02442                                                         node = -1
02443                                         except KeyError,err:
02444                                                 node = -1
02445                                         print "DEBUG MSG : cfDB.UpdateMultipleAttributesDevices",(self._deviceInfo[DEV_NAME],node,self._deviceInfo[DEV_PROMMODE],self._deviceInfo[DEV_LOCATION],'none',first,commit)
02446                                         success = cfDB.UpdateMultipleAttributesDevices(self._deviceInfo[DEV_NAME],node,self._deviceInfo[DEV_PROMMODE],self._deviceInfo[DEV_LOCATION],'none',first,commit)
02447                                         dev_url = self.GetURL(True);
02448                                         # Added by walid
02449                                         if success:
02450                                                 if dev_url and dev_url!=self._deviceInfo[DEV_URL]:
02451                                                         cfDB2.execute("UPDATE LHCB_DEVICES_URL SET URL='"+self._deviceInfo[DEV_URL]+"' WHERE DEVICENAME='"+self._deviceInfo[DEV_NAME]+"' ")
02452                                                 elif not dev_url and self._deviceInfo[DEV_URL]!="":
02453                                                         cfDB2.execute("INSERT INTO LHCB_DEVICES_URL (DEVICENAME, URL) VALUES ('"+self._deviceInfo[DEV_NAME]+"','"+self._deviceInfo[DEV_URL]+"') ")
02454                                                 
02455                                         if commit:
02456                                                 oracle.commit()
02457                                                 self._deviceInfo[NODE_CHANGED] = 0
02458                                                 self.Update(True)
02459                                                 
02460                                 elif self._deviceInfo[MODIFY_STATUS] == 1: # Change System
02461 
02462                                         success = cfDB.UpdateMultipleDeviceSystemList(self._deviceInfo[DEV_NAME],self._deviceInfo[DEV_SYSTEM],first,commit) #first and commit
02463 
02464                         elif self._deviceInfo[SAVE_STATUS] == RENAME:
02465                                 success = cfDB.UpdateMultipleDevNamesDevices(self._deviceInfo[OLD_NAME],self._deviceInfo[DEV_NAME],first,commit)
02466                                 if commit:
02467                                         self.Update(True)
02468                                 # Added by walid
02469                                 if success:
02470                                         dev_url = self.GetURL(True);
02471                                         if dev_url:
02472                                                 cfDB2.execute("UPDATE LHCB_DEVICES_URL SET DEVICENAME='"+self._deviceInfo[DEV_NAME]+"' WHERE DEVICENAME='"+self._deviceInfo[OLD_NAME]+"' ")
02473                                         
02474                                 
02475                         elif self._deviceInfo[SAVE_STATUS] == DELETE:
02476                             portIDs = self.GetPortIDs()
02477                             if portIDs !=[]:
02478                                 for portID in portIDs:
02479                                         cfDB.DeletePortRow(portID)
02480                             success=cfDB.DeleteFunctionalDevice(self._deviceInfo[DEV_ID])
02481                             cfDB2.execute("DELETE FROM LHCB_DEVICES_URL WHERE DEVICENAME='"+self._deviceInfo[DEV_NAME]+"' ")
02482                             
02483                         return True
02484 
02485                 except ValidationError,err:
02486                         self.__errormessage = str(err)
02487                         return False
02488                 except DBError,err:
02489                         self.__errormessage = str(err)
02490                         return False
02491                 except RuntimeError,err:
02492                         self.__errormessage = str(err)
02493                         return False #on error
02494 
02495         ##
02496         #  Sets the save status of this object to delete, and adds
02497         #               it to the dirty objects list for later update in the ConfDB.
02498         #               
02499         def Delete(self):
02500                 
02501                 self._deviceInfo[SAVE_STATUS] = DELETE
02502                 GetAppWin().AddToDirtyObjects(self)
02503 
02504         ##
02505         # Sets the save status of this object to modify, and
02506         #               adds it to the dirty objects list for later update in the ConfDB.
02507         #               The Modify status is set in the respective Set-functions for the
02508         #               parameters they change.
02509         #               
02510         def Modify(self,commit=1):
02511                 self._deviceInfo[SAVE_STATUS] = MODIFY
02512                 GetAppWin().AddToDirtyObjects(self)
02513 
02514         ##
02515         #  Sets the save status of this object to create, and adds it
02516         #               to the dirty objects list for later update in the ConfDB.
02517         #               
02518         def Create(self):
02519                 
02520                 self._deviceInfo[SAVE_STATUS] = CREATE
02521                 GetAppWin().AddToDirtyObjects(self)
02522 
02523 ##
02524 #  A link is a physical connection between two devices, and displayed visually in the
02525 #       visual window as lines.
02526 #       
02527 class Link(DBInfo):
02528 
02529         ##
02530         #  Constructor.
02531         # 
02532         #               Parameters:
02533         #               @systemname - (Obsolete) Name of the subsystem a link is in, but
02534         #               is now longer needed to be set because the subsystem it is in can be
02535         #               retrieved from the devices it connects.
02536         #               @linkID - If already stored in ConfDB the linkID is set, otherwise it is -1
02537         #               @reverseLink - only used when creating links in path view. If this is true
02538         #               the link is the opposite of what that is set (from = to and to = from)
02539         #               @new - whether the link is being created (True), or already created (False).
02540         #               
02541         def __init__(self,systemname,linkID=-1,reverseLink=False,new=True):
02542 
02543                 self._deviceInfo = {}
02544                 self._deviceInfo[DEV_OBJECT] = obj_LINK
02545                 self._deviceInfo[DEV_SYSTEM] = systemname
02546                 self._deviceInfo[DEV_LINK] = str(linkID) #always string, also linkIDs from the ConfDB
02547 
02548                 self._deviceInfo[DEV_SWITCH_FROM] = -1
02549                 self._deviceInfo[DEV_SWITCH_TO] = -1
02550                 self._deviceInfo[DEV_PORT_FROM] = -1
02551                 self._deviceInfo[DEV_PORT_TO] = -1
02552 
02553                 self._deviceInfo[DEV_PORTTYPE_TO] = ""
02554                 self._deviceInfo[DEV_PORTTYPE_FROM] = ""
02555 
02556                 self._deviceInfo[DEV_LINKTYPE] = -1
02557                 self._deviceInfo[DEV_BIDIRECTIONAL] = 0 #default, no
02558                 self._deviceInfo[DEV_LINK_USED] = -1 #default yes when creating, can be set to 0 if not to be used
02559                 self._deviceInfo[DEV_LINKINFO] = ""
02560 
02561                 #variables we need in order to know whether the 3 variables above have been modified by the user
02562                 self._deviceInfo[LINKTYPE_CHANGED] = 0
02563                 self._deviceInfo[BIDIRECTIONAL_CHANGED] = 0
02564                 self._deviceInfo[LINKUSED_CHANGED] = 0
02565                 self._deviceInfo[LINKINFO_CHANGED] = 0
02566 
02567                 # In case different link types should have different colours..not used
02568                 self._deviceInfo[DEV_COLOUR] = "(0, 0, 0)" #wxColour(0,0,0)
02569 
02570                 self._deviceInfo[SAVE_STATUS] = NO_STATUS
02571 
02572                 self.__reverseLink = reverseLink #only used for GetPaths() in a device object
02573 
02574                 self.__cfg = GetConfig()
02575 
02576                 self.__errormessage = ""
02577 
02578                 if new == False:
02579                         self.Update()
02580 
02581         ### GET ###
02582         def GetSystem(self):
02583                 return self._deviceInfo[DEV_SYSTEM]
02584         def GetSaveStatus(self):
02585                 return self._deviceInfo[SAVE_STATUS] #set INSERT, DELETE and UPDATE as constants
02586         def GetName(self):
02587                 return str(self._deviceInfo[DEV_LINK])
02588         def GetNodeTo(self):
02589                 return self._deviceInfo[DEV_SWITCH_TO]
02590         def GetNodeFrom(self):
02591                 return self._deviceInfo[DEV_SWITCH_FROM]
02592         def GetPortTo(self):
02593                 return self._deviceInfo[DEV_PORT_TO]
02594         def GetColor(self):
02595                 return self._deviceInfo[DEV_COLOUR]
02596         def GetPortFrom(self):
02597                 return self._deviceInfo[DEV_PORT_FROM]
02598         def GetPortTypeTo(self):
02599                 return self._deviceInfo[DEV_PORTTYPE_TO]
02600         def GetPortTypeFrom(self):
02601                 return self._deviceInfo[DEV_PORTTYPE_FROM]
02602         def GetReverseLink(self):
02603                 return self.__reverseLink
02604         def GetType(self):
02605                 return self._deviceInfo[DEV_LINKTYPE]
02606         def GetBidirectional(self):
02607                 return self._deviceInfo[DEV_BIDIRECTIONAL]
02608         def GetLinkUsed(self):
02609                 return self._deviceInfo[DEV_LINK_USED]
02610         def GetLinkInfo(self):
02611                 return self._deviceInfo[DEV_LINKINFO]
02612         def GetErrorMessage(self):
02613                 return self.__errormessage
02614         def SetErrorMessage(self,msg):
02615                 self.__errormessage = msg
02616 
02617         ###SET###
02618         def SetSaveStatus(self,state):
02619                 self._deviceInfo[SAVE_STATUS] = state
02620         def SetName(self,name):
02621                 # temporary unique link name before save to ConfDB
02622                 # set automatically in code (no user interference)
02623                 self._deviceInfo[DEV_LINK] = str(name) 
02624         def SetNodeTo(self,node):
02625                 Validation.ValidateString("Node To",node,100,False)
02626                 self._deviceInfo[DEV_SWITCH_TO] = node
02627         def SetNodeFrom(self,node):
02628                 Validation.ValidateString("Node From",node,100,False)
02629                 self._deviceInfo[DEV_SWITCH_FROM] = node
02630         def SetPortTo(self,port):
02631                 Validation.ValidateString("Port to",port,50,False)
02632                 self._deviceInfo[DEV_PORT_TO] = port
02633         def SetPortFrom(self,port):
02634                 Validation.ValidateString("Port from",port,50,False)
02635                 self._deviceInfo[DEV_PORT_FROM] = port
02636         def SetPortTypeTo(self,porttype):
02637                 Validation.ValidateString("Porttype To",porttype,100,True)
02638                 self._deviceInfo[DEV_PORTTYPE_TO] = porttype
02639         def SetPortTypeFrom(self,porttype):
02640                 Validation.ValidateString("Porttype From",porttype,100,True)
02641                 self._deviceInfo[DEV_PORTTYPE_FROM] = porttype
02642         def SetReverseLink(self,reverse):
02643                 self.__reverseLink = reverse
02644         def SetSystem(self,system):
02645                 Validation.ValidateSystem("Systemname",system)
02646                 self._deviceInfo[DEV_SYSTEM] = system #validate system
02647 
02648         def SetLinkInfo(self,linkinfo,changed=True):
02649                 Validation.ValidateString("Link Info",linkinfo,1000,True)
02650                 self._deviceInfo[DEV_LINKINFO] = linkinfo
02651                 if changed:
02652                         self._deviceInfo[LINKINFO_CHANGED] = 1
02653                 else:
02654                         self._deviceInfo[LINKINFO_CHANGED] = 0
02655         def IsTypeChanged(self):
02656                 return self._deviceInfo[LINKTYPE_CHANGED] == 1
02657         def IsBidirChanged(self):
02658                 return self._deviceInfo[BIDIRECTIONAL_CHANGED] == 1
02659         def IsLkusedChanged(self):
02660                 return self._deviceInfo[LINKUSED_CHANGED] == 1
02661         def IsReversed(self):
02662                 return self.__reverseLink
02663         def IsLkInfoChanged(self):
02664                 return self._deviceInfo[LINKINFO_CHANGED] == 1
02665         
02666         ##
02667         #  Update linktype name for a link.
02668         #               
02669         def SetType(self,linktype,changed=True):
02670                 Validation.ValidateString("Linktype",linktype,100,False)
02671                 self._deviceInfo[DEV_LINKTYPE] = linktype #name for user, but change to id before save, name or id, no Validation
02672                 if changed:
02673                         self._deviceInfo[LINKTYPE_CHANGED] = 1
02674                 else:
02675                         self._deviceInfo[LINKTYPE_CHANGED] = 0
02676         def SetBidirectional(self,bidir,changed=True):
02677                 Validation.ValidateNumber("Bidirectional",bidir,0,1)
02678                 self._deviceInfo[DEV_BIDIRECTIONAL] = bidir
02679                 if changed:
02680                         self._deviceInfo[BIDIRECTIONAL_CHANGED] = 1
02681                 else:
02682                         self._deviceInfo[BIDIRECTIONAL_CHANGED] = 0
02683         def SetLinkUsed(self,lkused,changed=True):
02684                 Validation.ValidateNumber("Link Used",lkused,0,1)
02685                 self._deviceInfo[DEV_LINK_USED] = lkused
02686                 if changed:
02687                         self._deviceInfo[LINKUSED_CHANGED] = 1
02688                 else:
02689                         self._deviceInfo[LINKUSED_CHANGED] = 0
02690         ##
02691         #  Copy member variable (parameters) information
02692         #               from a link object to another (this)
02693         #               
02694         def SetDict(self,newdict):
02695                 #self._deviceInfo = copy.deepcopy(newdict)
02696                 for entry in newdict:
02697                         self._deviceInfo[entry] = newdict[entry]
02698 
02699         ##
02700         # Get all info about a Point-to-Point connection (link).
02701         #                 
02702         #               TODO: Here we can have checks whether we need to look for link information in
02703         #               dirty objects list or ConfDB if this is the most recent version of the link
02704         #               object.
02705         #               
02706         #               @doNotLookUp - whether we should look for information about this object in dirty objects
02707         #               list and ConfDB (False) or not(True).
02708         #               
02709         def GetObjectInfo(self,doNotLookUp=True):
02710                 
02711                 if doNotLookUp == True:
02712                         return self._deviceInfo
02713                 else:
02714                         return self.Update()
02715 
02716         ##
02717         #  Update the information/parameters for this link with the most recent information,
02718         #               and also return the member variable dictionary.
02719         # 
02720         #               Parameters:
02721         #               @doNotCheckInDirtyList - if set to True, we do not check in the dirty objects list for
02722         #               a version of the object.
02723         # 
02724         #               !return - the member variable dictionary of parameters for the link
02725         #               
02726         def Update(self,doNotCheckInDirtyList=False):
02727 
02728                 if not doNotCheckInDirtyList:
02729                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
02730                                 tmp_obj = GetAppWin().GetDirtyObject(self._deviceInfo[DEV_LINK],Link)
02731                                 if tmp_obj != False:
02732                                         self._deviceInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
02733                                         return self._deviceInfo
02734 
02735                 try:
02736                     Validation.ValidateNumber("LinkID",int(self._deviceInfo[DEV_LINK]))
02737                     linkerror = True
02738                     result = cfDB.GetMacroConnectivityRow_lkid(int(self._deviceInfo[DEV_LINK]))
02739                     linkerror = False
02740                         
02741                     result = result[1:] #skip first '|' character
02742                     infolist = result.split("|")        #split string in list
02743 
02744                     i = 0
02745                     deviceInfo = {DEV_OBJECT : obj_LINK}        #To identify this as a linknode (as opposite to a devicenode)
02746                     deviceInfo[DEV_SYSTEM] = self._deviceInfo[DEV_SYSTEM]
02747 
02748                     deviceInfo[LINKTYPE_CHANGED] = 0
02749                     deviceInfo[BIDIRECTIONAL_CHANGED] = 0
02750                     deviceInfo[LINKUSED_CHANGED] = 0
02751                     deviceInfo[LINKINFO_CHANGED] = 0
02752                     deviceInfo[DEV_LINKINFO] = ""
02753         
02754                     for i in range(len(infolist)-1):
02755                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
02756                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
02757                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
02758                         if datatype == 'I': #integer
02759                                 tmp[1] = int(tmp[1])
02760                         elif datatype == 'C': #string
02761                                 tmp[1] = tmp[1].strip()
02762 
02763                         deviceInfo[tmp0] = tmp[1]
02764                         i += 1
02765 
02766                     # If link is reversed; fix it
02767                     if self.__reverseLink == True:
02768                         deviceInfo[DEV_SWITCH_FROM], deviceInfo[DEV_SWITCH_TO] = deviceInfo[DEV_SWITCH_TO], deviceInfo[DEV_SWITCH_FROM]
02769                         deviceInfo[DEV_PORT_FROM], deviceInfo[DEV_PORT_TO] = deviceInfo[DEV_PORT_TO], deviceInfo[DEV_PORT_FROM]
02770                         deviceInfo[DEV_PORTTYPE_FROM], deviceInfo[DEV_PORTTYPE_TO] = deviceInfo[DEV_PORTTYPE_TO], deviceInfo[DEV_PORTTYPE_FROM]
02771 
02772                     deviceInfo[DEV_LINK] = str(deviceInfo[DEV_LINK]) #convert the linktypeID of integer to string
02773 
02774                     try:
02775                         deviceInfo[DEV_COLOUR] = LinkTypesColor[deviceInfo[DEV_LINKTYPE]]
02776                     except:
02777                         print "WARNING : there no corresponding color found for the device type: "+deviceInfo[DEV_LINKTYPE]
02778                         deviceInfo[DEV_COLOUR] = '(0,0,0)'
02779                         
02780                     # Check whether link type of device type has been renamed, and take action thereafter
02781                     if deviceInfo[DEV_LINKTYPE] in GetAppWin().GetOldNames():
02782                         deviceInfo[DEV_LINKTYPE] = GetAppWin().GetNewNamesOfRenamed()[deviceInfo[DEV_LINKTYPE]] #set to the new name of the devtype
02783                     if deviceInfo[DEV_SWITCH_FROM] in GetAppWin().GetOldNames():
02784                         deviceInfo[DEV_SWITCH_FROM] = GetAppWin().GetNewNamesOfRenamed()[deviceInfo[DEV_SWITCH_FROM]] #set to the new name of the dv
02785                     if deviceInfo[DEV_SWITCH_TO] in GetAppWin().GetOldNames():
02786                         deviceInfo[DEV_SWITCH_TO] = GetAppWin().GetNewNamesOfRenamed()[deviceInfo[DEV_SWITCH_TO]] #set to the new name of the dev       
02787 
02788                     if deviceInfo[DEV_PORTTYPE_FROM].lower() == "none":
02789                         deviceInfo[DEV_PORTTYPE_FROM] = ""
02790                     if deviceInfo[DEV_PORTTYPE_TO].lower() == "none":
02791                         deviceInfo[DEV_PORTTYPE_TO] = ""
02792 
02793                     self._deviceInfo = deviceInfo
02794                     
02795                     #self.UpdateLinkType() #needed to be done if we choose to use different colours for different linktypes
02796                 
02797                     return self._deviceInfo
02798                                                                                                                              
02799                 except ValidationError,err:
02800                     self.__errormessage = str(err)
02801                     return False
02802                 except DBError,err:
02803                     self.__errormessage = str(err)
02804                     return False
02805                 except RuntimeError,err:
02806                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
02807                         if linkerror:
02808                                 self.__errormessage = "Didn't find the LinkID in the database: " + str(self._deviceInfo[DEV_LINK])
02809                         else:
02810                                 self.__errormessage = "Didn't find one of the devices the link links to in the database: " + str(self._deviceInfo[DEV_LINK])
02811                         return {} #none found
02812                     else:
02813                         self.__errormessage = str(err)
02814                     return False #on error
02815                 except ValueError,err:
02816                     self.__errormessage = str("LinkID is not a valid ID.")
02817                     return False
02818             
02819         ##
02820         #  A function that returns the string to the function that will be called in the
02821         #               ConfDBLibrary for the given save and modify status of this data object, as well as
02822         #               use of single or multiple insert.
02823         # 
02824         #               Parameters:
02825         #               Same as for Save(...)
02826         # 
02827         #               !return - returns a String with the function name as well as all set parameters
02828         #               
02829         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
02830 
02831                 save_status = self._deviceInfo[SAVE_STATUS]
02832                 
02833                 # Change name of port type to none, because the ConfDB Library function expects that instead
02834                 # of ""
02835                 if self._deviceInfo[DEV_PORTTYPE_FROM] == "":
02836                         porttype_from = "none"
02837                 else:
02838                         porttype_from = self._deviceInfo[DEV_PORTTYPE_FROM]
02839                         
02840                 if self._deviceInfo[DEV_PORTTYPE_TO] == "":
02841                         porttype_to = "none"
02842                 else:
02843                         porttype_to = self._deviceInfo[DEV_PORTTYPE_TO]
02844 
02845         
02846                 if save_status == CREATE:
02847                         if insertmany:
02848                                 return 'cfDB.InsertMultipleMacroLinks("%s","%s","%s","%s","%s","%s","%s",%i,"%s",%i,%i)' \
02849                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),str(self._deviceInfo[DEV_SWITCH_TO]),str(self._deviceInfo[DEV_PORT_FROM]),str(self._deviceInfo[DEV_PORT_TO]),str(porttype_from),str(porttype_to),str(self._deviceInfo[DEV_LINKTYPE]),self._deviceInfo[DEV_BIDIRECTIONAL],self._deviceInfo[DEV_LINKINFO],first,commit)
02850                         else:
02851                                 return 'cfDB.InsertMacroLink("%s","%s","%s","%s","%s","%s","%s",%i,"%s",%i)' \
02852                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),str(self._deviceInfo[DEV_SWITCH_TO]),str(self._deviceInfo[DEV_PORT_FROM]),str(self._deviceInfo[DEV_PORT_TO]),str(porttype_from),str(porttype_to),str(self._deviceInfo[DEV_LINKTYPE]),self._deviceInfo[DEV_BIDIRECTIONAL],self._deviceInfo[DEV_LINKINFO],commit)
02853 
02854                 elif save_status == MODIFY:
02855                         modify_status = self._deviceTypeInfo[MODIFY_STATUS]
02856                         tmpstring = ""
02857                         
02858                         if self._deviceInfo[BIDIRECTIONAL_CHANGED] == 1:
02859                                 tmpstring += 'cfDB.UpdateMultipleBidirectionalLinks("%s","%s","%s","%s","%s","%s",%i,%i,%i)\n' \
02860                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),"none",str(self._deviceInfo[DEV_PORT_FROM]),str(porttype_from),"none","none",self._deviceInfo[DEV_BIDIRECTIONAL],first,commit)
02861                                 
02862                         if self._deviceInfo[LINKTYPE_CHANGED] == 1:
02863                                 tmpstring += 'cfDB.UpdateMultipleLkTypeLinks("%s","%s","%s","%s","%s","%s","%s",%i,%i)\n' \
02864                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),"none",str(self._deviceInfo[DEV_PORT_FROM]),"none",str(porttype_from),"none",str(self._deviceInfo[DEV_LINKTYPE]),first,commit)
02865                         
02866                         if self._deviceInfo[LINKUSED_CHANGED] == 1:
02867                                 tmpstring += 'cfDB.UpdateMultipleLkUsedLinks("%s","%s","%s","%s","%s","%s",%i,%i,%i)\n' \
02868                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),"none",str(self._deviceInfo[DEV_PORT_FROM]),"none",str(porttype_from),"none",self._deviceInfo[DEV_LINK_USED],first,commit) ###??
02869                                 
02870                         if self._deviceInfo[LINKINFO_CHANGED] == 1:
02871                                 tmpstring += 'cfDB.UpdateMultipleLkInfoLinks("%s","%s","%s","%s","%s","%s","%s",%i,%i)\n' \
02872                                 %(str(self._deviceInfo[DEV_SWITCH_FROM]),"none",str(self._deviceInfo[DEV_PORT_FROM]),"none",str(porttype_from),"none",self._deviceInfo[DEV_LINKINFO],first,commit) ###??
02873 
02874 
02875                         return tmpstring
02876 
02877                 elif save_status == DELETE:
02878                         return 'cfDB.DeleteLinkRow(%i,%i)' \
02879                         %(int(self._deviceInfo[DEV_LINK]),1)
02880         
02881                 else: #invalid status
02882                         return ""
02883 
02884 
02885         ##
02886         #  Update changes to the ConfDB for this object.
02887         # 
02888         #               Parameters:
02889         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
02890         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
02891         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
02892         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
02893         #               insert function will be used, which is optimized for multiple inserts (use of cache)
02894         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
02895         #               commit is set to true, all data that are put on hold in the cache will be commited.
02896         #               
02897         def Save(self,first=False,insertmany=False,commit=True):
02898                 try:
02899                         if self._deviceInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE]:
02900                                 raise RuntimeError, "Save status incorrectly set. This object should not be stored in db."
02901                         
02902                         if self._deviceInfo[SAVE_STATUS] == CREATE or self._deviceInfo[SAVE_STATUS] == MODIFY:
02903                                 Validation.ValidateString("Device from",self._deviceInfo[DEV_SWITCH_FROM],100)
02904                                 Validation.ValidateString("Device to",self._deviceInfo[DEV_SWITCH_TO],100)
02905                                 Validation.ValidateString("Port from",self._deviceInfo[DEV_PORT_FROM],50,False)
02906                                 Validation.ValidateString("Port to",self._deviceInfo[DEV_PORT_TO],50,False)
02907                                 Validation.ValidateString("Porttype to",self._deviceInfo[DEV_PORTTYPE_TO],100,True)
02908                                 Validation.ValidateString("Porttype from",self._deviceInfo[DEV_PORTTYPE_FROM],100,True)
02909                                 Validation.ValidateString("Linktype",self._deviceInfo[DEV_LINKTYPE],100)
02910                                 Validation.ValidateNumber("Link bidirectional",self._deviceInfo[DEV_BIDIRECTIONAL],-1,1)
02911                                 Validation.ValidateString("Link ID",self._deviceInfo[DEV_LINK],100)
02912                                 Validation.ValidateString("Link Info",self._deviceInfo[DEV_LINKINFO],1000,True)
02913 
02914                                 # Change name of port type to none, because the ConfDB Library function expects that instead
02915                                 # of ""
02916                                 if self._deviceInfo[DEV_PORTTYPE_FROM] == "":
02917                                         porttype_from = "none"
02918                                 else:
02919                                         porttype_from = self._deviceInfo[DEV_PORTTYPE_FROM]
02920                                 if self._deviceInfo[DEV_PORTTYPE_TO] == "":
02921                                         porttype_to = "none"
02922                                 else:
02923                                         porttype_to = self._deviceInfo[DEV_PORTTYPE_TO]
02924 
02925                         if self._deviceInfo[SAVE_STATUS] == MODIFY or self._deviceInfo[SAVE_STATUS] == DELETE:
02926                                 Validation.ValidateNumber("Link ID",int(self._deviceInfo[DEV_LINK]),0)
02927 
02928                         if self._deviceInfo[SAVE_STATUS] == MODIFY:
02929                                 Validation.ValidateNumber("Link used",self._deviceInfo[DEV_LINK_USED],-1,1)
02930                         
02931                         print " END VALIDATION "
02932                         print self._deviceInfo[SAVE_STATUS],CREATE
02933                         if self._deviceInfo[SAVE_STATUS] == CREATE:
02934                                 if insertmany:
02935                                     success = cfDB.InsertMultipleMacroLinks(self._deviceInfo[DEV_SWITCH_FROM],self._deviceInfo[DEV_SWITCH_TO],self._deviceInfo[DEV_PORT_FROM],self._deviceInfo[DEV_PORT_TO],porttype_from,porttype_to,self._deviceInfo[DEV_LINKTYPE],self._deviceInfo[DEV_BIDIRECTIONAL],self._deviceInfo[DEV_LINKINFO],first,commit)
02936                                 else:
02937                                     print "argument de ma fonction : "
02938                                     print (self._deviceInfo[DEV_SWITCH_FROM],self._deviceInfo[DEV_SWITCH_TO],self._deviceInfo[DEV_PORT_FROM],self._deviceInfo[DEV_PORT_TO],porttype_from,porttype_to,self._deviceInfo[DEV_LINKTYPE],self._deviceInfo[DEV_BIDIRECTIONAL], self._deviceInfo[DEV_LINKINFO],commit)
02939                                     print "_-_____-_____-----_________-------________------"
02940                                     success = cfDB.InsertMacroLink(self._deviceInfo[DEV_SWITCH_FROM],self._deviceInfo[DEV_SWITCH_TO],self._deviceInfo[DEV_PORT_FROM],self._deviceInfo[DEV_PORT_TO],porttype_from,porttype_to,self._deviceInfo[DEV_LINKTYPE],self._deviceInfo[DEV_BIDIRECTIONAL], self._deviceInfo[DEV_LINKINFO],commit)
02941                                     print "Resultat : " +  str(success)
02942                                 if commit:
02943                                         #change from temp linkname to linkid in db
02944                                         found = self.SetLinkIDByDeviceAndPort(self._deviceInfo[DEV_SWITCH_FROM],self._deviceInfo[DEV_PORT_FROM],porttype_from,self._deviceInfo[DEV_SWITCH_TO],self._deviceInfo[DEV_PORT_TO],porttype_to)
02945                                         if not found:
02946                                                 raise RuntimeError,str(self.__errormessage)
02947                                         else:
02948                                                 self.Update(True)
02949                                                 
02950                         elif self._deviceInfo[SAVE_STATUS] == MODIFY:
02951                                 if self._deviceInfo[BIDIRECTIONAL_CHANGED] == 1:
02952                                         success = cfDB.UpdateMultipleBidirectionalLinks(self._deviceInfo[DEV_SWITCH_FROM],"none",self._deviceInfo[DEV_PORT_FROM],porttype_from,"none","none",self._deviceInfo[DEV_BIDIRECTIONAL],first,commit)
02953                                         if commit:
02954                                                 self._deviceInfo[BIDIRECTIONAL_CHANGED] = 0
02955                                 if self._deviceInfo[LINKTYPE_CHANGED] == 1:
02956                                         success = cfDB.UpdateMultipleLkTypeLinks(self._deviceInfo[DEV_SWITCH_FROM],"none",self._deviceInfo[DEV_PORT_FROM],"none",porttype_from,"none",self._deviceInfo[DEV_LINKTYPE],first,commit)
02957                                         if commit:
02958                                                 self._deviceInfo[LINKTYPE_CHANGED] = 0 #Need to UpdateLinktype if we set diff colour on the linktypes
02959                                 if self._deviceInfo[LINKUSED_CHANGED] == 1:
02960                                         success = cfDB.UpdateMultipleLkUsedLinks(self._deviceInfo[DEV_SWITCH_FROM],"none",self._deviceInfo[DEV_PORT_FROM],"none",porttype_from,"none",self._deviceInfo[DEV_LINK_USED],first,commit) ###??
02961                                         if commit:
02962                                                 self._deviceInfo[LINKUSED_CHANGED] = 0 #requres visWindow update?
02963                                                 
02964                                 if self._deviceInfo[LINKINFO_CHANGED] == 1:
02965                                         success = cfDB.UpdateMultipleLkInfoLinks(self._deviceInfo[DEV_SWITCH_FROM],"none",self._deviceInfo[DEV_PORT_FROM],"none",porttype_from,"none",self._deviceInfo[DEV_LINKINFO],first,commit) ###??
02966                                         if commit:
02967                                                 self._deviceInfo[LINKINFO_CHANGED] = 0 #requres visWindow update?
02968 
02969 
02970                                 # TODO: No update after modify??
02971 
02972                         elif self._deviceInfo[SAVE_STATUS] == DELETE:
02973                                 success = cfDB.DeleteLinkRow(int(self._deviceInfo[DEV_LINK]),1)
02974                                 #Of course no update is needed when it is deleted...
02975 
02976                         return True
02977 
02978                 except ValueError,err:
02979                         self.__errormessage = "An integer conversion failed. Cannot continue on the given link: " + str(self.GetName())
02980                         return False
02981                 except ValidationError,err:
02982                         print "validation errror"
02983                         self.__errormessage = str(err)
02984                         return False
02985                 except DBError,err:
02986                         print "DB error"
02987                         self.__errormesage = str(err)
02988                         return False
02989                 except RuntimeError,err:
02990                         print "runtime error"
02991                         self.__errormessage = str(err)
02992                         return False
02993 
02994         ##
02995         #  Before we store a link in the ConfDB, the linkID/name is a temporary name
02996         #               that is automatically assigned; this has to be changed to the unique ID set to
02997         #               the link in the ConfDB. This method updates the linkID to what it was set to
02998         #               in the ConfDB.
02999         # 
03000         #               !return - False if an error occurs, True otherwise
03001         #               
03002         def UpdateLinkID(self):
03003                 
03004                 if self._deviceInfo[DEV_PORTTYPE_FROM] == "":
03005                         porttype_from = "none"
03006                 else:
03007                         porttype_from = self._deviceInfo[DEV_PORTTYPE_FROM]
03008                 if self._deviceInfo[DEV_PORTTYPE_TO] == "":
03009                         porttype_to = "none"
03010                 else:
03011                         porttype_to = self._deviceInfo[DEV_PORTTYPE_TO]
03012 
03013                 found = self.SetLinkIDByDeviceAndPort(self._deviceInfo[DEV_SWITCH_FROM],self._deviceInfo[DEV_PORT_FROM],porttype_from,self._deviceInfo[DEV_SWITCH_TO],self._deviceInfo[DEV_PORT_TO],porttype_to)
03014                 if not found:
03015                         return False #errormessage already set in SetLinkIDByDeviceAndPort
03016                 self.Update(True) # Get most recent information about the link from the ConfDB.
03017                 return True
03018 
03019         ##
03020         #  This is the method that actually finds the new link ID to a link that was just
03021         #               stored in the ConfDB, by retrieving information about the link that is connected to the
03022         #               devices and ports this link is connected to.
03023         # 
03024         #               Parameters:
03025         #               @dev_from - the device name where the link is connected to the OUT port
03026         #               @port_from - the port number of the device that the link is connected to on the from-device (OUT port)
03027         #               @porttype_from - the port type of the device that the link is connected to on the from-device (OUT port)
03028         #               @dev_to - the device name where the link is connected to the IN port
03029         #               @port_to - the port number of the device that the link is connected to on the to-device (IN port)
03030         #               @porttype_to - the port type of the device that the link is connected to on the to-deivce (IN port)
03031         # 
03032         #               !return - True if successful, False otherwise.
03033         #               
03034         def SetLinkIDByDeviceAndPort(self,dev_from,port_from,porttype_from,dev_to,port_to,porttype_to):
03035 
03036                 try:
03037                         devid_from = cfDB.GetDeviceID_devicename(dev_from)
03038                         devid_to   = cfDB.GetDeviceID_devicename(dev_to)        
03039 
03040                         linkidtmp = []
03041                         linkidtmp.append(cfDB.GetMacroConnectivityRow_node(devid_from,port_from,2,porttype_from))
03042                         linkidtmp.append(cfDB.GetMacroConnectivityRow_node(devid_to,port_to,1,porttype_to))
03043 
03044                         linkidabs = []
03045 
03046                         j = 0
03047                         while j < 2:
03048                                 print str(linkidtmp[j])
03049                                 result = linkidtmp[j][1:]       #skip first '|' character
03050                                 linklist = result.split("|")    #split string in list
03051 
03052                                 i = 0
03053                                 for i in range(len(linklist)-1):
03054                                         tmp = linklist[i].split(":")            #split each property, name and datatype on left site, value on right side
03055                                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
03056                                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String, I - integer
03057                                         
03058                                         if datatype == 'I' and tmp0 == "linkid": #Found what we are looking for, the linkid
03059                                                 linkidabs.append(int(tmp[1]))
03060                                                 break
03061 
03062                                         i += 1
03063 
03064                                 j += 1
03065 
03066                         if linkidabs[0] == linkidabs[1]: #Fine, same linkid for the given connection, set it
03067                                 self._deviceInfo[DEV_LINK] = str(linkidabs[0]) #set as string
03068                                 return True
03069                         else:
03070                                 raise RuntimeError,"An unexpected error occured, couldn't retrieve correct LinkID"
03071 
03072                 except RuntimeError,err:
03073                         self.__errormessage = str(err)
03074                         return False
03075 
03076         ##
03077         #  Sets the save status of this object to delete, and adds
03078         #               it to the dirty objects list for later update in the ConfDB.
03079         #               
03080         def Delete(self):
03081                 
03082                 self._deviceInfo[SAVE_STATUS] = DELETE
03083                 GetAppWin().AddToDirtyObjects(self)
03084 
03085         ##
03086         #  Sets the save status of this object to modify, and adds
03087         #               it to the dirty objects list for later update in the ConfDB.
03088         #               Modify status is set in respective Set-methods.
03089         #               
03090         def Modify(self):
03091                 self._deviceInfo[SAVE_STATUS] = MODIFY
03092                 GetAppWin().AddToDirtyObjects(self)
03093 
03094         ##
03095         #  Sets the save status of this object to create, and adds
03096         #               it to the dirty objects list for later update in the ConfDB.
03097         #               
03098         def Create(self):
03099                 self.SetName(self.GetNodeFrom()+":"+str(self.GetPortFrom())+":"+self.GetNodeTo()+":"+str(self.GetPortTo()))
03100                 self._deviceInfo[SAVE_STATUS] = CREATE
03101                 GetAppWin().AddToDirtyObjects(self)
03102 
03103 ##
03104 #  Create a link type, which is an abstract object. Common properties for physical links of
03105 #       a given type; f.ex. HV, gas, data etc.
03106 #       
03107 class LinkType(DBInfo):
03108 
03109         ##
03110         #  Constructor.
03111         # 
03112         #               Parameters:
03113         #               @systemname - name of the subsystem this linktype is created in (Obsolete). Now
03114         #               all link types are available in all subsystems, because there are not that many of them.
03115         #               @linkTypeName - the unique link type name set by the user
03116         #               @new - whether the link type is being created (True) or that it has already been created (False)
03117         #               
03118         def __init__(self,systemName,linkTypeName="",new=True):
03119 
03120                 self._deviceInfo = {}
03121                 self._deviceInfo[LINK_NAME] = linkTypeName
03122                 self._deviceInfo[LINK_TYPE] = -1 #ID
03123                 self._deviceInfo[DEV_SYSTEM] = systemName
03124                 self._deviceInfo[DEV_COLOUR] = "(0, 0, 0)" #wxColour(0,0,0)
03125                 self._deviceInfo[OLD_NAME] = "" #previous name if renamed
03126 
03127                 self._deviceInfo[COMPOSITE_LINKS] = "" #set to "" if this is not a composite linktype
03128                                                         #if it composite this variable contains the commaseparated linktypes
03129                 self._deviceInfo[COMPLINKS_CHANGED] = 0
03130 
03131                 self._deviceInfo[SAVE_STATUS] = NO_STATUS
03132 
03133                 self.__cfg = GetConfig()
03134 
03135                 if new == False:
03136                         self.Update()
03137 
03138                 self.__errormessage = ""
03139 
03140         ### GET ###
03141         def GetOldName(self):
03142                 return self._deviceInfo[OLD_NAME]
03143         def GetSaveStatus(self):
03144                 return self._deviceInfo[SAVE_STATUS] #set INSERT, DELETE and UPDATE as constants
03145         def GetName(self):
03146                 return self._deviceInfo[LINK_NAME]
03147         def GetSystem(self):
03148                 return self._deviceInfo[DEV_SYSTEM]
03149         def GetID(self):
03150                 return self._deviceInfo[LINK_TYPE]
03151         def GetCompositeLinks(self):
03152                 return self._deviceInfo[COMPOSITE_LINKS]
03153         def GetErrorMessage(self):
03154                 return self.__errormessage
03155         def SetErrorMessage(self,msg):
03156                 self.__errormessage = msg
03157         def SetOldName(self,oldname):
03158                 self._deviceInfo[OLD_NAME] = oldname
03159         def SetSaveStatus(self,status):
03160                 self._deviceInfo[SAVE_STATUS] = status
03161         def SetName(self,name):
03162                 Validation.ValidateString("link type name",name,100,False)
03163                 self._deviceInfo[LINK_NAME] = name
03164         def SetSystem(self,name):
03165                 Validation.ValidateSystem("system name",name)
03166         def SetID(self,id):
03167                 Validation.ValidateNumber("link type id",id)
03168                 self._deviceInfo[LINK_TYPE] = id
03169         def SetCompositeLinks(self,concanlist):
03170                 self._deviceInfo[COMPLINKS_CHANGED] = 1
03171                 self._deviceInfo[COMPOSITE_LINKS] = concanlist #only set if composite linktype, else it is ""
03172         def SetDict(self,newdict):
03173                 #self._deviceInfo = copy.deepcopy(newdict)
03174                 for entry in newdict:
03175                         self._deviceInfo[entry] = newdict[entry]
03176 
03177         ##
03178         # Get all info about a link type.
03179         #                 
03180         #               TODO: Here we can have checks whether we need to look for link type information in
03181         #               dirty objects list or ConfDB if this is the most recent version of the link type
03182         #               object.
03183         #               
03184         #               @doNotLookUp - whether we should look for information about this object in dirty objects
03185         #               list and ConfDB (False) or not(True).
03186         #               
03187         def GetObjectInfo(self,doNotLookUp=True):
03188                 if doNotLookUp == True:
03189                         return self._deviceInfo
03190                 else:
03191                         return self.Update()
03192 
03193         ##
03194         #  Update the information/parameters for this link with the most recent information,
03195         #               and also return the member variable dictionary.
03196         # 
03197         #               Parameters:
03198         #               @doNotCheckInDirtyList - if set to True, we do not check in the dirty objects list for
03199         #               a version of the object.
03200         # 
03201         #               !return - the member variable dictionary of parameters for the link type
03202         #               
03203         def Update(self,doNotCheckInDirtyList=False):
03204 
03205                 # Dirty Objects list
03206                 if not doNotCheckInDirtyList:
03207                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
03208                                 tmp_obj = GetAppWin().GetDirtyObject(self._deviceInfo[LINK_NAME],LinkType)
03209                                 if tmp_obj != False:
03210                                         self._deviceInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
03211                                         return self._deviceInfo
03212                 # ConfDB
03213                 try:
03214                     Validation.ValidateString("Linktype name",self._deviceInfo[LINK_NAME],100)
03215                     result = cfDB.GetLkTypeRow_lkname(self._deviceInfo[LINK_NAME])
03216 
03217                     result = result[1:] #skip first '|' character
03218                     infolist = result.split("|")        #split string in list
03219 
03220                     i = 0
03221                     deviceInfo = {DEV_OBJECT : obj_LINK}        #To identify this as a link...maybe change to linktype?
03222                     deviceInfo[DEV_SYSTEM] = self._deviceInfo[DEV_SYSTEM]       #should be retrieved from db? YES..dangerous
03223                     deviceInfo[DEV_COLOUR] = "(0, 255, 0)" #wxColour(0,0,0) #default: black
03224                     for i in range(len(infolist)-1):
03225                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
03226                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
03227                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
03228                         #print "Datatypes: " + datatype
03229                         if datatype == 'I': #integer
03230                                 tmp[1] = int(tmp[1])
03231                         elif datatype == 'C': #string
03232                                 tmp[1] = tmp[1].strip()
03233 
03234                         deviceInfo[tmp0] = tmp[1]
03235                         i += 1
03236 
03237                     self._deviceInfo = deviceInfo                       #same name for indexes in dictionary and name on cols in database
03238                     return self._deviceInfo
03239                                                                                                                              
03240                 except ValidationError,err:
03241                     self.__errormessage = str(err)
03242                     return False
03243                 except DBError,err:
03244                     self.__errormessage = str(err)
03245                     return False
03246                 except RuntimeError,err:
03247                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
03248                         self.__errormessage = "Did not find the LinkType in the database: " + str(self._deviceInfo[LINK_NAME])
03249                         return {} #none found
03250                     else:
03251                         self.__errormessage = str(err)
03252                     return False #on error
03253             
03254         ##
03255         #  A function that returns the string to the function that will be called in the
03256         #               ConfDBLibrary for the given save and modify status of this data object, as well as
03257         #               use of single or multiple insert.
03258         # 
03259         #               Parameters:
03260         #               Same as for Save(...)
03261         # 
03262         #               !return - returns a String with the function name as well as all set parameters
03263         #               
03264         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
03265 
03266                 save_status = self._deviceInfo[SAVE_STATUS]
03267                 
03268                 if save_status == CREATE:
03269                         if self._deviceInfo[COMPOSITE_LINKS] == "":
03270                                 if insertmany:
03271                                         return 'cfDB.InsertMultipleSimpleLinkTypes("%s",%i,%i)' \
03272                                         %(str(self._deviceInfo[LINK_NAME]),first,commit)
03273                                 else:
03274                                         return 'cfDB.InsertSimpleLinkType("%s",%i)' \
03275                                         %(str(self._deviceInfo[LINK_NAME]),commit)
03276                         else:
03277                                 if insertmany:
03278                                         return 'cfDB.InsertMultipleCompositeLinkTypes("%s","%s",%i,%i)' \
03279                                         %(str(self._deviceInfo[LINK_NAME]),str(self._deviceInfo[COMPOSITE_LINKS]),first,commit)
03280                                 else:
03281                                         return 'cfDB.InsertCompositeLinkType("%s","%s",%i)' \
03282                                         %(str(self._deviceInfo[LINK_NAME]),str(self._deviceInfo[COMPOSITE_LINKS]),commit)
03283                 
03284                 elif save_status == MODIFY:
03285                         if self._deviceInfo[COMPLINKS_CHANGED] == 1:
03286                                 if string.find(self._deviceInfo[COMPOSITE_LINKS],",",0) == -1:
03287                                         self._deviceInfo[COMPOSITE_LINKS] = "none" #no longer a composite linktype
03288                                         return 'cfDB.UpdateMultipleCompositeLinkTypes("%s","%s",%i,%i)' \
03289                                         %(str(self._deviceInfo[LINK_NAME]),str(self._deviceInfo[COMPOSITE_LINKS]),first,last)
03290         
03291                 elif save_status == DELETE:
03292                         return "ERROR: Requested to delete LinkType; not possible"
03293 
03294                 elif save_status == RENAME:
03295                         return 'cfDB.UpdateMultipleLinkTypeNames("%s","%s",%i,%i)' \
03296                         %(str(self._deviceInfo[OLD_NAME]),str(self._deviceInfo[LINK_NAME]),first,commit)
03297         
03298                 else: #invalid status
03299                         return ""
03300 
03301         ##
03302         #  Update changes to the ConfDB for this object.
03303         # 
03304         #               Parameters:
03305         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
03306         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
03307         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
03308         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
03309         #               insert function will be used, which is optimized for multiple inserts (use of cache)
03310         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
03311         #               commit is set to true, all data that are put on hold in the cache will be commited.
03312         #               
03313         def Save(self,first=False,insertmany=False,commit=True):
03314 
03315                 try:
03316                         if self._deviceInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE,RENAME]:
03317                                 raise RuntimeError,"Wrong save status set, this linktype cannot be saved in database: " + str(self.GetName())
03318 
03319                         if self._deviceInfo[SAVE_STATUS] == CREATE or self._deviceInfo[SAVE_STATUS] == MODIFY:
03320                                 Validation.ValidateSystem("Linktype",self._deviceInfo[DEV_SYSTEM])
03321                                 Validation.ValidateString("Linkname",self._deviceInfo[LINK_NAME],100)
03322 
03323                         if self._deviceInfo[SAVE_STATUS] == MODIFY or self._deviceInfo[SAVE_STATUS] == DELETE:
03324                                 Validation.ValidateNumber("Linktype ID",int(self._deviceInfo[LINK_TYPE]))
03325 
03326                         if self._deviceInfo[SAVE_STATUS] == CREATE:
03327                                 if self._deviceInfo[COMPOSITE_LINKS] == "":
03328                                         if insertmany:
03329                                             success = cfDB.InsertMultipleSimpleLinkTypes(self._deviceInfo[LINK_NAME],first,commit)
03330                                         else:
03331                                             success = cfDB.InsertSimpleLinkType(self._deviceInfo[LINK_NAME],commit)
03332                                 else:
03333                                         if insertmany:
03334                                                 success = cfDB.InsertMultipleCompositeLinkTypes(self._deviceInfo[LINK_NAME],self._deviceInfo[COMPOSITE_LINKS],first,commit)
03335                                         else:
03336                                                 success = cfDB.InsertCompositeLinkType(self._deviceInfo[LINK_NAME],self._deviceInfo[COMPOSITE_LINKS],commit)
03337 
03338                                 self.Update(True) #update with data from database
03339 
03340                         elif self._deviceInfo[SAVE_STATUS] == MODIFY:
03341                                 if self._deviceInfo[COMPLINKS_CHANGED] == 1:
03342                                         if string.find(self._deviceInfo[COMPOSITE_LINKS],",",0) == -1:
03343                                                 self._deviceInfo[COMPOSITE_LINKS] = "none" #no longer a composite linktype
03344                                         
03345                                         success = cfDB.UpdateMultipleCompositeLinkTypes(self._deviceInfo[LINK_NAME],self._deviceInfo[COMPOSITE_LINKS],first,last)
03346                         
03347                         elif self._deviceInfo[SAVE_STATUS] == DELETE:
03348                                 GetAppWin().ShowError("It is not possible to delete a linktype once it is stored in ConfDB!",ERR_ERROR)
03349                         elif self._deviceInfo[SAVE_STATUS] == RENAME:
03350                                 success = cfDB.UpdateMultipleLinkTypeNames(self._deviceInfo[OLD_NAME],self._deviceInfo[LINK_NAME],first,commit)
03351                                 
03352                         return True
03353                 
03354                 except ValidationError,err:
03355                     self.__errormessage = str(err)
03356                     return False
03357                 except DBError,err:
03358                     self.__errormessage = str(err)
03359                     return False
03360                 except RuntimeError,err:
03361                     self.__errormessage = str(err)
03362                     return False #on error
03363                 except ValueError,err:
03364                     self.__errormessage = str("Linktype ID is not an integer.")
03365                     return False
03366 
03367         ##
03368         #  Sets the save status of this object to delete, and adds
03369         #               it to the dirty objects list for later update in the ConfDB.
03370         #               
03371         def Delete(self):
03372                 
03373                 self._deviceInfo[SAVE_STATUS] = DELETE
03374                 GetAppWin().AddToDirtyObjects(self)
03375 
03376         ##
03377         #  Sets the save status of this object to modify, and adds
03378         #               it to the dirty objects list for later update in the ConfDB.
03379         #               Modify status is set in respective Set-methods.
03380         #               
03381         def Modify(self):
03382                 self._deviceInfo[SAVE_STATUS] = MODIFY
03383                 GetAppWin().AddToDirtyObjects(self)
03384 
03385         ##
03386         #  Sets the save status of this object to delete, and adds
03387         #               it to the dirty objects list for later update in the ConfDB.
03388         #               
03389         def Create(self):
03390 
03391                 self._deviceInfo[SAVE_STATUS] = CREATE
03392                 GetAppWin().AddToDirtyObjects(self)
03393 
03394 ##
03395 #  A port is a physical part of a device; f.ex. a port on a switch. So this class contains
03396 #       properties (member variables) and methods for a port instance.
03397 #       
03398 class Port(DBInfo):
03399 
03400         ##
03401         #  Constructor.
03402         # 
03403         #               Parameters:
03404         #               @systemname - the name of the subsystem a port is in (actually the subsystem the device
03405         #               it is a part of is in). Obsolete and is no longer necessary.
03406         #               @portnbr - the port number, a string and usually an integer, not unique alone.
03407         #               @porttype -  the port type, a string, not unique alone.
03408         #               @portway - the port way (direction, in or out). It is unique together with port number 
03409         #               and port type it for a device.
03410         #               @devname - the device name, of which this port belongs to. Together with port number,
03411         #               port type and port way it is unique in a subsystem.
03412         #               
03413         def __init__(self,systemname,portnbr="",porttype="",portway=PORT_IN,devname="",new=True):
03414 
03415                 self.__portInfo = {}
03416                 self.__portInfo[DEV_SYSTEM] = systemname
03417                 self.__portInfo[DEV_PORT] = -1
03418                 self.__portInfo[DEV_PORTNBR] = portnbr
03419                 self.__portInfo[DEV_PORTTYPE] = porttype
03420                 self.__portInfo[DEV_PORTWAY] = portway #1 means this is input (IN), 2 means this is output (OUT)
03421                 self.__portInfo[DEV_NAME] = devname #devicename, must be set to id of device when update from db
03422 
03423                 self.__portInfo[PORT_BIA] = ""
03424                 self.__portInfo[PORT_MAC] = ""
03425                 self.__portInfo[PORT_SPEED] = -1
03426                 self.__portInfo[PORT_PHY] = ""
03427                 self.__portInfo[PORT_PXI] = -1
03428                 self.__portInfo[PORT_IP] = ""
03429                 self.__portInfo[PORT_ADM] = -1
03430                 self.__portInfo[PORT_IPNAME] = ""
03431                 self.__portInfo[PORT_SUBNET] = ""
03432 
03433                 self.__portInfo[SAVE_STATUS] = NO_STATUS
03434                 self.__portInfo[MODIFY_STATUS] = NO_STATUS
03435                 self.__portInfo[OLD_IP] = ""
03436 
03437                 self.__cfg = GetConfig()
03438 
03439                 if new == False:
03440                         self.Update()
03441 
03442                 self.__errormessage = ""
03443                 
03444         ##
03445         #  Since a port does not have a unique name, but a collection of several properties
03446         #               together; we create a port name with the following syntax/format:
03447         #               DEVICE_NAME: PORT NUMBER : PORT TYPE : IN/OUT
03448         #               
03449         def GetName(self):
03450         
03451                 if self.__portInfo[DEV_PORTWAY] == 1:
03452                         way = "IN"
03453                 else: #2
03454                         way = "OUT"
03455                         
03456                 tmp_name = self.__portInfo[DEV_NAME] + ": " + str(self.__portInfo[DEV_PORTNBR]) + " : " + self.__portInfo[DEV_PORTTYPE] + " : " + str(way)
03457                 
03458                 return tmp_name #DEVID:PORTNBR:PORTTYPE:PORTWAY
03459         
03460         def GetSystem(self):
03461                 return self.__portInfo[DEV_SYSTEM]
03462         def SetSystem(self,system):
03463                 Validation.ValidateSystem("System: Port",system)
03464                 self.__portInfo[DEV_SYSTEM] = system
03465         def GetDevice(self):
03466                 return self.__portInfo[DEV_NAME]
03467         def SetDevice(self,devname):
03468                 self.__portInfo[DEV_NAME] = devname
03469         def GetPortID(self):    
03470                 return self.__portInfo[DEV_PORT]
03471         def SetPortID(self,portid):
03472                 print "Portid: " + str(portid)
03473                 Validation.ValidateNumber("PortID",portid,-1)
03474                 self.__portInfo[DEV_PORT] = portid
03475         def GetPortNbr(self):
03476                 return self.__portInfo[DEV_PORTNBR]
03477         def SetPortNbr(self,portnbr):
03478                 Validation.ValidateString("PortNbr",portnbr,50)
03479                 self.__portInfo[DEV_PORTNBR] = portnbr
03480         def GetPortType(self):
03481                 return self.__portInfo[DEV_PORTTYPE]
03482         def SetPortType(self,porttype):
03483                 Validation.ValidateString("Porttype",porttype,100,True)
03484                 self.__portInfo[DEV_PORTTYPE] = porttype
03485         def GetPortWay(self):
03486                 return self.__portInfo[DEV_PORTWAY]#1 means this is input, 2 means this is output
03487         def SetPortWay(self,portway):
03488                 Validation.ValidateNumber("Portway",portway,1,2)
03489                 self.__portInfo[DEV_PORTWAY] = portway #1 means this is input, 2 means this is output
03490         def GetBia(self):
03491                 return self.__portInfo[PORT_BIA]
03492         def SetBia(self,bia):
03493                 Validation.ValidateString("Bia",bia,18,True)
03494                 self.__portInfo[PORT_BIA] = bia
03495         def GetMAC(self):
03496                 return self.__portInfo[PORT_MAC]
03497         def SetMAC(self,mac):
03498                 #Validation.ValidateString("MACAddress",macaddress,17,False,"r'^([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{1,1}$'")
03499                 Validation.ValidateString("MAC Adress",mac,18,True)
03500                 self.__portInfo[PORT_MAC] = mac
03501         def GetPortSpeed(self):
03502                 return self.__portInfo[PORT_SPEED]
03503         def SetPortSpeed(self,speed):
03504                 Validation.ValidateNumber("Port Speed",speed,0)
03505                 self.__portInfo[PORT_SPEED] = speed
03506         def GetPhy(self):
03507                 return self.__portInfo[PORT_PHY]
03508         def SetPhy(self,phy):
03509                 Validation.ValidateString("Phy",phy,3,True)
03510                 self.__portInfo[PORT_PHY] = phy
03511         def GetPXIBooting(self):
03512                 return self.__portInfo[PORT_PXI]
03513         def SetPXIBooting(self,pxi):
03514                 Validation.ValidateNumber("PXI Booting",pxi,0,1)
03515                 self.__portInfo[PORT_PXI] = pxi
03516         def GetIP(self):
03517                 return self.__portInfo[PORT_IP]
03518         def SetIP(self,ip):
03519                 Validation.ValidateString("IP",ip,15,True)
03520                 self.__portInfo[PORT_IP] = ip
03521         def SetOldIP(self,ip):
03522                 self.__portInfo[OLD_IP] = ip
03523         def GetOldIP(self):
03524                 return self.__portInfo[OLD_IP]
03525         def GetAdmStatus(self):
03526                 return self.__portInfo[PORT_ADM]
03527         def SetAdmStatus(self,admstatus):
03528                 Validation.ValidateNumber("Administrative Status",admstatus,0,1)
03529                 self.__portInfo[PORT_ADM] = admstatus
03530         def GetIPName(self):
03531                 return self.__portInfo[PORT_IPNAME]
03532         def SetIPName(self,ipname):
03533                 Validation.ValidateString("IP Name",ipname,100,True)
03534                 self.__portInfo[PORT_IPNAME] = ipname
03535         def GetSubnet(self):
03536                 return self.__portInfo[PORT_SUBNET]
03537         def SetSubnet(self,subnet):
03538                 Validation.ValidateString("Sub net",subnet,15,True)
03539                 self.__portInfo[PORT_SUBNET] = subnet
03540 
03541         def GetSaveStatus(self):
03542                 return self.__portInfo[SAVE_STATUS]
03543         def SetSaveStatus(self,status):
03544                 self.__portInfo[SAVE_STATUS] = status
03545         def GetModifyStatus(self):
03546                 return self.__portInfo[MODIFY_STATUS]
03547         def SetModifyStatus(self,status):
03548                 self.__portInfo[MODIFY_STATUS] = status #0 - normal, 1 - MACIP, 2 - IP
03549 
03550         def GetErrorMessage(self):
03551                 return self.__errormessage
03552         def SetErrorMessage(self,msg):
03553                 self.__errormessage = msg
03554         def SetDict(self,newdict):
03555                 #self.__portInfo = copy.deepcopy(newdict)
03556                 for entry in newdict:
03557                         self.__portInfo[entry] = newdict[entry]
03558 
03559         ##
03560         #  Sets the save status of this object to delete, and adds
03561         #               it to the dirty objects list for later update in the ConfDB.
03562         #               
03563         def Delete(self):
03564                 
03565                 self.__portInfo[SAVE_STATUS] = DELETE
03566                 GetAppWin().AddToDirtyObjects(self)
03567 
03568         ##
03569         #  Sets the save status of this object to modify, and adds
03570         #               it to the dirty objects list for later update in the ConfDB.
03571         #               The modify status is set in the respective Set-methods.
03572         #               
03573         def Modify(self):
03574                 self.__portInfo[SAVE_STATUS] = MODIFY
03575                 GetAppWin().AddToDirtyObjects(self)
03576 
03577         ##
03578         #  Sets the save status of this object to delete, and adds
03579         #               it to the dirty objects list for later update in the ConfDB.
03580         #               
03581         def Create(self):
03582 
03583                 self.__portInfo[SAVE_STATUS] = CREATE
03584                 GetAppWin().AddToDirtyObjects(self)
03585 
03586         ##
03587         # Get all info about a port.
03588         #                 
03589         #               TODO: Here we can have checks whether we need to look for port information in
03590         #               dirty objects list or ConfDB if this is the most recent version of the port
03591         #               object.
03592         #               
03593         #               @doNotLookUp - whether we should look for information about this object in dirty objects
03594         #               list and ConfDB (False) or not(True).
03595         #               
03596         def GetObjectInfo(self,doNotLookUp=True):
03597                 
03598                 if doNotLookUp == True:
03599                         return self.__portInfo
03600                 else:
03601                         return self.Update()
03602 
03603         ##
03604         #  Update the information/parameters for this link with the most recent information,
03605         #               and also return the member variable dictionary.
03606         # 
03607         #               Parameters:
03608         #               @doNotCheckInDirtyList - if set to True, we do not check in the dirty objects list for
03609         #               a version of the object.
03610         # 
03611         #               !return - the member variable dictionary of parameters for the link type
03612         #               
03613         def Update(self,doNotCheckInDirtyList=False):
03614 
03615                 # Dirty Objects List
03616                 if not doNotCheckInDirtyList:
03617                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
03618                                 tmp_obj = GetAppWin().GetDirtyObject(self.GetName(),Port)
03619                                 if tmp_obj != False:
03620                                         self.__portInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
03621                                         return self.__portInfo
03622                                 
03623                 # ConfDB
03624                 try:
03625                     Validation.ValidateString("Device Name",self.__portInfo[DEV_NAME])
03626                     Validation.ValidateString("PortNbr",self.__portInfo[DEV_PORTNBR],50)
03627                     Validation.ValidateString("Porttype",self.__portInfo[DEV_PORTTYPE],100,True)
03628                     Validation.ValidateNumber("Portway",self.__portInfo[DEV_PORTWAY],1,2)
03629                     
03630                     if self.__portInfo[DEV_PORTTYPE].lower() == "":
03631                         self.__portInfo[DEV_PORTTYPE] = "none"
03632 
03633                     devid = cfDB.GetDeviceID_devicename(self.__portInfo[DEV_NAME]) #devname -> devid
03634                     result = cfDB.GetPortRow_devid(devid,self.__portInfo[DEV_PORTNBR],self.__portInfo[DEV_PORTWAY],self.__portInfo[DEV_PORTTYPE])
03635                     #print "port " +str(result)
03636                     result = result[1:] #skip first '|' character
03637                     infolist = result.split("|")        #split string in list
03638 
03639                     i = 0
03640                     portInfo = {}
03641                     portInfo[DEV_SYSTEM] = self.__portInfo[DEV_SYSTEM]  #should be retrieved from db? YES..dangerous
03642                     portInfo[PORT_IPNAME] = ""
03643                     portInfo[PORT_SUBNET] = ""
03644                     portInfo[SAVE_STATUS] = -1
03645                     for i in range(len(infolist)-1):
03646                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
03647                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
03648                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
03649                         #print "Datatypes: " + datatype
03650                         #print "tmp " +str(tmp[1])
03651                         if len(tmp)==2 :
03652                             if datatype == 'I': #integer
03653                                 tmp[1] = int(tmp[1])
03654                             elif datatype == 'C': #string
03655                                 tmp[1] = tmp[1].strip()
03656                             portInfo[tmp0] = tmp[1]
03657                         else:
03658                             tmp.remove(tmp[0])
03659                             collect=":".join(tmp)
03660                             if datatype == 'I': #integer
03661                                 collect = int(collect)
03662                             elif datatype == 'C': #string
03663                                 collect= collect.strip()
03664                             portInfo[tmp0] = collect
03665                         
03666                         i += 1
03667 
03668                     if portInfo[PORT_PHY].lower() == "none":
03669                         portInfo[PORT_PHY] = ""
03670                     if portInfo[DEV_PORTTYPE].lower() == "none":
03671                         portInfo[DEV_PORTTYPE] = ""
03672 
03673                     #We have a port with ipname and subnet
03674                     if portInfo[PORT_IP] != "" or portInfo[PORT_IP].strip().lower() != "none": 
03675                         ipinfo = self.UpdateIPInfo(portInfo[PORT_IP].strip())
03676                         if ipinfo != False: #if ipinfo==false; error, but ignore
03677                                 for col in ipinfo:
03678                                         portInfo[col] = ipinfo[col]
03679 
03680                     self.__portInfo = portInfo          #same name for indexes in dictionary and name on cols in database
03681 
03682                     #change name of devname in case it has been renamed since last save
03683                     if self.__portInfo[DEV_NAME] in GetAppWin().GetOldNames():
03684                         self.__portInfo[DEV_NAME] = GetAppWin().GetNewNamesOfRenamed()[self.__portInfo[DEV_NAME]] #set to the new name of the dev
03685 
03686                     return self.__portInfo
03687                                                                                                                              
03688                 except ValidationError,err:
03689                     self.__errormessage = str(err)
03690                     return False
03691                 except DBError,err:
03692                     self.__errormessage = str(err)
03693                     return False
03694                 except RuntimeError,err:
03695                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
03696                         self.__errormessage = "Did not find the Port in the database: " + str(self.GetName())
03697                         return {} #none found
03698                     else:
03699                         self.__errormessage = str(err)
03700                     return False #on error
03701 
03702         ##
03703         #  If we have the portID for a port object; we can update the information for this
03704         #               object with info from the ConfDB usign the portID.
03705         # 
03706         #               !return - the port member variable dictionary
03707         #               
03708         def UpdateByPortID(self):
03709 
03710                 try:
03711                     Validation.ValidateNumber("PortID",self.__portInfo[DEV_PORT],0)
03712         
03713                     result = cfDB.GetPortRow_pid(self.__portInfo[DEV_PORT])
03714 
03715                     result = result[1:] #skip first '|' character
03716                     infolist = result.split("|")        #split string in list
03717 
03718                     i = 0
03719                     portInfo = {}
03720                     portInfo[DEV_SYSTEM] = GetAppWin().GetActiveSystem() #should be retrieved from db? YES..dangerous
03721                     portInfo[PORT_IPNAME] = "" #set to empty string because not retrieved from db
03722                     portInfo[PORT_SUBNET] = ""
03723                     portInfo[SAVE_STATUS] = -1
03724                     for i in range(len(infolist)-1):
03725                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
03726                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
03727                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
03728                         if len(tmp)==2 :
03729                             if datatype == 'I': #integer
03730                                 tmp[1] = int(tmp[1])
03731                             elif datatype == 'C': #string
03732                                 tmp[1] = tmp[1].strip()
03733                             portInfo[tmp0] = tmp[1]
03734                         else:
03735                             tmp.remove(tmp[0])
03736                             collect=":".join(tmp)
03737                             if datatype == 'I': #integer
03738                                 collect = int(collect)
03739                             elif datatype == 'C': #string
03740                                 collect= collect.strip()
03741                             portInfo[tmp0] = collect
03742                         i += 1
03743 
03744                     if portInfo[PORT_PHY].lower() == "none":
03745                         portInfo[PORT_PHY] = ""
03746                     if portInfo[DEV_PORTTYPE].lower() == "none":
03747                         portInfo[DEV_PORTTYPE] = ""
03748                 
03749                     # Port with IP name and subnet
03750                     if portInfo[PORT_IP] != "" or portInfo[PORT_IP].strip().lower() != "none":
03751                         ipinfo = self.UpdateIPInfo(portInfo[PORT_IP].strip())
03752                         if ipinfo != False: #if false, error, but ignore
03753                                 for col in ipinfo:
03754                                         portInfo[col] = ipinfo[col]
03755 
03756                     self.__portInfo = portInfo          #same name for indexes in dictionary and name on cols in database
03757 
03758                     #change name of devname in case it has been renamed since last save
03759                     if self.__portInfo[DEV_NAME] in GetAppWin().GetOldNames():
03760                         self.__portInfo[DEV_NAME] = GetAppWin().GetNewNamesOfRenamed()[self.__portInfo[DEV_NAME]] #set to the new name of the dev
03761                     #print "info: " + str(self.__portInfo)
03762 
03763                     return self.__portInfo
03764                                                                                                                              
03765                 except ValidationError,err:
03766                     self.__errormessage = str(err)
03767                     return False
03768                 except DBError,err:
03769                     self.__errormessage = str(err)
03770                     return False
03771                 except RuntimeError,err:
03772                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
03773                         self.__errormessage = "Did not find the Port in the database: " + str(self.GetName())
03774                         return {} #none found
03775                     else:
03776                         self.__errormessage = str(err)
03777                     return False #on error
03778 
03779         ##
03780         #  Update IP address and related network information for this port. This
03781         #               is not included in the other Update(...) method because most devices and
03782         #               ports does not have this network information.
03783         # 
03784         #               Parameters:
03785         #               @ip - the IP address (unique) of the port to be updated with info from ConfDB.
03786         #               
03787         def UpdateIPInfo(self,ip):
03788                 
03789                 try:
03790                         result = cfDB.GetIPInfoRow(ip)
03791                         result = result[1:]
03792                         infolist = result.split("|")
03793                         i = 0
03794                         portInfo = {}
03795                         for i in range(len(infolist)-1):
03796                                 tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
03797                                 tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
03798                                 datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
03799                                 #print "Datatypes: " + datatype
03800                                 if datatype == 'I': #integer
03801                                         tmp[1] = int(tmp[1])
03802                                 elif datatype == 'C': #string
03803                                         tmp[1] = tmp[1].strip()
03804         
03805                                 portInfo[tmp0] = tmp[1]
03806                                 i += 1
03807 
03808                         return portInfo
03809 
03810                 except ValidationError,err:
03811                     self.__errormessage = str(err)
03812                     return False
03813                 except DBError,err:
03814                     self.__errormessage = str(err)
03815                     return False
03816                 except RuntimeError,err:
03817                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
03818                         self.__errormessage = "Did not find the Port in the database: " + str(self.GetName())
03819                         return {} #none found
03820                     else:
03821                         self.__errormessage = str(err)
03822                     return False #on error
03823             
03824         ##
03825         #  A function that returns the string to the function that will be called in the
03826         #               ConfDBLibrary for the given save and modify status of this data object, as well as
03827         #               use of single or multiple insert.
03828         # 
03829         #               Parameters:
03830         #               Same as for Save(...)
03831         # 
03832         #               !return - returns a String with the function name as well as all set parameters
03833         #               
03834         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
03835 
03836                 save_status = self.__portInfo[SAVE_STATUS]
03837                 
03838                 if save_status == CREATE:
03839                         tmp_string = "intvector = IntVec()\n\
03840 intvector.append(%i)\n\
03841 intvector.append(%i)\n\
03842 intvector.append(%i)\n" \
03843                         %(self.__portInfo[PORT_SPEED],self.__portInfo[PORT_ADM],self.__portInfo[PORT_PXI])
03844                                 
03845                         if insertmany:
03846                                 return tmp_string + 'cfDB.InsertMultiplePorts("%s","%s",%i,"%s","%s","%s","%s","%s","%s",%s,"%s",%i,%i)' \
03847                                 %(str(self.__portInfo[DEV_NAME]),str(self.__portInfo[DEV_PORTNBR]),self.__portInfo[DEV_PORTWAY],str(self.__portInfo[DEV_PORTTYPE]),str(self.__portInfo[PORT_BIA]),str(self.__portInfo[PORT_IPNAME]),str(self.__portInfo[PORT_IP]),str(self.__portInfo[PORT_SUBNET]),str(self.__portInfo[PORT_MAC]),"intvector",str(self.__portInfo[PORT_PHY]),first,commit)
03848                         else:
03849                                 return tmp_string + 'cfDB.InsertMultiplePorts("%s","%s",%i,"%s","%s","%s","%s","%s","%s",%s,"%s",%i)' \
03850                                 %(str(self.__portInfo[DEV_NAME]),str(self.__portInfo[DEV_PORTNBR]),self.__portInfo[DEV_PORTWAY],str(self.__portInfo[DEV_PORTTYPE]),str(self.__portInfo[PORT_BIA]),str(self.__portInfo[PORT_IPNAME]),str(self.__portInfo[PORT_IP]),str(self.__portInfo[PORT_SUBNET]),str(self.__portInfo[PORT_MAC]),"intvector",str(self.__portInfo[PORT_PHY]),commit)
03851 
03852                 elif save_status == MODIFY:
03853                         if self.__portInfo[MODIFY_STATUS] == 0: #0 - normal, 1 - MACIP, 2 - IP
03854                                 #Also IP and MAC update available
03855                                 return 'cfDB.UpdateMultiplePorts("%s","%s",%i,"%s",%i,"%s",%i,%i,%i)' \
03856                                 %(str(self.__portInfo[DEV_NAME]),str(self.__portInfo[DEV_PORTNBR]),self.__portInfo[DEV_PORTWAY],str(self.__portInfo[DEV_PORTTYPE]),self.__portInfo[PORT_SPEED],str(self.__portInfo[PORT_PHY]),self.__portInfo[PORT_PXI],first,commit)
03857 
03858                         elif self.__portInfo[MODIFY_STATUS] == 1: #MACIP
03859                                 return 'cfDB.UpdateMultipleAttributeMacIPs("%s","%s","%s",%i,%i)' \
03860                                 %(str(self.__portInfo[PORT_IP]),str(self.__portInfo[PORT_SUBNET]),str(self.__portInfo[PORT_IPNAME]),first,commit)
03861                         elif self.__portInfo[MODIFY_STATUS] == 2: #IP
03862                                 return 'cfDB.UpdateMultipleIPAddresses("%s","%s",%i,%i)' \
03863                                 %(str(self.__portInfo[PORT_IP]),str(self.__portInfo[OLD_IP]),first,commit)
03864 
03865                 elif save_status == DELETE:
03866                         return 'cfDB.DeletePortRow(%i)' \
03867                         %(self.__portInfo[DEV_PORT])
03868 
03869                 else: #invalid status
03870                         return ""
03871                         
03872         ##
03873         #  Update changes to the ConfDB for this object.
03874         # 
03875         #               Parameters:
03876         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
03877         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
03878         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
03879         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
03880         #               insert function will be used, which is optimized for multiple inserts (use of cache)
03881         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
03882         #               commit is set to true, all data that are put on hold in the cache will be commited.
03883         #               
03884         def Save(self,first=False,insertmany=False,commit=True):
03885                 try:
03886                         
03887                         if self.__portInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE]:
03888                                 raise RuntimeError,"Wrong save status set, this port cannot be saved in database: " + str(self.GetName())
03889 
03890                         if self.__portInfo[SAVE_STATUS] == CREATE:
03891                                 Validation.ValidateString("Bia",self.__portInfo[PORT_BIA],18,True)
03892                                 #Validation.ValidateString("MACAddress",macaddress,17,False,"r'^([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{1,1}$'")
03893                                 Validation.ValidateString("MAC Adress",self.__portInfo[PORT_MAC],18,True)
03894                                 Validation.ValidateString("IP",self.__portInfo[PORT_IP],15,True)
03895                                 Validation.ValidateNumber("Administrative Status",self.__portInfo[PORT_ADM],0,1)
03896                                 Validation.ValidateString("IP Name",self.__portInfo[PORT_IPNAME],100,True)
03897                                 Validation.ValidateString("Sub net",self.__portInfo[PORT_SUBNET],15,True)
03898                         
03899                         if self.__portInfo[SAVE_STATUS] == CREATE or self.__portInfo[SAVE_STATUS] == MODIFY:
03900                                 Validation.ValidateString("Device Name",self.__portInfo[DEV_NAME],200)
03901                                 Validation.ValidateString("PortNbr",self.__portInfo[DEV_PORTNBR],50)
03902                                 Validation.ValidateString("Porttype",self.__portInfo[DEV_PORTTYPE],100,True)
03903                                 Validation.ValidateNumber("Portway",self.__portInfo[DEV_PORTWAY],1,2)
03904                                 
03905                                 Validation.ValidateNumber("Port Speed",self.__portInfo[PORT_SPEED],0)
03906                                 Validation.ValidateString("Phy",self.__portInfo[PORT_PHY],3,True)
03907                                 Validation.ValidateNumber("PXI Booting",self.__portInfo[PORT_PXI],0,1)
03908                                 
03909                         if self.__portInfo[SAVE_STATUS] == CREATE:
03910                                 # Needed to do it this way to create a real int vector that is supported
03911                                 # in C/C++. This IntVec() is imported from the confDBpython library.
03912                                 intvector = IntVec()
03913                                 intvector.append(self.__portInfo[PORT_SPEED])
03914                                 intvector.append(self.__portInfo[PORT_ADM])
03915                                 intvector.append(self.__portInfo[PORT_PXI])
03916                                 
03917                                 if insertmany:
03918                                         success = cfDB.InsertMultiplePorts(self.__portInfo[DEV_NAME],self.__portInfo[DEV_PORTNBR],self.__portInfo[DEV_PORTWAY],self.__portInfo[DEV_PORTTYPE],self.__portInfo[PORT_BIA],self.__portInfo[PORT_IPNAME],self.__portInfo[PORT_IP],self.__portInfo[PORT_SUBNET],self.__portInfo[PORT_MAC],intvector,self.__portInfo[PORT_PHY],first,commit)
03919                                 else:
03920                                         
03921                                         print (self.__portInfo[DEV_NAME],self.__portInfo[DEV_PORTNBR],self.__portInfo[DEV_PORTTYPE],self.__portInfo[DEV_PORTWAY],self.__portInfo[PORT_BIA],self.__portInfo[PORT_IPNAME],self.__portInfo[PORT_IP],self.__portInfo[PORT_SUBNET],self.__portInfo[PORT_MAC],intvector,self.__portInfo[PORT_PHY],commit)             
03922                                         success = cfDB.InsertPort(self.__portInfo[DEV_NAME],self.__portInfo[DEV_PORTNBR],self.__portInfo[DEV_PORTTYPE],self.__portInfo[DEV_PORTWAY],self.__portInfo[PORT_BIA],self.__portInfo[PORT_IPNAME],self.__portInfo[PORT_IP],self.__portInfo[PORT_SUBNET],self.__portInfo[PORT_MAC],intvector,self.__portInfo[PORT_PHY],commit)
03923                                         
03924                                 if commit:
03925                                         self.Update(True) #update with data from database (port ID set)
03926 
03927                         elif self.__portInfo[SAVE_STATUS] == MODIFY: #modify
03928                                 if self.__portInfo[MODIFY_STATUS] == 0: #0 - normal, 1 - MACIP, 2 - IP
03929                                         #Also IP and MAC update available
03930                                         success = cfDB.UpdateMultiplePorts(self.__portInfo[DEV_NAME],self.__portInfo[DEV_PORTNBR],self.__portInfo[DEV_PORTWAY],self.__portInfo[DEV_PORTTYPE],self.__portInfo[PORT_SPEED],self.__portInfo[PORT_PHY],self.__portInfo[PORT_PXI],first,commit)
03931 
03932                                 elif self.__portInfo[MODIFY_STATUS] == 1: #MACIP
03933                                         success = cfDB.UpdateMultipleAttributeMacIPs(self.__portInfo[PORT_IP],self.__portInfo[PORT_SUBNET],self.__portInfo[PORT_IPNAME],first,commit)
03934                                 elif self.__portInfo[MODIFY_STATUS] == 2: #IP
03935                                         success = cfDB.UpdateMultipleIPAddresses(self.__portInfo[PORT_IP],self.__portInfo[OLD_IP],first,commit)
03936 
03937                                 if commit:
03938                                         self.Update(True)
03939 
03940                         elif self.__portInfo[SAVE_STATUS] == DELETE: #delete
03941                                 if DEV_PORT in self.__portInfo.keys() and self.__portInfo[DEV_PORT] != -1:
03942                                         success = cfDB.DeletePortRow(self.__portInfo[DEV_PORT])
03943                                 else:
03944                                         GetAppWin().ShowError("The Port cannot be deleted because it doesnt have a portID set yet.",ERR_ERROR)
03945 
03946                         return True
03947                 
03948                 except ValidationError,err:
03949                     print "validation error "
03950                     self.__errormessage = str(err)
03951                     return False
03952                 except DBError,err:
03953                     print "DB error"
03954                     self.__errormessage = str(err)
03955                     return False
03956                 except RuntimeError,err:
03957                     print "run Time Error"
03958                     self.__errormessage = str(err)
03959                     return False #on error
03960                 except ValueError,err:
03961                     self.__errormessage = str("Device Name is not a string.")
03962                     return False
03963 
03964         #added by Lana
03965 ##
03966 # Class for storing information about a spare device. A spare device is a physical device with no connections
03967 #       
03968 class Spare_Device(DBInfo):
03969 
03970         ##
03971         #  Constructor.
03972         # 
03973         #               Parameters:
03974         #               @hwname - the  name of the spare device, given by the user. like SPARE_HYBRUD_01 optional
03975         #               @hwtype - should be prefixed by the system if it is only meant for a specific subsystem
03976         #               @serialnb- serialnb 
03977         #               @new        - whether the device is about to be created, or is already created.
03978         #               True if it is being created, False if not. If it is already created, we will
03979         #               fill the object with goods. (names and values)
03980         #               
03981         def __init__(self,hwtype,serialnb, hwname="",new=True):
03982                 
03983                 self.__errormessage = ""
03984 
03985                 self.__sparedeviceInfo = {}     #all device info that is common for all devices
03986                 self.__sparedeviceInfo[DEV_OBJECT] = obj_NODE
03987                 self.__sparedeviceInfo[SPARE_DEV_NAME] = hwname
03988 
03989                 self.__sparedeviceInfo[DEV_SERIAL] = serialnb # serial number
03990                 self.__sparedeviceInfo[DEV_HWTYPE] = "" # hardware type
03991                 self.__sparedeviceInfo[DEV_RESPONSIBLE] = "" # responsible for the device
03992                 self.__sparedeviceInfo[DEV_LOCATION] = "" # location string
03993                 self.__sparedeviceInfo[DEV_COMMENTS] = "" # comments/description
03994                 self.__sparedeviceInfo[SPARE_DEV_COLOUR] = "(255, 255, 255)" #wxColour(255,255,255)
03995                 self.__sparedeviceInfo[SPARE_OLD_SERIAL] = "" # if spare device has been renamed new serial nb), we store the old/previous name here
03996                 # We need to keep track of some parameters; whether they have been changed when the user modified the object
03997                 # or not because we have different modify functions for different parameters.
03998                 self.__sparedeviceInfo[MODIFY_STATUS] = NO_STATUS #0 - standard modify, 1 - change system list, NO_STATUS: not set
03999 
04000                 self.__sparedeviceInfo[SAVE_STATUS] = NO_STATUS
04001 
04002                 self.__spareports = [] # ports retrieved, of this device
04003                 self.__cfg = GetConfig() # configuration file reference
04004 
04005 
04006                 if new == False:
04007                         self.Update()
04008 
04009         ### GET ###
04010         def GetModifyStatus(self):
04011                 return self.__sparedeviceInfo[MODIFY_STATUS]
04012         def GetComments(self):
04013                 return self.__sparedeviceInfo[DEV_COMMENTS]
04014         def GetLocation(self):
04015                 return self.__sparedeviceInfo[DEV_LOCATION]
04016         def GetResponsible(self):
04017                 return self.__sparedeviceInfo[DEV_RESPONSIBLE]
04018         def GetHWType(self):
04019                 return self.__sparedeviceInfo[DEV_HWTYPE]
04020         def GetSerial(self):
04021                 return self.__sparedeviceInfo[DEV_SERIAL]
04022         def GetOldName(self):
04023                 return self.__sparedeviceInfo[SERIAL_OLD_SERIAL]
04024         def GetSaveStatus(self):
04025                 return self.__sparedeviceInfo[SAVE_STATUS] #set INSERT, DELETE and UPDATE as constants
04026         def GetHWName(self):
04027                 return self.__sparedeviceInfo[SPARE_DEV_NAME]
04028         def GetColour(self):
04029                 return self.__sparedeviceInfo[SPARE_DEV_COLOUR]
04030         def GetTheDict(self):
04031                 return self.__sparedeviceInfo
04032         def GetErrorMessage(self):
04033                 return self.__errormessage
04034         def GetName(self):
04035                 return self.__sparedeviceInfo[DEV_SERIAL]
04036         
04037         ### SET ###
04038         def SetModifyStatus(self,status):
04039                 self.__sparedeviceInfo[MODIFY_STATUS] = status
04040         def SetComments(self,comments):
04041                 Validation.ValidateString("User comments",comments,1000,True)
04042                 self.__sparedeviceInfo[DEV_COMMENTS] = comments
04043         def SetLocation(self,location):
04044                 Validation.ValidateString("Location",location,200,True)
04045                 self.__sparedeviceInfo[DEV_LOCATION] = location
04046         def SetResponsible(self,responsible):
04047                 Validation.ValidateString("Responsible",responsible,100,True)
04048                 self.__sparedeviceInfo[DEV_RESPONSIBLE] = responsible
04049         def SetHWType(self,hwtype):
04050                 Validation.ValidateString("Hardware type",hwtype,200,True)
04051                 self.__sparedeviceInfo[DEV_HWTYPE] = hwtype
04052         def SetHWType(self,hwname):
04053                 Validation.ValidateString("Hardware name",hwname,200,True)
04054                 self.__sparedeviceInfo[SPARE_DEV_NAME] = hwname
04055         def SetSerial(self,serial):
04056                 Validation.ValidateString("Serial number",serial,500)
04057                 self.__sparedeviceInfo[DEV_SERIAL] = serialnb
04058         def SetOldName(self,oldname):
04059                 self.__sparedeviceInfo[SPARE_OLD_SERIAL] = oldserial
04060         def SetSaveStatus(self,state):
04061                 self.__sparedeviceInfo[SAVE_STATUS] = state
04062         def SetErrorMessage(self,msg):
04063                 self.__errormessage = msg
04064 
04065         def SetDict(self,newdict):
04066                 for entry in newdict:
04067                         self.__sparedeviceInfo[entry] = newdict[entry]
04068                 #self.__sparedeviceInfo = copy.deepcopy(newdict)
04069 
04070         ##
04071         #  Copy device info from one device to another (this one).
04072         #               
04073         def SetAllInfoDict(self,devinfo):
04074                 my_serial = self.__sparedeviceInfo[DEV_SERIAL]
04075                 self.__sparedeviceInfo = {}
04076                 for item in devinfo:
04077                         self.__sparedeviceInfo[item] = devinfo[item]
04078                 self.__sparedeviceInfo[DEV_SERIAL] = my_serial
04079         
04080 
04081         ##
04082         #  Get all info about a device in a subsystem, given the unique name of a device.
04083         #               
04084         #               Here we do some check where to get the properies information from, f.ex. whether
04085         #               this device object is the most recent object in dirty list; if so we can just return
04086         #               this objects dictionary. TODO.
04087         # 
04088         #               @doNotLookUp - whether we should look for information about this object in dirty objects
04089         #               list and ConfDB (False) or not(True).
04090         #               
04091         def GetObjectInfo(self,doNotLookUp=True):
04092                 if doNotLookUp == True:
04093                         return self.__sparedeviceInfo
04094                 else:
04095                         self.Update()
04096                         
04097                 return self.__sparedeviceInfo
04098 
04099         ##
04100         #  Here we update the device with the most recent information about the device witht the
04101         #               given information; either in dirty objects list (if found and in creation mode), or from
04102         #               ConfDB.
04103         # 
04104         #               @doNotCheckInDirtyList - if True, we do not check in dirty objects list, but go straight
04105         #               forward to the ConfDB and look for information about this device there.
04106         #               
04107         def Update(self,doNotCheckInDirtyList=False):
04108         
04109                 # Dirty Objects List
04110                 if not doNotCheckInDirtyList:
04111                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
04112                                 tmp_obj = GetAppWin().GetDirtyObject(self.__sparedeviceInfo[SPARE_DEV_NAME],Spare_Device)
04113                                 if tmp_obj != False:
04114                                         self.__sparedeviceInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
04115                                         return self.__sparedeviceInfo
04116 
04117                 # ConfDB
04118                 try:
04119                         Validation.ValidateString("Spare hw serial nb",self.__sparedeviceInfo[DEV_SERIAL],100)
04120                         result = cfDB.GetHWDeviceRow_serialnb (self.__sparedeviceInfo[DEV_SERIAL])
04121                         #print 'get spare '+str(result)
04122                         result = result[1:]     #skip first | character
04123                         infolist = result.split("|")    #split string in list
04124                         i = 0
04125                         sparedeviceInfo = {DEV_OBJECT : obj_NODE}       #To identify this as a devicenode (as opposite to a linknode)
04126                         sparedeviceInfo[SPARE_DEV_COLOUR] = wxColour(red=255,green=255,blue=255) #changed to device type
04127                         sparedeviceInfo[DEV_HWTYPE] = ""
04128                         sparedeviceInfo[DEV_RESPONSIBLE] = ""
04129                         sparedeviceInfo[DEV_COMMENTS] = ""
04130                         sparedeviceInfo[MODIFY_STATUS] = NO_STATUS
04131                 
04132                         for i in range(len(infolist)-1):
04133                                 tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
04134                                 tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
04135                                 datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
04136                                 if datatype == 'I': #integer
04137                                         tmp[1] = int(tmp[1])
04138                                 elif datatype == 'C': #string
04139                                         tmp[1] = tmp[1].strip()
04140                                 sparedeviceInfo[tmp0] = tmp[1]
04141                                 i += 1
04142 
04143                         self.__sparedeviceInfo = sparedeviceInfo
04144 
04145                 
04146                         
04147                         return self.__sparedeviceInfo
04148                                                                                                                              
04149                 except ValidationError,err:
04150                     self.__errormessage = str(err)
04151                     return False
04152                 except DBError,err:
04153                     self.__errormessage = str(err)
04154                     return False
04155                 except RuntimeError,err:
04156                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
04157                         self.__errormessage = "No information found in the database on the given device: " + str(self.__sparedeviceInfo[DEV_SERIAL])
04158                         return {}
04159                     else:
04160                         self.__errormessage = str(err)
04161                         return False #on error
04162 
04163 
04164 
04165         
04166 
04167 
04168         ##
04169         #  Get all ports assigned to a device as port objects in a list.
04170         #               Look for ports in both dirty objects list and ConfDB.
04171         # 
04172         #               !return - list of port objects for the ports of a device.
04173         #               
04174         def GetSparePorts(self):
04175 
04176                 # 1. Get all ports assigned to this device in dirty objects list; if in creation mode
04177                 # 2. Get all portIDs assigned to this device from ConfDB; filter out those that were already found in dirty
04178                 # objects list
04179                 # 3. Retrieve all info for each port; from ConfDB or dirty objects list.
04180                 # 4. Return the port objects in a list.
04181 
04182                 try:
04183                         portids=[]
04184                         dirty_objs_ports=[]
04185                         tbd=[]
04186                         my_ports=[]
04187                         i=0
04188                         Validation.ValidateString("Serial number",self.__sparedeviceInfo[DEV_SERIAL],500)
04189                         portids = cfDB.GetPortInfoPerSpare(self.__sparedeviceInfo[DEV_SERIAL])
04190                         #print 'portids ' +str(portids[0])
04191                         if portids == False:
04192                                 raise RuntimeError,str(self.GetErrorMessage())
04193                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
04194                         for obj in tmp_dirtyobjs:
04195                                         if obj.__class__ == Spare_Port:
04196                                                 if obj.GetSpareDevice() == self.GetName(): #port of this device
04197                                                         if obj.GetSaveStatus() != DELETE:
04198                                                                 if obj.GetName() in dirty_objs_ports:
04199                                                                         i = 0
04200                                                                         for port in my_ports:
04201                                                                                 if port.GetName() == obj.GetName():
04202                                                                                         # Newer version found; replace
04203                                                                                         my_ports.pop(i)
04204                                                                                 i += 1
04205                                                                                                 
04206                                                                 my_ports.append(obj)
04207                                                                 dirty_objs_ports.append(obj.GetName())
04208                                                         else: #found port that is set to deleted, look for identical in dl
04209                                                                 print "infodel: " + str(obj.GetObjectInfo(True))
04210                                                                 print "Deleted obj: " + str(obj.GetName())
04211                                                                 if obj.GetName() in dirty_objs_ports:
04212                                                                         # del port found, del port if found in dirty objs
04213                                                                         i = 0
04214                                                                         while i < len(my_ports):
04215                                                                                 if my_ports[i].GetName() == obj.GetName():
04216                                                                                         my_ports.pop(i)
04217                                                                                         break
04218                                                                                 i += 1
04219                                                                                 
04220                                                                 tbd.append(obj.GetName())
04221                         while i < len(portids):
04222                                 port_tmp = portids[i].split("|")
04223                                 tmp_port = Spare_Port(port_tmp[0],port_tmp[1],port_tmp[2],self.__sparedeviceInfo[DEV_SERIAL],True)
04224                                 #print "port_tmp "+ str(port_tmp[2])
04225                                 tmp_port.SetMAC(port_tmp[3])
04226                                 tmp_port.SetBia(port_tmp[4])
04227                                 #print "value = "+ tmp_port.GetBia()
04228                                 i += 1
04229                                 if tmp_port.GetSpareDevice() not in dirty_objs_ports and tmp_port.GetName() not in tbd: 
04230                                         #in case we have a newer version in the dirty objects list
04231                                         #or the port is set to be deleted in dl
04232                                         my_ports.append(tmp_port)
04233 
04234 
04235                             
04236                                                 
04237                                                 
04238                         self.__spareports = my_ports
04239                         return self.__spareports
04240 
04241                 except ValidationError,err:
04242                     self.__errormessage = str(err)
04243                     return False
04244                 except DBError,err:
04245                     self.__errormessage = str(err)
04246                     return False
04247                 except RuntimeError,err:
04248                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
04249                         if portids == []:
04250                                 self.__errormessage = "No ports found for the selected device " + str(self.__sparedeviceInfo[DEV_SERIAL])
04251                                 return [] #none found
04252                         else: #didnt find ports in db, but we found in dirty list
04253                                 self.__ports = portids
04254                                 return self.__ports
04255                     else:
04256                         self.__errormessage = str(err)
04257                     return False #on error #NB! Change when error is fixed in DB moduel !!!!!
04258 
04259 
04260             
04261         ##
04262         #  A function that returns the string to the function that will be called in the
04263         #               ConfDBLibrary for the given save and modify status of this data object, as well as
04264         #               use of single or multiple insert.
04265         # 
04266         #               Parameters:
04267         #               Same as for Save(...)
04268         # 
04269         #               !return - returns a String with the function name as well as all set parameters
04270         #               
04271         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
04272 
04273                 save_status = self.__sparedeviceInfo[SAVE_STATUS]
04274         
04275                 if save_status == CREATE:
04276                         if insertmany:
04277                                 return 'cfDB.InsertMultipleSpareDevices("%s","%s","%s","%s","%s","%s",%i,%i)' \
04278                                 %(str(self.__sparedeviceInfo[SPARE_DEV_NAME]),str(self.__sparedeviceInfo[DEV_HWTYPE]),str(self.__sparedeviceInfo[DEV_SERIAL]),str(self.__sparedeviceInfo[DEV_RESPONSIBLE]),str(self.__sparedeviceInfo[DEV_LOCATION]),str(self.__sparedeviceInfo[DEV_COMMENTS]),first,commit)
04279                         else:
04280                                 return 'cfDB.InsertSpareDevice("%s","%s","%s","%s","%s","%s",%i)' \
04281                                 %(str(self.__sparedeviceInfo[SPARE_DEV_NAME]),str(self.__sparedeviceInfo[DEV_HWTYPE]),str(self.__sparedeviceInfo[DEV_SERIAL]),str(self.__sparedeviceInfo[DEV_RESPONSIBLE]),str(self.__sparedeviceInfo[DEV_LOCATION]),str(self.__sparedeviceInfo[DEV_COMMENTS]),commit)
04282                 
04283                 
04284                 elif save_status == DELETE:
04285                         return 'cfDB.DeleteHWDevice("%s")'\
04286                         %(str(self.sparedeviceInfo[DEV_SERIAL]))
04287 
04288                 elif save_status == RENAME:
04289                         return 'cfDB.UpdateHWSerialNB ("%s","%s")' \
04290                         %(str(self.__sparedeviceInfo[SPARE_OLD_SERIAL]),str(self.__sparedeviceInfo[DEV_SERIAL]))
04291         
04292                 else: #invalid status
04293                         return ""
04294 
04295 
04296         ##
04297         #  Update changes to the ConfDB for this object.
04298         # 
04299         #               Parameters:
04300         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
04301         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
04302         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
04303         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
04304         #               insert function will be used, which is optimized for multiple inserts (use of cache)
04305         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
04306         #               commit is set to true, all data that are put on hold in the cache will be commited.
04307         #               
04308         def Save(self,first=False,insertmany=False,commit=True):
04309                 
04310                 try:
04311                         if self.__sparedeviceInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE,RENAME]:
04312                                 raise ValidationError,"This object should not be in the dirty list or has incorrect savestatus setting"
04313 
04314                         if self.__sparedeviceInfo[SAVE_STATUS] == DELETE:
04315                                 GetAppWin().ShowError("A device cannot be deleted, only internally before stored in the database.",ERR_ERROR)
04316                         if self.__sparedeviceInfo[SAVE_STATUS] == RENAME:
04317                                 Validation.ValidateString("Device name",self.__sparedeviceInfo[DEV_SERIAL],100)
04318 
04319                         if self.__sparedeviceInfo[SAVE_STATUS] == CREATE or self.__sparedeviceInfo[SAVE_STATUS] == MODIFY:
04320                                 Validation.ValidateString("HW name",self.__sparedeviceInfo[SPARE_DEV_NAME],100)
04321                                 Validation.ValidateString("Serial number",self.__sparedeviceInfo[DEV_SERIAL],500)
04322                                 Validation.ValidateString("Hardware type",self.__sparedeviceInfo[DEV_HWTYPE],200,True)
04323                                 Validation.ValidateString("Responsible",self.__sparedeviceInfo[DEV_RESPONSIBLE],100,True)
04324                                 Validation.ValidateString("Location",self.__sparedeviceInfo[DEV_LOCATION],200,True)
04325                                 Validation.ValidateString("Comments",self.__sparedeviceInfo[DEV_COMMENTS],1000,True)
04326 
04327                         if self.__sparedeviceInfo[SAVE_STATUS] == CREATE:
04328                                 if insertmany:
04329                                         success = cfDB.InsertMultipleSpareDevices(self.__sparedeviceInfo[SPARE_DEV_NAME],self.__sparedeviceInfo[DEV_HWTYPE],self.__sparedeviceInfo[DEV_SERIAL],self.__sparedeviceInfo[DEV_RESPONSIBLE],self.__sparedeviceInfo[DEV_LOCATION],self.__sparedeviceInfo[DEV_COMMENTS],first,commit)
04330                                 else:
04331                                         success = cfDB.InsertSpareDevice(self.__sparedeviceInfo[SPARE_DEV_NAME],self.__sparedeviceInfo[DEV_HWTYPE],self.__sparedeviceInfo[DEV_SERIAL],self.__sparedeviceInfo[DEV_RESPONSIBLE],self.__sparedeviceInfo[DEV_LOCATION],self.__sparedeviceInfo[DEV_COMMENTS],commit)
04332                                 if commit:
04333                                         self.Update(True)
04334 
04335                                 
04336                         elif self._deviceInfo[SAVE_STATUS] == RENAME:
04337                                 success = cfDB.UpdateHWSerialNB(self.__sparedeviceInfo[SPARE_OLD_SERIAL],self.__sparedeviceInfo[DEV_SERIAL])
04338                                 if commit:
04339                                         self.Update(True)
04340                                 
04341                         elif self._deviceInfo[SAVE_STATUS] == DELETE:
04342                                 success = cfDB.DeleteHWDevice(self.__sparedeviceInfo[DEV_SERIAL])
04343                                 if commit:
04344                                         self.Update(True)
04345 
04346                         return True
04347 
04348                 except ValidationError,err:
04349                         self.__errormessage = str(err)
04350                         return False
04351                 except DBError,err:
04352                         self.__errormessage = str(err)
04353                         return False
04354                 except RuntimeError,err:
04355                         self.__errormessage = str(err)
04356                         return False #on error
04357 
04358         ##
04359         #  Sets the save status of this object to delete, and adds
04360         #               it to the dirty objects list for later update in the ConfDB.
04361         #               
04362         def Delete(self):
04363                 
04364                 self.__sparedeviceInfo[SAVE_STATUS] = DELETE
04365                 GetAppWin().AddToDirtyObjects(self)
04366 
04367         ##
04368         # Sets the save status of this object to modify, and
04369         #               adds it to the dirty objects list for later update in the ConfDB.
04370         #               The Modify status is set in the respective Set-functions for the
04371         #               parameters they change.
04372         #               
04373         def Modify(self,commit=1):
04374                 self.__sparedeviceInfo[SAVE_STATUS] = MODIFY
04375                 GetAppWin().AddToDirtyObjects(self)
04376 
04377         ##
04378         #  Sets the save status of this object to create, and adds it
04379         #               to the dirty objects list for later update in the ConfDB.
04380         #               
04381         def Create(self):
04382                 
04383                 self.__sparedeviceInfo[SAVE_STATUS] = CREATE
04384                 GetAppWin().AddToDirtyObjects(self)
04385         
04386         
04387         
04388 
04389 
04390 
04391 ##
04392 #  A port is a physical part of a device; f.ex. a port on a switch. So this class contains
04393 #       properties (member variables) and methods for a port of a spare device instance.
04394 #       
04395 class Spare_Port(DBInfo):
04396 
04397         ##
04398         #  Constructor.
04399         # 
04400         #               Parameters:
04401         #               @portnbr - the port number, a string and usually an integer, not unique alone.
04402         #               @porttype -  the port type, a string, not unique alone.
04403         #               @portway - the port way (direction, in or out). It is unique together with port number 
04404         #               and port type it for a device.
04405         #               @serialnb - serailn of the spare device, of which this port belongs to. Together with port number,
04406         #               port type and port way it is unique .
04407         #               
04408         def __init__(self,portnbr="",porttype="",portway=PORT_IN,serialnb="",new=True):
04409 
04410                 self.__spareportInfo = {}
04411                 self.__spareportInfo[DEV_PORTNBR] = portnbr
04412                 self.__spareportInfo[DEV_PORTTYPE] = porttype
04413                 self.__spareportInfo[DEV_PORTWAY] = portway #1 means this is input (IN), 2 means this is output (OUT)
04414                 self.__spareportInfo[DEV_SERIAL] = serialnb #serialnb, must be set to id of device when update from db
04415 
04416                 self.__spareportInfo[PORT_BIA] = ""
04417                 self.__spareportInfo[PORT_MAC] = ""
04418         
04419                 self.__spareportInfo[SAVE_STATUS] = NO_STATUS
04420                 self.__spareportInfo[MODIFY_STATUS] = NO_STATUS
04421 
04422                 self.__cfg = GetConfig()
04423 
04424                 if new == False:
04425                         self.Update()
04426 
04427                 self.__errormessage = ""
04428                 
04429         ##
04430         #  Since a port does not have a unique name, but a collection of several properties
04431         #               together; we create a port name with the following syntax/format:
04432         #               SERIALNB: PORT NUMBER : PORT TYPE : IN/OUT
04433         #               
04434         def GetName(self):
04435         
04436                 if self.__spareportInfo[DEV_PORTWAY]==1 or self.__spareportInfo[DEV_PORTWAY]=='1' :
04437                         way = "IN"
04438                 else: #2
04439                         way = "OUT"
04440                 #print 'port way ' +str(self.__spareportInfo[DEV_PORTWAY])
04441                 #print 'port way 2' + way
04442                 tmp_name = self.__spareportInfo[DEV_SERIAL] + ": " + self.__spareportInfo[DEV_PORTNBR] + " : " + self.__spareportInfo[DEV_PORTTYPE] + " : " + str(way)
04443                 
04444                 return tmp_name #SERIAL:PORTNBR:PORTTYPE:PORTWAY
04445         
04446         def GetSpareDevice(self):
04447                 return self.__spareportInfo[DEV_SERIAL]
04448         def SetSpareDevice(self,serial):
04449                 self.__spareportInfo[DEV_SERIAL] = serial
04450         def GetPortNbr(self):
04451                 return self.__spareportInfo[DEV_PORTNBR]
04452         def SetPortNbr(self,portnbr):
04453                 Validation.ValidateString("PortNbr",portnbr,50)
04454                 self.__spareportInfo[DEV_PORTNBR] = portnbr
04455         def GetPortType(self):
04456                 return self.__spareportInfo[DEV_PORTTYPE]
04457         def SetPortType(self,porttype):
04458                 Validation.ValidateString("Porttype",porttype,100,True)
04459                 self.__spareportInfo[DEV_PORTTYPE] = porttype
04460         def GetPortWay(self):
04461                 return self.__spareportInfo[DEV_PORTWAY]#1 means this is input, 2 means this is output
04462         def SetPortWay(self,portway):
04463                 Validation.ValidateNumber("Portway",portway,1,2)
04464                 self.__spareportInfo[DEV_PORTWAY] = portway #1 means this is input, 2 means this is output
04465         def GetBia(self):
04466                 return self.__spareportInfo[PORT_BIA]
04467         def SetBia(self,bia):
04468                 Validation.ValidateString("Bia",bia,18,True)
04469                 self.__spareportInfo[PORT_BIA] = bia
04470         def GetMAC(self):
04471                 return self.__spareportInfo[PORT_MAC]
04472         def SetMAC(self,mac):
04473                 #Validation.ValidateString("MACAddress",macaddress,17,False,"r'^([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{1,1}$'")
04474                 Validation.ValidateString("MAC Adress",mac,18,True)
04475                 self.__spareportInfo[PORT_MAC] = mac
04476         def GetSaveStatus(self):
04477                 return self.__spareportInfo[SAVE_STATUS]
04478         def SetSaveStatus(self,status):
04479                 self.__spareportInfo[SAVE_STATUS] = status
04480         def GetModifyStatus(self):
04481                 return self.__spareportInfo[MODIFY_STATUS]
04482         def SetModifyStatus(self,status):
04483                 self.__spareportInfo[MODIFY_STATUS] = status #0 - normal, 1 - MACIP, 2 - IP
04484 
04485         def GetErrorMessage(self):
04486                 return self.__errormessage
04487         def SetErrorMessage(self,msg):
04488                 self.__errormessage = msg
04489         def SetDict(self,newdict):
04490                 #self.__portInfo = copy.deepcopy(newdict)
04491                 for entry in newdict:
04492                         self.__spareportInfo[entry] = newdict[entry]
04493 
04494         ##
04495         #  Sets the save status of this object to delete, and adds
04496         #               it to the dirty objects list for later update in the ConfDB.
04497         #               
04498         def Delete(self):
04499                 
04500                 self.__spareportInfo[SAVE_STATUS] = DELETE
04501                 GetAppWin().AddToDirtyObjects(self)
04502 
04503         ##
04504         #  Sets the save status of this object to modify, and adds
04505         #               it to the dirty objects list for later update in the ConfDB.
04506         #               The modify status is set in the respective Set-methods.
04507         #               
04508         def Modify(self):
04509                 self.__spareportInfo[SAVE_STATUS] = MODIFY
04510                 GetAppWin().AddToDirtyObjects(self)
04511 
04512         ##
04513         #  Sets the save status of this object to delete, and adds
04514         #               it to the dirty objects list for later update in the ConfDB.
04515         #               
04516         def Create(self):
04517 
04518                 self.__spareportInfo[SAVE_STATUS] = CREATE
04519                 GetAppWin().AddToDirtyObjects(self)
04520 
04521         ##
04522         # Get all info about a port.
04523         #                 
04524         #               TODO: Here we can have checks whether we need to look for port information in
04525         #               dirty objects list or ConfDB if this is the most recent version of the port
04526         #               object.
04527         #               
04528         #               @doNotLookUp - whether we should look for information about this object in dirty objects
04529         #               list and ConfDB (False) or not(True).
04530         #               
04531         def GetObjectInfo(self,doNotLookUp=True):
04532                 
04533                 if doNotLookUp == True:
04534                         return self.__spareportInfo
04535                 else:
04536                         return self.Update()
04537 
04538         ##
04539         #  Update the information/parameters for this link with the most recent information,
04540         #               and also return the member variable dictionary.
04541         # 
04542         #               Parameters:
04543         #               @doNotCheckInDirtyList - if set to True, we do not check in the dirty objects list for
04544         #               a version of the object.
04545         # 
04546         #               !return - the member variable dictionary of parameters for the link type
04547         #               
04548         def Update(self,doNotCheckInDirtyList=False):
04549 
04550                 # Dirty Objects List
04551                 if not doNotCheckInDirtyList:
04552                         if GetAppWin().GetUserMode() == ID_CREATION_MODE:
04553                                 tmp_obj = GetAppWin().GetDirtyObject(self.GetName(),Spare_Port)
04554                                 if tmp_obj != False:
04555                                         self.__spareportInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
04556                                         return self.__spareportInfo
04557                                 
04558                 # ConfDB
04559                 try:
04560                     Validation.ValidateString("Serial nb",self.__spareportInfo[DEV_SERIAL])
04561                     Validation.ValidateString("PortNbr",self.__spareportInfo[DEV_PORTNBR],50)
04562                     Validation.ValidateString("Porttype",self.__spareportInfo[DEV_PORTTYPE],100,True)
04563                     Validation.ValidateNumber("Portway",self.__spareportInfo[DEV_PORTWAY],1,2)
04564                     
04565                     if self.__spareportInfo[DEV_PORTTYPE].lower() == "":
04566                         self.__spareportInfo[DEV_PORTTYPE] = "none"
04567                     #print 'self.__spareportInfo[DEV_SERIAL]' + str(self.__spareportInfo[DEV_PORTNBR]) +'test'
04568                     #print 'self.__spareportInfo[DEV_SERIAL]' + str(self.__spareportInfo[DEV_PORTTYPE])+ 'test'
04569                     #print 'self.__spareportInfo[DEV_SERIAL]' + str(self.__spareportInfo[DEV_PORTWAY])+ 'test'
04570                     #print 'self.__spareportInfo[DEV_SERIAL]' + str(self.__spareportInfo[DEV_SERIAL])+ 'test'
04571                     
04572                     result = cfDB.GetSparePortRow_snb(str(self.__spareportInfo[DEV_SERIAL]),str(self.__spareportInfo[DEV_PORTNBR]),self.__spareportInfo[DEV_PORTWAY],str(self.__spareportInfo[DEV_PORTTYPE]))
04573                     #print 'getspare ' + str(result)
04574                     result = result[1:] #skip first '|' character
04575                     infolist = result.split("|")        #split string in list
04576 
04577                     i = 0
04578                     portInfo = {}
04579                     portInfo[SAVE_STATUS] = -1
04580                     for i in range(len(infolist)-1):
04581                         tmp = infolist[i].split(":")            #split each property, name on left site, value on right side
04582                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
04583                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
04584                         
04585                         if len(tmp)==2 :
04586                             if datatype == 'I': #integer
04587                                 tmp[1] = int(tmp[1])
04588                             elif datatype == 'C': #string
04589                                 tmp[1] = tmp[1].strip()
04590                             portInfo[tmp0] = tmp[1]
04591                         else:
04592                             tmp.remove(tmp[0])
04593                             collect=":".join(tmp)
04594                             if datatype == 'I': #integer
04595                                 collect = int(collect)
04596                             elif datatype == 'C': #string
04597                                 collect= collect.strip()
04598                             portInfo[tmp0] = collect
04599                         i += 1
04600                         
04601                             
04602                             
04603                     if portInfo[DEV_PORTTYPE].lower() == "none":
04604                         portInfo[DEV_PORTTYPE] = ""
04605 
04606                    
04607                     self.__spareportInfo = portInfo             #same name for indexes in dictionary and name on cols in database
04608 
04609                    
04610                     return self.__spareportInfo
04611                                                                                                                              
04612                 except ValidationError,err:
04613                     self.__errormessage = str(err)
04614                     return False
04615                 except DBError,err:
04616                     self.__errormessage = str(err)
04617                     return False
04618                 except RuntimeError,err:
04619                     if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
04620                         self.__errormessage = "Did not find the Port in the database: " + str(self.GetName())
04621                         return {} #none found
04622                     else:
04623                         self.__errormessage = str(err)
04624                     return False #on error
04625 
04626 
04627             
04628         ##
04629         #  A function that returns the string to the function that will be called in the
04630         #               ConfDBLibrary for the given save and modify status of this data object, as well as
04631         #               use of single or multiple insert.
04632         # 
04633         #               Parameters:
04634         #               Same as for Save(...)
04635         # 
04636         #               !return - returns a String with the function name as well as all set parameters
04637         #               
04638         def PrintSaveFunction(self,first=False,insertmany=False,commit=True):
04639 
04640                 save_status = self.__spareportInfo[SAVE_STATUS]
04641                 
04642                 if save_status == CREATE:
04643                                         
04644                         if insertmany:
04645                                 return tmp_string + 'cfDB.InsertMultipleSparePorts("%s","%s",%i,"%s","%s","%s",%i,%i)' \
04646                                 %(str(self.__spareportInfo[DEV_SERIAL]),str(self.__spareportInfo[DEV_PORTNBR]),self.__spareportInfo[DEV_PORTWAY],str(self.__spareportInfo[DEV_PORTTYPE]),str(self.__spareportInfo[PORT_BIA]),str(self.__spareportInfo[PORT_MAC]),first,commit)
04647                         else:
04648                                 return tmp_string + 'cfDB.InsertSparePort("%s","%s",%i,"%s","%s","%s",%i)' \
04649                                 %(str(self.__spareportInfo[DEV_SERIAL]),str(self.__spareportInfo[DEV_PORTNBR]),self.__spareportInfo[DEV_PORTWAY],str(self.__spareportInfo[DEV_PORTTYPE]),str(self.__spareportInfo[PORT_BIA]),str(self.__spareportInfo[PORT_MAC]),commit)
04650 
04651                 else: #invalid status
04652                         return ""
04653 
04654         ##
04655         #  Update changes to the ConfDB for this object.
04656         # 
04657         #               Parameters:
04658         #               @first - if first is True; it is the first kind of this db update; prepare and initialize cache,
04659         #               if first is False, add it to the already existing cache. cache is only used if insertmany = True.
04660         #               @insertmany - If insertmany is set to false, the single insert function will be used, 
04661         #               which is optimized for single inserts. If insertmany is set to true, the multiple 
04662         #               insert function will be used, which is optimized for multiple inserts (use of cache)
04663         #               @commit - if commit is set to false, no data will be commited, put are put on hold in the cache, if 
04664         #               commit is set to true, all data that are put on hold in the cache will be commited.
04665         #               
04666         def Save(self,first=False,insertmany=False,commit=True):
04667 
04668                 try:
04669                         if self.__spareportInfo[SAVE_STATUS] not in [CREATE,MODIFY,DELETE]:
04670                                 raise RuntimeError,"Wrong save status set, this port cannot be saved in database: " + str(self.GetName())
04671 
04672                         if self.__spareportInfo[SAVE_STATUS] == CREATE:
04673                                 Validation.ValidateString("Bia",self.__spareportInfo[PORT_BIA],18,True)
04674                                 #Validation.ValidateString("MACAddress",macaddress,17,False,"r'^([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{1,1}$'")
04675                                 Validation.ValidateString("MAC Adress",self.__spareportInfo[PORT_MAC],18,True)
04676                         
04677                         if self.__spareportInfo[SAVE_STATUS] == CREATE or self.__spareportInfo[SAVE_STATUS] == MODIFY:
04678                                 Validation.ValidateString("Serial nb",self.__spareportInfo[DEV_SERIAL],200)
04679                                 Validation.ValidateString("PortNbr",self.__spareportInfo[DEV_PORTNBR],50)
04680                                 Validation.ValidateString("Porttype",self.__spareportInfo[DEV_PORTTYPE],100,True)
04681                                 Validation.ValidateNumber("Portway",self.__spareportInfo[DEV_PORTWAY],1,2)
04682 
04683                         if self.__spareportInfo[SAVE_STATUS] == CREATE:
04684                                 # Needed to do it this way to create a real int vector that is supported
04685                                 # in C/C++. This IntVec() is imported from the confDBpython library.
04686                                 print "before inserting spare ports"
04687                                 if insertmany:
04688                                         success = cfDB.InsertMultipleSparePorts(self.__spareportInfo[DEV_SERIAL],self.__spareportInfo[DEV_PORTNBR],self.__spareportInfo[DEV_PORTWAY],self.__spareportInfo[DEV_PORTTYPE],self.__spareportInfo[PORT_BIA],self.__spareportInfo[PORT_MAC],first,commit)
04689                                 else:
04690                                         success = cfDB.InsertSparePort(self.__spareportInfo[DEV_SERIAL],self.__spareportInfo[DEV_PORTNBR],self.__spareportInfo[DEV_PORTTYPE],self.__spareportInfo[DEV_PORTWAY],self.__spareportInfo[PORT_BIA],self.__spareportInfo[PORT_MAC],commit)
04691 
04692                                 if commit:
04693                                         self.Update(True) #update with data from database (port ID set)
04694 
04695                         return True
04696                 
04697                 except ValidationError,err:
04698                     self.__errormessage = str(err)
04699                     return False
04700                 except DBError,err:
04701                     self.__errormessage = str(err)
04702                     return False
04703                 except RuntimeError,err:
04704                     self.__errormessage = str(err)
04705                     return False #on error
04706                 except ValueError,err:
04707                     self.__errormessage = str("Device Name is not a string.")
04708                     return False
04709 
04710         
04711                 
04712 
04713 ##
04714 #  There are several device types, and each device is of only one device type.
04715 #       A device type contains information that is common for devices of the same type.
04716 #       It is not a physical object itself.
04717 #       
04718 class SpareHWType(DBInfo):
04719 
04720         ##
04721         #  Constructor.
04722         # 
04723         #               Parameters:
04724         #               @systemname - name of the subsystem(s) the device type is available in
04725         #               @deviceType - device type name set by the user; which identifies a device type
04726         #               @new        - if True, this device type is newly created, not stored in ConfDB yet
04727         #               if False, this is a device type that is already created, and hence we can retrieve
04728         #               information for the object from ConfDB or dirty objects list. That is done by calling
04729         #               the Update(...) function in the constructor.
04730         #               
04731         def __init__(self,hwType="",new=True):
04732                 self.__errormessage = ""
04733                 self.__SpareHWTypeInfo = {}     #all device type info that is common for all device types in this dictionary
04734                 self.__SpareHWTypeInfo[DEV_PORTS_IN] = 1
04735                 self.__SpareHWTypeInfo[DEV_PORTS_OUT] = 1
04736                 self.__SpareHWTypeInfo[DEV_TYPE_DESCRIPTION] = "it is a hw spare type"
04737                 self.__SpareHWTypeInfo[DEV_SYSTEM] = "All"
04738                 self.__SpareHWTypeInfo[DEV_HWTYPE] = hwType
04739                 
04740                 self._deviceTypeInfo[DEV_COLOUR] = None # wxColour object
04741 
04742                 self.__devices = []     #a list of devices of this device type (if retrieved)
04743 
04744                                                                #MODIFY - update, DELETE - delete, RENAME - rename
04745 
04746                 self.__cfg = GetConfig() # Get the configuration file from global method (May be not needed)
04747 
04748                 if new == False:
04749                         self.Update() #Force an update, retrieve info from db or dl
04750 
04751         ###### GET ######
04752            
04753         def GetName(self):
04754             return self.__SpareHWTypeInfo[DEV_HWTYPE]
04755         def GetPortsIn(self):
04756                 return self.__SpareHWTypeInfo[DEV_PORTS_IN]
04757         def GetPortsOut(self):
04758                 return self.__SpareHWTypeInfo[DEV_PORTS_OUT]
04759         def GetDescription(self):
04760                 return self.__SpareHWTypeInfo[DEV_TYPE_DESCRIPTION]
04761         def GetSystem(self):
04762                 return self.__SpareHWTypeInfo[DEV_SYSTEM]
04763         def GetColour(self):
04764                 return self.__SpareHWTypeInfo[DEV_COLOUR]
04765         def GetErrorMessage(self):
04766                 return self.__errormessage
04767 
04768         ###### SET ######
04769         def SetErrorMessage(self,msg):
04770                 self.__errormessage = msg
04771         def SetName(self,name):
04772                 Validation.ValidateString("spare hwtype name",name,100,False)
04773                 self.__SpareHWTypeInfo[DEV_HWTYPE] = name
04774         def SetPortsIn(self,nbr):
04775                 Validation.ValidateNumber("nbr ports in",nbr,0,10000)
04776                 self.__SpareHWTypeInfo[DEV_PORTS_IN] = nbr
04777         def SetPortsOut(self,nbr):
04778                 Validation.ValidateNumber("nbr ports out",nbr,0,10000)
04779                 self.__SpareHWTypeInfo[DEV_PORTS_OUT] = nbr
04780         def SetDescription(self,descr):
04781                 Validation.ValidateString("device type description",descr,500,True)
04782                 self.__SpareHWTypeInfo[DEV_TYPE_DESCRIPTION] = descr
04783         def SetColour(self,colour): 
04784                 #will always be a valid value/wxcolour object as the user cannot set it directly
04785                 self.__SpareHWTypeInfo[DEV_COLOUR] = colour
04786         def SetSystem(self,name):
04787                 if string.lower(name)!='all':
04788                     Validation.ValidateSystem("system name",name)
04789                 self.__SpareHWTypeInfo[DEV_SYSTEM] = name
04790         def SetDict(self,newdict): 
04791                 # Copy all the contents of the dictionary: just like a object copy except some variables.
04792                 # This is implemented because the deepcopy of objects itself caused segmentation faults.
04793                 #self._deviceTypeInfo = copy.deepcopy(newdict)
04794                 for entry in newdict:
04795                         self.__SpareHWTypeInfo[entry] = newdict[entry]
04796         def SetSaveStatus(self,status):
04797                 self.__SpareHWTypeInfo[SAVE_STATUS] = status
04798         def SetDictInfo(self,dict):
04799                 # Almost the same as SetDict(...) but this is more safe. As actually use of deepcopy
04800                 # sometimes causes segmentation faults, even the one above.
04801                 for item in dict:
04802                         self.__SpareHWTypeInfo[item] = dict[item]
04803 
04804         ##
04805         #  Get all info about a device type in a subsystem, when given the name of a device type in the constructor.
04806         #               Here we can set up to check different statuses (TODO), f.ex. if it is the most recent version of an object;
04807         #               then just return the contents; else look in dl and db.
04808         # 
04809         #               @doNotLookUp - whether we should look for more recent information in dirty objects list or ConfDB.
04810         # 
04811         #               !return - a dictionary with all the parameters set.
04812         #               
04813         def GetObjectInfo(self,doNotLookUp=True):
04814 
04815                 if doNotLookUp == True:
04816                         return self.__SpareHWTypeInfo
04817                 else:
04818                         return self.Update()
04819 
04820         ##
04821         #  Check first in dirty objects list for most recent version of this object; if in creation mode.
04822         #               If in navigation mode or alredy looked in dirty objects list and not found; check in ConfDB.
04823         # 
04824         #               @doNotCheckInDirtyList - if True, we skip the check in the dirty list, else we check. But only in
04825         #               creation mode
04826         # 
04827         #               !return - a dictionary with all the parameters set.
04828         #               
04829         def Update(self,doNotCheckInDirtyList=False):
04830 
04831                 if not doNotCheckInDirtyList:
04832                         # Dirty Objects List
04833                         if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Creation Mode
04834                                 # We look for dirty object of same name (unique within type) and type (device type)
04835                                 tmp_obj = GetAppWin().GetDirtyObject(self.__SpareHWTypeInfo[DEV_HWTYPE],SpareHWType)
04836                                 if tmp_obj != False: # Found an object of same type
04837                                         self.__SpareHWTypeInfo = copy.deepcopy(tmp_obj.GetObjectInfo(True))
04838                                         return self.__SpareHWTypeInfo # return what we found after we set it to this object
04839                 
04840                 try:
04841                     # ConfDB
04842                     Validation.ValidateString("DeviceType name",self._deviceTypeInfo[DEV_TYPE],100)
04843  
04844                     result = '|hwtype (C):'+self.__SpareHWTypeInfo[DEV_TYPE]+'|description (C):it is a hw spare type|nbrofinput (I):1|nbrofoutput (I):1|rgb_color (C):none|' # Get device type info from ConfDB
04845 
04846                     result = result[1:] #skip first '|' character
04847                     infolist = result.split("|")        #split string to a list; each entry is a parameter name and value
04848 
04849                     i = 0
04850                     deviceTypeInfo = {DEV_OBJECT : obj_NODE}    #To identify this as a devicenode (as opposite to a linknode)
04851                     deviceTypeInfo[DEV_SYSTEM] = self.__SpareHWTypeInfo[DEV_SYSTEM] # Not stored in ConfDB
04852                     for i in range(len(infolist)-1):
04853                         tmp = infolist[i].split(":")    #split each property, name on left site, value on right side
04854                         tmp0 = tmp[0].split("(")[0].strip().lower()     #split away the paranthesis telling datatype, and trim the string (strip)
04855                         datatype = tmp[0].split("(")[1].split(")")[0].strip()   #get datatype, C - String,I - integer etc.
04856                         if datatype == 'I': #integer
04857                                 tmp[1] = int(tmp[1])
04858                         elif datatype == 'C': #string
04859                                 tmp[1] = tmp[1].strip()
04860 
04861                         deviceTypeInfo[tmp0] = tmp[1]
04862                         i += 1
04863 
04864                     #convert rgbcolour to wxColour object
04865                     if deviceTypeInfo[DEV_COLOUR] in ["none","None","","(0,0,0)"]:
04866                             deviceTypeInfo[DEV_COLOUR] = GetAppWin().GetTempDeviceTypeColour(deviceTypeInfo[DEV_HWTYPE])
04867                     else:
04868                             rgbcolour = deviceTypeInfo[DEV_COLOUR].split(",")
04869                             deviceTypeInfo[DEV_COLOUR] = QColour(int(rgbcolour[0]),int(rgbcolour[1]),int(rgbcolour[2]))
04870 
04871                     self._deviceTypeInfo = deviceTypeInfo
04872 
04873                     return self._deviceTypeInfo                                                                                                         
04874                                                                                                                              
04875                 except ValidationError,err:
04876                         self.__errormessage = str(err)
04877                         return False
04878                 except ValueError,err:
04879                         self.__errormessage = "Could not convert data, found wrong datatype: " + str(err)
04880                         return False
04881                 except DBError,err:
04882                         self.__errormessage = str(err)
04883                         return False
04884                 except RuntimeError,err:
04885                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
04886                                 self.__errormessage = "No information found in the database on the given devicetype: " + str(self.__SpareHWTypeInfo[DEV_HWTYPE])
04887                                 return {}
04888                         else:
04889                                 self.__errormessage = str(err)
04890 
04891                         return False #on error
04892 
04893         ##
04894         #  General get a device at a given location.
04895         #                   TODO: should also be moved to SubSystem class.
04896         #                   NB! This function does not look for devices that are not yet stored in the ConfDB.
04897         # 
04898         #                   @location_string - the location string which looks for devices with the same location
04899         #                   string set.
04900         #               
04901         def GetHWSparesByLocation(self,location_string):
04902 
04903                 try:
04904 
04905                     res = cfDB.GetSpareHWPerLocation(location_string)
04906                     devices = res
04907 
04908                     i = 0 #reset
04909                     my_devices = []
04910                     while i < len(devices):
04911                         my_spares.append(devices[i])
04912                         i += 1
04913 
04914                     return my_spares
04915 
04916                 except RuntimeError,err:
04917                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
04918                                         self.__errormessage = "No devices found at the given location."
04919                                         return [] #none found
04920                         else:
04921                                 self.__errormessage = str(err)
04922                         return False #on error
04923 
04924         ##
04925         #  Get all _sparedevice_names_ for a given device type; each device name is unique. Looks both in 
04926         #               dirty objects list and ConfDB.
04927         #               
04928         #               !Return - list of device names; both in db and in dirtylist
04929         #               
04930         def GetSpareDevices(self):  #should be called only for spare devices
04931 
04932                 devices_in_dirtylist = []
04933                 my_devices = []
04934                 dirty_objs_devs = []
04935                 tbd = [] #to be deleted
04936                 #tbd_objs = -[]
04937                 if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Only if creation mode
04938                         tmp_dirtyobjs = GetAppWin().GetDirtyObjects()
04939                         for obj in tmp_dirtyobjs:
04940                                 # If type is: DEVICE
04941                                 if obj.__class__ == Device:
04942                                         # If not set to be deleted, and that the device type is correct (this type)
04943                                         if obj.GetSaveStatus() != DELETE and obj.GetType() == self.__SpareHWTypeInfo[DEV_TYPE]:
04944                                                 if obj.GetName() not in my_devices: # If not already added; ADD!
04945                                                         my_devices.append(obj.GetName())
04946                                                         dirty_objs_devs.append(obj.GetName())
04947                                         #if set to be deleted and correct type
04948                                         elif obj.GetSaveStatus() == DELETE and obj.GetType() == self.__SpareHWTypeInfo[DEV_TYPE]:
04949                                                 # if already added; remove
04950                                                 if obj.GetName() in my_devices:
04951                                                         my_devices.remove(obj.GetName())
04952                                                         dirty_objs_devs.remove(obj.GetName())
04953                                                 # set to the tbd list, in case we find same device in ConfDB, but set for
04954                                                 # delete in dirty objects list
04955                                                 tbd.append(obj.GetName())
04956 
04957                 #First check if this device type has been renamed, cause the name in DB will be the prev one:
04958                 if self.GetName() in GetAppWin().GetNewNames():
04959                         old_name = GetAppWin().GetOldNamesOfRenamed()[self.GetName()]
04960                 else:
04961                         old_name = self.__SpareHWTypeInfo[DEV_TYPE]
04962                         
04963                 try:
04964                                           
04965                     tmp = cfDB.GetSpareHWPerType(old_name)
04966                         
04967                     devices = tmp                                                                                                                    
04968                     i = 0 #reset
04969                     if GetAppWin().GetUserMode() == ID_CREATION_MODE: # Need to do some checks if creation mode
04970                         while i < len(devices):
04971                                 dev_tmp = devices[i].split("|")
04972                                 # do add to list if:
04973                                 # a. not already added
04974                                 # b. not set for deletion
04975                                 # c. not already added under a new name (renamed)
04976                                 if (dev_tmp[0] not in dirty_objs_devs) and (dev_tmp[0] not in tbd) and dev_tmp[0] not in GetAppWin().GetOldNames():
04977                                         my_devices.append(str(dev_tmp[0]))
04978                                 i += 1
04979 
04980 
04981                     else: #navigation mode
04982                         while i < len(devices):
04983                                         dev_tmp = devices[i].split("|")
04984                                         if  dev_tmp[0] not in GetAppWin().GetOldNames(): #TODO: this is wrong? do not need 
04985                                                                                         #to do this in navigation mode?
04986                                                 my_devices.append(str(dev_tmp[0]))
04987                                                 i += 1
04988 
04989                     self.__devices = my_devices
04990                                 
04991                     return self.__devices
04992 
04993                 except ValidationError,err:
04994                         self.__errormessage = str(err)
04995                         return False
04996                 except DBError,err:
04997                         self.__errormessage = str(err)
04998                         return False
04999                 except RuntimeError,err:
05000                         if string.find(str(err),"NO_ROWS_SELECTED",0) != -1:
05001                                 if len(my_devices) == 0:
05002                                         self.__errormessage = "No devices found for the given device type " + str(self.__SpareHWTypeInfo[DEV_TYPE])
05003                                         return [] #none found
05004                                 else: #none found in db, but we found in dirty list
05005                                         self.__devices = my_devices
05006                                         return self.__devices
05007                         else:
05008                                 self.__errormessage = str(err)
05009                         return False #on error
05010 
05011 
05012         
05013         
05014 
05015         ##
05016         #  Delete this object. This object is put in the dirty list and set for deletion. 
05017         #               Sets the save status to deletion.
05018         #               
05019         def Delete(self):
05020                 
05021                 self._deviceTypeInfo[SAVE_STATUS] = DELETE
05022                 GetAppWin().AddToDirtyObjects(self) #possible to send an instance of itself?
05023 
05024         ##
05025         #  Modifies a device type with new values set by the user through the set functions. The modify status
05026         #               is set through SetModifyStatus(...) if needed.
05027         #               Sets the save status to modify, and adds the object to the dirty objects list.
05028         #               
05029         def Modify(self):
05030                 self._deviceTypeInfo[SAVE_STATUS] = MODIFY
05031                 GetAppWin().AddToDirtyObjects(self)
05032 
05033         ##
05034         #  Create a device type. Set save status to creation, and adds the object to the
05035         #               dirty objects list.
05036         #               
05037         def Create(self):
05038                 
05039                 self._deviceTypeInfo[SAVE_STATUS] = CREATE
05040                 GetAppWin().AddToDirtyObjects(self)
05041         
05042 #end added by lana
05043 
05044 

Generated on Fri Aug 31 11:11:16 2007 for CDBVis by  doxygen 1.5.3