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

Generated on Wed Jun 27 12:56:38 2007 for libdap++ by  doxygen 1.4.7