EMANE  1.2.1
configurationloader.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "configurationloader.h"
35 
36 #include <libxml/parser.h>
37 
38 #include <utility>
39 
41 {
42  xmlParserCtxtPtr pContext{xmlNewParserCtxt()};
43 
44  xmlDocPtr pDoc = xmlCtxtReadFile(pContext,
45  sConfigurationFile.c_str(),
46  0,
47  XML_PARSE_NOENT |
48  XML_PARSE_DTDLOAD |
49  XML_PARSE_DTDATTR |
50  XML_PARSE_DTDVALID);
51 
52  if(!pDoc)
53  {
54  throw makeException<ConfigureException>("Failed to parse document: %s",
55  sConfigurationFile.c_str());
56  }
57 
58  if(pContext->valid == 0)
59  {
60  throw makeException<ConfigureException>("Failed to validate document: %s",
61  sConfigurationFile.c_str());
62  }
63 
64  xmlNodePtr pRoot = xmlDocGetRootElement(pDoc);
65 
66  xmlChar * pLibrary = xmlGetProp(pRoot,BAD_CAST "library");
67 
68  sPluginName_ = reinterpret_cast<char *>(pLibrary);
69 
70  xmlFree(pLibrary);
71 
72  if(!xmlStrcmp(pRoot->name,BAD_CAST "mac"))
73  {
74  type_ = PluginType::MAC;
75  }
76  else if(!xmlStrcmp(pRoot->name,BAD_CAST "phy"))
77  {
78  type_ = PluginType::PHY;
79  }
80  else if(!xmlStrcmp(pRoot->name,BAD_CAST "shim"))
81  {
82  type_ = PluginType::SHIM;
83  }
84  else if(!xmlStrcmp(pRoot->name,BAD_CAST "eventgenerator"))
85  {
86  type_ = PluginType::GENERATOR;
87  }
88  else if(!xmlStrcmp(pRoot->name,BAD_CAST "eventagent"))
89  {
90  type_ = PluginType::AGENT;
91  }
92  else if(!xmlStrcmp(pRoot->name,BAD_CAST "transport"))
93  {
94  type_ = PluginType::TRANSPORT;
95  }
96  else
97  {
98  throw makeException<ConfigureException>("Unkown plugin type: %s",
99  pRoot->name);
100  }
101 
102  for(xmlNodePtr pNode = pRoot->children; pNode; pNode = pNode->next)
103  {
104  if(pNode->type == XML_ELEMENT_NODE)
105  {
106  if(!xmlStrcmp(pNode->name,BAD_CAST "param"))
107  {
108  xmlChar * pName = xmlGetProp(pNode,BAD_CAST "name");
109  xmlChar * pValue = xmlGetProp(pNode,BAD_CAST "value");
110 
111  std::string sName{std::string{reinterpret_cast<const char *>(pName)}};
112  std::string sValue{std::string{reinterpret_cast<const char *>(pValue)}};
113 
114  xmlFree(pName);
115  xmlFree(pValue);
116 
117  // test for duplicate configuration items
118  if(isUniqueConfigurationName(sName))
119  {
120  request_.push_back(std::make_pair(sName,
121  std::vector<std::string>{sValue}));
122  }
123  else
124  {
125  throw makeException<ConfigureException>("Duplicate parameter name: %s",
126  sName.c_str());
127  }
128  }
129  else if(!xmlStrcmp(pNode->name,BAD_CAST "paramlist"))
130  {
131  xmlChar * pName = xmlGetProp(pNode,BAD_CAST "name");
132 
133  std::string sName{std::string{reinterpret_cast<const char *>(pName)}};
134 
135  xmlFree(pName);
136 
137  // test for duplicate configuration items
138  if(isUniqueConfigurationName(sName))
139  {
140  std::vector<std::string> values;
141 
142  for(xmlNodePtr pItem = pNode->children; pItem; pItem = pItem->next)
143  {
144  if(pItem->type == XML_ELEMENT_NODE)
145  {
146  if(!xmlStrcmp(pItem->name,BAD_CAST "item"))
147  {
148  xmlChar * pValue = xmlGetProp(pItem,BAD_CAST "value");
149  values.push_back(reinterpret_cast<char *>(pValue));
150  xmlFree(pValue);
151  }
152  }
153  }
154 
155  request_.push_back(std::make_pair(sName,values));
156  }
157  else
158  {
159  throw makeException<ConfigureException>("Duplicate parameter name: %s",
160  sName.c_str());
161  }
162  }
163  }
164  }
165 }
166 
169 {
170  return request_;
171 }
172 
173 const std::string
175 {
176  return sPluginName_;
177 }
178 
179 bool
180 EMANE::Application::ConfigurationLoader::isUniqueConfigurationName(std::string & sName)
181 {
182  return std::find_if(request_.begin(),
183  request_.end(),
184  std::bind(std::equal_to<std::string>(),
185  std::bind(&ConfigurationUpdateRequest::value_type::first,
186  std::placeholders::_1),
187  sName)) == request_.end();
188 }
189 
190 
192 {
193  return type_;
194 }
const EMANE::ConfigurationUpdateRequest & getConfigurationUpdateRequest() const
std::vector< ConfigurationNameStringValues > ConfigurationUpdateRequest
ConfigurationLoader(std::string &sConfigurationFile)