Dynamic lib selection and deployment
[anna.git] / include / anna / diameter / stack / Engine.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_diameter_stack_Engine_hpp
10 #define anna_diameter_stack_Engine_hpp
11
12
13 // Local
14 #include <anna/diameter/stack/Dictionary.hpp>
15
16 #include <anna/xml/DTDMemory.hpp>
17 #include <anna/core/RuntimeException.hpp>
18 #include <anna/core/Singleton.hpp>
19
20 // STL
21 #include <string>
22 #include <vector>
23
24
25 namespace anna {
26
27 namespace diameter {
28
29 namespace stack {
30
31
32
33 //------------------------------------------------------------------------------
34 //----------------------------------------------------------------- class Engine
35 //------------------------------------------------------------------------------
36 /**
37 * Engine information
38 */
39 class Engine : public anna::Singleton <Engine> {
40
41
42   const anna::xml::DTDMemory * getDictionariesDTD() const throw() { return &a_dtd; }
43
44 public:
45
46   typedef std::map<unsigned int, Dictionary*> stack_container;
47   typedef stack_container::const_iterator const_stack_iterator;
48   typedef stack_container::iterator stack_iterator;
49
50
51   // get
52   /**
53   * Returns the dictionary registered with the provided identifier, which commonly
54   * is the 'Application-Id'.
55   *
56   * @param stackId Stack identifier.
57   * @return Dictionary reference, NULL if no stack found
58   */
59   const Dictionary * getDictionary(unsigned int stackId) const throw();
60
61   /** Beginning stack iterator */
62   const_stack_iterator stack_begin() const throw() { return a_stacks.begin(); }
63   /** Ending stack iterator */
64   const_stack_iterator stack_end() const throw() { return a_stacks.end(); }
65   /** Stack size */
66   int stack_size() const throw() { return a_stacks.size(); }
67
68   // helpers
69   /**
70   * Gets boolean about empty stack condition
71   *
72   * @return Boolean about empty stack condition
73   */
74   bool isEmpty(void) const throw() { return (!a_stacks.size()); }
75
76   /**
77   * Class string representation
78   *
79   * @param all Complete engine information versus only stacks list with its ids and dictionary names
80   *
81   * @return String with class content
82   */
83   std::string asString(bool all = true) const throw();
84
85   // set
86
87   /**
88   * Creates a diameter dictionary based on xml document file and store it over the provided stack identifier.
89   * If the stack is currently used, an exception will be launched to notify the stack collision (a dictionary
90   * could be removed with #removeStack).
91   * If missing xml path file, the dictionary will be created without loading data.
92   *
93   * <pre>
94   * Method 1 - Create and load xml data (commonly used for mono-load stacks):
95   *     engine->createDictionary(MMS_STACK_ID, "/var/tmp/mms.xml");
96   *
97   * Method 2 - Create and then, load xml data (useful for multi-load stacks):
98   *     Dictionary * d = engine->createDictionary(MMS_STACK_ID);
99   *     // Loading data:
100   *     d->load("/var/tmp/mms.xml");
101   *     ...
102   * Method 3 - Create and then, load data through Dictionary API (*):
103   *     Dictionary * d = engine->createDictionary(MMS_STACK_ID);
104   *     // Loading data:
105   *     d->addFormat(...);
106   *     d->addVendor(...);
107   *     ...
108   *
109   * (*) Applications could create a dictionary with its own API (#Dictionary) but it is much more difficult,
110   *     and usually, the method version with xml document load is used instead of this.
111   *
112   * </pre>
113   *
114   * @param stackId Stack identifier for created dictionary. We recommend to use the Diameter 'Application-Id' unless
115   * the application is going to use dictionaries covering different applications (which is not very usual).
116   * @param xmlPathFile Path file to the xml document which represents the diameter dictionary.
117   *
118   * @return Dictionary registered. When exception happen, dictionary can be accessed by #getDictionary
119   */
120   Dictionary * createDictionary(unsigned int stackId, const std::string & xmlPathFile = "") throw(anna::RuntimeException);
121
122   /**
123   * Register a externally created Dictionary or a derived class from Dictionary
124   *
125   * @param stackId Stack identifier for provided dictionary. We recommend to use the Diameter 'Application-Id' unless
126   * the application is going to use dictionaries covering different applications (which is not very usual).
127   * @param dictionary Externally created dictionary
128   *
129   * @return Dictionary registered. When exception happen, dictionary can be accessed by #getDictionary
130   */
131   Dictionary * registerDictionary(unsigned int stackId, Dictionary *dictionary) throw(anna::RuntimeException);
132
133   /**
134   * Loads an XML dictionary document over the diameter stack identifiers (one or more stack id's).
135   * Passing more than one stack id, synchronized loadings are performed, which could be useful when
136   * an application loads many dictionaries with common avps.
137   *
138   * @param stacks Stacks identifiers over which the dictionary will be load.
139   * @param xmlPathFile Path file to the xml document which represents the diameter dictionary.
140   */
141   void loadDictionary(const std::vector<unsigned int> & stacks, const std::string & xmlPathFile) throw(anna::RuntimeException);
142
143   /**
144   * Loads an XML dictionary document over all the diameter engine registered stacks. When more than one stack id is
145   * used, synchronized loadings are performed, which could be useful when an application loads many dictionaries with
146   * common avps.
147   *
148   * @param xmlPathFile Path file to the xml document which represents the diameter dictionary.
149   */
150   void loadDictionary(const std::string & xmlPathFile) throw(anna::RuntimeException);
151
152   /**
153   * Remove all stacks registered on diameter stack engine
154   */
155   void removeStacks(void) throw() { a_stacks.clear(); }
156
157   /**
158   * Remove the stack provided.
159   *
160   * @param stackId Stack identifier for created dictionary
161   */
162   void removeStack(unsigned int stackId) throw();
163
164 private:
165
166   anna::xml::DTDMemory a_dtd;
167   stack_container a_stacks;
168
169   Engine();
170
171   friend class anna::Singleton <Engine>;
172   friend class Dictionary; // access to 'getDictionariesDTD()'
173 };
174
175
176 }
177 }
178 }
179
180
181 #endif