e332fec2b574de9fd0f5266319559364ba70a99d
[anna.git] / include / anna / diameter / stack / Dictionary.hpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // http://redmine.teslayout.com/projects/anna-suite
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     *  Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_diameter_stack_Dictionary_hpp
38 #define anna_diameter_stack_Dictionary_hpp
39
40
41 // Local
42 #include <anna/diameter/defines.hpp>
43 #include <anna/diameter/stack/Format.hpp>
44 #include <anna/diameter/stack/Vendor.hpp>
45 #include <anna/diameter/stack/Avp.hpp>
46 #include <anna/diameter/stack/Command.hpp>
47
48 #include <anna/core/RuntimeException.hpp>
49
50 // STL
51 #include <string>
52 #include <map>
53
54 namespace anna {
55 namespace xml {
56 class Node;
57 class DTDMemory;
58 }
59 }
60
61
62
63
64 namespace anna {
65
66 namespace diameter {
67
68 namespace stack {
69
70
71
72 //------------------------------------------------------------------------------
73 //------------------------------------------------------------- class Dictionary
74 //------------------------------------------------------------------------------
75 /**
76 * Dictionary information
77 */
78 class Dictionary {
79
80 public:
81
82   typedef std::map<std::string, Format> format_container;
83   typedef format_container::const_iterator const_format_iterator;
84
85   typedef std::map<S32, Vendor> vendor_container;
86   typedef vendor_container::const_iterator const_vendor_iterator;
87
88   struct lessAvp { // order by vendor id
89     bool operator()(AvpId id1, AvpId id2) const {
90       if(id1.second == id2.second) return (id1.first < id2.first);
91
92       return (id1.second < id2.second);
93     }
94   };
95   typedef std::map<AvpId, Avp, lessAvp> avp_container;
96   typedef avp_container::const_iterator const_avp_iterator;
97
98
99   struct lessCommand {
100     bool operator()(CommandId id1, CommandId id2) const {
101       if(id1.first == id2.first) {
102         if(id1.second != id2.second) return (id1.second);  // request -> answer
103
104         return (false);
105       }
106
107       return (id1.first < id2.first);
108     }
109   };
110   typedef std::map<CommandId, Command, lessCommand> command_container;
111   typedef command_container::const_iterator const_command_iterator;
112
113 protected:
114   std::string a_name;
115
116 private:
117
118   bool a_allowUpdates;
119   format_container a_formats;
120   vendor_container a_vendors;
121   avp_container a_avps;
122   command_container a_commands;
123
124   // Auxiliary
125   const anna::xml::DTDMemory * a_dtd;
126
127   // Name identifiers:
128   typedef std::map<std::string, const Vendor *> vendorNames_container;
129   typedef vendorNames_container::const_iterator const_vendorNames_iterator;
130
131   typedef std::map<std::string, const Avp *> avpNames_container;
132   typedef avpNames_container::const_iterator const_avpNames_iterator;
133
134   typedef std::map<std::string, const Command *> commandNames_container;
135   typedef commandNames_container::const_iterator const_commandNames_iterator;
136
137   vendorNames_container a_vendorNames;
138   avpNames_container a_avpNames;
139   commandNames_container a_commandNames;
140
141
142   // init
143   void initialize() throw();
144
145   // check & addings
146   //void checkUniqueIdentifiers(const anna::xml::Node *rootNode) const throw(anna::RuntimeException);
147   void extractFormats(const anna::xml::Node *rootNode) throw(anna::RuntimeException);
148   void extractVendors(const anna::xml::Node *rootNode) throw(anna::RuntimeException);
149   void extractAvps(const anna::xml::Node *rootNode) throw(anna::RuntimeException);
150   void extractCommands(const anna::xml::Node *rootNode) throw(anna::RuntimeException);
151
152 public:
153
154   Dictionary();
155   ~Dictionary() {};
156
157   // get
158   const std::string & getName() const throw() { return a_name; }
159   const Format * getFormat(const std::string & formatName) const throw();
160   const Vendor * getVendor(S32 vendorId) const throw();
161   const Vendor * getVendor(const std::string & vendorName) const throw();
162   const Avp * getAvp(const AvpId & avpId) const throw();
163   const Avp * getAvp(const std::string & avpName) const throw();
164   const Command * getCommand(const CommandId & commandId) const throw();
165   const Command * getCommand(const std::string & commandName) const throw();
166
167   // set
168   void allowUpdates(bool allow = true) throw() { a_allowUpdates = allow; }
169   void addFormat(const Format &, bool reserved = false) throw(anna::RuntimeException);
170   void addVendor(const Vendor &) throw(anna::RuntimeException);
171   void addAvp(const Avp &) throw(anna::RuntimeException);
172   void addCommand(const Command &) throw(anna::RuntimeException);
173
174   // containers
175   const_format_iterator format_begin() const throw() { return a_formats.begin(); }
176   const_format_iterator format_end() const throw() { return a_formats.end(); }
177   int format_size() const throw() { return a_formats.size(); }
178
179   const_vendor_iterator vendor_begin() const throw() { return a_vendors.begin(); }
180   const_vendor_iterator vendor_end() const throw() { return a_vendors.end(); }
181   int vendor_size() const throw() { return a_vendors.size(); }
182
183   const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
184   const_avp_iterator avp_end() const throw() { return a_avps.end(); }
185   int avp_size() const throw() { return a_avps.size(); }
186
187   const_command_iterator command_begin() const throw() { return a_commands.begin(); }
188   const_command_iterator command_end() const throw() { return a_commands.end(); }
189   int command_size() const throw() { return a_commands.size(); }
190
191
192   // helpers
193   /**
194   * Class string representation
195   *
196   * @return String with class content
197   */
198   std::string asString(void) const throw();
199
200   /**
201      Class XML representation.
202      \param parent XML node over which we will put instance information.
203      \return XML documentcon with class content.
204   */
205   anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
206
207   /**
208      Class XML string representation
209      \return XML string representation with class content.
210   */
211   std::string asXMLString() const throw();
212
213   // operators
214
215   /**
216   * Loads an XML dictionary document over the diameter dictionary.
217   *
218   * Successive loadings will imply data accumulation, and the behaviour for redefinitions could be configured
219   * in two ways: allow updating for dictionary items, or launch exception when any collision is found. This
220   * could be set at #allowUpdates, and default value deny such redefinitions. It could be interesting, in order
221   * to keep a more compact multi-stack configuration, allow updates sharing out the whole stack dictionaries as
222   * many parts as possible to get centralized definitions. I.e. common vendors and avps used at a unique xml file,
223   * and stack-specific commands in other set of xml files. Application only would have to load common part for all
224   * the created dictionaries with this method and specific one for each final dictionary:
225   *
226   * @param pathFile Path file to the xml document which represents the diameter dictionary.
227   *
228   * <pre>
229   * Dictionary *nokiaStack = stackEngine.createDictionary("/var/tmp/vendors_and_avps.xml", NOKIA_STACK_ID);
230   * Dictionary *huaweiStack = stackEngine.createDictionary("/var/tmp/vendors_and_avps.xml", HUAWEI_STACK_ID);
231   * nokiaStack->load("/var/tmp/nokia_commands.xml");
232   * huaweiStack->load("/var/tmp/huawei_commands.xml");
233   * </pre>
234   */
235   virtual void load(const std::string & pathFile) throw(anna::RuntimeException);
236
237   /**
238   * Clears dictionary content
239   */
240   void clear(void) throw() { initialize(); } // initialize and prepares the dictionary
241 };
242
243
244 }
245 }
246 }
247
248
249 #endif