Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ResourceRetriever::getFilePath() #972

Merged
merged 8 commits into from
Feb 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

### DART 6.4.0 (201X-XX-XX)

* Common

* Added ResourceRetriever::getFilePath(): [#972](https://github.com/dartsim/dart/pull/972)

* Kinematics/Dynamics

* Added lazy evaluation for shape's volume and bounding-box computation: [#959](https://github.com/dartsim/dart/pull/959)
Expand Down
27 changes: 19 additions & 8 deletions dart/common/LocalResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,7 @@ namespace common {
//==============================================================================
bool LocalResourceRetriever::exists(const Uri& _uri)
{
// Open and close the file to check if it exists. It would be more efficient
// to stat() it, but that is not portable.
if(_uri.mScheme.get_value_or("file") != "file")
return false;
else if (!_uri.mPath)
return false;

return std::ifstream(_uri.getFilesystemPath(), std::ios::binary).good();
return !getFilePath(_uri).empty();
}

//==============================================================================
Expand All @@ -70,5 +63,23 @@ common::ResourcePtr LocalResourceRetriever::retrieve(const Uri& _uri)
return nullptr;
}

//==============================================================================
std::string LocalResourceRetriever::getFilePath(const Uri& uri)
{
// Open and close the file to check if it exists. It would be more efficient
// to stat() it, but that is not portable.
if(uri.mScheme.get_value_or("file") != "file")
return "";
else if (!uri.mPath)
return "";

const auto path = uri.getFilesystemPath();

if (std::ifstream(path, std::ios::binary).good())
return path;
else
return "";
}

} // namespace common
} // namespace dart
3 changes: 3 additions & 0 deletions dart/common/LocalResourceRetriever.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class LocalResourceRetriever : public virtual ResourceRetriever

// Documentation inherited.
ResourcePtr retrieve(const Uri& _uri) override;

// Documentation inherited.
std::string getFilePath(const Uri& uri) override;
};

using LocalResourceRetrieverPtr = std::shared_ptr<LocalResourceRetriever>;
Expand Down
6 changes: 6 additions & 0 deletions dart/common/ResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,11 @@ std::string ResourceRetriever::readAll(const Uri& uri)
return resource->readAll();
}

//==============================================================================
std::string ResourceRetriever::getFilePath(const Uri& /*uri*/)
{
return "";
}

} // namespace common
} // namespace dart
19 changes: 12 additions & 7 deletions dart/common/ResourceRetriever.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ class ResourceRetriever
public:
virtual ~ResourceRetriever() = default;

/// \brief Return whether the resource specified by a URI exists.
/// Returns whether the resource specified by a URI exists.
virtual bool exists(const Uri& _uri) = 0;

/// \brief Return the resource specified by a URI or nullptr on failure.
/// Returns the resource specified by a URI or nullptr on failure.
virtual ResourcePtr retrieve(const Uri& _uri) = 0;

/// Reads all data from the resource of uri, and returns it as a string.
Expand All @@ -61,11 +61,16 @@ class ResourceRetriever
/// \throw std::runtime_error when failed to read sucessfully.
virtual std::string readAll(const Uri& uri);

// We don't const-qualify for exists, retrieve, and readAll here. Derived
// classes of ResourceRetriever will be interacting with external resources
// that you don't necessarily have control over so we cannot guarantee that
// you get the same result every time with the same input Uri. Indeed,
// const-qualification for those functions is pointless.
/// Returns absolute file path to \c uri; an empty string if unavailable.
///
/// This base class returns an empty string by default.
virtual std::string getFilePath(const Uri& uri);

// We don't const-qualify for exists, retrieve, readAll, and getFilePath here.
// Derived classes of ResourceRetriever will be interacting with external
// resources that you don't necessarily have control over so we cannot
// guarantee that you get the same result every time with the same input Uri.
// Indeed, const-qualification for those functions is pointless.
};

using ResourceRetrieverPtr = std::shared_ptr<ResourceRetriever>;
Expand Down
13 changes: 13 additions & 0 deletions dart/utils/CompositeResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ common::ResourcePtr CompositeResourceRetriever::retrieve(
return nullptr;
}

//==============================================================================
std::string CompositeResourceRetriever::getFilePath(const common::Uri& uri)
{
for (const auto& resourceRetriever : getRetrievers(uri))
{
const auto path = resourceRetriever->getFilePath(uri);
if (!path.empty())
return path;
}

return "";
}

//==============================================================================
std::vector<common::ResourceRetrieverPtr>
CompositeResourceRetriever::getRetrievers(const common::Uri& _uri) const
Expand Down
3 changes: 3 additions & 0 deletions dart/utils/CompositeResourceRetriever.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class CompositeResourceRetriever : public virtual common::ResourceRetriever
// Documentation inherited.
common::ResourcePtr retrieve(const common::Uri& _uri) override;

