axis-c-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dustfinger x <dustfin...@muddymukluk.com>
Subject RESTLocation: how best to traverse the tree to map parameters?
Date Sat, 02 Apr 2011 20:53:21 GMT
// 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}&param2={aparam2}&param3={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&param2=bar&param3=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

Mime
View raw message