1 //**************************************************************************************************
2 //
3 //     OSSIM Open Source Geospatial Data Processing Library
4 //     See top level LICENSE.txt file for license information
5 //
6 //**************************************************************************************************
7 
8 #pragma once
9 
10 #include <ostream>
11 #include <ossim/plugin/ossimPluginConstants.h>
12 #include <ossim/base/JsonInterface.h>
13 #include <ossim/base/ossimFilename.h>
14 #include <vector>
15 #include <map>
16 
17 namespace ossim
18 {
19 // Forward decl defined after JsonParam
20 class JsonParam;
21 
22 /**
23  * Base class for maintaining parameters affecting the runtime configuration of OSSIM executables.
24  * The state is imported and exported via JSON. There are default configuration files that should
25  * be part of the install, that are accessed by this class. Custom settings can also be loaded.
26  *
27  * There are two functionally equivalent forms for specifying parameters: long and short.
28  * Parameters are initially declared via the long form with descriptions and default values. These
29  * values must be supplied in default JSON files as part of the OSSIM install.
30  *
31  * Once the parameters are declared via the long form, the short form can be used to supply runtime
32  * overrides.
33  *
34  * The long form format is
35  *
36  *    {  "parameters": [
37  *          {
38  *             "name": "<param_name>",
39  *             "descr": "<param description",
40  *             "type": "string"|"float"|"uint"|"int"|"bool",
41  *             "value": <value>
42  *          }, ...
43  *       ]
44  *    }
45  *
46  * The short form is:
47  *
48  *    {  "parameters": [
49  *          "<param_name>": <value>, ...
50  *       ]
51  *    }
52  *
53  * The short form parameter is only accepted if it has previously been loaded via the long form so
54  * that the data type is known.
55  *
56  * Parameters are usually accessed knowing the data type ahead of time. For example, a string
57  * parameter is accessed as:
58  *
59  *    string paramVal = jsonConfig.getParameter("param_name").asSTring();
60  *
61  * If the parameter is not found, the special null-parameter is returned from getParameter(), and
62  * casting to a tye will return 0, false, or empty string.
63  */
64 class OSSIM_DLL JsonConfig : public ossim::JsonInterface
65 {
66 public:
67    /** Default Ctor loads all default .json files in the share/ossim system dir */
68    JsonConfig();
69 
70    JsonConfig(const ossimFilename& configFile);
71 
72    //! Destructor
73    virtual ~JsonConfig();
74 
75    //! Opens and parses JSON file. The "parameters" keyword is expected in the root node
76    bool open(const ossimFilename& configFile);
77 
78    //! Reads the params controlling the process from the JSON node named "parameters".
79    virtual void loadJSON(const Json::Value& params_json_node);
80 
81    //! Reads the params controlling the process from the JSON node named "parameters".
82    virtual void saveJSON(Json::Value& params_json_node) const;
83 
84    //! Returns a parameter (might be a null parameter if paramName not found in the configuration.
85    JsonParam& getParameter(const char* paramName);
86 
87    /** Adds parameter to the configuration. Any previous parameter of the same name is replaced. */
88    void setParameter(const JsonParam& p);
89 
90    //! Convenience method returns TRUE if the currently set diagnostic level is <= level
91    bool diagnosticLevel(unsigned int level) const;
92 
93    //! Outputs JSON to output stream provided.
94    friend std::ostream& operator<<(std::ostream& out, const JsonConfig& obj);
95 
96    bool paramExists(const char* paramName) const;
97 
98 protected:
JsonConfig(const JsonConfig &)99    JsonConfig(const JsonConfig& /*hide_this*/) {}
100 
101    bool getBoolValue(bool& rtn_val, const std::string& json_value) const;
102 
103    std::map<std::string, JsonParam> m_paramsMap;
104    static JsonParam s_nullParam;
105 };
106 
107 
108 /**
109  * Represents a single configuration parameter. This class provides for packing and unpacking the
110  * parameter from JSON payload, and provides for handling all datatypes of parameters.
111  */
112 class JsonParam
113 {
114 public:
115    enum ParamType {
116       UNASSIGNED=0,
117       BOOL=1,
118       INT=2,
119       UINT=3,
120       FLOAT=4,
121       STRING=5,
122       VECTOR=6
123    };
124 
JsonParam()125    JsonParam() : _type(UNASSIGNED), _value(0) {}
126 
127    JsonParam(const ossimString& argname,
128             const ossimString& arglabel,
129             const ossimString& argdescr,
130             ParamType   argparamType,
131             void* value);
132 
133    JsonParam(const JsonParam& copy);
134 
~JsonParam()135    ~JsonParam() { resetValue(); }
136 
137    /** Initializes from a JSON node. Return true if successful */
138    bool loadJSON(const Json::Value& json_node);
139 
140    void saveJSON(Json::Value& json_node) const;
141 
name()142    const ossimString& name() const { return _name; }
label()143    const ossimString& label() const { return _label; }
descr()144    const ossimString& descr() const { return _descr; }
type()145    ParamType    type() const { return _type; }
146 
isBool()147    bool isBool() const  {return (_type == BOOL); }
148    bool asBool() const;
149 
isUint()150    bool isUint() const  {return (_type == UINT); }
151    unsigned int asUint() const;
152 
isInt()153    bool isInt() const  {return (_type == INT);}
154    int  asInt() const;
155 
isFloat()156    bool isFloat() const {return (_type == FLOAT);}
157    double asFloat() const;
158 
isString()159    bool isString() const {return (_type == STRING);}
160    std::string asString() const;
161 
isVector()162    bool isVector() const {return (_type == VECTOR);}
163    void asVector(std::vector<double>& v) const;
164 
165    bool operator==(const JsonParam& p) const { return (p._name == _name); }
166 
167    /** Outputs JSON to output stream provided */
168    friend std::ostream& operator<<(std::ostream& out, const JsonParam& obj);
169 
170 private:
171    void setValue(void* value);
172    void resetValue();
173 
174    ossimString _name;
175    ossimString _label;
176    ossimString _descr;
177    ParamType   _type;
178    void*       _value;
179    std::vector<ossimString> _allowedValues; // only used for multiple-choice string parameters
180 };
181 
182 
183 }
184