diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/HtmlDocument.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/HtmlDocument.java new file mode 100644 index 0000000000..db0f988908 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/HtmlDocument.java @@ -0,0 +1,46 @@ +package com.baeldung.fluentinterface; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +public class HtmlDocument { + private final String content; + + private HtmlDocument(String html) { + this.content = html; + } + + public HtmlDocument() { + this(""); + } + + public String html() { + return String.format("%s", content); + } + + public HtmlDocument header(String header) { + return new HtmlDocument(String.format("%s

%s

", content, header)); + } + + public HtmlDocument secondaryHeader(String header) { + return new HtmlDocument(String.format("%s

%s

", content, header)); + } + + public HtmlDocument paragraph(String paragraph) { + return new HtmlDocument(String.format("%s

%s

", content, paragraph)); + } + + public HtmlDocument horizontalLine() { + return new HtmlDocument(String.format("%s
", content)); + } + + public HtmlDocument orderedList(String... items) { + String listItems = stream(items).map(el -> String.format("
  • %s
  • ", el)).collect(joining()); + return new HtmlDocument(String.format("%s
      %s
    ", content, listItems)); + } + + public HtmlDocument unorderedList(String... items) { + String listItems = stream(items).map(el -> String.format("
  • %s
  • ", el)).collect(joining()); + return new HtmlDocument(String.format("%s ", content, listItems)); + } +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/LargeHtmlDocument.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/LargeHtmlDocument.java new file mode 100644 index 0000000000..fff8c97b5b --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/LargeHtmlDocument.java @@ -0,0 +1,40 @@ +package com.baeldung.fluentinterface; + +import com.baeldung.fluentinterface.components.HtmlElement; +import com.baeldung.fluentinterface.components.HtmlHeader; +import com.baeldung.fluentinterface.components.HtmlList; + +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; + +public class LargeHtmlDocument { + private final String content; + + private LargeHtmlDocument(String html) { + this.content = html; + } + + public LargeHtmlDocument() { + this(""); + } + + public String html() { + return format("%s", content); + } + + public LargeHtmlDocument head(HtmlElement head) { + return new LargeHtmlDocument(format("%s %s", content, head.html())); + } + public LargeHtmlDocument body(HtmlElement body) { + return new LargeHtmlDocument(format("%s %s", content, body.html())); + } + public LargeHtmlDocument footer(HtmlElement footer) { + return new LargeHtmlDocument(format("%s ", content, footer.html())); + } + + private LargeHtmlDocument append(String html) { + return new LargeHtmlDocument(format("%s %s", content, html)); + } + +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/User.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/User.java new file mode 100644 index 0000000000..1606369c26 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/User.java @@ -0,0 +1,65 @@ +package com.baeldung.fluentinterface; + +public class User { + private String firstName; + private String lastName; + private String email; + private String username; + private Long id; + + public String name() { + return firstName + " " + lastName; + } + + public User(String firstName, String lastName, String email, String username, Long id) { + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.username = username; + this.id = id; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String firstName; + private String lastName; + private String email; + private String username; + private Long id; + + private Builder() { + } + + public Builder firstName(String firstName) { + this.firstName = firstName; + return this; + } + + public Builder lastName(String lastName) { + this.lastName = lastName; + return this; + } + + public Builder email(String email) { + this.email = email; + return this; + } + + public Builder username(String username) { + this.username = username; + return this; + } + + public Builder id(Long id) { + this.id = id; + return this; + } + + public User build() { + return new User(firstName, lastName, email, username, id); + } + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HorizontalLine.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HorizontalLine.java new file mode 100644 index 0000000000..66979b98f9 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HorizontalLine.java @@ -0,0 +1,8 @@ +package com.baeldung.fluentinterface.components; + +public class HorizontalLine implements HtmlElement { + @Override + public String html() { + return "
    "; + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlDiv.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlDiv.java new file mode 100644 index 0000000000..7625401444 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlDiv.java @@ -0,0 +1,29 @@ +package com.baeldung.fluentinterface.components; + +public class HtmlDiv implements HtmlElement { + + private final String content; + + public HtmlDiv(String content) { + this.content = content; + } + + public HtmlDiv() { + this.content = ""; + } + + public HtmlDiv append(HtmlElement element) { + return new HtmlDiv(content + element.html()); + } + public HtmlDiv text(String text) { + return new HtmlDiv(content + text); + } + public HtmlDiv paragraph(String text) { + return new HtmlDiv(content + text); + } + + @Override + public String html() { + return String.format("
    %s
    ", content); + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlElement.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlElement.java new file mode 100644 index 0000000000..ff46dc0029 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlElement.java @@ -0,0 +1,5 @@ +package com.baeldung.fluentinterface.components; + +public interface HtmlElement { + String html(); +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlHeader.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlHeader.java new file mode 100644 index 0000000000..12c400014d --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlHeader.java @@ -0,0 +1,34 @@ +package com.baeldung.fluentinterface.components; + +public class HtmlHeader implements HtmlElement { + + private final Type type; + private final String value; + + public HtmlHeader(Type type, String value) { + this.type = type; + this.value = value; + } + + @Override + public String html() { + return String.format("<%s>%s", type.tag(), value, type.tag()); + } + + public enum Type { + PRIMARY("h1"), + SECONDARY("h2"), + THIRD("h3"), + FOURTH("h4"); + + private final String tag; + + Type(String tag) { + this.tag = tag; + } + + public String tag() { + return tag; + } + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlList.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlList.java new file mode 100644 index 0000000000..030c9aaa5c --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlList.java @@ -0,0 +1,39 @@ +package com.baeldung.fluentinterface.components; + +import java.util.Arrays; +import java.util.List; + +import static java.lang.String.format; +import static java.util.stream.Collectors.joining; + +public class HtmlList implements HtmlElement { + + private final Type type; + private final List items; + + public HtmlList(Type type, String... items) { + this.type = type; + this.items = Arrays.asList(items); + } + + @Override + public String html() { + String listItems = items.stream().map(el -> format("
  • %s
  • ", el)).collect(joining()); + return String.format("<%s>%s", type.tag(), listItems, type.tag()); + } + + public enum Type { + ORDERED("ol"), + UNORDERED("ul"); + + private final String tag; + + Type(String tag) { + this.tag = tag; + } + + public String tag() { + return tag; + } + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlSpan.java b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlSpan.java new file mode 100644 index 0000000000..2bdf55eb72 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/main/java/com/baeldung/fluentinterface/components/HtmlSpan.java @@ -0,0 +1,27 @@ +package com.baeldung.fluentinterface.components; + +public class HtmlSpan implements HtmlElement { + + private final String content; + + public HtmlSpan(String content) { + this.content = content; + } + + public HtmlSpan() { + this.content = ""; + } + + public HtmlSpan append(HtmlElement element) { + return new HtmlSpan(content + element.html()); + } + + public HtmlSpan paragraph(String text) { + return new HtmlSpan(content + text); + } + + @Override + public String html() { + return String.format("%s", content); + } +} diff --git a/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/fluentinterface/FluentInterfaceUnitTest.java b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/fluentinterface/FluentInterfaceUnitTest.java new file mode 100644 index 0000000000..bf5aadcf13 --- /dev/null +++ b/patterns-modules/design-patterns-behavioral-2/src/test/java/com/baeldung/fluentinterface/FluentInterfaceUnitTest.java @@ -0,0 +1,101 @@ +package com.baeldung.fluentinterface; + +import com.baeldung.fluentinterface.components.*; +import com.baeldung.fluentinterface.components.HtmlHeader.Type; +import org.junit.jupiter.api.Test; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.baeldung.fluentinterface.components.HtmlList.Type.ORDERED; +import static org.assertj.core.api.Assertions.assertThat; + +class FluentInterfaceUnitTest { + + @Test + void givenTenNumbers_thenStreamIsProcessedCorrectly() { + Stream numbers = Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + Stream processedNumbers = numbers.distinct() + .filter(nr -> nr % 2 == 0) + .skip(1) + .limit(4) + .map(nr -> "#" + nr) + .peek(nr -> System.out.println(nr)); + String result = processedNumbers.collect(Collectors.joining(", ")); + + assertThat(result).isEqualTo("#2, #4, #6, #8"); + } + + @Test + void givenUserBuilder_thenCreateUserCorrectly() { + User.Builder userBuilder = User.builder(); + userBuilder = userBuilder + .firstName("John") + .lastName("Doe") + .email("jd@gmail.com") + .username("jd_2000") + .id(1234L); + + User user = userBuilder.build(); + + assertThat(user.name()).isEqualTo("John Doe"); + } + + @Test + void givenHtmlDocument_thenGenerateHtmlCorrectly() { + HtmlDocument document = new HtmlDocument() + .header("Principles of O.O.P.") + .paragraph("OOP in Java.") + .horizontalLine() + .paragraph("The main pillars of OOP are:") + .orderedList("Encapsulation", "Inheritance", "Abstraction", "Polymorphism"); + String html = document.html(); + + assertThat(html).isEqualToIgnoringWhitespace( + "" + + "

    Principles of O.O.P.

    " + + "

    OOP in Java.

    " + + "
    " + + "

    The main pillars of OOP are:

    " + + "
      " + + "
    1. Encapsulation
    2. " + + "
    3. Inheritance
    4. " + + "
    5. Abstraction
    6. " + + "
    7. Polymorphism
    8. " + + "
    " + + "" + ); + } + + @Test + void givenHtmlDocument_thenInstanceIsImmutable() { + HtmlDocument document = new HtmlDocument() + .header("Principles of O.O.P."); + HtmlDocument updatedDocument = document + .paragraph("OOP in Java."); + + assertThat(document).isNotEqualTo(updatedDocument); + } + + + @Test + void givenLargeHtmlDocument_thenGenerateHtmlCorrectly() { + String html = new LargeHtmlDocument() + .head(new HtmlHeader(Type.PRIMARY, "title")) + .body(new HtmlDiv() + .append(new HtmlSpan() + .paragraph("learning OOP from John Doe") + .append(new HorizontalLine()) + .paragraph("The pillars of OOP:") + ) + .append(new HtmlList(ORDERED, "Encapsulation", "Inheritance", "Abstraction", "Polymorphism")) + ) + .footer(new HtmlDiv() + .paragraph("trademark John Doe") + ) + .html(); + + String expectedHtml = "

    title

    learning OOP from John Doe
    The pillars of OOP:
    1. Encapsulation
    2. Inheritance
    3. Abstraction
    4. Polymorphism
    "; + assertThat(html).isEqualToIgnoringWhitespace(expectedHtml); + } +} \ No newline at end of file