This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/674-use-properties-type-in-filter in repository https://gitbox.apache.org/repos/asf/celix.git
commit f833cc883e15a56b74abf43ccc5fdffae5306506 Author: Pepijn Noltes <[email protected]> AuthorDate: Sat Nov 25 20:54:33 2023 +0100 Improve celix filter documentation --- libs/utils/include/celix_filter.h | 154 ++++++++++++++++++++++++++++++-------- 1 file changed, 124 insertions(+), 30 deletions(-) diff --git a/libs/utils/include/celix_filter.h b/libs/utils/include/celix_filter.h index 33f24ed2..c8b0d7e0 100644 --- a/libs/utils/include/celix_filter.h +++ b/libs/utils/include/celix_filter.h @@ -17,20 +17,65 @@ * under the License. */ +/** + * @file celix_filter.h + * @brief Header file for the Celix Filter API. + * + * An Apache Celix filter is a based on LDAP filters, for more information about LDAP filters see: + * - https://tools.ietf.org/html/rfc4515 + * - https://tools.ietf.org/html/rfc1960 + * + * In short an Apache Celix filter is a tree of filter nodes, parsed from a filter string. + * Each node has an operand, an optional attribute string and an optional value string. + * The operand can be one of the following: + * - `=`: equal + * - `=*`: present + * - `~=`: approx + * - `>=`: greater + * - `<=`: less + * - `>=`: greater equal + * - `<=`: less equal + * - `=`: substring if string contains a `*`. + * - `!`: not + * - `&`: and + * - `|`: or + * + The filter string is a list of filter node strings wrapped in parenthesis to group filter nodes. + * The following are valid filter strings: + * - `(key=value)` # Matches if properties contains a entry with key "key" and value "value". + * - `(key>=2)`# Matches if properties contains a entry with key "key" and value greater or equal to 2. + * - `(key=*)` # Matches if properties contains a entry with key "key". + * - `(!(key=value))` # Matches if properties does not contain a entry with key "key" and value "value". + * - `(&(key1=value1)(key2=value2))` # Matches if properties contains a entry with key "key1" and value "value1" and + * # a entry with key "key2" and value "value2". + * - `(|(key1=value1)(key2=value2))` # Matches if properties contains a entry with key "key1" and value "value1" or + * # a entry with key "key2" and value "value2". + * + * Apache Celix filters can be used to match a set of Apache Celix properties and such Apache Celix filters should be + * used together with a set of properties. + * + * Internally attribute values will be parsed to a long, double, boolean and Apache Celix version if + * possible during creation. And these types attribute values will be used in the to-be-matched property value, + * if the property value is of the same type. + * + */ + #ifndef CELIX_FILTER_H_ #define CELIX_FILTER_H_ -#include "celix_properties.h" #include "celix_array_list.h" #include "celix_cleanup.h" +#include "celix_properties.h" #include "celix_utils_export.h" #ifdef __cplusplus extern "C" { #endif -typedef enum celix_filter_operand_enum -{ +/** + * @brief Enumeration of the filter operands. + */ +typedef enum celix_filter_operand_enum { CELIX_FILTER_OPERAND_EQUAL, CELIX_FILTER_OPERAND_APPROX, CELIX_FILTER_OPERAND_GREATER, @@ -44,23 +89,25 @@ typedef enum celix_filter_operand_enum CELIX_FILTER_OPERAND_NOT, } celix_filter_operand_t; +/** + * @brief Internal opaque struct for internal use only. + */ +typedef struct celix_filter_internal celix_filter_internal_t; // opaque struct for internal use only -typedef struct celix_filter_internal celix_filter_internal_t; //opaque struct for internal use only - -typedef struct celix_filter_struct celix_filter_t; - -struct celix_filter_struct { - celix_filter_operand_t operand; - const char *attribute; //NULL for operands AND, OR ot NOT - const char *value; //NULL for operands AND, OR or NOT NOT - const char *filterStr; +/** + * @brief The Apache Celix filter struct. + */ +typedef struct celix_filter_struct { + celix_filter_operand_t operand; /**< The filter operand. */ + const char* attribute; /**< The filter attribute; NULL for operands `AND`, `OR` or `NOT`. */ + const char* value; /**< The filter value; NULL for operands `AND`, `OR` or `NOT`. */ + const char* filterStr; /**< The filter string representation. */ - //type is celix_filter_t* for AND, OR and NOT operator and char* for SUBSTRING - //for other operands children is NULL - celix_array_list_t *children; + celix_array_list_t* children; /**< The filter children; only valid if the operand is not `AND`, `OR` or `NOT` else + the value is NULL. */ - celix_filter_internal_t* internal; //for internal use only -}; + celix_filter_internal_t* internal; /**< Internal use only. */ +} celix_filter_t; /** * @brief Create a filter based on the provided filter string. @@ -70,45 +117,92 @@ struct celix_filter_struct { * @param filterStr The filter string. * @return The created filter or NULL if the filter string is invalid. */ -CELIX_UTILS_EXPORT celix_filter_t* celix_filter_create(const char *filterStr); +CELIX_UTILS_EXPORT celix_filter_t* celix_filter_create(const char* filterStr); -CELIX_UTILS_EXPORT void celix_filter_destroy(celix_filter_t *filter); +/** + * @brief Destroy the provided filter. Ignores NULL values. + */ +CELIX_UTILS_EXPORT void celix_filter_destroy(celix_filter_t* filter); +/** + * @brief Add support for `celix_autoptr`. + */ CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_filter_t, celix_filter_destroy) -CELIX_UTILS_EXPORT bool celix_filter_match(const celix_filter_t *filter, const celix_properties_t* props); +/** + * @brief Check whether the provided filter matches the provided properties. + * @param[in] filter The filter. + * @param[in] props The properties. + * @return True if the filter matches the properties, false otherwise. + */ +CELIX_UTILS_EXPORT bool celix_filter_match(const celix_filter_t* filter, const celix_properties_t* props); -CELIX_UTILS_EXPORT bool celix_filter_equals(const celix_filter_t *filter1, const celix_filter_t *filter2); +/** + * @brief Check whether the 2 filters are equal. + * + * Note that the equals is done based on the parsed filter string and not on the provided filter strings. + * So the filters parsed from the strings "(key=value)" and " (key=value)" are equal. + * + * @param[in] filter1 The first filter. + * @param[in] filter2 The second filter. + * @return True if the filters are equal, false otherwise. + */ +CELIX_UTILS_EXPORT bool celix_filter_equals(const celix_filter_t* filter1, const celix_filter_t* filter2); -CELIX_UTILS_EXPORT const char* celix_filter_getFilterString(const celix_filter_t *filter); +/** + * @brief Get the filter string representation. + * + * @param[in] filter The filter. + * @return The filter string representation. The returned string is owned by the filter, must not be freed and is only + * valid as long as the filter is valid. + */ +CELIX_UTILS_EXPORT const char* celix_filter_getFilterString(const celix_filter_t* filter); /** - * Find the filter attribute. - * @return The attribute value or NULL if the attribute is not found. + * @brief Find the filter attribute. + * + * @param[in] filter The filter. + * @param[in] attribute The attribute to find. + * @return The found attribute value or NULL if the attribute is not found. The returned string is owned by the filter, + * must not be freed and is only valid as long as the filter is valid. */ -CELIX_UTILS_EXPORT const char* celix_filter_findAttribute(const celix_filter_t *filter, const char *attribute); +CELIX_UTILS_EXPORT const char* celix_filter_findAttribute(const celix_filter_t* filter, const char* attribute); /** - * Check whether the filter indicates the mandatory presence of an attribute with a specific value for the provided attribute key. + * @brief Check whether the filter indicates the mandatory presence of an attribute with a specific value for the + * provided attribute key. * * Example: * using this function for attribute key "key1" on filter "(key1=value1)" yields true. * using this function for attribute key "key1" on filter "(!(key1=value1))" yields false. * using this function for attribute key "key1" on filter "(key1>=value1)" yields false. * using this function for attribute key "key1" on filter "(|(key1=value1)(key2=value2))" yields false. -*/ -CELIX_UTILS_EXPORT bool celix_filter_hasMandatoryEqualsValueAttribute(const celix_filter_t *filter, const char *attribute); + * + * @param[in] filter The filter. + * @param[in] attribute The attribute to check. + * @return True if the filter indicates the mandatory presence of an attribute with a specific value for the provided + * attribute key, false otherwise. + */ +CELIX_UTILS_EXPORT bool celix_filter_hasMandatoryEqualsValueAttribute(const celix_filter_t* filter, + const char* attribute); /** - * Chek whether the filter indicates the mandatory absence of an attribute, regardless of its value, for the provided attribute key. + * @brief Check whether the filter indicates the mandatory absence of an attribute, regardless of its value, for the + * provided attribute key. * * example: * using this function for attribute key "key1" on the filter "(!(key1=*))" yields true. * using this function for attribute key "key1" on the filter "(key1=*) yields false. * using this function for attribute key "key1" on the filter "(key1=value)" yields false. * using this function for attribute key "key1" on the filter "(|(!(key1=*))(key2=value2))" yields false. + * + * @param[in] filter The filter. + * @param[in] attribute The attribute to check. + * @return True if the filter indicates the mandatory absence of an attribute, regardless of its value, for the provided + * attribute key, false otherwise. */ -CELIX_UTILS_EXPORT bool celix_filter_hasMandatoryNegatedPresenceAttribute(const celix_filter_t *filter, const char *attribute); +CELIX_UTILS_EXPORT bool celix_filter_hasMandatoryNegatedPresenceAttribute(const celix_filter_t* filter, + const char* attribute); #ifdef __cplusplus }
