// GenericDataset.cxx #include "dataset_base/GenericDataset.h" #include #include #include "dataset_util/memsize.h" #include "dataset_util/Text.h" #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" #include "dataset_credential/GssCredentialManager.h" #include "dataset_base/DatasetRepository.h" #include "dataset_base/DatasetCreator.h" using std::string; using std::cerr; using std::endl; using dset::GssCredentialManager; using dset::Content; using dset::Location; using dset::Dataset; using dset::DatasetList; using dset::DatasetRepository; using dset::DatasetCreator; using dset::GenericDataset; typedef Dataset::Time Time; typedef GenericDataset::StorageState StorageState; typedef GenericDataset::Name Name; typedef GenericDataset::EventState EventState; typedef GenericDataset::NameList NameList; typedef GenericDataset::Promoter Promoter; typedef std::map PMap; //********************************************************************** // Local helpers. //********************************************************************** namespace { const StorageState UNDEFINED = GenericDataset::UNDEFINED; const StorageState ABSENT = GenericDataset::ABSENT; const StorageState IMPLICIT = GenericDataset::IMPLICIT; const StorageState COMPOSITE = GenericDataset::COMPOSITE; const StorageState EXPLICIT = GenericDataset::EXPLICIT; const EventState EVUNDEF = GenericDataset::EVUNDEF; const EventState EVNONE = GenericDataset::EVNONE; const EventState EVFIRST = GenericDataset::EVFIRST; //********************************************************************** // Containers for promoters. PMap& pmap() { static PMap val; return val; } NameList& pnames() { static NameList val; return val; } //********************************************************************** // Creator. const Dataset* create(const XmlElement& ele, DatasetRepository* prep) { const Dataset* pdst = 0; if ( ele.name() != GenericDataset::xml_name() ) return pdst; string fulltype = ele.attribute("fulltype"); if ( fulltype == "" ) return pdst; // If the fulltype is registered, call the corresponding creator. const GenericDataset* pgen = GenericDataset::create(ele, prep); if ( pgen == 0 ) return pdst; if ( GenericDataset::has_promoter(fulltype) ) { pdst = GenericDataset::promote(*pgen); delete pgen; } else { pdst = pgen; } return pdst; } //********************************************************************** // Convert StorageState to string. string sstate_to_string(StorageState sta) { switch(sta) { case UNDEFINED: assert(false); break; case ABSENT: return "ABSENT"; case EXPLICIT: return "EXPLICIT"; case COMPOSITE: return "COMPOSITE"; case IMPLICIT: return "IMPLICIT"; } return ""; } //********************************************************************** // Convert string to StorageState. StorageState string_to_sstate(string str) { if ( str == "UNDEFINED" ) assert(false); if ( str == "ABSENT" ) return ABSENT; if ( str == "EXPLICIT" ) return EXPLICIT; if ( str == "COMPOSITE" ) return COMPOSITE; if ( str == "IMPLICIT" ) return IMPLICIT; return UNDEFINED; } //********************************************************************** // Convert EventState to string. string evstate_to_string(EventState sta) { switch(sta) { case EVUNDEF: assert(false); break; case EVNONE: return "EVNONE"; case EVFIRST: return "EVFIRST"; } return ""; } //********************************************************************** // Convert string to EventState. EventState string_to_evstate(string str) { if ( str == "EVUNDEF" ) assert(false); if ( str == "EVNONE" ) return EVNONE; if ( str == "EVFIRST" ) return EVFIRST; return EVUNDEF; } //********************************************************************** // Content and location error values. // Content is composite. int composite_content_error() { return 21; } // Content is implicit. int implicit_content_error() { return 22; } // Content is absent. int absent_content_error() { return 23; } // Content is absent. int undefined_content_error() { return 24; } // Location is composite. int composite_location_error() { return 31; } // Location is implicit. int implicit_location_error() { return 32; } //********************************************************************** // Register creator. int GenericDataset_xml_stat = DatasetCreator::insert(GenericDataset::xml_name(), create); //********************************************************************** // Register the DTD. DtdRegistry::Status GenericDataset_dtd_stat = DtdRegistry::register_dtd("dataset"); //********************************************************************** } // end unnamed namespace //********************************************************************** // Static functions. //********************************************************************** // DTD. // // Items flagged 1.20-1.30 were added between versions 1.20 and 1.30 // and are temporarily left IMPLIED to allow backward compatibility. const Text& GenericDataset::dtd() { static Text txt; if ( txt.size() == 0 ) { txt.append(""); txt.append(""); txt.append(""); txt.append(""); } return txt; } //********************************************************************** // Static members. //********************************************************************** // Creator. const GenericDataset* GenericDataset:: create(const XmlElement& ele, DatasetRepository*) { const GenericDataset* pdst = 0; if ( ele.name() != GenericDataset::xml_name() ) return pdst; GenericDataset* pdstnew = new GenericDataset(ele); pdstnew->lock(); pdst = pdstnew; return pdst; } //********************************************************************** // Register a promoter. int GenericDataset::register_promoter(Name name, Promoter pfun) { if ( pmap().find(name) == pmap().end() ) { pmap()[name] = pfun; pnames().insert(name); assert( pmap().size() == pnames().size() ); return 0; } else { if ( pmap()[name] == pfun ) { return 0; } } return 1; } //********************************************************************** // Promote a dataset. const GenericDataset* GenericDataset::promote(const GenericDataset& gen) { PMap::const_iterator ifun = pmap().find(gen.fulltype()); if ( ifun == pmap().end() ) return 0; Promoter pfun = ifun->second; return pfun(gen); } //********************************************************************** // Return the list of promoter names. bool GenericDataset::has_promoter(Name name) { return pmap().find(name) != pmap().end(); } //********************************************************************** // Return the list of promoter names. const NameList& GenericDataset::promoters() { return pnames(); } //********************************************************************** // Protected members. //********************************************************************** // Create extra XML. const XmlElement* GenericDataset::create_extra_xml() const { return 0; } //********************************************************************** // Return the extra XML. const XmlElement* GenericDataset::extra_xml() const { return m_pxxml; } //********************************************************************** // Set full type. int GenericDataset::set_fulltype(string fulltype) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_fulltype.size() ) return 3; m_fulltype = fulltype; return 0; } //********************************************************************** // Set invalid. int GenericDataset::set_invalid() { if ( ! is_valid() ) return 1; m_error = 999; m_locked = true; return 0; } //********************************************************************** // Set error. int GenericDataset::set_error(int err) { if ( ! is_valid() ) return 1; if ( err <= 0 ) return 2; m_error = err; m_locked = true; return 0; } //********************************************************************** // Set ID using unique ID generator. int GenericDataset::set_id() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( id().is_valid() ) return 3; DatasetId did = Dataset::id_generator().next(); if ( ! did.is_valid() ) return 4; m_id = did; return 0; } //********************************************************************** // Unset content state. int GenericDataset::unset_content() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; m_con_storage = UNDEFINED; m_con = Content(undefined_content_error()); return 0; } //********************************************************************** // Set content state absent. int GenericDataset::set_content_absent() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != UNDEFINED ) return 3; m_con_storage = ABSENT; m_con = Content(absent_content_error()); return 0; } //********************************************************************** // Set content state implicit. int GenericDataset::set_content_implicit() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != UNDEFINED ) return 3; m_con_storage = IMPLICIT; m_con = Content(implicit_content_error()); return 0; } //********************************************************************** // Set content state composite. int GenericDataset::set_content_composite() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != UNDEFINED ) return 3; m_con_storage = COMPOSITE; return 0; } //********************************************************************** // Set the content. int GenericDataset::set_content(const Content& con) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != UNDEFINED ) return 3; m_con = con; m_con_storage = EXPLICIT; return 0; } //********************************************************************** // Update the content. int GenericDataset::reset_content(const Content& con) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != EXPLICIT ) return 3; m_con = con; return 0; } //********************************************************************** // Merge the content. int GenericDataset::merge_content(const Content& con) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_con_storage != EXPLICIT ) return 3; int mstat = m_con.merge(con); if ( mstat != 0 ) return 100 + mstat; return 0; } //********************************************************************** // Set location implicit. int GenericDataset::set_location_implicit() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_loc_storage != UNDEFINED ) return 3; m_loc_storage = IMPLICIT; return 0; } //********************************************************************** // Set location composite. int GenericDataset::set_location_composite() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_loc_storage != UNDEFINED ) return 3; m_loc_storage = COMPOSITE; return 0; } //********************************************************************** // Set location. int GenericDataset:: set_location(const Location& loc, const Location* piloc) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_loc_storage != UNDEFINED ) return 3; m_loc = loc; if ( piloc != 0 ) { m_iloc = *piloc; } m_loc_storage = EXPLICIT; return 0; } //********************************************************************** // Set virtual. int GenericDataset::set_virtual() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_loc_storage != UNDEFINED ) return 3; m_loc_storage = ABSENT; return 0; } //********************************************************************** // Set event content to none. int GenericDataset::set_evstate_none() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_evstate != EVUNDEF ) return 3; m_evstate = EVNONE; return 0; } //********************************************************************** // Set event content to first. int GenericDataset::set_evstate_first() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( m_evstate != EVUNDEF ) return 3; m_evstate = EVFIRST; return 0; } //********************************************************************** // Set the constituent ID's. int GenericDataset:: set_constituent_ids(const DatasetIdList& dids) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( constituents().size() ) return 3; m_dids = dids; return 0; } //********************************************************************** // Append a constituent ID. int GenericDataset::append_constituent_id(DatasetId did, bool dup) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( ! dup && constituent_ids().find(did) != constituent_ids().end() ) return 3; m_dids.insert(did); m_dsts.clear(); if ( content_storage_state() == COMPOSITE ) m_con = Content(composite_content_error()); if ( location_storage_state() == COMPOSITE ) m_loc = Location(composite_location_error()); m_iloc = Location(composite_location_error()); return 0; } //********************************************************************** // Append a constituent. int GenericDataset::append_constituent(const Dataset& dst, bool dup) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( !dup && constituent_ids().find(dst.id()) != constituent_ids().end() ) return 3; // If needed and possible, register constituent in repository. DatasetRepository& rep = DatasetRepository::default_instance(); if ( rep.is_valid() && !rep.has(dst.id()) ) { rep.insert(&dst, false); } // Is the list of constituents up to date? bool have_cons = m_dsts.size() > 0 || m_dids.size() == 0; // Append the ID. m_dids.insert(dst.id()); // If the list of consituents is up to date, append the new dataset. if ( have_cons ) { m_dsts.push_back(&dst); } // Set flags to rebuild location and content on demand. if ( content_storage_state() == COMPOSITE ) m_con = Content(composite_content_error()); if ( location_storage_state() == COMPOSITE ) m_loc = Location(composite_location_error()); m_iloc = Location(composite_location_error()); return 0; } //********************************************************************** // Constructors and destructor. //********************************************************************** // Constructor. GenericDataset::GenericDataset() : m_error(0), m_locked(false), m_parent(0), m_owner(GssCredentialManager::owner()), m_create_time(time(0)), m_con_storage(UNDEFINED), m_loc_storage(UNDEFINED), m_evstate(EVUNDEF), m_pxxml(0), m_manage_xxml(false) { } //********************************************************************** // Constructor for an invalid dataset. GenericDataset::GenericDataset(bool lock) : m_error(999), m_locked(lock), m_parent(0), m_owner(""), m_create_time(time(0)), m_con_storage(UNDEFINED), m_loc_storage(UNDEFINED), m_evstate(EVUNDEF), m_pxxml(0), m_manage_xxml(false) { } //********************************************************************** // Constructor for a virtual dataset. GenericDataset:: GenericDataset(const Content& con, string fulltype, DatasetId id) : m_fulltype(fulltype), m_error(0), m_locked(false), m_id(id), m_parent(0), m_owner(GssCredentialManager::owner()), m_create_time(time(0)), m_con_storage(EXPLICIT), m_loc_storage(ABSENT), m_evstate(EVUNDEF), m_con(con), m_pxxml(0), m_manage_xxml(false) { if ( ! this->id().is_valid() ) { set_id(); } if ( con.size() && con.front().has_events() ) { set_evstate_first(); } else { set_evstate_none(); } } //********************************************************************** // Constructor for a nonvirtual dataset. GenericDataset:: GenericDataset(const Content& con, const Location& loc, string fulltype, DatasetId id) : m_fulltype(fulltype), m_error(0), m_locked(false), m_id(id), m_parent(0), m_owner(GssCredentialManager::owner()), m_create_time(time(0)), m_con_storage(EXPLICIT), m_loc_storage(EXPLICIT), m_evstate(EVUNDEF), m_con(con), m_loc(loc), m_pxxml(0), m_manage_xxml(false) { if ( ! this->id().is_valid() ) { set_id(); } if ( con.size() && con.front().has_events() ) { set_evstate_first(); } else { set_evstate_none(); } } //********************************************************************** // Constructor for a nonvirtual dataset with interface location. GenericDataset:: GenericDataset(const Content& con, const Location& loc, const Location& iloc, string fulltype, DatasetId id) : m_fulltype(fulltype), m_error(0), m_locked(false), m_id(id), m_parent(0), m_owner(GssCredentialManager::owner()), m_create_time(time(0)), m_con_storage(EXPLICIT), m_loc_storage(EXPLICIT), m_evstate(EVUNDEF), m_con(con), m_loc(loc), m_iloc(iloc), m_pxxml(0), m_manage_xxml(false) { if ( ! this->id().is_valid() ) { set_id(); } if ( con.size() && con.front().has_events() ) { set_evstate_first(); } else { set_evstate_none(); } } //********************************************************************** // Copy constructor. GenericDataset::GenericDataset(const GenericDataset& rhs) : m_fulltype(rhs.m_fulltype), m_error(rhs.m_error), m_locked(rhs.m_locked), m_id(rhs.m_id), m_pid(rhs.m_pid), m_parent(rhs.m_parent), m_owner(rhs.m_owner), m_create_time(rhs.m_create_time), m_con_storage(rhs.m_con_storage), m_loc_storage(rhs.m_loc_storage), m_evstate(rhs.m_evstate), m_con(rhs.m_con), m_loc(rhs.m_loc), m_iloc(rhs.m_iloc), m_dids(rhs.m_dids), m_dsts(rhs.m_dsts), m_pxxml(rhs.m_pxxml), m_manage_xxml(false) { if ( m_pxxml != 0 && rhs.m_manage_xxml ) { m_pxxml = new XmlElement(*m_pxxml); m_manage_xxml = true; } } //********************************************************************** // XML constructor. GenericDataset::GenericDataset(const XmlElement& ele) : m_error(0), m_locked(false), m_parent(0), m_create_time(0), m_con_storage(UNDEFINED), m_loc_storage(UNDEFINED), m_evstate(EVUNDEF), m_pxxml(0), m_manage_xxml(false) { if ( ele.name() != xml_name() ) return; set_fulltype(ele.attribute("fulltype")); set_id(DatasetId(ele.attribute("id"))); string spid = ele.attribute("parent"); if ( spid.size() ) { set_parent_id(DatasetId(spid)); } if ( ele.has_attribute("owner") ) { m_owner = ele.attribute("owner"); } else { m_owner = "unknown"; } m_create_time = ele.attribute_as_int("create_time"); m_con_storage = string_to_sstate(ele.attribute("cstorage")); m_loc_storage = string_to_sstate(ele.attribute("lstorage")); m_evstate = string_to_evstate(ele.attribute("evstate")); // Fetch constituent dataset ID's. const XmlElement* pxdst = ele.single_child("DatasetIdList"); if ( pxdst != 0 ) { m_dids = DatasetIdList(*pxdst); } // Fetch content. if ( m_con_storage == EXPLICIT ) { const XmlElement* pxcon = ele.single_child("Content"); assert( pxcon != 0 ); m_con = Content(*pxcon); } else if ( m_con_storage == COMPOSITE ) { m_con = Content(composite_content_error()); } else if ( m_con_storage == IMPLICIT ) { m_con = Content(implicit_content_error()); } else if ( m_con_storage == ABSENT ) { m_con = Content(absent_content_error()); } else { assert(false); } // Fetch location. if ( m_loc_storage == EXPLICIT ) { const XmlElement* pxloc = ele.single_child("Location"); assert( pxloc != 0 ); m_loc = Location(*pxloc); const XmlElement* pxiloc = ele.single_child("InterfaceLocation"); if ( pxiloc != 0 ) { const XmlElement* pxilocloc = pxiloc->single_child("Location"); assert( pxilocloc != 0 ); m_iloc = Location(*pxilocloc); } } else if ( m_loc_storage == ABSENT ) { } else if ( m_loc_storage == COMPOSITE ) { m_loc = Location(composite_location_error()); } else if ( m_loc_storage == IMPLICIT ) { } else { assert(false); } // Extra XML. const XmlElement* pxtra = ele.single_child("ExtraData"); if ( pxtra != 0 ) { m_pxxml = new XmlElement(*pxtra); m_manage_xxml = true; } // Lock the dataset. lock(); if ( ! is_locked() ) set_invalid(); } //********************************************************************** // Destructor. GenericDataset::~GenericDataset() { if ( m_manage_xxml ) { delete m_pxxml; } } //********************************************************************** // Inherited const methods. //********************************************************************** // Full type. string GenericDataset::fulltype() const { return m_fulltype; } //********************************************************************** // Validity. bool GenericDataset::is_valid() const { return m_error == 0; } //********************************************************************** // Error. int GenericDataset::error() const { return m_error; } //********************************************************************** // Emptiness. bool GenericDataset::is_empty() const { return content().is_empty(); } //********************************************************************** // Return the ID. DatasetId GenericDataset::id() const { return m_id; } //********************************************************************** // Return the parent ID. DatasetId GenericDataset::parent_id() const { return m_pid; } //********************************************************************** // Return the parent. const Dataset* GenericDataset::parent() const { // If parent is not evaluated , try to create it. if ( m_parent==0 && m_pid.is_valid() ) { DatasetRepository& rep = DatasetRepository::default_instance(); m_parent = rep.extract(m_pid); } return m_parent; } //********************************************************************** // Return the owner. string GenericDataset::owner() const { return m_owner; } //********************************************************************** // Return the create time. Time GenericDataset::create_time() const { return m_create_time; } //********************************************************************** // Return the lock status. bool GenericDataset::is_locked() const { return m_locked; } //********************************************************************** // Return the content. const Content& GenericDataset::content() const { if ( m_con.error() == composite_content_error() ) { m_con = Content(); const DatasetList& dsts = constituents(); for ( DatasetList::const_iterator idst=dsts.begin(); idst!=dsts.end(); ++idst ) { const Dataset* pdst = *idst; if ( pdst == 0 ) { m_con = Content(41); break; } m_con.push_back(pdst->content()); } } return m_con; } //********************************************************************** // Is virtual. bool GenericDataset::is_virtual() const { return m_loc_storage == ABSENT; } //********************************************************************** // Return the location. const Location& GenericDataset::location() const { if ( m_loc.error() == composite_location_error() ) { m_loc = Location(); m_iloc = Location(); const DatasetList& dsts = constituents(); for ( DatasetList::const_iterator idst=dsts.begin(); idst!=dsts.end(); ++idst ) { const Dataset* pdst = *idst; if ( pdst == 0 ) { m_loc = Location(41); m_iloc = Location(41); break; } m_loc.add(pdst->location()); m_iloc.add(pdst->interface_location()); } } return m_loc; } //********************************************************************** // Return the interface location. const Location& GenericDataset::interface_location() const { if ( m_iloc.error() == composite_location_error() ) { location(); } if ( m_iloc.is_empty() ) { return m_loc; } return m_iloc; } //********************************************************************** // Is event dataset. bool GenericDataset::is_event_dataset() const { return m_evstate != EVNONE; } //********************************************************************** // Event count. EventIdList::size_type GenericDataset::event_count() const { switch (m_evstate) { case EVNONE: return 0; case EVFIRST: return content().front().event_count(); default: assert( false ); } return 0; } //********************************************************************** // Event list. const EventIdList& GenericDataset::event_ids() const { static EventIdList empty; switch (m_evstate) { case EVNONE: return empty; case EVFIRST: return content().front().event_ids(); default: assert( false ); } return empty; } //********************************************************************** // Return the constituent datastet ID's. const DatasetIdList& GenericDataset::constituent_ids() const { return m_dids; } //********************************************************************** // Return the constituent datasets. const DatasetList& GenericDataset::constituents() const { // Evaluate constituents if absent. DatasetRepository& rep = DatasetRepository::default_instance(); if ( m_dsts.size()==0 && m_dids.size() ) { rep.extract(m_dids, m_dsts); } return m_dsts; } //********************************************************************** // Clone. GenericDataset* GenericDataset::clone(std::string) const { if ( ! is_valid() ) return 0; if ( ! is_locked() ) return 0; GenericDataset* pgen = new GenericDataset(*this); pgen->m_locked = false; pgen->m_id = DatasetId(); pgen->m_pid = DatasetId(); pgen->m_parent = 0; int chk = pgen->set_id(); chk += pgen->set_parent(*this); if ( chk ) { delete pgen; return 0; } const GenericDataset* pdst = promote(*pgen); if ( pdst == 0 ) return pgen; delete pgen; return const_cast(pdst); } //********************************************************************** // Release. int GenericDataset::release() const { int stat = 0; if ( m_dsts.size() ) { for ( DatasetList::const_iterator idst = m_dsts.begin(); idst!= m_dsts.end(); ++idst ) { assert( *idst != 0 ); const Dataset& dst = **idst; int newstat = dst.release(); if ( newstat != 0 && stat == 0 ) stat = newstat; } } return stat; } //********************************************************************** // Memory size. size_t GenericDataset::memsize() const { size_t mem = 0; mem += sizeof(m_fulltype); // Expect small # types. mem += sizeof(m_error); mem += sizeof(m_id); mem += sizeof(m_pid); mem += sizeof(m_parent); mem += sizeof(m_con_storage); mem += sizeof(m_loc_storage); mem += sizeof(m_evstate); mem += m_con.memsize(); mem += m_loc.memsize(); mem += m_iloc.memsize(); mem += memsize_multiset(m_dids); mem += memsize_vector(m_dsts); mem += sizeof(m_pxxml); if ( m_manage_xxml ) { mem += m_pxxml->memsize(); } mem += sizeof(m_manage_xxml); return mem; } //********************************************************************** // Return XML representation. const XmlElement* GenericDataset::xml() const { if ( ! is_valid() ) { cerr << "Dataset::xml: Dataset is invalid" << endl; return 0; } if ( ! id().is_global() ) { cerr << "Dataset::xml: ID is not globa" << endl; return 0; } if ( owner().size() == 0 ) { cerr << "Dataset::xml: Owner is not defined" << endl; return 0; } if ( create_time() == 0 && owner() != "unknown" ) { cerr << "Dataset::xml: Create time is not defined" << endl; return 0; } if ( ! is_locked() ) { cerr << "Dataset::xml: Dataset is not locked" << endl; return 0; } XmlElement* pele = new XmlElement(xml_name()); pele->add_attribute("fulltype", fulltype()); pele->add_attribute("id", id().to_string()); pele->add_attribute("owner", owner()); pele->add_attribute_as_int("create_time", create_time()); if ( parent_id().is_valid() ) { pele->add_attribute("parent", parent_id().to_string()); } pele->add_attribute("cstorage", sstate_to_string(m_con_storage)); pele->add_attribute("lstorage", sstate_to_string(m_loc_storage)); pele->add_attribute("evstate", evstate_to_string(m_evstate)); pele->add_attribute("id", id().to_string()); if ( content_storage_state() == EXPLICIT ) { const XmlElement* pxcon = content().xml(); if ( pxcon == 0 ) { delete pele; return 0; } pele->add_child(pxcon); } if ( location_storage_state() == EXPLICIT ) { const XmlElement* pxloc = location().xml(); if ( pxloc == 0 ) { delete pele; return 0; } pele->add_child(pxloc); if ( interface_location() != location() ) { const XmlElement* pxloc = interface_location().xml(); if ( pxloc == 0 ) { delete pele; return 0; } XmlElement* pxiloc = new XmlElement("InterfaceLocation"); pxiloc->add_child(pxloc); pele->add_child(pxiloc); } } if ( constituent_ids().size() ) { const XmlElement* pxdst = constituent_ids().xml(); if ( pxdst == 0 ) { delete pele; return 0; } pele->add_child(pxdst); } const XmlElement* pxtra = create_extra_xml(); if ( pxtra != 0 ) { string xtype = pxtra->name(); if ( xtype == "ExtraData" ) { pele->add_child(pxtra); } else { cerr << "GenericDataset::xml: Inavlid extra data type: " << xtype << endl; delete pxtra; } } return pele; } //********************************************************************** // Inherited non-const methods. //********************************************************************** // Lock. int GenericDataset::lock() { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( ! fulltype().size() ) return 3; if ( ! m_id.is_valid() ) return 4; if ( m_con_storage == UNDEFINED ) return 5; if ( m_loc_storage == UNDEFINED ) return 6; if ( m_evstate == EVUNDEF ) return 7; m_locked = true; return 0; } //********************************************************************** // Set the ID. int GenericDataset::set_id(const DatasetId& newid) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( !is_locked() && !id().is_global() && newid.is_valid() ) { m_id = newid; return 0; } return 3; } //********************************************************************** // Set parent ID. int GenericDataset::set_parent_id(const DatasetId& id) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; m_pid = id; m_parent = 0; return 0; } //********************************************************************** // Set the parent. int GenericDataset::set_parent(const Dataset& dst) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; if ( ! dst.is_valid() ) return 3; if ( ! dst.is_locked() ) return 4; if ( ! dst.id().is_valid() ) return 5; m_parent = &dst; m_pid = m_parent->id(); return 0; } //********************************************************************** // Merge. int GenericDataset::merge(const Dataset&, string) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; cerr << "GenericDataset: Attempt to merge generic dataset fails" << endl; return 999; } //********************************************************************** // Select. // Implement this once selection is added to Content. int GenericDataset::select(const Content&) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; return 999; } //********************************************************************** // Select events. // Implement this once selection is added to Content. int GenericDataset::select_events(const EventIdList&) { if ( ! is_valid() ) return 1; if ( is_locked() ) return 2; return 999; } //**********************************************************************