AISResources.cc

Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 #include "config.h"
00027 
00028 #include <iostream>
00029 #include <fstream>
00030 #include <algorithm>
00031 #include <functional>
00032 
00033 #include "AISResources.h"
00034 #include "AISDatabaseParser.h"
00035 
00036 using namespace std;
00037 
00038 namespace libdap {
00039 
00045 ostream &
00046 operator<<(ostream &os, const Resource &r)
00047 {
00048     os << "<ancillary";
00049     if (r.d_rule != Resource::overwrite) {
00050         os << " rule=\"";
00051         (r.d_rule == Resource::fallback) ? os << "fallback\"" : os << "replace\"";
00052     }
00053     os << " url=\"" << r.d_url << "\"/>";
00054 
00055     return os;
00056 }
00057 
00061 ostream &
00062 operator<<(ostream &os, const AISResources &ais_res)
00063 {
00064     os << "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>"
00065     << endl;
00066     os << "<!DOCTYPE ais SYSTEM \"http://xml.opendap.org/ais/ais_database.dtd\">" << endl;
00067     os << "<ais xmlns=\"http://xml.opendap.org/ais\">" << endl;
00068 
00069     for (AISResources::ResourceRegexpsCIter pos = ais_res.d_re.begin();
00070          pos != ais_res.d_re.end(); ++pos) {
00071         os << "<entry>" << endl;
00072         // write primary
00073         os << "<primary regexp=\"" << pos->first << "\"/>" << endl;
00074         // write the vector of Resource objects
00075         for (ResourceVectorCIter i = pos->second.begin();
00076              i != pos->second.end(); ++i) {
00077             os << *i << endl;
00078         }
00079         os << "</entry>" << endl;
00080     }
00081 
00082     //  Under VC++ 6.x, 'pos' is twice tagged as twice in the
00083     //  same scope (this method - not just within for blocks), so
00084     //  I gave it another name.  ROM - 6/14/03
00085     for (AISResources::ResourceMapCIter pos2 = ais_res.d_db.begin();
00086          pos2 != ais_res.d_db.end(); ++pos2) {
00087         os << "<entry>" << endl;
00088         // write primary
00089         os << "<primary url=\"" << pos2->first << "\"/>" << endl;
00090         // write the vector of Resource objects
00091         for (ResourceVectorCIter i = pos2->second.begin();
00092              i != pos2->second.end(); ++i) {
00093             os << *i << endl;
00094         }
00095         os << "</entry>" << endl;
00096     }
00097 
00098     os << "</ais>" << endl;
00099 
00100     return os;
00101 }
00102 
00105 AISResources::AISResources(const string &database) throw(AISDatabaseReadFailed)
00106 {
00107     read_database(database);
00108 }
00109 
00116 void
00117 AISResources::add_url_resource(const string &url, const Resource &ancillary)
00118 {
00119     add_url_resource(url, ResourceVector(1, ancillary));
00120 }
00121 
00127 void
00128 AISResources::add_url_resource(const string &url, const ResourceVector &rv)
00129 {
00130     ResourceMapIter pos = d_db.find(url);
00131     if (pos == d_db.end()) {
00132         d_db.insert(std::make_pair(url, rv));
00133     }
00134     else {
00135         // There's already a ResourceVector, append to it.
00136         for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
00137             pos->second.push_back(*i);
00138     }
00139 }
00140 
00145 void
00146 AISResources::add_regexp_resource(const string &re, const Resource &ancillary)
00147 {
00148     add_regexp_resource(re, ResourceVector(1, ancillary));
00149 }
00150 
00157 void
00158 AISResources::add_regexp_resource(const string &re, const ResourceVector &rv)
00159 {
00160     ResourceRegexpsIter pos = find_if(d_re.begin(), d_re.end(),
00161                                       FindRegexp(re));
00162     if (pos == d_re.end()) {
00163         d_re.push_back(std::make_pair(re, rv));
00164     }
00165     else {
00166         // There's already a ResourceVector, append to it.
00167         for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
00168             pos->second.push_back(*i);
00169     }
00170 }
00171 
00180 bool
00181 AISResources::has_resource(const string &primary) const
00182 {
00183     // This code looks for the 'primary' in the AIS database (which is a STL
00184     // map<> of strings and AIS stuff. As an optimization, it first uses the
00185     // map<> class' find() method to see if the 'primary' is in there as a
00186     // literal. If not, then it tries to match each regular expression in the
00187     // database.
00188     return ((d_db.find(primary) != d_db.end())
00189             || (find_if(d_re.begin(), d_re.end(), MatchRegexp(primary))
00190                 != d_re.end()));
00191 
00192 }
00193 
00212 ResourceVector
00213 AISResources::get_resource(const string &primary)
00214 {
00215     ResourceVector rv;
00216     const ResourceMapIter &i = d_db.find(primary);
00217 
00218     if (i != d_db.end())
00219         rv = i->second;
00220 
00221     // Finds the first matching regular expression and returns a vector of
00222     // AIS resources.
00223     const ResourceRegexpsIter &j = find_if(d_re.begin(), d_re.end(),
00224                                            MatchRegexp(primary));
00225     if (j != d_re.end())
00226         copy(j->second.begin(), j->second.end(), inserter(rv, rv.begin()));
00227 
00228     if (rv.size() == 0)
00229         throw NoSuchPrimaryResource();
00230 
00231     return rv;
00232 }
00233 
00241 void
00242 AISResources::read_database(const string &database)
00243 {
00244     AISDatabaseParser parser;
00245 
00246     parser.intern(database, this);
00247 }
00248 
00257 void
00258 AISResources::write_database(const string &filename)
00259 {
00260     ofstream fos;
00261     fos.open(filename.c_str());
00262 
00263     if (!fos)
00264         throw AISDatabaseWriteFailed("Could not open file :" + filename);
00265 
00266     fos << *this << endl;
00267 
00268     if (!fos)
00269         throw AISDatabaseWriteFailed();
00270 }
00271 
00272 } // namespace libdap

Generated on Mon May 18 10:25:02 2009 for libdap++ by  doxygen 1.4.7