1 /* defines the currently used bootstrap config file */
2 #include <opensrf/osrfConfig.h>
6 @brief Routines for managing osrfConfigs to represent configuration information.
10 @brief Points to the default configuration.
12 static osrfConfig* osrfConfigDefault = NULL;
15 @brief Install a specified osrfConfig as the default configuration.
16 @param cfg Pointer to the configuration to be stored.
18 Store the passed pointer for future reference. The calling code yields ownership of the
19 associated osrfConfig.
21 void osrfConfigSetDefaultConfig(osrfConfig* cfg) {
23 if( osrfConfigDefault )
24 osrfConfigFree( osrfConfigDefault );
25 osrfConfigDefault = cfg;
30 @brief Free an osrfConfig.
31 @param cfg Pointer to the osrfConfig to be freed.
33 void osrfConfigFree(osrfConfig* cfg) {
35 jsonObjectFree(cfg->config);
36 free(cfg->configContext);
42 @brief Report whether a default configuration has been installed.
43 @return Boolean: true if a default configuration is available, or false if not.
45 int osrfConfigHasDefaultConfig( void ) {
46 return ( osrfConfigDefault != NULL );
50 @brief Free the default configuration, if it exists.
52 void osrfConfigCleanup( void ) {
53 osrfConfigFree(osrfConfigDefault);
54 osrfConfigDefault = NULL;
58 @brief Replace the jsonObject of an osrfConfig.
59 @param cfg The osrfConfig to alter.
60 @param obj The jsonObject to install in the osrfConfig.
62 This is useful if you have a json object already, rather than an XML configuration file
65 void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj) {
66 if(!cfg || !obj) return;
67 jsonObjectFree(cfg->config);
68 cfg->config = jsonObjectClone(obj);
72 @brief Load an XML configuration file into a jsonObject within an osrfConfig.
73 @param configFile Name of the XML configuration file.
74 @param configContext (Optional) Root of a subtree in the configuration file,
75 @return If successful, a pointer to the resulting osrfConfig; otherwise NULL.
77 If @a configContext is not NULL, save a copy of the string to which it points. It is a
78 tag identifying one or more subtrees within the XML; subsequent searches will examine
79 only matching subtrees. Otherwise they will search the tree from the root.
81 (In practice a configContext is always supplied, so that different programs can share
82 the same configuration file, partitioned by context tags.)
84 The calling code is responsible for freeing the returned config object by calling
87 osrfConfig* osrfConfigInit(const char* configFile, const char* configContext) {
88 if(!configFile) return NULL;
90 // Load XML from the configuration file
92 xmlDocPtr doc = xmlParseFile(configFile);
94 osrfLogWarning( OSRF_LOG_MARK, "Unable to parse XML config file %s", configFile);
98 // Translate it into a jsonObject
99 jsonObject* json_config = xmlDocToJSON(doc);
103 osrfLogWarning( OSRF_LOG_MARK, "xmlDocToJSON failed for config %s", configFile);
107 // Build an osrfConfig and return it by pointer
108 osrfConfig* cfg = safe_malloc(sizeof(osrfConfig));
111 cfg->configContext = strdup(configContext);
113 cfg->configContext = NULL;
115 cfg->config = json_config;
121 @brief Search a configuration for a specified value.
122 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
123 @param path A printf-style format string representing the search path. Subsequent
124 parameters, if any, are inserted into the format string to form the search path.
125 @return A pointer to a newly allocated string containing the value, if found; otherwise
128 Search for a value in the configuration, as specified by the search path.
130 If cfg is NULL, search the default configuration; otherwise search the configuration
133 If the configuration includes a configContext, then prepend it to the path, like so:
134 "//<configContext><path>". Hence the path should begin with a slash to separate it from
135 the context. Search for the resulting effective path at any level within the
138 If the configuration does @em not include a configContext, then start the search at the
139 root of the configuration. In this case the path should @em not begin with a slash.
141 If the configuration contains more than one entry at locations matching the effective
142 search path, return NULL.
144 Return numeric values as numeric strings.
146 The calling code is responsible for freeing the returned string by calling free().
148 char* osrfConfigGetValue(const osrfConfig* cfg, const char* path, ...) {
149 if(!path) return NULL;
151 cfg = osrfConfigDefault;
153 osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()");
157 VA_LIST_TO_STRING(path);
160 if(cfg->configContext) {
161 jsonObject* outer_obj =
162 jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
163 obj = jsonObjectExtractIndex( outer_obj, 0 );
164 jsonObjectFree( outer_obj );
166 obj = jsonObjectFindPath( cfg->config, VA_BUF );
168 char* val = jsonObjectToSimpleString(obj);
174 @brief Search for one or more subtrees of a configuration.
175 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
176 @param path A printf-style format string representing the search path. Subsequent
177 parameters, if any, are inserted into the format string to form the search path.
178 @return A pointer to a jsonObject representing a subset of the specified configuration,
179 if found; otherwise NULL.
181 Search for subtrees of the configuration, as specified by the search path.
183 If the configuration includes a configContext, then prepend it to the path, like so:
184 "//<configContext><path>". Hence the path should begin with a slash to separate it from
185 the context. Search for the resulting effective path at any level within the
188 If the configuration does @em not include a configContext, then start the search at the
189 root of the configuration. In this case the path should @em not begin with a slash.
191 If any entries match the effective path, return copies of them all as elements of a
192 jsonObject of type JSON_ARRAY.
194 If no entries match the effective path, return a jsonObject of type JSON_NULL.
196 The calling code is responsible for freeing the returned jsonObject by calling
199 jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, const char* path, ...) {
200 if(!path) return NULL;
202 cfg = osrfConfigDefault;
204 osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValueObject()");
208 VA_LIST_TO_STRING(path);
209 if(cfg->configContext)
210 return jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
212 return jsonObjectFindPath(cfg->config, VA_BUF);
216 @brief Search for one or more values in a configuration, specified by a path.
217 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
218 @param arr Pointer to an osrfStringArray to be populated with values.
219 @param path A printf-style format string representing the search path. Subsequent
220 parameters, if any, are inserted into the format string to form the search path.
221 @return The number of values loaded into the osrfStringArray.
223 Search the configuration for values specified by the search path. Load any values
224 found (either strings or numbers) into an existing osrfStringArray supplied by the
227 Make no effort to delete any strings that may already be in the osrfStringArray.
228 Ordinarily the calling code should ensure that the osrfStringArray is empty when passed.
230 If the configuration includes a configContext, then prepend it to the path, like so:
231 "//<configContext><path>". Hence the path should begin with a slash to separate it from
232 the context. Search for the resulting effective path at any level within the
235 If the configuration does @em not include a configContext, then start the search at the
236 root of the configuration. In this case the path should @em not begin with a slash.
238 int osrfConfigGetValueList(const osrfConfig* cfg, osrfStringArray* arr,
239 const char* path, ...) {
241 if(!arr || !path) return 0;
243 cfg = osrfConfigDefault;
245 osrfLogWarning( OSRF_LOG_MARK, "No Config object!");
249 VA_LIST_TO_STRING(path);
252 if(cfg->configContext) {
253 obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
255 obj = jsonObjectFindPath( cfg->config, VA_BUF);
260 if(obj && obj->type == JSON_ARRAY ) {
263 for( i = 0; i < obj->size; i++ ) {
265 const char* val = jsonObjectGetString( jsonObjectGetIndex(obj, i) );
268 osrfStringArrayAdd(arr, val);