int celix_eventAdmin_addEventHandlerWithProperties()

in bundles/event_admin/event_admin/src/celix_event_admin.c [356:436]


int celix_eventAdmin_addEventHandlerWithProperties(void* handle, void* svc, const celix_properties_t* props) {
    assert(handle != NULL);
    assert(svc != NULL);
    assert(props != NULL);
    celix_event_admin_t* ea = (celix_event_admin_t*)handle;
    const char *topics = celix_properties_get(props, CELIX_EVENT_TOPIC, NULL);
    if (topics == NULL) {
        celix_logHelper_error(ea->logHelper, "Failed to add event handler. No %s property set", CELIX_EVENT_TOPIC);
        return CELIX_ILLEGAL_ARGUMENT;
    }
    long serviceId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1L);
    assert(serviceId >= 0);

    celix_autofree celix_event_handler_t *handler = calloc(1, sizeof(*handler));
    if (handler == NULL) {
        celix_logHelper_error(ea->logHelper, "Failed to create event handler.");
        return CELIX_ENOMEM;
    }
    handler->service = svc;
    handler->serviceId = serviceId;
    handler->serviceDescription = celix_properties_get(props, CELIX_FRAMEWORK_SERVICE_DESCRIPTION, "Unknown");
    const char *deliver = celix_properties_get(props, CELIX_EVENT_DELIVERY, NULL);
    handler->asyncOrdered = (deliver == NULL || strstr(deliver,CELIX_EVENT_DELIVERY_ASYNC_ORDERED) != NULL);
    handler->eventFilter = NULL;
    handler->blackListed = false;
    handler->handlingAsyncEventCnt = 0;

    celix_autofree char* topicsCopy = celix_utils_strdup(topics);
    if (topicsCopy == NULL) {
        celix_logHelper_error(ea->logHelper, "Failed to dup topics %s.", topics);
        return CELIX_ENOMEM;
    }

    celix_autoptr(celix_string_hash_map_t) topicsMap = celix_stringHashMap_create();//avoid topic duplicates
    if (topicsMap == NULL) {
        celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(ea->logHelper, "Failed to create topics map.");
        return CELIX_ENOMEM;
    }
    char* savePtr = NULL;
    char* token = strtok_r(topicsCopy, ",", &savePtr);
    while (token != NULL) {
        char *trimmedToken = celix_utils_trimInPlace(token);
        if (celix_stringHashMap_put(topicsMap, trimmedToken, NULL) != CELIX_SUCCESS) {
            celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
            celix_logHelper_error(ea->logHelper, "Failed to add topic %s to topics map.", trimmedToken);
            return CELIX_ENOMEM;
        }
        token = strtok_r(NULL, ",", &savePtr);
    }

    celix_autoptr(celix_filter_t) eventFilter = NULL;
    const char* eventFilterStr = celix_properties_get(props, CELIX_EVENT_FILTER, NULL);
    if (eventFilterStr) {
        eventFilter = handler->eventFilter = celix_filter_create(eventFilterStr);
        if (eventFilter == NULL) {
            celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
            celix_logHelper_error(ea->logHelper, "Failed to create event filter for %s.", eventFilterStr);
            return CELIX_BUNDLE_EXCEPTION;
        }
    }

    celix_auto(celix_rwlock_wlock_guard_t) wLockGuard = celixRwlockWlockGuard_init(&ea->lock);
    celix_status_t status = celix_longHashMap_put(ea->eventHandlers, handler->serviceId, handler);
    if (status != CELIX_SUCCESS) {
        celix_logHelper_logTssErrors(ea->logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(ea->logHelper, "Failed to add event handler(%s).", handler->serviceDescription);
        return status;
    }

    CELIX_STRING_HASH_MAP_ITERATE(topicsMap, iter) {
        celix_eventAdmin_subscribeTopicFor(ea, iter.key, handler);
    }

    celix_logHelper_debug(ea->logHelper, "Added event handler(%s) for topics %s", handler->serviceDescription, topics);

    celix_steal_ptr(eventFilter);
    celix_steal_ptr(handler);

    return CELIX_SUCCESS;
}