// Documentation inherited.
std::string getFilePath(const common::Uri& uri) override;

private:
std::vector<common::ResourceRetrieverPtr> getRetrievers(
const common::Uri& _uri) const;
Expand Down
33 changes: 33 additions & 0 deletions dart/utils/DartResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,39 @@ common::ResourcePtr DartResourceRetriever::retrieve(const common::Uri& uri)
return nullptr;
}

//==============================================================================
std::string DartResourceRetriever::getFilePath(const common::Uri& uri)
{
std::string relativePath;
if (!resolveDataUri(uri, relativePath))
return "";

if (uri.mAuthority.get() == "sample")
{
for (const auto& dataPath : mDataDirectories)
{
common::Uri fileUri;
fileUri.fromPath(dataPath + relativePath);

const auto path = mLocalRetriever->getFilePath(fileUri);

// path is empty if the file specified by fileUri doesn't exist.
if (!path.empty())
return path;
}
}
else
{
const auto path = mLocalRetriever->getFilePath(uri);

// path is empty if the file specified by fileUri doesn't exist.
if (!path.empty())
return path;
}

return "";
}

//==============================================================================
void DartResourceRetriever::addDataDirectory(
const std::string& dataDirectory)
Expand Down
3 changes: 3 additions & 0 deletions dart/utils/DartResourceRetriever.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class DartResourceRetriever : public common::ResourceRetriever
// Documentation inherited.
common::ResourcePtr retrieve(const common::Uri& uri) override;

// Documentation inherited.
std::string getFilePath(const common::Uri& uri) override;

private:

void addDataDirectory(const std::string& packageDirectory);
Expand Down
25 changes: 24 additions & 1 deletion dart/utils/PackageResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,15 @@ bool PackageResourceRetriever::exists(const common::Uri& _uri)
if (!resolvePackageUri(_uri, packageName, relativePath))
return false;

for(const std::string& packagePath : getPackagePaths(packageName))
for (const std::string& packagePath : getPackagePaths(packageName))
{
common::Uri fileUri;
fileUri.fromPath(packagePath + relativePath);

if (mLocalRetriever->exists(fileUri))
return true;
}

return false;
}

Expand All @@ -102,6 +103,28 @@ common::ResourcePtr PackageResourceRetriever::retrieve(const common::Uri& _uri)
return nullptr;
}

//==============================================================================
std::string PackageResourceRetriever::getFilePath(const common::Uri& uri)
{
std::string packageName, relativePath;
if (!resolvePackageUri(uri, packageName, relativePath))
return "";

for(const std::string& packagePath : getPackagePaths(packageName))
{
common::Uri fileUri;
fileUri.fromPath(packagePath + relativePath);

const auto path = mLocalRetriever->getFilePath(fileUri);

// path is empty if the file specified by fileUri doesn't exist.
if (!path.empty())
return path;
}

return "";
}

//==============================================================================
const std::vector<std::string>& PackageResourceRetriever::getPackagePaths(
const std::string& _packageName) const
Expand Down
3 changes: 3 additions & 0 deletions dart/utils/PackageResourceRetriever.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class PackageResourceRetriever : public virtual common::ResourceRetriever
// Documentation inherited.
common::ResourcePtr retrieve(const common::Uri& _uri) override;

// Documentation inherited.
std::string getFilePath(const common::Uri& uri) override;

private:
common::ResourceRetrieverPtr mLocalRetriever;
std::unordered_map<std::string, std::vector<std::string> > mPackageMap;
Expand Down
14 changes: 14 additions & 0 deletions unittests/TestHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,20 @@ struct PresentResourceRetriever : public dart::common::ResourceRetriever
return true;
}

std::string getFilePath(const dart::common::Uri& _uri) override
{
mGetFilePath.push_back(_uri.toString());
return _uri.toString();
}

dart::common::ResourcePtr retrieve(const dart::common::Uri& _uri) override
{
mRetrieve.push_back(_uri.toString());
return std::make_shared<TestResource>();
}

std::vector<std::string> mExists;
std::vector<std::string> mGetFilePath;
std::vector<std::string> mRetrieve;
};

Expand All @@ -524,13 +531,20 @@ struct AbsentResourceRetriever : public dart::common::ResourceRetriever
return false;
}

std::string getFilePath(const dart::common::Uri& _uri) override
{
mGetFilePath.push_back(_uri.toString());
return "";
}

dart::common::ResourcePtr retrieve(const dart::common::Uri& _uri) override
{
mRetrieve.push_back(_uri.toString());
return nullptr;
}

std::vector<std::string> mExists;
std::vector<std::string> mGetFilePath;
std::vector<std::string> mRetrieve;
};

