class LoaderTest(unittest.TestCase):
    
    __test__ = True
    
    def setUp(self):
        self.classLoader = Loader()
        # swap last two paths to change the class search order    
        lastPathEntry = sys.path.pop()
        sys.path.append("../../main/controller/")
        sys.path.append(lastPathEntry)
    
    def testLoadMyClass(self):
        method = self.classLoader.findMethodInstanceByName("test.controller.my_test_module", "MyTestClass", "myTestMethod")
        self.assertNotEqual(None, method, "Method is not populated.")        
    
    def testLoadMyClass2(self):
        method = self.classLoader.findMethodInstanceByName("test.controller.package.my_test_module_2", "MyTestClass2", "myTestMethod2")
        self.assertNotEqual(None, method, "Method 2 is not populated.")   
        method()
        
    def testLoadVolumeControllerAction(self):
        method = self.classLoader.findMethodInstanceByName("main.controller.volume.volume_controller", "VolumeController", "volumeUp")
        self.assertNotEqual(None, method, "Method should be initiated")                

    def testLoadShellControllerAction(self):
        method = self.classLoader.findMethodInstanceByName("main.controller.shell.shell_controller", "ShellController", "executeCommand")
        self.assertNotEqual(None, method, "Method should be initiated")
 def __init__(self, configurationPath, classLoader = None):
     self.logger = logging.getLogger("app")
     self.configurationPath = configurationPath
     self.buttons = {}
     self.cache = {}
     self.gapDuration = 0
     self.blocking = 0
     if classLoader is None:
         self.classLoader = Loader()
     else:
         self.classLoader = classLoader
 def setUp(self):
     self.classLoader = Loader()
     # swap last two paths to change the class search order    
     lastPathEntry = sys.path.pop()
     sys.path.append("../../main/controller/")
     sys.path.append(lastPathEntry)
class ConfigurationReader:    
    def __init__(self, configurationPath, classLoader = None):
        self.logger = logging.getLogger("app")
        self.configurationPath = configurationPath
        self.buttons = {}
        self.cache = {}
        self.gapDuration = 0
        self.blocking = 0
        if classLoader is None:
            self.classLoader = Loader()
        else:
            self.classLoader = classLoader
        
    def readConfiguration(self):   
                
        self.logger.info("Reading configuration from %s" % self.configurationPath)        
        tree = ET.parse(self.configurationPath)
        root = tree.getroot()
        propertyElements = root.findall('properties/property')
        for propertyElement in propertyElements:
            propertyId = propertyElement.get("id")
            propertyValue = propertyElement.text
            if(propertyId == "gapDuration"):
                self.gapDuration = propertyValue
            elif(propertyId == "blocking"):
                self.blocking = propertyValue
        buttonElements = root.findall('buttons/button')
        for buttonElement in buttonElements:
            buttonId = buttonElement.get("id")
            self.logger.debug("Button configuration: %s" % buttonId)            
            actionElements = buttonElement.findall('action')            
            buttonClick = None
            buttonDoubleClick = None
            buttonHold = None
            for actionElement in actionElements:
                # build task
                taskElement = actionElement.find("task")                
                moduleName = taskElement.find("module").text
                className = taskElement.find("class").text
                methodName = taskElement.find("method").text
                parameter = taskElement.find("parameter").text                 
                task = self.buildTask(moduleName, className, methodName, parameter)                
                # store method instance in the cache
                self.storeMethod(task)                
                # build action
                actionId = actionElement.get("id")
                isCancelableElement = actionElement.find("isCancelable")
                fireDelayElement = actionElement.find("fireDelay")                
                minimalRepeatTriggerElement = actionElement.find("minimalRepeatTrigger")
                action = self.buildAction(actionId, task, isCancelableElement, fireDelayElement, minimalRepeatTriggerElement)
                # assign task to button
                actionType = actionElement.get("type")
                if (actionType == ActionType.CLICK):
                    buttonClick = action
                elif (actionType == ActionType.DOUBLE_CLICK):
                    buttonDoubleClick = action
                else:
                    buttonHold = action            
            button = self.buildButton(buttonId, buttonClick, buttonDoubleClick, buttonHold)
            self.storeButton(button)                
            self.logger.info("New button added: %s" % button)        
        return Configuration(self.gapDuration, self.blocking, self.buttons, self.cache)
    
    def buildButton(self, buttonId, clickAction, doubleClickAction, holdAction):
        button = Button(buttonId)
        button.click = clickAction
        button.doubleClick = doubleClickAction
        button.hold = holdAction
        return button
        
    def buildAction(self, actionId, task, isCancelableElement, fireDelayElement, minimalRepeatTriggerElement):        
        if(isCancelableElement != None):
            if(isCancelableElement.text.lower == "true"):
                isCancelable = True
            else:
                isCancelable = False    
        else:
            isCancelable = True
        if(fireDelayElement != None):
            fireDelay = float(fireDelayElement.text)
        else:
            fireDelay = 0        
        if(minimalRepeatTriggerElement != None):
            minimalRepeatTrigger = int(minimalRepeatTriggerElement.text)
        else:
            minimalRepeatTrigger = 0 
        action = Action(actionId, task, fireDelay, isCancelable, minimalRepeatTrigger)
        return action
    
    def buildTask(self, moduleName, className, methodName, parameter):
        task = Task(moduleName, className, methodName, parameter)
        return task
    
    def storeButton(self, button):
        self.buttons[button.id] = button
        
    def storeMethod(self, task):
        taskUniqueKey = task.taskUniqueKey()
        self.logger.debug("Storing method with key: %s" % taskUniqueKey)        
        if self.cache.has_key(taskUniqueKey):
            self.logger.debug("Method already cached.")
            return
        self.logger.info("New method added: %s" % taskUniqueKey)
        methodInstance = self.classLoader.findMethodInstanceByName(task.module, task.clazz, task.method)                          
        self.cache[taskUniqueKey] = methodInstance