Changeset 5371

Show
Ignore:
Timestamp:
03/13/08 11:01:38 (4 months ago)
Author:
morris
Message:

Allow loading of collections of fields

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libwired/trunk/libwired/p7/wi-p7-spec.c

    r5326 r5371  
    147147 
    148148static _wi_p7_spec_parameter_t *                        _wi_p7_spec_parameter_with_node(wi_p7_spec_t *, xmlNodePtr, _wi_p7_spec_message_t *); 
     149static _wi_p7_spec_parameter_t *                        _wi_p7_spec_parameter_with_field(wi_p7_spec_t *, _wi_p7_spec_message_t *, _wi_p7_spec_field_t *); 
    149150static void                                                                     _wi_p7_spec_parameter_dealloc(wi_runtime_instance_t *); 
    150151static wi_string_t *                                            _wi_p7_spec_parameter_description(wi_runtime_instance_t *); 
     
    284285        wi_hash_t                                                               *messages_name, *messages_id; 
    285286        wi_hash_t                                                               *fields_name, *fields_id; 
     287        wi_hash_t                                                               *collections_name; 
    286288        wi_hash_t                                                               *types_name, *types_id; 
    287289        wi_hash_t                                                               *transactions_name; 
     
    303305static wi_boolean_t                                                     _wi_p7_spec_load_types(wi_p7_spec_t *, xmlNodePtr); 
    304306static wi_boolean_t                                                     _wi_p7_spec_load_fields(wi_p7_spec_t *, xmlNodePtr); 
     307static wi_boolean_t                                                     _wi_p7_spec_load_collection(wi_p7_spec_t *, xmlNodePtr); 
     308static _wi_p7_spec_field_t *                            _wi_p7_spec_load_field(wi_p7_spec_t *, xmlNodePtr); 
    305309static wi_boolean_t                                                     _wi_p7_spec_load_messages(wi_p7_spec_t *, xmlNodePtr); 
    306310static wi_boolean_t                                                     _wi_p7_spec_load_transactions(wi_p7_spec_t *, xmlNodePtr); 
     
    540544                500, wi_hash_null_key_callbacks, wi_hash_default_value_callbacks); 
    541545 
     546        p7_spec->collections_name               = wi_hash_init_with_capacity(wi_hash_alloc(), 20); 
     547 
    542548        p7_spec->types_name                             = wi_hash_init_with_capacity(wi_hash_alloc(), 20); 
    543549        p7_spec->types_id                               = wi_hash_init_with_capacity_and_callbacks(wi_hash_alloc(), 
     
    821827 
    822828static wi_boolean_t _wi_p7_spec_load_fields(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     829        xmlNodePtr              field_node; 
     830         
     831        for(field_node = node->children; field_node != NULL; field_node = field_node->next) { 
     832                if(field_node->type == XML_ELEMENT_NODE) { 
     833                        if(strcmp((const char *) field_node->name, "field") == 0) { 
     834                                if(!_wi_p7_spec_load_field(p7_spec, field_node)) 
     835                                        return false; 
     836                        } 
     837                        else if(strcmp((const char *) field_node->name, "collection") == 0) { 
     838                                if(!_wi_p7_spec_load_collection(p7_spec, field_node)) 
     839                                        return false; 
     840                        } 
     841                } 
     842        } 
     843         
     844        return true; 
     845} 
     846 
     847 
     848 
     849static wi_boolean_t _wi_p7_spec_load_collection(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     850        wi_array_t                              *collection; 
     851        wi_string_t                             *name; 
    823852        _wi_p7_spec_field_t             *field; 
    824853        xmlNodePtr                              field_node; 
    825854         
     855        name = wi_autorelease(wi_p7_xml_copy_string_for_attribute(node, WI_STR("name"))); 
     856         
     857        if(!name) { 
     858                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     859                        WI_STR("Collection has no \"name\"")); 
     860                 
     861                return false; 
     862        } 
     863 
     864        if(wi_hash_data_for_key(p7_spec->collections_name, name)) { 
     865                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     866                        WI_STR("Collection with name \"%@\" already exists"), 
     867                        name); 
     868                 
     869                return false; 
     870        } 
     871         
     872        collection = wi_array(); 
     873         
    826874        for(field_node = node->children; field_node != NULL; field_node = field_node->next) { 
    827875                if(field_node->type == XML_ELEMENT_NODE) { 
    828                         field = _wi_p7_spec_field_with_node(p7_spec, field_node); 
     876                        field = _wi_p7_spec_load_field(p7_spec, field_node); 
    829877                         
    830878                        if(!field) 
    831879                                return false; 
    832880                         
    833                         if(wi_hash_data_for_key(p7_spec->fields_name, field->name)) { 
    834                                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    835                                         WI_STR("Field with name \"%@\" already exists"), 
    836                                         field->name); 
    837                                  
    838                                 return false; 
    839                         } 
    840                          
    841                         if(wi_hash_data_for_key(p7_spec->fields_id, (void *) field->id)) { 
    842                                 wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    843                                         WI_STR("Field with id %lu (name \"%@\") already exists"), 
    844                                         field->id, field->name); 
    845                                  
    846                                 return false; 
    847                         } 
    848  
    849                         wi_hash_set_data_for_key(p7_spec->fields_name, field, field->name); 
    850                         wi_hash_set_data_for_key(p7_spec->fields_id, field, (void *) field->id); 
    851                 } 
    852         } 
     881                        wi_array_add_data(collection, field); 
     882                } 
     883        } 
     884         
     885        if(wi_array_count(collection) == 0) { 
     886                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     887                        WI_STR("Collection has no fields")); 
     888                 
     889                return false; 
     890        } 
     891 
     892        wi_hash_set_data_for_key(p7_spec->collections_name, collection, name); 
    853893         
    854894        return true; 
     895} 
     896 
     897 
     898 
     899static _wi_p7_spec_field_t * _wi_p7_spec_load_field(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     900        _wi_p7_spec_field_t             *field; 
     901         
     902        field = _wi_p7_spec_field_with_node(p7_spec, node); 
     903         
     904        if(!field) 
     905                return NULL; 
     906         
     907        if(wi_hash_data_for_key(p7_spec->fields_name, field->name)) { 
     908                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     909                        WI_STR("Field with name \"%@\" already exists"), 
     910                        field->name); 
     911                 
     912                return NULL; 
     913        } 
     914         
     915        if(wi_hash_data_for_key(p7_spec->fields_id, (void *) field->id)) { 
     916                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     917                        WI_STR("Field with id %lu (name \"%@\") already exists"), 
     918                        field->id, field->name); 
     919                 
     920                return NULL; 
     921        } 
     922 
     923        wi_hash_set_data_for_key(p7_spec->fields_name, field, field->name); 
     924        wi_hash_set_data_for_key(p7_spec->fields_id, field, (void *) field->id); 
     925         
     926        return field; 
    855927} 
    856928 
     
    17871859 
    17881860static _wi_p7_spec_message_t * _wi_p7_spec_message_with_node(wi_p7_spec_t *p7_spec, xmlNodePtr node) { 
     1861        wi_enumerator_t                         *enumerator; 
     1862        wi_array_t                                      *fields; 
     1863        wi_string_t                                     *field_name, *collection_name, *use; 
    17891864        xmlNodePtr                                      parameter_node; 
    17901865        _wi_p7_spec_message_t           *message; 
    17911866        _wi_p7_spec_parameter_t         *parameter; 
     1867        _wi_p7_spec_field_t                     *field; 
     1868        wi_boolean_t                            required; 
    17921869 
    17931870    message = wi_autorelease(wi_runtime_create_instance(_wi_p7_spec_message_runtime_id, sizeof(_wi_p7_spec_message_t))); 
     
    18171894        for(parameter_node = node->children; parameter_node != NULL; parameter_node = parameter_node->next) { 
    18181895                if(parameter_node->type == XML_ELEMENT_NODE) { 
    1819                         parameter = _wi_p7_spec_parameter_with_node(p7_spec, parameter_node, message); 
    1820  
    1821                         if(!parameter) 
    1822                                 return NULL; 
    1823                          
    1824                         if(wi_hash_data_for_key(message->parameters_name, parameter->field->name)) { 
     1896                        field_name                      = wi_autorelease(wi_p7_xml_copy_string_for_attribute(parameter_node, WI_STR("field"))); 
     1897                        collection_name         = wi_autorelease(wi_p7_xml_copy_string_for_attribute(parameter_node, WI_STR("collection"))); 
     1898                         
     1899                        if(field_name) { 
     1900                                parameter = _wi_p7_spec_parameter_with_node(p7_spec, parameter_node, message); 
     1901 
     1902                                if(!parameter) 
     1903                                        return NULL; 
     1904                                 
     1905                                if(wi_hash_data_for_key(message->parameters_name, parameter->field->name)) { 
     1906                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1907                                                WI_STR("Message \"%@\" has a duplicate field \"%@\""), 
     1908                                                message->name, parameter->field->name); 
     1909                                         
     1910                                        return NULL; 
     1911                                } 
     1912                                 
     1913                                wi_hash_set_data_for_key(message->parameters_name, parameter, parameter->field->name); 
     1914                                wi_hash_set_data_for_key(message->parameters_id, parameter, (void *) parameter->field->id); 
     1915                                 
     1916                                if(parameter->required) 
     1917                                        message->required_parameters++; 
     1918                        } 
     1919                        else if(collection_name) { 
     1920                                fields = wi_hash_data_for_key(p7_spec->collections_name, collection_name); 
     1921                                 
     1922                                if(!fields) { 
     1923                                        wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1924                                                WI_STR("Parameter in message \"%@\" has an invalid \"collection\" (\"%@\")"), 
     1925                                                message->name, collection_name); 
     1926                                } 
     1927 
     1928                                required = false; 
     1929                                use = wi_autorelease(wi_p7_xml_copy_string_for_attribute(parameter_node, WI_STR("use"))); 
     1930 
     1931                                if(use) { 
     1932                                        if(wi_string_case_insensitive_compare(use, WI_STR("required")) != 0 && 
     1933                                           wi_string_case_insensitive_compare(use, WI_STR("optional")) != 0) { 
     1934                                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1935                                                        WI_STR("Parameter \"%@\" in message \"%@\" has an invalid \"use\" (\"%@\")"), 
     1936                                                        collection_name, message->name, use); 
     1937                                                 
     1938                                                return NULL; 
     1939                                        } 
     1940 
     1941                                        required = (wi_string_case_insensitive_compare(use, WI_STR("required")) == 0); 
     1942                                } 
     1943 
     1944                                enumerator = wi_array_data_enumerator(fields); 
     1945                                 
     1946                                while((field = wi_enumerator_next_data(enumerator))) { 
     1947                                        parameter = _wi_p7_spec_parameter_with_field(p7_spec, message, field); 
     1948                                         
     1949                                        if(!parameter) 
     1950                                                return NULL; 
     1951 
     1952                                        if(wi_hash_data_for_key(message->parameters_name, parameter->field->name)) { 
     1953                                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
     1954                                                        WI_STR("Message \"%@\" has a duplicate field \"%@\""), 
     1955                                                        message->name, parameter->field->name); 
     1956                                                 
     1957                                                return NULL; 
     1958                                        } 
     1959                                         
     1960                                        wi_hash_set_data_for_key(message->parameters_name, parameter, parameter->field->name); 
     1961                                        wi_hash_set_data_for_key(message->parameters_id, parameter, (void *) parameter->field->id); 
     1962                                         
     1963                                        parameter->required = required; 
     1964                                         
     1965                                        if(parameter->required) 
     1966                                                message->required_parameters++; 
     1967                                } 
     1968                        } 
     1969                        else { 
    18251970                                wi_error_set_libwired_p7_error(WI_ERROR_P7_INVALIDSPEC, 
    1826                                         WI_STR("Message \"%@\" has a duplicate field \"%@\""), 
    1827                                         message->name, parameter->field->name); 
     1971                                        WI_STR("Parameter in message \"%@\" has no \"field\" or \"collection\""), 
     1972                                        message->name); 
    18281973                                 
    18291974                                return NULL; 
    18301975                        } 
    1831                          
    1832                         wi_hash_set_data_for_key(message->parameters_name, parameter, parameter->field->name); 
    1833                         wi_hash_set_data_for_key(message->parameters_id, parameter, (void *) parameter->field->id); 
    1834                          
    1835                         if(parameter->required) 
    1836                                 message->required_parameters++; 
    18371976                } 
    18381977        } 
     
    19102049                parameter->required = (wi_string_case_insensitive_compare(use, WI_STR("required")) == 0); 
    19112050        } 
     2051 
     2052        return parameter; 
     2053} 
     2054 
     2055 
     2056 
     2057static _wi_p7_spec_parameter_t * _wi_p7_spec_parameter_with_field(wi_p7_spec_t *p7_spec, _wi_p7_spec_message_t *message, _wi_p7_spec_field_t *field) { 
     2058        _wi_p7_spec_parameter_t *parameter; 
     2059 
     2060    parameter = wi_autorelease(wi_runtime_create_instance(_wi_p7_spec_parameter_runtime_id, sizeof(_wi_p7_spec_parameter_t))); 
     2061        parameter->field = wi_retain(field); 
    19122062 
    19132063        return parameter;