You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by dustfinger x <du...@muddymukluk.com> on 2011/04/02 22:53:21 UTC
RESTLocation: how best to traverse the tree to map parameters?
// GOAL
Goal: to map uri parameters to their respective values by populating a
map<char*,char*> collection.
// PROBLEM
Problem: The tree structure duplicates nodes and allocates different memory
for those nodes. This makes it somewhat difficult to check if the map
already contains the key before doing an insert. I will illustrate exactly
what my issue is with an example:
Suppose that I have the following RESTLocation defined for the operation
named paramTest.
<parameter
name="RESTLocation">get/many/param/type/{type}/name/of/{name}/end?param1={aparam1}¶m2={aparam2}¶m3={aparam3}</parameter>
paramTest will invoke a method called populateUriParameterMap which
populates a map<char*, char*> structure that maps the name of each parameter
to its assigned value. type->atype, name->aname etc... Once the map has been
populated paramTest will iterate over the map and write the associated
values to the axis log.
So when I request the following resource I get the resulting log:
get/many/param/type/atype/name/of/aname/end?param1=foo¶m2=bar¶m3=foobar
The log shows param1, param2, param3 twice, but with different memory
addresses. I check to see if the map contains these keys before doing the
insert, but it will always pass the test, since it is different memory.
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param1 [6ca830], second = foo [6d1be0]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param2 [6caa80], second = bar [6d1b20]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param3 [6cab00], second = foobar [6d1b80]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=name [6cabc0], second = aname [6d1a60]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param1 [6cad30], second = foo [6d1ac0]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=type [6cb160], second = atype [6d1a00]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param2 [6cb9d0], second = bar [6d1c40]
[Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param3 [6cbba0], second = foobar [6d1ca0]
Is there a way for me to iterate through the tree and skip these duplicate
nodes? Otherwise I will have to run a value based comparison check on the
maps collection of keys to see if the value of the key is already in the map
and this is not desirable.
// RELEVANT SOURCE CODE BEGIN
/**
*/
axiom_node_t* paramTest(const axutil_env_t *environment, axiom_node_t
*node){
AXIS2_ENV_CHECK(environment, NULL);
axiom_node_t *return_node = NULL;
map<char*, char*> uriParameterMap = map<char*, char*>();
map<char*, char*>::const_iterator itr;
populateUriParameterMap(environment, node, uriParameterMap);
for(itr = uriParameterMap.begin(); itr!=uriParameterMap.end(); itr++){
char* first = itr->first;
char* second = itr->second;
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "queryParam Map first=%s
[%d], second = %s [%d]", first, first, second, second);
}
return return_node;
}
void populateUriParameterMap(const axutil_env_t *environment, axiom_node_t
*node, map<char*, char*> &uriParameterMap){
/* Extracting out the child nodes from the request */
axiom_node_t *child = axiom_node_get_first_child(node, environment);
axiom_node_t *sibling = child;
axis2_char_t* localName = NULL;
axis2_char_t* textValue = NULL;
while(sibling && !axiom_node_is_complete(sibling, environment)){
axiom_types_t nodeType = axiom_node_get_node_type(sibling, environment);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "type_node of type [%d]
found ", nodeType);
axiom_element_t *dataElement =
static_cast<axiom_element_t*>(axiom_node_get_data_element(sibling,
environment));
localName = axiom_element_get_localname(dataElement, environment);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->localName
[%s] found ", localName);
textValue = axiom_element_get_text(dataElement, environment,sibling);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->text_value
[%s] found ", textValue);
//insert into map, but first check to see if it already contains the
key.
//This will always return true since the tree has duplicate nodes with
different memory addresses.
if(uriParameterMap.end() == uriParameterMap.find(localName)){
uriParameterMap.insert(pair<char*, char*>(localName, textValue));
}
sibling = axiom_node_get_next_sibling(sibling, environment);
}
}
// RELEVANT SOURCE CODE END
Sincerely,
dustfinger
Re: RESTLocation: how best to traverse the tree to map parameters?
Posted by dustfinger x <du...@muddymukluk.com>.
I resolved the issue by changing the defenition of my map from map<char*,
char*> uriParameterMap = map<char*, char*>(); to
map<string, char*> uriParameterMap = map<char*, char*>(); so now the key is
not a pointer. I am still curious if I am traversing the tree the best way
for what I am trying to accomplish, none the less it seems to be satisfying
my requirements. Here is the output from the logs after changing the
definition of the map
[Sat Apr 2 15:46:54 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=name [6d1ac8], second = aname [6d1a90]
[Sat Apr 2 15:46:54 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param1 [6d1b58], second = foo [6d1b20]
[Sat Apr 2 15:46:54 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param2 [6d1be8], second = bar [6d1bb0]
[Sat Apr 2 15:46:54 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=param3 [6d1c78], second = foobar [6d1c40]
[Sat Apr 2 15:46:54 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
Map first=type [6d1a38], second = atype [6d1a00]
Here is the updated code:
// CODE BEGIN
axiom_node_t* paramTest(const axutil_env_t *environment, axiom_node_t
*node){
AXIS2_ENV_CHECK(environment, NULL);
axiom_node_t *return_node = NULL;
map<string, char*> uriParameterMap = map<string, char*>();
map<string, char*>::const_iterator itr;
populateUriParameterMap(environment, node, uriParameterMap);
//build response
for(itr = uriParameterMap.begin(); itr!=uriParameterMap.end(); itr++){
string first = itr->first;
char* second = itr->second;
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "queryParam Map first=%s
[%0x], second = %s [%0x]", first.c_str(), first.c_str(), second, second);
}
return return_node;
}
void populateUriParameterMap(const axutil_env_t *environment, axiom_node_t
*node, map<string, char*> &uriParameterMap){
/* Extracting out the child nodes from the request */
axiom_node_t *child = axiom_node_get_first_child(node, environment);
axiom_node_t *sibling = child;
axis2_char_t* localName = NULL;
axis2_char_t* textValue = NULL;
while(sibling && !axiom_node_is_complete(sibling, environment)){
axiom_types_t nodeType = axiom_node_get_node_type(sibling, environment);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "type_node of type [%d]
found ", nodeType);
axiom_element_t *dataElement =
static_cast<axiom_element_t*>(axiom_node_get_data_element(sibling,
environment));
localName = axiom_element_get_localname(dataElement, environment);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->localName
[%s] found ", localName);
textValue = axiom_element_get_text(dataElement, environment,sibling);
AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->text_value
[%s] found ", textValue);
string sLocalName = localName;
//insert into map, but first check to see if it already contains the
key.
if(uriParameterMap.end() == uriParameterMap.find(sLocalName)){
uriParameterMap.insert(pair<string, char*>(sLocalName, textValue));
}
sibling = axiom_node_get_next_sibling(sibling, environment);
}
}
// CODE END
sincerely,
dustfinger
On Sat, Apr 2, 2011 at 2:53 PM, dustfinger x <du...@muddymukluk.com>wrote:
> // GOAL
> Goal: to map uri parameters to their respective values by populating a
> map<char*,char*> collection.
>
> // PROBLEM
> Problem: The tree structure duplicates nodes and allocates different memory
> for those nodes. This makes it somewhat difficult to check if the map
> already contains the key before doing an insert. I will illustrate exactly
> what my issue is with an example:
>
> Suppose that I have the following RESTLocation defined for the operation
> named paramTest.
>
> <parameter
> name="RESTLocation">get/many/param/type/{type}/name/of/{name}/end?param1={aparam1}¶m2={aparam2}¶m3={aparam3}</parameter>
>
> paramTest will invoke a method called populateUriParameterMap which
> populates a map<char*, char*> structure that maps the name of each parameter
> to its assigned value. type->atype, name->aname etc... Once the map has been
> populated paramTest will iterate over the map and write the associated
> values to the axis log.
>
> So when I request the following resource I get the resulting log:
>
> get/many/param/type/atype/name/of/aname/end?param1=foo¶m2=bar¶m3=foobar
>
> The log shows param1, param2, param3 twice, but with different memory
> addresses. I check to see if the map contains these keys before doing the
> insert, but it will always pass the test, since it is different memory.
>
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param1 [6ca830], second = foo [6d1be0]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param2 [6caa80], second = bar [6d1b20]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param3 [6cab00], second = foobar [6d1b80]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=name [6cabc0], second = aname [6d1a60]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param1 [6cad30], second = foo [6d1ac0]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=type [6cb160], second = atype [6d1a00]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param2 [6cb9d0], second = bar [6d1c40]
> [Sat Apr 2 14:45:48 2011] [debug] DataServiceSkeleton.cpp(340) queryParam
> Map first=param3 [6cbba0], second = foobar [6d1ca0]
>
> Is there a way for me to iterate through the tree and skip these duplicate
> nodes? Otherwise I will have to run a value based comparison check on the
> maps collection of keys to see if the value of the key is already in the map
> and this is not desirable.
>
> // RELEVANT SOURCE CODE BEGIN
>
> /**
> */
> axiom_node_t* paramTest(const axutil_env_t *environment, axiom_node_t
> *node){
>
> AXIS2_ENV_CHECK(environment, NULL);
>
> axiom_node_t *return_node = NULL;
>
> map<char*, char*> uriParameterMap = map<char*, char*>();
> map<char*, char*>::const_iterator itr;
> populateUriParameterMap(environment, node, uriParameterMap);
>
> for(itr = uriParameterMap.begin(); itr!=uriParameterMap.end(); itr++){
> char* first = itr->first;
> char* second = itr->second;
>
> AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "queryParam Map first=%s
> [%d], second = %s [%d]", first, first, second, second);
> }
>
>
> return return_node;
> }
>
> void populateUriParameterMap(const axutil_env_t *environment, axiom_node_t
> *node, map<char*, char*> &uriParameterMap){
>
> /* Extracting out the child nodes from the request */
> axiom_node_t *child = axiom_node_get_first_child(node, environment);
> axiom_node_t *sibling = child;
>
> axis2_char_t* localName = NULL;
> axis2_char_t* textValue = NULL;
>
> while(sibling && !axiom_node_is_complete(sibling, environment)){
> axiom_types_t nodeType = axiom_node_get_node_type(sibling,
> environment);
> AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "type_node of type [%d]
> found ", nodeType);
> axiom_element_t *dataElement =
> static_cast<axiom_element_t*>(axiom_node_get_data_element(sibling,
> environment));
>
>
> localName = axiom_element_get_localname(dataElement, environment);
> AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->localName
> [%s] found ", localName);
>
> textValue = axiom_element_get_text(dataElement, environment,sibling);
>
> AXIS2_LOG_USER(environment->log, AXIS2_LOG_SI, "dataElement->text_value
> [%s] found ", textValue);
>
> //insert into map, but first check to see if it already contains the
> key.
> //This will always return true since the tree has duplicate nodes with
> different memory addresses.
> if(uriParameterMap.end() == uriParameterMap.find(localName)){
> uriParameterMap.insert(pair<char*, char*>(localName, textValue));
> }
>
> sibling = axiom_node_get_next_sibling(sibling, environment);
>
> }
> }
>
> // RELEVANT SOURCE CODE END
>
> Sincerely,
>
> dustfinger
>