diff --git a/pystac/layout.py b/pystac/layout.py index 27fe31c34..eb543f049 100644 --- a/pystac/layout.py +++ b/pystac/layout.py @@ -517,3 +517,41 @@ def get_item_href(self, item: "Item_Type", parent_dir: str) -> str: item_root = join_path_or_url(join_type, parent_dir, "{}".format(item.id)) return join_path_or_url(join_type, item_root, "{}.json".format(item.id)) + + +class AsIsLayoutStrategy(HrefLayoutStrategy): + """Layout strategy that simply preserves the current href of all objects. + + If any object doesn't have a self href, a ValueError is raised. + """ + + def get_catalog_href( + self, cat: "Catalog_Type", parent_dir: str, is_root: bool + ) -> str: + href = cat.self_href + if href is None: + raise ValueError( + f"Catalog is missing href, required for AsIsLayoutStrategy: {cat}" + ) + else: + return href + + def get_collection_href( + self, col: "Collection_Type", parent_dir: str, is_root: bool + ) -> str: + href = col.self_href + if href is None: + raise ValueError( + f"Collection is missing href, required for AsIsLayoutStrategy: {col}" + ) + else: + return href + + def get_item_href(self, item: "Item_Type", parent_dir: str) -> str: + href = item.self_href + if href is None: + raise ValueError( + f"Item is missing href, required for AsIsLayoutStrategy: {item}" + ) + else: + return href diff --git a/tests/test_layout.py b/tests/test_layout.py index f88365364..42d810d23 100644 --- a/tests/test_layout.py +++ b/tests/test_layout.py @@ -10,6 +10,7 @@ CustomLayoutStrategy, TemplateLayoutStrategy, BestPracticesLayoutStrategy, + AsIsLayoutStrategy, TemplateError, ) from tests.utils import TestCases, ARBITRARY_GEOM, ARBITRARY_BBOX @@ -420,3 +421,41 @@ def test_produces_layout_for_item(self) -> None: href = self.strategy.get_href(item, parent_dir="http://example.com") expected = "http://example.com/{}/{}.json".format(item.id, item.id) self.assertEqual(href, expected) + + +class AsIsLayoutStrategyTest(unittest.TestCase): + def setUp(self) -> None: + self.strategy = AsIsLayoutStrategy() + + def test_catalog(self) -> None: + cat = pystac.Catalog(id="test", description="test desc") + with self.assertRaises(ValueError): + self.strategy.get_href(cat, parent_dir="http://example.com", is_root=True) + cat.set_self_href("/an/href") + href = self.strategy.get_href( + cat, parent_dir="https://example.com", is_root=True + ) + self.assertEqual(href, "/an/href") + + def test_collection(self) -> None: + collection = TestCases.test_case_8() + collection.set_self_href(None) + with self.assertRaises(ValueError): + self.strategy.get_href( + collection, parent_dir="http://example.com", is_root=True + ) + collection.set_self_href("/an/href") + href = self.strategy.get_href( + collection, parent_dir="https://example.com", is_root=True + ) + self.assertEqual(href, "/an/href") + + def test_item(self) -> None: + collection = TestCases.test_case_8() + item = next(iter(collection.get_all_items())) + item.set_self_href(None) + with self.assertRaises(ValueError): + self.strategy.get_href(item, parent_dir="http://example.com") + item.set_self_href("/an/href") + href = self.strategy.get_href(item, parent_dir="http://example.com") + self.assertEqual(href, "/an/href")