// JobPreferences.cxx #include "dial_job/JobPreferences.h" #include #include #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" #include "dataset_id/UniqueId.h" using std::ostream; using std::cerr; using std::endl; using std::string; using std::auto_ptr; using dial::JobPreferencesId; using dial::JobPreferences; typedef XmlElement::ElementList ElementList; typedef JobPreferences::Name Name; typedef JobPreferences::Name Value; typedef JobPreferences::NameList NameList; typedef JobPreferences::ValueMap ValueMap; //********************************************************************** // Local definitions. //********************************************************************** namespace { // Register the DTD. DtdRegistry::Status ISTAT_JobPreferences = DtdRegistry::register_dtd("dial"); } // end unnamed namespace //********************************************************************** // Static methods. //********************************************************************** // XML name. const char* JobPreferences::xml_name() { return "JobPreferences"; } //********************************************************************** // ID context. const char* JobPreferences::id_context() { return "JobPreferences"; } //********************************************************************** // DTD. const Text& JobPreferences::dtd() { static Text txt; if ( txt.size() == 0 ) { txt.append(""); txt.append(""); txt.append(""); txt.append(""); } return txt; } //********************************************************************** // Default instance. const JobPreferences& JobPreferences::default_instance() { static JobPreferences defpref; if ( ! defpref.is_locked() ) { defpref.lock(); } assert( defpref.is_locked() ); return defpref; } //********************************************************************** // Constructors and destructor. //********************************************************************** // Default constructor. JobPreferences::JobPreferences() : m_lock(false), m_error(0) { } //********************************************************************** // XML constructor. JobPreferences::JobPreferences(const XmlElement& ele) : m_lock(true), m_error(0) { if ( ele.name() != xml_name() ) return; // Check version. string ver = ele.attribute("xml_version"); if ( ver != "1.30" ) { cerr << "JobPreferences::ctor(XmlElement): Invalid version" << endl; m_error = 1; return; } // Fetch ID. const XmlElement* pxid = ele.single_child(JobPreferencesId::xml_name()); if ( pxid == 0 ) { m_error = 2; return; } m_id = JobPreferencesId(*pxid); if ( ver == "0.90" ) { return; } // Fetch elements. const ElementList& ents = ele.children("JobPreferencesEntry"); for ( ElementList::const_iterator ient=ents.begin(); ient!=ents.end(); ++ient ) { // Fetch the XML description of this element. const XmlElement* pent = *ient; if ( pent == 0 ) { m_error = 3; return; } // Extract the name. Name name = pent->attribute("name"); if ( name == "" ) { m_error = 4; return; }; Value tvalue = pent->attribute("value"); Text::xml_to_text(tvalue); if ( m_vals.find(name) != m_vals.end() ) { m_error = 5; return; } // Put entry in map. m_vals[name] = tvalue; m_names.push_back(name); } } //********************************************************************** // Copy constructor. // Copy fails if object is invalid or unlocked. JobPreferences::JobPreferences(const JobPreferences& rhs) : m_lock(true), m_error(0) { if ( ! rhs.is_locked() ) { m_error = 11; return; } m_id = rhs.m_id; m_names = rhs.m_names; m_vals = rhs.m_vals; } //********************************************************************** // Assignment. // Fails if object is invalid or unlocked. JobPreferences& JobPreferences::operator=(const JobPreferences& rhs) { if ( &rhs == this ) return *this; m_id = rhs.m_id; m_error = rhs.m_error; if ( ! rhs.is_locked() ) { m_error = 11; return *this; } m_lock = true; m_id = rhs.m_id; m_names = rhs.m_names; m_vals = rhs.m_vals; } //********************************************************************** // Destructor. JobPreferences::~JobPreferences() { } //********************************************************************** // Non-const members. //********************************************************************** // Lock. int JobPreferences::lock() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; m_id = JobPreferencesId::generate(); m_lock = true; return 0; } //********************************************************************** // Add an entry. int JobPreferences::insert(Name name, Value val, bool replace) { if ( ! is_unlocked() ) { return 1; } if ( m_vals.find(name) != m_vals.end() ) { return 2; } m_vals[name] = val; m_names.push_back(name); return 0; } //********************************************************************** // Const members. //********************************************************************** // Validity. bool JobPreferences::is_valid() const { return m_error == 0; } //********************************************************************** // Error. int JobPreferences::error() const { return m_error; } //********************************************************************** // Is locked. bool JobPreferences::is_locked() const { return is_valid() && m_lock; } //********************************************************************** // Is unlocked. bool JobPreferences::is_unlocked() const { return is_valid() && !m_lock; } //********************************************************************** // Return the ID. JobPreferencesId JobPreferences::id() const { return m_id; } //********************************************************************** // Return the number of entries. JobPreferences::size_type JobPreferences::size() const { return m_names.size(); } //********************************************************************** // Return the list of names. const NameList& JobPreferences::names() const { return m_names; } //********************************************************************** // Has an entry. bool JobPreferences::has(Name name) const { if ( ! is_valid() ) return false; return m_vals.find(name) != m_vals.end(); } //********************************************************************** // Extract an entry. Value JobPreferences::extract(Name name) const { if ( ! is_valid() ) return ""; ValueMap::const_iterator ival = m_vals.find(name); if ( ival == m_vals.end() ) { return ""; } return ival->second; } //********************************************************************** // Clone. JobPreferences* JobPreferences::clone() const { JobPreferences* pobj = new JobPreferences(*this); pobj->m_lock = false; return pobj; } //********************************************************************** // Write to XML. const XmlElement* JobPreferences::xml() const { if ( ! is_locked() ) return 0; auto_ptr pele(new XmlElement(xml_name())); // Add version. pele->add_attribute("xml_version", "1.30"); // Add ID. const XmlElement* pxid = id().xml(); if ( pxid == 0 || ! pxid->is_valid() ) { delete pxid; return 0; } pele->add_child(pxid); // Add entries. for ( ValueMap::const_iterator ival=m_vals.begin(); ival!=m_vals.end(); ++ival ) { string name = ival->first; string value = ival->second; Text::text_to_xml(value); XmlElement* pxent = new XmlElement("JobPreferencesEntry"); pxent->add_attribute("name", name); pxent->add_attribute("value", value); pele->add_child(pxent); } // Return the XML. return pele.release(); } //********************************************************************** // Display. void JobPreferences::display() const { std::cout << *this << std::endl; } //********************************************************************** // Web page. Text JobPreferences::web_page(string baseurl, string entry) const { Text wp; wp.append(""); // Display prefs. if ( entry == "" ) { string header = "Job preferences " + id().to_string(); wp.append("" + header + ""); wp.append("

