diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AddressablePath.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AddressablePath.java new file mode 100644 index 0000000..558479b --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AddressablePath.java @@ -0,0 +1,34 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public abstract class AddressablePath implements Nameable { + + private final String name; + private Nameable parent; + + protected AddressablePath(String name) { + this.name = name; + } + + protected void setParent(Nameable parent) { + this.parent = parent; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + if (parent == null) { + return name; + } + + return Stream.of(parent.toString(), name) + .collect(Collectors.joining("/")); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/File.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/File.java new file mode 100644 index 0000000..62656d4 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/File.java @@ -0,0 +1,8 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +public class File extends AddressablePath { + + protected File(String name) { + super(name); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Folder.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Folder.java new file mode 100644 index 0000000..4d6411d --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Folder.java @@ -0,0 +1,39 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; + +public final class Folder extends AddressablePath { + + private final AddressablePath[] paths; + + public Folder(String name, AddressablePath... paths) { + super(name); + this.paths = paths; + for (AddressablePath path : paths) { + path.setParent(this); + } + } + + public List find(Predicate nameMatcher) { + List result = new ArrayList<>(); + + Arrays.stream(paths) + .filter(path -> nameMatcher.test(path.getName())) + .map(Object::toString) + .forEach(result::add); + + Arrays.stream(paths) + .filter(Folder.class::isInstance) + .map(Folder.class::cast) + .map(folder -> folder.find(nameMatcher)) + .flatMap(Collection::stream) + .forEach(result::add); + + return result; + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Nameable.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Nameable.java new file mode 100644 index 0000000..7330934 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Nameable.java @@ -0,0 +1,5 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +public interface Nameable { + String getName(); +} diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/FolderCompositeTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/FolderCompositeTest.java new file mode 100644 index 0000000..499fc02 --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/FolderCompositeTest.java @@ -0,0 +1,27 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +class FolderCompositeTest { + + @Test + public void shouldAllowToSearchNames() { + var root = new Folder("root", + new Folder("css", new File("main.css"), new File("user.css")), + new Folder("js", new File("main.js"), new File("user.js")), + new Folder("fonts", new File("monospace.ttf")), + new Folder("images", new File("logo.png")), + new File("index.html") + ); + + Assertions.assertEquals(List.of("root/css", "root/css/main.css", "root/css/user.css"), + root.find(name -> name.contains("css"))); + Assertions.assertEquals(List.of("root/js/main.js", "root/js/user.js"), + root.find(name -> name.endsWith(".js"))); + Assertions.assertEquals(List.of(), root.find(name -> name.endsWith(".exe"))); + } + +}