blob: 6118d2ad5be7452546a40a76c9cb9d2b4d42cb5c [file] [log] [blame]
/*******************************************************************************
* 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;
}