// FileCatalog.cxx #include "dataset_file/FileCatalog.h" #include #include #include #include #include "dataset_util/Text.h" #include "dataset_util/Environment.h" #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" using std::string; using std::ostream; using std::cerr; using std::endl; using dset::Url; using dset::FileCatalog; typedef FileCatalog::Name Name; typedef FileCatalog::Locator Locator; typedef std::map LocatorMap; //********************************************************************** // Local definitions. //********************************************************************** namespace { //********************************************************************** // Return the map of locators. LocatorMap& locs() { static LocatorMap slocs; return slocs; } //********************************************************************** // Register the DTD. DtdRegistry::Status ISTAT = DtdRegistry::register_dtd("dataset"); //********************************************************************** // Return the default file catalog. // Sets the specified value if set is true. FileCatalog* default_catalog(bool set, FileCatalog* pfcin) { static string prefix = "FileCatalog::default_catalog: "; static string defenv = "LocalFileCatalog"; static FileCatalog* pfc = 0; // If requested, set default catalog. if ( set ) { if ( pfc!=0 && pfcin!=0 ) { cerr << prefix << "Catalog is already set" << endl; return 0; } else { pfc = pfcin; return pfc; } } // Locate catalog if default is not yet assigned. if ( pfc == 0 ) { string envcat = Environment::current().value("DIAL_FILE_CATALOG"); if ( ! envcat.size() ) { envcat = defenv; cerr << prefix << "Environment variable DIAL_FILE_CATALOG is not defined" << endl; cerr << " Using default: " << envcat << endl; } string type = envcat; string name = ""; string::size_type ipos = envcat.find(":"); if ( ipos != string::npos ) { type = envcat.substr(0, ipos); if ( ipos+1 > envcat.size() ) { name = envcat.substr(ipos+1); } } pfc = FileCatalog::locate(type, name); if ( pfc == 0 ) { cerr << prefix << "Unable to locate file catalog." << endl; cerr << " Type: " << type << endl; cerr << " Name: " << name << endl; } } return pfc; } //********************************************************************** } // end unnamed namespace //********************************************************************** // Static member functions. //********************************************************************** // Return the DTD. const Text& FileCatalog::dtd() { static Text txt; if ( txt.size() == 0 ) { txt.append(""); txt.append(""); } return txt; } //********************************************************************** // Register a locator for a type. int FileCatalog::register_locator(Name type, Locator pfun) { if ( locs().find(type) != locs().end() ) { return 1; } locs()[type] = pfun; return 0; } //********************************************************************** // Fetch a file catalog using type and catalog name. FileCatalog* FileCatalog::locate(Name type, Name catalog) { string prefix = "FileCatalog::locate: "; LocatorMap::const_iterator iloc = locs().find(type); if ( iloc == locs().end() ) { if ( type == "MagdaFileCatalog" ) { string lib = "libmysqlpp_dial.so"; void* handle = dlopen(lib.c_str(), RTLD_NOW|RTLD_GLOBAL); if ( handle == 0 ) { cerr << prefix << "Unable to load library " << lib << endl; } lib = "libdataset_magda.so"; handle = dlopen(lib.c_str(), RTLD_NOW|RTLD_GLOBAL); if ( handle == 0 ) { cerr << prefix << "Unable to load library " << lib << endl; } } else if ( type == "PoolFileCatalog" ) { string lib = "libdataset_pool.so"; void* handle = dlopen(lib.c_str(), RTLD_NOW|RTLD_GLOBAL); if ( handle == 0 ) { cerr << prefix << "Unable to load library " << lib << endl; } } iloc = locs().find(type); } if ( locs().find(type) == locs().end() ) { cerr << prefix << "Unknown file catalog type: " << type << endl; return 0; } return locs()[type](type, catalog); } //********************************************************************** // Fetch a file catalog using XML. FileCatalog* FileCatalog::locate(const XmlElement& ele) { if ( ele.name() != FileCatalog::xml_name() ) return 0; if ( ! ele.has_attribute("type") ) return 0; Name type = ele.attribute("type"); Name name = ele.attribute("name"); return locate(type, name); } //********************************************************************** // Set the default file catalog. FileCatalog* FileCatalog::set_default_instance(Name type, Name name) { static string prefix = "FileCatalog::set_default_instance: "; FileCatalog* pfc = locate(type, name); if ( pfc == 0 ) { cerr << prefix << "Unable to locate file catalog:" << endl; cerr << " Type: " << type << endl; cerr << " Name: " << name << endl; } else { default_catalog(true, pfc); } return pfc; } //********************************************************************** // Fetch the default file catalog. FileCatalog* FileCatalog::default_instance() { return default_catalog(false, 0); } //********************************************************************** // Member functions. //********************************************************************** // Destructor. FileCatalog::~FileCatalog() { } //********************************************************************** // Writeable. bool FileCatalog::catalog_is_writeable() { return true; } //********************************************************************** // Error status. int FileCatalog::error() const { return 0; } //********************************************************************** // Output stream. void FileCatalog::ostr(ostream& str) const { Name nam = name(); str << type(); if ( nam.size() > 0 ) { str << ":" << nam; } } //********************************************************************** // Write to XML. const XmlElement* FileCatalog::xml() const { XmlElement* pele = new XmlElement(xml_name()); pele->add_attribute("type", type()); pele->add_attribute("name", name()); return pele; } //********************************************************************** // Free functions. //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const FileCatalog& rhs) { rhs.ostr(lhs); return lhs; } //**********************************************************************