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 
00043 ostream &
00044 operator<<(ostream &os, const Resource &r)
00045 {
00046     os << "<ancillary";
00047     if (r.d_rule != Resource::overwrite) {
00048         os << " rule=\"";
00049         (r.d_rule == Resource::fallback) ? os << "fallback\"" : os << "replace\"";
00050     }
00051     os << " url=\"" << r.d_url << "\"/>";
00052 
00053     return os;
00054 }
00055 
00059 ostream &
00060 operator<<(ostream &os, const AISResources &ais_res)
00061 {
00062     os << "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>"
00063     << endl;
00064     os << "<!DOCTYPE ais SYSTEM \"http://xml.opendap.org/ais/ais_database.dtd\">" << endl;
00065     os << "<ais xmlns=\"http://xml.opendap.org/ais\">" << endl;
00066 
00067     for (AISResources::ResourceRegexpsCIter pos = ais_res.d_re.begin();
00068          pos != ais_res.d_re.end(); ++pos) {
00069         os << "<entry>" << endl;
00070         // write primary
00071         os << "<primary regexp=\"" << pos->first << "\"/>" << endl;
00072         // write the vector of Resource objects
00073         for (ResourceVectorCIter i = pos->second.begin();
00074              i != pos->second.end(); ++i) {
00075             os << *i << endl;
00076         }
00077         os << "</entry>" << endl;
00078     }
00079 
00080     //  Under VC++ 6.x, 'pos' is twice tagged as twice in the
00081     //  same scope (this method - not just within for blocks), so
00082     //  I gave it another name.  ROM - 6/14/03
00083     for (AISResources::ResourceMapCIter pos2 = ais_res.d_db.begin();
00084          pos2 != ais_res.d_db.end(); ++pos2) {
00085         os << "<entry>" << endl;
00086         // write primary
00087         os << "<primary url=\"" << pos2->first << "\"/>" << endl;
00088         // write the vector of Resource objects
00089         for (ResourceVectorCIter i = pos2->second.begin();
00090              i != pos2->second.end(); ++i) {
00091             os << *i << endl;
00092         }
00093         os << "</entry>" << endl;
00094     }
00095 
00096     os << "</ais>" << endl;
00097 
00098     return os;
00099 }
00100 
00103 AISResources::AISResources(const string &database) throw(AISDatabaseReadFailed)
00104 {
00105     read_database(database);
00106 }
00107 
00114 void
00115 AISResources::add_url_resource(const string &url, const Resource &ancillary)
00116 {
00117     add_url_resource(url, ResourceVector(1, ancillary));
00118 }
00119 
00125 void
00126 AISResources::add_url_resource(const string &url, const ResourceVector &rv)
00127 {
00128     ResourceMapIter pos = d_db.find(url);
00129     if (pos == d_db.end()) {
00130         d_db.insert(std::make_pair(url, rv));
00131     }
00132     else {
00133         // There's already a ResourceVector, append to it.
00134         for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
00135             pos->second.push_back(*i);
00136     }
00137 }
00138 
00143 void
00144 AISResources::add_regexp_resource(const string &re, const Resource &ancillary)
00145 {
00146     add_regexp_resource(re, ResourceVector(1, ancillary));
00147 }
00148 
00155 void
00156 AISResources::add_regexp_resource(const string &re, const ResourceVector &rv)
00157 {
00158     ResourceRegexpsIter pos = find_if(d_re.begin(), d_re.end(),
00159                                       FindRegexp(re));
00160     if (pos == d_re.end()) {
00161         d_re.push_back(std::make_pair(re, rv));
00162     }
00163     else {
00164         // There's already a ResourceVector, append to it.
00165         for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
00166             pos->second.push_back(*i);
00167     }
00168 }
00169 
00178 bool
00179 AISResources::has_resource(const string &primary) const
00180 {
00181     // This code looks for the 'primary' in the AIS database (which is a STL
00182     // map<> of strings and AIS stuff. As an optimization, it first uses the
00183     // map<> class' find() method to see if the 'primary' is in there as a
00184     // literal. If not, then it tries to match each regular expression in the
00185     // database.
00186     return ((d_db.find(primary) != d_db.end())
00187             || (find_if(d_re.begin(), d_re.end(), MatchRegexp(primary))
00188                 != d_re.end()));
00189 
00190 }
00191 
00210 ResourceVector
00211 AISResources::get_resource(const string &primary)
00212 {
00213     ResourceVector rv;
00214     const ResourceMapIter &i = d_db.find(primary);
00215 
00216     if (i != d_db.end())
00217         rv = i->second;
00218 
00219     // Finds the first matching regular expression and returns a vector of
00220     // AIS resources.
00221     const ResourceRegexpsIter &j = find_if(d_re.begin(), d_re.end(),
00222                                            MatchRegexp(primary));
00223     if (j != d_re.end())
00224         copy(j->second.begin(), j->second.end(), inserter(rv, rv.begin()));
00225 
00226     if (rv.size() == 0)
00227         throw NoSuchPrimaryResource();
00228 
00229     return rv;
00230 }
00231 
00239 void
00240 AISResources::read_database(const string &database)
00241 {
00242     AISDatabaseParser parser;
00243 
00244     parser.intern(database, this);
00245 }
00246 
00255 void
00256 AISResources::write_database(const string &filename)
00257 {
00258     ofstream fos;
00259     fos.open(filename.c_str());
00260 
00261     if (!fos)
00262         throw AISDatabaseWriteFailed("Could not open file :" + filename);
00263 
00264     fos << *this << endl;
00265 
00266     if (!fos)
00267         throw AISDatabaseWriteFailed();
00268 }
00269 
00270 } // namespace libdap

Generated on Tue Jun 10 18:00:29 2008 for libdap++ by  doxygen 1.5.4