Extended validation for CommonAPI Addresses
[profile/ivi/common-api-dbus-runtime.git] / src / CommonAPI / DBus / DBusAddressTranslator.cpp
index 87f6f93..a1c836e 100644 (file)
@@ -21,13 +21,14 @@ namespace DBus {
 
 
 enum class TypeEnum {
-    DBUS_CONNECTION, DBUS_OBJECT, DBUS_INTERFACE
+    DBUS_CONNECTION, DBUS_OBJECT, DBUS_INTERFACE, DBUS_PREDEFINED
 };
 
 static const std::unordered_map<std::string, TypeEnum> allowedValueTypes = {
                 {"dbus_connection", TypeEnum::DBUS_CONNECTION},
                 {"dbus_object", TypeEnum::DBUS_OBJECT},
-                {"dbus_interface", TypeEnum::DBUS_INTERFACE}
+                {"dbus_interface", TypeEnum::DBUS_INTERFACE},
+                {"dbus_predefined", TypeEnum::DBUS_PREDEFINED}
 };
 
 
@@ -36,26 +37,29 @@ DBusAddressTranslator::DBusAddressTranslator() {}
 
 void DBusAddressTranslator::init() {
     std::string fqnOfConfigFile = getCurrentBinaryFileFQN();
-    fqnOfConfigFile += DBUS_CONFIG_SUFFIX;
-
     std::ifstream addressConfigFile;
-    addressConfigFile.open(fqnOfConfigFile.c_str());
 
-    if(addressConfigFile.is_open()) {
-        readConfigFile(addressConfigFile);
-        addressConfigFile.close();
-    }
+    if (fqnOfConfigFile != "") {
+        fqnOfConfigFile += DBUS_CONFIG_SUFFIX;
 
-    addressConfigFile.clear();
-    std::vector<std::string> splittedConfigFQN = split(fqnOfConfigFile, '/');
-    std::string globalConfigFQN = DBUS_GLOBAL_CONFIG_ROOT + splittedConfigFQN.at(splittedConfigFQN.size() - 1);
-    addressConfigFile.open(globalConfigFQN);
-    if(addressConfigFile.is_open()) {
-        readConfigFile(addressConfigFile);
-        addressConfigFile.close();
+        addressConfigFile.open(fqnOfConfigFile.c_str());
+
+        if (addressConfigFile.is_open()) {
+            readConfigFile(addressConfigFile);
+            addressConfigFile.close();
+        }
+
+        addressConfigFile.clear();
+        std::vector<std::string> splittedConfigFQN = split(fqnOfConfigFile, '/');
+        std::string globalConfigFQN = DBUS_GLOBAL_CONFIG_ROOT + splittedConfigFQN.at(splittedConfigFQN.size() - 1);
+        addressConfigFile.open(globalConfigFQN);
+        if (addressConfigFile.is_open()) {
+            readConfigFile(addressConfigFile);
+            addressConfigFile.close();
+        }
+        addressConfigFile.clear();
     }
 
-    addressConfigFile.clear();
     addressConfigFile.open(DBUS_GLOBAL_CONFIG_FQN);
     if(addressConfigFile.is_open()) {
         readConfigFile(addressConfigFile);
@@ -64,7 +68,7 @@ void DBusAddressTranslator::init() {
 }
 
 
-inline void readValue(std::string& readLine, DBusServiceAddress& dbusServiceAddress) {
+inline void readValue(std::string& readLine, CommonApiServiceDetails& serviceDetails) {
     std::stringstream readStream(readLine);
 
     std::string paramName;
@@ -77,13 +81,16 @@ inline void readValue(std::string& readLine, DBusServiceAddress& dbusServiceAddr
         getline(readStream, paramValue);
         switch(typeEntry->second) {
             case TypeEnum::DBUS_CONNECTION:
-                std::get<0>(dbusServiceAddress) = paramValue;
+                std::get<0>(std::get<0>(serviceDetails)) = paramValue;
                 break;
             case TypeEnum::DBUS_OBJECT:
-                std::get<1>(dbusServiceAddress) = paramValue;
+                std::get<1>(std::get<0>(serviceDetails)) = paramValue;
                 break;
             case TypeEnum::DBUS_INTERFACE:
-                std::get<2>(dbusServiceAddress) = paramValue;
+                std::get<2>(std::get<0>(serviceDetails)) = paramValue;
+                break;
+            case TypeEnum::DBUS_PREDEFINED:
+                std::get<1>(serviceDetails) = paramValue == "true" ? true : false;
                 break;
         }
     }
@@ -96,11 +103,16 @@ inline void reset(DBusServiceAddress& dbusServiceAddress) {
     std::get<2>(dbusServiceAddress) = "";
 }
 
+inline void reset(CommonApiServiceDetails& serviceDetails) {
+    reset(std::get<0>(serviceDetails));
+    std::get<1>(serviceDetails) = false;
+}
+
 
 void DBusAddressTranslator::readConfigFile(std::ifstream& addressConfigFile) {
     std::string currentlyParsedCommonApiAddress;
-    DBusServiceAddress dbusServiceAddress;
-    reset(dbusServiceAddress);
+    CommonApiServiceDetails serviceDetails;
+    reset(serviceDetails);
 
     bool newAddressFound = false;
 
@@ -111,36 +123,39 @@ void DBusAddressTranslator::readConfigFile(std::ifstream& addressConfigFile) {
 
         if (readLine[0] == '[' && readLine[readLineLength - 1] == ']') {
             if (newAddressFound) {
-                fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
-                knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
-                knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
+                fillUndefinedValues(serviceDetails, currentlyParsedCommonApiAddress);
+                commonApiAddressDetails.insert( {currentlyParsedCommonApiAddress, serviceDetails});
+                dbusToCommonApiAddress.insert( {std::get<0>(serviceDetails), currentlyParsedCommonApiAddress});
+            }
+            reset(serviceDetails);
+            std::string newAddress = readLine.substr(1, readLineLength - 2);
+            if (isValidCommonApiAddress(newAddress)) {
+                currentlyParsedCommonApiAddress = std::move(newAddress);
+                newAddressFound = commonApiAddressDetails.find(currentlyParsedCommonApiAddress) == commonApiAddressDetails.end();
             }
-            reset(dbusServiceAddress);
-            currentlyParsedCommonApiAddress = readLine.substr(1, readLineLength - 2);
-            newAddressFound = knownDBusAddresses.find(currentlyParsedCommonApiAddress) == knownDBusAddresses.end();
 
         } else if (newAddressFound) {
-            readValue(readLine, dbusServiceAddress);
+            readValue(readLine, serviceDetails);
         }
     }
     if(newAddressFound) {
-        fillUndefinedValues(dbusServiceAddress, currentlyParsedCommonApiAddress);
-        knownDBusAddresses.insert( {currentlyParsedCommonApiAddress, dbusServiceAddress});
-        knownCommonAddresses.insert( {dbusServiceAddress, currentlyParsedCommonApiAddress});
+        fillUndefinedValues(serviceDetails, currentlyParsedCommonApiAddress);
+        commonApiAddressDetails.insert( {currentlyParsedCommonApiAddress, serviceDetails});
+        dbusToCommonApiAddress.insert( {std::get<0>(serviceDetails), currentlyParsedCommonApiAddress});
     }
 }
 
 
-void DBusAddressTranslator::fillUndefinedValues(DBusServiceAddress& dbusServiceAddress, const std::string& commonApiAddress) const {
+void DBusAddressTranslator::fillUndefinedValues(CommonApiServiceDetails& serviceDetails, const std::string& commonApiAddress) const {
     std::string connectionName;
     std::string objectPath;
     std::string interfaceName;
 
     findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
 
-    std::get<0>(dbusServiceAddress) = std::get<0>(dbusServiceAddress) == "" ? connectionName : std::get<0>(dbusServiceAddress);
-    std::get<1>(dbusServiceAddress) = std::get<1>(dbusServiceAddress) == "" ? objectPath : std::get<1>(dbusServiceAddress);
-    std::get<2>(dbusServiceAddress) = std::get<2>(dbusServiceAddress) == "" ? interfaceName : std::get<2>(dbusServiceAddress);
+    std::get<0>(std::get<0>(serviceDetails)) = std::get<0>(std::get<0>(serviceDetails)) == "" ? connectionName : std::get<0>(std::get<0>(serviceDetails));
+    std::get<1>(std::get<0>(serviceDetails)) = std::get<1>(std::get<0>(serviceDetails)) == "" ? objectPath : std::get<1>(std::get<0>(serviceDetails));
+    std::get<2>(std::get<0>(serviceDetails)) = std::get<2>(std::get<0>(serviceDetails)) == "" ? interfaceName : std::get<2>(std::get<0>(serviceDetails));
 }
 
 
@@ -159,15 +174,15 @@ void DBusAddressTranslator::searchForDBusAddress(const std::string& commonApiAdd
                                                  std::string& connectionName,
                                                  std::string& objectPath) {
 
-    const auto& foundAddressMapping = knownDBusAddresses.find(commonApiAddress);
+    const auto& foundAddressMapping = commonApiAddressDetails.find(commonApiAddress);
 
-    if(foundAddressMapping != knownDBusAddresses.end()) {
-        connectionName = std::get<0>(foundAddressMapping->second);
-        objectPath = std::get<1>(foundAddressMapping->second);
-        interfaceName = std::get<2>(foundAddressMapping->second);
+    if(foundAddressMapping != commonApiAddressDetails.end()) {
+        connectionName = std::get<0>(std::get<0>(foundAddressMapping->second));
+        objectPath = std::get<1>(std::get<0>(foundAddressMapping->second));
+        interfaceName = std::get<2>(std::get<0>(foundAddressMapping->second));
     } else {
         findFallbackDBusAddress(commonApiAddress, interfaceName, connectionName, objectPath);
-        knownDBusAddresses.insert( {commonApiAddress, std::make_tuple(connectionName, objectPath, interfaceName) } );
+        commonApiAddressDetails.insert( {commonApiAddress, std::make_tuple(std::make_tuple(connectionName, objectPath, interfaceName), false) } );
     }
 }
 
@@ -178,15 +193,28 @@ void DBusAddressTranslator::searchForCommonAddress(const std::string& interfaceN
 
     DBusServiceAddress dbusAddress(connectionName, objectPath, interfaceName);
 
-    const auto& foundAddressMapping = knownCommonAddresses.find(dbusAddress);
-    if (foundAddressMapping != knownCommonAddresses.end()) {
+    const auto& foundAddressMapping = dbusToCommonApiAddress.find(dbusAddress);
+    if (foundAddressMapping != dbusToCommonApiAddress.end()) {
         commonApiAddress = foundAddressMapping->second;
     } else {
         findFallbackCommonAddress(commonApiAddress, interfaceName, connectionName, objectPath);
-        knownCommonAddresses.insert( {std::move(dbusAddress), commonApiAddress} );
+        dbusToCommonApiAddress.insert( {std::move(dbusAddress), commonApiAddress} );
     }
 }
 
+void DBusAddressTranslator::getPredefinedInstances(const std::string& connectionName,
+                                                   std::vector<DBusServiceAddress>& instances) {
+    instances.clear();
+    auto dbusAddress = commonApiAddressDetails.begin();
+    while (dbusAddress != commonApiAddressDetails.end()) {
+        CommonApiServiceDetails serviceDetails = dbusAddress->second;
+        if (connectionName == std::get<0>(std::get<0>(serviceDetails))
+                        && true == std::get<1>(serviceDetails)) {
+            instances.push_back(std::get<0>(serviceDetails));
+        }
+        dbusAddress++;
+    }
+}
 
 void DBusAddressTranslator::findFallbackDBusAddress(const std::string& commonApiAddress,
                                                     std::string& interfaceName,