bes Updated for version 3.20.10
BESModuleApp.cc
1// BESModuleApp.C
2
3// This file is part of bes, A C++ back-end server implementation framework
4// for the OPeNDAP Data Access Protocol.
5
6// Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8//
9// This library is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact University Corporation for Atmospheric Research at
24// 3080 Center Green Drive, Boulder, CO 80301
25
26// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27// Please read the full copyright statement in the file COPYRIGHT_UCAR.
28//
29// Authors:
30// pwest Patrick West <pwest@ucar.edu>
31// jgarcia Jose Garcia <jgarcia@ucar.edu>
32
33#include <iostream>
34
35#include "BESModuleApp.h"
36#include "BESError.h"
37#include "BESPluginFactory.h"
38#include "BESAbstractModule.h"
39#include "TheBESKeys.h"
40#include "BESUtil.h"
41
42using namespace std;
43
50 BESApp()
51{
52}
53
60{
61}
62
69int BESModuleApp::initialize(int argC, char **argV)
70{
71 int retVal = BESApp::initialize(argC, argV);
72 if (!retVal) {
73 try {
74 retVal = loadModules();
75 }
76 catch( BESError &e ) {
77 string newerr = "Error during module initialization: ";
78 newerr += e.get_message();
79 cerr << newerr << endl;
80 retVal = 1;
81 }
82 catch( ... ) {
83 string newerr = "Error during module initialization: ";
84 newerr += "caught unknown exception";
85 cerr << newerr << endl;
86 retVal = 1;
87 }
88 }
89
90 return retVal;
91}
92
95int BESModuleApp::loadModules()
96{
97 int retVal = 0;
98
99 bool found = false;
100 vector<string> vals;
101 TheBESKeys::TheKeys()->get_values("BES.modules", vals, found);
102 vector<string>::iterator l = vals.begin();
103 vector<string>::iterator le = vals.end();
104
105 // The following code was likely added before we had the 'Include'
106 // directive. Now all modules have a line in their .conf file to
107 // Include dap.conf and that makes this redundant. However, what
108 // was happening was a module named XdapX would match the find()
109 // call below and would wind up being loaded _before_ the dap module.
110 // That led to all sorts of runtime problems. See ticket 2258. Since
111 // we don't need this and it can cause problems, I'm removing it.
112 // jhrg 10/13/14
113#if 0
114 // This is a kludge. But we want to be sure that the dap
115 // modules get loaded first.
116 vector<string> ordered_list;
117 for (; l != le; l++) {
118 string mods = (*l);
119 if (mods != "") {
120 if (mods.find("dap", 0) != string::npos) {
121 ordered_list.insert(ordered_list.begin(), mods);
122 }
123 else {
124 ordered_list.push_back(mods);
125 }
126 }
127 }
128
129 l = ordered_list.begin();
130 le = ordered_list.end();
131#endif
132 for (; l != le; l++) {
133 string mods = (*l);
134 list<string> mod_list;
135 BESUtil::explode(',', mods, mod_list);
136
137 list<string>::iterator i = mod_list.begin();
138 list<string>::iterator e = mod_list.end();
139 for (; i != e; i++) {
140 if (!(*i).empty()) {
141 string key = "BES.module." + (*i);
142 string so;
143 try {
144 TheBESKeys::TheKeys()->get_value(key, so, found);
145 }
146 catch( BESError &e ) {
147 cerr << e.get_message() << endl;
148 return 1;
149 }
150 if (so == "") {
151 cerr << "Couldn't find the module for " << (*i) << endl;
152 return 1;
153 }
154 bes_module new_mod;
155 new_mod._module_name = (*i);
156 new_mod._module_library = so;
157 _module_list.push_back(new_mod);
158 }
159 }
160 }
161
162 list<bes_module>::iterator mi = _module_list.begin();
163 list<bes_module>::iterator me = _module_list.end();
164 for (; mi != me; mi++) {
165 bes_module curr_mod = *mi;
166 _moduleFactory.add_mapping(curr_mod._module_name, curr_mod._module_library);
167 }
168
169 for (mi = _module_list.begin(); mi != me; mi++) {
170 bes_module curr_mod = *mi;
171 try {
172 string modname = curr_mod._module_name;
173 BESAbstractModule *o = _moduleFactory.get(modname);
174 o->initialize(modname);
175 delete o;
176 }
177 catch( BESError &e ) {
178 cerr << "Caught plugin exception during initialization of " << curr_mod._module_name << " module:" << endl
179 << " " << e.get_message() << endl;
180 retVal = 1;
181 break;
182 }
183 catch( ... ) {
184 cerr << "Caught unknown exception during initialization of " << curr_mod._module_name << " module" << endl;
185 retVal = 1;
186 break;
187 }
188 }
189
190 return retVal;
191}
192
202{
203 list<bes_module>::iterator i = _module_list.begin();
204 list<bes_module>::iterator e = _module_list.end();
205 bool done = false;
206 try {
207 // go in the reverse order that the modules were loaded
208 // TODO replace this with a reverse iterator. jhrg 12/21/12
209 while (!done) {
210 if (e == i)
211 done = true;
212 else {
213 e--;
214 bes_module curr_mod = *e;
215 string modname = curr_mod._module_name;
216 BESAbstractModule *o = _moduleFactory.get(modname);
217 if (o) {
218 o->terminate(modname);
219 delete o;
220 }
221 }
222 }
223 }
224 catch( BESError &e ) {
225 cerr << "Caught exception during module termination: " << e.get_message() << endl;
226 }
227 catch( ... ) {
228 cerr << "Caught unknown exception during terminate" << endl;
229 }
230
231 return BESApp::terminate(sig);
232}
233
242void BESModuleApp::dump(ostream &strm) const
243{
244 strm << BESIndent::LMarg << "BESModuleApp::dump - (" << (void *) this << ")" << endl;
245 BESIndent::Indent();
246 if (_module_list.size()) {
247 strm << BESIndent::LMarg << "loaded modules:" << endl;
248 BESIndent::Indent();
249 list<bes_module>::const_iterator i = _module_list.begin();
250 list<bes_module>::const_iterator e = _module_list.end();
251 for (; i != e; i++) {
252 bes_module curr_mod = *i;
253 strm << BESIndent::LMarg << curr_mod._module_name << ": " << curr_mod._module_library << endl;
254 }
255 BESIndent::UnIndent();
256 }
257 else {
258 strm << BESIndent::LMarg << "loaded modules: none" << endl;
259 }
260 BESIndent::UnIndent();
261}
262
Application class for BES applications.
Definition: BESApp.h:56
virtual int initialize(int argC, char **argV)
Initialize the application using the passed argc and argv values.
Definition: BESApp.cc:72
virtual int terminate(int sig=0)
Clean up after the application.
Definition: BESApp.cc:102
Abstract exception class for the BES with basic string message.
Definition: BESError.h:58
virtual std::string get_message()
get the error message for this exception
Definition: BESError.h:99
virtual ~BESModuleApp(void)
Default destructor.
Definition: BESModuleApp.cc:59
BESModuleApp(void)
Default constructor.
Definition: BESModuleApp.cc:49
virtual void dump(std::ostream &strm) const
dumps information about this object
virtual int terminate(int sig=0)
clean up after the application
virtual int initialize(int argC, char **argV)
Load and initialize any BES modules.
Definition: BESModuleApp.cc:69
void add_mapping(const std::string &name, const std::string &library_name)
C * get(const std::string &name)
static void explode(char delim, const std::string &str, std::list< std::string > &values)
Definition: BESUtil.cc:580
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:340
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:71
void get_values(const std::string &s, std::vector< std::string > &vals, bool &found)
Retrieve the values of a given key, if set.
Definition: TheBESKeys.cc:371