Branch data Line data Source code
1 : : // Copyright (C) 2010, 2011 Internet Systems Consortium.
2 : : //
3 : : // Permission to use, copy, modify, and distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
8 : : // DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
9 : : // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
10 : : // INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
11 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
12 : : // FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
13 : : // NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
14 : : // WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : :
16 : : #ifndef _MODULE_SPEC_H
17 : : #define _MODULE_SPEC_H 1
18 : :
19 : : #include <cc/data.h>
20 : :
21 : : #include <sstream>
22 : :
23 : : namespace isc { namespace config {
24 : :
25 : : ///
26 : : /// A standard ModuleSpec exception that is thrown when a
27 : : /// specification is not in the correct form.
28 : : ///
29 : 71 : class ModuleSpecError : public isc::Exception {
30 : : public:
31 : 71 : ModuleSpecError(const char* file, size_t line,
32 : : const char* what = "Module specification is invalid") :
33 : 71 : isc::Exception(file, line, what) {}
34 : : };
35 : :
36 : : ///
37 : : /// The \c ModuleSpec class holds a data specification.
38 : : /// Each module should have a .spec file containing the specification
39 : : /// for configuration and commands for that module.
40 : : /// This class holds that specification, and provides a function to
41 : : /// validate a set of data, to see whether it conforms to the given
42 : : /// specification
43 : : ///
44 : : /// The form of the specification is described in doc/ (TODO)
45 : : ///
46 [ + - ][ + - ]: 569 : class ModuleSpec {
[ + - ][ + - ]
47 : : public:
48 : 116 : ModuleSpec() {};
49 : : /// Create a \c ModuleSpec instance with the given data as
50 : : /// the specification
51 : : /// \param e The Element containing the data specification
52 : : /// \param check If false, the module specification in the file
53 : : /// is not checked to be of the correct form.
54 : : explicit ModuleSpec(isc::data::ConstElementPtr e,
55 : : const bool check = true)
56 : : throw(ModuleSpecError);
57 : :
58 : : /// Returns the commands part of the specification as an
59 : : /// ElementPtr, returns an empty ElementPtr if there is none
60 : : /// \return ElementPtr Shared pointer to the commands
61 : : /// part of the specification
62 : : isc::data::ConstElementPtr getCommandsSpec() const;
63 : :
64 : : /// Returns the configuration part of the specification as an
65 : : /// ElementPtr
66 : : /// \return ElementPtr Shared pointer to the configuration
67 : : /// part of the specification
68 : : isc::data::ConstElementPtr getConfigSpec() const;
69 : :
70 : : /// Returns the statistics part of the specification as an
71 : : /// ElementPtr
72 : : /// \return ElementPtr Shared pointer to the statistics
73 : : /// part of the specification
74 : : isc::data::ConstElementPtr getStatisticsSpec() const;
75 : :
76 : : /// Returns the full module specification as an ElementPtr
77 : : /// \return ElementPtr Shared pointer to the specification
78 : : isc::data::ConstElementPtr getFullSpec() const {
79 : 67 : return module_specification;
80 : : }
81 : :
82 : : /// Returns the module name as specified by the specification
83 : : const std::string getModuleName() const;
84 : :
85 : : /// Returns the module description as specified by the specification
86 : : /// returns an empty string if there is no description
87 : : const std::string getModuleDescription() const;
88 : :
89 : : // returns true if the given element conforms to this data
90 : : // configuration specification
91 : : /// Validates the given configuration data for this specification.
92 : : /// \param data The base \c Element of the data to check
93 : : /// \param full If true, all non-optional configuration parameters
94 : : /// must be specified.
95 : : /// \return true if the data conforms to the specification,
96 : : /// false otherwise.
97 : : bool validateConfig(isc::data::ConstElementPtr data,
98 : : const bool full = false) const;
99 : :
100 : : // returns true if the given element conforms to this data
101 : : // statistics specification
102 : : /// Validates the given statistics data for this specification.
103 : : /// \param data The base \c Element of the data to check
104 : : /// \param full If true, all non-optional statistics parameters
105 : : /// must be specified.
106 : : /// \return true if the data conforms to the specification,
107 : : /// false otherwise.
108 : : bool validateStatistics(isc::data::ConstElementPtr data,
109 : : const bool full = false) const;
110 : :
111 : : /// Validates the arguments for the given command
112 : : ///
113 : : /// This checks the command and argument against the
114 : : /// specification in the module's .spec file.
115 : : ///
116 : : /// A command is considered valid if:
117 : : /// - it is known (the 'command' string must have an entry in
118 : : /// the specification)
119 : : /// - the args is a MapElement
120 : : /// - args contains all mandatory arguments
121 : : /// - args does not contain unknown arguments
122 : : /// - all arguments in args match their specification
123 : : /// If all of these are true, this function returns \c true
124 : : /// If not, this method returns \c false
125 : : ///
126 : : /// Example usage:
127 : : /// \code
128 : : /// ElementPtr errors = Element::createList();
129 : : /// if (module_specification_.validateCommand(cmd_str,
130 : : /// arg,
131 : : /// errors)) {
132 : : /// std::cout << "Command is valid" << std::endl;
133 : : /// } else {
134 : : /// std::cout << "Command is invalid: " << std::endl;
135 : : /// BOOST_FOREACH(ConstElementPtr error,
136 : : /// errors->listValue()) {
137 : : /// std::cout << error->stringValue() << std::endl;
138 : : /// }
139 : : /// }
140 : : /// \endcode
141 : : ///
142 : : /// \param command The command to validate the arguments for
143 : : /// \param args A dict containing the command parameters
144 : : /// \param errors An ElementPtr pointing to a ListElement. Any
145 : : /// errors that are found are added as
146 : : /// StringElements to this list
147 : : /// \return true if the command is known and the parameters are correct
148 : : /// false otherwise
149 : : bool validateCommand(const std::string& command,
150 : : isc::data::ConstElementPtr args,
151 : : isc::data::ElementPtr errors) const;
152 : :
153 : :
154 : : /// errors must be of type ListElement
155 : : bool validateConfig(isc::data::ConstElementPtr data, const bool full,
156 : : isc::data::ElementPtr errors) const;
157 : :
158 : : /// errors must be of type ListElement
159 : : bool validateStatistics(isc::data::ConstElementPtr data, const bool full,
160 : : isc::data::ElementPtr errors) const;
161 : :
162 : : private:
163 : : bool validateItem(isc::data::ConstElementPtr spec,
164 : : isc::data::ConstElementPtr data,
165 : : const bool full,
166 : : isc::data::ElementPtr errors) const;
167 : : bool validateSpec(isc::data::ConstElementPtr spec,
168 : : isc::data::ConstElementPtr data,
169 : : const bool full,
170 : : isc::data::ElementPtr errors) const;
171 : : bool validateSpecList(isc::data::ConstElementPtr spec,
172 : : isc::data::ConstElementPtr data,
173 : : const bool full,
174 : : isc::data::ElementPtr errors) const;
175 : :
176 : : isc::data::ConstElementPtr module_specification;
177 : : };
178 : :
179 : : /// Creates a \c ModuleSpec instance from the contents
180 : : /// of the file given by file_name.
181 : : /// If check is true, and the module specification is not of
182 : : /// the correct form, a ModuleSpecError is thrown. If the file
183 : : /// could not be parse, a ParseError is thrown.
184 : : /// \param file_name The file to be opened and parsed
185 : : /// \param check If true, the module specification in the file
186 : : /// is checked to be of the correct form
187 : : ModuleSpec
188 : : moduleSpecFromFile(const std::string& file_name, const bool check = true)
189 : : throw(isc::data::JSONError, ModuleSpecError);
190 : :
191 : : /// Creates a \c ModuleSpec instance from the given input
192 : : /// stream that contains the contents of a .spec file.
193 : : /// If check is true, and the module specification is not of
194 : : /// the correct form, a ModuleSpecError is thrown. If the
195 : : /// file could not be parsed, a ParseError is thrown.
196 : : /// \param in The std::istream containing the .spec file data
197 : : /// \param check If true, the module specification is checked
198 : : /// to be of the correct form
199 : : ModuleSpec
200 : : moduleSpecFromFile(std::ifstream& in, const bool check = true)
201 : : throw(isc::data::JSONError, ModuleSpecError);
202 : : } }
203 : :
204 : : #endif // _DATA_DEF_H
205 : :
206 : : // Local Variables:
207 : : // mode: c++
208 : : // End:
|