Java 11 migrate remaining p (#1122)

* Moves partial-response to Java 11

* Moves pipeline to Java 11

* Moves poison-pill to Java 11

* Moves priority-queue to Java 11

* Moves private-class-data to Java 11

* Moves producer-consumer to Java 11

* Moves promise to Java 11

* Moves property to Java 11

* Moves prototype to Java 11

* Moves proxy to Java 11

* Corrects checkstyle errors

* Fixes build for pipeline pattern
This commit is contained in:
Anurag Agarwal 2020-01-16 11:36:36 +05:30 committed by Ilkka Seppälä
parent 1401accb4f
commit 428efc7d53
82 changed files with 532 additions and 601 deletions

View File

@ -24,6 +24,11 @@
package com.iluwatar.masterworker;
import com.iluwatar.masterworker.system.ArrayTransposeMasterWorker;
import com.iluwatar.masterworker.system.MasterWorker;
import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
import com.iluwatar.masterworker.system.systemmaster.Master;
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
import com.iluwatar.masterworker.system.systemworkers.Worker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -26,6 +26,23 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>

View File

@ -71,8 +71,8 @@ public final class App {
public static void main(String[] args) {
try {
File applicationFile =
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
var classLoader = App.class.getClassLoader();
var applicationFile = new File(classLoader.getResource("sample-ui/login.html").getPath());
// should work for unix like OS (mac, unix etc...)
if (Desktop.isDesktopSupported()) {

View File

@ -67,8 +67,8 @@ public final class App {
public static void main(String[] args) {
try {
File applicationFile =
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
var classLoader = App.class.getClassLoader();
var applicationFile = new File(classLoader.getResource("sample-ui/login.html").getPath());
// Should work for unix like OS (mac, unix etc...)
if (Desktop.isDesktopSupported()) {

View File

@ -23,14 +23,14 @@
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import com.iluwatar.pageobject.pages.AlbumListPage;
import com.iluwatar.pageobject.pages.AlbumPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test Album Selection and Album Listing
*/
@ -45,7 +45,7 @@ public class AlbumListPageTest {
@Test
public void testSelectAlbum() {
AlbumPage albumPage = albumListPage.selectAlbum("21");
var albumPage = albumListPage.selectAlbum("21");
albumPage.navigateToPage();
assertTrue(albumPage.isAt());
}

View File

@ -23,14 +23,14 @@
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import com.iluwatar.pageobject.pages.AlbumListPage;
import com.iluwatar.pageobject.pages.AlbumPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test Album Page Operations
*/
@ -46,7 +46,7 @@ public class AlbumPageTest {
@Test
public void testSaveAlbum() {
AlbumPage albumPageAfterChanges = albumPage
var albumPageAfterChanges = albumPage
.changeAlbumTitle("25")
.changeArtist("Adele Laurie Blue Adkins")
.changeAlbumYear(2015)
@ -60,7 +60,7 @@ public class AlbumPageTest {
@Test
public void testCancelChanges() {
AlbumListPage albumListPage = albumPage.cancelChanges();
var albumListPage = albumPage.cancelChanges();
albumListPage.navigateToPage();
assertTrue(albumListPage.isAt());
}

View File

@ -23,14 +23,14 @@
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import com.iluwatar.pageobject.pages.AlbumListPage;
import com.iluwatar.pageobject.pages.LoginPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test Login Page Object
*/
@ -45,7 +45,7 @@ public class LoginPageTest {
@Test
public void testLogin() {
AlbumListPage albumListPage = loginPage
var albumListPage = loginPage
.enterUsername("admin")
.enterPassword("password")
.login();

View File

@ -26,7 +26,6 @@ package com.iluwatar.pageobject.pages;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.util.List;
@ -79,8 +78,8 @@ public class AlbumListPage extends Page {
*/
public AlbumPage selectAlbum(String albumTitle) {
// uses XPath to find list of html anchor tags with the class album in it
List<HtmlAnchor> albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
for (HtmlAnchor anchor : albumLinks) {
var albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
for (var anchor : albumLinks) {
if (anchor.getTextContent().equals(albumTitle)) {
try {
anchor.click();

View File

@ -30,7 +30,6 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.io.IOException;
/**
@ -83,7 +82,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumTitle(String albumTitle) {
HtmlTextInput albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
var albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
albumTitleInputTextField.setText(albumTitle);
return this;
}
@ -96,7 +95,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeArtist(String artist) {
HtmlTextInput artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
var artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
artistInputTextField.setText(artist);
return this;
}
@ -109,8 +108,8 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumYear(int year) {
HtmlSelect albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
HtmlOption yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
var albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
var yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
albumYearSelectOption.setSelectedAttribute(yearOption, true);
return this;
}
@ -123,7 +122,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumRating(String albumRating) {
HtmlTextInput albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
var albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
albumRatingInputTextField.setText(albumRating);
return this;
}
@ -135,7 +134,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
HtmlNumberInput numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
var numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
return this;
}
@ -147,7 +146,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumListPage}
*/
public AlbumListPage cancelChanges() {
HtmlSubmitInput cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
var cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
try {
cancelButton.click();
} catch (IOException e) {
@ -163,7 +162,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage saveChanges() {
HtmlSubmitInput saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
var saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
try {
saveButton.click();
} catch (IOException e) {

View File

@ -79,7 +79,7 @@ public class LoginPage extends Page {
* @return {@link LoginPage}
*/
public LoginPage enterUsername(String username) {
HtmlTextInput usernameInputTextField = (HtmlTextInput) page.getElementById("username");
var usernameInputTextField = (HtmlTextInput) page.getElementById("username");
usernameInputTextField.setText(username);
return this;
}
@ -92,7 +92,7 @@ public class LoginPage extends Page {
* @return {@link LoginPage}
*/
public LoginPage enterPassword(String password) {
HtmlPasswordInput passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
var passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
passwordInputPasswordField.setText(password);
return this;
}
@ -101,11 +101,11 @@ public class LoginPage extends Page {
/**
* Clicking on the login button to 'login'
*
* @return {@link AlbumListPage}
* - this is the page that user gets navigated to once successfully logged in
* @return {@link AlbumListPage} - this is the page that user gets navigated to once successfully
* logged in
*/
public AlbumListPage login() {
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
var loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
try {
loginButton.click();
} catch (IOException e) {

View File

@ -31,8 +31,7 @@ import com.gargoylesoftware.htmlunit.WebClient;
public abstract class Page {
/**
* Application Under Test path
* This directory location is where html web pages are located
* Application Under Test path This directory location is where html web pages are located
*/
public static final String AUT_PATH = "src/main/resources/sample-ui/";

View File

@ -81,8 +81,8 @@ public class AlbumListPage extends Page {
*/
public AlbumPage selectAlbum(String albumTitle) {
// uses XPath to find list of html anchor tags with the class album in it
List<HtmlAnchor> albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
for (HtmlAnchor anchor : albumLinks) {
var albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
for (var anchor : albumLinks) {
if (anchor.getTextContent().equals(albumTitle)) {
try {
anchor.click();

View File

@ -25,7 +25,6 @@ package com.iluwatar.pageobject;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlNumberInput;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
@ -85,7 +84,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumTitle(String albumTitle) {
HtmlTextInput albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
var albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
albumTitleInputTextField.setText(albumTitle);
return this;
}
@ -98,7 +97,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeArtist(String artist) {
HtmlTextInput artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
var artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
artistInputTextField.setText(artist);
return this;
}
@ -111,8 +110,8 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumYear(int year) {
HtmlSelect albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
HtmlOption yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
var albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
var yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
albumYearSelectOption.setSelectedAttribute(yearOption, true);
return this;
}
@ -125,7 +124,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumRating(String albumRating) {
HtmlTextInput albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
var albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
albumRatingInputTextField.setText(albumRating);
return this;
}
@ -137,8 +136,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
HtmlNumberInput numberOfSongsNumberField =
(HtmlNumberInput) page.getElementById("numberOfSongs");
var numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
return this;
}
@ -150,7 +148,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumListPage}
*/
public AlbumListPage cancelChanges() {
HtmlSubmitInput cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
var cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
try {
cancelButton.click();
} catch (IOException e) {
@ -166,7 +164,7 @@ public class AlbumPage extends Page {
* @return {@link AlbumPage}
*/
public AlbumPage saveChanges() {
HtmlSubmitInput saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
var saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
try {
saveButton.click();
} catch (IOException e) {

View File

@ -82,7 +82,7 @@ public class LoginPage extends Page {
* @return {@link LoginPage}
*/
public LoginPage enterUsername(String username) {
HtmlTextInput usernameInputTextField = (HtmlTextInput) page.getElementById("username");
var usernameInputTextField = (HtmlTextInput) page.getElementById("username");
usernameInputTextField.setText(username);
return this;
}
@ -95,8 +95,7 @@ public class LoginPage extends Page {
* @return {@link LoginPage}
*/
public LoginPage enterPassword(String password) {
HtmlPasswordInput passwordInputPasswordField =
(HtmlPasswordInput) page.getElementById("password");
var passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
passwordInputPasswordField.setText(password);
return this;
}
@ -109,7 +108,7 @@ public class LoginPage extends Page {
* logged in
*/
public AlbumListPage login() {
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
var loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
try {
loginButton.click();
} catch (IOException e) {

View File

@ -23,14 +23,12 @@
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import com.iluwatar.pageobject.AlbumListPage;
import com.iluwatar.pageobject.AlbumPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test Album Selection and Album Listing
*/
@ -45,7 +43,7 @@ public class AlbumListPageTest {
@Test
public void testSelectAlbum() {
AlbumPage albumPage = albumListPage.selectAlbum("21");
var albumPage = albumListPage.selectAlbum("21");
albumPage.navigateToPage();
assertTrue(albumPage.isAt());
}

View File

@ -25,11 +25,10 @@ package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* Test Album Page Operations
*/
@ -45,7 +44,7 @@ public class AlbumPageTest {
@Test
public void testSaveAlbum() {
AlbumPage albumPageAfterChanges = albumPage
var albumPageAfterChanges = albumPage
.changeAlbumTitle("25")
.changeArtist("Adele Laurie Blue Adkins")
.changeAlbumYear(2015)
@ -59,7 +58,7 @@ public class AlbumPageTest {
@Test
public void testCancelChanges() {
AlbumListPage albumListPage = albumPage.cancelChanges();
var albumListPage = albumPage.cancelChanges();
albumListPage.navigateToPage();
assertTrue(albumListPage.isAt());
}

View File

@ -25,11 +25,10 @@ package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.gargoylesoftware.htmlunit.WebClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* Test Login Page Object
*/
@ -44,7 +43,7 @@ public class LoginPageTest {
@Test
public void testLogin() {
AlbumListPage albumListPage = loginPage
var albumListPage = loginPage
.enterUsername("admin")
.enterPassword("password")
.login();

View File

@ -44,30 +44,31 @@ public class App {
* @param args program argument.
*/
public static void main(String[] args) throws Exception {
Map<Integer, Video> videos = Map.of(
var videos = Map.of(
1, new Video(1, "Avatar", 178, "epic science fiction film",
"James Cameron", "English"),
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
"Hideaki Anno", "Japanese"),
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
"Christopher Nolan", "English"));
VideoResource videoResource = new VideoResource(new FieldJsonMapper(), videos);
"Christopher Nolan", "English")
);
var videoResource = new VideoResource(new FieldJsonMapper(), videos);
LOGGER.info("Retrieving full response from server:-");
LOGGER.info("Get all video information:");
String videoDetails = videoResource.getDetails(1);
var videoDetails = videoResource.getDetails(1);
LOGGER.info(videoDetails);
LOGGER.info("----------------------------------------------------------");
LOGGER.info("Retrieving partial response from server:-");
LOGGER.info("Get video @id, @title, @director:");
String specificFieldsDetails = videoResource.getDetails(3, "id", "title", "director");
var specificFieldsDetails = videoResource.getDetails(3, "id", "title", "director");
LOGGER.info(specificFieldsDetails);
LOGGER.info("Get video @id, @length:");
String videoLength = videoResource.getDetails(3, "id", "length");
var videoLength = videoResource.getDetails(3, "id", "length");
LOGGER.info(videoLength);
}
}

View File

@ -38,13 +38,16 @@ public class FieldJsonMapper {
* @return json of required fields from video
*/
public String toJson(Video video, String[] fields) throws Exception {
StringBuilder json = new StringBuilder().append("{");
var json = new StringBuilder().append("{");
for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
var i = 0;
var fieldsLength = fields.length;
while (i < fieldsLength) {
json.append(getString(video, Video.class.getDeclaredField(fields[i])));
if (i != fieldsLength - 1) {
json.append(",");
}
i++;
}
json.append("}");
return json.toString();
@ -52,7 +55,7 @@ public class FieldJsonMapper {
private String getString(Video video, Field declaredField) throws IllegalAccessException {
declaredField.setAccessible(true);
Object value = declaredField.get(video);
var value = declaredField.get(video);
if (declaredField.get(video) instanceof Integer) {
return "\"" + declaredField.getName() + "\"" + ": " + value;
}

View File

@ -32,8 +32,7 @@ public class AppTest {
@Test
public void main() throws Exception {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,11 +23,11 @@
package com.iluwatar.partialresponse;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* tests {@link FieldJsonMapper}.
*/
@ -41,12 +41,15 @@ public class FieldJsonMapperTest {
@Test
public void shouldReturnJsonForSpecifiedFieldsInVideo() throws Exception {
String[] fields = new String[]{"id", "title", "length"};
Video video = new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|", "Hideaki Anno", "Japanese");
var fields = new String[]{"id", "title", "length"};
var video = new Video(
2, "Godzilla Resurgence", 120,
"Action & drama movie|", "Hideaki Anno", "Japanese"
);
String jsonFieldResponse = mapper.toJson(video, fields);
var jsonFieldResponse = mapper.toJson(video, fields);
String expectedDetails = "{\"id\": 2,\"title\": \"Godzilla Resurgence\",\"length\": 120}";
var expectedDetails = "{\"id\": 2,\"title\": \"Godzilla Resurgence\",\"length\": 120}";
assertEquals(expectedDetails, jsonFieldResponse);
}
}

View File

@ -23,19 +23,18 @@
package com.iluwatar.partialresponse;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
/**
* tests {@link VideoResource}.
*/
@ -48,33 +47,33 @@ public class VideoResourceTest {
@Before
public void setUp() {
Map<Integer, Video> videos = Map.of(
1, new Video(1, "Avatar", 178, "epic science fiction film",
"James Cameron", "English"),
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
"Hideaki Anno", "Japanese"),
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
"Christopher Nolan", "English"));
var videos = Map.of(
1, new Video(1, "Avatar", 178, "epic science fiction film",
"James Cameron", "English"),
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
"Hideaki Anno", "Japanese"),
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
"Christopher Nolan", "English"));
resource = new VideoResource(fieldJsonMapper, videos);
}
@Test
public void shouldGiveVideoDetailsById() throws Exception {
String actualDetails = resource.getDetails(1);
var actualDetails = resource.getDetails(1);
String expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178,\"description\": "
var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178,\"description\": "
+ "\"epic science fiction film\",\"director\": \"James Cameron\",\"language\": \"English\",}";
assertEquals(expectedDetails, actualDetails);
}
@Test
public void shouldGiveSpecifiedFieldsInformationOfVideo() throws Exception {
String[] fields = new String[]{"id", "title", "length"};
var fields = new String[]{"id", "title", "length"};
String expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}";
var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}";
when(fieldJsonMapper.toJson(any(Video.class), eq(fields))).thenReturn(expectedDetails);
String actualFieldsDetails = resource.getDetails(2, fields);
var actualFieldsDetails = resource.getDetails(2, fields);
assertEquals(expectedDetails, actualFieldsDetails);
}

View File

@ -36,11 +36,12 @@ class ConvertToCharArrayHandler implements Handler<String, char[]> {
@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));
var characters = input.toCharArray();
var string = Arrays.toString(characters);
LOGGER.info(
String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
ConvertToCharArrayHandler.class, input, String.class, string, Character[].class)
);
return characters;
}

View File

@ -23,6 +23,7 @@
package com.iluwatar.pipeline;
import java.util.function.IntPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,18 +37,14 @@ class RemoveAlphabetsHandler implements Handler<String, String> {
@Override
public String process(String input) {
StringBuilder inputWithoutAlphabets = new StringBuilder();
var inputWithoutAlphabets = new StringBuilder();
var isAlphabetic = (IntPredicate) Character::isAlphabetic;
input.chars()
.filter(isAlphabetic.negate())
.mapToObj(x -> (char) x)
.forEachOrdered(inputWithoutAlphabets::append);
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();
var inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
LOGGER.info(
String.format(
"Current handler: %s, input is %s of type %s, output is %s, of type %s",

View File

@ -23,6 +23,7 @@
package com.iluwatar.pipeline;
import java.util.function.IntPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,21 +37,20 @@ class RemoveDigitsHandler implements Handler<String, String> {
@Override
public String process(String input) {
StringBuilder inputWithoutDigits = new StringBuilder();
var inputWithoutDigits = new StringBuilder();
var isDigit = (IntPredicate) Character::isDigit;
input.chars()
.filter(isDigit.negate())
.mapToObj(x -> (char) x)
.forEachOrdered(inputWithoutDigits::append);
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));
var 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;
}

View File

@ -32,7 +32,6 @@ public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,10 +23,10 @@
package com.iluwatar.pipeline;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import org.junit.jupiter.api.Test;
/**
* Test for {@link Pipeline}
*/
@ -34,12 +34,12 @@ public class PipelineTest {
@Test
public void testAddHandlersToPipeline() {
Pipeline<String, char[]> filters = new Pipeline<>(new RemoveAlphabetsHandler())
var filters = new Pipeline<>(new RemoveAlphabetsHandler())
.addHandler(new RemoveDigitsHandler())
.addHandler(new ConvertToCharArrayHandler());
assertArrayEquals(
new char[] {'#', '!', '(', '&', '%', '#', '!'},
new char[]{'#', '!', '(', '&', '%', '#', '!'},
filters.execute("#H!E(L&L0O%THE3R#34E!")
);
}

View File

@ -42,26 +42,18 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
MessageQueue queue = new SimpleMessageQueue(10000);
var queue = new SimpleMessageQueue(10000);
final Producer producer = new Producer("PRODUCER_1", queue);
final Consumer consumer = new Consumer("CONSUMER_1", queue);
final var producer = new Producer("PRODUCER_1", queue);
final var consumer = new Consumer("CONSUMER_1", queue);
new Thread() {
@Override
public void run() {
consumer.consume();
}
}.start();
new Thread(consumer::consume).start();
new Thread() {
@Override
public void run() {
producer.send("hand shake");
producer.send("some very important information");
producer.send("bye!");
producer.stop();
}
}.start();
new Thread(() -> {
producer.send("hand shake");
producer.send("some very important information");
producer.send("bye!");
producer.stop();
}).start();
}
}

View File

@ -47,22 +47,20 @@ public class Consumer {
*/
public void consume() {
while (true) {
Message msg;
try {
msg = queue.take();
var msg = queue.take();
if (Message.POISON_PILL.equals(msg)) {
LOGGER.info("Consumer {} receive request to terminate.", name);
break;
}
var sender = msg.getHeader(Headers.SENDER);
var body = msg.getBody();
LOGGER.info("Message [{}] from [{}] received by [{}]", body, sender, name);
} catch (InterruptedException e) {
// allow thread to exit
LOGGER.error("Exception caught.", e);
return;
}
String sender = msg.getHeader(Headers.SENDER);
String body = msg.getBody();
LOGGER.info("Message [{}] from [{}] received by [{}]", body, sender, name);
}
}
}

View File

@ -57,7 +57,7 @@ public class Producer {
throw new IllegalStateException(String.format(
"Producer %s was stopped and fail to deliver requested message [%s].", body, name));
}
Message msg = new SimpleMessage();
var msg = new SimpleMessage();
msg.addHeader(Headers.DATE, new Date().toString());
msg.addHeader(Headers.SENDER, name);
msg.setBody(body);

View File

@ -26,15 +26,12 @@ package com.iluwatar.poison.pill;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,20 +23,19 @@
package com.iluwatar.poison.pill;
import static org.junit.jupiter.api.Assertions.assertTrue;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Date: 12/27/15 - 9:45 PM
*
@ -58,15 +57,15 @@ public class ConsumerTest {
@Test
public void testConsume() throws Exception {
final Message[] messages = new Message[]{
final var messages = List.of(
createMessage("you", "Hello!"),
createMessage("me", "Hi!"),
Message.POISON_PILL,
createMessage("late_for_the_party", "Hello? Anyone here?"),
};
createMessage("late_for_the_party", "Hello? Anyone here?")
);
final MessageQueue queue = new SimpleMessageQueue(messages.length);
for (final Message message : messages) {
final var queue = new SimpleMessageQueue(messages.size());
for (final var message : messages) {
queue.put(message);
}
@ -85,7 +84,7 @@ public class ConsumerTest {
* @return The message instance
*/
private static Message createMessage(final String sender, final String message) {
final SimpleMessage msg = new SimpleMessage();
final var msg = new SimpleMessage();
msg.addHeader(Message.Headers.SENDER, sender);
msg.addHeader(Message.Headers.DATE, LocalDateTime.now().toString());
msg.setBody(message);
@ -106,7 +105,7 @@ public class ConsumerTest {
}
public boolean logContains(String message) {
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
return log.stream().map(ILoggingEvent::getFormattedMessage).anyMatch(message::equals);
}
}

View File

@ -23,12 +23,12 @@
package com.iluwatar.poison.pill;
import org.junit.jupiter.api.Test;
import static com.iluwatar.poison.pill.Message.Headers;
import static com.iluwatar.poison.pill.Message.POISON_PILL;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
/**
* Date: 12/27/15 - 10:30 PM
*

View File

@ -23,9 +23,6 @@
package com.iluwatar.poison.pill;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@ -35,6 +32,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
/**
* Date: 12/27/15 - 10:32 PM
*
@ -44,16 +44,16 @@ public class ProducerTest {
@Test
public void testSend() throws Exception {
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
final Producer producer = new Producer("producer", publishPoint);
final var publishPoint = mock(MqPublishPoint.class);
final var producer = new Producer("producer", publishPoint);
verifyZeroInteractions(publishPoint);
producer.send("Hello!");
final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
final var messageCaptor = ArgumentCaptor.forClass(Message.class);
verify(publishPoint).put(messageCaptor.capture());
final Message message = messageCaptor.getValue();
final var message = messageCaptor.getValue();
assertNotNull(message);
assertEquals("producer", message.getHeader(Message.Headers.SENDER));
assertNotNull(message.getHeader(Message.Headers.DATE));
@ -64,8 +64,8 @@ public class ProducerTest {
@Test
public void testStop() throws Exception {
final MqPublishPoint publishPoint = mock(MqPublishPoint.class);
final Producer producer = new Producer("producer", publishPoint);
final var publishPoint = mock(MqPublishPoint.class);
final var producer = new Producer("producer", publishPoint);
verifyZeroInteractions(publishPoint);
producer.stop();
@ -78,7 +78,7 @@ public class ProducerTest {
assertNotNull(e);
assertNotNull(e.getMessage());
assertEquals("Producer Hello! was stopped and fail to deliver requested message [producer].",
e.getMessage());
e.getMessage());
}
verifyNoMoreInteractions(publishPoint);

View File

@ -23,16 +23,14 @@
package com.iluwatar.poison.pill;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/**
* Date: 12/27/15 - 10:25 PM
*
@ -42,11 +40,11 @@ public class SimpleMessageTest {
@Test
public void testGetHeaders() {
final SimpleMessage message = new SimpleMessage();
final var message = new SimpleMessage();
assertNotNull(message.getHeaders());
assertTrue(message.getHeaders().isEmpty());
final String senderName = "test";
final var senderName = "test";
message.addHeader(Message.Headers.SENDER, senderName);
assertNotNull(message.getHeaders());
assertFalse(message.getHeaders().isEmpty());
@ -55,8 +53,8 @@ public class SimpleMessageTest {
@Test
public void testUnModifiableHeaders() {
final SimpleMessage message = new SimpleMessage();
final Map<Message.Headers, String> headers = message.getHeaders();
final var message = new SimpleMessage();
final var headers = message.getHeaders();
assertThrows(UnsupportedOperationException.class, () -> {
headers.put(Message.Headers.SENDER, "test");
});

View File

@ -37,22 +37,22 @@ public class Application {
*/
public static void main(String[] args) throws Exception {
QueueManager queueManager = new QueueManager(100);
var queueManager = new QueueManager(100);
// push some message to queue
// Low Priority message
for (int i = 0; i < 100; i++) {
for (var i = 0; i < 100; i++) {
queueManager.publishMessage(new Message("Low Message Priority", 0));
}
// High Priority message
for (int i = 0; i < 100; i++) {
for (var i = 0; i < 100; i++) {
queueManager.publishMessage(new Message("High Message Priority", 1));
}
// run worker
Worker worker = new Worker(queueManager);
var worker = new Worker(queueManager);
worker.run();

View File

@ -57,7 +57,7 @@ public class PriorityMessageQueue<T extends Comparable> {
return null;
}
final T root = queue[0];
final var root = queue[0];
queue[0] = queue[size - 1];
size--;
maxHeapifyDown();
@ -83,10 +83,10 @@ public class PriorityMessageQueue<T extends Comparable> {
private void maxHeapifyDown() {
int index = 0;
var index = 0;
while (hasLeftChild(index)) {
int smallerIndex = leftChildIndex(index);
var smallerIndex = leftChildIndex(index);
if (hasRightChild(index) && right(index).compareTo(left(index)) > 0) {
smallerIndex = rightChildIndex(index);
@ -106,7 +106,7 @@ public class PriorityMessageQueue<T extends Comparable> {
}
private void maxHeapifyUp() {
int index = size - 1;
var index = size - 1;
while (hasParent(index) && parent(index).compareTo(queue[index]) < 0) {
swap(parentIndex(index), index);
index = parentIndex(index);
@ -154,7 +154,7 @@ public class PriorityMessageQueue<T extends Comparable> {
}
private void swap(int fpos, int tpos) {
T tmp = queue[fpos];
var tmp = queue[fpos];
queue[fpos] = queue[tpos];
queue[tpos] = tmp;
}
@ -170,7 +170,7 @@ public class PriorityMessageQueue<T extends Comparable> {
* For debug .. print current state of queue
*/
public void print() {
for (int i = 0; i <= size / 2; i++) {
for (var i = 0; i <= size / 2; i++) {
LOGGER.info(" PARENT : " + queue[i] + " LEFT CHILD : "
+ left(i) + " RIGHT CHILD :" + right(i));
}

View File

@ -33,7 +33,7 @@ public class QueueManager {
private final PriorityMessageQueue<Message> messagePriorityMessageQueue;
public QueueManager(int initialCapacity) {
messagePriorityMessageQueue = new PriorityMessageQueue<Message>(new Message[initialCapacity]);
messagePriorityMessageQueue = new PriorityMessageQueue<>(new Message[initialCapacity]);
}
/**

View File

@ -45,7 +45,7 @@ public class Worker {
@SuppressWarnings("squid:S2189")
public void run() throws Exception {
while (true) {
Message message = queueManager.receiveMessage();
var message = queueManager.receiveMessage();
if (message == null) {
LOGGER.info("No Message ... waiting");
Thread.sleep(200);

View File

@ -23,11 +23,11 @@
package com.iluwatar.priority.queue;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
/**
* Test case for order of messages
*/
@ -36,25 +36,25 @@ public class PriorityMessageQueueTest {
@Test
public void remove() {
PriorityMessageQueue<String> stringPriorityMessageQueue = new PriorityMessageQueue<>(new String[2]);
String pushMessage = "test";
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new String[2]);
var pushMessage = "test";
stringPriorityMessageQueue.add(pushMessage);
assertEquals(stringPriorityMessageQueue.remove(), pushMessage);
}
@Test
public void add() {
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
stringPriorityMessageQueue.add(1);
stringPriorityMessageQueue.add(5);
stringPriorityMessageQueue.add(10);
stringPriorityMessageQueue.add(3);
assertTrue(stringPriorityMessageQueue.remove() == 10);
assertEquals(10, (int) stringPriorityMessageQueue.remove());
}
@Test
public void isEmpty() {
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
assertTrue(stringPriorityMessageQueue.isEmpty());
stringPriorityMessageQueue.add(1);
stringPriorityMessageQueue.remove();
@ -63,12 +63,12 @@ public class PriorityMessageQueueTest {
@Test
public void testEnsureSize() {
PriorityMessageQueue<Integer> stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
var stringPriorityMessageQueue = new PriorityMessageQueue<>(new Integer[2]);
assertTrue(stringPriorityMessageQueue.isEmpty());
stringPriorityMessageQueue.add(1);
stringPriorityMessageQueue.add(2);
stringPriorityMessageQueue.add(2);
stringPriorityMessageQueue.add(3);
assertTrue(stringPriorityMessageQueue.remove() == 3);
assertEquals(3, (int) stringPriorityMessageQueue.remove());
}
}

View File

@ -23,10 +23,10 @@
package com.iluwatar.priority.queue;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
* Check queue manager
*/
@ -34,21 +34,21 @@ public class QueueManagerTest {
@Test
public void publishMessage() {
QueueManager queueManager = new QueueManager(2);
Message testMessage = new Message("Test Message", 1);
var queueManager = new QueueManager(2);
var testMessage = new Message("Test Message", 1);
queueManager.publishMessage(testMessage);
Message recivedMessage = queueManager.receiveMessage();
var recivedMessage = queueManager.receiveMessage();
assertEquals(testMessage, recivedMessage);
}
@Test
public void receiveMessage() {
QueueManager queueManager = new QueueManager(2);
Message testMessage1 = new Message("Test Message 1", 1);
var queueManager = new QueueManager(2);
var testMessage1 = new Message("Test Message 1", 1);
queueManager.publishMessage(testMessage1);
Message testMessage2 = new Message("Test Message 2", 2);
var testMessage2 = new Message("Test Message 2", 2);
queueManager.publishMessage(testMessage2);
Message recivedMessage = queueManager.receiveMessage();
var recivedMessage = queueManager.receiveMessage();
assertEquals(testMessage2, recivedMessage);
}
}

View File

@ -46,13 +46,13 @@ public class App {
*/
public static void main(String[] args) {
// stew is mutable
Stew stew = new Stew(1, 2, 3, 4);
var stew = new Stew(1, 2, 3, 4);
stew.mix();
stew.taste();
stew.mix();
// immutable stew protected with Private Class Data pattern
ImmutableStew immutableStew = new ImmutableStew(2, 4, 3, 6);
var immutableStew = new ImmutableStew(2, 4, 3, 6);
immutableStew.mix();
}
}

View File

@ -26,15 +26,12 @@ package com.iluwatar.privateclassdata;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,13 +23,13 @@
package com.iluwatar.privateclassdata;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.privateclassdata.utils.InMemoryAppender;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Date: 12/27/15 - 10:46 PM
*
@ -54,10 +54,10 @@ public class ImmutableStewTest {
*/
@Test
public void testMix() {
final Stew stew = new Stew(1, 2, 3, 4);
final String expectedMessage = "Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers";
var stew = new Stew(1, 2, 3, 4);
var expectedMessage = "Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers";
for (int i = 0; i < 20; i++) {
for (var i = 0; i < 20; i++) {
stew.mix();
assertEquals(expectedMessage, appender.getLastMessage());
}
@ -70,15 +70,17 @@ public class ImmutableStewTest {
*/
@Test
public void testDrink() {
final Stew stew = new Stew(1, 2, 3, 4);
final var stew = new Stew(1, 2, 3, 4);
stew.mix();
assertEquals("Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers", appender.getLastMessage());
assertEquals("Mixing the stew we find: 1 potatoes, 2 carrots, 3 meat and 4 peppers", appender
.getLastMessage());
stew.taste();
assertEquals("Tasting the stew", appender.getLastMessage());
assertEquals("Tasting the stew", appender.getLastMessage());
stew.mix();
assertEquals("Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers", appender.getLastMessage());
assertEquals("Mixing the stew we find: 0 potatoes, 1 carrots, 2 meat and 3 peppers", appender
.getLastMessage());
}
}

View File

@ -23,13 +23,13 @@
package com.iluwatar.privateclassdata;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.privateclassdata.utils.InMemoryAppender;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Date: 12/27/15 - 10:46 PM
*
@ -54,11 +54,11 @@ public class StewTest {
*/
@Test
public void testMix() {
final ImmutableStew stew = new ImmutableStew(1, 2, 3, 4);
final String expectedMessage = "Mixing the immutable stew we find: 1 potatoes, "
final var stew = new ImmutableStew(1, 2, 3, 4);
final var expectedMessage = "Mixing the immutable stew we find: 1 potatoes, "
+ "2 carrots, 3 meat and 4 peppers";
for (int i = 0; i < 20; i++) {
for (var i = 0; i < 20; i++) {
stew.mix();
assertEquals(expectedMessage, appender.getLastMessage());
}

View File

@ -26,10 +26,9 @@ package com.iluwatar.privateclassdata.utils;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.LoggerFactory;
/**
* InMemory Log Appender Util.

View File

@ -26,20 +26,18 @@ package com.iluwatar.producer.consumer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Producer Consumer Design pattern is a classic concurrency or threading pattern which reduces
* coupling between Producer and Consumer by separating Identification of work with
* Execution of Work.
* coupling between Producer and Consumer by separating Identification of work with Execution of
* Work.
*
* <p>In producer consumer design pattern a shared queue is used to control the flow and this
* separation allows you to code producer and consumer separately. It also addresses the issue
* of different timing require to produce item or consuming item. by using producer consumer
* pattern both Producer and Consumer Thread can work with different speed.
*
* separation allows you to code producer and consumer separately. It also addresses the issue of
* different timing require to produce item or consuming item. by using producer consumer pattern
* both Producer and Consumer Thread can work with different speed.
*/
public class App {
@ -47,18 +45,17 @@ public class App {
/**
* Program entry point.
*
* @param args
* command line args
*
* @param args command line args
*/
public static void main(String[] args) {
ItemQueue queue = new ItemQueue();
var queue = new ItemQueue();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 2; i++) {
var executorService = Executors.newFixedThreadPool(5);
for (var i = 0; i < 2; i++) {
final Producer producer = new Producer("Producer_" + i, queue);
final var producer = new Producer("Producer_" + i, queue);
executorService.submit(() -> {
while (true) {
producer.produce();
@ -66,8 +63,8 @@ public class App {
});
}
for (int i = 0; i < 3; i++) {
final Consumer consumer = new Consumer("Consumer_" + i, queue);
for (var i = 0; i < 3; i++) {
final var consumer = new Consumer("Consumer_" + i, queue);
executorService.submit(() -> {
while (true) {
consumer.consume();

View File

@ -46,10 +46,9 @@ public class Consumer {
* Consume item from the queue.
*/
public void consume() throws InterruptedException {
Item item = queue.take();
var item = queue.take();
LOGGER.info("Consumer [{}] consume item [{}] produced by [{}]", name,
item.getId(), item.getProducer());
item.getId(), item.getProducer());
}
}

View File

@ -30,7 +30,7 @@ import java.util.Random;
* to queue.
*/
public class Producer {
private static final Random RANDOM = new Random();
private final ItemQueue queue;
@ -49,7 +49,7 @@ public class Producer {
*/
public void produce() throws InterruptedException {
Item item = new Item(name, itemId++);
var item = new Item(name, itemId++);
queue.put(item);
Thread.sleep(RANDOM.nextInt(2000));
}

View File

@ -26,16 +26,13 @@ package com.iluwatar.producer.consumer;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() throws Exception {
String[] args = {};
App.main(args);
public void test() {
App.main(new String[]{});
}
}

View File

@ -23,13 +23,13 @@
package com.iluwatar.producer.consumer;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.Test;
/**
* Date: 12/27/15 - 11:01 PM
*
@ -41,15 +41,15 @@ public class ConsumerTest {
@Test
public void testConsume() throws Exception {
final ItemQueue queue = spy(new ItemQueue());
for (int id = 0; id < ITEM_COUNT; id++) {
final var queue = spy(new ItemQueue());
for (var id = 0; id < ITEM_COUNT; id++) {
queue.put(new Item("producer", id));
}
reset(queue); // Don't count the preparation above as interactions with the queue
final Consumer consumer = new Consumer("consumer", queue);
final var consumer = new Consumer("consumer", queue);
for (int id = 0; id < ITEM_COUNT; id++) {
for (var id = 0; id < ITEM_COUNT; id++) {
consumer.consume();
}

View File

@ -23,8 +23,6 @@
package com.iluwatar.producer.consumer;
import org.junit.jupiter.api.Test;
import static java.time.Duration.ofMillis;
import static org.junit.jupiter.api.Assertions.assertTimeout;
import static org.mockito.Matchers.any;
@ -32,6 +30,8 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import org.junit.jupiter.api.Test;
/**
* Date: 12/28/15 - 12:12 AM
*
@ -42,8 +42,8 @@ public class ProducerTest {
@Test
public void testProduce() {
assertTimeout(ofMillis(6000), () -> {
final ItemQueue queue = mock(ItemQueue.class);
final Producer producer = new Producer("producer", queue);
final var queue = mock(ItemQueue.class);
final var producer = new Producer("producer", queue);
producer.produce();
verify(queue).put(any(Item.class));

View File

@ -29,19 +29,18 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Promise object is used for asynchronous computations. A Promise represents an operation
* that hasn't completed yet, but is expected in the future.
* The Promise object is used for asynchronous computations. A Promise represents an operation that
* hasn't completed yet, but is expected in the future.
*
* <p>A Promise represents a proxy for a value not necessarily known when the promise is created. It
* allows you to associate dependent promises to an asynchronous action's eventual success value or
* failure reason. This lets asynchronous methods return values like synchronous methods: instead
* of the final value, the asynchronous method returns a promise of having a value at some point
* in the future.
* <p>A Promise represents a proxy for a value not necessarily known when the promise is created.
* It allows you to associate dependent promises to an asynchronous action's eventual success value
* or failure reason. This lets asynchronous methods return values like synchronous methods: instead
* of the final value, the asynchronous method returns a promise of having a value at some point in
* the future.
*
* <p>Promises provide a few advantages over callback objects:
* <ul>
@ -58,14 +57,15 @@ import org.slf4j.LoggerFactory;
* a file download promise, then a promise of character frequency, then a promise of lowest
* frequency character which is finally consumed and result is printed on console.
* </ul>
*
*
* @see CompletableFuture
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private static final String DEFAULT_URL = "https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/promise/README.md";
private static final String DEFAULT_URL =
"https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/promise/README.md";
private final ExecutorService executor;
private final CountDownLatch stopLatch;
@ -76,12 +76,13 @@ public class App {
/**
* Program entry point.
*
* @param args arguments
* @throws InterruptedException if main thread is interrupted.
* @throws ExecutionException if an execution error occurs.
* @throws ExecutionException if an execution error occurs.
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
App app = new App();
var app = new App();
try {
app.promiseUsage();
} finally {
@ -100,13 +101,12 @@ public class App {
* consume the result in a Consumer<Character>
*/
private void calculateLowestFrequencyChar() {
lowestFrequencyChar()
.thenAccept(
charFrequency -> {
LOGGER.info("Char with lowest frequency is: {}", charFrequency);
taskCompleted();
}
);
lowestFrequencyChar().thenAccept(
charFrequency -> {
LOGGER.info("Char with lowest frequency is: {}", charFrequency);
taskCompleted();
}
);
}
/*
@ -114,13 +114,12 @@ public class App {
* in a Consumer<Integer>
*/
private void calculateLineCount() {
countLines()
.thenAccept(
count -> {
LOGGER.info("Line count is: {}", count);
taskCompleted();
}
);
countLines().thenAccept(
count -> {
LOGGER.info("Line count is: {}", count);
taskCompleted();
}
);
}
/*
@ -128,17 +127,15 @@ public class App {
* then promise to apply function to calculate lowest character frequency.
*/
private Promise<Character> lowestFrequencyChar() {
return characterFrequency()
.thenApply(Utility::lowestFrequencyChar);
return characterFrequency().thenApply(Utility::lowestFrequencyChar);
}
/*
* Download the file at DEFAULT_URL and when that promise is fulfilled,
* then promise to apply function to calculate character frequency.
*/
private Promise<Map<Character, Integer>> characterFrequency() {
return download(DEFAULT_URL)
.thenApply(Utility::characterFrequency);
private Promise<Map<Character, Long>> characterFrequency() {
return download(DEFAULT_URL).thenApply(Utility::characterFrequency);
}
/*
@ -146,8 +143,7 @@ public class App {
* then promise to apply function to count lines in that file.
*/
private Promise<Integer> countLines() {
return download(DEFAULT_URL)
.thenApply(Utility::countLines);
return download(DEFAULT_URL).thenApply(Utility::countLines);
}
/*

View File

@ -32,10 +32,10 @@ import java.util.function.Function;
/**
* A Promise represents a proxy for a value not necessarily known when the promise is created. It
* allows you to associate dependent promises to an asynchronous action's eventual success value or
* failure reason. This lets asynchronous methods return values like synchronous methods: instead
* of the final value, the asynchronous method returns a promise of having a value at some point
* in the future.
*
* failure reason. This lets asynchronous methods return values like synchronous methods: instead of
* the final value, the asynchronous method returns a promise of having a value at some point in the
* future.
*
* @param <T> type of result.
*/
public class Promise<T> extends PromiseSupport<T> {
@ -51,6 +51,7 @@ public class Promise<T> extends PromiseSupport<T> {
/**
* Fulfills the promise with the provided value.
*
* @param value the fulfilled value that can be accessed using {@link #get()}.
*/
@Override
@ -61,8 +62,9 @@ public class Promise<T> extends PromiseSupport<T> {
/**
* Fulfills the promise with exception due to error in execution.
* @param exception the exception will be wrapped in {@link ExecutionException}
* when accessing the value using {@link #get()}.
*
* @param exception the exception will be wrapped in {@link ExecutionException} when accessing the
* value using {@link #get()}.
*/
@Override
public void fulfillExceptionally(Exception exception) {
@ -86,10 +88,10 @@ public class Promise<T> extends PromiseSupport<T> {
}
/**
* Executes the task using the executor in other thread and fulfills the promise returned
* once the task completes either successfully or with an exception.
*
* @param task the task that will provide the value to fulfill the promise.
* Executes the task using the executor in other thread and fulfills the promise returned once the
* task completes either successfully or with an exception.
*
* @param task the task that will provide the value to fulfill the promise.
* @param executor the executor in which the task should be run.
* @return a promise that represents the result of running the task provided.
*/
@ -105,21 +107,23 @@ public class Promise<T> extends PromiseSupport<T> {
}
/**
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with
* result of this promise as argument to the action provided.
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with result
* of this promise as argument to the action provided.
*
* @param action action to be executed.
* @return a new promise.
*/
public Promise<Void> thenAccept(Consumer<? super T> action) {
Promise<Void> dest = new Promise<>();
var dest = new Promise<Void>();
fulfillmentAction = new ConsumeAction(this, dest, action);
return dest;
}
/**
* Set the exception handler on this promise.
* @param exceptionHandler a consumer that will handle the exception occurred while fulfilling
* the promise.
*
* @param exceptionHandler a consumer that will handle the exception occurred while fulfilling the
* promise.
* @return this
*/
public Promise<T> onError(Consumer<? super Throwable> exceptionHandler) {
@ -128,8 +132,9 @@ public class Promise<T> extends PromiseSupport<T> {
}
/**
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with
* result of this promise as argument to the function provided.
* Returns a new promise that, when this promise is fulfilled normally, is fulfilled with result
* of this promise as argument to the function provided.
*
* @param func function to be executed.
* @return a new promise.
*/
@ -140,8 +145,8 @@ public class Promise<T> extends PromiseSupport<T> {
}
/**
* Accesses the value from source promise and calls the consumer, then fulfills the
* destination promise.
* Accesses the value from source promise and calls the consumer, then fulfills the destination
* promise.
*/
private class ConsumeAction implements Runnable {

View File

@ -27,16 +27,15 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A really simplified implementation of future that allows completing it successfully with a value
* A really simplified implementation of future that allows completing it successfully with a value
* or exceptionally with an exception.
*/
class PromiseSupport<T> implements Future<T> {
private static final Logger LOGGER = LoggerFactory.getLogger(PromiseSupport.class);
private static final int RUNNING = 1;
@ -93,13 +92,12 @@ class PromiseSupport<T> implements Future<T> {
}
if (state == COMPLETED) {
return value;
}
}
throw new ExecutionException(exception);
}
@Override
public T get(long timeout, TimeUnit unit)
throws ExecutionException, TimeoutException {
public T get(long timeout, TimeUnit unit) throws ExecutionException {
synchronized (lock) {
while (state == RUNNING) {
try {
@ -110,10 +108,10 @@ class PromiseSupport<T> implements Future<T> {
}
}
}
if (state == COMPLETED) {
return value;
}
}
throw new ExecutionException(exception);
}
}

View File

@ -29,13 +29,13 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,86 +48,68 @@ public class Utility {
/**
* Calculates character frequency of the file provided.
*
* @param fileLocation location of the file.
* @return a map of character to its frequency, an empty map if file does not exist.
*/
public static Map<Character, Integer> characterFrequency(String fileLocation) {
Map<Character, Integer> characterToFrequency = new HashMap<>();
try (Reader reader = new FileReader(fileLocation);
BufferedReader bufferedReader = new BufferedReader(reader)) {
for (String line; (line = bufferedReader.readLine()) != null;) {
for (char c : line.toCharArray()) {
if (!characterToFrequency.containsKey(c)) {
characterToFrequency.put(c, 1);
} else {
characterToFrequency.put(c, characterToFrequency.get(c) + 1);
}
}
}
public static Map<Character, Long> characterFrequency(String fileLocation) {
try (var bufferedReader = new BufferedReader(new FileReader(fileLocation))) {
return bufferedReader.lines()
.flatMapToInt(String::chars)
.mapToObj(x -> (char) x)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
} catch (IOException ex) {
ex.printStackTrace();
}
return characterToFrequency;
return Collections.emptyMap();
}
/**
* Return the character with the lowest frequency, if exists.
*
* @return the character, {@code Optional.empty()} otherwise.
*/
public static Character lowestFrequencyChar(Map<Character, Integer> charFrequency) {
Character lowestFrequencyChar = null;
Iterator<Entry<Character, Integer>> iterator = charFrequency.entrySet().iterator();
Entry<Character, Integer> entry = iterator.next();
int minFrequency = entry.getValue();
lowestFrequencyChar = entry.getKey();
while (iterator.hasNext()) {
entry = iterator.next();
if (entry.getValue() < minFrequency) {
minFrequency = entry.getValue();
lowestFrequencyChar = entry.getKey();
}
}
return lowestFrequencyChar;
public static Character lowestFrequencyChar(Map<Character, Long> charFrequency) {
return charFrequency
.entrySet()
.stream()
.min(Comparator.comparingLong(Entry::getValue))
.map(Entry::getKey)
.orElseThrow();
}
/**
* Count the number of lines in a file.
*
* @return number of lines, 0 if file does not exist.
*/
public static Integer countLines(String fileLocation) {
int lineCount = 0;
try (Reader reader = new FileReader(fileLocation);
BufferedReader bufferedReader = new BufferedReader(reader)) {
while (bufferedReader.readLine() != null) {
lineCount++;
}
try (var bufferedReader = new BufferedReader(new FileReader(fileLocation))) {
return (int) bufferedReader.lines().count();
} catch (IOException ex) {
ex.printStackTrace();
}
return lineCount;
return 0;
}
/**
* Downloads the contents from the given urlString, and stores it in a temporary directory.
*
* @return the absolute path of the file downloaded.
*/
public static String downloadFile(String urlString) throws IOException {
LOGGER.info("Downloading contents from url: {}", urlString);
URL url = new URL(urlString);
File file = File.createTempFile("promise_pattern", null);
try (Reader reader = new InputStreamReader(url.openStream());
BufferedReader bufferedReader = new BufferedReader(reader);
FileWriter writer = new FileWriter(file)) {
for (String line; (line = bufferedReader.readLine()) != null; ) {
var url = new URL(urlString);
var file = File.createTempFile("promise_pattern", null);
try (var bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
var writer = new FileWriter(file)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
writer.write(line);
writer.write("\n");
}
LOGGER.info("File downloaded at: {}", file.getAbsolutePath());
return file.getAbsolutePath();
} catch (IOException ex) {
throw ex;
}
}
}

View File

@ -23,12 +23,10 @@
package com.iluwatar.promise;
import java.util.concurrent.ExecutionException;
import org.junit.jupiter.api.Test;
import java.util.concurrent.ExecutionException;
/**
*
* Application test.
*/
public class AppTest {

View File

@ -23,8 +23,13 @@
package com.iluwatar.promise;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@ -33,15 +38,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Tests Promise class.
@ -58,7 +56,7 @@ public class PromiseTest {
}
@Test
public void promiseIsFulfilledWithTheResultantValueOfExecutingTheTask()
public void promiseIsFulfilledWithTheResultantValueOfExecutingTheTask()
throws InterruptedException, ExecutionException {
promise.fulfillInAsync(new NumberCrunchingTask(), executor);
@ -66,21 +64,20 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
@Test
public void promiseIsFulfilledWithAnExceptionIfTaskThrowsAnException()
throws InterruptedException, ExecutionException, TimeoutException {
public void promiseIsFulfilledWithAnExceptionIfTaskThrowsAnException()
throws InterruptedException, TimeoutException {
testWaitingForeverForPromiseToBeFulfilled();
testWaitingSomeTimeForPromiseToBeFulfilled();
}
private void testWaitingForeverForPromiseToBeFulfilled()
throws InterruptedException, TimeoutException {
Promise<Integer> promise = new Promise<>();
private void testWaitingForeverForPromiseToBeFulfilled() throws InterruptedException {
var promise = new Promise<Integer>();
promise.fulfillInAsync(() -> {
throw new RuntimeException("Barf!");
}, executor);
try {
promise.get();
fail("Fetching promise should result in exception if the task threw an exception");
@ -88,7 +85,7 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
try {
promise.get(1000, TimeUnit.SECONDS);
fail("Fetching promise should result in exception if the task threw an exception");
@ -97,14 +94,13 @@ public class PromiseTest {
assertFalse(promise.isCancelled());
}
}
private void testWaitingSomeTimeForPromiseToBeFulfilled()
throws InterruptedException, TimeoutException {
Promise<Integer> promise = new Promise<>();
private void testWaitingSomeTimeForPromiseToBeFulfilled() throws InterruptedException {
var promise = new Promise<Integer>();
promise.fulfillInAsync(() -> {
throw new RuntimeException("Barf!");
}, executor);
try {
promise.get(1000, TimeUnit.SECONDS);
fail("Fetching promise should result in exception if the task threw an exception");
@ -112,7 +108,7 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
try {
promise.get();
fail("Fetching promise should result in exception if the task threw an exception");
@ -120,18 +116,15 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
}
@Test
public void dependentPromiseIsFulfilledAfterTheConsumerConsumesTheResultOfThisPromise()
public void dependentPromiseIsFulfilledAfterTheConsumerConsumesTheResultOfThisPromise()
throws InterruptedException, ExecutionException {
Promise<Void> dependentPromise = promise
var dependentPromise = promise
.fulfillInAsync(new NumberCrunchingTask(), executor)
.thenAccept(value -> {
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
});
.thenAccept(value -> assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value));
dependentPromise.get();
assertTrue(dependentPromise.isDone());
@ -139,9 +132,9 @@ public class PromiseTest {
}
@Test
public void dependentPromiseIsFulfilledWithAnExceptionIfConsumerThrowsAnException()
throws InterruptedException, ExecutionException, TimeoutException {
Promise<Void> dependentPromise = promise
public void dependentPromiseIsFulfilledWithAnExceptionIfConsumerThrowsAnException()
throws InterruptedException {
var dependentPromise = promise
.fulfillInAsync(new NumberCrunchingTask(), executor)
.thenAccept(value -> {
throw new RuntimeException("Barf!");
@ -155,7 +148,7 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
try {
dependentPromise.get(1000, TimeUnit.SECONDS);
fail("Fetching dependent promise should result in exception "
@ -167,12 +160,12 @@ public class PromiseTest {
}
@Test
public void dependentPromiseIsFulfilledAfterTheFunctionTransformsTheResultOfThisPromise()
public void dependentPromiseIsFulfilledAfterTheFunctionTransformsTheResultOfThisPromise()
throws InterruptedException, ExecutionException {
Promise<String> dependentPromise = promise
var dependentPromise = promise
.fulfillInAsync(new NumberCrunchingTask(), executor)
.thenApply(value -> {
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
assertEquals(NumberCrunchingTask.CRUNCHED_NUMBER, value);
return String.valueOf(value);
});
@ -181,11 +174,11 @@ public class PromiseTest {
assertTrue(dependentPromise.isDone());
assertFalse(dependentPromise.isCancelled());
}
@Test
public void dependentPromiseIsFulfilledWithAnExceptionIfTheFunctionThrowsException()
throws InterruptedException, ExecutionException, TimeoutException {
Promise<String> dependentPromise = promise
public void dependentPromiseIsFulfilledWithAnExceptionIfTheFunctionThrowsException()
throws InterruptedException {
var dependentPromise = promise
.fulfillInAsync(new NumberCrunchingTask(), executor)
.thenApply(value -> {
throw new RuntimeException("Barf!");
@ -199,7 +192,7 @@ public class PromiseTest {
assertTrue(promise.isDone());
assertFalse(promise.isCancelled());
}
try {
dependentPromise.get(1000, TimeUnit.SECONDS);
fail("Fetching dependent promise should result in exception "
@ -209,26 +202,26 @@ public class PromiseTest {
assertFalse(promise.isCancelled());
}
}
@Test
public void fetchingAnAlreadyFulfilledPromiseReturnsTheFulfilledValueImmediately()
throws InterruptedException, ExecutionException, TimeoutException {
Promise<Integer> promise = new Promise<>();
public void fetchingAnAlreadyFulfilledPromiseReturnsTheFulfilledValueImmediately()
throws ExecutionException {
var promise = new Promise<Integer>();
promise.fulfill(NumberCrunchingTask.CRUNCHED_NUMBER);
promise.get(1000, TimeUnit.SECONDS);
}
@SuppressWarnings("unchecked")
@Test
public void exceptionHandlerIsCalledWhenPromiseIsFulfilledExceptionally() {
Promise<Object> promise = new Promise<>();
Consumer<Throwable> exceptionHandler = mock(Consumer.class);
var promise = new Promise<>();
var exceptionHandler = mock(Consumer.class);
promise.onError(exceptionHandler);
Exception exception = new Exception("barf!");
var exception = new Exception("barf!");
promise.fulfillExceptionally(exception);
verify(exceptionHandler).accept(eq(exception));
}

View File

@ -49,36 +49,36 @@ public class App {
*/
public static void main(String[] args) {
/* set up */
Prototype charProto = new Character();
var charProto = new Character();
charProto.set(Stats.STRENGTH, 10);
charProto.set(Stats.AGILITY, 10);
charProto.set(Stats.ARMOR, 10);
charProto.set(Stats.ATTACK_POWER, 10);
Character mageProto = new Character(Type.MAGE, charProto);
var mageProto = new Character(Type.MAGE, charProto);
mageProto.set(Stats.INTELLECT, 15);
mageProto.set(Stats.SPIRIT, 10);
Character warProto = new Character(Type.WARRIOR, charProto);
var warProto = new Character(Type.WARRIOR, charProto);
warProto.set(Stats.RAGE, 15);
warProto.set(Stats.ARMOR, 15); // boost default armor for warrior
Character rogueProto = new Character(Type.ROGUE, charProto);
var rogueProto = new Character(Type.ROGUE, charProto);
rogueProto.set(Stats.ENERGY, 15);
rogueProto.set(Stats.AGILITY, 15); // boost default agility for rogue
/* usage */
Character mag = new Character("Player_1", mageProto);
var mag = new Character("Player_1", mageProto);
mag.set(Stats.ARMOR, 8);
LOGGER.info(mag.toString());
Character warrior = new Character("Player_2", warProto);
var warrior = new Character("Player_2", warProto);
LOGGER.info(warrior.toString());
Character rogue = new Character("Player_3", rogueProto);
var rogue = new Character("Player_3", rogueProto);
LOGGER.info(rogue.toString());
Character rogueDouble = new Character("Player_4", rogue);
var rogueDouble = new Character("Player_4", rogue);
rogueDouble.set(Stats.ATTACK_POWER, 12);
LOGGER.info(rogueDouble.toString());
}

View File

@ -93,7 +93,7 @@ public class Character implements Prototype {
@Override
public Integer get(Stats stat) {
boolean containsValue = properties.containsKey(stat);
var containsValue = properties.containsKey(stat);
if (containsValue) {
return properties.get(stat);
} else {
@ -118,7 +118,7 @@ public class Character implements Prototype {
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
var builder = new StringBuilder();
if (name != null) {
builder.append("Player: ").append(name).append('\n');
}
@ -128,8 +128,8 @@ public class Character implements Prototype {
}
builder.append("Stats:\n");
for (Stats stat : Stats.values()) {
Integer value = this.get(stat);
for (var stat : Stats.values()) {
var value = this.get(stat);
if (value == null) {
continue;
}

View File

@ -26,15 +26,12 @@ package com.iluwatar.property;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,14 +23,15 @@
package com.iluwatar.property;
import org.junit.jupiter.api.Test;
import static com.iluwatar.property.Character.Type;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
/**
* Date: 12/28/15 - 7:46 PM
*
@ -40,13 +41,13 @@ public class CharacterTest {
@Test
public void testPrototypeStats() throws Exception {
final Character prototype = new Character();
final var prototype = new Character();
for (final Stats stat : Stats.values()) {
for (final var stat : Stats.values()) {
assertFalse(prototype.has(stat));
assertNull(prototype.get(stat));
final Integer expectedValue = stat.ordinal();
final var expectedValue = stat.ordinal();
prototype.set(stat, expectedValue);
assertTrue(prototype.has(stat));
assertEquals(expectedValue, prototype.get(stat));
@ -59,15 +60,13 @@ public class CharacterTest {
}
@Test
public void testCharacterStats() throws Exception {
final Character prototype = new Character();
for (final Stats stat : Stats.values()) {
prototype.set(stat, stat.ordinal());
}
public void testCharacterStats() {
final var prototype = new Character();
Arrays.stream(Stats.values()).forEach(stat -> prototype.set(stat, stat.ordinal()));
final Character mage = new Character(Type.MAGE, prototype);
for (final Stats stat : Stats.values()) {
final Integer expectedValue = stat.ordinal();
final var mage = new Character(Type.MAGE, prototype);
for (final var stat : Stats.values()) {
final var expectedValue = stat.ordinal();
assertTrue(mage.has(stat));
assertEquals(expectedValue, mage.get(stat));
}
@ -75,17 +74,17 @@ public class CharacterTest {
@Test
public void testToString() {
final Character prototype = new Character();
final var prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.AGILITY, 2);
prototype.set(Stats.INTELLECT, 3);
assertEquals("Stats:\n - AGILITY:2\n - ARMOR:1\n - INTELLECT:3\n", prototype.toString());
final Character stupid = new Character(Type.ROGUE, prototype);
final var stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertEquals("Character type: ROGUE\nStats:\n - AGILITY:2\n - ARMOR:1\n", stupid.toString());
final Character weak = new Character("weak", prototype);
final var weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertEquals("Player: weak\nStats:\n - AGILITY:2\n - INTELLECT:3\n", weak.toString());
@ -93,32 +92,32 @@ public class CharacterTest {
@Test
public void testName() {
final Character prototype = new Character();
final var prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.INTELLECT, 2);
assertNull(prototype.name());
final Character stupid = new Character(Type.ROGUE, prototype);
final var stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertNull(stupid.name());
final Character weak = new Character("weak", prototype);
final var weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertEquals("weak", weak.name());
}
@Test
public void testType() {
final Character prototype = new Character();
final var prototype = new Character();
prototype.set(Stats.ARMOR, 1);
prototype.set(Stats.INTELLECT, 2);
assertNull(prototype.type());
final Character stupid = new Character(Type.ROGUE, prototype);
final var stupid = new Character(Type.ROGUE, prototype);
stupid.remove(Stats.INTELLECT);
assertEquals(Type.ROGUE, stupid.type());
final Character weak = new Character("weak", prototype);
final var weak = new Character("weak", prototype);
weak.remove(Stats.ARMOR);
assertNull(weak.type());
}

View File

@ -52,11 +52,11 @@ class Sheep implements Cloneable {
Then it can be cloned like below
```java
Sheep original = new Sheep("Jolly");
var original = new Sheep("Jolly");
System.out.println(original.getName()); // Jolly
// Clone and modify what is required
Sheep cloned = original.clone();
var cloned = original.clone();
cloned.setName("Dolly");
System.out.println(cloned.getName()); // Dolly
```

View File

@ -46,24 +46,23 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
HeroFactory factory = new HeroFactoryImpl(
var factory = new HeroFactoryImpl(
new ElfMage("cooking"),
new ElfWarlord("cleaning"),
new ElfBeast("protecting")
);
Mage mage = factory.createMage();
Warlord warlord = factory.createWarlord();
Beast beast = factory.createBeast();
var mage = factory.createMage();
var warlord = factory.createWarlord();
var beast = factory.createBeast();
LOGGER.info(mage.toString());
LOGGER.info(warlord.toString());
LOGGER.info(beast.toString());
factory =
new HeroFactoryImpl(
new OrcMage("axe"),
new OrcWarlord("sword"),
new OrcBeast("laser")
);
factory = new HeroFactoryImpl(
new OrcMage("axe"),
new OrcWarlord("sword"),
new OrcBeast("laser")
);
mage = factory.createMage();
warlord = factory.createWarlord();
beast = factory.createBeast();

View File

@ -28,9 +28,11 @@ package com.iluwatar.prototype;
*/
public abstract class Beast implements Prototype {
public Beast() { }
public Beast() {
}
public Beast(Beast source) { }
public Beast(Beast source) {
}
@Override
public abstract Beast copy();

View File

@ -60,15 +60,11 @@ public class ElfBeast extends Beast {
if (getClass() != obj.getClass()) {
return false;
}
ElfBeast other = (ElfBeast) obj;
var other = (ElfBeast) obj;
if (helpType == null) {
if (other.helpType != null) {
return false;
}
} else if (!helpType.equals(other.helpType)) {
return false;
return other.helpType == null;
}
return true;
return helpType.equals(other.helpType);
}
}

View File

@ -60,14 +60,10 @@ public class ElfMage extends Mage {
if (getClass() != obj.getClass()) {
return false;
}
ElfMage other = (ElfMage) obj;
var other = (ElfMage) obj;
if (helpType == null) {
if (other.helpType != null) {
return false;
}
} else if (!helpType.equals(other.helpType)) {
return false;
return other.helpType == null;
}
return true;
return helpType.equals(other.helpType);
}
}

View File

@ -60,14 +60,10 @@ public class ElfWarlord extends Warlord {
if (getClass() != obj.getClass()) {
return false;
}
ElfWarlord other = (ElfWarlord) obj;
var other = (ElfWarlord) obj;
if (helpType == null) {
if (other.helpType != null) {
return false;
}
} else if (!helpType.equals(other.helpType)) {
return false;
return other.helpType == null;
}
return true;
return helpType.equals(other.helpType);
}
}

View File

@ -28,9 +28,11 @@ package com.iluwatar.prototype;
*/
public abstract class Mage implements Prototype {
public Mage() { }
public Mage() {
}
public Mage(Mage source) { }
public Mage(Mage source) {
}
@Override
public abstract Mage copy();

View File

@ -60,15 +60,11 @@ public class OrcBeast extends Beast {
if (getClass() != obj.getClass()) {
return false;
}
OrcBeast other = (OrcBeast) obj;
var other = (OrcBeast) obj;
if (weapon == null) {
if (other.weapon != null) {
return false;
}
} else if (!weapon.equals(other.weapon)) {
return false;
return other.weapon == null;
}
return true;
return weapon.equals(other.weapon);
}

View File

@ -60,14 +60,10 @@ public class OrcMage extends Mage {
if (getClass() != obj.getClass()) {
return false;
}
OrcMage other = (OrcMage) obj;
var other = (OrcMage) obj;
if (weapon == null) {
if (other.weapon != null) {
return false;
}
} else if (!weapon.equals(other.weapon)) {
return false;
return other.weapon == null;
}
return true;
return weapon.equals(other.weapon);
}
}

View File

@ -60,14 +60,10 @@ public class OrcWarlord extends Warlord {
if (getClass() != obj.getClass()) {
return false;
}
OrcWarlord other = (OrcWarlord) obj;
var other = (OrcWarlord) obj;
if (weapon == null) {
if (other.weapon != null) {
return false;
}
} else if (!weapon.equals(other.weapon)) {
return false;
return other.weapon == null;
}
return true;
return weapon.equals(other.weapon);
}
}

View File

@ -28,9 +28,11 @@ package com.iluwatar.prototype;
*/
public abstract class Warlord implements Prototype {
public Warlord() { }
public Warlord() {
}
public Warlord(Warlord source) { }
public Warlord(Warlord source) {
}
@Override
public abstract Warlord copy();

View File

@ -26,15 +26,12 @@ package com.iluwatar.prototype;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,37 +23,40 @@
package com.iluwatar.prototype;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
import java.util.Collection;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
* Date: 12/28/15 - 8:45 PM
*
* @param <P> Prototype
* @author Jeroen Meulemeester
*/
public class PrototypeTest<P extends Prototype> {
static Collection<Object[]> dataProvider() {
return List.of(
new Object[]{new OrcBeast("axe"), "Orcish wolf attacks with axe"},
new Object[]{new OrcMage("sword"), "Orcish mage attacks with sword"},
new Object[]{new OrcWarlord("laser"), "Orcish warlord attacks with laser"},
new Object[]{new ElfBeast("cooking"), "Elven eagle helps in cooking"},
new Object[]{new ElfMage("cleaning"), "Elven mage helps in cleaning"},
new Object[]{new ElfWarlord("protecting"), "Elven warlord helps in protecting"}
new Object[]{new OrcBeast("axe"), "Orcish wolf attacks with axe"},
new Object[]{new OrcMage("sword"), "Orcish mage attacks with sword"},
new Object[]{new OrcWarlord("laser"), "Orcish warlord attacks with laser"},
new Object[]{new ElfBeast("cooking"), "Elven eagle helps in cooking"},
new Object[]{new ElfMage("cleaning"), "Elven mage helps in cleaning"},
new Object[]{new ElfWarlord("protecting"), "Elven warlord helps in protecting"}
);
}
@ParameterizedTest
@MethodSource("dataProvider")
public void testPrototype(P testedPrototype, String expectedToString) throws Exception {
public void testPrototype(P testedPrototype, String expectedToString) {
assertEquals(expectedToString, testedPrototype.toString());
final Object clone = testedPrototype.copy();
final var clone = testedPrototype.copy();
assertNotNull(clone);
assertNotSame(clone, testedPrototype);
assertSame(testedPrototype.getClass(), clone.getClass());

View File

@ -100,7 +100,7 @@ public class WizardTowerProxy implements WizardTower {
And here is tower entering scenario
```java
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
var proxy = new WizardTowerProxy(new IvoryTower());
proxy.enter(new Wizard("Red wizard")); // Red wizard enters the tower.
proxy.enter(new Wizard("White wizard")); // White wizard enters the tower.
proxy.enter(new Wizard("Black wizard")); // Black wizard enters the tower.

View File

@ -44,7 +44,7 @@ public class App {
*/
public static void main(String[] args) {
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
var proxy = new WizardTowerProxy(new IvoryTower());
proxy.enter(new Wizard("Red wizard"));
proxy.enter(new Wizard("White wizard"));
proxy.enter(new Wizard("Black wizard"));

View File

@ -26,15 +26,12 @@ package com.iluwatar.proxy;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
App.main(new String[]{});
}
}

View File

@ -23,14 +23,15 @@
package com.iluwatar.proxy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.proxy.utils.InMemoryAppender;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Tests for {@link IvoryTower}
*/
@ -49,18 +50,16 @@ public class IvoryTowerTest {
}
@Test
public void testEnter() throws Exception {
final Wizard[] wizards = new Wizard[]{
public void testEnter() {
final var wizards = List.of(
new Wizard("Gandalf"),
new Wizard("Dumbledore"),
new Wizard("Oz"),
new Wizard("Merlin")
};
);
IvoryTower tower = new IvoryTower();
for (Wizard wizard : wizards) {
tower.enter(wizard);
}
var tower = new IvoryTower();
wizards.forEach(tower::enter);
assertTrue(appender.logContains("Gandalf enters the tower."));
assertTrue(appender.logContains("Dumbledore enters the tower."));

View File

@ -23,20 +23,19 @@
package com.iluwatar.proxy;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import org.junit.jupiter.api.Test;
/**
* Tests for {@link Wizard}
*/
public class WizardTest {
@Test
public void testToString() throws Exception {
final String[] wizardNames = {"Gandalf", "Dumbledore", "Oz", "Merlin"};
for (String name : wizardNames) {
assertEquals(name, new Wizard(name).toString());
}
public void testToString() {
List.of("Gandalf", "Dumbledore", "Oz", "Merlin")
.forEach(name -> assertEquals(name, new Wizard(name).toString()));
}
}

View File

@ -23,14 +23,15 @@
package com.iluwatar.proxy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.proxy.utils.InMemoryAppender;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Tests for {@link WizardTowerProxy}
*/
@ -50,17 +51,15 @@ public class WizardTowerProxyTest {
@Test
public void testEnter() throws Exception {
final Wizard[] wizards = new Wizard[]{
final var wizards = List.of(
new Wizard("Gandalf"),
new Wizard("Dumbledore"),
new Wizard("Oz"),
new Wizard("Merlin")
};
);
final WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
for (Wizard wizard : wizards) {
proxy.enter(wizard);
}
final var proxy = new WizardTowerProxy(new IvoryTower());
wizards.forEach(proxy::enter);
assertTrue(appender.logContains("Gandalf enters the tower."));
assertTrue(appender.logContains("Dumbledore enters the tower."));

View File

@ -26,10 +26,9 @@ package com.iluwatar.proxy.utils;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.LoggerFactory;
/**
@ -54,7 +53,7 @@ public class InMemoryAppender extends AppenderBase<ILoggingEvent> {
}
public boolean logContains(String message) {
return log.stream().anyMatch(event -> event.getFormattedMessage().equals(message));
return log.stream().map(ILoggingEvent::getFormattedMessage).anyMatch(message::equals);
}
public int getLogSize() {