" + header + "

"); /* wp.append("Owner: " + owner()); time_t time = create_time(); string stime = asctime(gmtime(&time)); wp.append("
Created: " + stime + " UTC"); wp.append("

Description:"); */ if ( names().size() == 0 ) { wp.append("No preferences defined"); } else { wp.append(""); wp.append("
namevalue"); for ( JobPreferences::NameList::const_iterator inam=names().begin(); inam!=names().end(); ++inam ) { string name = *inam; string sval = extract(name); Text::text_to_xml(sval); wp.append("
" + name + "" + sval); } wp.append("
"); } } wp.append(""); return wp; } //********************************************************************** // Free functions. //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const JobPreferences& rhs) { if ( ! rhs.is_valid() ) { lhs << "Invalid job preferences"; return lhs; } lhs << "Job preferences with ID " << rhs.id().to_string() << " is "; if ( rhs.is_unlocked() ) lhs << "un"; lhs << "locked and has "; const NameList& names = rhs.names(); NameList::size_type count = names.size(); lhs << count; if ( count == 1 ) { lhs << " entry:"; } else { lhs << " entries"; if ( count > 0 ) lhs << ":"; } for ( NameList::const_iterator inam=names.begin(); inam!=names.end(); ++inam ) { Name name = *inam; Value value = rhs.extract(name); lhs << "\n " << name << ": " << value; lhs.flush(); } return lhs; } //**********************************************************************