libdap  Updated for version 3.20.6
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 
36 using namespace std;
37 
38 namespace libdap {
39 
45 ostream &
46 operator<<(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 
61 ostream &
62 operator<<(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 
105 AISResources::AISResources(const string &database) throw(AISDatabaseReadFailed)
106 {
107  read_database(database);
108 }
109 
116 void
117 AISResources::add_url_resource(const string &url, const Resource &ancillary)
118 {
119  add_url_resource(url, ResourceVector(1, ancillary));
120 }
121 
127 void
128 AISResources::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 
145 void
146 AISResources::add_regexp_resource(const string &re, const Resource &ancillary)
147 {
148  add_regexp_resource(re, ResourceVector(1, ancillary));
149 }
150 
157 void
158 AISResources::add_regexp_resource(const string &re, const ResourceVector &rv)
159 {
160  ResourceRegexpsIter pos = find_if(d_re.begin(), d_re.end(),
161  FindRegexp(re));
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 
180 bool
181 AISResources::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(), MatchRegexp(primary))
190  != d_re.end()));
191 
192 }
193 
212 ResourceVector
213 AISResources::get_resource(const string &primary)
214 {
215  ResourceVector rv;
216  const ResourceMapIter &i = d_db.find(primary);
217 
218  if (i != d_db.end())
219  rv = i->second;
220 
221  // Finds the first matching regular expression and returns a vector of
222  // AIS resources.
223  const ResourceRegexpsIter &j = find_if(d_re.begin(), d_re.end(),
224  MatchRegexp(primary));
225  if (j != d_re.end())
226  copy(j->second.begin(), j->second.end(), inserter(rv, rv.begin()));
227 
228  if (rv.size() == 0)
229  throw NoSuchPrimaryResource();
230 
231  return rv;
232 }
233 
241 void
242 AISResources::read_database(const string &database)
243 {
244  AISDatabaseParser parser;
245 
246  parser.intern(database, this);
247 }
248 
257 void
258 AISResources::write_database(const string &filename)
259 {
260  ofstream fos;
261  fos.open(filename.c_str());
262 
263  if (!fos)
264  throw AISDatabaseWriteFailed("Could not open file :" + filename);
265 
266  fos << *this << endl;
267 
268  if (!fos)
269  throw AISDatabaseWriteFailed();
270 }
271 
272 } // namespace libdap
Manage AIS resources.
Definition: AISResources.h:70
void intern(const string &database, AISResources *ais)
STL namespace.
top level DAP object to house generic methods
Definition: AISConnect.cc:30
ostream & operator<<(ostream &os, const Resource &r)
Definition: AISResources.cc:46
Associate a rule with an ancillary resource.
Definition: Resource.h:50