std::vector<std::shared_ptr<SimulatorResource>> SimulatorManager::createResource(
            const std::string &configPath, unsigned int count)
{
    VALIDATE_INPUT(configPath.empty(), "Empty path!")
    VALIDATE_INPUT(!count, "Count is zero!")

    std::vector<std::shared_ptr<SimulatorResource>> resources =
                SimulatorResourceFactory::getInstance()->createResource(configPath, count);
    if (!resources.size())
        throw SimulatorException(SIMULATOR_ERROR, "Failed to create resource!");
    return resources;
}
JNIEXPORT void JNICALL
Java_org_oic_simulator_server_SimulatorSingleResource_addAttribute
(JNIEnv *env, jobject object, jobject resAttribute)
{
    VALIDATE_INPUT(env, !resAttribute, "Resource attribute is null!")

    SimulatorSingleResourceSP singleResource = simulatorSingleResourceToCpp(env, object);
    VALIDATE_OBJECT(env, singleResource)

    try
    {
        SimulatorResourceModel::Attribute attribute;
        if (!simulatorResourceAttributeToCpp(env, resAttribute, attribute))
        {
            throwSimulatorException(env, SIMULATOR_ERROR,
                                    "Failed to covnert SimulatorResourceAttribute java object!");
            return;
        }

        singleResource->addAttribute(attribute);
    }
    catch (SimulatorException &e)
    {
        throwSimulatorException(env, e.code(), e.what());
    }
}
std::shared_ptr<SimulatorResource> SimulatorManager::createResource(
    const std::string &configPath)
{
    VALIDATE_INPUT(configPath.empty(), "Empty path!")

    std::shared_ptr<SimulatorResource> resource =
        SimulatorResourceFactory::getInstance()->createResource(configPath);
    if (!resource)
        throw SimulatorException(SIMULATOR_ERROR, "Failed to create resource!");
    return resource;
}
void SimulatorSingleResourceImpl::setInterface(const std::string &interfaceType)
{
    VALIDATE_INPUT(interfaceType.empty(), "Interface type list is empty!")

    std::lock_guard<std::recursive_mutex> lock(m_objectLock);
    if (m_resourceHandle)
    {
        throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED,
                                 "Resource interface can not be reset when resource is started!");
    }

    m_interfaces = {interfaceType};
}
void SimulatorSingleResourceImpl::setURI(const std::string &uri)
{
    VALIDATE_INPUT(uri.empty(), "Uri is empty!")

    std::lock_guard<std::recursive_mutex> lock(m_objectLock);
    if (m_resourceHandle)
    {
        throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED,
                                 "URI can not be set when resource is started!");
    }

    m_uri = uri;
}
JNIEXPORT void JNICALL
Java_org_oic_simulator_server_SimulatorSingleResource_updateAttribute
(JNIEnv *env, jobject object, jstring attrName, jobject attrValue)
{
    VALIDATE_INPUT(env, !attrName, "Attribute name is null!")
    VALIDATE_INPUT(env, !attrValue, "Attribute value is null!")

    SimulatorSingleResourceSP singleResource = simulatorSingleResourceToCpp(env, object);
    VALIDATE_OBJECT(env, singleResource)

    SimulatorResourceModel::ValueVariant value;
    if (!AttributeValueToCpp(env, attrValue, value))
    {
        throwSimulatorException(env, SIMULATOR_ERROR,
                                "Failed to covnert AttributeValue java object!");
        return;
    }

    SimulatorResourceModel::Attribute attribute(JniString(env, attrName).get());
    attribute.setValue(value);
    singleResource->updateAttributeValue(attribute);
}
void SimulatorSingleResourceImpl::setName(const std::string &name)
{
    VALIDATE_INPUT(name.empty(), "Name is empty!")

    std::lock_guard<std::recursive_mutex> lock(m_objectLock);
    if (m_resourceHandle)
    {
        throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED,
                                 "Name can not be set when resource is started!");
    }

    m_name = name;
}
JNIEXPORT void JNICALL
Java_org_oic_simulator_server_SimulatorSingleResource_removeAttribute
(JNIEnv *env, jobject object, jstring attrName)
{
    VALIDATE_INPUT(env, !attrName, "Attribute name is null!")

    SimulatorSingleResourceSP singleResource = simulatorSingleResourceToCpp(env, object);
    VALIDATE_OBJECT(env, singleResource)

    try
    {
        JniString jniAttrName(env, attrName);
        singleResource->removeAttribute(jniAttrName.get());
    }
    catch (InvalidArgsException &e)
    {
        throwInvalidArgsException(env, e.code(), e.what());
    }
}
void SimulatorSingleResourceImpl::setInterface(const std::vector<std::string> &interfaceTypes)
{
    VALIDATE_INPUT(interfaceTypes.empty(), "Interface type list is empty!")

    std::lock_guard<std::recursive_mutex> lock(m_objectLock);
    if (m_resourceHandle)
    {
        throw SimulatorException(SIMULATOR_OPERATION_NOT_ALLOWED,
                                 "Resource interface can not be reset when resource is started!");
    }

    m_interfaces.clear();
    for (auto &interfaceType : interfaceTypes)
    {
        if (m_interfaces.end() ==
            std::find(m_interfaces.begin(), m_interfaces.end(), interfaceType))
        {
            m_interfaces.push_back(interfaceType);
        }
    }
}
void SimulatorSingleResourceImpl::setName(const std::string &name)
{
    VALIDATE_INPUT(name.empty(), "Name is empty!")
    m_name = name;
}