Commit 174b23aa authored by David Thompson's avatar David Thompson
Browse files

Implement simple attribute query filtering.

parent d0d9d984
......@@ -894,10 +894,33 @@ smtk::resource::ComponentPtr Resource::find(const smtk::common::UUID& attId) con
}
std::function<bool(const smtk::resource::ComponentPtr&)> Resource::queryOperation(
const std::string&) const
const std::string& filter) const
{
// TODO: fill me in!
return [](const smtk::resource::ComponentPtr&) { return true; };
if (filter.empty() || filter == "any" || filter == "*")
{
return [](const smtk::resource::ComponentPtr&) { return true; };
}
const std::string attributeFilter("attribute");
if (!filter.compare(0, attributeFilter.size(), attributeFilter))
{
std::string spec = filter.substr(attributeFilter.size());
const std::string definitionFilter("[type='");
auto sszm2 = spec.size() - 2;
auto dfsz = definitionFilter.size();
if (!spec.compare(0, dfsz, definitionFilter) && spec.substr(sszm2) == "']")
{
const std::string sdef = spec.substr(dfsz, sszm2 - dfsz);
smtk::attribute::DefinitionPtr defn = this->findDefinition(sdef);
if (defn)
{
return [defn](const smtk::resource::ComponentPtr& comp) {
auto attr = std::dynamic_pointer_cast<Attribute>(comp);
return (attr && attr->isA(defn));
};
}
}
}
return [](const smtk::resource::ComponentPtr&) { return false; };
}
// visit all components in the resource.
......
......@@ -39,6 +39,14 @@ namespace attribute
class Attribute;
class Definition;
/**\brief Store information about attribute definitions and instances.
*
* This subclass of smtk::resource::Resource holds attribute data.
* The file contains at least a schema (definitions and item-definitions)
* but may also contain attribute instances that conform to the schema
* as well as information about how to present the attribute system
* through a series of views.
*/
class SMTKCORE_EXPORT Resource
: public smtk::resource::DerivedFrom<Resource, smtk::resource::Resource>
{
......@@ -89,8 +97,19 @@ public:
// given a resource component's UUID, return the resource component.
smtk::resource::ComponentPtr find(const smtk::common::UUID& id) const override;
// given a std::string describing a query, return a functor for performing the
// query.
/**\brief Given a std::string describing a query, return a functor for performing the query.
*
* Currently, the query string must be either empty, `*`, `any`, or of the form
* `attribute[type='xxx']`, where `xxx` specifies the name of a definition that
* the resulting attributes instantiate.
* Note that if an attribute type `xxx` is provided, any attribute whose
* definition inherits from `xxx` as a base will be included, not just
* those whose immediate, concrete type is `xxx`.
*
* If the query string filters attributes by their definition types, note that
* the definition must exist at the time that queryOperation() is called.
* This requirement allows faster repeated evaluation of the query.
*/
std::function<bool(const smtk::resource::ComponentPtr&)> queryOperation(
const std::string&) const override;
......
......@@ -31,6 +31,7 @@ set(smtkAttributePythonDataTests
)
set(smtkAttributePythonNewDataTests
attributeItemByPath
attributeQuery
)
if (SMTK_DATA_DIR)
......
import sys
#=============================================================================
#
# Copyright (c) Kitware, Inc.
# All rights reserved.
# See LICENSE.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the above copyright notice for more information.
#
#=============================================================================
import smtk
from smtk import attribute
from smtk import io
import smtk.testing
import os
class TestAttributeQuery(smtk.testing.TestCase):
def setUp(self):
if smtk.testing.DATA_DIR == '':
self.skipTest('SMTK test-data directory not provided')
self.resource = smtk.attribute.Resource.create()
logger = smtk.io.Logger()
reader = smtk.io.AttributeReader()
filenm = os.path.join(smtk.testing.DATA_DIR, 'attribute',
'attribute_collection', 'HydraTemplateV1.sbt')
status = reader.read(self.resource, filenm, logger)
print(
'\n'.join([logger.record(i).message for i in range(logger.numberOfRecords())]))
self.assertFalse(status, 'Could not read {fn}'.format(fn=filenm))
att = self.resource.createAttribute('hydrostat')
att = self.resource.createAttribute('BasicTurbulenceModel')
att = self.resource.createAttribute('InitialConditions')
att = self.resource.createAttribute('ppesolver')
def testQueryAny(self):
attrs = self.resource.find('any')
for aa in attrs:
print('Found %s of type %s' % (aa.name(), aa.type()))
self.assertEqual(
len(attrs), 4, 'Expected 4 attributes, got %d.' % len(attrs))
def testQueryByDefinition(self):
attrs = self.resource.find("attribute[type='hydrostat']")
self.assertEqual(
len(attrs), 1, 'Expected 1 attributes, got %d.' % len(attrs))
attr = attrs.pop()
self.assertEqual(attr.type(), 'hydrostat',
'Unexpected attribute type "%s"' % attr.type())
if __name__ == '__main__':
smtk.testing.process_arguments()
smtk.testing.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment