Skip to content

Commit

Permalink
Remove Workspace::setName method
Browse files Browse the repository at this point in the history
The name is now a pure lookup into the ADS. The rename/remove methods
no longer need to be overloaded in the ADS so have been removed. The
add/addOrReplace are still required for the additional WorkspaceGroup
behaviour.
The add/addOrReplace methods have been refactored and a bug fixed where
the name on the workspace could be updated even if the DataService method
was going to throw.
Refs #6187
  • Loading branch information
martyngigg committed Aug 6, 2013
1 parent fcdb1b5 commit fcf4731
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 207 deletions.
8 changes: 2 additions & 6 deletions Code/Mantid/Framework/API/inc/MantidAPI/AnalysisDataService.h
Expand Up @@ -110,10 +110,6 @@ class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Worksp
virtual void add( const std::string& name, const boost::shared_ptr<API::Workspace>& workspace);
/// Overridden addOrReplace member to attach the name to the workspace when a workspace object is added to the service
virtual void addOrReplace( const std::string& name, const boost::shared_ptr<API::Workspace>& workspace);
/// Overridden rename member to attach the new name to the workspace when a workspace object is renamed
virtual void rename( const std::string& oldName, const std::string& newName);
/// Overridden remove member to delete its name held by the workspace itself
virtual void remove( const std::string& name);

/** Retrieve a workspace and cast it to the given WSTYPE
*
Expand All @@ -132,11 +128,9 @@ class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Worksp

/** @name Methods to work with workspace groups */
//@{

void addToGroup(const std::string& groupName, const std::string& wsName);
void deepRemoveGroup(const std::string& name);
void removeFromGroup(const std::string& groupName, const std::string& wsName);

//@}

/// Create an info tree out of InfoNodes to describe the current state of the ADS.
Expand All @@ -145,6 +139,8 @@ class DLLExport AnalysisDataServiceImpl : public Kernel::DataService<API::Worksp
private:
/// Checks the name is valid, throwing if not
void verifyName(const std::string & name);
/// Add workspace to the service with the given name
void addToService(const std::string &name, const boost::shared_ptr<API::Workspace> & ws, const bool replace);

friend struct Mantid::Kernel::CreateUsingNew<AnalysisDataServiceImpl>;
/// Constructor
Expand Down
19 changes: 6 additions & 13 deletions Code/Mantid/Framework/API/inc/MantidAPI/Workspace.h
Expand Up @@ -7,7 +7,6 @@
#include "MantidKernel/DataItem.h"
#include "MantidAPI/WorkspaceHistory.h"
#include "MantidAPI/DllConfig.h"
#include "MantidKernel/Exception.h"

