libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
AISResources.cc
Go to the documentation of this file.
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of libdap, A C++ implementation of the OPeNDAP Data
5// Access Protocol.
6
7// Copyright (c) 2003 OPeNDAP, Inc.
8// Author: James Gallagher <jgallagher@opendap.org>
9//
10// This library is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Lesser General Public
12// License as published by the Free Software Foundation; either
13// version 2.1 of the License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23//
24// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
26#include "config.h"
27
28#include <algorithm>
29#include <fstream>
30#include <functional>
31#include <iostream>
32
33#include "AISDatabaseParser.h"
34#include "AISResources.h"
35
36using namespace std;
37
38namespace libdap {
39
45ostream &operator<<(ostream &os, const Resource &r) {
46 os << "<ancillary";
47 if (r.d_rule != Resource::overwrite) {
48 os << " rule=\"";
49 (r.d_rule == Resource::fallback) ? os << "fallback\"" : os << "replace\"";
50 }
51 os << " url=\"" << r.d_url << "\"/>";
52
53 return os;
54}
55
59ostream &operator<<(ostream &os, const AISResources &ais_res) {
60 os << "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>" << endl;
61 os << "<!DOCTYPE ais SYSTEM \"http://xml.opendap.org/ais/ais_database.dtd\">" << endl;
62 os << "<ais xmlns=\"http://xml.opendap.org/ais\">" << endl;
63
64 for (AISResources::ResourceRegexpsCIter pos = ais_res.d_re.begin(); pos != ais_res.d_re.end(); ++pos) {
65 os << "<entry>" << endl;
66 // write primary
67 os << "<primary regexp=\"" << pos->first << "\"/>" << endl;
68 // write the vector of Resource objects
69 for (ResourceVectorCIter i = pos->second.begin(); i != pos->second.end(); ++i) {
70 os << *i << endl;
71 }
72 os << "</entry>" << endl;
73 }
74
75 // Under VC++ 6.x, 'pos' is twice tagged as twice in the
76 // same scope (this method - not just within for blocks), so
77 // I gave it another name. ROM - 6/14/03
78 for (AISResources::ResourceMapCIter pos2 = ais_res.d_db.begin(); pos2 != ais_res.d_db.end(); ++pos2) {
79 os << "<entry>" << endl;
80 // write primary
81 os << "<primary url=\"" << pos2->first << "\"/>" << endl;
82 // write the vector of Resource objects
83 for (ResourceVectorCIter i = pos2->second.begin(); i != pos2->second.end(); ++i) {
84 os << *i << endl;
85 }
86 os << "</entry>" << endl;
87 }
88
89 os << "</ais>" << endl;
90
91 return os;
92}
93
96AISResources::AISResources(const string &database) throw(AISDatabaseReadFailed) { read_database(database); }
97
104void AISResources::add_url_resource(const string &url, const Resource &ancillary) {
105 add_url_resource(url, ResourceVector(1, ancillary));
106}
107
113void AISResources::add_url_resource(const string &url, const ResourceVector &rv) {
114 ResourceMapIter pos = d_db.find(url);
115 if (pos == d_db.end()) {
116 d_db.insert(std::make_pair(url, rv));
117 } else {
118 // There's already a ResourceVector, append to it.
119 for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
120 pos->second.push_back(*i);
121 }
122}
123
128void AISResources::add_regexp_resource(const string &re, const Resource &ancillary) {
129 add_regexp_resource(re, ResourceVector(1, ancillary));
130}
131
138void AISResources::add_regexp_resource(const string &re, const ResourceVector &rv) {
139 ResourceRegexpsIter pos = find_if(d_re.begin(), d_re.end(), [re](const RVPair &p) { return re == p.first; });
140 if (pos == d_re.end()) {
141 d_re.push_back(std::make_pair(re, rv));
142 } else {
143 // There's already a ResourceVector, append to it.
144 for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
145 pos->second.push_back(*i);
146 }
147}
148
150
157bool AISResources::has_resource(const string &primary) const {
158 // This code looks for the 'primary' in the AIS database (which is a STL
159 // map<> of strings and AIS stuff. As an optimization, it first uses the
160 // map<> class' find() method to see if the 'primary' is in there as a
161 // literal. If not, then it tries to match each regular expression in the
162 // database.
163 return ((d_db.find(primary) != d_db.end()) || (find_if(d_re.begin(), d_re.end(), [primary](const RVPair &p) {
164 Regex r(p.first.c_str());
165 return r.match(p.first) != -1;
166 } /*MatchRegexp(primary)*/) != d_re.end()));
167}
168
189 const ResourceMapIter &i = d_db.find(primary);
190
191 if (i != d_db.end())
192 rv = i->second;
193
194 // Finds the first matching regular expression and returns a vector of
195 // AIS resources.
196 const ResourceRegexpsIter &j = find_if(d_re.begin(), d_re.end(), [primary](const RVPair &p) {
197 Regex r(p.first.c_str());
198 return r.match(p.first) != -1;
199 } /*MatchRegexp(primary)*/);
200 if (j != d_re.end())
201 copy(j->second.begin(), j->second.end(), inserter(rv, rv.begin()));
202
203 if (rv.size() == 0)
204 throw NoSuchPrimaryResource();
205
206 return rv;
207}
208
216void AISResources::read_database(const string &database) {
217 AISDatabaseParser parser;
218
219 parser.intern(database, this);
220}
221
230void AISResources::write_database(const string &filename) {
231 ofstream fos;
232 fos.open(filename.c_str());
233
234 if (!fos)
235 throw AISDatabaseWriteFailed("Could not open file :" + filename);
236
237 fos << *this << endl;
238
239 if (!fos)
241}
242
243} // namespace libdap
void intern(const string &database, AISResources *ais)
virtual void write_database(const string &filename)
virtual ResourceVector get_resource(const string &primary)
virtual bool has_resource(const string &primary) const
virtual void read_database(const string &database)
virtual void add_regexp_resource(const string &regexp, const Resource &ancillary)
virtual void add_url_resource(const string &url, const Resource &ancillary)
Associate a rule with an ancillary resource.
Definition Resource.h:49
top level DAP object to house generic methods
Definition AISConnect.cc:30
vector< Resource > ResourceVector
ResourceVector::const_iterator ResourceVectorCIter
ostream & operator<<(ostream &os, const Resource &r)