Skip to content

Updated pull request #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Apr 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Design pattern samples in Java.

## Build status:
Expand Down Expand Up @@ -62,6 +61,13 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
* [Callback](#callback)
* [Execute Around](#execute-around)

### Presentation Tier Patterns

Presentation Tier patterns are the top-most level of the application, this is concerned with translating tasks and results to something the user can understand.

* [Intercepting Filter](#intercepting-filter)


## <a name="abstract-factory">Abstract Factory</a> [&#8593;](#list-of-design-patterns)
**Intent:** Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Expand Down Expand Up @@ -431,6 +437,17 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
**Applicability:** Use the Callback pattern when
* When some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity.


## <a name="intercepting-filter">Intercepting Filter</a> [&#8593;](#list-of-design-patterns)
**Intent:** Provide pluggable filters to conduct necessary pre-processing and post-processing to requests from a client to a target

![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/intercepting-filter/etc/Intercepting-filter.png "Intercepting Filter")

**Applicability:** Use the Intercepting Filter pattern when
* a system uses pre-processing or post-processing requests
* a system should do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers
* you want a modular approach to configuring pre-processing and post-processing schemes

**Real world examples:**
* [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped.

Expand All @@ -453,6 +470,7 @@ Behavioral patterns are concerned with algorithms and the assignment of responsi
**Real world examples:**
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) prototype inheritance


# Frequently asked questions

**<a id="Q1">Q: What is the difference between State and Strategy patterns?</a>**
Expand All @@ -476,7 +494,7 @@ The difference is the intent of the patterns. While Proxy controls access to the
1. Fork the repository.
2. Implement the code changes in your fork. Remember to add sufficient comments documenting the implementation.
3. Create a simple class diagram from your example code.
4. Add description of the pattern in README.md and link to the class diagram.
4. Add description of the pattern in README.md and link to the class diagram.
5. Create a pull request.

**For creating/editing UML diagrams** you need one of the following:
Expand All @@ -497,10 +515,13 @@ The difference is the intent of the patterns. While Proxy controls access to the
* [Let’s Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf)
* [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1)
* [Martin Fowler - Event Aggregator](http://martinfowler.com/eaaDev/EventAggregator.html)
* [TutorialsPoint - Intercepting Filter](http://www.tutorialspoint.com/design_pattern/intercepting_filter_pattern.htm)
* [Presentation Tier Pattern](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be: Presentation Tier Patterns

* [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1)




# License

This project is licensed under the terms of the MIT license.
Binary file added intercepting-filter/etc/Intercepting-filter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions intercepting-filter/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>intercepting-filter</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
14 changes: 14 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/AddressFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter is responsible for checking/filtering the input in the address field, returns null if field is empty
* @author joshzambales
*
*/
public class AddressFilter implements Filter{
public String execute(String[] request){
if(request[2].equals("")){
return null;
}else return request[2];
}
}
35 changes: 35 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
*
* This is an app that checks whether the order request is valid through pre-processing done via Filters
* Each field has its own corresponding Filter
* @author joshzambales
*
*/
public class App{
public static void main(String[] args){
FilterManager filterManager = new FilterManager(new Target());
filterManager.setFilter(new NameFilter());
filterManager.setFilter(new ContactFilter());
filterManager.setFilter(new AddressFilter());
filterManager.setFilter(new DepositFilter());
filterManager.setFilter(new OrderFilter());

Client client = new Client();
client.setFilterManager(filterManager);
}
}









90 changes: 90 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/Client.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

/**
* The Client class is responsible for handling the input and running them through filters inside the filterManager
*
* This is where Filters come to play as the client pre-processes the request before being displayed in the Target
*
* @author joshzambales
*
*/
public class Client extends JFrame{
private FilterManager filterManager;
private JLabel jl;
private JTextField[] jtFields;
private JTextArea[] jtAreas;
private JButton clearButton, processButton;
public Client(){
super("Client System");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,300);
jl = new JLabel("RUNNING...");
jtFields = new JTextField[3];
for(int i = 0; i < 3; i++){
jtFields[i] = new JTextField();
}
jtAreas = new JTextArea[2];
for(int i = 0; i < 2; i++){
jtAreas[i] = new JTextArea();
}
clearButton = new JButton("Clear");
processButton = new JButton("Process");

setup();
}
private void setup(){
setLayout(new BorderLayout());
JPanel panel = new JPanel();
add(jl,BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
panel.setLayout(new GridLayout(6,2));
panel.add(new JLabel("Name"));
panel.add(jtFields[0]);
panel.add(new JLabel("Contact Number"));
panel.add(jtFields[1]);
panel.add(new JLabel("Address"));
panel.add(jtAreas[0]);
panel.add(new JLabel("Deposit Number"));
panel.add(jtFields[2]);
panel.add(new JLabel("Order"));
panel.add(jtAreas[1]);
panel.add(clearButton);
panel.add(processButton);

clearButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
for(JTextArea i : jtAreas){
i.setText("");
}
for(JTextField i : jtFields){
i.setText("");
}
}
});

processButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
String request = String.format("%s&%s&%s&%s&%s",jtFields[0].getText(),jtFields[1].getText(),jtAreas[0].getText(),jtFields[2].getText(),jtAreas[1].getText());

jl.setText(sendRequest(request));
}
});

JRootPane rootPane = SwingUtilities.getRootPane(processButton);
rootPane.setDefaultButton(processButton);
setVisible(true);
}
public void setFilterManager(FilterManager filterManager){
this.filterManager = filterManager;
}
public String sendRequest(String request){
return filterManager.filterRequest(request);
}
}
14 changes: 14 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/ContactFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter checks for the contact field in which it checks if the input consist of numbers and it also checks if the input follows the length constraint (11 digits)
* @author joshzambales
*
*/
public class ContactFilter implements Filter{
public String execute(String[] request){
if(request[1].equals("") || request[1].matches(".*[^\\d]+.*") || request[1].length() != 11){
return null;
}else return request[1];
}
}
15 changes: 15 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/DepositFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.iluwatar;
/**
* Concrete implementation of filter
*
* This checks for the deposit code, returns null when deposit field is empty
* @author joshzambales
*
*/
public class DepositFilter implements Filter{
public String execute(String[] request){
if(request[3].equals("")){
return null;
}else return request[3];
}
}
11 changes: 11 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/Filter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.iluwatar;
/**
* Filter interface
* Filters perform certain tasks prior or after execution of request by request handler.
* In this case, before the request is handled by the target, the request undergoes through each Filter
* @author joshzambales
*
*/
public interface Filter{
public String execute(String[] request);
}
49 changes: 49 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/FilterChain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.iluwatar;
import java.util.*;
/**
* Filter Chain carries multiple filters and help to execute them in defined order on target.
*
* @author joshzambales
*/
public class FilterChain{
private ArrayList<Filter> filters = new ArrayList<Filter>();
private final Target target;

public FilterChain(Target target){
this.target = target;
}
public void addFilter(Filter filter){
filters.add(filter);
}

public String execute(String request){
String tempout[] = new String[filters.size()];

String tempin[] = request.split("&");
int i = 0;
try{
for(Filter filter:filters){
tempout[i] = null;
tempout[i++] = filter.execute(tempin);
}
}catch(Exception e){
return "NOT ENOUGHT INPUT";
}

if(tempout[4] == null){
return "INVALID ORDER!";
}else if(tempout[3] == null){
return "INVALID DEPOSIT NUMBER!";
}else if(tempout[2] == null){
return "INVALID ADRDESS!";
}else if(tempout[1] == null){
return "INVALID Contact Number!";
}else if(tempout[0] == null){
return "INVALID Name!";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know if this will violate pattern structure or filters reusability, but I would like to keep related things together.
For example OrderFilter must know that it works with input array index-field "4", and FilterChain must know that value abscence for tempout[4] is "INVALID ORDER".
I see this magic (numbers and messages) go as constants either to Filter interface, or as public static final fields in each implementation.
if (tempout[OrderFilter.INDEX] == null) { return OrderFilter.ERROR_MSG; }

And one step further (although its also can have more problem with pattern consistency):
can we move INDEX and ERROR_MSG to Filter interface as methods, so we can perform polimorfic loop on list of filters instead of if-else chain?

}else{
target.execute(tempout);
return "RUNNING...";
}
}

}
24 changes: 24 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/FilterManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.iluwatar;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
/**
* Filter Manager manages the filters and Filter Chain.
* @author joshzambales
*
*/
public class FilterManager{
private FilterChain filterChain;

public FilterManager(Target target){
filterChain = new FilterChain(target);
}
public void setFilter(Filter filter){
filterChain.addFilter(filter);
}
public String filterRequest(String request){
return filterChain.execute(request);
}
}
14 changes: 14 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/NameFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This filter checks if the input in the Name field is valid. (alphanumeric)
* @author joshzambales
*
*/
public class NameFilter implements Filter{
public String execute(String[] request){
if(request[0].equals("") || request[0].matches(".*[^\\w|\\s]+.*")){
return null;
}else return request[0];
}
}
15 changes: 15 additions & 0 deletions intercepting-filter/src/main/java/com/iluwatar/OrderFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.iluwatar;
/**
* Concrete implementation of filter
* This checks for the order field, returns null when order field is empty
*
* @author joshzambales
*
*/
public class OrderFilter implements Filter{
public String execute(String[] request){
if(request[4].equals("")){
return null;
}else return request[4];
}
}
Loading