diff --git a/pipeline/README.md b/pipeline/README.md
new file mode 100644
index 000000000..e990affd6
--- /dev/null
+++ b/pipeline/README.md
@@ -0,0 +1,37 @@
+---
+layout: pattern
+title: Pipeline
+folder: pipeline
+permalink: /patterns/pipeline/
+categories: Behavioral
+tags:
+ - Java
+ - Functional
+ - Difficulty-Intermediate
+---
+
+## Intent
+Allows processing of data in a series of stages by giving in an initial input and passing the processed output to be used by the next stages.
+
+## Applicability
+Use the Pipeline pattern when you want to
+
+* execute individual stages that yields a final value
+* add readability to complex sequence of operations by providing a fluent builder as an interface
+* improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle)
+
+## Typical Use Case
+
+* implement stages and execute them in an ordered manner
+
+## Real world examples
+
+* [java.util.Stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
+* [Maven Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
+* [Functional Java](https://github.com/functionaljava/functionaljava)
+
+## Credits
+
+* [The Pipeline Pattern — for fun and profit](https://medium.com/@aaronweatherall/the-pipeline-pattern-for-fun-and-profit-9b5f43a98130)
+* [The Pipeline design pattern (in Java)](https://medium.com/@deepakbapat/the-pipeline-design-pattern-in-java-831d9ce2fe21)
+* [Pipelines | Microsoft Docs](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff963548(v=pandp.10))
\ No newline at end of file
diff --git a/pipeline/pom.xml b/pipeline/pom.xml
new file mode 100644
index 000000000..7ad60d562
--- /dev/null
+++ b/pipeline/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.22.0-SNAPSHOT
+
+ pipeline
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/App.java b/pipeline/src/main/java/com.iluwatar.pipeline/App.java
new file mode 100644
index 000000000..7efa2ecca
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/App.java
@@ -0,0 +1,66 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * The Pipeline pattern uses ordered stages to process a sequence of input values.
+ * Each implemented task is represented by a stage of the pipeline. You can think of
+ * pipelines as similar to assembly lines in a factory, where each item in the assembly
+ * line is constructed in stages. The partially assembled item is passed from one assembly
+ * stage to another. The outputs of the assembly line occur in the same order as that of the
+ * inputs.
+ *
+ * Classes used in this example are suffixed with "Handlers", and synonymously refers to the
+ * "stage".
+ */
+public class App {
+ /**
+ * Specify the initial input type for the first stage handler and the expected output type
+ * of the last stage handler as type parameters for Pipeline. Use the fluent builder by
+ * calling addHandler to add more stage handlers on the pipeline.
+ */
+ public static void main(String[] args) {
+ /*
+ Suppose we wanted to pass through a String to a series of filtering stages and convert it
+ as a char array on the last stage.
+
+ - Stage handler 1 (pipe): Removing the alphabets, accepts a String input and returns the
+ processed String output. This will be used by the next handler as its input.
+
+ - Stage handler 2 (pipe): Removing the digits, accepts a String input and returns the
+ processed String output. This shall also be used by the last handler we have.
+
+ - Stage handler 3 (pipe): Converting the String input to a char array handler. We would
+ be returning a different type in here since that is what's specified by the requirement.
+ This means that at any stages along the pipeline, the handler can return any type of data
+ as long as it fulfills the requirements for the next handler's input.
+
+ Suppose we wanted to add another handler after ConvertToCharArrayHandler. That handler
+ then is expected to receive an input of char[] array since that is the type being returned
+ by the previous handler, ConvertToCharArrayHandler.
+ */
+ new Pipeline<>(new RemoveAlphabetsHandler())
+ .addHandler(new RemoveDigitsHandler())
+ .addHandler(new ConvertToCharArrayHandler());
+ }
+}
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java
new file mode 100644
index 000000000..b69241914
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/ConvertToCharArrayHandler.java
@@ -0,0 +1,45 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+
+/**
+ * Stage handler that converts an input String to its char[] array counterpart.
+ */
+class ConvertToCharArrayHandler implements Handler {
+
+ private final Logger logger = LoggerFactory.getLogger(ConvertToCharArrayHandler.class);
+
+ @Override
+ public char[] process(String input) {
+ char[] characters = input.toCharArray();
+ logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+ ConvertToCharArrayHandler.class, input, String.class, Arrays.toString(characters), Character[].class));
+
+ return characters;
+ }
+}
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java b/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java
new file mode 100644
index 000000000..7d2bc0db7
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/Handler.java
@@ -0,0 +1,32 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * Forms a contract to all stage handlers to accept a certain type of input and return a processed output.
+ * @param the input type of the handler
+ * @param the processed output type of the handler
+ */
+interface Handler {
+ O process(I input);
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java b/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java
new file mode 100644
index 000000000..8e231bbc4
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/Pipeline.java
@@ -0,0 +1,46 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+/**
+ * Main Pipeline class that initially sets the current handler. Processed output
+ * of the initial handler is then passed as the input to the next stage handlers.
+ * @param the type of the input for the first stage handler
+ * @param the final stage handler's output type
+ */
+class Pipeline {
+
+ private final Handler currentHandler;
+
+ Pipeline(Handler currentHandler) {
+ this.currentHandler = currentHandler;
+ }
+
+ Pipeline addHandler(Handler newHandler) {
+ return new Pipeline<>(input -> newHandler.process(currentHandler.process(input)));
+ }
+
+ O execute(I input) {
+ return currentHandler.process(input);
+ }
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java
new file mode 100644
index 000000000..208505274
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveAlphabetsHandler.java
@@ -0,0 +1,54 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Stage handler that returns a new instance of String without the alphabet characters of the input string.
+ */
+class RemoveAlphabetsHandler implements Handler {
+
+ private final Logger logger = LoggerFactory.getLogger(RemoveAlphabetsHandler.class);
+
+ @Override
+ public String process(String input) {
+ StringBuilder inputWithoutAlphabets = new StringBuilder();
+
+ for (int index = 0; index < input.length(); index++) {
+ char currentCharacter = input.charAt(index);
+ if (Character.isAlphabetic(currentCharacter)) {
+ continue;
+ }
+
+ inputWithoutAlphabets.append(currentCharacter);
+ }
+
+ String inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
+ logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+ RemoveAlphabetsHandler.class, input, String.class, inputWithoutAlphabetsStr, String.class));
+
+ return inputWithoutAlphabetsStr;
+ }
+}
\ No newline at end of file
diff --git a/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java
new file mode 100644
index 000000000..e0c0aa6a8
--- /dev/null
+++ b/pipeline/src/main/java/com.iluwatar.pipeline/RemoveDigitsHandler.java
@@ -0,0 +1,54 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014-2016 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Stage handler that returns a new instance of String without the digit characters of the input string.
+ */
+class RemoveDigitsHandler implements Handler {
+
+ private final Logger logger = LoggerFactory.getLogger(RemoveDigitsHandler.class);
+
+ @Override
+ public String process(String input) {
+ StringBuilder inputWithoutDigits = new StringBuilder();
+
+ for (int index = 0; index < input.length(); index++) {
+ char currentCharacter = input.charAt(index);
+ if (Character.isDigit(currentCharacter)) {
+ continue;
+ }
+
+ inputWithoutDigits.append(currentCharacter);
+ }
+
+ String inputWithoutDigitsStr = inputWithoutDigits.toString();
+ logger.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
+ RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class));
+
+ return inputWithoutDigitsStr;
+ }
+}
\ No newline at end of file
diff --git a/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java b/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java
new file mode 100644
index 000000000..79524575c
--- /dev/null
+++ b/pipeline/src/test/java/com.iluwatar.pipeline/AppTest.java
@@ -0,0 +1,37 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Application Test
+ */
+public class AppTest {
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java b/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java
new file mode 100644
index 000000000..1a2676e25
--- /dev/null
+++ b/pipeline/src/test/java/com.iluwatar.pipeline/PipelineTest.java
@@ -0,0 +1,45 @@
+/**
+ * The MIT License
+ * Copyright (c) 2014 Ilkka Seppälä
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package com.iluwatar.pipeline;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+
+/**
+ * Test for {@link Pipeline}
+ */
+public class PipelineTest {
+
+ @Test
+ public void testAddHandlersToPipeline() {
+ Pipeline filters = new Pipeline<>(new RemoveAlphabetsHandler())
+ .addHandler(new RemoveDigitsHandler())
+ .addHandler(new ConvertToCharArrayHandler());
+
+ assertArrayEquals(
+ new char[] {'#', '!', '(', '&', '%', '#', '!'},
+ filters.execute("#H!E(L&L0O%THE3R#34E!")
+ );
+ }
+}
diff --git a/pom.xml b/pom.xml
index 33219175e..39cfee91c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,7 @@
property
intercepting-filter
producer-consumer
+ pipeline
poison-pill
reader-writer-lock
lazy-loading