CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

context.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Ilya A. Volynets-Evenbakh                       *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include <serverconfig/serverconfig.h>
00022 #include <iostream>
00023 #include <algorithm>
00024 
00025 namespace container {
00026 namespace serverconfig {
00027 
00028 Context::~Context()
00029 {
00030     for(ctxlist_t::iterator it=m_kids.begin(); it!=m_kids.end(); it++) {
00031         delete *it;
00032     }
00033 }
00034 
00040 bool Context::process(ServerConfig& cfg, ConfigNode* node)
00041 {
00042     m_name=node->getName();
00043     m_type=node->getType();
00044     ConfigNode::childlist_t kids = cfg.getNodes(node);
00045     for(ConfigNode::childlist_t::iterator it=kids.begin();
00046         it!=kids.end(); it++)
00047     {
00048         Context* ctx=getContext(**it);
00049         if(ctx) {
00050             addChildContext(ctx);
00051             if(!ctx->process(cfg, *it)) {
00052                 std::cerr<< "Error loading context "<<ctx->getName()<<std::endl;
00053                 return false;
00054             }
00055         } else {
00056             if(!setParam(**it)) {
00057                 std::cerr<<"Failed setting parameter "<<(*it)->getType()
00058                     <<" In context "<<getName()<<" of type "<<getType()<<std::endl;
00059                 return false;
00060             }
00061         }
00062     }
00063     return true;
00064 }
00065 
00066 
00070 void Context::addChildContext(Context* ctx)
00071 {
00072     m_kids.push_back(ctx);
00073 }
00074 
00075 class NodeNameComparator
00076 {
00077     std::string m_search;
00078 public:
00079     NodeNameComparator(const std::string& s) :m_search(s){}
00080     bool operator()(const ConfigNode& node)
00081     { return node.getName()==m_search;}
00082 };
00083 
00084 bool Context::CfgParamList::add(const ConfigNode& node)
00085 {
00086     if(m_flags&PARAM_SINGLE_OF_TYPE && ! empty()) {
00087         std::cerr<<"Error: parameter of type "<<node.getType()<<" was already set";
00088         return false;
00089     }
00090     if(m_flags&PARAM_SINGLE_OF_NAME &&
00091         std::find_if(begin(),end(),NodeNameComparator(node.getName()))!=end())
00092     {
00093         std::cerr<<"Error: parameter with name"<<node.getName()<<" was already set";
00094         return false;
00095     }
00096     push_back(node);
00097     return true;
00098 }
00099 
00105 bool Context::setParam(const ConfigNode& node)
00106 {
00107     cfgparamlist_t &params=this->m_params[node.getType()];
00108     unsetparams_t& unsetParams=getUnsetParams();
00109     unsetparams_t::iterator it=unsetParams.find(node.getType());
00110     if(it!=unsetParams.end()) {
00111         params.m_flags=it->second.flags();
00112         unsetParams.erase(it);
00113     }
00114     if(params.add(node))
00115         return onSetParam(node);
00116     std::cerr<<"Error setting paramter "<<node.getType()<<" ("<<node.getName()<<')'<<std::endl;
00117     return false;
00118 }
00119 
00123 const Context::cfgparamlist_t* Context::getParam(const std::string& type) const
00124 {
00125     params_t::const_iterator it=m_params.find(type);
00126     if(it==m_params.end())
00127         return 0;
00128     return &it->second;
00129 }
00130 
00131 
00135 bool Context::complete()
00136 {
00137     unsetparams_t& unsetParams=getUnsetParams();
00138     for(unsetparams_t::iterator it=unsetParams.begin();it!=unsetParams.end();) {
00139         const cfgparamlist_t* params;
00140         if(m_parent && it->second.inheritable()) {
00141             if((params=m_parent->getParam(it->first))) {
00142                 //Have to increment _before_ calling setParam,
00143                 //since setParam may erase current element, thus
00144                 //invalidating current iterator.
00145                 //At the same time I have to increment it _after_
00146                 //I used it to get any data I need
00147                 it++;
00148                 for(cfgparamlist_t::const_iterator it=params->begin();
00149                     it!=params->end(); it++)
00150                 {
00151                     setParam(*it);
00152                 }
00153                 continue;
00154             }
00155         }
00156         if(it->second.required()) {
00157             std::cerr<<"Parameter "<<it->first<<" must be set in context "<<getType()<<" ("<<getName()<<')'<<std::endl;
00158             return false;
00159         }
00160         it++; // see comments above...
00161     }
00162     if(!onPreComplete()) {
00163         std::cerr<<"Error in context setup "<<getType()<<" ("<<getName()<<')'<<std::endl;
00164         return false;
00165     }
00166     for(ctxlist_t::iterator it=m_kids.begin(); it!=m_kids.end(); it++){
00167         if(!(*it)->complete()) {
00168             std::cerr<<"Error in context setup completion "<<(*it)->getType()
00169                 <<" ("<<(*it)->getName()<<')'<<std::endl;
00170             return false;
00171         }
00172     }
00173     return onPostComplete();
00174 }
00175 
00176 bool Context::setString(const ConfigNode& node, std::string& dest)
00177 {
00178     util::param_t::const_iterator value=node.getAttrs().find("value");
00179     if(value==node.getAttrs().end()) {
00180         std::cerr<<"No value specified"<<std::endl;
00181         return false;
00182     }
00183     dest=value->second;
00184     return true;
00185 }
00186 
00187 }
00188 }

SourceForge.net Logo