| /******************************************************************************* |
| * 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; |
| Selector *p; |
| selector_entry *entry; |
| filter->selectorset.count = hash_count(selectors); |
| filter->selectorset.selectors = u_malloc(sizeof(Selector)* |
| filter->selectorset.count); |
| |
| p = filter->selectorset.selectors; |
| hash_scan_begin(&hs, selectors); |
| while ((hn = hash_scan_next(&hs))) { |
| p->name = u_strdup((char *)hnode_getkey(hn)); |
| entry = (selector_entry *)hnode_get(hn); |
| if(entry->type == 1) { |
| p->type = 1; |
| p->value = (char *)epr_copy(entry->entry.eprp); |
| debug("key=%s value=%p(nested epr)", |
| (char *) hnode_getkey(hn), p->value); |
| } else { |
| p->type = 0; |
| p->value = u_strdup(entry->entry.text); |
| debug("key=%s value=%s", |
| (char *) hnode_getkey(hn), p->value); |
| } |
| 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); |
| } |
| |
| int filter_add_selector(filter_t *filter, const char* key, const char *value) |
| { |
| int i; |
| Selector *entry; |
| if(filter == NULL || key == NULL || value == NULL) |
| return 0; |
| entry = filter->selectorset.selectors; |
| for(i = 0; i < filter->selectorset.count; i++) { |
| if(strcmp(key, entry[i].name) == 0) |
| return -1; |
| } |
| entry = u_realloc(entry, (filter->selectorset.count+1) * sizeof(Selector)); |
| if(entry == NULL) return -1; |
| |
| entry[filter->selectorset.count].type = 0; |
| entry[filter->selectorset.count].name = u_strdup(key); |
| entry[filter->selectorset.count].value = u_strdup(value); |
| filter->selectorset.selectors = entry; |
| filter->selectorset.count++; |
| |
| return 0; |
| |
| } |
| |
| filter_t * filter_copy(filter_t *filter) |
| { |
| filter_t *filter_cpy = NULL; |
| Selector *p1; |
| Selector *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(Selector) * |
| filter->selectorset.count); |
| p1 = filter->selectorset.selectors; |
| p2 = filter_cpy->selectorset.selectors; |
| for(i = 0; i < filter_cpy->selectorset.count; i++) { |
| p2->name = u_strdup(p1->name); |
| p2->type = p1->type; |
| if(p1->type == 0) |
| p2->value = u_strdup(p1->value); |
| else |
| p2->value = (char *)epr_copy((epr_t*)p1->value); |
| 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) |
| { |
| Selector *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++) { |
| u_free(p->name); |
| if(p->type == 0) |
| u_free(p->value); |
| else |
| epr_destroy((epr_t*)p->value); |
| 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].value); |
| ws_xml_add_node_attr(instance_node, NULL, WSM_NAME, filter->selectorset.selectors[i].name); |
| } |
| else { |
| epr_serialize(node, NULL, NULL, (epr_t *)filter->selectorset.selectors[i].value, 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(Selector) * filter->selectorset.count ); |
| while(i < filter->selectorset.count) { |
| 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) { |
| filter->selectorset.selectors[i].name = u_strdup(ws_xml_get_attr_value(attr)); |
| } |
| instance_node = ws_xml_get_child(entry_node, 0, XML_NS_ADDRESSING, WSA_EPR); |
| if(instance_node) { |
| filter->selectorset.selectors[i].type = 1; |
| filter->selectorset.selectors[i].value = (char *)epr_deserialize(instance_node, NULL, NULL, 1); |
| } |
| else { |
| filter->selectorset.selectors[i].type = 0; |
| filter->selectorset.selectors[i].value = u_strdup(ws_xml_get_node_text(entry_node)); |
| } |
| i++; |
| } |
| } |
| else |
| filter->query = u_strdup(ws_xml_get_node_text(filter_node)); |
| |
| return filter; |
| |
| CLEANUP: |
| filter_destroy(filter); |
| return NULL; |
| } |