public interface CategoryTree
Consult the documentation for categories for more information.
Modifier and Type | Method and Description |
---|---|
Optional<Category> |
findByExternalId(String externalId)
Finds a category by its external ID.
|
Optional<Category> |
findById(String id)
Finds a category by id.
|
Optional<Category> |
findByKey(String key)
Finds a category by the key.
|
Optional<Category> |
findBySlug(Locale locale,
String slug)
Finds a category by the slug and a specific locale.
|
List<Category> |
findChildren(Identifiable<Category> category)
return the children for category.
|
List<Category> |
findSiblings(Collection<? extends Identifiable<Category>> categoryIds)
Gets a list containing all categories that share a parent
with at least one of the given categories.
|
List<Category> |
getAllAsFlatList()
All categories as a flat list.
|
Category |
getRootAncestor(Identifiable<Category> category)
For a given category searches the ancestor that is in root level.
|
List<Category> |
getRoots()
Root categories (the ones that have no parent).
|
CategoryTree |
getSubtree(Collection<? extends Identifiable<Category>> parentCategories)
Gets the subtree of the given parent categories.
|
List<Category> |
getSubtreeRoots()
For a subtree the categories which are at the top level.
|
static CategoryTree |
of(List<Category> allCategoriesAsFlatList)
Creates a category tree from a flat list of categories.
|
List<Category> getRoots()
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
assertThat(tree.getRoots()).extracting(Resource::getId).containsOnly("A", "B", "C");
See the test code.
Optional<Category> findById(String id)
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Optional<Category> optional = tree.findById("B-2-3");
assertThat(optional).isPresent();
assertThat(optional.get().getId()).isEqualTo("B-2-3");
See the test code.
final CategoryTree tree = createAbcCategoryTree();
final Optional<Category> optional = tree.findById("id-which-does-not-exist");
assertThat(optional).isEmpty();
assertThatThrownBy(() -> optional.get()).isInstanceOf(NoSuchElementException.class);
See the test code.
id
- the ID of the category to search forOptional<Category> findByExternalId(String externalId)
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category category = tree.findById("B-2-3").get();
final String externalId = "external-id-B-2-3";
assertThat(category.getExternalId()).isEqualTo(externalId);
final Optional<Category> optional = tree.findByExternalId(externalId);
assertThat(optional).isPresent().contains(category);
See the test code.
externalId
- the external id of the category to findOptional<Category> findBySlug(Locale locale, String slug)
locale
- the localeslug
- the slugOptional<Category> findByKey(String key)
key
- the category keyList<Category> getAllAsFlatList()
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
assertThat(tree.getAllAsFlatList())
.hasSize(39)
.extracting(cat -> cat.getId())
//don't rely on the order!
.containsOnly("A", "B", "C",
"A-1", "A-2", "A-3",
"B-1", "B-2", "B-3",
"C-1", "C-2", "C-3",
"A-1-1", "A-1-2", "A-1-3",
"A-2-1", "A-2-2", "A-2-3",
"A-3-1", "A-3-2", "A-3-3",
"B-1-1", "B-1-2", "B-1-3",
"B-2-1", "B-2-2", "B-2-3",
"B-3-1", "B-3-2", "B-3-3",
"C-1-1", "C-1-2", "C-1-3",
"C-2-1", "C-2-2", "C-2-3",
"C-3-1", "C-3-2", "C-3-3");
See the test code.
List<Category> findChildren(Identifiable<Category> category)
CategoryTree
then the list is empty.
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category category = tree.findById("B").get();
final List<Category> children = tree.findChildren(category);
assertThat(children).extracting(Resource::getId)
.as("only direct children are present")
.containsOnly("B-1", "B-2", "B-3");
See the test code.
final CategoryTree tree = createAbcCategoryTree();
final Category category = tree.findById("B-1-1").get();
final List<Category> children = tree.findChildren(category);
assertThat(children).as("leaf nodes produce empty lists").isEmpty();
See the test code.
category
- the category which should be the parent category to the result listList<Category> findSiblings(Collection<? extends Identifiable<Category>> categoryIds)
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category b2 = tree.findById("B-2").get();
final Category b1 = tree.findById("B-1").get();
final Category c2 = tree.findById("C-2").get();
final Category c21 = tree.findById("C-2-1").get();
final Category c22 = tree.findById("C-2-2").get();
final Category c23 = tree.findById("C-2-3").get();
final Category b = tree.findById("B").get();
final Category a = tree.findById("A").get();
assertThat(tree.findSiblings(singletonList(b2)))
.extracting(c -> c.getId())
.as("one category will provide all its siblings (no recursion) without including itself")
.containsOnly("B-1", "B-3");
assertThat(tree.findSiblings(asList(b1, b2))).extracting(c -> c.getId())
.as("providing multiple categories which are siblings exclude themselves from the result list")
.containsOnly("B-3");
assertThat(tree.findSiblings(asList(b2, c2))).extracting(c -> c.getId())
.as("using non-sibling categories as arguments results in getting all their siblings in one list")
.containsOnly("B-1", "B-3", "C-1", "C-3");
assertThat(tree.findSiblings(asList(b, b1))).extracting(c -> c.getId())
.as("even on different levels it will provide the siblings and will filter out all input categories")
.containsOnly("A", "C", "B-2", "B-3");
assertThat(tree.findSiblings(asList(a, b))).extracting(c -> c.getId()).containsOnly("C");
assertThat(tree.findSiblings(asList(c21, c22, c23))).extracting(c -> c.getId())
.as("if there are no siblings available")
.isEmpty();
See the test code.
categoryIds
- Categories for which the sibling categories should be fetchedCategoryTree getSubtree(Collection<? extends Identifiable<Category>> parentCategories)
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category category = tree.findById("B").get();
final CategoryTree subtree = tree.getSubtree(singletonList(category));
assertThat(subtree.getAllAsFlatList()).hasSize(13);
assertThat(subtree.findById(category.getId())).isPresent();
assertThat(subtree.getRoots()).hasSize(1);
assertThat(subtree.getSubtreeRoots()).isEqualTo(subtree.getRoots());
assertThat(subtree.findById("B-1")).isPresent();
assertThat(subtree.findById("C-1")).isEmpty();
See the test code.
final CategoryTree tree = createAbcCategoryTree();
final Category a = tree.findById("A").get();
final Category b1 = tree.findById("B-1").get();
final Category c22 = tree.findById("C-2-2").get();
final CategoryTree subtree = tree.getSubtree(asList(a, b1, c22));
assertThat(subtree.getRoots()).extracting(c -> c.getId())
.as("roots are still categories which have no parent and are included in this tree")
.containsOnly("A")
.doesNotContain("B-1", "C-2-2", "B", "C");
assertThat(subtree.getSubtreeRoots()).extracting(c -> c.getId())
.as("subtree roots are the categories at the top," +
"no matter if they have a parent reference")
.containsOnly("A", "B-1", "C-2-2")
.doesNotContain("B", "C", "B-2");
assertThat(subtree.findById("A")).isPresent();
assertThat(subtree.findById("B-1")).isPresent();
assertThat(subtree.findById("C-2-2")).isPresent();
assertThat(subtree.findById("B-1-2")).isPresent();
assertThat(subtree.findById("C")).isEmpty();
assertThat(subtree.findById("B-2")).isEmpty();
assertThat(subtree.findByExternalId("external-id-C-2-2")).isPresent();
assertThat(subtree.findByExternalId("external-id-B-2")).isEmpty();
assertThat(subtree.findBySlug(Locale.ENGLISH, "slug-C-2-2")).isPresent();
assertThat(subtree.findBySlug(Locale.ENGLISH, "slug-B-2")).isEmpty();
assertThat(subtree.getAllAsFlatList()).hasSize(18);
assertThat(subtree.findChildren(b1)).hasSize(3);
assertThat(subtree.findChildren(tree.findById("C").get())).hasSize(0);
assertThat(subtree.findChildren(tree.findById("C-2").get()))
.as("C-2 is not included in the tree but its direct child C-2-2")
.hasSize(1);
assertThat(subtree.findSiblings(singletonList(a))).hasSize(0);
assertThat(subtree.findSiblings(singletonList(c22))).hasSize(0);
assertThat(subtree.findSiblings(singletonList(tree.findById("B-1-1").get()))).hasSize(2);
final CategoryTree b1Subtree = subtree.getSubtree(singletonList(b1));
assertThat(b1Subtree.getAllAsFlatList()).hasSize(4);
assertThat(b1Subtree.getRoots()).hasSize(0);
assertThat(b1Subtree.getSubtreeRoots()).hasSize(1);
See the test code.
parentCategories
- the list of parent categories to use as a starting pointCategory getRootAncestor(Identifiable<Category> category)
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category a = tree.findById("A").get();
final Category a1 = tree.findById("A-1").get();
final Category a23 = tree.findById("A-2-3").get();
assertThat(tree.getRootAncestor(a)).isEqualTo(a);
assertThat(tree.getRootAncestor(a1)).isEqualTo(a);
assertThat(tree.getRootAncestor(a23)).isEqualTo(a);
See the test code.
category
- the category which to find the root ancestorList<Category> getSubtreeRoots()
Unlike getRoots()
this does ignore the parent reference.
The examples use the ABC example set.
final CategoryTree tree = createAbcCategoryTree();
final Category a = tree.findById("A").get();
final Category b1 = tree.findById("B-1").get();
final Category c22 = tree.findById("C-2-2").get();
final CategoryTree subtree = tree.getSubtree(asList(a, b1, c22));
assertThat(subtree.getRoots()).extracting(c -> c.getId())
.as("roots are still categories which have no parent and are included in this tree")
.containsOnly("A")
.doesNotContain("B-1", "C-2-2", "B", "C");
assertThat(subtree.getSubtreeRoots()).extracting(c -> c.getId())
.as("subtree roots are the categories at the top," +
"no matter if they have a parent reference")
.containsOnly("A", "B-1", "C-2-2")
.doesNotContain("B", "C", "B-2");
See the test code.
static CategoryTree of(List<Category> allCategoriesAsFlatList)
allCategoriesAsFlatList
- all categories as flat list.