Skip to content
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
2 changes: 1 addition & 1 deletion .github/badges/branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .github/badges/jacoco.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ cd java-patterns-and-constructs
### Patterns
* [Abstract Factory](src/main/java/com/penapereira/example/constructs/abstractfactory/)
* [Adapter](src/main/java/com/penapereira/example/constructs/adapter/)
* [Chain of Responsibility](src/main/java/com/penapereira/example/constructs/chainofresponsibility/)
* [Decorator](src/main/java/com/penapereira/example/constructs/decorator/)
* [Factory](src/main/java/com/penapereira/example/constructs/factory/)
* [Factory Method](src/main/java/com/penapereira/example/constructs/factorymethod/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ public class AppCommandLineRunner implements CommandLineRunner {

@Override
public void run(String... args) throws Exception {
log.info(msg.getGreeting());
log.info(msg.getHomeUrl());
EventQueue.invokeLater(() -> {
main.initializeFrame();
main.setVisible(true);
});
log.info(msg.getSeparator());
log.info(msg.getGreeting());
log.info(msg.getHomeUrl());
log.info(msg.getInstructions());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.penapereira.example.constructs.app.properties.ApplicationProperties;
import com.penapereira.example.constructs.app.properties.Messages;

@Component
Expand All @@ -23,12 +24,17 @@ public class ExamplesCommandLineRunner implements CommandLineRunner {
@Autowired
Messages msg;

@Autowired
ApplicationProperties props;

@Override
public void run(String... args) throws Exception {
List<String> beanNames = Arrays.asList(ctx.getBeanNamesForType(ExampleRunnerInterface.class));

listExamples(beanNames);
executeExamples(beanNames);

if (props.getEnableCommandLineRunner()) {
listExamples(beanNames);
executeExamples(beanNames);
}
}

private void listExamples(List<String> beanNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ public class ApplicationProperties {

@Value("classpath:icon.png")
protected Resource appIcon;

protected Boolean enableCommandLineRunner;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ public class Messages {
protected String info;
protected String examplesFound;
protected String enableTraceToSeeExamplesDetails;
protected String enableDebugToSeeExamplesList;
protected String separator;
protected String outputTitle;
protected String enableDebugToSeeExamplesList;
protected String separator;
protected String outputTitle;
protected String preserveLog;
protected String instructions;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JCheckBox;
import javax.swing.SwingConstants;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.penapereira.example.constructs.app.properties.ApplicationProperties;
import com.penapereira.example.constructs.app.properties.Messages;
import com.penapereira.example.constructs.app.ExampleRunnerInterface;

@Component
public class MainWindow extends JFrame {
Expand All @@ -31,13 +35,19 @@ public class MainWindow extends JFrame {

private static final long serialVersionUID = 1L;

private JTextArea outputArea;
private JTextArea outputArea;
private JCheckBox preserveLogCheck;

@Autowired
Messages msg;

@Autowired
ApplicationProperties props;
@Autowired
ApplicationProperties props;

@Autowired
ApplicationContext ctx;

private java.util.Map<String, ExampleRunnerInterface> examples;

public MainWindow() {
super();
Expand Down Expand Up @@ -73,19 +83,28 @@ private void loadIcon() {
private JPanel getMainComponent() {
JPanel mainPanel = new JPanel(new BorderLayout());

JPanel infoPanel = new JPanel(new GridLayout(4, 1));
createCenteredTitle(msg.getGreeting(), infoPanel);
createCenteredLabelOnPanel(msg.getInfo(), infoPanel);
createCenteredHyperlink(msg.getHomeUrl(), infoPanel);
mainPanel.add(infoPanel, BorderLayout.NORTH);
JPanel infoPanel = new JPanel(new GridLayout(4, 1));
createCenteredTitle(msg.getGreeting(), infoPanel);
createCenteredLabelOnPanel(msg.getInfo(), infoPanel);
createCenteredHyperlink(msg.getHomeUrl(), infoPanel);
mainPanel.add(infoPanel, BorderLayout.NORTH);

mainPanel.add(createExamplesPanel(), BorderLayout.WEST);

outputArea = new JTextArea(10, 40);
outputArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(outputArea);
scrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder(msg.getOutputTitle()));
mainPanel.add(scrollPane, BorderLayout.CENTER);
outputArea = new JTextArea(10, 40);
outputArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(outputArea);
scrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder(msg.getOutputTitle()));

return mainPanel;
preserveLogCheck = new JCheckBox(msg.getPreserveLog());

JPanel outputPanel = new JPanel(new BorderLayout());
outputPanel.add(preserveLogCheck, BorderLayout.NORTH);
outputPanel.add(scrollPane, BorderLayout.CENTER);

mainPanel.add(outputPanel, BorderLayout.CENTER);

return mainPanel;
}

private void createCenteredTitle(String text, JPanel panel) {
Expand Down Expand Up @@ -117,4 +136,55 @@ public void appendOutput(String text) {
}
}

private JPanel createExamplesPanel() {
examples = ctx.getBeansOfType(ExampleRunnerInterface.class);

JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBorder(javax.swing.BorderFactory.createTitledBorder(msg.getExamplesFound()));

javax.swing.JButton allButton = new javax.swing.JButton("Run All");
allButton.addActionListener(e -> runAllExamples());
panel.add(allButton);

examples.forEach((name, runner) -> {
String clean = name.replaceFirst("ExampleRunner", "");
javax.swing.JButton btn = new javax.swing.JButton(clean);
btn.addActionListener(e -> runExample(runner));
panel.add(btn);
});

return panel;
}

private void runExample(ExampleRunnerInterface runner) {
if (!preserveLogCheck.isSelected()) {
outputArea.setText("");
}
new Thread(() -> {
try {
log.trace(msg.getSeparator());
runner.runExample();
} catch (Exception e) {
log.error("Error executing example", e);
}
}).start();
}

private void runAllExamples() {
if (!preserveLogCheck.isSelected()) {
outputArea.setText("");
}
new Thread(() -> {
examples.values().forEach(r -> {
try {
log.trace(msg.getSeparator());
r.runExample();
} catch (Exception e) {
log.error("Error executing example", e);
}
});
}).start();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.penapereira.example.constructs.chainofresponsibility;

public abstract class AbstractHandler implements Handler {
private Handler next;

@Override
public void setNext(Handler next) {
this.next = next;
}

@Override
public String handle(int request) {
if (next != null) {
return next.handle(request);
}
return "unhandled";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.penapereira.example.constructs.chainofresponsibility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.penapereira.example.constructs.app.ExampleRunnerInterface;

@Component
public class ChainOfResponsibilityExampleRunner implements ExampleRunnerInterface {

private static final Logger log = LoggerFactory.getLogger(ChainOfResponsibilityExampleRunner.class);

@Override
public void runExample() throws Exception {
log.trace("Executing Chain of Responsibility Pattern Implementation");

Handler negative = new NegativeHandler();
Handler zero = new ZeroHandler();
Handler positive = new PositiveHandler();

negative.setNext(zero);
zero.setNext(positive);

int[] requests = { -1, 0, 1 };
for (int r : requests) {
log.trace(" " + r + " is " + negative.handle(r));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.penapereira.example.constructs.chainofresponsibility;

public interface Handler {
void setNext(Handler next);
String handle(int request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.penapereira.example.constructs.chainofresponsibility;

public class NegativeHandler extends AbstractHandler {
@Override
public String handle(int request) {
if (request < 0) {
return "negative";
}
return super.handle(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.penapereira.example.constructs.chainofresponsibility;

public class PositiveHandler extends AbstractHandler {
@Override
public String handle(int request) {
if (request > 0) {
return "positive";
}
return super.handle(request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Chain of Responsibility Pattern

The chain of responsibility pattern passes a request along a chain of handlers until one of them deals with it.

## Class diagram


```plantuml
@startuml
interface Handler {
+setNext(h)
+handle(request)
}
abstract class AbstractHandler implements Handler {
-next : Handler
}
class NegativeHandler extends AbstractHandler
class ZeroHandler extends AbstractHandler
class PositiveHandler extends AbstractHandler
Handler <|.. AbstractHandler
AbstractHandler --> Handler : next
@enduml
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.penapereira.example.constructs.chainofresponsibility;

public class ZeroHandler extends AbstractHandler {
@Override
public String handle(int request) {
if (request == 0) {
return "zero";
}
return super.handle(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import com.penapereira.example.constructs.app.ExampleRunnerInterface;

import com.penapereira.example.constructs.decorator.ComponentIF;

@Component
public class DecoratorExampleRunner implements ExampleRunnerInterface {

Expand Down
8 changes: 5 additions & 3 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ app.windowMarginX=50
app.windowMarginY=50
app.linkColor=#0645AD
app.linkColorHover=#3366BB
app.enableCommandLineRunner=false

# Messages

msg.windowTitle=Java Patterns and Constructs
msg.greeting=Welcome to Java Patterns and Constructs
msg.info=You can check documentation, examples and diagrams at:
msg.homeUrl=https://github.com/lpenap/java-patterns-and-constructs
msg.examplesFound=Implemented examples found
msg.examplesFound=Examples
msg.instructions=To run an example, click on the button for the desired example.

msg.enableTraceToSeeExamplesDetails= [*] Please enable TRACE log level if you want to see examples output
msg.enableDebugToSeeExamplesList= [*] Please enable DEBUG log level if you want to see the examples list
msg.outputTitle=Output

msg.outputTitle=Logger Output
msg.preserveLog=Preserve log
msg.separator=-------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.penapereira.example.constructs.chainofresponsibility;

import org.junit.jupiter.api.Test;

class ChainOfResponsibilityExampleRunnerTests {
@Test
void runExampleRuns() throws Exception {
new ChainOfResponsibilityExampleRunner().runExample();
}
}
Loading