namespace Mantid
{
Expand All @@ -25,7 +24,6 @@ namespace API
//----------------------------------------------------------------------
// Forward Declaration
//----------------------------------------------------------------------
class AnalysisDataServiceImpl;

/** Base Workspace Abstract Class.
Expand Down Expand Up @@ -65,10 +63,10 @@ class MANTID_API_DLL Workspace : public Kernel::DataItem
{
public:
enum IconType {Default = 0, Matrix, Group, MD, Table};
/// Default constructor
InfoNode();
/// Constructor
InfoNode(const Workspace& workspace);
/// Constructor
InfoNode(const AnalysisDataServiceImpl*);
/// Destructor
~InfoNode();
/// Add a new line
Expand Down Expand Up @@ -105,8 +103,8 @@ class MANTID_API_DLL Workspace : public Kernel::DataItem
virtual ~Workspace();

// DataItem interface
/// Name
virtual const std::string name() const { return this->getName(); }
/// Returns a string giving the name of the workspace if it has been stored in the ADS
virtual const std::string name() const;
/** Marks the workspace as safe for multiple threads to edit data simutaneously.
* Workspace creation is always considered to be a single threaded operation.
* @return true if the workspace is suitable for multithreaded operations, otherwise false.
Expand All @@ -119,7 +117,8 @@ class MANTID_API_DLL Workspace : public Kernel::DataItem
void setComment(const std::string&);
virtual const std::string getTitle() const;
const std::string& getComment() const;
const std::string& getName() const;
/// Here for backwards-compatability with old code
const std::string getName() const;
bool isDirty(const int n=1) const;
/// Get the footprint in memory in bytes.
virtual size_t getMemorySize() const = 0;
Expand All @@ -137,18 +136,12 @@ class MANTID_API_DLL Workspace : public Kernel::DataItem
virtual InfoNode* createInfoNode() const;

private:
void setName(const std::string&);
/// The title of the workspace
std::string m_title;
/// A user-provided comment that is attached to the workspace
std::string m_comment;
/// The name associated with the object within the ADS (This is required for workspace algebra
std::string m_name;
/// The history of the workspace, algorithm and environment
WorkspaceHistory m_history;

friend class AnalysisDataServiceImpl;

};


Expand Down
15 changes: 8 additions & 7 deletions Code/Mantid/Framework/API/inc/MantidAPI/WorkspaceGroup.h
Expand Up @@ -68,21 +68,20 @@ class MANTID_API_DLL WorkspaceGroup : public Workspace
/// The collection itself is considered to take up no space
virtual size_t getMemorySize() const { return 0; }
/// Adds a workspace to the group.
void addWorkspace(Workspace_sptr workspace);
void addWorkspace(const Workspace_sptr & workspace);
/// Return the number of entries within the group
int getNumberOfEntries() const { return static_cast<int>(this->size()); }
/// Return the size of the group, so it is more like a container
size_t size() const { return m_workspaces.size(); }
/// Return the ith workspace
Workspace_sptr getItem(const size_t index) const;
/// Return the workspace by name
Workspace_sptr getItem(const std::string wsName) const;
/// Remove a workspace from the group
void removeItem(const size_t index);
/// Remove all names from the group but do not touch the ADS
Workspace_sptr getItem(const std::string &wsName) const;
/// Drop all of the references to the workspaces contained within this group
void removeAll();
/// This method returns true if the group is empty (no member workspace)
bool isEmpty() const;
/// Returns true all of the names have the same prefix
bool areNamesSimilar() const;
/// Inidicates that the workspace group can be treated as multiperiod.
bool isMultiperiod() const;
Expand Down Expand Up @@ -116,14 +115,16 @@ class MANTID_API_DLL WorkspaceGroup : public Workspace
const WorkspaceGroup& operator=(const WorkspaceGroup&);
/// ADS removes a member of this group using this method. It doesn't send notifications in contrast to remove(name).
void removeByADS(const std::string& name);
/// Remove a given pointer from the group
void removeItem(const Workspace_sptr & object);
/// Turn ADS observations on/off
void observeADSNotifications(const bool observeADS);
/// Check if a workspace is included in any child groups and groups in them.
bool isInChildGroup( const Workspace& workspace ) const;
/// Callback when a delete notification is received
void workspaceDeleteHandle(Mantid::API::WorkspacePostDeleteNotification_ptr notice);
void workspaceDeleteHandle(Mantid::API::WorkspacePreDeleteNotification_ptr notice);
/// Observer for workspace delete notfications
Poco::NObserver<WorkspaceGroup, Mantid::API::WorkspacePostDeleteNotification> m_deleteObserver;
Poco::NObserver<WorkspaceGroup, Mantid::API::WorkspacePreDeleteNotification> m_deleteObserver;
/// Callback when a before-replace notification is received
void workspaceReplaceHandle(Mantid::API::WorkspaceBeforeReplaceNotification_ptr notice);
/// Observer for workspace before-replace notfications
Expand Down
133 changes: 37 additions & 96 deletions Code/Mantid/Framework/API/src/AnalysisDataService.cpp
Expand Up @@ -55,117 +55,28 @@ namespace Mantid
}

/**
* Overwridden add member to attach the name to the workspace when a workspace object is added to the service
* Overridden add member to attach the name to the workspace when a workspace object is added to the service
* If the name already exists then this throws a std::runtime_error. If a workspace group is added adds the
* members which are not in the ADS yet.
* @param name The name of the object
* @param workspace The shared pointer to the workspace to store
*/
void AnalysisDataServiceImpl::add( const std::string& name, const boost::shared_ptr<API::Workspace>& workspace)
{
verifyName(name);
//Attach the name to the workspace
if( workspace ) workspace->setName(name);
Kernel::DataService<API::Workspace>::add(name, workspace);

// if a group is added add its members as well
auto group = boost::dynamic_pointer_cast<WorkspaceGroup>( workspace );
if ( !group ) return;
group->observeADSNotifications( true );
for(size_t i = 0; i < group->size(); ++i)
{
auto ws = group->getItem( i );
std::string wsName = ws->name();
// if anonymous make up a name and add
if ( wsName.empty() )
{
wsName = name + "_" + boost::lexical_cast<std::string>( i + 1 );
}
else if ( doesExist( wsName ) )
{// if ws is already there do nothing
wsName.clear();
}
// add member workspace if needed
if ( !wsName.empty() )
{
add( wsName, ws );
}
}
const bool replaceWS(false);
addToService(name, workspace, replaceWS);
}

/**
* Overwridden addOrReplace member to attach the name to the workspace when a workspace object is added to the service.
* Overridden addOrReplace member to attach the name to the workspace when a workspace object is added to the service.
* This will overwrite one of the same name. If the workspace is group adds or replaces its members.
* @param name The name of the object
* @param workspace The shared pointer to the workspace to store
*/
void AnalysisDataServiceImpl::addOrReplace( const std::string& name, const boost::shared_ptr<API::Workspace>& workspace)
{
verifyName(name);

//Attach the name to the workspace
if( workspace ) workspace->setName(name);
Kernel::DataService<API::Workspace>::addOrReplace(name, workspace);

// if a group is added add its members as well
auto group = boost::dynamic_pointer_cast<WorkspaceGroup>( workspace );
if ( !group ) return;
group->observeADSNotifications( true );
for(size_t i = 0; i < group->size(); ++i)
{
auto ws = group->getItem( i );
std::string wsName = ws->name();
// make up a name for an anonymous workspace
if ( wsName.empty() )
{
wsName = name + "_" + boost::lexical_cast<std::string>( i + 1 );
}
else if ( doesExist( wsName ) )
{// if ws is already there do nothing
wsName.clear();
}
// add member workspace if needed
if ( !wsName.empty() )
{
addOrReplace( wsName, ws );
}
}
}

/**
* Overridden rename member to attach the new name to the workspace when a workspace object is renamed
* @param oldName The old name of the object
* @param newName The new name of the object
*/
void AnalysisDataServiceImpl::rename( const std::string& oldName, const std::string& newName)
{
Kernel::DataService<API::Workspace>::rename( oldName, newName );
//Attach the new name to the workspace
auto ws = retrieve( newName );
ws->setName( newName );
}

/**
* Overridden remove member to delete its name held by the workspace itself.
* It is important to do if the workspace isn't deleted after removal.
* @param name The name of a workspace to remove.
*/
void AnalysisDataServiceImpl::remove( const std::string& name )
{
Workspace_sptr ws;
try
{
ws = retrieve( name );
}
catch(Kernel::Exception::NotFoundError)
{
// do nothing - remove will do what's needed
}
Kernel::DataService<API::Workspace>::remove( name );
if ( ws )
{
ws->setName( "" );
}
const bool replaceWS(true);
addToService(name, workspace, replaceWS);
}

/**
Expand Down Expand Up @@ -254,7 +165,7 @@ namespace Mantid
}

// build the tree
Workspace::InfoNode *root = new Workspace::InfoNode(this);
Workspace::InfoNode *root = new Workspace::InfoNode;
for( auto ws = workspaces.begin(); ws != workspaces.end(); ++ws )
{
if ( !rootGroup.isInChildGroup(**ws) )
Expand Down Expand Up @@ -319,6 +230,36 @@ namespace Mantid
}
}

/**
* If replace=false, a group is being added & member already exists in the service then this will throw and that member will have no name
* @param name The name to attach to the workspace
* @param workspace The pointer to be added
* @param replace If true then addOrReplace is called, else just add
*/
void AnalysisDataServiceImpl::addToService(const std::string & name, const boost::shared_ptr<API::Workspace> & workspace,
const bool replace)
{
verifyName(name);
if(replace) Kernel::DataService<API::Workspace>::addOrReplace(name, workspace);
else Kernel::DataService<API::Workspace>::add(name, workspace);

// if a group is added add its members as well
auto group = boost::dynamic_pointer_cast<WorkspaceGroup>( workspace );
if ( !group ) return;
group->observeADSNotifications( true );
for(size_t i = 0; i < group->size(); ++i)
{
auto ws = group->getItem( i );
std::string wsName = ws->name();
// if anonymous make up a name and add
if ( wsName.empty() )
{
wsName = name + "_" + boost::lexical_cast<std::string>( i + 1 );
}
if(replace) addOrReplace(wsName, ws); // Always replace to be sure the object is up to date
else add(wsName, ws);
}
}

} // Namespace API
} // Namespace Mantid
Expand Down

0 comments on commit fcf4731

Please sign in to comment.