Compare commits

..

17 Commits

Author SHA1 Message Date
b423002e6c updated Random() to SecureRandom() (#1670)
* updated Random() to SecureRandom()

* batch 2 of SecureRandom updates
2021-03-06 13:26:02 +02:00
CF
c150871a94 Update to JUnit5 across all modules (#1668)
* Updated saga to JUnit 5

* Update fix for CI job in trampoline module

* Updated update-method module to JUnit 5

* Upgraded to latest JUnit Jupiter
JUnit 4 is not needed when using JUnit-Vintage

* Reverted change to access modifier on Trampoline

* Cleanup to resolve code smells

* Formatting

* Formatting

* Migrating to JUnit5 and updating some Mockito patterns

* Migrating to JUnit5

* Migrating to JUnit5

* Migrating to JUnit 5

* Formatting cleanup

* Added missing scope for junit

* Fixed tests that were not running previously.

Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
2021-03-06 14:42:46 +05:30
e9d0b3e98c remove labeling trigger for PR and actions set to master (#1666) 2021-03-05 19:51:09 +02:00
CF
903453229c Updated update-method module to JUnit 5 (#1542)
* Updated saga to JUnit 5

* Update fix for CI job in trampoline module

* Updated update-method module to JUnit 5

* Upgraded to latest JUnit Jupiter
JUnit 4 is not needed when using JUnit-Vintage

* Reverted change to access modifier on Trampoline

* Cleanup to resolve code smells

* Formatting

* Formatting

Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
2021-03-04 10:49:31 +05:30
c3c90e2bd4 created CircleCI config for sonar analysis (#1664)
* created sonar config

#1663

* updated license headers

* xvfb to run tests

* updated circle image to enable css and JS analysis
2021-03-01 16:50:34 +02:00
268e4148b4 #1625 add Turkish translation for singleton design pattern (#1665)
Co-authored-by: Halil Demir <halil.demir@zalando.de>
Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
2021-03-01 19:20:06 +05:30
0220f3df12 docs: add richardmr36 as a contributor (#1662)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-02-28 11:51:47 +02:00
846d05672a #1638 Add Parameter Object pattern (#1650)
* #1638 Add Parameter Object pattern

* #1638 Fix comments and formatting for Parameter Object pattern

* #1638 Fix formatting, commenting, remove string concatenation in Parameter Object pattern

* #1638 Fix readme formatting and log parameter object
2021-02-28 11:42:48 +02:00
03bc4a6b9a update CI badge (#1658) 2021-02-21 15:21:11 +02:00
cda2675221 Upgrade jacoco (#1657)
Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
2021-02-16 12:27:11 +05:30
a79bed9a46 #1655: added maven wrapper (#1656)
Addresses Point 1 and 2
2021-02-15 17:13:06 +02:00
7c01bc7464 format readme.md 2021-02-14 23:43:33 +02:00
edbea7d50b format readme.md 2021-02-14 23:33:40 +02:00
d2f926e3e8 format readme.md 2021-02-14 23:23:05 +02:00
fc837e289f format readme.md 2021-02-14 23:01:05 +02:00
fce8d25736 format readme.md 2021-02-14 22:51:42 +02:00
cbffcb28c8 #455 Static content hosting cloud pattern (#1654)
* #455 work on readme.md

* #455 work on readme.md

* #455 S3 web site complete

* #455 add cloudfront and diagram

* Apply suggestions from code review

added syntax highlighting

Co-authored-by: Subhrodip Mohanta <hello@subho.xyz>
2021-02-15 01:42:21 +05:30
103 changed files with 2007 additions and 628 deletions

View File

@ -1404,6 +1404,15 @@
"contributions": [
"translation"
]
},
{
"login": "richardmr36",
"name": "Martel Richard",
"avatar_url": "https://avatars.githubusercontent.com/u/19147333?v=4",
"profile": "https://github.com/richardmr36",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 4,

52
.circleci/config.yml Normal file
View File

@ -0,0 +1,52 @@
#
# The MIT License
# Copyright © 2014-2021 Ilkka Seppälä
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
version: 2
jobs:
sonar-pr:
docker:
- image: circleci/openjdk:11-node
steps:
- checkout
- restore_cache:
key: jdp-sonar-pr-{{ checksum "pom.xml" }}
- run: |
if [ -n "${CIRCLE_PR_NUMBER}" ]; then
MAVEN_OPTS="-Xmx3000m" xvfb-run ./mvnw -B clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
-Dsonar.pullrequest.key=${CIRCLE_PR_NUMBER} \
-Dsonar.pullrequest.branch=${CIRCLE_BRANCH} \
-Dsonar.pullrequest.base=master
else
echo "No Sonar PR analysis as this is not a pull request"
fi
- save_cache:
key: jdp-sonar-pr-{{ checksum "pom.xml" }}
paths:
- ~/.m2
workflows:
version: 2
all:
jobs:
- sonar-pr

View File

@ -40,25 +40,25 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v2
uses: actions/checkout@master
with:
# Disabling shallow clone for improving relevancy of SonarQube reporting
fetch-depth: 0
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@master
with:
java-version: 11
- name: Cache SonarCloud packages
uses: actions/cache@v2
uses: actions/cache@master
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven dependencies
uses: actions/cache@v2
uses: actions/cache@master
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
@ -69,11 +69,8 @@ jobs:
- name: Install xvfb
run: sudo apt-get install -y xvfb
# The SonarQube analysis is only for the master branch of the main repository.
# SonarQube scan does not work for forked repositories try changing it to xvfb-run mvn clean verify
# See https://jira.sonarsource.com/browse/MMF-1371
- name: Build with Maven and run SonarQube analysis
run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
run: xvfb-run ./mvnw clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
env:
# These two env variables are needed for sonar analysis
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -29,7 +29,7 @@ name: Java PR Builder
on:
pull_request:
branches: [ master ]
types: [ opened, reopened, synchronize, labeled, unlabeled ]
types: [ opened, reopened, synchronize ]
jobs:
build:
@ -38,15 +38,15 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v2
uses: actions/checkout@master
- name: Set up JDK 11
uses: actions/setup-java@v1
uses: actions/setup-java@master
with:
java-version: 11
- name: Cache Maven Dependecies
uses: actions/cache@v2
uses: actions/cache@master
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
@ -57,8 +57,5 @@ jobs:
- name: Install xvfb
run: sudo apt-get install -y xvfb
# This worflow is only for building Pull Requests, the master branch runs Sonar analysis on the main repository.
# SonarQube scan does not work for forked repositories.
# See https://jira.sonarsource.com/browse/MMF-1371
- name: Build with Maven
run: xvfb-run mvn clean verify
run: xvfb-run ./mvnw clean verify

125
.mvn/wrapper/MavenWrapperDownloader.java vendored Normal file
View File

@ -0,0 +1,125 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

25
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,25 @@
#
# The MIT License
# Copyright © 2014-2021 Ilkka Seppälä
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

View File

@ -4,18 +4,18 @@
# Design patterns implemented in Java
![Java CI with Maven](https://github.com/iluwatar/java-design-patterns/workflows/Java%20CI%20with%20Maven/badge.svg)
![Java CI](https://github.com/iluwatar/java-design-patterns/workflows/Java%20CI/badge.svg)
[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)
[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=ncloc)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-154-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-155-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<br/>
Read in different language : [![CN](/assets/flags/CN.png)**CN**](/zh/README.md),[![KR](/assets/flags/KR.png)**KR**](/ko/README.md),[![FR](/assets/flags/FR.png)**FR**](/fr/README.md),[![TR](/assets/flags/TR.png)**TR**](/tr/README.md),[![AR](/assets/flags/AR.png)**AR**](/ar/README.md),
Read in different language : [![CN](/assets/flags/CN.png)**CN**](/zh/README.md), [![KR](/assets/flags/KR.png)**KR**](/ko/README.md), [![FR](/assets/flags/FR.png)**FR**](/fr/README.md), [![TR](/assets/flags/TR.png)**TR**](/tr/README.md), [![AR](/assets/flags/AR.png)**AR**](/ar/README.md)
<br/>
@ -306,6 +306,7 @@ This project is licensed under the terms of the MIT license.
<tr>
<td align="center"><a href="https://github.com/byoungju94"><img src="https://avatars.githubusercontent.com/u/42516378?v=4?s=100" width="100px;" alt=""/><br /><sub><b>byoungju94</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=byoungju94" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/moustafafarhat"><img src="https://avatars.githubusercontent.com/u/38836727?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Moustafa Farhat</b></sub></a><br /><a href="#translation-moustafafarhat" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/richardmr36"><img src="https://avatars.githubusercontent.com/u/19147333?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martel Richard</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=richardmr36" title="Code">💻</a></td>
</tr>
</table>

View File

@ -36,8 +36,8 @@
<artifactId>arrange-act-assert</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -23,11 +23,11 @@
package com.iluwatar.arrangeactassert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
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 org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It is a way to structure your
@ -51,10 +51,11 @@ import org.junit.Test;
* change and one reason to fail. In a large and complicated code base, tests that honor the single
* responsibility principle are much easier to troubleshoot.
*/
public class CashAAATest {
class CashAAATest {
@Test
public void testPlus() {
void testPlus() {
//Arrange
var cash = new Cash(3);
//Act
@ -64,7 +65,7 @@ public class CashAAATest {
}
@Test
public void testMinus() {
void testMinus() {
//Arrange
var cash = new Cash(8);
//Act
@ -75,7 +76,7 @@ public class CashAAATest {
}
@Test
public void testInsufficientMinus() {
void testInsufficientMinus() {
//Arrange
var cash = new Cash(1);
//Act
@ -86,7 +87,7 @@ public class CashAAATest {
}
@Test
public void testUpdate() {
void testUpdate() {
//Arrange
var cash = new Cash(5);
//Act

View File

@ -23,23 +23,24 @@
package com.iluwatar.arrangeactassert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
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 org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* ({@link CashAAATest}) is an anti-example of AAA pattern. This test is functionally correct, but
* with the addition of new feature, it needs refactoring. There are an awful lot of steps in that
* with the addition of a new feature, it needs refactoring. There are an awful lot of steps in that
* test method, but it verifies the class' important behavior in just eleven lines. It violates the
* single responsibility principle. If this test method failed after a small code change, it might
* take some digging to discover why.
*/
public class CashAntiAAATest {
class CashAntiAAATest {
@Test
public void testCash() {
void testCash() {
//initialize
var cash = new Cash(3);
//test plus

View File

@ -45,11 +45,6 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -55,13 +55,13 @@ the content globally.
4. Create IAM user that has only the necessary rights for this application.
* Click `Users`
* Click `Add user`. Choose `User name` as you wish and `Access type` should be `Programmatic access`. Click `Next: Permissions`.
* Choose `Attach existing policies directly`. Select `AmazonS3FullAccess` and `CloudFrontFullAccess`. Click `Next: Tags`.
* No tags are necessarily needed, so just click `Next: Review`.
* Review the presented information and if all seems good click `Create user`.
* You are presented with `Access key ID` and `Secret access key` which you will need to complete this example, so store them safely.
* Click `Close`.
* Click `Users`
* Click `Add user`. Choose `User name` as you wish and `Access type` should be `Programmatic access`. Click `Next: Permissions`.
* Choose `Attach existing policies directly`. Select `AmazonS3FullAccess` and `CloudFrontFullAccess`. Click `Next: Tags`.
* No tags are necessarily needed, so just click `Next: Review`.
* Review the presented information and if all seems good click `Create user`.
* You are presented with `Access key ID` and `Secret access key` which you will need to complete this example, so store them safely.
* Click `Close`.
5. [Install AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html) to gain programmic access to AWS cloud.
@ -69,83 +69,60 @@ the content globally.
7. Create AWS S3 bucket for the web site content. Note that the S3 bucket names must be globally unique.
* The syntax is `aws s3 mb <bucket name>` as described in the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-buckets-creating)
* For example `aws s3 mb s3://my-static-website-jh34jsjmg`
* Verify that the bucket was successfully created with command `aws s3 ls` which list the existing buckets
* The syntax is `aws s3 mb <bucket name>` as described in the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-buckets-creating)
* For example `aws s3 mb s3://my-static-website-jh34jsjmg`
* Verify that the bucket was successfully created with command `aws s3 ls` which list the existing buckets
8. Configure the bucket as a web site with command `aws s3 website` as described in the [instructions](https://docs.aws.amazon.com/cli/latest/reference/s3/website.html).
* E.g. `aws s3 website s3://my-static-website-jh34jsjmg --index-document index.html --error-document error.html`
* E.g. `aws s3 website s3://my-static-website-jh34jsjmg --index-document index.html --error-document error.html`
9. Upload content to the bucket.
* First create the content, at least `index.html` and `error.html` documents.
index.html
```html
<!doctype html>
<head>
<title>My Static Web Site</title>
</head>
<body>
<h1>I'm the index.html</h1>
</body>
```
error.html
```html
<!doctype html>
<head>
<title>My Static Web Site</title>
</head>
<body>
<h1>I'm the index.html</h1>
</body>
```
* Upload the content to your bucket as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy)
* E.g. `aws s3 cp index.html s3://my-static-website-jh34jsjmg` and `aws s3 cp error.html s3://my-static-website-jh34jsjmg`
* First create the content, at least `index.html` and `error.html` documents.
* Upload the content to your bucket as described [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy)
* E.g. `aws s3 cp index.html s3://my-static-website-jh34jsjmg` and `aws s3 cp error.html s3://my-static-website-jh34jsjmg`
10. Next we need to set the bucket policy to allow read access.
* Create `policy.json` with the following contents (note that you need to replace the bucket name with your own).
* Create `policy.json` with the following contents (note that you need to replace the bucket name with your own).
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-static-website-jh34jsjmg/*"
}
]
}
```
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-static-website-jh34jsjmg/*"
}
]
}
```
* Set the bucket policy according to these [instructions](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-policy.html)
* E.g. `aws s3api put-bucket-policy --bucket my-static-website-jh34jsjmg --policy file://policy.json`
* Set the bucket policy according to these [instructions](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-bucket-policy.html)
* E.g. `aws s3api put-bucket-policy --bucket my-static-website-jh34jsjmg --policy file://policy.json`
11. Test the web site in your browser.
* The web site URL format is `http://<bucket-name>.s3-website-<region-name>.amazonaws.com`
* E.g. this web site was created in `eu-west-1` region with name `my-static-website-jh34jsjmg` so it can be accessed via url `http://my-static-website-jh34jsjmg.s3-website-eu-west-1.amazonaws.com`
* The web site URL format is `http://<bucket-name>.s3-website-<region-name>.amazonaws.com`
* E.g. this web site was created in `eu-west-1` region with name `my-static-website-jh34jsjmg` so it can be accessed via url `http://my-static-website-jh34jsjmg.s3-website-eu-west-1.amazonaws.com`
12. Create CloudFormation distribution for the web site.
* The syntax is described in [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-distribution.html)
* E.g. the easiest way is to call `aws cloudfront create-distribution --origin-domain-name my-static-website-jh34jsjmg.s3.amazonaws.com --default-root-object index.html`
* There's also JSON syntax e.g. `--distribution-config file://dist-config.json` to pass distribution configuration arguments in file
* The output of the call will show you the exact distribution settings including the generated CloudFront domain name you can use for testing e.g. `d2k3xwnaqa8nqx.cloudfront.net`
* CloudFormation distribution deployment takes some time, but once it's completed your web site is served from data centers all around the globe!
* The syntax is described in [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-distribution.html)
* E.g. the easiest way is to call `aws cloudfront create-distribution --origin-domain-name my-static-website-jh34jsjmg.s3.amazonaws.com --default-root-object index.html`
* There's also JSON syntax e.g. `--distribution-config file://dist-config.json` to pass distribution configuration arguments in file
* The output of the call will show you the exact distribution settings including the generated CloudFront domain name you can use for testing e.g. `d2k3xwnaqa8nqx.cloudfront.net`
* CloudFormation distribution deployment takes some time, but once it's completed your web site is served from data centers all around the globe!
13. That's it! You have implemented a static web site with content distribution network serving it lightning fast all around the world.
* To update the web site you need to update the objects in S3 bucket and invalidate the objects in the CloudFront distribution
* To do it from AWS CLI see [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html)
* Some further development you might want to do is serve the content over https and add a domain name for your site
* To update the web site you need to update the objects in S3 bucket and invalidate the objects in the CloudFront distribution
* To do it from AWS CLI see [this reference](https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html)
* Some further development you might want to do is serve the content over https and add a domain name for your site
## Applicability

View File

@ -34,12 +34,6 @@
<artifactId>combinator</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,11 +23,11 @@
package com.iluwatar.combinator;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class CombinatorAppTest {
import org.junit.jupiter.api.Test;
class CombinatorAppTest {
/**
* Issue: Add at least one assertion to this test case.
@ -37,7 +37,7 @@ public class CombinatorAppTest {
*/
@Test
public void shouldExecuteApplicationWithoutException() {
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> CombinatorApp.main(new String[]{}));
}
}
}

View File

@ -23,22 +23,19 @@
package com.iluwatar.combinator;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.*;
public class FinderTest {
class FinderTest {
@Test
public void contains() {
void contains() {
var example = "the first one \nthe second one \n";
var result = Finder.contains("second").find(example);
Assert.assertEquals(result.size(),1);
Assert.assertEquals(result.get(0),"the second one ");
assertEquals(1, result.size());
assertEquals("the second one ", result.get(0));
}
}
}

View File

@ -23,44 +23,44 @@
package com.iluwatar.combinator;
import org.junit.Assert;
import org.junit.Test;
import static com.iluwatar.combinator.Finders.advancedFinder;
import static com.iluwatar.combinator.Finders.expandedFinder;
import static com.iluwatar.combinator.Finders.filteredFinder;
import static com.iluwatar.combinator.Finders.specializedFinder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import org.junit.jupiter.api.Test;
import static com.iluwatar.combinator.Finders.*;
import static org.junit.Assert.*;
public class FindersTest {
class FindersTest {
@Test
public void advancedFinderTest() {
void advancedFinderTest() {
var res = advancedFinder("it was","kingdom","sea").find(text());
Assert.assertEquals(res.size(),1);
Assert.assertEquals(res.get(0),"It was many and many a year ago,");
assertEquals(1, res.size());
assertEquals("It was many and many a year ago,", res.get(0));
}
@Test
public void filteredFinderTest() {
void filteredFinderTest() {
var res = filteredFinder(" was ", "many", "child").find(text());
Assert.assertEquals(res.size(),1);
Assert.assertEquals(res.get(0),"But we loved with a love that was more than love-");
assertEquals(1, res.size());
assertEquals("But we loved with a love that was more than love-", res.get(0));
}
@Test
public void specializedFinderTest() {
void specializedFinderTest() {
var res = specializedFinder("love","heaven").find(text());
Assert.assertEquals(res.size(),1);
Assert.assertEquals(res.get(0),"With a love that the winged seraphs of heaven");
assertEquals(1, res.size());
assertEquals("With a love that the winged seraphs of heaven", res.get(0));
}
@Test
public void expandedFinderTest() {
void expandedFinderTest() {
var res = expandedFinder("It was","kingdom").find(text());
Assert.assertEquals(res.size(),3);
Assert.assertEquals(res.get(0),"It was many and many a year ago,");
Assert.assertEquals(res.get(1),"In a kingdom by the sea,");
Assert.assertEquals(res.get(2),"In this kingdom by the sea;");
assertEquals(3, res.size());
assertEquals("It was many and many a year ago,", res.get(0));
assertEquals("In a kingdom by the sea,", res.get(1));
assertEquals("In this kingdom by the sea;", res.get(2));
}
@ -80,4 +80,4 @@ public class FindersTest {
+ "Coveted her and me.";
}
}
}

View File

@ -23,8 +23,8 @@
package com.iluwatar.commander;
import java.security.SecureRandom;
import java.util.Hashtable;
import java.util.Random;
/**
* Order class holds details of the order.
@ -45,7 +45,7 @@ public class Order { //can store all transactions ids also
public final String id;
final float price;
final long createdTime;
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
private static final String ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
private static final Hashtable<String, Boolean> USED_IDS = new Hashtable<String, Boolean>();
PaymentStatus paid;

View File

@ -23,10 +23,10 @@
package com.iluwatar.commander;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
@ -56,7 +56,7 @@ public class Retry<T> {
void handleIssue(T obj, Exception e);
}
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
private final Operation op;
private final HandleErrorIssue<T> handleError;

View File

@ -24,10 +24,11 @@
package com.iluwatar.commander;
import com.iluwatar.commander.exceptions.DatabaseUnavailableException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
/**
* Service class is an abstract class extended by all services in this example. They all have a
@ -42,7 +43,7 @@ public abstract class Service {
protected final Database database;
public ArrayList<Exception> exceptionsList;
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
private static final String ALL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
private static final Hashtable<String, Boolean> USED_IDS = new Hashtable<>();

View File

@ -36,10 +36,6 @@
<artifactId>double-buffer</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>

View File

@ -23,14 +23,14 @@
package com.iluwatar.doublebuffer;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;
/**
* App unit test.
*/
public class AppTest {
class AppTest {
/**
* Issue: Add at least one assertion to this test case.
@ -40,7 +40,7 @@ public class AppTest {
*/
@Test
public void shouldExecuteApplicationWithoutException() {
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}

View File

@ -23,17 +23,19 @@
package com.iluwatar.doublebuffer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* FrameBuffer unit test.
*/
public class FrameBufferTest {
class FrameBufferTest {
@Test
public void testClearAll() {
void testClearAll() {
try {
var field = FrameBuffer.class.getDeclaredField("pixels");
var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH];
@ -43,14 +45,14 @@ public class FrameBufferTest {
field.setAccessible(true);
field.set(frameBuffer, pixels);
frameBuffer.clearAll();
Assert.assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]);
assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]);
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
@Test
public void testClear() {
void testClear() {
try {
var field = FrameBuffer.class.getDeclaredField("pixels");
var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH];
@ -60,21 +62,21 @@ public class FrameBufferTest {
field.setAccessible(true);
field.set(frameBuffer, pixels);
frameBuffer.clear(0, 0);
Assert.assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]);
assertEquals(Pixel.WHITE, frameBuffer.getPixels()[0]);
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
@Test
public void testDraw() {
void testDraw() {
var frameBuffer = new FrameBuffer();
frameBuffer.draw(0, 0);
Assert.assertEquals(Pixel.BLACK, frameBuffer.getPixels()[0]);
assertEquals(Pixel.BLACK, frameBuffer.getPixels()[0]);
}
@Test
public void testGetPixels() {
void testGetPixels() {
try {
var field = FrameBuffer.class.getDeclaredField("pixels");
var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH];
@ -83,9 +85,9 @@ public class FrameBufferTest {
var frameBuffer = new FrameBuffer();
field.setAccessible(true);
field.set(frameBuffer, pixels);
Assert.assertEquals(pixels, frameBuffer.getPixels());
assertEquals(pixels, frameBuffer.getPixels());
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}

View File

@ -23,17 +23,19 @@
package com.iluwatar.doublebuffer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.ArrayList;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Scene unit tests.
*/
public class SceneTest {
class SceneTest {
@Test
public void testGetBuffer() {
void testGetBuffer() {
try {
var scene = new Scene();
var field1 = Scene.class.getDeclaredField("current");
@ -46,14 +48,14 @@ public class SceneTest {
var field2 = Scene.class.getDeclaredField("frameBuffers");
field2.setAccessible(true);
field2.set(scene, frameBuffers);
Assert.assertEquals(frameBuffer, scene.getBuffer());
assertEquals(frameBuffer, scene.getBuffer());
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to access private field.");
fail("Fail to access private field.");
}
}
@Test
public void testDraw() {
void testDraw() {
try {
var scene = new Scene();
var field1 = Scene.class.getDeclaredField("current");
@ -63,10 +65,10 @@ public class SceneTest {
field2.setAccessible(true);
field2.set(scene, 1);
scene.draw(new ArrayList<>());
Assert.assertEquals(1, field1.get(scene));
Assert.assertEquals(0, field2.get(scene));
assertEquals(1, field1.get(scene));
assertEquals(0, field2.get(scene));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to access private field");
fail("Fail to access private field");
}
}
}

View File

@ -23,8 +23,8 @@
package com.iluwatar.event.asynchronous;
import java.security.SecureRandom;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
/**
@ -43,7 +43,7 @@ public class EventManager implements ThreadCompleteListener {
public static final int MAX_ID = MAX_RUNNING_EVENTS;
public static final int MAX_EVENT_TIME = 1800; // in seconds / 30 minutes.
private int currentlyRunningSyncEvent = -1;
private final Random rand;
private final SecureRandom rand;
private final Map<Integer, Event> eventPool;
private static final String DOES_NOT_EXIST = " does not exist.";
@ -52,7 +52,7 @@ public class EventManager implements ThreadCompleteListener {
* EventManager constructor.
*/
public EventManager() {
rand = new Random(1);
rand = new SecureRandom();
eventPool = new ConcurrentHashMap<Integer, Event>(MAX_RUNNING_EVENTS);
}

View File

@ -38,10 +38,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -35,11 +35,6 @@
<artifactId>game-loop</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,7 +23,7 @@
package com.iluwatar.gameloop;
import java.util.Random;
import java.security.SecureRandom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -80,7 +80,7 @@ public abstract class GameLoop {
*/
protected void processInput() {
try {
var lag = new Random().nextInt(200) + 50;
var lag = new SecureRandom().nextInt(200) + 50;
Thread.sleep(lag);
} catch (InterruptedException e) {
logger.error(e.getMessage());

View File

@ -43,11 +43,6 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -24,10 +24,10 @@
package com.iluwatar.hexagonal.domain;
import com.google.common.base.Joiner;
import java.security.SecureRandom;
import java.util.Collections;
import java.util.HashSet;
import java.util.PrimitiveIterator;
import java.util.Random;
import java.util.Set;
/**
@ -126,7 +126,7 @@ public class LotteryNumbers {
* @param max the max value (inclusive)
*/
public RandomNumberGenerator(int min, int max) {
randomIterator = new Random().ints(min, max + 1).iterator();
randomIterator = new SecureRandom().ints(min, max + 1).iterator();
}
/**

View File

@ -30,9 +30,9 @@ import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import java.security.SecureRandom;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
@ -41,7 +41,7 @@ import java.util.stream.Collectors;
public class SampleData {
private static final List<PlayerDetails> PLAYERS;
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
static {
PLAYERS = List.of(

View File

@ -32,11 +32,6 @@
</parent>
<artifactId>leader-followers</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,7 +23,7 @@
package com.iluwatar.leaderfollowers;
import java.util.Random;
import java.security.SecureRandom;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -84,7 +84,7 @@ public class App {
* Add tasks.
*/
private static void addTasks(TaskSet taskSet) throws InterruptedException {
var rand = new Random();
var rand = new SecureRandom();
for (var i = 0; i < 5; i++) {
var time = Math.abs(rand.nextInt(1000));
taskSet.addTask(new Task(time));

View File

@ -23,20 +23,20 @@
package com;
import com.iluwatar.leaderfollowers.App;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import com.iluwatar.leaderfollowers.App;
import org.junit.jupiter.api.Test;
/**
*
* Application test
*
*/
public class AppTest {
class AppTest {
@Test
public void shouldExecuteApplicationWithoutException() {
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}

View File

@ -23,22 +23,23 @@
package com;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.iluwatar.leaderfollowers.Task;
import com.iluwatar.leaderfollowers.TaskHandler;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Tests for TaskHandler
*/
public class TaskHandlerTest {
class TaskHandlerTest {
@Test
public void testHandleTask() throws InterruptedException {
void testHandleTask() throws InterruptedException {
var taskHandler = new TaskHandler();
var handle = new Task(100);
taskHandler.handleTask(handle);
Assert.assertTrue(handle.isFinished());
assertTrue(handle.isFinished());
}
}

View File

@ -23,30 +23,31 @@
package com;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.leaderfollowers.Task;
import com.iluwatar.leaderfollowers.TaskSet;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Tests for TaskSet
*/
public class TaskSetTest {
class TaskSetTest {
@Test
public void testAddTask() throws InterruptedException {
void testAddTask() throws InterruptedException {
var taskSet = new TaskSet();
taskSet.addTask(new Task(10));
Assert.assertTrue(taskSet.getSize() == 1);
assertEquals(1, taskSet.getSize());
}
@Test
public void testGetTask() throws InterruptedException {
void testGetTask() throws InterruptedException {
var taskSet = new TaskSet();
taskSet.addTask(new Task(100));
Task task = taskSet.getTask();
Assert.assertTrue(task.getTime() == 100);
Assert.assertTrue(taskSet.getSize() == 0);
assertEquals(100, task.getTime());
assertEquals(0, taskSet.getSize());
}
}

View File

@ -23,43 +23,45 @@
package com;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import com.iluwatar.leaderfollowers.TaskHandler;
import com.iluwatar.leaderfollowers.TaskSet;
import com.iluwatar.leaderfollowers.WorkCenter;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Tests for WorkCenter
*/
public class WorkCenterTest {
class WorkCenterTest {
@Test
public void testCreateWorkers() {
void testCreateWorkers() {
var taskSet = new TaskSet();
var taskHandler = new TaskHandler();
var workCenter = new WorkCenter();
workCenter.createWorkers(5, taskSet, taskHandler);
Assert.assertEquals(workCenter.getWorkers().size(), 5);
Assert.assertEquals(workCenter.getWorkers().get(0), workCenter.getLeader());
assertEquals(5, workCenter.getWorkers().size());
assertEquals(workCenter.getWorkers().get(0), workCenter.getLeader());
}
@Test
public void testNullLeader() {
void testNullLeader() {
var workCenter = new WorkCenter();
workCenter.promoteLeader();
Assert.assertNull(workCenter.getLeader());
assertNull(workCenter.getLeader());
}
@Test
public void testPromoteLeader() {
void testPromoteLeader() {
var taskSet = new TaskSet();
var taskHandler = new TaskHandler();
var workCenter = new WorkCenter();
workCenter.createWorkers(5, taskSet, taskHandler);
workCenter.removeWorker(workCenter.getLeader());
workCenter.promoteLeader();
Assert.assertEquals(workCenter.getWorkers().size(), 4);
Assert.assertEquals(workCenter.getWorkers().get(0), workCenter.getLeader());
assertEquals(4, workCenter.getWorkers().size());
assertEquals(workCenter.getWorkers().get(0), workCenter.getLeader());
}
}

View File

@ -21,18 +21,18 @@
* THE SOFTWARE.
*/
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
/**
* Guard test
*/
public class GuardTest {
class GuardTest {
@Test
public void testGuard() {
void testGuard() {
var guard = new Guard();
assertThat(guard, instanceOf(Permission.class));
}

View File

@ -23,7 +23,7 @@
package com.iluwatar.masterworker;
import java.util.Random;
import java.security.SecureRandom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -35,7 +35,7 @@ public class ArrayUtilityMethods {
private static final Logger LOGGER = LoggerFactory.getLogger(ArrayUtilityMethods.class);
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
/**
* Method arraysSame compares 2 arrays @param a1 and @param a2 and @return whether their values

310
mvnw vendored Executable file
View File

@ -0,0 +1,310 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

186
mvnw.cmd vendored Normal file
View File

@ -0,0 +1,186 @@
@REM
@REM The MIT License
@REM Copyright © 2014-2021 Ilkka Seppälä
@REM
@REM Permission is hereby granted, free of charge, to any person obtaining a copy
@REM of this software and associated documentation files (the "Software"), to deal
@REM in the Software without restriction, including without limitation the rights
@REM to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
@REM copies of the Software, and to permit persons to whom the Software is
@REM furnished to do so, subject to the following conditions:
@REM
@REM The above copyright notice and this permission notice shall be included in
@REM all copies or substantial portions of the Software.
@REM
@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
@REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
@REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@REM AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
@REM LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
@REM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
@REM THE SOFTWARE.
@REM
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

138
parameter-object/README.md Normal file
View File

@ -0,0 +1,138 @@
---
layout: pattern
title: Parameter Object
folder: parameter-object
permalink: /patterns/parameter-object/
categories: Behavioral
tags:
- Extensibility
---
## Intent
The syntax of Java language doesnt allow you to declare a method with a predefined value
for a parameter. Probably the best option to achieve default method parameters in Java is
by using the method overloading. Method overloading allows you to declare several methods
with the same name but with a different number of parameters. But the main problem with
method overloading as a solution for default parameter values reveals itself when a method
accepts multiple parameters. Creating an overloaded method for each possible combination of
parameters might be cumbersome. To deal with this issue, the Parameter Object pattern is used.
## Explanation
The Parameter Object is simply a wrapper object for all parameters of a method.
It is nothing more than just a regular POJO. The advantage of the Parameter Object over a
regular method parameter list is the fact that class fields can have default values.
Once the wrapper class is created for the method parameter list, a corresponding builder class
is also created. Usually it's an inner static class. The final step is to use the builder
to construct a new parameter object. For those parameters that are skipped,
their default values are going to be used.
**Programmatic Example**
Here's the simple `SearchService` class where Method Overloading is used to default values here. To use method overloading, either the number of arguments or argument type has to be different.
```java
public class SearchService {
//Method Overloading example. SortOrder is defaulted in this method
public String search(String type, String sortBy) {
return getQuerySummary(type, sortBy, SortOrder.DESC);
}
/* Method Overloading example. SortBy is defaulted in this method. Note that the type has to be
different here to overload the method */
public String search(String type, SortOrder sortOrder) {
return getQuerySummary(type, "price", sortOrder);
}
private String getQuerySummary(String type, String sortBy, SortOrder sortOrder) {
return "Requesting shoes of type \"" + type + "\" sorted by \"" + sortBy + "\" in \""
+ sortOrder.getValue() + "ending\" order...";
}
}
```
Next we present the `SearchService` with `ParameterObject` created with Builder pattern.
```java
public class SearchService {
/* Parameter Object example. Default values are abstracted into the Parameter Object
at the time of Object creation */
public String search(ParameterObject parameterObject) {
return getQuerySummary(parameterObject.getType(), parameterObject.getSortBy(),
parameterObject.getSortOrder());
}
private String getQuerySummary(String type, String sortBy, SortOrder sortOrder) {
return "Requesting shoes of type \"" + type + "\" sorted by \"" + sortBy + "\" in \""
+ sortOrder.getValue() + "ending\" order...";
}
}
public class ParameterObject {
public static final String DEFAULT_SORT_BY = "price";
public static final SortOrder DEFAULT_SORT_ORDER = SortOrder.ASC;
private String type;
private String sortBy = DEFAULT_SORT_BY;
private SortOrder sortOrder = DEFAULT_SORT_ORDER;
private ParameterObject(Builder builder) {
type = builder.type;
sortBy = builder.sortBy != null && !builder.sortBy.isBlank() ? builder.sortBy : sortBy;
sortOrder = builder.sortOrder != null ? builder.sortOrder : sortOrder;
}
public static Builder newBuilder() {
return new Builder();
}
//Getters and Setters...
public static final class Builder {
private String type;
private String sortBy;
private SortOrder sortOrder;
private Builder() {
}
public Builder withType(String type) {
this.type = type;
return this;
}
public Builder sortBy(String sortBy) {
this.sortBy = sortBy;
return this;
}
public Builder sortOrder(SortOrder sortOrder) {
this.sortOrder = sortOrder;
return this;
}
public ParameterObject build() {
return new ParameterObject(this);
}
}
}
```
## Class diagram
![alt text](./etc/parameter-object.png "Parameter Object")
## Applicability
This pattern shows us the way to have default parameters for a method in Java as the language doesn't default parameters feature out of the box.
## Credits
- [Does Java have default parameters?](http://dolszewski.com/java/java-default-parameters)

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

View File

@ -0,0 +1,52 @@
@startuml
package com.iluwatar.parameter.object {
class App {
- LOGGER : Logger {static}
+ App()
+ main(args : String[]) {static}
}
class ParameterObject {
+ DEFAULT_SORT_BY : String {static}
+ DEFAULT_SORT_ORDER : SortOrder {static}
- sortBy : String
- sortOrder : SortOrder
- type : String
- ParameterObject(builder : Builder)
+ getSortBy() : String
+ getSortOrder() : SortOrder
+ getType() : String
+ newBuilder() : Builder {static}
+ setSortBy(sortBy : String)
+ setSortOrder(sortOrder : SortOrder)
+ setType(type : String)
}
class Builder {
- sortBy : String
- sortOrder : SortOrder
- type : String
- Builder()
+ build() : ParameterObject
+ sortBy(sortBy : String) : Builder
+ sortOrder(sortOrder : SortOrder) : Builder
+ withType(type : String) : Builder
}
class SearchService {
+ SearchService()
- getQuerySummary(type : String, sortBy : String, sortOrder : SortOrder) : String
+ search(parameterObject : ParameterObject) : String
+ search(type : String, sortBy : String) : String
+ search(type : String, sortOrder : SortOrder) : String
}
enum SortOrder {
+ ASC {static}
+ DESC {static}
- value : String
+ getValue() : String
+ valueOf(name : String) : SortOrder {static}
+ values() : SortOrder[] {static}
}
}
Builder --> "-sortOrder" SortOrder
Builder ..+ ParameterObject
ParameterObject --> "-DEFAULT_SORT_ORDER" SortOrder
@enduml

61
parameter-object/pom.xml Normal file
View File

@ -0,0 +1,61 @@
<?xml version="1.0"?>
<!--
The MIT License
Copyright © 2014-2021 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.24.0-SNAPSHOT</version>
</parent>
<artifactId>parameter-object</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<configuration>
<archive>
<manifest>
<mainClass>com.iluwatar.parameter.object.App</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,62 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The syntax of Java language doesnt allow you to declare a method with a predefined value
* for a parameter. Probably the best option to achieve default method parameters in Java is
* by using the method overloading. Method overloading allows you to declare several methods
* with the same name but with a different number of parameters. But the main problem with
* method overloading as a solution for default parameter values reveals itself when a method
* accepts multiple parameters. Creating an overloaded method for each possible combination of
* parameters might be cumbersome. To deal with this issue, the Parameter Object pattern is used.
* The Parameter Object is simply a wrapper object for all parameters of a method.
* It is nothing more than just a regular POJO. The advantage of the Parameter Object over a
* regular method parameter list is the fact that class fields can have default values.
* Once the wrapper class is created for the method parameter list, a corresponding builder class
* is also created. Usually it's an inner static class. The final step is to use the builder
* to construct a new parameter object. For those parameters that are skipped,
* their default values are going to be used.
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
ParameterObject params = ParameterObject.newBuilder()
.withType("sneakers")
.sortBy("brand")
.build();
LOGGER.info(params.toString());
LOGGER.info(new SearchService().search(params));
}
}

View File

@ -0,0 +1,113 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
public class ParameterObject {
/**
* Default values are defined here.
*/
public static final String DEFAULT_SORT_BY = "price";
public static final SortOrder DEFAULT_SORT_ORDER = SortOrder.ASC;
private String type;
/**
* Default values are assigned here.
*/
private String sortBy = DEFAULT_SORT_BY;
private SortOrder sortOrder = DEFAULT_SORT_ORDER;
/**
* Overriding default values on object creation only when builder object has a valid value.
*/
private ParameterObject(Builder builder) {
setType(builder.type);
setSortBy(builder.sortBy != null && !builder.sortBy.isBlank() ? builder.sortBy : sortBy);
setSortOrder(builder.sortOrder != null ? builder.sortOrder : sortOrder);
}
public static Builder newBuilder() {
return new Builder();
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSortBy() {
return sortBy;
}
public void setSortBy(String sortBy) {
this.sortBy = sortBy;
}
public SortOrder getSortOrder() {
return sortOrder;
}
public void setSortOrder(SortOrder sortOrder) {
this.sortOrder = sortOrder;
}
@Override
public String toString() {
return String.format("ParameterObject[type='%s', sortBy='%s', sortOrder='%s']",
type, sortBy, sortOrder);
}
public static final class Builder {
private String type;
private String sortBy;
private SortOrder sortOrder;
private Builder() {
}
public Builder withType(String type) {
this.type = type;
return this;
}
public Builder sortBy(String sortBy) {
this.sortBy = sortBy;
return this;
}
public Builder sortOrder(SortOrder sortOrder) {
this.sortOrder = sortOrder;
return this;
}
public ParameterObject build() {
return new ParameterObject(this);
}
}
}

View File

@ -0,0 +1,60 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
public class SearchService {
/**
* Below two methods of name `search` is overloaded so that we can send a default value for
* one of the criteria and call the final api. A default SortOrder is sent in the first method
* and a default SortBy is sent in the second method. So two separate method definitions are
* needed for having default values for one argument in each case. Hence multiple overloaded
* methods are needed as the number of argument increases.
*/
public String search(String type, String sortBy) {
return getQuerySummary(type, sortBy, SortOrder.ASC);
}
public String search(String type, SortOrder sortOrder) {
return getQuerySummary(type, "price", sortOrder);
}
/**
* The need for multiple method definitions can be avoided by the Parameter Object pattern.
* Below is the example where only one method is required and all the logic for having default
* values are abstracted into the Parameter Object at the time of object creation.
*/
public String search(ParameterObject parameterObject) {
return getQuerySummary(parameterObject.getType(), parameterObject.getSortBy(),
parameterObject.getSortOrder());
}
private String getQuerySummary(String type, String sortBy, SortOrder sortOrder) {
return String.format("Requesting shoes of type \"%s\" sorted by \"%s\" in \"%sending\" order..",
type,
sortBy,
sortOrder.getValue());
}
}

View File

@ -0,0 +1,39 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
public enum SortOrder {
ASC("asc"),
DESC("desc");
private String value;
SortOrder(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,41 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Application test
*/
class AppTest {
private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class);
@Test
void shouldExecuteApplicationWithoutException() {
App.main(new String[]{});
LOGGER.info("Executed successfully without exception.");
}
}

View File

@ -0,0 +1,63 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ParameterObjectTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ParameterObjectTest.class);
@Test
public void testForDefaultSortBy() {
//Creating parameter object with default value for SortBy set
ParameterObject params = ParameterObject.newBuilder()
.withType("sneakers")
.sortOrder(SortOrder.DESC)
.build();
assertEquals(ParameterObject.DEFAULT_SORT_BY, params.getSortBy(),
"Default SortBy is not set.");
LOGGER.info("{} Default parameter value is set during object creation as no value is passed."
, "SortBy");
}
@Test
public void testForDefaultSortOrder() {
//Creating parameter object with default value for SortOrder set
ParameterObject params = ParameterObject.newBuilder()
.withType("sneakers")
.sortBy("brand")
.build();
assertEquals(ParameterObject.DEFAULT_SORT_ORDER, params.getSortOrder(),
"Default SortOrder is not set.");
LOGGER.info("{} Default parameter value is set during object creation as no value is passed."
, "SortOrder");
}
}

View File

@ -0,0 +1,63 @@
/*
* The MIT License
* Copyright © 2014-2021 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.parameter.object;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
class SearchServiceTest {
private static final Logger LOGGER = LoggerFactory.getLogger(SearchServiceTest.class);
private ParameterObject parameterObject;
private SearchService searchService;
@BeforeEach
public void setUp() {
//Creating parameter object with default values set
parameterObject = ParameterObject.newBuilder()
.withType("sneakers")
.build();
searchService = new SearchService();
}
/**
* Testing parameter object against the overloaded method to verify if the behaviour is same.
*/
@Test
public void testDefaultParametersMatch() {
assertEquals(searchService.search(parameterObject), searchService.search("sneakers",
SortOrder.ASC), "Default Parameter values do not not match.");
LOGGER.info("SortBy Default parameter value matches.");
assertEquals(searchService.search(parameterObject), searchService.search("sneakers",
"price"), "Default Parameter values do not not match.");
LOGGER.info("SortOrder Default parameter value matches.");
LOGGER.info("testDefaultParametersMatch executed successfully without errors.");
}
}

View File

@ -35,12 +35,6 @@
<artifactId>partial-response</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>

View File

@ -23,17 +23,18 @@
package com.iluwatar.partialresponse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Map;
/**
* tests {@link VideoResource}.
*/
@ -44,8 +45,8 @@ class VideoResourceTest {
private static VideoResource resource;
@BeforeAll
static void setUp() {
@BeforeEach
void setUp() {
var videos = Map.of(
1, new Video(1, "Avatar", 178, "epic science fiction film",
"James Cameron", "English"),
@ -70,7 +71,7 @@ class VideoResourceTest {
var fields = new String[]{"id", "title", "length"};
var expectedDetails = "{\"id\": 1,\"title\": \"Avatar\",\"length\": 178}";
Mockito.when(fieldJsonMapper.toJson(Matchers.any(Video.class), Matchers.eq(fields))).thenReturn(expectedDetails);
Mockito.when(fieldJsonMapper.toJson(any(Video.class), eq(fields))).thenReturn(expectedDetails);
var actualFieldsDetails = resource.getDetails(2, fields);

13
pom.xml
View File

@ -41,11 +41,11 @@
<spring-data.version>2.0.14.RELEASE</spring-data.version>
<h2.version>1.4.190</h2.version>
<junit.version>4.12</junit.version>
<junit-jupiter.version>5.5.2</junit-jupiter.version>
<junit-vintage.version>${junit.version}.2</junit-vintage.version>
<junit-jupiter.version>5.7.1</junit-jupiter.version>
<junit-vintage.version>${junit-jupiter.version}</junit-vintage.version>
<sping-test-junit5.version>1.0.2</sping-test-junit5.version>
<compiler.version>3.8.1</compiler.version>
<jacoco.version>0.8.4</jacoco.version>
<jacoco.version>0.8.6</jacoco.version>
<commons-dbcp.version>1.4</commons-dbcp.version>
<camel.version>2.24.0</camel.version>
<guava.version>19.0</guava.version>
@ -208,6 +208,7 @@
<module>factory</module>
<module>separated-interface</module>
<module>special-case</module>
<module>parameter-object</module>
</modules>
<repositories>
@ -273,12 +274,6 @@
<artifactId>camel-stream</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>

View File

@ -23,7 +23,7 @@
package com.iluwatar.producer.consumer;
import java.util.Random;
import java.security.SecureRandom;
/**
* Class responsible for producing unit of work that can be expressed as {@link Item} and submitted
@ -31,7 +31,7 @@ import java.util.Random;
*/
public class Producer {
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
private final ItemQueue queue;

View File

@ -41,10 +41,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -34,11 +34,6 @@
<artifactId>role-object</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,14 +23,14 @@
package com.iluwatar.roleobject;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class ApplicationRoleObjectTest {
import org.junit.jupiter.api.Test;
class ApplicationRoleObjectTest {
@Test
public void shouldExecuteApplicationWithoutException() {
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> ApplicationRoleObject.main(new String[]{}));
}
}

View File

@ -23,15 +23,16 @@
package com.iluwatar.roleobject;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class BorrowerRoleTest {
import org.junit.jupiter.api.Test;
class BorrowerRoleTest {
@Test
public void borrowTest() {
void borrowTest() {
var borrowerRole = new BorrowerRole();
borrowerRole.setName("test");
Assert.assertEquals(borrowerRole.borrow(), "Borrower test wants to get some money.");
assertEquals("Borrower test wants to get some money.", borrowerRole.borrow());
}
}

View File

@ -23,22 +23,22 @@
package com.iluwatar.roleobject;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
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 org.junit.Test;
import org.junit.jupiter.api.Test;
public class CustomerCoreTest {
class CustomerCoreTest {
@Test
public void addRole() {
void addRole() {
var core = new CustomerCore();
assertTrue(core.addRole(Role.Borrower));
}
@Test
public void hasRole() {
void hasRole() {
var core = new CustomerCore();
core.addRole(Role.Borrower);
assertTrue(core.hasRole(Role.Borrower));
@ -46,7 +46,7 @@ public class CustomerCoreTest {
}
@Test
public void remRole() {
void remRole() {
var core = new CustomerCore();
core.addRole(Role.Borrower);
@ -60,7 +60,7 @@ public class CustomerCoreTest {
}
@Test
public void getRole() {
void getRole() {
var core = new CustomerCore();
core.addRole(Role.Borrower);
@ -76,17 +76,17 @@ public class CustomerCoreTest {
@Test
public void toStringTest() {
void toStringTest() {
var core = new CustomerCore();
core.addRole(Role.Borrower);
assertEquals(core.toString(), "Customer{roles=[Borrower]}");
assertEquals("Customer{roles=[Borrower]}", core.toString());
core = new CustomerCore();
core.addRole(Role.Investor);
assertEquals(core.toString(), "Customer{roles=[Investor]}");
assertEquals("Customer{roles=[Investor]}", core.toString());
core = new CustomerCore();
assertEquals(core.toString(), "Customer{roles=[]}");
assertEquals("Customer{roles=[]}", core.toString());
}

View File

@ -23,16 +23,17 @@
package com.iluwatar.roleobject;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class InvestorRoleTest {
import org.junit.jupiter.api.Test;
class InvestorRoleTest {
@Test
public void investTest() {
void investTest() {
var investorRole = new InvestorRole();
investorRole.setName("test");
investorRole.setAmountToInvest(10);
Assert.assertEquals(investorRole.invest(), "Investor test has invested 10 dollars");
assertEquals("Investor test has invested 10 dollars", investorRole.invest());
}
}

View File

@ -23,15 +23,17 @@
package com.iluwatar.roleobject;
import org.junit.Assert;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RoleTest {
import org.junit.jupiter.api.Test;
class RoleTest {
@Test
public void instanceTest() {
void instanceTest() {
var instance = Role.Borrower.instance();
Assert.assertTrue(instance.isPresent());
Assert.assertEquals(instance.get().getClass(), BorrowerRole.class);
assertTrue(instance.isPresent());
assertEquals(instance.get().getClass(), BorrowerRole.class);
}
}

View File

@ -35,11 +35,6 @@
<artifactId>saga</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,18 +23,19 @@
package com.iluwatar.saga.choreography;
import com.iluwatar.saga.orchestration.SagaApplication;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import com.iluwatar.saga.orchestration.SagaApplication;
import org.junit.jupiter.api.Test;
/***
* empty test
*/
public class SagaApplicationTest {
class SagaApplicationTest {
@Test
public void shouldExecuteWithoutException() {
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> SagaApplication.main(new String[]{}));
}
}
}

View File

@ -23,24 +23,25 @@
package com.iluwatar.saga.choreography;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* test to check choreography saga
*/
public class SagaChoreographyTest {
class SagaChoreographyTest {
@Test
public void executeTest() {
void executeTest() {
var sd = serviceDiscovery();
var service = sd.findAny();
var badOrderSaga = service.execute(newSaga("bad_order"));
var goodOrderSaga = service.execute(newSaga("good_order"));
Assert.assertEquals(badOrderSaga.getResult(), Saga.SagaResult.ROLLBACKED);
Assert.assertEquals(goodOrderSaga.getResult(), Saga.SagaResult.FINISHED);
assertEquals(Saga.SagaResult.ROLLBACKED, badOrderSaga.getResult());
assertEquals(Saga.SagaResult.FINISHED, goodOrderSaga.getResult());
}
private static Saga newSaga(Object value) {

View File

@ -23,15 +23,15 @@
package com.iluwatar.saga.orchestration;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* empty test
*/
public class SagaApplicationTest {
class SagaApplicationTest {
@Test
public void mainTest() {
void mainTest() {
SagaApplication.main(new String[]{});
}
}
}

View File

@ -23,28 +23,30 @@
package com.iluwatar.saga.orchestration;
import org.junit.jupiter.api.Test;
import static com.iluwatar.saga.orchestration.Saga.Result;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
/**
* test to test orchestration logic
*/
public class SagaOrchestratorInternallyTest {
class SagaOrchestratorInternallyTest {
private final List<String> records = new ArrayList<>();
@Test
public void executeTest() {
void executeTest() {
var sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
var result = sagaOrchestrator.execute(1);
Assert.assertEquals(result, Result.ROLLBACK);
Assert.assertArrayEquals(
records.toArray(new String[]{}),
new String[]{"+1", "+2", "+3", "+4", "-4", "-3", "-2", "-1"});
assertEquals(Result.ROLLBACK, result);
assertArrayEquals(
new String[]{"+1", "+2", "+3", "+4", "-4", "-3", "-2", "-1"},
records.toArray(new String[]{}));
}
private static Saga newSaga() {

View File

@ -23,22 +23,23 @@
package com.iluwatar.saga.orchestration;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* test to check general logic
*/
public class SagaOrchestratorTest {
class SagaOrchestratorTest {
@Test
public void execute() {
void execute() {
SagaOrchestrator sagaOrchestrator = new SagaOrchestrator(newSaga(), serviceDiscovery());
Saga.Result badOrder = sagaOrchestrator.execute("bad_order");
Saga.Result crashedOrder = sagaOrchestrator.execute("crashed_order");
Assert.assertEquals(badOrder, Saga.Result.ROLLBACK);
Assert.assertEquals(crashedOrder, Saga.Result.CRASHED);
assertEquals(Saga.Result.ROLLBACK, badOrder);
assertEquals(Saga.Result.CRASHED, crashedOrder);
}
private static Saga newSaga() {

View File

@ -30,17 +30,14 @@ import static org.mockito.Mockito.when;
import com.amazonaws.services.lambda.runtime.Context;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
/**
* Unit tests for LambdaInfoApiHandler
*/
@RunWith(MockitoJUnitRunner.class)
public class LambdaInfoApiHandlerTest {
class LambdaInfoApiHandlerTest {
@Test
public void handleRequestWithMockContext() {
void handleRequestWithMockContext() {
var lambdaInfoApiHandler = new LambdaInfoApiHandler();
var context = mock(Context.class);
when(context.getAwsRequestId()).thenReturn("mock aws request id");

View File

@ -36,10 +36,6 @@
<artifactId>sharding</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,9 +23,9 @@
package com.iluwatar.sharding;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -58,7 +58,7 @@ public class LookupShardManager extends ShardManager {
return lookupMap.get(key);
} else {
var shardCount = shardMap.size();
return new Random().nextInt(shardCount - 1) + 1;
return new SecureRandom().nextInt(shardCount - 1) + 1;
}
}

View File

@ -23,17 +23,17 @@
package com.iluwatar.sharding;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;
/**
* Unit tests for App class.
*/
public class AppTest {
class AppTest {
@Test
public void shouldExecuteWithoutException() {
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}

View File

@ -23,22 +23,22 @@
package com.iluwatar.sharding;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for HashShardManager class.
*/
public class HashShardManagerTest {
class HashShardManagerTest {
private HashShardManager hashShardManager;
/**
* Initialize hashShardManager instance.
*/
@Before
@BeforeEach
public void setup() {
hashShardManager = new HashShardManager();
var shard1 = new Shard(1);
@ -49,16 +49,11 @@ public class HashShardManagerTest {
hashShardManager.addNewShard(shard3);
}
@After
public void tearDown() {
}
@Test
public void testStoreData() {
void testStoreData() {
var data = new Data(1, "test", Data.DataType.TYPE_1);
hashShardManager.storeData(data);
Assert.assertEquals(data, hashShardManager.getShardById(1).getDataById(1));
assertEquals(data, hashShardManager.getShardById(1).getDataById(1));
}
}

View File

@ -23,22 +23,24 @@
package com.iluwatar.sharding;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for LookupShardManager class.
*/
public class LookupShardManagerTest {
class LookupShardManagerTest {
private LookupShardManager lookupShardManager;
/**
* Initialize lookupShardManager instance.
*/
@Before
@BeforeEach
public void setup() {
lookupShardManager = new LookupShardManager();
var shard1 = new Shard(1);
@ -50,7 +52,7 @@ public class LookupShardManagerTest {
}
@Test
public void testStoreData() {
void testStoreData() {
try {
var data = new Data(1, "test", Data.DataType.TYPE_1);
lookupShardManager.storeData(data);
@ -59,9 +61,9 @@ public class LookupShardManagerTest {
var lookupMap = (Map<Integer, Integer>) field.get(lookupShardManager);
var shardId = lookupMap.get(1);
var shard = lookupShardManager.getShardById(shardId);
Assert.assertEquals(data, shard.getDataById(1));
assertEquals(data, shard.getDataById(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
}

View File

@ -23,21 +23,22 @@
package com.iluwatar.sharding;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for RangeShardManager class.
*/
public class RangeShardManagerTest {
class RangeShardManagerTest {
private RangeShardManager rangeShardManager;
/**
* Initialize rangeShardManager instance.
*/
@Before
@BeforeEach
public void setup() {
rangeShardManager = new RangeShardManager();
var shard1 = new Shard(1);
@ -49,10 +50,10 @@ public class RangeShardManagerTest {
}
@Test
public void testStoreData() {
void testStoreData() {
var data = new Data(1, "test", Data.DataType.TYPE_1);
rangeShardManager.storeData(data);
Assert.assertEquals(data, rangeShardManager.getShardById(1).getDataById(1));
assertEquals(data, rangeShardManager.getShardById(1).getDataById(1));
}
}

View File

@ -23,49 +23,46 @@
package com.iluwatar.sharding;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for ShardManager class.
*/
public class ShardManagerTest {
class ShardManagerTest {
private ShardManager shardManager;
/**
* Initialize shardManager instance.
*/
@Before
public void setup() {
@BeforeEach
void setup() {
shardManager = new TestShardManager();
}
@After
public void tearDown() {
}
@Test
public void testAddNewShard() {
void testAddNewShard() {
try {
var shard = new Shard(1);
shardManager.addNewShard(shard);
var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true);
var map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(1, map.size());
Assert.assertEquals(shard, map.get(1));
assertEquals(1, map.size());
assertEquals(shard, map.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
@Test
public void testRemoveShardById() {
void testRemoveShardById() {
try {
var shard = new Shard(1);
shardManager.addNewShard(shard);
@ -73,19 +70,19 @@ public class ShardManagerTest {
var field = ShardManager.class.getDeclaredField("shardMap");
field.setAccessible(true);
var map = (Map<Integer, Shard>) field.get(shardManager);
Assert.assertEquals(true, flag);
Assert.assertEquals(0, map.size());
assertTrue(flag);
assertEquals(0, map.size());
} catch (IllegalAccessException | NoSuchFieldException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
@Test
public void testGetShardById() {
void testGetShardById() {
var shard = new Shard(1);
shardManager.addNewShard(shard);
var tmpShard = shardManager.getShardById(1);
Assert.assertEquals(shard, tmpShard);
assertEquals(shard, tmpShard);
}
class TestShardManager extends ShardManager {

View File

@ -23,50 +23,47 @@
package com.iluwatar.sharding;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Unit tests for Shard class.
*/
public class ShardTest {
class ShardTest {
private Data data;
private Shard shard;
@Before
@BeforeEach
public void setup() {
data = new Data(1, "test", Data.DataType.TYPE_1);
shard = new Shard(1);
}
@After
public void tearDown() {
}
@Test
public void testStoreData() {
void testStoreData() {
try {
shard.storeData(data);
var field = Shard.class.getDeclaredField("dataStore");
field.setAccessible(true);
var dataMap = (Map<Integer, Data>) field.get(shard);
Assert.assertEquals(1, dataMap.size());
Assert.assertEquals(data, dataMap.get(1));
assertEquals(1, dataMap.size());
assertEquals(data, dataMap.get(1));
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
@Test
public void testClearData() {
void testClearData() {
try {
var dataMap = new HashMap<Integer, Data>();
dataMap.put(1, data);
@ -75,9 +72,9 @@ public class ShardTest {
field.set(shard, dataMap);
shard.clearData();
dataMap = (HashMap<Integer, Data>) field.get(shard);
Assert.assertEquals(0, dataMap.size());
assertEquals(0, dataMap.size());
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail("Fail to modify field access.");
fail("Fail to modify field access.");
}
}
}

View File

@ -38,10 +38,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -23,15 +23,17 @@
package com.iluwatar.singleton;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.lang.reflect.InvocationTargetException;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Date: 12/29/15 - 19:26 PM.
*
* @author Jeroen Meulemeester
*/
public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDoubleCheckLocking> {
class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDoubleCheckLocking> {
/**
* Create a new singleton test instance using the given 'getInstance' method.
@ -43,12 +45,12 @@ public class ThreadSafeDoubleCheckLockingTest extends SingletonTest<ThreadSafeDo
/**
* Test creating new instance by refection.
*/
@Test(expected = InvocationTargetException.class)
public void testCreatingNewInstanceByRefection() throws Exception {
@Test
void testCreatingNewInstanceByRefection() throws Exception {
ThreadSafeDoubleCheckLocking.getInstance();
var constructor = ThreadSafeDoubleCheckLocking.class.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance((Object[]) null);
assertThrows(InvocationTargetException.class, () -> constructor.newInstance((Object[]) null));
}
}

View File

@ -23,8 +23,8 @@
package com.iluwatar.spatialpartition;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -112,7 +112,7 @@ public class App {
public static void main(String[] args) {
var bubbles1 = new HashMap<Integer, Bubble>();
var bubbles2 = new HashMap<Integer, Bubble>();
var rand = new Random();
var rand = new SecureRandom();
for (int i = 0; i < 10000; i++) {
var b = new Bubble(rand.nextInt(300), rand.nextInt(300), i, rand.nextInt(2) + 1);
bubbles1.put(i, b);

View File

@ -23,9 +23,9 @@
package com.iluwatar.spatialpartition;
import java.security.SecureRandom;
import java.util.Collection;
import java.util.HashMap;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -36,7 +36,7 @@ import org.slf4j.LoggerFactory;
public class Bubble extends Point<Bubble> {
private static final Logger LOGGER = LoggerFactory.getLogger(Bubble.class);
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
final int radius;

View File

@ -36,10 +36,6 @@
<artifactId>subclass-sandbox</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>

View File

@ -23,17 +23,17 @@
package com.iluwatar.subclasssandbox;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;
/**
* App unit tests.
*/
public class AppTest {
class AppTest {
@Test
public void shouldExecuteWithoutException() {
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@ -23,45 +23,45 @@
package com.iluwatar.subclasssandbox;
import com.github.stefanbirkner.systemlambda.Statement;
import org.junit.Assert;
import org.junit.Test;
import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.stefanbirkner.systemlambda.Statement;
import org.junit.jupiter.api.Test;
/**
* GroundDive unit tests.
*/
public class GroundDiveTest {
class GroundDiveTest {
@Test
public void testMove() throws Exception {
void testMove() throws Exception {
var groundDive = new GroundDive();
groundDive.move(1.0, 1.0, 1.0);
var outputLog = getLogContent(() -> groundDive.move(1.0, 1.0, 1.0));
var expectedLog = "Move to ( 1.0, 1.0, 1.0 )";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testPlaySound() throws Exception {
void testPlaySound() throws Exception {
var groundDive = new GroundDive();
var outputLog = getLogContent(() -> groundDive.playSound("SOUND_NAME", 1));
var expectedLog = "Play SOUND_NAME with volumn 1";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testSpawnParticles() throws Exception {
void testSpawnParticles() throws Exception {
var groundDive = new GroundDive();
final var outputLog = getLogContent(
() -> groundDive.spawnParticles("PARTICLE_TYPE", 100));
final var expectedLog = "Spawn 100 particle with type PARTICLE_TYPE";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testActivate() throws Exception {
void testActivate() throws Exception {
var groundDive = new GroundDive();
var logs = tapSystemOutNormalized(groundDive::activate)
.split("\n");
@ -72,10 +72,10 @@ public class GroundDiveTest {
final var expectedLog2 = "Play GROUNDDIVE_SOUND with volumn 5";
final var log3 = getLogContent(logs[2]);
final var expectedLog3 = "Spawn 20 particle with type GROUNDDIVE_PARTICLE";
Assert.assertEquals(logs.length, expectedSize);
Assert.assertEquals(log1, expectedLog1);
Assert.assertEquals(log2, expectedLog2);
Assert.assertEquals(log3, expectedLog3);
assertEquals(logs.length, expectedSize);
assertEquals(log1, expectedLog1);
assertEquals(log2, expectedLog2);
assertEquals(log3, expectedLog3);
}
private String getLogContent(Statement statement) throws Exception {

View File

@ -23,44 +23,44 @@
package com.iluwatar.subclasssandbox;
import com.github.stefanbirkner.systemlambda.Statement;
import org.junit.Assert;
import org.junit.Test;
import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.stefanbirkner.systemlambda.Statement;
import org.junit.jupiter.api.Test;
/**
* SkyLaunch unit tests.
*/
public class SkyLaunchTest {
class SkyLaunchTest {
@Test
public void testMove() throws Exception {
void testMove() throws Exception {
var skyLaunch = new SkyLaunch();
var outputLog = getLogContent(() -> skyLaunch.move(1.0, 1.0, 1.0));
var expectedLog = "Move to ( 1.0, 1.0, 1.0 )";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testPlaySound() throws Exception {
void testPlaySound() throws Exception {
var skyLaunch = new SkyLaunch();
var outputLog = getLogContent(() -> skyLaunch.playSound("SOUND_NAME", 1));
var expectedLog = "Play SOUND_NAME with volumn 1";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testSpawnParticles() throws Exception {
void testSpawnParticles() throws Exception {
var skyLaunch = new SkyLaunch();
var outputLog = getLogContent(
() -> skyLaunch.spawnParticles("PARTICLE_TYPE", 100));
var expectedLog = "Spawn 100 particle with type PARTICLE_TYPE";
Assert.assertEquals(outputLog, expectedLog);
assertEquals(outputLog, expectedLog);
}
@Test
public void testActivate() throws Exception {
void testActivate() throws Exception {
var skyLaunch = new SkyLaunch();
var logs = tapSystemOutNormalized(skyLaunch::activate)
.split("\n");
@ -71,10 +71,10 @@ public class SkyLaunchTest {
final var expectedLog2 = "Play SKYLAUNCH_SOUND with volumn 1";
final var log3 = getLogContent(logs[2]);
final var expectedLog3 = "Spawn 100 particle with type SKYLAUNCH_PARTICLE";
Assert.assertEquals(logs.length, expectedSize);
Assert.assertEquals(log1, expectedLog1);
Assert.assertEquals(log2, expectedLog2);
Assert.assertEquals(log3, expectedLog3);
assertEquals(logs.length, expectedSize);
assertEquals(log1, expectedLog1);
assertEquals(log2, expectedLog2);
assertEquals(log3, expectedLog3);
}
private String getLogContent(Statement statement) throws Exception {

View File

@ -38,11 +38,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-migrationsupport</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -68,7 +68,7 @@ public final class RainbowFishSerializer {
var map = Map.of(
"name", rainbowFish.getName(),
"age", String.format("%d", rainbowFish.getAge()),
"lengthMeters", String.format("%d", rainbowFish.getLengthMeters()),
LENGTH_METERS, String.format("%d", rainbowFish.getLengthMeters()),
WEIGHT_TONS, String.format("%d", rainbowFish.getWeightTons()),
"angry", Boolean.toString(rainbowFish.getAngry()),
"hungry", Boolean.toString(rainbowFish.getHungry()),
@ -95,7 +95,7 @@ public final class RainbowFishSerializer {
return new RainbowFish(
map.get("name"),
Integer.parseInt(map.get("age")),
Integer.parseInt(map.get("lengthMeters")),
Integer.parseInt(map.get(LENGTH_METERS)),
Integer.parseInt(map.get(WEIGHT_TONS))
);
}

View File

@ -23,14 +23,13 @@
package com.iluwatar.tolerantreader;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import java.io.File;
import java.io.IOException;
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.assertDoesNotThrow;
/**
* Application test
*/

View File

@ -25,26 +25,32 @@ package com.iluwatar.tolerantreader;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import org.junit.Rule;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
import org.junit.rules.TemporaryFolder;
import org.junit.jupiter.api.io.TempDir;
/**
* Date: 12/30/15 - 18:39 PM
*
* @author Jeroen Meulemeester
*/
@EnableRuleMigrationSupport
public class RainbowFishSerializerTest {
class RainbowFishSerializerTest {
/**
* Create a temporary folder, used to generate files in during this test
*/
@Rule
public final TemporaryFolder testFolder = new TemporaryFolder();
@TempDir
static Path testFolder;
@BeforeEach
void beforeEach() {
assertTrue(Files.isDirectory(testFolder));
}
/**
* Rainbow fish version 1 used during the tests
@ -60,11 +66,11 @@ public class RainbowFishSerializerTest {
* Verify if a fish, written as version 1 can be read back as version 1
*/
@Test
public void testWriteV1ReadV1() throws Exception {
final var outputFile = this.testFolder.newFile();
RainbowFishSerializer.writeV1(V1, outputFile.getPath());
void testWriteV1ReadV1() throws Exception {
final var outputPath = Files.createFile(testFolder.resolve("outputFile"));
RainbowFishSerializer.writeV1(V1, outputPath.toString());
final var fish = RainbowFishSerializer.readV1(outputFile.getPath());
final var fish = RainbowFishSerializer.readV1(outputPath.toString());
assertNotSame(V1, fish);
assertEquals(V1.getName(), fish.getName());
assertEquals(V1.getAge(), fish.getAge());
@ -77,11 +83,11 @@ public class RainbowFishSerializerTest {
* Verify if a fish, written as version 2 can be read back as version 1
*/
@Test
public void testWriteV2ReadV1() throws Exception {
final var outputFile = this.testFolder.newFile();
RainbowFishSerializer.writeV2(V2, outputFile.getPath());
void testWriteV2ReadV1() throws Exception {
final var outputPath = Files.createFile(testFolder.resolve("outputFile2"));
RainbowFishSerializer.writeV2(V2, outputPath.toString());
final var fish = RainbowFishSerializer.readV1(outputFile.getPath());
final var fish = RainbowFishSerializer.readV1(outputPath.toString());
assertNotSame(V2, fish);
assertEquals(V2.getName(), fish.getName());
assertEquals(V2.getAge(), fish.getAge());
@ -89,4 +95,4 @@ public class RainbowFishSerializerTest {
assertEquals(V2.getWeightTons(), fish.getWeightTons());
}
}
}

View File

@ -23,22 +23,22 @@
package com.iluwatar.tolerantreader;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Date: 12/30/15 - 18:34 PM
*
* @author Jeroen Meulemeester
*/
public class RainbowFishTest {
class RainbowFishTest {
/**
* Verify if the getters of a {@link RainbowFish} return the expected values
*/
@Test
public void testValues() {
void testValues() {
final var fish = new RainbowFish("name", 1, 2, 3);
assertEquals("name", fish.getName());
assertEquals(1, fish.getAge());

View File

@ -27,20 +27,20 @@ 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 org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Date: 12/30/15 - 18:35 PM
*
* @author Jeroen Meulemeester
*/
public class RainbowFishV2Test {
class RainbowFishV2Test {
/**
* Verify if the getters of a {@link RainbowFish} return the expected values
*/
@Test
public void testValues() {
void testValues() {
final var fish = new RainbowFishV2("name", 1, 2, 3, false, true, false);
assertEquals("name", fish.getName());
assertEquals(1, fish.getAge());

87
tr/singleton/README.md Normal file
View File

@ -0,0 +1,87 @@
---
layout: pattern
title: Singleton
folder: singleton
permalink: /patterns/singleton/
categories: Creational
tags:
- Gang of Four
---
## Amaç
Bir sınıfın yalnızca bir örneğine sahip olduğundan emin olun ve ona global bir erişim noktası sağlayın.
## Açıklama
Örnek
> Büyücülerin büyülerini çalıstıkları tek bir fildişi kule olabilir. Aynı büyülü fildişi kule,
> büyücüler tarafından her zaman kullanılır. Buradaki fildişi kulesi singleton tasarım desenine örnektir.
Özetle
> Belirli bir sınıftan yalnızca bir nesnenin oluşturulmasını sağlar.
Wikipedia açıklaması
> Yazılım mühendisliğinde, tekil desen, bir sınıfın somutlaştırılmasını tek bir nesneyle sınırlayan
> bir yazılım tasarım modelidir.Bu,sistemdeki eylemleri koordine etmek için
> tam olarak bir nesne gerektiğinde kullanışlıdır.
**Örnek**
Joshua Bloch, Effective Java 2nd Edition p.18
> Enum singleton tasarım desenini uygulamak için en iyi yoldur.
```java
public enum EnumIvoryTower {
INSTANCE
}
```
Tanımladıktan sonra kullanmak için:
```java
var enumIvoryTower1 = EnumIvoryTower.INSTANCE;
var enumIvoryTower2 = EnumIvoryTower.INSTANCE;
assertEquals(enumIvoryTower1, enumIvoryTower2); // true
```
## Sınıf diagramı
![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/singleton/etc/singleton.urm.png)
## Uygulanabilirlik
Singleton tasarım deseni şu durumlarda kullanılmalıdır
* Bir sınıfın tam olarak bir örneği olmalı ve iyi bilinen bir erişim noktasından istemciler tarafından erişilebilir olmalıdır.
* Tek örnek alt sınıflandırma yoluyla genişletilebilir olduğunda ve istemciler, kodlarını değiştirmeden genişletilmiş bir örnek kullanabilmelidir
## Use Case
* Logging sınıflarında
* Database bağlantılarını yönetmek için
* File manager
## Gerçek dünya örnekleri
* [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29)
* [java.awt.Desktop#getDesktop()](http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#getDesktop--)
* [java.lang.System#getSecurityManager()](http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getSecurityManager--)
## Sonuçlar
* Kendi yaratımını ve yaşam döngüsünü kontrol ederek Tek Sorumluluk İlkesini (SRP) ihlal ediyor.
* Bu nesne tarafından kullanılan bir nesnenin ve kaynakların serbest bırakılmasını önleyen global bir paylaşılan örnek kullanmayı teşvik eder.
* Birbirine sıkı bağlı kod oluşturur. Singleton tasarım deseni kullanan istemci sınıflarını test etmek zorlaşır.
* Bir Singleton tasarım deseninden alt sınıflar oluşturmak neredeyse imkansız hale gelir.
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)

View File

@ -98,7 +98,7 @@ public interface Trampoline<T> {
return trampoline(this);
}
private T trampoline(final Trampoline<T> trampoline) {
T trampoline(final Trampoline<T> trampoline) {
return Stream.iterate(trampoline, Trampoline::jump)
.filter(Trampoline::complete)
.findFirst()

View File

@ -26,9 +26,9 @@ package com.iluwatar.typeobject;
import com.iluwatar.typeobject.Candy.Type;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.json.simple.parser.ParseException;
/**
@ -38,7 +38,7 @@ import org.json.simple.parser.ParseException;
*/
public class CellPool {
private static final Random RANDOM = new Random();
private static final SecureRandom RANDOM = new SecureRandom();
public static final String FRUIT = "fruit";
public static final String CANDY = "candy";
List<Cell> pool;

View File

@ -35,19 +35,9 @@
<artifactId>unit-of-work</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -23,17 +23,17 @@
package com.iluwatar.unitofwork;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import org.junit.jupiter.api.Test;
/**
* AppTest
*/
public class AppTest {
class AppTest {
@Test
public void shouldExecuteWithoutException() {
void shouldExecuteWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

View File

@ -23,43 +23,32 @@
package com.iluwatar.unitofwork;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import java.util.HashMap;
import java.util.List;
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 org.junit.jupiter.api.Test;
/**
* tests {@link StudentRepository}
*/
@RunWith(MockitoJUnitRunner.class)
public class StudentRepositoryTest {
class StudentRepositoryTest {
private final Student student1 = new Student(1, "Ram", "street 9, cupertino");
private final Student student2 = new Student(1, "Sham", "Z bridge, pune");
private Map<String, List<Student>> context;
@Mock
private StudentDatabase studentDatabase;
private StudentRepository studentRepository;
@Before
public void setUp() {
context = new HashMap<>();
studentRepository = new StudentRepository(context, studentDatabase);
}
private final Map<String, List<Student>> context = new HashMap<>();
private final StudentDatabase studentDatabase = mock(StudentDatabase.class);
private final StudentRepository studentRepository = new StudentRepository(context, studentDatabase);;
@Test
public void shouldSaveNewStudentWithoutWritingToDb() {
void shouldSaveNewStudentWithoutWritingToDb() {
studentRepository.registerNew(student1);
studentRepository.registerNew(student2);
@ -68,7 +57,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldSaveDeletedStudentWithoutWritingToDb() {
void shouldSaveDeletedStudentWithoutWritingToDb() {
studentRepository.registerDeleted(student1);
studentRepository.registerDeleted(student2);
@ -77,7 +66,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldSaveModifiedStudentWithoutWritingToDb() {
void shouldSaveModifiedStudentWithoutWritingToDb() {
studentRepository.registerModified(student1);
studentRepository.registerModified(student2);
@ -86,7 +75,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldSaveAllLocalChangesToDb() {
void shouldSaveAllLocalChangesToDb() {
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
@ -99,7 +88,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldNotWriteToDbIfContextIsNull() {
void shouldNotWriteToDbIfContextIsNull() {
var studentRepository = new StudentRepository(null, studentDatabase);
studentRepository.commit();
@ -108,16 +97,16 @@ public class StudentRepositoryTest {
}
@Test
public void shouldNotWriteToDbIfNothingToCommit() {
void shouldNotWriteToDbIfNothingToCommit() {
var studentRepository = new StudentRepository(new HashMap<>(), studentDatabase);
studentRepository.commit();
verifyZeroInteractions(studentDatabase);
verifyNoMoreInteractions(studentDatabase);
}
@Test
public void shouldNotInsertToDbIfNoRegisteredStudentsToBeCommitted() {
void shouldNotInsertToDbIfNoRegisteredStudentsToBeCommitted() {
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
@ -127,7 +116,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldNotModifyToDbIfNotRegisteredStudentsToBeCommitted() {
void shouldNotModifyToDbIfNotRegisteredStudentsToBeCommitted() {
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
@ -137,7 +126,7 @@ public class StudentRepositoryTest {
}
@Test
public void shouldNotDeleteFromDbIfNotRegisteredStudentsToBeCommitted() {
void shouldNotDeleteFromDbIfNotRegisteredStudentsToBeCommitted() {
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
@ -145,4 +134,4 @@ public class StudentRepositoryTest {
verify(studentDatabase, never()).delete(student1);
}
}
}

View File

@ -35,10 +35,6 @@
<artifactId>update-method</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>

View File

@ -23,9 +23,9 @@
package com.iluwatar.updatemethod;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -66,7 +66,7 @@ public class World {
*/
private void processInput() {
try {
int lag = new Random().nextInt(200) + 50;
int lag = new SecureRandom().nextInt(200) + 50;
Thread.sleep(lag);
} catch (InterruptedException e) {
LOGGER.error(e.getMessage());

View File

@ -23,14 +23,14 @@
package com.iluwatar.updatemethod;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
public class AppTest {
class AppTest {
@Test
public void shouldExecuteApplicationWithoutException() {
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}

Some files were not shown because too many files have changed in this diff Show More