Commit 93b80096 authored by Bob Obara's avatar Bob Obara Committed by Kitware Robot
Browse files

Merge topic 'refactoringReferenceItem'

915f00e4

 ENH: Refactoring ReferenceItem, ComponentItem, and ResourceItem

Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: T.J. Corona's avatarT.J. Corona <tj.corona@kitware.com>
Merge-request: !2034
parents fe07830c 915f00e4
......@@ -111,3 +111,12 @@ Added a class for utility methods. The current ones include:
* associatableObjects - a method to return a set of persistent objects that can be assigned to a ReferenceItem
* checkUniquenessCondition - a method that removes resource::Components from a set based on the uniqueness constraint associated with a ComponentItem
### Changes to ReferenceItem
* Deprecated the following methods - note that the old methods are still available but will produce compiler warnings if used (C++14 feature)
* objectValue replaced by value
* setObjectValue replaced by setValue
* appendObjectValues replaced by appendValues
* setObjectValues replaced by setValues
* Added Methods
* isValueValid - the validity of the item now factors in the state of the instance. This is needed to support Unique Constraints
......@@ -14,6 +14,5 @@ Now PhraseContent and DescriptivePhrase classes learn the ability
to get the undecoratedContent directly via undecoratedContent()
function.
## ComponentItemPhraseModel
Added a phrase model that uses the associatable objects method in the new smtk::attribute::Utilities class.
This method takes uniqueness into consideration.
## ReferenceItemPhraseModel
Added a phrase model that uses the associatable objects method in the new smtk::attribute::Utilities class. This method takes uniqueness into consideration.
## Changes to SMTK Resource
* queryOperation now returns a functor that takes in a const smtk::resource::Component& instead of a const smtk::resource::ConstComponentPtr&
......@@ -489,7 +489,7 @@ bool Attribute::associate(smtk::resource::PersistentObjectPtr obj)
}
// Did it pass the association rules?
if ((m_associatedObjects != nullptr) && m_associatedObjects->appendObjectValue(obj))
if ((m_associatedObjects != nullptr) && m_associatedObjects->appendValue(obj))
{
return true;
}
......@@ -546,8 +546,7 @@ bool Attribute::associateEntity(const smtk::model::EntityRef& entityRef)
if (res)
return res;
res =
(m_associatedObjects) ? m_associatedObjects->appendObjectValue(entityRef.component()) : false;
res = (m_associatedObjects) ? m_associatedObjects->appendValue(entityRef.component()) : false;
return res;
}
......
......@@ -121,13 +121,13 @@ set(attributeHeaders
StringItemDefinition.h
Tag.h
UnsetValueError.h
Utilities.h
ValueItem.h
ValueItemDefinition.h
ValueItemDefinitionTemplate.h
ValueItemTemplate.h
VoidItem.h
VoidItemDefinition.h
utility/Queries.h
)
set(attributeSrcs
......@@ -165,11 +165,11 @@ set(attributeSrcs
ResourceItemDefinition.cxx
StringItem.cxx
StringItemDefinition.cxx
Utilities.cxx
ValueItem.cxx
ValueItemDefinition.cxx
VoidItem.cxx
VoidItemDefinition.cxx
utility/Queries.cxx
)
# construct operator inputs
......
......@@ -38,7 +38,7 @@ bool ComponentItem::setValue(std::size_t ii, ComponentPtr value)
{
if (this->isValueValid(ii, value))
{
return this->setObjectValue(ii, value);
return ReferenceItem::setValue(ii, value);
}
return false;
}
......@@ -58,48 +58,3 @@ std::string ComponentItem::valueAsString(std::size_t i) const
}
return str.str();
}
bool ComponentItem::isValueValid(std::size_t i, const ComponentPtr entity) const
{
// is the size valid
if (i >= this->numberOfValues())
{
return false;
}
if (entity == nullptr)
{
// This value is always valid
return true;
}
// Lets test its definition
auto def = this->definitionAs<ComponentItemDefinition>();
if (!def->isValueValid(entity))
{
return false;
}
// Is this the current value
if (this->isSet(i) && (this->value(i) == entity))
{
return true;
}
// Else we need to check to see if its role is unique
auto att = m_referencedAttribute.lock();
if (att == nullptr)
{
return false;
}
auto attRes = att->attributeResource();
if (attRes == nullptr)
{
return false;
}
if (!attRes->isRoleUnique(def->role()))
{
return true;
}
return (attRes->findAttribute(entity, def->role()) == nullptr);
}
......@@ -54,13 +54,10 @@ public:
/// Return the type of storage used by the item.
Item::Type type() const override;
virtual bool isValueValid(std::size_t ii, const ComponentPtr entity) const;
bool isValueValid(const ComponentPtr entity) const { return this->isValueValid(0, entity); }
/// Return the \a i-th value as a component.
ComponentPtr value(std::size_t ii = 0) const
{
return std::dynamic_pointer_cast<Component>(this->objectValue(ii));
return std::dynamic_pointer_cast<Component>(ReferenceItem::value(ii));
}
/// Set the \a i-th value as a component.
......@@ -70,9 +67,9 @@ public:
/**\brief Append a value to the item if possible.
*
* This method ensures compile-time type-safety while appendObjectValue() does not.
* This method ensures compile-time type-safety while appendValue() does not.
*/
bool appendValue(ComponentPtr value) { return this->appendObjectValue(value); }
bool appendValue(ComponentPtr value) { return ReferenceItem::appendValue(value); }
/// Serialize the \a i-th value to a string.
std::string valueAsString(std::size_t ii) const override;
......
......@@ -41,8 +41,12 @@ Item::Type ComponentItemDefinition::type() const
bool ComponentItemDefinition::isValueValid(smtk::resource::ConstPersistentObjectPtr obj) const
{
auto comp = std::dynamic_pointer_cast<const smtk::resource::Component>(obj);
return this->checkComponent(comp);
auto comp = dynamic_cast<const smtk::resource::Component*>(obj.get());
if (comp == nullptr)
{
return false;
}
return this->checkComponent(*comp);
}
smtk::attribute::ItemPtr ComponentItemDefinition::buildItem(
......
......@@ -27,11 +27,11 @@ namespace smtk
namespace attribute
{
/// Internally, ReferenceItems cache retreived PersistentObjects to speed up
/// Internally, ReferenceItems cache retrieved PersistentObjects to speed up
/// repeated calls to their contents. These PersistentObjects can be cached as
/// std::shared_ptr-s or std::weak_ptr-s as determined by the flag
/// "holdReference" in ReferenceItemDefinition. To accomplish this, we cache
/// retreived values as a variant that accepts both types.
/// retrieved values as a variant that accepts both types.
struct ReferenceItem::Cache
: std::vector<boost::variant<std::shared_ptr<smtk::resource::PersistentObject>,
std::weak_ptr<smtk::resource::PersistentObject> > >
......@@ -388,6 +388,11 @@ bool ReferenceItem::setObjectKey(std::size_t i, const smtk::attribute::Reference
}
smtk::resource::PersistentObjectPtr ReferenceItem::objectValue(std::size_t i) const
{
return this->value(i);
}
smtk::resource::PersistentObjectPtr ReferenceItem::value(std::size_t i) const
{
if (i >= static_cast<std::size_t>(m_cache->size()))
return nullptr;
......@@ -395,15 +400,15 @@ smtk::resource::PersistentObjectPtr ReferenceItem::objectValue(std::size_t i) co
auto result = boost::apply_visitor(access_reference(), (*m_cache)[i]);
if (result == nullptr)
{
result = this->objectValue(m_keys[i]);
result = this->value(m_keys[i]);
assignToCache(i, result);
}
return result;
}
bool ReferenceItem::setObjectValue(const PersistentObjectPtr& val)
bool ReferenceItem::setValue(const PersistentObjectPtr& val)
{
return this->setObjectValue(0, val);
return this->setValue(0, val);
}
ReferenceItem::Key ReferenceItem::linkTo(const PersistentObjectPtr& val)
......@@ -432,8 +437,64 @@ ReferenceItem::Key ReferenceItem::linkTo(const PersistentObjectPtr& val)
return ReferenceItem::Key();
}
bool ReferenceItem::setObjectValue(std::size_t i, const PersistentObjectPtr& val)
bool ReferenceItem::isValueValid(std::size_t i, const PersistentObjectPtr& val) const
{
// is the size valid
if (i >= this->numberOfValues())
{
return false;
}
if (val == nullptr)
{
// This value is always valid
return true;
}
// Lets test its definition
auto def = this->definitionAs<ReferenceItemDefinition>();
if (!def->isValueValid(val))
{
return false;
}
// Is this the current value
if (this->isSet(i) && (this->value(i) == val))
{
return true;
}
auto comp = std::dynamic_pointer_cast<smtk::resource::Component>(val);
if (comp == nullptr)
{
return true;
}
// Else we need to check to see if its role is unique - this is currently supported
// for resource component
auto att = m_referencedAttribute.lock();
if (att == nullptr)
{
return false;
}
auto attRes = att->attributeResource();
if (attRes == nullptr)
{
return false;
}
if (!attRes->isRoleUnique(def->role()))
{
return true;
}
return (attRes->findAttribute(comp, def->role()) == nullptr);
}
bool ReferenceItem::setValue(std::size_t i, const PersistentObjectPtr& val)
{
if (!this->isValueValid(i, val))
{
return false;
}
auto def = static_cast<const ReferenceItemDefinition*>(this->definition().get());
if ((i >= m_cache->size()) || (val != nullptr && !def->isValueValid(val)))
{
......@@ -455,7 +516,7 @@ bool ReferenceItem::setObjectValue(std::size_t i, const PersistentObjectPtr& val
return true;
}
bool ReferenceItem::appendObjectValue(const PersistentObjectPtr& val)
bool ReferenceItem::appendValue(const PersistentObjectPtr& val)
{
// First - is this value valid?
auto def = static_cast<const ReferenceItemDefinition*>(this->definition().get());
......@@ -469,7 +530,7 @@ bool ReferenceItem::appendObjectValue(const PersistentObjectPtr& val)
bool foundEmpty = false;
for (std::size_t i = 0; i < n; ++i)
{
if (this->isSet(i) && (this->objectValue(i) == val))
if (this->isSet(i) && (this->value(i) == val))
{
return true;
}
......@@ -482,7 +543,7 @@ bool ReferenceItem::appendObjectValue(const PersistentObjectPtr& val)
// If not, was there a space available?
if (foundEmpty)
{
return this->setObjectValue(emptyIndex, val);
return this->setValue(emptyIndex, val);
}
// Finally - are we allowed to change the number of values?
if ((def->isExtensible() && def->maxNumberOfValues() &&
......@@ -578,7 +639,7 @@ std::string ReferenceItem::valueAsString() const
std::string ReferenceItem::valueAsString(std::size_t i) const
{
std::ostringstream result;
auto entry = this->objectValue(i);
auto entry = this->value(i);
smtk::resource::ResourcePtr rsrc;
smtk::resource::ComponentPtr comp;
if ((rsrc = std::dynamic_pointer_cast<smtk::resource::Resource>(entry)))
......@@ -605,7 +666,7 @@ bool ReferenceItem::isSet(std::size_t i) const
void ReferenceItem::unset(std::size_t i)
{
this->setObjectValue(i, PersistentObjectPtr());
this->setValue(i, PersistentObjectPtr());
}
bool ReferenceItem::assign(ConstItemPtr& sourceItem, unsigned int options)
......@@ -629,8 +690,8 @@ bool ReferenceItem::assign(ConstItemPtr& sourceItem, unsigned int options)
{
if (sourceReferenceItem->isSet(i))
{
auto val = sourceReferenceItem->objectValue(i);
this->setObjectValue(i, val);
auto val = sourceReferenceItem->value(i);
this->setValue(i, val);
}
else
{
......@@ -736,7 +797,7 @@ bool ReferenceItem::setDefinition(smtk::attribute::ConstItemDefinitionPtr adef)
return true;
}
smtk::resource::PersistentObjectPtr ReferenceItem::objectValue(const ReferenceItem::Key& key) const
smtk::resource::PersistentObjectPtr ReferenceItem::value(const ReferenceItem::Key& key) const
{
AttributePtr myAtt = this->m_referencedAttribute.lock();
if (myAtt == nullptr)
......@@ -799,7 +860,7 @@ bool ReferenceItem::resolve() const
(!def->holdReference() && (*key) != nullKey && myAtt->resource()->manager() != nullptr))
{
// ...set it equal to the object pointer accessed using its key.
auto newValue = this->objectValue(*key);
auto newValue = this->value(*key);
if (def->holdReference())
{
......
......@@ -197,28 +197,90 @@ public:
Key objectKey(std::size_t i = 0) const;
bool setObjectKey(std::size_t i, const Key& key);
/// Return the \a i-th component stored in this item.
PersistentObjectPtr objectValue(std::size_t i = 0) const;
/// Return the \a i-th object stored in this item.
PersistentObjectPtr value(std::size_t i = 0) const;
template <typename T>
typename T::Ptr valueAs(std::size_t i = 0) const
{
return std::dynamic_pointer_cast<T>(this->objectValue(i));
return std::dynamic_pointer_cast<T>(this->value(i));
}
/** Return the \a i-th object stored in this item.
* \deprecated This method will go away in future versions of SMTK
* See instead value(std::size_t)
*/
[[deprecated(
"ReferenceItem::objectValue has been replaced with ReferenceItem::value")]] PersistentObjectPtr
objectValue(std::size_t i = 0) const;
virtual bool isValueValid(std::size_t ii, const PersistentObjectPtr& entity) const;
bool isValueValid(const PersistentObjectPtr& entity) const
{
return this->isValueValid(0, entity);
}
/**\brief Set the component stored with this item.
*
* This always sets the 0-th item and is a convenience method
* for cases where only 1 value is needed.
*/
bool setObjectValue(const PersistentObjectPtr& val);
/// Set the \a i-th value to the given item. This method does no checking to see if \a i is valid.
//bool setObjectValue(std::size_t i, const PersistentObjectPtr& val);
bool setObjectValue(std::size_t i, const PersistentObjectPtr& val);
bool setValue(const PersistentObjectPtr& val);
/** Set the \a i-th value to the given item. This method does no checking to see if \a i is valid.
* bool setObjectValue(std::size_t i, const PersistentObjectPtr& val);
* Return the \a i-th object stored in this item.
*/
bool setValue(std::size_t i, const PersistentObjectPtr& val);
/**\brief Set the component stored with this item.
*
* This always sets the 0-th item and is a convenience method
* for cases where only 1 value is needed.
* \deprecated This method will go away in future versions of SMTK
* See instead setValue()
*/
[[deprecated(
"ReferenceItem::setObjectValue has been replaced with ReferenceItem::setValue")]] bool
setObjectValue(const PersistentObjectPtr& val)
{
return this - setValue(val);
}
/** Set the \a i-th value to the given item. This method does no checking to see if \a i is valid.
* bool setObjectValue(std::size_t i, const PersistentObjectPtr& val);
* Return the \a i-th object stored in this item.
* \deprecated This method will go away in future versions of SMTK
* See instead setValue(std::size_t, const PersistentObjectPtr&)
*/
[[deprecated(
"ReferenceItem::setObjectValue has been replaced with ReferenceItem::setValue")]] bool
setObjectValue(std::size_t i, const PersistentObjectPtr& val)
{
return this->setValue(i, val);
}
[[deprecated(
"ReferenceItem::appendObjectValue has been replaced with ReferenceItem::appendValue")]] bool
appendObjectValue(const PersistentObjectPtr& val)
{
return this->appendValue(val);
}
template <typename I>
bool setObjectValues(
I vbegin, I vend, typename std::iterator_traits<I>::difference_type offset = 0);
bool setValues(I vbegin, I vend, typename std::iterator_traits<I>::difference_type offset = 0);
template <typename I>
bool appendValues(I vbegin, I vend);
template <typename I>
bool appendObjectValues(I vbegin, I vend);
[[deprecated(
"ReferenceItem::setObjectValues has been replaced with ReferenceItem::setValues")]] bool
setObjectValues(I vbegin, I vend, typename std::iterator_traits<I>::difference_type offset = 0)
{
return this->setValues<I>(vbegin, vend, offset);
}
template <typename I>
[[deprecated(
"ReferenceItem::appendObjectValues has been replaced with ReferenceItem::appendValues")]] bool
appendObjectValues(I vbegin, I vend)
{
return this->appendValues<I>(vbegin, vend);
}
template <typename I, typename T>
bool setValuesVia(I vbegin, I vend, const T& converter,
......@@ -234,7 +296,7 @@ public:
* if there is an unset value anywhere in the allocated array, that will
* be preferred to reallocation.
*/
bool appendObjectValue(const PersistentObjectPtr& val);
bool appendValue(const PersistentObjectPtr& val);
/**\brief Remove the value at the \a i-th location.
*
* If the number of values may not be changed, then the \a i-th
......@@ -313,7 +375,7 @@ protected:
bool setDefinition(smtk::attribute::ConstItemDefinitionPtr def) override;
/// Return the object stored in this item associated with \a key.
PersistentObjectPtr objectValue(const ReferenceItem::Key& key) const;
PersistentObjectPtr value(const ReferenceItem::Key& key) const;
/// Resolve the object pointers by accessing them using their associated keys.
/// Return true if all object pointers were successfully resolved.
......@@ -353,7 +415,7 @@ SMTKCORE_EXPORT bool ReferenceItem::iteratorIsSet<ReferenceItem::const_iterator>
const ReferenceItem::const_iterator& iterator) const;
template <typename I>
bool ReferenceItem::setObjectValues(
bool ReferenceItem::setValues(
I vbegin, I vend, typename std::iterator_traits<I>::difference_type offset)
{
bool ok = false;
......@@ -369,7 +431,7 @@ bool ReferenceItem::setObjectValues(
continue;
}
if (!this->setObjectValue(offset + i, *it))
if (!this->setValue(offset + i, *it))
{
ok = false;
break;
......@@ -385,9 +447,9 @@ bool ReferenceItem::setObjectValues(
}
template <typename I>
bool ReferenceItem::appendObjectValues(I vbegin, I vend)
bool ReferenceItem::appendValues(I vbegin, I vend)
{
return this->setObjectValues(vbegin, vend, this->numberOfValues());
return this->setValues(vbegin, vend, this->numberOfValues());
}
template <typename I, typename T>
......@@ -407,7 +469,7 @@ bool ReferenceItem::setValuesVia(
continue;
}
if (!this->setObjectValue(offset + i, converter(*it)))
if (!this->setValue(offset + i, converter(*it)))
{
ok = false;
break;
......
......@@ -76,15 +76,15 @@ bool ReferenceItemDefinition::isValueValid(resource::ConstPersistentObjectPtr en
return ok;
}
smtk::resource::ConstResourcePtr rsrc;
smtk::resource::ConstComponentPtr comp;
if ((rsrc = std::dynamic_pointer_cast<const smtk::resource::Resource>(entity)))
const smtk::resource::Resource* rsrc;
const smtk::resource::Component* comp;
if ((rsrc = dynamic_cast<const smtk::resource::Resource*>(entity.get())))
{
ok = this->checkResource(rsrc);
ok = this->checkResource(*rsrc);
}
else if ((comp = std::dynamic_pointer_cast<const smtk::resource::Component>(entity)))
else if ((comp = dynamic_cast<const smtk::resource::Component*>(entity.get())))
{
ok = this->checkComponent(comp);
ok = this->checkComponent(*comp);
}
return ok;
}
......@@ -209,14 +209,8 @@ void ReferenceItemDefinition::copyTo(Ptr dest) const
}
}
bool ReferenceItemDefinition::checkResource(smtk::resource::ConstResourcePtr rsrc) const
bool ReferenceItemDefinition::checkResource(const smtk::resource::Resource& rsrc) const
{
// If the resource is invalid, then no filtering is needed.
if (!rsrc)
{
return false;
}
// If there are no filter values, then we accept all resources.
if (m_acceptable.empty())
{
......@@ -237,7 +231,7 @@ bool ReferenceItemDefinition::checkResource(smtk::resource::ConstResourcePtr rsr
// ...we check if the resource in question is of that type. Acceptable
// entries for resources do not have a filter string, so we check that
// the filter string is empty.
if ((acceptable.second.empty() || m_onlyResources) && rsrc->isOfType(acceptable.first))
if ((acceptable.second.empty() || m_onlyResources) && rsrc.isOfType(acceptable.first))
{
return true;
}
......@@ -246,16 +240,10 @@ bool ReferenceItemDefinition::checkResource(smtk::resource::ConstResourcePtr rsr
return false;
}
bool ReferenceItemDefinition::checkComponent(smtk::resource::ConstComponentPtr comp) const
bool ReferenceItemDefinition::checkComponent(const smtk::resource::Component& comp) const
{
// If the component is invalid, then no filtering is needed.
if (!comp)
{
return false;
}
// All components are required to have resources in order to be valid.
auto rsrc = comp->resource();
auto rsrc = comp.resource();
if (!rsrc)
{
return false;
......
......@@ -130,9 +130,9 @@ protected:
void copyTo(Ptr dst) const;
/// Return whether a resource is accepted by this definition. Used internally by isValueValid().
bool checkResource(smtk::resource::ConstResourcePtr rsrc) const;
bool checkResource(const smtk::resource::Resource& rsrc) const;
/// Return whether a component is accepted by this definition. Used internally by isValueValid().
bool checkComponent(smtk::resource::ConstComponentPtr comp) const;
bool checkComponent(const smtk::resource::Component& comp) const;
bool m_useCommonLabel;
std::vector<std::string> m_valueLabels;
......
......@@ -919,12 +919,12 @@ std::string Resource::createAttributeQuery(const std::string& defType)
return s;
}
std::function<bool(const smtk::resource::ConstComponentPtr&)> Resource::queryOperation(
std::function<bool(const smtk::resource::Component&)> Resource::queryOperation(
const std::string& filter) const
{
if (filter.empty() || filter == "any" || filter == "*")
{
return [](const smtk::resource::ConstComponentPtr& /*unused*/) { return true; };
return [](const smtk::resource::Component& /*unused*/) { return true; };
}