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;
29 osrfConfig* osrfConfigGetDefaultConfig() {
30 return osrfConfigDefault;
34 @brief Free an osrfConfig.
35 @param cfg Pointer to the osrfConfig to be freed.
37 void osrfConfigFree(osrfConfig* cfg) {
39 jsonObjectFree(cfg->config);
40 free(cfg->configContext);
41 free(cfg->configFileName);
47 @brief Report whether a default configuration has been installed.
48 @return Boolean: true if a default configuration is available, or false if not.
50 int osrfConfigHasDefaultConfig( void ) {
51 return ( osrfConfigDefault != NULL );
55 @brief Free the default configuration, if it exists.
57 void osrfConfigCleanup( void ) {
58 osrfConfigFree(osrfConfigDefault);
59 osrfConfigDefault = NULL;
63 @brief Replace the jsonObject of an osrfConfig.
64 @param cfg The osrfConfig to alter.
65 @param obj The jsonObject to install in the osrfConfig.
67 This is useful if you have a json object already, rather than an XML configuration file
70 void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj) {
71 if(!cfg || !obj) return;
72 jsonObjectFree(cfg->config);
73 cfg->config = jsonObjectClone(obj);
77 @brief Load an XML configuration file into a jsonObject within an osrfConfig.
78 @param configFile Name of the XML configuration file.
79 @param configContext (Optional) Root of a subtree in the configuration file,
80 @return If successful, a pointer to the resulting osrfConfig; otherwise NULL.
82 If @a configContext is not NULL, save a copy of the string to which it points. It is a
83 tag identifying one or more subtrees within the XML; subsequent searches will examine
84 only matching subtrees. Otherwise they will search the tree from the root.
86 (In practice a configContext is always supplied, so that different programs can share
87 the same configuration file, partitioned by context tags.)
89 The calling code is responsible for freeing the returned config object by calling
92 osrfConfig* osrfConfigInit(const char* configFile, const char* configContext) {
93 if(!configFile) return NULL;
95 // Load XML from the configuration file
97 xmlDocPtr doc = xmlParseFile(configFile);
99 osrfLogWarning( OSRF_LOG_MARK, "Unable to parse XML config file %s", configFile);
103 // Translate it into a jsonObject
104 jsonObject* json_config = xmlDocToJSON(doc);
108 osrfLogWarning( OSRF_LOG_MARK, "xmlDocToJSON failed for config %s", configFile);
112 // Build an osrfConfig and return it by pointer
113 osrfConfig* cfg = safe_malloc(sizeof(osrfConfig));
116 cfg->configContext = strdup(configContext);
118 cfg->configContext = NULL;
120 cfg->configFileName = strdup(configFile);
121 cfg->config = json_config;
127 @brief Search a configuration for a specified value.
128 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
129 @param path A printf-style format string representing the search path. Subsequent
130 parameters, if any, are inserted into the format string to form the search path.
131 @return A pointer to a newly allocated string containing the value, if found; otherwise
134 Search for a value in the configuration, as specified by the search path.
136 If cfg is NULL, search the default configuration; otherwise search the configuration
139 If the configuration includes a configContext, then prepend it to the path, like so:
140 "//<configContext><path>". Hence the path should begin with a slash to separate it from
141 the context. Search for the resulting effective path at any level within the
144 If the configuration does @em not include a configContext, then start the search at the
145 root of the configuration. In this case the path should @em not begin with a slash.
147 If the configuration contains more than one entry at locations matching the effective
148 search path, return NULL.
150 Return numeric values as numeric strings.
152 The calling code is responsible for freeing the returned string by calling free().
154 char* osrfConfigGetValue(const osrfConfig* cfg, const char* path, ...) {
155 if(!path) return NULL;
157 cfg = osrfConfigDefault;
159 osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()");
163 VA_LIST_TO_STRING(path);
166 if(cfg->configContext) {
167 jsonObject* outer_obj =
168 jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
169 obj = jsonObjectExtractIndex( outer_obj, 0 );
170 jsonObjectFree( outer_obj );
172 obj = jsonObjectFindPath( cfg->config, VA_BUF );
174 char* val = jsonObjectToSimpleString(obj);
180 @brief Search for one or more subtrees of a configuration.
181 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
182 @param path A printf-style format string representing the search path. Subsequent
183 parameters, if any, are inserted into the format string to form the search path.
184 @return A pointer to a jsonObject representing a subset of the specified configuration,
185 if found; otherwise NULL.
187 Search for subtrees of the configuration, as specified by the search path.
189 If the configuration includes a configContext, then prepend it to the path, like so:
190 "//<configContext><path>". Hence the path should begin with a slash to separate it from
191 the context. Search for the resulting effective path at any level within the
194 If the configuration does @em not include a configContext, then start the search at the
195 root of the configuration. In this case the path should @em not begin with a slash.
197 If any entries match the effective path, return copies of them all as elements of a
198 jsonObject of type JSON_ARRAY.
200 If no entries match the effective path, return a jsonObject of type JSON_NULL.
202 The calling code is responsible for freeing the returned jsonObject by calling
205 jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, const char* path, ...) {
206 if(!path) return NULL;
208 cfg = osrfConfigDefault;
210 osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValueObject()");
214 VA_LIST_TO_STRING(path);
215 if(cfg->configContext)
216 return jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
218 return jsonObjectFindPath(cfg->config, VA_BUF);
222 @brief Search for one or more values in a configuration, specified by a path.
223 @param cfg (Optional) The configuration to search, or NULL for the default configuration.
224 @param arr Pointer to an osrfStringArray to be populated with values.
225 @param path A printf-style format string representing the search path. Subsequent
226 parameters, if any, are inserted into the format string to form the search path.
227 @return The number of values loaded into the osrfStringArray.
229 Search the configuration for values specified by the search path. Load any values
230 found (either strings or numbers) into an existing osrfStringArray supplied by the
233 Make no effort to delete any strings that may already be in the osrfStringArray.
234 Ordinarily the calling code should ensure that the osrfStringArray is empty when passed.
236 If the configuration includes a configContext, then prepend it to the path, like so:
237 "//<configContext><path>". Hence the path should begin with a slash to separate it from
238 the context. Search for the resulting effective path at any level within the
241 If the configuration does @em not include a configContext, then start the search at the
242 root of the configuration. In this case the path should @em not begin with a slash.
244 int osrfConfigGetValueList(const osrfConfig* cfg, osrfStringArray* arr,
245 const char* path, ...) {
247 if(!arr || !path) return 0;
249 cfg = osrfConfigDefault;
251 osrfLogWarning( OSRF_LOG_MARK, "No Config object!");
255 VA_LIST_TO_STRING(path);
258 if(cfg->configContext) {
259 obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
261 obj = jsonObjectFindPath( cfg->config, VA_BUF);
266 if(obj && obj->type == JSON_ARRAY ) {
269 for( i = 0; i < obj->size; i++ ) {
271 const char* val = jsonObjectGetString( jsonObjectGetIndex(obj, i) );
274 osrfStringArrayAdd(arr, val);