Expand Down
82 changes: 82 additions & 0 deletions unittests/unit/test_CompositeResourceRetriever.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,88 @@ TEST(CompositeResourceRetriever, exists_DefaultResourceRetrieverSucceeds_Returns
EXPECT_TRUE(retriever3->mRetrieve.empty());
}

TEST(CompositeResourceRetriever, getFilePath_NothingRegistered_ReturnsEmptyString)
{
CompositeResourceRetriever retriever;
EXPECT_EQ(retriever.getFilePath(Uri::createFromString("package://test/foo")), "");
}

TEST(CompositeResourceRetriever, getFilePath_AllRetrieversFail_ReturnsFalse)
{
auto retriever1 = std::make_shared<AbsentResourceRetriever>();
auto retriever2 = std::make_shared<AbsentResourceRetriever>();
CompositeResourceRetriever retriever;

EXPECT_TRUE(retriever.addSchemaRetriever("package", retriever1));
retriever.addDefaultRetriever(retriever2);

EXPECT_EQ(retriever.getFilePath(Uri::createFromString("package://test/foo")), "");

EXPECT_TRUE(retriever1->mExists.empty());
ASSERT_EQ(1u, retriever1->mGetFilePath.size());
EXPECT_EQ("package://test/foo", retriever1->mGetFilePath.front());
EXPECT_TRUE(retriever1->mRetrieve.empty());

EXPECT_TRUE(retriever2->mExists.empty());
ASSERT_EQ(1u, retriever2->mGetFilePath.size());
EXPECT_EQ("package://test/foo", retriever2->mGetFilePath.front());
EXPECT_TRUE(retriever2->mRetrieve.empty());
}

TEST(CompositeResourceRetriever, getFilePath_CompositeResourceRetrieverSucceeds_ReturnsFilePath)
{
auto retriever1 = std::make_shared<PresentResourceRetriever>();
auto retriever2 = std::make_shared<AbsentResourceRetriever>();
auto retriever3 = std::make_shared<AbsentResourceRetriever>();
CompositeResourceRetriever retriever;

EXPECT_TRUE(retriever.addSchemaRetriever("package", retriever1));
EXPECT_TRUE(retriever.addSchemaRetriever("package", retriever2));
retriever.addDefaultRetriever(retriever3);

EXPECT_EQ(retriever.getFilePath(Uri::createFromString("package://test/foo")), "package://test/foo");

EXPECT_TRUE(retriever2->mExists.empty());
ASSERT_EQ(1u, retriever1->mGetFilePath.size());
EXPECT_EQ("package://test/foo", retriever1->mGetFilePath.front());
EXPECT_TRUE(retriever1->mRetrieve.empty());

EXPECT_TRUE(retriever2->mExists.empty());
EXPECT_TRUE(retriever2->mGetFilePath.empty());
EXPECT_TRUE(retriever2->mRetrieve.empty());
EXPECT_TRUE(retriever3->mExists.empty());
EXPECT_TRUE(retriever3->mGetFilePath.empty());
EXPECT_TRUE(retriever3->mRetrieve.empty());
}

TEST(CompositeResourceRetriever, getFilePath_DefaultResourceRetrieverSucceeds_ReturnsFilePath)
{
auto retriever1 = std::make_shared<AbsentResourceRetriever>();
auto retriever2 = std::make_shared<PresentResourceRetriever>();
auto retriever3 = std::make_shared<AbsentResourceRetriever>();
CompositeResourceRetriever retriever;

EXPECT_TRUE(retriever.addSchemaRetriever("package", retriever1));
retriever.addDefaultRetriever(retriever2);
retriever.addDefaultRetriever(retriever3);

EXPECT_EQ(retriever.getFilePath(Uri::createFromString("package://test/foo")), "package://test/foo");

EXPECT_TRUE(retriever1->mExists.empty());
ASSERT_EQ(1u, retriever1->mGetFilePath.size());
EXPECT_EQ("package://test/foo", retriever1->mGetFilePath.front());
EXPECT_TRUE(retriever1->mRetrieve.empty());

EXPECT_TRUE(retriever2->mExists.empty());
ASSERT_EQ(1u, retriever2->mGetFilePath.size());
EXPECT_EQ("package://test/foo", retriever2->mGetFilePath.front());
EXPECT_TRUE(retriever2->mRetrieve.empty());

EXPECT_TRUE(retriever3->mExists.empty());
EXPECT_TRUE(retriever3->mGetFilePath.empty());
EXPECT_TRUE(retriever3->mRetrieve.empty());
}

TEST(CompositeResourceRetriever, retrieve_NothingRegistered_ReturnsNull)
{
CompositeResourceRetriever retriever;
Expand Down
Loading