OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
NCMLContainer.cc
Go to the documentation of this file.
1 // NCMLContainer.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of ncml_module, A C++ module that can be loaded in to
6 // the OPeNDAP Back-End Server (BES) and is able to handle ncml requests.
7 
8 // Copyright (c) 2002,2003 OPeNDAP, Inc.
9 // Author: Patrick West <pwest@ucar.edu>
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 // (c) COPYRIGHT URI/MIT 1994-1999
28 // Please read the full copyright statement in the file COPYRIGHT_URI.
29 //
30 // Authors:
31 // pcw Patrick West <pwest@ucar.edu>
32 
33 #include "config.h"
34 
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 
39 #include <fstream>
40 #include <cerrno>
41 #include <cstdlib>
42 #include <cstring>
43 
44 using std::ofstream;
45 using std::endl;
46 using std::ios_base;
47 
48 #include "NCMLContainer.h"
49 #include "NCMLContainerStorage.h"
50 
51 #include <BESSyntaxUserError.h>
52 #include <BESInternalError.h>
53 #include <BESDebug.h>
54 
68 NCMLContainer::NCMLContainer(const string &sym_name, const string &xml_doc) :
69  BESContainer(sym_name, "", "ncml"), _xml_doc(xml_doc), _accessed(false)
70 {
71 }
72 
73 NCMLContainer::NCMLContainer(const NCMLContainer &copy_from) :
74  BESContainer(copy_from), _xml_doc(copy_from._xml_doc), _accessed(copy_from._accessed)
75 {
76  // we can not make a copy of this container once the NCML document has
77  // been written to the temporary file
78  if (_accessed) {
79  string err = (string) "The Container has already been accessed, " + "can not create a copy of this container.";
80  throw BESInternalError(err, __FILE__, __LINE__);
81  }
82 }
83 
85 {
86  if (copy_to._accessed) {
87  string err = (string) "The Container has already been accessed, " + "can not duplicate this resource.";
88  throw BESInternalError(err, __FILE__, __LINE__);
89  }
90  copy_to._xml_doc = _xml_doc;
91  copy_to._accessed = false;
92  BESContainer::_duplicate(copy_to);
93 }
94 
97 {
98  NCMLContainer *container = new NCMLContainer;
99  _duplicate(*container);
100  return container;
101 }
102 
104 {
105  if (_accessed) {
106  release();
107  }
108 }
109 
116 {
117  BESDEBUG("ncml", "accessing " << _xml_doc << endl);
118  if (!_accessed) {
119  // save the xml document to a temporary file, open it, unlink
120  // it. In release, close the file. This will remove the file if
121  // it is no longer open.
122 
123  string tempfile_template = "ncml_module_XXXXXX";
124 #if defined(WIN32) || defined(TEST_WIN32_TEMPS)
125  char *tempfile_c = _mktemp( (char *)tempfile_template.c_str() );
126 #else
127  char *tempfile_c = mktemp((char *) tempfile_template.c_str());
128 #endif
129  string tempfile;
130  if (tempfile_c) {
131  tempfile = tempfile_c;
132  }
133  else {
134  string err = (string) "Unable to create temporary ncml document " + _tmp_file_name;
135  throw BESInternalError(err, __FILE__, __LINE__);
136  }
137 
138  _tmp_file_name = NCMLContainerStorage::NCML_TempDir + "/" + tempfile + ".ncml";
139 
140  ofstream ostrm;
141  int my_errno = 0;
142 
143  ostrm.open(_tmp_file_name.c_str(), ios_base::out);
144  my_errno = errno;
145 
146  if (!ostrm) {
147  string err = (string) "Unable to write out the ncml document " + _tmp_file_name;
148  if (my_errno) {
149  char *str = strerror(my_errno);
150  if (str) err += (string) " " + str;
151  }
152  throw BESInternalError(err, __FILE__, __LINE__);
153  }
154 
155  // write out <?xml version="1.0" encoding="UTF-8"?>
156  ostrm << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
157 
158  // then write out the r_name as the ncml document (no validation)
159  ostrm << _xml_doc << endl;
160 
161  ostrm.close();
162 
163  _accessed = true;
164  }
165  return _tmp_file_name;
166 }
167 
175 {
176  if (_accessed && !_tmp_file_name.empty()) {
177  unlink(_tmp_file_name.c_str());
178  _tmp_file_name = "";
179  }
180  _accessed = false;
181  return true;
182 }
183 
191 void NCMLContainer::dump(ostream &strm) const
192 {
193  strm << BESIndent::LMarg << "NCMLContainer::dump - (" << (void *) this << ")" << endl;
195  if (_accessed) {
196  strm << BESIndent::LMarg << "temporary file: " << _tmp_file_name << endl;
197  }
198  else {
199  strm << BESIndent::LMarg << "temporary file: not open" << endl;
200  }
201  BESContainer::dump(strm);
203 }
204 
exception thrown if inernal error encountered
Container representing a NCML request.
Definition: NCMLContainer.h:51
virtual void dump(ostream &strm) const
dumps information about this object
static void Indent()
Definition: BESIndent.cc:38
static ostream & LMarg(ostream &strm)
Definition: BESIndent.cc:73
virtual BESContainer * ptr_duplicate()
pure abstract method to duplicate this instances of BESContainer
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
Definition: BESContainer.cc:50
void _duplicate(NCMLContainer &copy_to)
virtual bool release()
release the NCML cached resources
virtual string access()
access the NCML target response by making the NCML request
virtual void dump(ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:68
virtual ~NCMLContainer()
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
A container is something that holds data.
Definition: BESContainer.h:60
static void UnIndent()
Definition: BESIndent.cc:44