libdap Updated for version 3.21.0
libdap4 is an implementation of OPeNDAP's DAP protocol.
AISResources.cc
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 <iostream>
29#include <fstream>
30#include <algorithm>
31#include <functional>
32
33#include "AISResources.h"
34#include "AISDatabaseParser.h"
35
36using namespace std;
37
38namespace libdap {
39
45ostream &
46operator<<(ostream &os, const Resource &r)
47{
48 os << "<ancillary";
49 if (r.d_rule != Resource::overwrite) {
50 os << " rule=\"";
51 (r.d_rule == Resource::fallback) ? os << "fallback\"" : os << "replace\"";
52 }
53 os << " url=\"" << r.d_url << "\"/>";
54
55 return os;
56}
57
61ostream &
62operator<<(ostream &os, const AISResources &ais_res)
63{
64 os << "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>"
65 << endl;
66 os << "<!DOCTYPE ais SYSTEM \"http://xml.opendap.org/ais/ais_database.dtd\">" << endl;
67 os << "<ais xmlns=\"http://xml.opendap.org/ais\">" << endl;
68
69 for (AISResources::ResourceRegexpsCIter pos = ais_res.d_re.begin();
70 pos != ais_res.d_re.end(); ++pos) {
71 os << "<entry>" << endl;
72 // write primary
73 os << "<primary regexp=\"" << pos->first << "\"/>" << endl;
74 // write the vector of Resource objects
75 for (ResourceVectorCIter i = pos->second.begin();
76 i != pos->second.end(); ++i) {
77 os << *i << endl;
78 }
79 os << "</entry>" << endl;
80 }
81
82 // Under VC++ 6.x, 'pos' is twice tagged as twice in the
83 // same scope (this method - not just within for blocks), so
84 // I gave it another name. ROM - 6/14/03
85 for (AISResources::ResourceMapCIter pos2 = ais_res.d_db.begin();
86 pos2 != ais_res.d_db.end(); ++pos2) {
87 os << "<entry>" << endl;
88 // write primary
89 os << "<primary url=\"" << pos2->first << "\"/>" << endl;
90 // write the vector of Resource objects
91 for (ResourceVectorCIter i = pos2->second.begin();
92 i != pos2->second.end(); ++i) {
93 os << *i << endl;
94 }
95 os << "</entry>" << endl;
96 }
97
98 os << "</ais>" << endl;
99
100 return os;
101}
102
106{
107 read_database(database);
108}
109
116void
117AISResources::add_url_resource(const string &url, const Resource &ancillary)
118{
119 add_url_resource(url, ResourceVector(1, ancillary));
120}
121
127void
128AISResources::add_url_resource(const string &url, const ResourceVector &rv)
129{
130 ResourceMapIter pos = d_db.find(url);
131 if (pos == d_db.end()) {
132 d_db.insert(std::make_pair(url, rv));
133 }
134 else {
135 // There's already a ResourceVector, append to it.
136 for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
137 pos->second.push_back(*i);
138 }
139}
140
145void
146AISResources::add_regexp_resource(const string &re, const Resource &ancillary)
147{
148 add_regexp_resource(re, ResourceVector(1, ancillary));
149}
150
157void
158AISResources::add_regexp_resource(const string &re, const ResourceVector &rv)
159{
160 ResourceRegexpsIter pos = find_if(d_re.begin(), d_re.end(),
161 [re](const RVPair &p){ return re == p.first; });
162 if (pos == d_re.end()) {
163 d_re.push_back(std::make_pair(re, rv));
164 }
165 else {
166 // There's already a ResourceVector, append to it.
167 for (ResourceVectorCIter i = rv.begin(); i != rv.end(); ++i)
168 pos->second.push_back(*i);
169 }
170}
171
173
180bool
181AISResources::has_resource(const string &primary) const
182{
183 // This code looks for the 'primary' in the AIS database (which is a STL
184 // map<> of strings and AIS stuff. As an optimization, it first uses the
185 // map<> class' find() method to see if the 'primary' is in there as a
186 // literal. If not, then it tries to match each regular expression in the
187 // database.
188 return ((d_db.find(primary) != d_db.end())
189 || (find_if(d_re.begin(), d_re.end(),
190 [primary] (const RVPair &p) {
191 Regex r(p.first.c_str());
192 return r.match(p.first) != -1; } /*MatchRegexp(primary)*/)
193 != d_re.end()));
194
195}
196
215ResourceVector
216AISResources::get_resource(const string &primary)
217{
218 ResourceVector rv;
219 const ResourceMapIter &i = d_db.find(primary);
220
221 if (i != d_db.end())
222 rv = i->second;
223
224 // Finds the first matching regular expression and returns a vector of
225 // AIS resources.
226 const ResourceRegexpsIter &j = find_if(d_re.begin(), d_re.end(),
227 [primary] (const RVPair &p) {
228 Regex r(p.first.c_str());
229 return r.match(p.first) != -1; } /*MatchRegexp(primary)*/);
230 if (j != d_re.end())
231 copy(j->second.begin(), j->second.end(), inserter(rv, rv.begin()));
232
233 if (rv.size() == 0)
234 throw NoSuchPrimaryResource();
235
236 return rv;
237}
238
246void
247AISResources::read_database(const string &database)
248{
249 AISDatabaseParser parser;
250
251 parser.intern(database, this);
252}
253
262void
263AISResources::write_database(const string &filename)
264{
265 ofstream fos;
266 fos.open(filename.c_str());
267
268 if (!fos)
269 throw AISDatabaseWriteFailed("Could not open file :" + filename);
270
271 fos << *this << endl;
272
273 if (!fos)
275}
276
277} // 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:51
top level DAP object to house generic methods
Definition AISConnect.cc:30
ostream & operator<<(ostream &os, const Resource &r)