/******************************************************************************* * Copyright (C) 2004-2006 Intel Corp. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of Intel Corp. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /** * @author Liang Hou, Intel Corp. */ #include "u/libu.h" #include "wsman-xml.h" #include "wsman-names.h" #include "wsman-filter.h" filter_t * filter_initialize(void) { filter_t *filter = u_zalloc(sizeof(filter_t)); return filter; } static int filter_set(filter_t *filter, const char *dialect, const char *query, epr_t *epr, hash_t *selectors, const int assocType, const char *assocClass, const char *resultClass, const char *role, const char *resultRole, char **resultProp, const int propNum) { int i = 0; if(dialect == NULL) { filter->dialect = u_strdup(WSM_XPATH_FILTER_DIALECT); } else { filter->dialect = u_strdup(dialect); } if (query) { filter->query = u_strdup(query); } else if(epr != 0) { filter->epr = epr_copy(epr); filter->assocType = assocType; if(assocClass) filter->assocClass = u_strdup(assocClass); if(resultClass) filter->resultClass = u_strdup(resultClass); if(role) filter->role = u_strdup(role); if(resultRole) filter->resultRole = u_strdup(resultRole); if(resultProp && propNum) { filter->resultProp = u_malloc(propNum*sizeof(char *)); filter->PropNum = propNum; while(i < propNum) { filter->resultProp[i] = u_strdup(resultProp[i]); i++; } } } else if(selectors) { hnode_t *hn; hscan_t hs; key_value_t *p; key_value_t *entry; filter->selectorset.count = hash_count(selectors); filter->selectorset.selectors = u_malloc(sizeof(key_value_t)* filter->selectorset.count); p = filter->selectorset.selectors; hash_scan_begin(&hs, selectors); while ((hn = hash_scan_next(&hs))) { entry = (key_value_t *)hnode_get(hn); key_value_create((char *)hnode_getkey(hn), (entry->type == 0)?entry->v.text:NULL, (entry->type == 1)?entry->v.epr:NULL, p); p++; } } else goto cleanup; return 0; cleanup: return 1; } filter_t *filter_create(const char *dialect, const char *query, epr_t *epr, hash_t *selectors, const int assocType, const char *assocClass, const char *resultClass, const char *role, const char *resultRole, char **resultProp, const int propNum) { int ret = 0; filter_t *filter = filter_initialize(); if (filter == NULL) return NULL; ret = filter_set(filter, dialect, query, epr, selectors, assocType, assocClass, resultClass, role, resultRole, resultProp, propNum); if (ret == 1 ) { filter_destroy(filter); return NULL; } else { return filter; } } int filter_set_simple(filter_t *filter, const char *dialect, const char *query) { return filter_set(filter, dialect, query, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0); } filter_t * filter_create_simple(const char *dialect, const char *query) { return filter_create(dialect, query, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0); } int filter_set_assoc(filter_t *filter, epr_t *epr, const int assocType, const char *assocClass, const char *resultClass, const char *role, const char *resultRole, char **resultProp, const int propNum) { return filter_set(filter, WSM_ASSOCIATION_FILTER_DIALECT, NULL, epr, NULL, assocType, assocClass, resultClass, role, resultRole, resultProp, propNum); } filter_t * filter_create_assoc(epr_t *epr, const int assocType, const char *assocClass, const char *resultClass, const char *role, const char *resultRole, char **resultProp, const int propNum) { return filter_create(WSM_ASSOCIATION_FILTER_DIALECT, NULL, epr, NULL, assocType, assocClass, resultClass, role, resultRole, resultProp, propNum); } filter_t * filter_create_selector(hash_t *selectors) { return filter_create(WSM_SELECTOR_FILTER_DIALECT, NULL, NULL, selectors, 0, NULL, NULL, NULL, NULL, NULL, 0); } static int _filter_add_selector(filter_t *filter, const char* key, const char *value, const epr_t *epr) { int i; key_value_t *entry; if(filter == NULL || key == NULL || ((value == NULL) && (epr == NULL))) return 0; entry = filter->selectorset.selectors; for(i = 0; i < filter->selectorset.count; i++) { if(strcmp(key, entry[i].key) == 0) return -1; } entry = u_realloc(entry, (filter->selectorset.count+1) * sizeof(key_value_t)); if(entry == NULL) return -1; key_value_create(key, value, epr, &(entry[filter->selectorset.count])); filter->selectorset.selectors = entry; filter->selectorset.count++; return 0; } int filter_add_selector(filter_t *filter, const char* key, const char *value) { return _filter_add_selector(filter, key, value, NULL); } int filter_add_selector_epr(filter_t *filter, const char* key, const epr_t *value) { return _filter_add_selector(filter, key, NULL, value); } filter_t * filter_copy(filter_t *filter) { filter_t *filter_cpy = NULL; key_value_t *p1; key_value_t *p2; int i = 0; if(filter == NULL) return NULL; filter_cpy = u_zalloc(sizeof(filter_t)); if(filter_cpy == NULL) return NULL; if(filter->dialect) filter_cpy->dialect = u_strdup(filter->dialect); filter_cpy->assocType = filter->assocType; if(filter->epr) filter_cpy->epr = epr_copy(filter->epr); if(filter->query) filter_cpy->query = u_strdup(filter->query); filter_cpy->selectorset.count = filter->selectorset.count; filter_cpy->selectorset.selectors = u_malloc(sizeof(key_value_t) * filter->selectorset.count); p1 = filter->selectorset.selectors; p2 = filter_cpy->selectorset.selectors; for(i = 0; i < filter_cpy->selectorset.count; i++) { key_value_copy(p1, p2); p1++; p2++; } if(filter->assocClass) filter_cpy->assocClass = u_strdup(filter->assocClass); if(filter->resultClass) filter_cpy->resultClass = u_strdup(filter->resultClass); if(filter->resultRole) filter_cpy->resultRole = u_strdup(filter->resultRole); if(filter->resultProp) { int i = 0; filter_cpy->resultProp = u_malloc(filter->PropNum*sizeof(char *)); filter_cpy->PropNum = filter->PropNum; while(i < filter->PropNum) { filter_cpy->resultProp[i] = u_strdup(filter->resultProp[i]); i++; } } return filter_cpy; } void filter_destroy(filter_t *filter) { key_value_t *p; int i; if(filter == NULL) return; if(filter->assocClass) u_free(filter->assocClass); if(filter->dialect) u_free(filter->dialect); if(filter->query) u_free(filter->query); if(filter->epr) epr_destroy(filter->epr); p = filter->selectorset.selectors; for(i = 0; i< filter->selectorset.count; i++) { key_value_destroy(p, 1); p++; } u_free(filter->selectorset.selectors); if(filter->resultClass) u_free(filter->resultClass); if(filter->resultProp) { int i = 0; while(i < filter->PropNum) { u_free(filter->resultProp[i]); i++; } u_free(filter->resultProp); } if(filter->resultRole) u_free(filter->resultRole); if(filter->role) u_free(filter->role); u_free(filter); } int filter_serialize(WsXmlNodeH node, filter_t *filter, const char *ns) { int r = 0; WsXmlNodeH filter_node = NULL; WsXmlNodeH instance_node = NULL; if(filter->query) { filter_node = ws_xml_add_child(node, ns, WSM_FILTER, filter->query); } else if(filter->epr) { filter_node = ws_xml_add_child(node, ns, WSM_FILTER, NULL); if(filter->assocType == 0) instance_node = ws_xml_add_child(filter_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES, NULL); else instance_node = ws_xml_add_child(filter_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES, NULL); r = epr_serialize(instance_node, XML_NS_CIM_BINDING, WSMB_OBJECT, filter->epr, 1); if(r) return r; if(filter->assocClass) ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_CLASS_NAME, filter->assocClass); if(filter->role) ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_ROLE, filter->role); if(filter->resultClass) ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_RESULT_CLASS_NAME, filter->resultClass); if(filter->resultRole) ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_RESULT_ROLE, filter->resultRole); if(filter->resultProp) { int i = 0; while(i < filter->PropNum) { ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_INCLUDE_RESULT_PROPERTY, filter->resultProp[i]); i++; } } } else if(filter->selectorset.count) { int i = 0; filter_node = ws_xml_add_child(node, ns, WSM_FILTER, NULL); node = ws_xml_add_child(filter_node, XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL); while (i < filter->selectorset.count) { if(filter->selectorset.selectors[i].type == 0) { instance_node = ws_xml_add_child(node, XML_NS_WS_MAN, WSM_SELECTOR, filter->selectorset.selectors[i].v.text); ws_xml_add_node_attr(instance_node, NULL, WSM_NAME, filter->selectorset.selectors[i].key); } else { epr_serialize(node, NULL, NULL, (epr_t *)filter->selectorset.selectors[i].v.epr, 1); } i++; } } else { return -1; } if(filter->dialect) ws_xml_add_node_attr(filter_node, NULL, WSM_DIALECT, filter->dialect); return r; } filter_t * filter_deserialize(WsXmlNodeH node, const char *ns) { char *dialect = NULL; int properNum = 0; int i = 0; WsXmlAttrH attr = NULL; filter_t *filter = NULL; WsXmlNodeH instance_node = NULL; WsXmlNodeH entry_node = NULL; /* look for wse:Filter */ WsXmlNodeH filter_node = ws_xml_get_child(node, 0, ns, WSM_FILTER); if(filter_node == NULL) return NULL; filter = u_zalloc(sizeof(filter_t)); dialect = ws_xml_find_attr_value(filter_node, NULL, WSM_DIALECT); if(dialect) filter->dialect = u_strdup(dialect); else{ attr = ws_xml_get_node_attr(filter_node, 0); if(attr) { filter->dialect = u_strdup(ws_xml_get_attr_value(attr)); } else filter->dialect = u_strdup(WSM_XPATH_FILTER_DIALECT); } if(strcmp(filter->dialect , WSM_ASSOCIATION_FILTER_DIALECT) == 0) { instance_node = ws_xml_get_child(filter_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES); if(instance_node) { filter->assocType = 0; } else { instance_node = ws_xml_get_child(filter_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES); if(instance_node) { filter->assocType = 1; } else goto CLEANUP; } filter->epr = epr_deserialize(instance_node, XML_NS_CIM_BINDING, WSMB_OBJECT, 1); entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_CLASS_NAME); if(entry_node) filter->assocClass = u_strdup(ws_xml_get_node_text(entry_node)); entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_ROLE); if(entry_node) filter->role = u_strdup(ws_xml_get_node_text(entry_node)); entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_RESULT_CLASS_NAME); if(entry_node) filter->resultClass = u_strdup(ws_xml_get_node_text(entry_node)); entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_RESULT_ROLE); if(entry_node) filter->resultRole = u_strdup(ws_xml_get_node_text(entry_node)); properNum = ws_xml_get_child_count(instance_node) - 4; filter->resultProp = u_zalloc(properNum * sizeof(char*)); while(i < properNum) { filter_node = ws_xml_get_child(instance_node, i, XML_NS_CIM_BINDING, WSMB_INCLUDE_RESULT_PROPERTY); if(filter_node == NULL) break; filter->resultProp[i] = u_strdup(ws_xml_get_node_text(filter_node)); i++; } filter->PropNum = i; } else if(strcmp(filter->dialect, WSM_SELECTOR_FILTER_DIALECT) == 0) { filter_node = ws_xml_get_child(filter_node, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET); if(filter_node == NULL) goto CLEANUP; filter->selectorset.count = ws_xml_get_child_count(filter_node); filter->selectorset.selectors = u_malloc(sizeof(key_value_t) * filter->selectorset.count ); while(i < filter->selectorset.count) { const char *key; const char *text; epr_t *epr; entry_node = ws_xml_get_child(filter_node, i, XML_NS_WS_MAN, WSM_SELECTOR); if(entry_node == NULL) break; attr = ws_xml_find_node_attr(entry_node, NULL, WSM_NAME); if(attr) { key = ws_xml_get_attr_value(attr); } else { key = NULL; } instance_node = ws_xml_get_child(entry_node, 0, XML_NS_ADDRESSING, WSA_EPR); if(instance_node) { epr = epr_deserialize(instance_node, NULL, NULL, 1); text = NULL; } else { text = ws_xml_get_node_text(entry_node); epr = NULL; } key_value_create(key, text, epr, filter->selectorset.selectors + i); if (epr) { /* key_value_create() did a epr_copy */ epr_destroy(epr); } i++; } } else filter->query = u_strdup(ws_xml_get_node_text(filter_node)); return filter; CLEANUP: filter_destroy(filter); return NULL; }