diff --git a/README.md b/README.md index b1eb8b87a..d5c2a2e82 100644 --- a/README.md +++ b/README.md @@ -430,7 +430,7 @@ Presentation Tier patterns are the top-most level of the application, this is co ## Intercepting Filter [↑](#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/joshzambales/java-design-patterns/blob/master/intercepting-filter/etc/Intercepting-filter.png "Intercepting Filter") +![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 diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index 72c37c3ed..19ebdfbe2 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -1,74 +1,18 @@ - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.0-SNAPSHOT - pom - - - UTF-8 - - - abstract-factory - builder - factory-method - prototype - singleton - adapter - bridge - composite - decorator - facade - flyweight - proxy - chain - command - interpreter - iterator - mediator - memento - model-view-presenter - observer - state - strategy - template-method - visitor - double-checked-locking - servant - service-locator - null-object - event-aggregator - callback - execute-around - property - - - - - - junit - junit - 4.11 - test - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.7 - 1.7 - - - - - - \ No newline at end of file + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.0-SNAPSHOT + + intercepting-filter + + + junit + junit + test + + + diff --git a/intercepting-filter/src/main/AddressFilter.java b/intercepting-filter/src/main/AddressFilter.java new file mode 100644 index 000000000..68a4b5eff --- /dev/null +++ b/intercepting-filter/src/main/AddressFilter.java @@ -0,0 +1,14 @@ + +/** + * Concrete implementation of filter + * + * @author joshzambales + * + */ +public class AddressFilter implements Filter{ + public String execute(String[] request){ + if(request[2].equals("")){ + return null; + }else return request[2]; + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/App.java b/intercepting-filter/src/main/App.java index a41e623bc..c3bc3cd0d 100644 --- a/intercepting-filter/src/main/App.java +++ b/intercepting-filter/src/main/App.java @@ -3,6 +3,13 @@ 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()); @@ -17,229 +24,15 @@ public class App{ } } -interface Filter{ - public String execute(String[] request); -} -class NameFilter implements Filter{ - public String execute(String[] request){ - if(request[0].equals("") || request[0].matches(".*[^\\w|\\s]+.*")){ - return null; - }else return request[0]; - } -} -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]; - } -} -class AddressFilter implements Filter{ - public String execute(String[] request){ - if(request[2].equals("")){ - return null; - }else return request[2]; - } -} -class DepositFilter implements Filter{ - public String execute(String[] request){ - if(request[3].equals("")){ - return null; - }else return request[3]; - } -} -class OrderFilter implements Filter{ - public String execute(String[] request){ - if(request[4].equals("")){ - return null; - }else return request[4]; - } -} -class Target extends JFrame{ - JTable jt; - JScrollPane jsp; - DefaultTableModel dtm; - JButton del; - public Target(){ - super("Order System"); - setDefaultCloseOperation(EXIT_ON_CLOSE); - setSize(640,480); - dtm = new DefaultTableModel(new Object[]{"Name", "Contact Number", "Address", "Deposit Number", "Order"},0); - jt = new JTable(dtm); - del = new JButton("Delete"); - setup(); - } - private void setup(){ - setLayout(new BorderLayout()); - JPanel bot = new JPanel(); - add(jt.getTableHeader(), BorderLayout.NORTH); - bot.setLayout(new BorderLayout()); - bot.add(del, BorderLayout.EAST); - add(bot, BorderLayout.SOUTH); - jsp = new JScrollPane(jt); - jsp.setPreferredSize(new Dimension(500,250)); - add(jsp, BorderLayout.CENTER); - del.addActionListener(new DListener()); - JRootPane rootPane = SwingUtilities.getRootPane(del); - rootPane.setDefaultButton(del); - setVisible(true); - } - public void execute(String[] request){ - //System.out.println(request[4]); - dtm.addRow(new Object[]{request[0],request[1],request[2],request[3],request[4]}); - } - class DListener implements ActionListener{ - @Override - public void actionPerformed(ActionEvent e){ - int temp = jt.getSelectedRow(); - if(temp == -1) return; - int temp2 = jt.getSelectedRowCount(); - for(int i = 0; i < temp2; i++){ - dtm.removeRow(temp); - } - } - } -} -class FilterChain{ - private ArrayList filters = new ArrayList(); - private 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); - //System.out.println(tempout[i]); - } - }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!"; - }else{ - target.execute(tempout); - return "RUNNING..."; - } - } - - public void setTarget(Target target){ - this.target = target; - } -} - -class FilterManager{ - FilterChain filterChain; - - public FilterManager(Target target){ - filterChain = new FilterChain(); - filterChain.setTarget(target); - } - public void setFilter(Filter filter){ - filterChain.addFilter(filter); - } - public String filterRequest(String request){ - return filterChain.execute(request); - } -} - -class Client extends JFrame{ - FilterManager filterManager; - JLabel jl; - JTextField[] jtfarr; - JTextArea[] jtaarr; - JButton[] buttarr; - public Client(){ - super("Client System"); - setDefaultCloseOperation(EXIT_ON_CLOSE); - setSize(300,300); - jl = new JLabel("RUNNING..."); - jtfarr = new JTextField[3]; - for(int i = 0; i < 3; i++){ - jtfarr[i] = new JTextField(); - } - jtaarr = new JTextArea[2]; - for(int i = 0; i < 2; i++){ - jtaarr[i] = new JTextArea(); - } - buttarr = new JButton[2]; - buttarr[0] = new JButton("Clear"); - buttarr[1] = 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(jtfarr[0]); - panel.add(new JLabel("Contact Number")); - panel.add(jtfarr[1]); - panel.add(new JLabel("Address")); - panel.add(jtaarr[0]); - panel.add(new JLabel("Deposit Number")); - panel.add(jtfarr[2]); - panel.add(new JLabel("Order")); - panel.add(jtaarr[1]); - panel.add(buttarr[0]); - panel.add(buttarr[1]); - - buttarr[0].addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e){ - for(JTextArea i : jtaarr){ - i.setText(""); - } - for(JTextField i : jtfarr){ - i.setText(""); - } - } - }); - - buttarr[1].addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e){ - jl.setText(sendRequest(jtfarr[0].getText()+"&"+jtfarr[1].getText()+"&"+jtaarr[0].getText()+"&"+jtfarr[2].getText()+"&"+jtaarr[1].getText())); - } - }); - - JRootPane rootPane = SwingUtilities.getRootPane(buttarr[1]); - rootPane.setDefaultButton(buttarr[1]); - setVisible(true); - } - public void setFilterManager(FilterManager filterManager){ - this.filterManager = filterManager; - } - public String sendRequest(String request){ - return filterManager.filterRequest(request); - } -} \ No newline at end of file diff --git a/intercepting-filter/src/main/Client.java b/intercepting-filter/src/main/Client.java new file mode 100644 index 000000000..a62d34702 --- /dev/null +++ b/intercepting-filter/src/main/Client.java @@ -0,0 +1,86 @@ + 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{ + FilterManager filterManager; + JLabel jl; + JTextField[] jtFields; + JTextArea[] jtAreas; + 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){ + jl.setText(sendRequest(jtFields[0].getText()+"&"+jtFields[1].getText()+"&"+jtAreas[0].getText()+"&"+jtFields[2].getText()+"&"+jtAreas[1].getText())); + } + }); + + 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); + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/ContactFilter.java b/intercepting-filter/src/main/ContactFilter.java new file mode 100644 index 000000000..f44398963 --- /dev/null +++ b/intercepting-filter/src/main/ContactFilter.java @@ -0,0 +1,13 @@ +/** + * Concrete implementation of filter + * + * @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]; + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/DepositFilter.java b/intercepting-filter/src/main/DepositFilter.java new file mode 100644 index 000000000..8d1b9303e --- /dev/null +++ b/intercepting-filter/src/main/DepositFilter.java @@ -0,0 +1,13 @@ +/** + * Concrete implementation of filter + * + * @author joshzambales + * + */ +public class DepositFilter implements Filter{ + public String execute(String[] request){ + if(request[3].equals("")){ + return null; + }else return request[3]; + } +} diff --git a/intercepting-filter/src/main/Filter.java b/intercepting-filter/src/main/Filter.java new file mode 100644 index 000000000..578f1c5fd --- /dev/null +++ b/intercepting-filter/src/main/Filter.java @@ -0,0 +1,8 @@ +/** + * Filter interface + * @author joshzambales + * + */ +public interface Filter{ + public String execute(String[] request); +} diff --git a/intercepting-filter/src/main/FilterChain.java b/intercepting-filter/src/main/FilterChain.java new file mode 100644 index 000000000..04b991c2c --- /dev/null +++ b/intercepting-filter/src/main/FilterChain.java @@ -0,0 +1,48 @@ + 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 filters = new ArrayList(); + private 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!"; + }else{ + target.execute(tempout); + return "RUNNING..."; + } + } + +} diff --git a/intercepting-filter/src/main/FilterManager.java b/intercepting-filter/src/main/FilterManager.java new file mode 100644 index 000000000..380222a75 --- /dev/null +++ b/intercepting-filter/src/main/FilterManager.java @@ -0,0 +1,23 @@ + 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{ + 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); + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/NameFilter.java b/intercepting-filter/src/main/NameFilter.java new file mode 100644 index 000000000..61d368ce2 --- /dev/null +++ b/intercepting-filter/src/main/NameFilter.java @@ -0,0 +1,7 @@ +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]; + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/OrderFilter.java b/intercepting-filter/src/main/OrderFilter.java new file mode 100644 index 000000000..8ccf5a67d --- /dev/null +++ b/intercepting-filter/src/main/OrderFilter.java @@ -0,0 +1,13 @@ +/** + * Concrete implementation of filter + * + * @author joshzambales + * + */ +public class OrderFilter implements Filter{ + public String execute(String[] request){ + if(request[4].equals("")){ + return null; + }else return request[4]; + } +} \ No newline at end of file diff --git a/intercepting-filter/src/main/Target.java b/intercepting-filter/src/main/Target.java new file mode 100644 index 000000000..93c7d93f7 --- /dev/null +++ b/intercepting-filter/src/main/Target.java @@ -0,0 +1,58 @@ + import java.util.*; +import javax.swing.*; +import javax.swing.table.*; +import java.awt.*; +import java.awt.event.*; +/** + * This is where the requests are displayed after being validated by filters. + * + * @author mjoshzambales + * + */ +public class Target extends JFrame{ + JTable jt; + JScrollPane jsp; + DefaultTableModel dtm; + JButton del; + public Target(){ + super("Order System"); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setSize(640,480); + dtm = new DefaultTableModel(new Object[]{"Name", "Contact Number", "Address", "Deposit Number", "Order"},0); + jt = new JTable(dtm); + del = new JButton("Delete"); + setup(); + } + private void setup(){ + setLayout(new BorderLayout()); + JPanel bot = new JPanel(); + add(jt.getTableHeader(), BorderLayout.NORTH); + bot.setLayout(new BorderLayout()); + bot.add(del, BorderLayout.EAST); + add(bot, BorderLayout.SOUTH); + jsp = new JScrollPane(jt); + jsp.setPreferredSize(new Dimension(500,250)); + add(jsp, BorderLayout.CENTER); + + del.addActionListener(new DListener()); + + JRootPane rootPane = SwingUtilities.getRootPane(del); + rootPane.setDefaultButton(del); + setVisible(true); + } + public void execute(String[] request){ + dtm.addRow(new Object[]{request[0],request[1],request[2],request[3],request[4]}); + } + + class DListener implements ActionListener{ + @Override + public void actionPerformed(ActionEvent e){ + int temp = jt.getSelectedRow(); + if(temp == -1) return; + int temp2 = jt.getSelectedRowCount(); + for(int i = 0; i < temp2; i++){ + dtm.removeRow(temp); + } + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7cfff29c4..80f25c549 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ null-object event-aggregator callback + intercepting-filter