blob: 0efc270c67254dade9c41588975fab42f52b521e [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;
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;
}