Merge branch 'master' into BAEL-2762
# Conflicts: # spring-boot-security/pom.xml # spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/SpringBootSecurityApplication.java # spring-boot-security/src/main/java/com/baeldung/springbootsecurity/basic_auth/config/BasicAuthConfiguration.java # spring-boot-security/src/test/java/com/baeldung/springbootsecurity/basic_auth/BasicAuthConfigurationIntegrationTest.java
This commit is contained in:
commit
5421b1af95
|
@ -17,3 +17,4 @@
|
|||
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
||||
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
||||
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
||||
- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm)
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
<version>${org.assertj.core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.dpaukov</groupId>
|
||||
<artifactId>combinatoricslib3</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -77,7 +82,7 @@
|
|||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<guava.version>25.1-jre</guava.version>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.math3.util.CombinatoricsUtils;
|
||||
|
||||
public class ApacheCommonsCombinationGenerator {
|
||||
|
||||
private static final int N = 6;
|
||||
private static final int R = 3;
|
||||
|
||||
/**
|
||||
* Print all combinations of r elements from a set
|
||||
* @param n - number of elements in set
|
||||
* @param r - number of elements in selection
|
||||
*/
|
||||
public static void generate(int n, int r) {
|
||||
Iterator<int[]> iterator = CombinatoricsUtils.combinationsIterator(n, r);
|
||||
while (iterator.hasNext()) {
|
||||
final int[] combination = iterator.next();
|
||||
System.out.println(Arrays.toString(combination));
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
generate(N, R);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import org.paukov.combinatorics3.Generator;
|
||||
|
||||
public class CombinatoricsLibCombinationGenerator {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Generator.combination(0, 1, 2, 3, 4, 5)
|
||||
.simple(3)
|
||||
.stream()
|
||||
.forEach(System.out::println);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class GuavaCombinationsGenerator {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Set<Set<Integer>> combinations = Sets.combinations(ImmutableSet.of(0, 1, 2, 3, 4, 5), 3);
|
||||
System.out.println(combinations.size());
|
||||
System.out.println(Arrays.toString(combinations.toArray()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class IterativeCombinationGenerator {
|
||||
|
||||
private static final int N = 5;
|
||||
private static final int R = 2;
|
||||
|
||||
/**
|
||||
* Generate all combinations of r elements from a set
|
||||
* @param n the number of elements in input set
|
||||
* @param r the number of elements in a combination
|
||||
* @return the list containing all combinations
|
||||
*/
|
||||
public List<int[]> generate(int n, int r) {
|
||||
List<int[]> combinations = new ArrayList<>();
|
||||
int[] combination = new int[r];
|
||||
|
||||
// initialize with lowest lexicographic combination
|
||||
for (int i = 0; i < r; i++) {
|
||||
combination[i] = i;
|
||||
}
|
||||
|
||||
while (combination[r - 1] < n) {
|
||||
combinations.add(combination.clone());
|
||||
|
||||
// generate next combination in lexicographic order
|
||||
int t = r - 1;
|
||||
while (t != 0 && combination[t] == n - r + t) {
|
||||
t--;
|
||||
}
|
||||
combination[t]++;
|
||||
for (int i = t + 1; i < r; i++) {
|
||||
combination[i] = combination[i - 1] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return combinations;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
|
||||
List<int[]> combinations = generator.generate(N, R);
|
||||
System.out.println(combinations.size());
|
||||
for (int[] combination : combinations) {
|
||||
System.out.println(Arrays.toString(combination));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SelectionRecursiveCombinationGenerator {
|
||||
|
||||
private static final int N = 6;
|
||||
private static final int R = 3;
|
||||
|
||||
/**
|
||||
* Generate all combinations of r elements from a set
|
||||
* @param n - number of elements in input set
|
||||
* @param r - number of elements to be chosen
|
||||
* @return the list containing all combinations
|
||||
*/
|
||||
public List<int[]> generate(int n, int r) {
|
||||
List<int[]> combinations = new ArrayList<>();
|
||||
helper(combinations, new int[r], 0, n - 1, 0);
|
||||
return combinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose elements from set by recursing over elements selected
|
||||
* @param combinations - List to store generated combinations
|
||||
* @param data - current combination
|
||||
* @param start - starting element of remaining set
|
||||
* @param end - last element of remaining set
|
||||
* @param index - number of elements chosen so far.
|
||||
*/
|
||||
private void helper(List<int[]> combinations, int data[], int start, int end, int index) {
|
||||
if (index == data.length) {
|
||||
int[] combination = data.clone();
|
||||
combinations.add(combination);
|
||||
} else {
|
||||
int max = Math.min(end, end + 1 - data.length + index);
|
||||
for (int i = start; i <= max; i++) {
|
||||
data[index] = i;
|
||||
helper(combinations, data, i + 1, end, index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
|
||||
List<int[]> combinations = generator.generate(N, R);
|
||||
for (int[] combination : combinations) {
|
||||
System.out.println(Arrays.toString(combination));
|
||||
}
|
||||
System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class SetRecursiveCombinationGenerator {
|
||||
|
||||
private static final int N = 5;
|
||||
private static final int R = 2;
|
||||
|
||||
/**
|
||||
* Generate all combinations of r elements from a set
|
||||
* @param n - number of elements in set
|
||||
* @param r - number of elements in selection
|
||||
* @return the list containing all combinations
|
||||
*/
|
||||
public List<int[]> generate(int n, int r) {
|
||||
List<int[]> combinations = new ArrayList<>();
|
||||
helper(combinations, new int[r], 0, n-1, 0);
|
||||
return combinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param combinations - List to contain the generated combinations
|
||||
* @param data - List of elements in the selection
|
||||
* @param start - index of the starting element in the remaining set
|
||||
* @param end - index of the last element in the set
|
||||
* @param index - number of elements selected so far
|
||||
*/
|
||||
private void helper(List<int[]> combinations, int data[], int start, int end, int index) {
|
||||
if (index == data.length) {
|
||||
int[] combination = data.clone();
|
||||
combinations.add(combination);
|
||||
} else if (start <= end) {
|
||||
data[index] = start;
|
||||
helper(combinations, data, start + 1, end, index + 1);
|
||||
helper(combinations, data, start + 1, end, index);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
|
||||
List<int[]> combinations = generator.generate(N, R);
|
||||
for (int[] combination : combinations) {
|
||||
System.out.println(Arrays.toString(combination));
|
||||
}
|
||||
System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.algorithms.combination;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class CombinationUnitTest {
|
||||
|
||||
private static final int N = 5;
|
||||
private static final int R = 3;
|
||||
private static final int nCr = 10;
|
||||
|
||||
@Test
|
||||
public void givenSetAndSelectionSize_whenCalculatedUsingSetRecursiveAlgorithm_thenExpectedCount() {
|
||||
SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
|
||||
List<int[]> selection = generator.generate(N, R);
|
||||
assertEquals(nCr, selection.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSetAndSelectionSize_whenCalculatedUsingSelectionRecursiveAlgorithm_thenExpectedCount() {
|
||||
SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
|
||||
List<int[]> selection = generator.generate(N, R);
|
||||
assertEquals(nCr, selection.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSetAndSelectionSize_whenCalculatedUsingIterativeAlgorithm_thenExpectedCount() {
|
||||
IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
|
||||
List<int[]> selection = generator.generate(N, R);
|
||||
assertEquals(nCr, selection.size());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.algorithms.reversingtree;
|
||||
|
||||
public class TreeNode {
|
||||
|
||||
private int value;
|
||||
private TreeNode rightChild;
|
||||
private TreeNode leftChild;
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public TreeNode getRightChild() {
|
||||
return rightChild;
|
||||
}
|
||||
|
||||
public void setRightChild(TreeNode rightChild) {
|
||||
this.rightChild = rightChild;
|
||||
}
|
||||
|
||||
public TreeNode getLeftChild() {
|
||||
return leftChild;
|
||||
}
|
||||
|
||||
public void setLeftChild(TreeNode leftChild) {
|
||||
this.leftChild = leftChild;
|
||||
}
|
||||
|
||||
public TreeNode(int value, TreeNode rightChild, TreeNode leftChild) {
|
||||
this.value = value;
|
||||
this.rightChild = rightChild;
|
||||
this.leftChild = leftChild;
|
||||
}
|
||||
|
||||
public TreeNode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.algorithms.reversingtree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class TreeReverser {
|
||||
|
||||
public TreeNode createBinaryTree() {
|
||||
|
||||
TreeNode leaf1 = new TreeNode(3);
|
||||
TreeNode leaf2 = new TreeNode(1);
|
||||
TreeNode leaf3 = new TreeNode(9);
|
||||
TreeNode leaf4 = new TreeNode(6);
|
||||
|
||||
TreeNode nodeLeft = new TreeNode(2, leaf1, leaf2);
|
||||
TreeNode nodeRight = new TreeNode(7, leaf3, leaf4);
|
||||
|
||||
TreeNode root = new TreeNode(4, nodeRight, nodeLeft);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public void reverseRecursive(TreeNode treeNode) {
|
||||
if (treeNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TreeNode temp = treeNode.getLeftChild();
|
||||
treeNode.setLeftChild(treeNode.getRightChild());
|
||||
treeNode.setRightChild(temp);
|
||||
|
||||
reverseRecursive(treeNode.getLeftChild());
|
||||
reverseRecursive(treeNode.getRightChild());
|
||||
}
|
||||
|
||||
public void reverseIterative(TreeNode treeNode) {
|
||||
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
|
||||
|
||||
if (treeNode != null) {
|
||||
queue.add(treeNode);
|
||||
}
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
|
||||
TreeNode node = queue.poll();
|
||||
if (node.getLeftChild() != null)
|
||||
queue.add(node.getLeftChild());
|
||||
if (node.getRightChild() != null)
|
||||
queue.add(node.getRightChild());
|
||||
|
||||
TreeNode temp = node.getLeftChild();
|
||||
node.setLeftChild(node.getRightChild());
|
||||
node.setRightChild(temp);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(TreeNode root) {
|
||||
if (root == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuffer buffer = new StringBuffer(String.valueOf(root.getValue())).append(" ");
|
||||
|
||||
buffer.append(toString(root.getLeftChild()));
|
||||
buffer.append(toString(root.getRightChild()));
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.algorithms.reversingtree;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TreeReverserUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenTreeWhenReversingRecursivelyThenReversed() {
|
||||
TreeReverser reverser = new TreeReverser();
|
||||
|
||||
TreeNode treeNode = reverser.createBinaryTree();
|
||||
|
||||
reverser.reverseRecursive(treeNode);
|
||||
|
||||
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||
.trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTreeWhenReversingIterativelyThenReversed() {
|
||||
TreeReverser reverser = new TreeReverser();
|
||||
|
||||
TreeNode treeNode = reverser.createBinaryTree();
|
||||
|
||||
reverser.reverseIterative(treeNode);
|
||||
|
||||
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||
.trim());
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,3 @@
|
|||
## Core Java Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
||||
- [Java - Reading a Large File Efficiently](http://www.baeldung.com/java-read-lines-large-file)
|
||||
- [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string)
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
- [AWS S3 with Java](http://www.baeldung.com/aws-s3-java)
|
||||
- [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda)
|
||||
- [Managing EC2 Instances in Java](http://www.baeldung.com/ec2-java)
|
||||
- [http://www.baeldung.com/aws-s3-multipart-upload](https://github.com/eugenp/tutorials/tree/master/aws)
|
||||
- [Multipart Uploads in Amazon S3 with Java](http://www.baeldung.com/aws-s3-multipart-upload)
|
||||
- [Integration Testing with a Local DynamoDB Instance](http://www.baeldung.com/dynamodb-local-integration-tests)
|
||||
- [Using the JetS3t Java Client With Amazon S3](http://www.baeldung.com/jets3t-amazon-s3)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cas</artifactId>
|
||||
<name>cas</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>cas-secured-app</module>
|
||||
<module>cas-server</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,73 @@
|
|||
issuer:
|
||||
uri: http://localhost:8080/uaa
|
||||
|
||||
spring_profiles: postgresql,default
|
||||
|
||||
database.driverClassName: org.postgresql.Driver
|
||||
database.url: jdbc:postgresql:uaadb2
|
||||
database.username: postgres
|
||||
database.password: postgres
|
||||
|
||||
encryption:
|
||||
active_key_label: CHANGE-THIS-KEY
|
||||
encryption_keys:
|
||||
- label: CHANGE-THIS-KEY
|
||||
passphrase: CHANGEME
|
||||
|
||||
login:
|
||||
serviceProviderKey: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5
|
||||
L39WqS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vA
|
||||
fpOwznoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQAB
|
||||
AoGAVOj2Yvuigi6wJD99AO2fgF64sYCm/BKkX3dFEw0vxTPIh58kiRP554Xt5ges
|
||||
7ZCqL9QpqrChUikO4kJ+nB8Uq2AvaZHbpCEUmbip06IlgdA440o0r0CPo1mgNxGu
|
||||
lhiWRN43Lruzfh9qKPhleg2dvyFGQxy5Gk6KW/t8IS4x4r0CQQD/dceBA+Ndj3Xp
|
||||
ubHfxqNz4GTOxndc/AXAowPGpge2zpgIc7f50t8OHhG6XhsfJ0wyQEEvodDhZPYX
|
||||
kKBnXNHzAkEAyCA76vAwuxqAd3MObhiebniAU3SnPf2u4fdL1EOm92dyFs1JxyyL
|
||||
gu/DsjPjx6tRtn4YAalxCzmAMXFSb1qHfwJBAM3qx3z0gGKbUEWtPHcP7BNsrnWK
|
||||
vw6By7VC8bk/ffpaP2yYspS66Le9fzbFwoDzMVVUO/dELVZyBnhqSRHoXQcCQQCe
|
||||
A2WL8S5o7Vn19rC0GVgu3ZJlUrwiZEVLQdlrticFPXaFrn3Md82ICww3jmURaKHS
|
||||
N+l4lnMda79eSp3OMmq9AkA0p79BvYsLshUJJnvbk76pCjR28PK4dV1gSDUEqQMB
|
||||
qy45ptdwJLqLJCeNoR0JUcDNIRhOCuOPND7pcMtX6hI/
|
||||
-----END RSA PRIVATE KEY-----
|
||||
serviceProviderKeyPassword: password
|
||||
serviceProviderCertificate: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSTCCArKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJhdzEO
|
||||
MAwGA1UECBMFYXJ1YmExDjAMBgNVBAoTBWFydWJhMQ4wDAYDVQQHEwVhcnViYTEO
|
||||
MAwGA1UECxMFYXJ1YmExDjAMBgNVBAMTBWFydWJhMR0wGwYJKoZIhvcNAQkBFg5h
|
||||
cnViYUBhcnViYS5hcjAeFw0xNTExMjAyMjI2MjdaFw0xNjExMTkyMjI2MjdaMHwx
|
||||
CzAJBgNVBAYTAmF3MQ4wDAYDVQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAM
|
||||
BgNVBAcTBWFydWJhMQ4wDAYDVQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAb
|
||||
BgkqhkiG9w0BCQEWDmFydWJhQGFydWJhLmFyMIGfMA0GCSqGSIb3DQEBAQUAA4GN
|
||||
ADCBiQKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5L39W
|
||||
qS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vAfpOw
|
||||
znoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQABo4Ha
|
||||
MIHXMB0GA1UdDgQWBBTx0lDzjH/iOBnOSQaSEWQLx1syGDCBpwYDVR0jBIGfMIGc
|
||||
gBTx0lDzjH/iOBnOSQaSEWQLx1syGKGBgKR+MHwxCzAJBgNVBAYTAmF3MQ4wDAYD
|
||||
VQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAMBgNVBAcTBWFydWJhMQ4wDAYD
|
||||
VQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAbBgkqhkiG9w0BCQEWDmFydWJh
|
||||
QGFydWJhLmFyggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYvBJ
|
||||
0HOZbbHClXmGUjGs+GS+xC1FO/am2suCSYqNB9dyMXfOWiJ1+TLJk+o/YZt8vuxC
|
||||
KdcZYgl4l/L6PxJ982SRhc83ZW2dkAZI4M0/Ud3oePe84k8jm3A7EvH5wi5hvCkK
|
||||
RpuRBwn3Ei+jCRouxTbzKPsuCVB+1sNyxMTXzf0=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
#The secret that an external login server will use to authenticate to the uaa using the id `login`
|
||||
LOGIN_SECRET: loginsecret
|
||||
|
||||
jwt:
|
||||
token:
|
||||
signing-key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAqUeygEfDGxI6c1VDQ6xIyUSLrP6iz1y97iHFbtXSxXaArL4a
|
||||
...
|
||||
v6Mtt5LcRAAVP7pemunTdju4h8Q/noKYlVDVL30uLYUfKBL4UKfOBw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
verification-key: |
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUeygEfDGxI6c1VDQ6xI
|
||||
...
|
||||
AwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>cf-uaa-oauth2-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>uaa-client-webapp</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.cfuaa.oauth2.client;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CFUAAOAuth2ClientApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CFUAAOAuth2ClientApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.cfuaa.oauth2.client;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@RestController
|
||||
public class CFUAAOAuth2ClientController {
|
||||
|
||||
@Value("${resource.server.url}")
|
||||
private String remoteResourceServer;
|
||||
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
private OAuth2AuthorizedClientService authorizedClientService;
|
||||
|
||||
public CFUAAOAuth2ClientController(OAuth2AuthorizedClientService authorizedClientService) {
|
||||
this.authorizedClientService = authorizedClientService;
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
public String index(OAuth2AuthenticationToken authenticationToken) {
|
||||
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||
|
||||
String response = "Hello, " + authenticationToken.getPrincipal().getName();
|
||||
response += "</br></br>";
|
||||
response += "Here is your accees token :</br>" + oAuth2AccessToken.getTokenValue();
|
||||
response += "</br>";
|
||||
response += "</br>You can use it to call these Resource Server APIs:";
|
||||
response += "</br></br>";
|
||||
response += "<a href='/read'>Call Resource Server Read API</a>";
|
||||
response += "</br>";
|
||||
response += "<a href='/write'>Call Resource Server Write API</a>";
|
||||
return response;
|
||||
}
|
||||
|
||||
@RequestMapping("/read")
|
||||
public String read(OAuth2AuthenticationToken authenticationToken) {
|
||||
String url = remoteResourceServer + "/read";
|
||||
return callResourceServer(authenticationToken, url);
|
||||
}
|
||||
|
||||
@RequestMapping("/write")
|
||||
public String write(OAuth2AuthenticationToken authenticationToken) {
|
||||
String url = remoteResourceServer + "/write";
|
||||
return callResourceServer(authenticationToken, url);
|
||||
}
|
||||
|
||||
private String callResourceServer(OAuth2AuthenticationToken authenticationToken, String url) {
|
||||
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Authorization", "Bearer " + oAuth2AccessToken.getTokenValue());
|
||||
|
||||
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
|
||||
ResponseEntity<String> responseEntity = null;
|
||||
|
||||
String response = null;
|
||||
try {
|
||||
responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
|
||||
response = responseEntity.getBody();
|
||||
} catch (HttpClientErrorException e) {
|
||||
response = e.getMessage();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties)
|
||||
#spring.security.oauth2.client.provider.*= # OAuth provider details.
|
||||
#spring.security.oauth2.client.registration.*= # OAuth client registrations.
|
||||
|
||||
server.port=8081
|
||||
#server.servlet.context-path=/uaa-client-webapp
|
||||
|
||||
uaa.url=http://localhost:8080/uaa
|
||||
resource.server.url=http://localhost:8082
|
||||
|
||||
spring.security.oauth2.client.registration.uaa.client-name=UAA OAuth2 Client
|
||||
spring.security.oauth2.client.registration.uaa.client-id=client1
|
||||
spring.security.oauth2.client.registration.uaa.client-secret=client1
|
||||
spring.security.oauth2.client.registration.uaa.authorization-grant-type=authorization_code
|
||||
spring.security.oauth2.client.registration.uaa.scope=resource.read,resource.write,openid,profile
|
||||
spring.security.oauth2.client.registration.uaa.redirect-uri=http://localhost:8081/login/oauth2/code/uaa
|
||||
#spring.security.oauth2.client.registration.uaa.redirect-uri=http://localhost:8081/**
|
||||
|
||||
spring.security.oauth2.client.provider.uaa.token-uri=${uaa.url}/oauth/token
|
||||
spring.security.oauth2.client.provider.uaa.authorization-uri=${uaa.url}/oauth/authorize
|
||||
spring.security.oauth2.client.provider.uaa.jwk-set-uri=${uaa.url}/token_keys
|
||||
spring.security.oauth2.client.provider.uaa.user-info-uri=${uaa.url}/userinfo
|
||||
spring.security.oauth2.client.provider.uaa.user-name-attribute=user_name
|
|
@ -0,0 +1 @@
|
|||
tintin
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung.cfuaa</groupId>
|
||||
<artifactId>cf-uaa-oauth2-resource-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>cf-uaa-oauth2-resource-server</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CFUAAOAuth2ResourceServerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CFUAAOAuth2ResourceServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.security.Principal;
|
||||
|
||||
@RestController
|
||||
public class CFUAAOAuth2ResourceServerRestController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String index(@AuthenticationPrincipal Jwt jwt) {
|
||||
return String.format("Hello, %s!", jwt.getSubject());
|
||||
}
|
||||
|
||||
@GetMapping("/read")
|
||||
public String read(JwtAuthenticationToken jwtAuthenticationToken) {
|
||||
return "Hello write: " + jwtAuthenticationToken.getTokenAttributes();
|
||||
}
|
||||
|
||||
@GetMapping("/write")
|
||||
public String write(Principal principal) {
|
||||
return "Hello write: " + principal.getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@EnableWebSecurity
|
||||
public class CFUAAOAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeRequests()
|
||||
.antMatchers("/read/**").hasAuthority("SCOPE_resource.read")
|
||||
.antMatchers("/write/**").hasAuthority("SCOPE_resource.write")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.oauth2ResourceServer()
|
||||
.jwt();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
server.port=8082
|
||||
|
||||
uaa.url=http://localhost:8080/uaa
|
||||
|
||||
#approch1
|
||||
spring.security.oauth2.resourceserver.jwt.issuer-uri=${uaa.url}/oauth/token
|
||||
|
||||
#approch2
|
||||
#spring.security.oauth2.resourceserver.jwt.jwk-set-uri=${uaa.url}/token_key
|
||||
|
||||
# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties)
|
||||
#security.oauth2.client.client-id=client1
|
||||
#security.oauth2.client.client-secret=client1
|
||||
|
||||
#security.oauth2.resource.jwt.key-uri=${uaa.url}/token_key
|
||||
#security.oauth2.resource.token-info-uri=${uaa.url}/oauth/check_token
|
|
@ -4,3 +4,8 @@
|
|||
|
||||
- [JDBC with Groovy](http://www.baeldung.com/jdbc-groovy)
|
||||
- [Working with JSON in Groovy](http://www.baeldung.com/groovy-json)
|
||||
- [Reading a File in Groovy](https://www.baeldung.com/groovy-file-read)
|
||||
- [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings)
|
||||
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
||||
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
||||
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.io
|
||||
|
||||
class Task implements Serializable {
|
||||
String description
|
||||
Date startDate
|
||||
Date dueDate
|
||||
int status
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
First line of text
|
||||
Second line of text
|
||||
Third line of text
|
||||
Fourth line of text
|
|
@ -0,0 +1,3 @@
|
|||
Line one of output example
|
||||
Line two of output example
|
||||
Line three of output example
|
Binary file not shown.
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.io
|
||||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
class DataAndObjectsUnitTest {
|
||||
@Test
|
||||
void whenUsingWithDataOutputStream_thenDataIsSerializedToAFile() {
|
||||
String message = 'This is a serialized string'
|
||||
int length = message.length()
|
||||
boolean valid = true
|
||||
new File('src/main/resources/ioData.txt').withDataOutputStream { out ->
|
||||
out.writeUTF(message)
|
||||
out.writeInt(length)
|
||||
out.writeBoolean(valid)
|
||||
}
|
||||
|
||||
String loadedMessage = ""
|
||||
int loadedLength
|
||||
boolean loadedValid
|
||||
|
||||
new File('src/main/resources/ioData.txt').withDataInputStream { is ->
|
||||
loadedMessage = is.readUTF()
|
||||
loadedLength = is.readInt()
|
||||
loadedValid = is.readBoolean()
|
||||
}
|
||||
|
||||
assertEquals(message, loadedMessage)
|
||||
assertEquals(length, loadedLength)
|
||||
assertEquals(valid, loadedValid)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingWithObjectOutputStream_thenObjectIsSerializedToFile() {
|
||||
Task task = new Task(description:'Take out the trash', startDate:new Date(), status:0)
|
||||
new File('src/main/resources/ioSerializedObject.txt').withObjectOutputStream { out ->
|
||||
out.writeObject(task)
|
||||
}
|
||||
|
||||
Task taskRead
|
||||
|
||||
new File('src/main/resources/ioSerializedObject.txt').withObjectInputStream { is ->
|
||||
taskRead = is.readObject()
|
||||
}
|
||||
|
||||
assertEquals(task.description, taskRead.description)
|
||||
assertEquals(task.startDate, taskRead.startDate)
|
||||
assertEquals(task.status, taskRead.status)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package com.baeldung.io
|
||||
|
||||
import static org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
|
||||
class ReadExampleUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingEachLine_thenCorrectLinesReturned() {
|
||||
def expectedList = [
|
||||
'First line of text',
|
||||
'Second line of text',
|
||||
'Third line of text',
|
||||
'Fourth line of text']
|
||||
|
||||
def lines = []
|
||||
|
||||
new File('src/main/resources/ioInput.txt').eachLine { line ->
|
||||
lines.add(line)
|
||||
}
|
||||
assertEquals(expectedList, lines)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingReadEachLineWithLineNumber_thenCorrectLinesReturned() {
|
||||
def expectedList = [
|
||||
'Second line of text',
|
||||
'Third line of text',
|
||||
'Fourth line of text']
|
||||
|
||||
def lineNoRange = 2..4
|
||||
def lines = []
|
||||
|
||||
new File('src/main/resources/ioInput.txt').eachLine { line, lineNo ->
|
||||
if (lineNoRange.contains(lineNo)) {
|
||||
lines.add(line)
|
||||
}
|
||||
}
|
||||
assertEquals(expectedList, lines)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingReadEachLineWithLineNumberStartAtZero_thenCorrectLinesReturned() {
|
||||
def expectedList = [
|
||||
'Second line of text',
|
||||
'Third line of text',
|
||||
'Fourth line of text']
|
||||
|
||||
def lineNoRange = 1..3
|
||||
def lines = []
|
||||
|
||||
new File('src/main/resources/ioInput.txt').eachLine(0, { line, lineNo ->
|
||||
if (lineNoRange.contains(lineNo)) {
|
||||
lines.add(line)
|
||||
}
|
||||
})
|
||||
assertEquals(expectedList, lines)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingWithReader_thenLineCountReturned() {
|
||||
def expectedCount = 4
|
||||
def actualCount = 0
|
||||
new File('src/main/resources/ioInput.txt').withReader { reader ->
|
||||
while(reader.readLine()) {
|
||||
actualCount++
|
||||
}
|
||||
}
|
||||
assertEquals(expectedCount, actualCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingNewReader_thenOutputFileCreated() {
|
||||
def outputPath = 'src/main/resources/ioOut.txt'
|
||||
def reader = new File('src/main/resources/ioInput.txt').newReader()
|
||||
new File(outputPath).append(reader)
|
||||
reader.close()
|
||||
def ioOut = new File(outputPath)
|
||||
assertTrue(ioOut.exists())
|
||||
ioOut.delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingWithInputStream_thenCorrectBytesAreReturned() {
|
||||
def expectedLength = 1139
|
||||
byte[] data = []
|
||||
new File("src/main/resources/binaryExample.jpg").withInputStream { stream ->
|
||||
data = stream.getBytes()
|
||||
}
|
||||
assertEquals(expectedLength, data.length)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingNewInputStream_thenOutputFileCreated() {
|
||||
def outputPath = 'src/main/resources/binaryOut.jpg'
|
||||
def is = new File('src/main/resources/binaryExample.jpg').newInputStream()
|
||||
new File(outputPath).append(is)
|
||||
is.close()
|
||||
def ioOut = new File(outputPath)
|
||||
assertTrue(ioOut.exists())
|
||||
ioOut.delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingCollect_thenCorrectListIsReturned() {
|
||||
def expectedList = ['First line of text', 'Second line of text', 'Third line of text', 'Fourth line of text']
|
||||
|
||||
def actualList = new File('src/main/resources/ioInput.txt').collect {it}
|
||||
assertEquals(expectedList, actualList)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingAsStringArray_thenCorrectArrayIsReturned() {
|
||||
String[] expectedArray = ['First line of text', 'Second line of text', 'Third line of text', 'Fourth line of text']
|
||||
|
||||
def actualArray = new File('src/main/resources/ioInput.txt') as String[]
|
||||
assertArrayEquals(expectedArray, actualArray)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingText_thenCorrectStringIsReturned() {
|
||||
def ln = System.getProperty('line.separator')
|
||||
def expectedString = "First line of text${ln}Second line of text${ln}Third line of text${ln}Fourth line of text"
|
||||
def actualString = new File('src/main/resources/ioInput.txt').text
|
||||
assertEquals(expectedString.toString(), actualString)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingBytes_thenByteArrayIsReturned() {
|
||||
def expectedLength = 1139
|
||||
def contents = new File('src/main/resources/binaryExample.jpg').bytes
|
||||
assertEquals(expectedLength, contents.length)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.io
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import groovy.io.FileType
|
||||
import groovy.io.FileVisitResult
|
||||
|
||||
class TraverseFileTreeUnitTest {
|
||||
@Test
|
||||
void whenUsingEachFile_filesAreListed() {
|
||||
new File('src/main/resources').eachFile { file ->
|
||||
println file.name
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException)
|
||||
void whenUsingEachFileOnAFile_anErrorOccurs() {
|
||||
new File('src/main/resources/ioInput.txt').eachFile { file ->
|
||||
println file.name
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileMatch_filesAreListed() {
|
||||
new File('src/main/resources').eachFileMatch(~/io.*\.txt/) { file ->
|
||||
println file.name
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileRecurse_thenFilesInSubfoldersAreListed() {
|
||||
new File('src/main').eachFileRecurse(FileType.FILES) { file ->
|
||||
println "$file.parent $file.name"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachFileRecurse_thenDirsInSubfoldersAreListed() {
|
||||
new File('src/main').eachFileRecurse(FileType.DIRECTORIES) { file ->
|
||||
println "$file.parent $file.name"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingEachDirRecurse_thenDirsAndSubDirsAreListed() {
|
||||
new File('src/main').eachDirRecurse { dir ->
|
||||
println "$dir.parent $dir.name"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingTraverse_thenDirectoryIsTraversed() {
|
||||
new File('src/main').traverse { file ->
|
||||
if (file.directory && file.name == 'groovy') {
|
||||
FileVisitResult.SKIP_SUBTREE
|
||||
} else {
|
||||
println "$file.parent - $file.name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package com.baeldung.io
|
||||
|
||||
import static org.junit.Assert.*
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class WriteExampleUnitTest {
|
||||
@Before
|
||||
void clearOutputFile() {
|
||||
new File('src/main/resources/ioOutput.txt').text = ''
|
||||
new File('src/main/resources/ioBinaryOutput.bin').delete()
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingWithWriter_thenFileCreated() {
|
||||
def outputLines = [
|
||||
'Line one of output example',
|
||||
'Line two of output example',
|
||||
'Line three of output example'
|
||||
]
|
||||
|
||||
def outputFileName = 'src/main/resources/ioOutput.txt'
|
||||
new File(outputFileName).withWriter { writer ->
|
||||
outputLines.each { line ->
|
||||
writer.writeLine line
|
||||
}
|
||||
}
|
||||
def writtenLines = new File(outputFileName).collect {it}
|
||||
assertEquals(outputLines, writtenLines)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingNewWriter_thenFileCreated() {
|
||||
def outputLines = [
|
||||
'Line one of output example',
|
||||
'Line two of output example',
|
||||
'Line three of output example'
|
||||
]
|
||||
|
||||
def outputFileName = 'src/main/resources/ioOutput.txt'
|
||||
def writer = new File(outputFileName).newWriter()
|
||||
outputLines.forEach {line ->
|
||||
writer.writeLine line
|
||||
}
|
||||
writer.flush()
|
||||
writer.close()
|
||||
|
||||
def writtenLines = new File(outputFileName).collect {it}
|
||||
assertEquals(outputLines, writtenLines)
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingDoubleLessThanOperator_thenFileCreated() {
|
||||
def outputLines = [
|
||||
'Line one of output example',
|
||||
'Line two of output example',
|
||||
'Line three of output example'
|
||||
]
|
||||
|
||||
def ln = System.getProperty('line.separator')
|
||||
def outputFileName = 'src/main/resources/ioOutput.txt'
|
||||
new File(outputFileName) << "Line one of output example${ln}Line two of output example${ln}Line three of output example"
|
||||
def writtenLines = new File(outputFileName).collect {it}
|
||||
assertEquals(outputLines.size(), writtenLines.size())
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingBytes_thenBinaryFileCreated() {
|
||||
def outputFileName = 'src/main/resources/ioBinaryOutput.bin'
|
||||
def outputFile = new File(outputFileName)
|
||||
byte[] outBytes = [44, 88, 22]
|
||||
outputFile.bytes = outBytes
|
||||
assertEquals(3, new File(outputFileName).size())
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingWithOutputStream_thenBinaryFileCreated() {
|
||||
def outputFileName = 'src/main/resources/ioBinaryOutput.bin'
|
||||
byte[] outBytes = [44, 88, 22]
|
||||
new File(outputFileName).withOutputStream { stream ->
|
||||
stream.write(outBytes)
|
||||
}
|
||||
assertEquals(3, new File(outputFileName).size())
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingNewOutputStream_thenBinaryFileCreated() {
|
||||
def outputFileName = 'src/main/resources/ioBinaryOutput.bin'
|
||||
byte[] outBytes = [44, 88, 22]
|
||||
def os = new File(outputFileName).newOutputStream()
|
||||
os.write(outBytes)
|
||||
os.close()
|
||||
assertEquals(3, new File(outputFileName).size())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
package com.baeldung.groovy.lists
|
||||
|
||||
import static groovy.test.GroovyAssert.*
|
||||
import org.junit.Test
|
||||
|
||||
class ListTest{
|
||||
|
||||
@Test
|
||||
void testCreateList() {
|
||||
|
||||
def list = [1, 2, 3]
|
||||
assertNotNull(list)
|
||||
|
||||
def listMix = ['A', "b", 1, true]
|
||||
assertTrue(listMix == ['A', "b", 1, true])
|
||||
|
||||
def linkedList = [1, 2, 3] as LinkedList
|
||||
assertTrue(linkedList instanceof LinkedList)
|
||||
|
||||
ArrayList arrList = [1, 2, 3]
|
||||
assertTrue(arrList.class == ArrayList)
|
||||
|
||||
def copyList = new ArrayList(arrList)
|
||||
assertTrue(copyList == arrList)
|
||||
|
||||
def cloneList = arrList.clone()
|
||||
assertTrue(cloneList == arrList)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateEmptyList() {
|
||||
|
||||
def emptyList = []
|
||||
assertTrue(emptyList.size() == 0)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompareTwoLists() {
|
||||
|
||||
def list1 = [5, 6.0, 'p']
|
||||
def list2 = [5, 6.0, 'p']
|
||||
assertTrue(list1 == list2)
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetItemsFromList(){
|
||||
|
||||
def list = ["Hello", "World"]
|
||||
|
||||
assertTrue(list.get(1) == "World")
|
||||
assertTrue(list[1] == "World")
|
||||
assertTrue(list[-1] == "World")
|
||||
assertTrue(list.getAt(1) == "World")
|
||||
assertTrue(list.getAt(-2) == "Hello")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAddItemsToList() {
|
||||
|
||||
def list = []
|
||||
|
||||
list << 1
|
||||
list.add("Apple")
|
||||
assertTrue(list == [1, "Apple"])
|
||||
|
||||
list[2] = "Box"
|
||||
list[4] = true
|
||||
assertTrue(list == [1, "Apple", "Box", null, true])
|
||||
|
||||
list.add(1, 6.0)
|
||||
assertTrue(list == [1, 6.0, "Apple", "Box", null, true])
|
||||
|
||||
def list2 = [1, 2]
|
||||
list += list2
|
||||
list += 12
|
||||
assertTrue(list == [1, 6.0, "Apple", "Box", null, true, 1, 2, 12])
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateItemsInList() {
|
||||
|
||||
def list =[1, "Apple", 80, "App"]
|
||||
list[1] = "Box"
|
||||
list.set(2,90)
|
||||
assertTrue(list == [1, "Box", 90, "App"])
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveItemsFromList(){
|
||||
|
||||
def list = [1, 2, 3, 4, 5, 5, 6, 6, 7]
|
||||
|
||||
list.remove(3)
|
||||
assertTrue(list == [1, 2, 3, 5, 5, 6, 6, 7])
|
||||
|
||||
list.removeElement(5)
|
||||
assertTrue(list == [1, 2, 3, 5, 6, 6, 7])
|
||||
|
||||
assertTrue(list - 6 == [1, 2, 3, 5, 7])
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIteratingOnAList(){
|
||||
|
||||
def list = [1, "App", 3, 4]
|
||||
list.each{ println it * 2}
|
||||
|
||||
list.eachWithIndex{ it, i -> println "$i : $it" }
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCollectingToAnotherList(){
|
||||
|
||||
def list = ["Kay", "Henry", "Justin", "Tom"]
|
||||
assertTrue(list.collect{"Hi " + it} == ["Hi Kay", "Hi Henry", "Hi Justin", "Hi Tom"])
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJoinItemsInAList(){
|
||||
assertTrue(["One", "Two", "Three"].join(",") == "One,Two,Three")
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFilteringOnLists(){
|
||||
def filterList = [2, 1, 3, 4, 5, 6, 76]
|
||||
|
||||
assertTrue(filterList.find{it > 3} == 4)
|
||||
|
||||
assertTrue(filterList.findAll{it > 3} == [4, 5, 6, 76])
|
||||
|
||||
assertTrue(filterList.findAll{ it instanceof Number} == [2, 1, 3, 4, 5, 6, 76])
|
||||
|
||||
assertTrue(filterList.grep( Number )== [2, 1, 3, 4, 5, 6, 76])
|
||||
|
||||
assertTrue(filterList.grep{ it> 6 }== [76])
|
||||
|
||||
def conditionList = [2, 1, 3, 4, 5, 6, 76]
|
||||
|
||||
assertFalse(conditionList.every{ it < 6})
|
||||
|
||||
assertTrue(conditionList.any{ it%2 == 0})
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUniqueItemsInAList(){
|
||||
assertTrue([1, 3, 3, 4].toUnique() == [1, 3, 4])
|
||||
|
||||
def uniqueList = [1, 3, 3, 4]
|
||||
uniqueList.unique()
|
||||
assertTrue(uniqueList == [1, 3, 4])
|
||||
|
||||
assertTrue(["A", "B", "Ba", "Bat", "Cat"].toUnique{ it.size()} == ["A", "Ba", "Bat"])
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSorting(){
|
||||
|
||||
assertTrue([1, 2, 1, 0].sort() == [0, 1, 1, 2])
|
||||
Comparator mc = {a,b -> a == b? 0: a < b? 1 : -1}
|
||||
|
||||
def list = [1, 2, 1, 0]
|
||||
list.sort(mc)
|
||||
assertTrue(list == [2, 1, 1, 0])
|
||||
|
||||
def strList = ["na", "ppp", "as"]
|
||||
assertTrue(strList.max() == "ppp")
|
||||
|
||||
Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1}
|
||||
def numberList = [3, 2, 0, 7]
|
||||
assertTrue(numberList.min(minc) == 0)
|
||||
}
|
||||
}
|
|
@ -4,3 +4,4 @@
|
|||
- [Java 11 Local Variable Syntax for Lambda Parameters](https://www.baeldung.com/java-var-lambda-params)
|
||||
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
||||
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
|
||||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.jlink;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class HelloWorld {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(HelloWorld.class.getName());
|
||||
|
||||
public static void main(String[] args) {
|
||||
LOG.info("Hello World!");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module jlinkModule {
|
||||
requires java.logging;
|
||||
}
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
### Relevant Articles:
|
||||
- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
|
||||
- [Guide to Java 8’s Functional Interfaces](http://www.baeldung.com/java-8-functional-interfaces)
|
||||
- [Functional Interfaces in Java 8](http://www.baeldung.com/java-8-functional-interfaces)
|
||||
- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
|
||||
- [Java 8 New Features](http://www.baeldung.com/java-8-new-features)
|
||||
- [New Features in Java 8](http://www.baeldung.com/java-8-new-features)
|
||||
- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips)
|
||||
- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator)
|
||||
- [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector)
|
||||
|
@ -38,3 +38,5 @@
|
|||
- [Java @SafeVarargs Annotation](https://www.baeldung.com/java-safevarargs)
|
||||
- [Java @Deprecated Annotation](https://www.baeldung.com/java-deprecated)
|
||||
- [Java 8 Predicate Chain](https://www.baeldung.com/java-predicate-chain)
|
||||
- [Method References in Java](https://www.baeldung.com/java-method-references)
|
||||
- [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation)
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
package com.baeldung.java8.optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class OptionalChainingUnitTest {
|
||||
|
||||
private boolean getEmptyEvaluated;
|
||||
private boolean getHelloEvaluated;
|
||||
private boolean getByeEvaluated;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
getEmptyEvaluated = false;
|
||||
getHelloEvaluated = false;
|
||||
getByeEvaluated = false;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturned() {
|
||||
Optional<String> found = Stream.of(getEmpty(), getHello(), getBye())
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
assertEquals(getHello(), found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoEmptyOptionals_whenChaining_thenEmptyOptionalIsReturned() {
|
||||
Optional<String> found = Stream.of(getEmpty(), getEmpty())
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
assertFalse(found.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoEmptyOptionals_whenChaining_thenDefaultIsReturned() {
|
||||
String found = Stream.<Supplier<Optional<String>>>of(
|
||||
() -> createOptional("empty"),
|
||||
() -> createOptional("empty")
|
||||
)
|
||||
.map(Supplier::get)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst()
|
||||
.orElseGet(() -> "default");
|
||||
|
||||
assertEquals("default", found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturnedAndRestNotEvaluated() {
|
||||
Optional<String> found = Stream.<Supplier<Optional<String>>>of(this::getEmpty, this::getHello, this::getBye)
|
||||
.map(Supplier::get)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
assertTrue(this.getEmptyEvaluated);
|
||||
assertTrue(this.getHelloEvaluated);
|
||||
assertFalse(this.getByeEvaluated);
|
||||
assertEquals(getHello(), found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTwoOptionalsReturnedByOneArgMethod_whenChaining_thenFirstNonEmptyIsReturned() {
|
||||
Optional<String> found = Stream.<Supplier<Optional<String>>>of(
|
||||
() -> createOptional("empty"),
|
||||
() -> createOptional("hello")
|
||||
)
|
||||
.map(Supplier::get)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst();
|
||||
|
||||
assertEquals(createOptional("hello"), found);
|
||||
}
|
||||
|
||||
private Optional<String> getEmpty() {
|
||||
this.getEmptyEvaluated = true;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<String> getHello() {
|
||||
this.getHelloEvaluated = true;
|
||||
return Optional.of("hello");
|
||||
}
|
||||
|
||||
private Optional<String> getBye() {
|
||||
this.getByeEvaluated = true;
|
||||
return Optional.of("bye");
|
||||
}
|
||||
|
||||
private Optional<String> createOptional(String input) {
|
||||
if (input == null || input == "" || input == "empty") {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(input);
|
||||
}
|
||||
}
|
|
@ -9,14 +9,13 @@
|
|||
- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
|
||||
- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
|
||||
- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture)
|
||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||
- [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api)
|
||||
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
|
||||
- [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional)
|
||||
- [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams)
|
||||
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
||||
- [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles)
|
||||
- [Exploring the New HTTP Client in Java 9](http://www.baeldung.com/java-9-http-client)
|
||||
- [Exploring the New HTTP Client in Java 9 and 11](http://www.baeldung.com/java-9-http-client)
|
||||
- [Method Handles in Java](http://www.baeldung.com/java-method-handles)
|
||||
- [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue)
|
||||
- [A Guide to Java 9 Modularity](http://www.baeldung.com/java-9-modularity)
|
||||
|
@ -25,5 +24,6 @@
|
|||
- [Iterate Through a Range of Dates in Java](https://www.baeldung.com/java-iterate-date-range)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
### Relevant Articles:
|
||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
||||
- [Guide to the Java ArrayList](http://www.baeldung.com/java-arraylist)
|
||||
- [Random List Element](http://www.baeldung.com/java-random-list-element)
|
||||
- [Java – Get Random Item/Element From a List](http://www.baeldung.com/java-random-list-element)
|
||||
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
|
||||
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
|
||||
- [How to TDD a List Implementation in Java](http://www.baeldung.com/java-test-driven-list)
|
||||
|
@ -28,3 +28,6 @@
|
|||
- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection)
|
||||
- [Multi Dimensional ArrayList in Java](https://www.baeldung.com/java-multi-dimensional-arraylist)
|
||||
- [Determine If All Elements Are the Same in a Java List](https://www.baeldung.com/java-list-all-equal)
|
||||
- [List of Primitive Integer Values in Java](https://www.baeldung.com/java-list-primitive-int)
|
||||
- [Performance Comparison of Primitive Lists in Java](https://www.baeldung.com/java-list-primitive-performance)
|
||||
- [Filtering a Java Collection by a List](https://www.baeldung.com/java-filter-collection-by-list)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.collection.filtering;
|
||||
|
||||
/**
|
||||
* Java 8 Collection Filtering by List of Values base class.
|
||||
*
|
||||
* @author Rodolfo Felipe
|
||||
*/
|
||||
public class Employee {
|
||||
|
||||
private Integer employeeNumber;
|
||||
private String name;
|
||||
private Integer departmentId;
|
||||
|
||||
public Employee(Integer employeeNumber, String name, Integer departmentId) {
|
||||
this.employeeNumber = employeeNumber;
|
||||
this.name = name;
|
||||
this.departmentId = departmentId;
|
||||
}
|
||||
|
||||
public Integer getEmployeeNumber() {
|
||||
return employeeNumber;
|
||||
}
|
||||
|
||||
public void setEmployeeNumber(Integer employeeNumber) {
|
||||
this.employeeNumber = employeeNumber;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getDepartmentId() {
|
||||
return departmentId;
|
||||
}
|
||||
|
||||
public void setDepartmentId(Integer departmentId) {
|
||||
this.departmentId = departmentId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package com.baeldung.collection.filtering;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Various filtering examples.
|
||||
*
|
||||
* @author Rodolfo Felipe
|
||||
*/
|
||||
public class CollectionFilteringUnitTest {
|
||||
|
||||
private List<Employee> buildEmployeeList() {
|
||||
return Arrays.asList(new Employee(1, "Mike", 1), new Employee(2, "John", 1), new Employee(3, "Mary", 1), new Employee(4, "Joe", 2), new Employee(5, "Nicole", 2), new Employee(6, "Alice", 2), new Employee(7, "Bob", 3), new Employee(8, "Scarlett", 3));
|
||||
}
|
||||
|
||||
private List<String> employeeNameFilter() {
|
||||
return Arrays.asList("Alice", "Mike", "Bob");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingForEachLoop() {
|
||||
List<Employee> filteredList = new ArrayList<>();
|
||||
List<Employee> originalList = buildEmployeeList();
|
||||
List<String> nameFilter = employeeNameFilter();
|
||||
|
||||
for (Employee employee : originalList) {
|
||||
for (String name : nameFilter) {
|
||||
if (employee.getName()
|
||||
.equalsIgnoreCase(name)) {
|
||||
filteredList.add(employee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertThat(filteredList.size(), Matchers.is(nameFilter.size()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambda() {
|
||||
List<Employee> filteredList;
|
||||
List<Employee> originalList = buildEmployeeList();
|
||||
List<String> nameFilter = employeeNameFilter();
|
||||
|
||||
filteredList = originalList.stream()
|
||||
.filter(employee -> nameFilter.contains(employee.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assert.assertThat(filteredList.size(), Matchers.is(nameFilter.size()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmployeeList_andNameFilterList_thenObtainFilteredEmployeeList_usingLambdaAndHashSet() {
|
||||
List<Employee> filteredList;
|
||||
List<Employee> originalList = buildEmployeeList();
|
||||
Set<String> nameFilterSet = employeeNameFilter().stream()
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
filteredList = originalList.stream()
|
||||
.filter(employee -> nameFilterSet.contains(employee.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Assert.assertThat(filteredList.size(), Matchers.is(nameFilterSet.size()));
|
||||
}
|
||||
|
||||
}
|
|
@ -32,3 +32,4 @@
|
|||
- [A Guide to Iterator in Java](http://www.baeldung.com/java-iterator)
|
||||
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
||||
- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
package com.baeldung.performance;
|
||||
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.SingleShotTime)
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@Measurement(batchSize = 100000, iterations = 10)
|
||||
@Warmup(batchSize = 100000, iterations = 10)
|
||||
|
@ -19,8 +23,8 @@ public class ArraySortBenchmark {
|
|||
|
||||
@State(Scope.Thread)
|
||||
public static class Initialize {
|
||||
Integer[] numbers = {5, 22, 10, 0};
|
||||
int[] primitives = {5, 22, 10, 0};
|
||||
Integer[] numbers = { -769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737, 1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518, -1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167 };
|
||||
int[] primitives = { -769214442, -1283881723, 1504158300, -1260321086, -1800976432, 1278262737, 1863224321, 1895424914, 2062768552, -1051922993, 751605209, -1500919212, 2094856518, -1014488489, -931226326, -1677121986, -2080561705, 562424208, -1233745158, 41308167 };
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
|
|
|
@ -21,4 +21,5 @@
|
|||
- [Java CyclicBarrier vs CountDownLatch](https://www.baeldung.com/java-cyclicbarrier-countdownlatch)
|
||||
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
|
||||
- [A Guide to ThreadLocalRandom in Java](http://www.baeldung.com/java-thread-local-random)
|
||||
- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join)
|
||||
- [The Thread.join() Method in Java](http://www.baeldung.com/java-thread-join)
|
||||
- [Passing Parameters to Java Threads](https://www.baeldung.com/java-thread-parameters)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## Core Java IO Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Java - Reading a Large File Efficiently](http://www.baeldung.com/java-read-lines-large-file)
|
||||
- [How to Read a Large File Efficiently with Java](http://www.baeldung.com/java-read-lines-large-file)
|
||||
- [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string)
|
||||
- [Java – Write to File](http://www.baeldung.com/java-write-to-file)
|
||||
- [Java - Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream)
|
||||
|
@ -11,7 +11,7 @@
|
|||
- [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer)
|
||||
- [Java – Directory Size](http://www.baeldung.com/java-folder-size)
|
||||
- [Differences Between the Java WatchService API and the Apache Commons IO Monitor Library](http://www.baeldung.com/java-watchservice-vs-apache-commons-io-monitor-library)
|
||||
- [Calculate the Size of a File in Java](http://www.baeldung.com/java-file-size)
|
||||
- [File Size in Java](http://www.baeldung.com/java-file-size)
|
||||
- [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path)
|
||||
- [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer)
|
||||
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
||||
|
@ -30,7 +30,6 @@
|
|||
- [Download a File From an URL in Java](http://www.baeldung.com/java-download-file)
|
||||
- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink)
|
||||
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||
- [Reading a CSV File into an Array](https://www.baeldung.com/java-csv-file-array)
|
||||
|
@ -40,3 +39,4 @@
|
|||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||
- [How to Write to a CSV File in Java](https://www.baeldung.com/java-csv)
|
||||
- [List Files in a Directory in Java](https://www.baeldung.com/java-list-directory-files)
|
||||
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
=========
|
||||
|
||||
## Core Java JVM Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Method Inlining in the JVM](http://www.baeldung.com/method-inlining-in-the-jvm/)
|
|
@ -0,0 +1,40 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>core-java-jvm</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>core-java-jvm</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.inlining;
|
||||
|
||||
public class ConsecutiveNumbersSum {
|
||||
|
||||
private long totalSum;
|
||||
private int totalNumbers;
|
||||
|
||||
public ConsecutiveNumbersSum(int totalNumbers) {
|
||||
this.totalNumbers = totalNumbers;
|
||||
}
|
||||
|
||||
public long getTotalSum() {
|
||||
totalSum = 0;
|
||||
for (int i = 1; i <= totalNumbers; i++) {
|
||||
totalSum += i;
|
||||
}
|
||||
return totalSum;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.inlining;
|
||||
|
||||
public class InliningExample {
|
||||
|
||||
public static final int NUMBERS_OF_ITERATIONS = 15000;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i = 1; i < NUMBERS_OF_ITERATIONS; i++) {
|
||||
calculateSum(i);
|
||||
}
|
||||
}
|
||||
|
||||
private static long calculateSum(int n) {
|
||||
return new ConsecutiveNumbersSum(n).getTotalSum();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.inlining;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ConsecutiveNumbersSumUnitTest {
|
||||
|
||||
private static final int TOTAL_NUMBERS = 10;
|
||||
|
||||
@Test
|
||||
public void givenTotalIntegersNumber_whenSumCalculated_thenEquals() {
|
||||
ConsecutiveNumbersSum consecutiveNumbersSum = new ConsecutiveNumbersSum(TOTAL_NUMBERS);
|
||||
long expectedSum = calculateExpectedSum(TOTAL_NUMBERS);
|
||||
|
||||
assertEquals(expectedSum, consecutiveNumbersSum.getTotalSum());
|
||||
}
|
||||
|
||||
private long calculateExpectedSum(int totalNumbers) {
|
||||
return totalNumbers * (totalNumbers + 1) / 2;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
### Relevant Articles:
|
||||
- [Guide to hashCode() in Java](http://www.baeldung.com/java-hashcode)
|
||||
- [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static)
|
||||
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
|
||||
- [Polymorphism in Java](http://www.baeldung.com/java-polymorphism)
|
||||
- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override)
|
||||
- [How to Make a Deep Copy of an Object in Java](http://www.baeldung.com/java-deep-copy)
|
||||
|
@ -22,3 +21,4 @@
|
|||
- [Inheritance and Composition (Is-a vs Has-a relationship) in Java](http://www.baeldung.com/java-inheritance-composition)
|
||||
- [A Guide to Constructors in Java](https://www.baeldung.com/java-constructors)
|
||||
- [Java equals() and hashCode() Contracts](https://www.baeldung.com/java-equals-hashcode-contracts)
|
||||
- [Marker Interfaces in Java](https://www.baeldung.com/java-marker-interfaces)
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
## Core Java Lang Syntax Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Introduction to Java Generics](http://www.baeldung.com/java-generics)
|
||||
- [The Basics of Java Generics](http://www.baeldung.com/java-generics)
|
||||
- [Java Primitive Conversions](http://www.baeldung.com/java-primitive-conversions)
|
||||
- [Java Double Brace Initialization](http://www.baeldung.com/java-double-brace-initialization)
|
||||
- [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator)
|
||||
- [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break)
|
||||
- [A Guide to Java Initialization](http://www.baeldung.com/java-initialization)
|
||||
- [A Guide to Creating Objects in Java](http://www.baeldung.com/java-initialization)
|
||||
- [A Guide to Java Loops](http://www.baeldung.com/java-loops)
|
||||
- [Varargs in Java](http://www.baeldung.com/java-varargs)
|
||||
- [A Guide to Java Enums](http://www.baeldung.com/a-guide-to-java-enums)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [A Guide to Java Enums](http://www.baeldung.com/a-guide-to-java-enums)
|
|
@ -1,5 +1,6 @@
|
|||
package com.baeldung.generics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
@ -28,4 +29,10 @@ public class Generics {
|
|||
buildings.forEach(Building::paint);
|
||||
}
|
||||
|
||||
public static List<Integer> createList(int a) {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
list.add(a);
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItems;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
@ -66,4 +67,12 @@ public class GenericsUnitTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnInt_whenAddedToAGenericIntegerList_thenAListItemCanBeAssignedToAnInt() {
|
||||
int number = 7;
|
||||
List<Integer> list = Generics.createList(number);
|
||||
int otherNumber = list.get(0);
|
||||
assertThat(otherNumber, is(number));
|
||||
}
|
||||
|
||||
}
|
|
@ -41,3 +41,4 @@
|
|||
- [Java Interfaces](https://www.baeldung.com/java-interfaces)
|
||||
- [Attaching Values to Java Enum](https://www.baeldung.com/java-enum-values)
|
||||
- [Variable Scope in Java](https://www.baeldung.com/java-variable-scope)
|
||||
- [Java Classes and Objects](https://www.baeldung.com/java-classes-objects)
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
- [A Guide to the Java URL](http://www.baeldung.com/java-url)
|
||||
- [Working with Network Interfaces in Java](http://www.baeldung.com/java-network-interfaces)
|
||||
- [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets)
|
||||
- [URL Encoding and Decoding in Java](http://www.baeldung.com/java-url-encoding-decoding)
|
||||
- [How to Perform a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request)
|
||||
- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri)
|
||||
- [Guide to Java URL Encoding/Decoding](http://www.baeldung.com/java-url-encoding-decoding)
|
||||
- [Do a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request)
|
||||
- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri)
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.socket.read;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Client {
|
||||
|
||||
//Initialize socket, input and output stream
|
||||
private Socket socket = null;
|
||||
private DataInputStream in = null;
|
||||
private DataOutputStream out = null;
|
||||
|
||||
public void runClient(String ip, int port) {
|
||||
try {
|
||||
socket = new Socket(ip, port);
|
||||
System.out.println("Connected to server ...");
|
||||
in = new DataInputStream(System.in);
|
||||
out = new DataOutputStream(socket.getOutputStream());
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
char type = 's'; // s for string
|
||||
int length = 29;
|
||||
String data = "This is a string of length 29";
|
||||
byte[] dataInBytes = data.getBytes();
|
||||
//Sending data in TLV format
|
||||
try {
|
||||
out.writeChar(type);
|
||||
out.writeInt(length);
|
||||
out.write(dataInBytes);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.socket.read;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Server {
|
||||
|
||||
//Socket and input stream
|
||||
private Socket socket = null;
|
||||
private ServerSocket server = null;
|
||||
private DataInputStream in = null;
|
||||
|
||||
public void runServer(int port) {
|
||||
//Start the server and wait for connection
|
||||
try {
|
||||
server = new ServerSocket(port);
|
||||
System.out.println("Server Started. Waiting for connection ...");
|
||||
socket = server.accept();
|
||||
System.out.println("Got connection from client.");
|
||||
//Get input stream from socket variable and convert the same to DataInputStream
|
||||
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
|
||||
//Read type and length of data
|
||||
char dataType = in.readChar();
|
||||
int length = in.readInt();
|
||||
System.out.println("Type : "+dataType);
|
||||
System.out.println("Lenght :"+length);
|
||||
//Read String data in bytes
|
||||
byte[] messageByte = new byte[length];
|
||||
boolean end = false;
|
||||
String dataString = "";
|
||||
int totalBytesRead = 0;
|
||||
//We need to run while loop, to read all data in that stream
|
||||
while(!end) {
|
||||
int currentBytesRead = in.read(messageByte);
|
||||
totalBytesRead = currentBytesRead + totalBytesRead;
|
||||
if(totalBytesRead <= length) {
|
||||
dataString += new String(messageByte,0,currentBytesRead);
|
||||
} else {
|
||||
dataString += new String(messageByte,0,length - totalBytesRead + currentBytesRead);
|
||||
}
|
||||
if(dataString.length()>=length) {
|
||||
end = true;
|
||||
}
|
||||
}
|
||||
System.out.println("Read "+length+" bytes of message from client. Message = "+dataString);;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.socket.read;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SocketReadAllDataLiveTest {
|
||||
|
||||
@Test
|
||||
public void givenServerAndClient_whenClientSendsAndServerReceivesData_thenCorrect() {
|
||||
//Run server in new thread
|
||||
Runnable runnable1 = () -> { runServer(); };
|
||||
Thread thread1 = new Thread(runnable1);
|
||||
thread1.start();
|
||||
//Wait for 10 seconds
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//Run client in a new thread
|
||||
Runnable runnable2 = () -> { runClient(); };
|
||||
Thread thread2 = new Thread(runnable2);
|
||||
thread2.start();
|
||||
}
|
||||
|
||||
public static void runServer() {
|
||||
//Run Server
|
||||
Server server = new Server();
|
||||
server.runServer(5555);
|
||||
}
|
||||
|
||||
public static void runClient() {
|
||||
//Run Client
|
||||
Client client = new Client();
|
||||
client.runClient("127.0.0.1", 5555);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
*.class
|
||||
|
||||
0.*
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
.resourceCache
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# Files generated by integration tests
|
||||
*.txt
|
||||
backup-pom.xml
|
||||
/bin/
|
||||
/temp
|
||||
|
||||
#IntelliJ specific
|
||||
.idea/
|
||||
*.iml
|
|
@ -0,0 +1,8 @@
|
|||
=========
|
||||
|
||||
This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
||||
|
||||
##
|
||||
### Relevant Articles:
|
||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
|
@ -0,0 +1,82 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>core-java-os</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-os</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
</dependency>
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-os</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<!-- util -->
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<collections-generic.version>4.01</collections-generic.version>
|
||||
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<asspectj.version>1.8.9</asspectj.version>
|
||||
<maven.compiler.source>1.9</maven.compiler.source>
|
||||
<maven.compiler.target>1.9</maven.compiler.target>
|
||||
<guava.version>25.1-jre</guava.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -3,5 +3,5 @@ package com.baeldung.java9.process;
|
|||
public class ProcessCompilationError {
|
||||
//This method has been written to generate error to display
|
||||
//how process errorStream() can consume error
|
||||
public static void();
|
||||
//public static void();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -18,13 +18,13 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public class ProcessAPIEnhancementsUnitTest {
|
||||
|
||||
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsTest.class);
|
||||
Logger log = LoggerFactory.getLogger(ProcessAPIEnhancementsUnitTest.class);
|
||||
|
||||
@Test
|
||||
public void givenCurrentProcess_whenInvokeGetInfo_thenSuccess() throws IOException {
|
||||
ProcessHandle processHandle = ProcessHandle.current();
|
||||
ProcessHandle.Info processInfo = processHandle.info();
|
||||
assertNotNull(processHandle.getPid());
|
||||
assertNotNull(processHandle.pid());
|
||||
assertEquals(false, processInfo.arguments()
|
||||
.isPresent());
|
||||
assertEquals(true, processInfo.command()
|
||||
|
@ -51,7 +51,7 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||
.start();
|
||||
ProcessHandle processHandle = process.toHandle();
|
||||
ProcessHandle.Info processInfo = processHandle.info();
|
||||
assertNotNull(processHandle.getPid());
|
||||
assertNotNull(processHandle.pid());
|
||||
assertEquals(false, processInfo.arguments()
|
||||
.isPresent());
|
||||
assertEquals(true, processInfo.command()
|
||||
|
@ -72,7 +72,7 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||
Stream<ProcessHandle> liveProcesses = ProcessHandle.allProcesses();
|
||||
liveProcesses.filter(ProcessHandle::isAlive)
|
||||
.forEach(ph -> {
|
||||
assertNotNull(ph.getPid());
|
||||
assertNotNull(ph.pid());
|
||||
assertEquals(true, ph.info()
|
||||
.command()
|
||||
.isPresent());
|
||||
|
@ -102,12 +102,12 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||
Stream<ProcessHandle> children = ProcessHandle.current()
|
||||
.children();
|
||||
children.filter(ProcessHandle::isAlive)
|
||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||
.command()));
|
||||
Stream<ProcessHandle> descendants = ProcessHandle.current()
|
||||
.descendants();
|
||||
descendants.filter(ProcessHandle::isAlive)
|
||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.getPid(), ph.info()
|
||||
.forEach(ph -> log.info("PID: {}, Cmd: {}", ph.pid(), ph.info()
|
||||
.command()));
|
||||
}
|
||||
|
||||
|
@ -121,12 +121,12 @@ public class ProcessAPIEnhancementsUnitTest {
|
|||
.start();
|
||||
ProcessHandle processHandle = process.toHandle();
|
||||
|
||||
log.info("PID: {} has started", processHandle.getPid());
|
||||
log.info("PID: {} has started", processHandle.pid());
|
||||
CompletableFuture<ProcessHandle> onProcessExit = processHandle.onExit();
|
||||
onProcessExit.get();
|
||||
assertEquals(false, processHandle.isAlive());
|
||||
onProcessExit.thenAccept(ph -> {
|
||||
log.info("PID: {} has stopped", ph.getPid());
|
||||
log.info("PID: {} has stopped", ph.pid());
|
||||
});
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ public class ProcessApiUnitTest {
|
|||
@Test
|
||||
public void processInfoExample() throws NoSuchAlgorithmException {
|
||||
ProcessHandle self = ProcessHandle.current();
|
||||
long PID = self.getPid();
|
||||
long PID = self.pid();
|
||||
ProcessHandle.Info procInfo = self.info();
|
||||
Optional<String[]> args = procInfo.arguments();
|
||||
Optional<String> cmd = procInfo.commandLine();
|
||||
|
@ -45,7 +45,7 @@ public class ProcessApiUnitTest {
|
|||
|
||||
Stream<ProcessHandle> allProc = ProcessHandle.current().children();
|
||||
allProc.forEach(p -> {
|
||||
System.out.println("Proc " + p.getPid());
|
||||
System.out.println("Proc " + p.pid());
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class ProcessApiUnitTest {
|
|||
public void createAndDestroyProcess() throws IOException, InterruptedException {
|
||||
int numberOfChildProcesses = 5;
|
||||
for (int i = 0; i < numberOfChildProcesses; i++) {
|
||||
createNewJVM(ServiceMain.class, i).getPid();
|
||||
createNewJVM(ServiceMain.class, i).pid();
|
||||
}
|
||||
|
||||
Stream<ProcessHandle> childProc = ProcessHandle.current().children();
|
||||
|
@ -62,10 +62,10 @@ public class ProcessApiUnitTest {
|
|||
|
||||
childProc = ProcessHandle.current().children();
|
||||
childProc.forEach(processHandle -> {
|
||||
assertTrue("Process " + processHandle.getPid() + " should be alive!", processHandle.isAlive());
|
||||
assertTrue("Process " + processHandle.pid() + " should be alive!", processHandle.isAlive());
|
||||
CompletableFuture<ProcessHandle> onProcExit = processHandle.onExit();
|
||||
onProcExit.thenAccept(procHandle -> {
|
||||
System.out.println("Process with PID " + procHandle.getPid() + " has stopped");
|
||||
System.out.println("Process with PID " + procHandle.pid() + " has stopped");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -73,14 +73,14 @@ public class ProcessApiUnitTest {
|
|||
|
||||
childProc = ProcessHandle.current().children();
|
||||
childProc.forEach(procHandle -> {
|
||||
assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());
|
||||
assertTrue("Could not kill process " + procHandle.pid(), procHandle.destroy());
|
||||
});
|
||||
|
||||
Thread.sleep(5000);
|
||||
|
||||
childProc = ProcessHandle.current().children();
|
||||
childProc.forEach(procHandle -> {
|
||||
assertFalse("Process " + procHandle.getPid() + " should not be alive!", procHandle.isAlive());
|
||||
assertFalse("Process " + procHandle.pid() + " should not be alive!", procHandle.isAlive());
|
||||
});
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ import java.lang.Integer;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ProcessUnderstandingTest {
|
||||
class ProcessUnderstandingUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenSourceProgram_whenExecutedFromAnotherProgram_thenSourceProgramOutput3() throws IOException {
|
|
@ -0,0 +1,182 @@
|
|||
package com.baeldung.processbuilder;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ProcessBuilder.Redirect;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class ProcessBuilderUnitTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder tempFolder = new TemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenInvokeStart_thenSuccess() throws IOException, InterruptedException, ExecutionException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("java", "-version");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
|
||||
List<String> results = readOutput(process.getInputStream());
|
||||
assertThat("Results should not be empty", results, is(not(empty())));
|
||||
assertThat("Results should contain java version: ", results, hasItem(containsString("java version")));
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenModifyEnvironment_thenSuccess() throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
Map<String, String> environment = processBuilder.environment();
|
||||
environment.forEach((key, value) -> System.out.println(key + value));
|
||||
|
||||
environment.put("GREETING", "Hola Mundo");
|
||||
|
||||
List<String> command = getGreetingCommand();
|
||||
processBuilder.command(command);
|
||||
Process process = processBuilder.start();
|
||||
|
||||
List<String> results = readOutput(process.getInputStream());
|
||||
assertThat("Results should not be empty", results, is(not(empty())));
|
||||
assertThat("Results should contain a greeting ", results, hasItem(containsString("Hola Mundo")));
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenModifyWorkingDir_thenSuccess() throws IOException, InterruptedException {
|
||||
List<String> command = getDirectoryListingCommand();
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
|
||||
processBuilder.directory(new File("src"));
|
||||
Process process = processBuilder.start();
|
||||
|
||||
List<String> results = readOutput(process.getInputStream());
|
||||
assertThat("Results should not be empty", results, is(not(empty())));
|
||||
assertThat("Results should contain directory listing: ", results, hasItems(containsString("main"), containsString("test")));
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenRedirectStandardOutput_thenSuccessWriting() throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("java", "-version");
|
||||
|
||||
processBuilder.redirectErrorStream(true);
|
||||
File log = tempFolder.newFile("java-version.log");
|
||||
processBuilder.redirectOutput(log);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
|
||||
assertEquals("If redirected, should be -1 ", -1, process.getInputStream()
|
||||
.read());
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
|
||||
List<String> lines = Files.lines(log.toPath())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat("Results should not be empty", lines, is(not(empty())));
|
||||
assertThat("Results should contain java version: ", lines, hasItem(containsString("java version")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenRedirectStandardOutput_thenSuccessAppending() throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("java", "-version");
|
||||
|
||||
File log = tempFolder.newFile("java-version-append.log");
|
||||
processBuilder.redirectErrorStream(true);
|
||||
processBuilder.redirectOutput(Redirect.appendTo(log));
|
||||
|
||||
Process process = processBuilder.start();
|
||||
|
||||
assertEquals("If redirected output, should be -1 ", -1, process.getInputStream()
|
||||
.read());
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
|
||||
List<String> lines = Files.lines(log.toPath())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat("Results should not be empty", lines, is(not(empty())));
|
||||
assertThat("Results should contain java version: ", lines, hasItem(containsString("java version")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenStartingPipeline_thenSuccess() throws IOException, InterruptedException {
|
||||
if (!isWindows()) {
|
||||
List<ProcessBuilder> builders = Arrays.asList(
|
||||
new ProcessBuilder("find", "src", "-name", "*.java", "-type", "f"),
|
||||
new ProcessBuilder("wc", "-l"));
|
||||
|
||||
List<Process> processes = ProcessBuilder.startPipeline(builders);
|
||||
Process last = processes.get(processes.size() - 1);
|
||||
|
||||
List<String> output = readOutput(last.getInputStream());
|
||||
assertThat("Results should not be empty", output, is(not(empty())));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProcessBuilder_whenInheritIO_thenSuccess() throws IOException, InterruptedException {
|
||||
List<String> command = getEchoCommand();
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
|
||||
processBuilder.inheritIO();
|
||||
Process process = processBuilder.start();
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
}
|
||||
|
||||
private List<String> readOutput(InputStream inputStream) throws IOException {
|
||||
try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
return output.lines()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getDirectoryListingCommand() {
|
||||
return isWindows() ? Arrays.asList("cmd.exe", "/c", "dir") : Arrays.asList("/bin/sh", "-c", "ls");
|
||||
}
|
||||
|
||||
private List<String> getGreetingCommand() {
|
||||
return isWindows() ? Arrays.asList("cmd.exe", "/c", "echo %GREETING%") : Arrays.asList("/bin/bash", "-c", "echo $GREETING");
|
||||
}
|
||||
|
||||
private List<String> getEchoCommand() {
|
||||
return isWindows() ? Arrays.asList("cmd.exe", "/c", "echo hello") : Arrays.asList("/bin/sh", "-c", "echo hello");
|
||||
}
|
||||
|
||||
private boolean isWindows() {
|
||||
return System.getProperty("os.name")
|
||||
.toLowerCase()
|
||||
.startsWith("windows");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
|
@ -8,5 +8,5 @@
|
|||
- [Encrypting and Decrypting Files in Java](http://www.baeldung.com/java-cipher-input-output-stream)
|
||||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
||||
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
|
||||
- [SHA-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
||||
- [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
||||
- [Enabling TLS v1.2 in Java 7](https://www.baeldung.com/java-7-tls-v12)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid)
|
||||
- [A Guide to the ResourceBundle](http://www.baeldung.com/java-resourcebundle)
|
||||
- [Class Loaders in Java](http://www.baeldung.com/java-classloaders)
|
||||
- [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking)
|
||||
- [Guide to Java Clock Class](http://www.baeldung.com/java-clock)
|
||||
- [Importance of Main Manifest Attribute in a Self-Executing JAR](http://www.baeldung.com/java-jar-executable-manifest-main-class)
|
||||
- [Java Global Exception Handler](http://www.baeldung.com/java-global-exception-handler)
|
||||
|
@ -50,3 +49,4 @@
|
|||
- [Using Curl in Java](https://www.baeldung.com/java-curl)
|
||||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
||||
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
||||
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
|
||||
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class Positive
|
||||
|
||||
@Target(AnnotationTarget.FIELD)
|
||||
annotation class AllowedNames(val names: Array<String>)
|
|
@ -0,0 +1,3 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
class Item(@Positive val amount: Float, @AllowedNames(["Alice", "Bob"]) val name: String)
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val item = Item(amount = 1.0f, name = "Bob")
|
||||
val validator = Validator()
|
||||
println("Is instance valid? ${validator.isValid(item)}")
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
/**
|
||||
* Naive annotation-based validator.
|
||||
* @author A.Shcherbakov
|
||||
*/
|
||||
class Validator() {
|
||||
|
||||
/**
|
||||
* Return true if every item's property annotated with @Positive is positive and if
|
||||
* every item's property annotated with @AllowedNames has a value specified in that annotation.
|
||||
*/
|
||||
fun isValid(item: Item): Boolean {
|
||||
val fields = item::class.java.declaredFields
|
||||
for (field in fields) {
|
||||
field.isAccessible = true
|
||||
for (annotation in field.annotations) {
|
||||
val value = field.get(item)
|
||||
if (field.isAnnotationPresent(Positive::class.java)) {
|
||||
val amount = value as Float
|
||||
if (amount < 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (field.isAnnotationPresent(AllowedNames::class.java)) {
|
||||
val allowedNames = field.getAnnotation(AllowedNames::class.java)?.names
|
||||
val name = value as String
|
||||
allowedNames?.let {
|
||||
if (!it.contains(name)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class CustomColor(val rgb: Int): Comparable<CustomColor> {
|
||||
|
||||
override fun compareTo(other: CustomColor): Int {
|
||||
return this.rgb.compareTo(other.rgb)
|
||||
}
|
||||
|
||||
operator fun rangeTo(that: CustomColor) = ColorRange(this,that)
|
||||
|
||||
operator fun inc(): CustomColor {
|
||||
return CustomColor(rgb + 1)
|
||||
}
|
||||
|
||||
init {
|
||||
if(rgb < 0x000000 || rgb > 0xFFFFFF){
|
||||
throw IllegalStateException("RGB must be between 0 and 16777215")
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "CustomColor(rgb=$rgb)"
|
||||
}
|
||||
}
|
||||
class ColorRange(override val start: CustomColor,
|
||||
override val endInclusive: CustomColor) : ClosedRange<CustomColor>, Iterable<CustomColor>{
|
||||
|
||||
override fun iterator(): Iterator<CustomColor> {
|
||||
return ColorIterator(start, endInclusive)
|
||||
}
|
||||
}
|
||||
|
||||
class ColorIterator(val start: CustomColor, val endInclusive: CustomColor) : Iterator<CustomColor> {
|
||||
|
||||
var initValue = start
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return initValue <= endInclusive
|
||||
}
|
||||
|
||||
override fun next(): CustomColor {
|
||||
return initValue++
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val a = CustomColor(0xABCDEF)
|
||||
val b = CustomColor(-1)
|
||||
val c = CustomColor(0xABCDFF)
|
||||
|
||||
for(color in a..c){
|
||||
println(color)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.scope
|
||||
|
||||
data class Student(var studentId: String = "", var name: String = "", var surname: String = "") {
|
||||
}
|
||||
|
||||
data class Teacher(var teacherId: Int = 0, var name: String = "", var surname: String = "") {
|
||||
fun setId(anId: Int): Teacher = apply { teacherId = anId }
|
||||
fun setName(aName: String): Teacher = apply { name = aName }
|
||||
fun setSurname(aSurname: String): Teacher = apply { surname = aSurname }
|
||||
}
|
||||
|
||||
data class Headers(val headerInfo: String)
|
||||
|
||||
data class Response(val headers: Headers)
|
||||
|
||||
data class RestClient(val url: String) {
|
||||
fun getResponse() = Response(Headers("some header info"))
|
||||
}
|
||||
|
||||
data class BankAccount(val id: Int) {
|
||||
fun checkAuthorization(username: String) = Unit
|
||||
fun addPayee(payee: String) = Unit
|
||||
fun makePayment(paymentDetails: String) = Unit
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.annotations
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertFalse
|
||||
|
||||
class ValidationTest {
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsAlice_thenTrue() {
|
||||
assertTrue(Validator().isValid(Item(1f, "Alice")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsBob_thenTrue() {
|
||||
assertTrue(Validator().isValid(Item(1f, "Bob")))
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsAlice_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Alice")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsBob_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Bob")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsOneAndNameIsTom_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(1f, "Tom")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenAmountIsMinusOneAndNameIsTom_thenFalse() {
|
||||
assertFalse(Validator().isValid(Item(-1f, "Tom")))
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.range
|
||||
|
||||
import org.junit.Test
|
||||
import java.lang.IllegalStateException
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class CustomColorTest {
|
||||
|
||||
@Test
|
||||
fun testInvalidConstructor(){
|
||||
assertFailsWith(IllegalStateException::class){
|
||||
CustomColor(-1)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun assertHas10Colors(){
|
||||
assertTrue {
|
||||
val a = CustomColor(1)
|
||||
val b = CustomColor(10)
|
||||
val range = a..b
|
||||
for(cc in range){
|
||||
println(cc)
|
||||
}
|
||||
range.toList().size == 10
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun assertContains0xCCCCCC(){
|
||||
assertTrue {
|
||||
val a = CustomColor(0xBBBBBB)
|
||||
val b = CustomColor(0xDDDDDD)
|
||||
val range = a..b
|
||||
range.contains(CustomColor(0xCCCCCC))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
package com.baeldung.scope
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
|
||||
class ScopeFunctionsUnitTest {
|
||||
|
||||
class Logger {
|
||||
|
||||
var called : Boolean = false
|
||||
|
||||
fun info(message: String) {
|
||||
called = true
|
||||
}
|
||||
|
||||
fun wasCalled() = called
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldTransformWhenLetFunctionUsed() {
|
||||
val stringBuider = StringBuilder()
|
||||
val numberOfCharacters = stringBuider.let {
|
||||
it.append("This is a transformation function.")
|
||||
it.append("It takes a StringBuilder instance and returns the number of characters in the generated String")
|
||||
it.length
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
numberOfCharacters == 128
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldHandleNullabilityWhenLetFunctionUsed() {
|
||||
|
||||
val message: String? = "hello there!"
|
||||
val charactersInMessage = message?.let {
|
||||
"At this point is safe to reference the variable. Let's print the message: $it"
|
||||
} ?: "default value"
|
||||
|
||||
assertTrue {
|
||||
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
|
||||
}
|
||||
|
||||
val aNullMessage = null
|
||||
val thisIsNull = aNullMessage?.let {
|
||||
"At this point it would be safe to reference the variable. But it will not really happen because it is null. Let's reference: $it"
|
||||
} ?: "default value"
|
||||
|
||||
assertTrue {
|
||||
thisIsNull.equals("default value")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldInitializeObjectWhenUsingApply() {
|
||||
val aStudent = Student().apply {
|
||||
studentId = "1234567"
|
||||
name = "Mary"
|
||||
surname = "Smith"
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
aStudent.name.equals("Mary")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldAllowBuilderStyleObjectDesignWhenApplyUsedInClassMethods() {
|
||||
val teacher = Teacher()
|
||||
.setId(1000)
|
||||
.setName("Martha")
|
||||
.setSurname("Spector")
|
||||
|
||||
assertTrue {
|
||||
teacher.surname.equals("Spector")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldAllowSideEffectWhenUsingAlso() {
|
||||
val restClient = RestClient("http://www.someurl.com")
|
||||
|
||||
val logger = Logger()
|
||||
|
||||
val headers = restClient
|
||||
.getResponse()
|
||||
.also { logger.info(it.toString()) }
|
||||
.headers
|
||||
|
||||
assertTrue {
|
||||
logger.wasCalled() && headers.headerInfo.equals("some header info")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldInitializeFieldWhenAlsoUsed() {
|
||||
val aStudent = Student().also { it.name = "John"}
|
||||
|
||||
assertTrue {
|
||||
aStudent.name.equals("John")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldLogicallyGroupObjectCallsWhenUsingWith() {
|
||||
val bankAccount = BankAccount(1000)
|
||||
with (bankAccount) {
|
||||
checkAuthorization("someone")
|
||||
addPayee("some payee")
|
||||
makePayment("payment information")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldConvertObjectWhenRunUsed() {
|
||||
val stringBuider = StringBuilder()
|
||||
val numberOfCharacters = stringBuider.run {
|
||||
append("This is a transformation function.")
|
||||
append("It takes a StringBuilder instance and returns the number of characters in the generated String")
|
||||
length
|
||||
}
|
||||
|
||||
assertTrue {
|
||||
numberOfCharacters == 128
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldHandleNullabilityWhenRunIsUsed() {
|
||||
val message: String? = "hello there!"
|
||||
val charactersInMessage = message?.run {
|
||||
"At this point is safe to reference the variable. Let's print the message: $this"
|
||||
} ?: "default value"
|
||||
|
||||
assertTrue {
|
||||
charactersInMessage.equals("At this point is safe to reference the variable. Let's print the message: hello there!")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package com.baeldung.lambda
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class SplittingTest {
|
||||
private val evenList = listOf(0, "a", 1, "b", 2, "c");
|
||||
|
||||
private val unevenList = listOf(0, "a", 1, "b", 2, "c", 3);
|
||||
|
||||
private fun verifyList(resultList: List<List<Any>>) {
|
||||
assertEquals("[[0, a], [1, b], [2, c]]", resultList.toString())
|
||||
}
|
||||
|
||||
private fun verifyPartialList(resultList: List<List<Any>>) {
|
||||
assertEquals("[[0, a], [1, b], [2, c], [3]]", resultList.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenChunked_thenListIsSplit() {
|
||||
val resultList = evenList.chunked(2)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenChunked_thenListIsSplit() {
|
||||
val resultList = unevenList.chunked(2)
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWindowed_thenListIsSplit() {
|
||||
val resultList = evenList.windowed(2, 2)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenPartialWindowed_thenListIsSplit() {
|
||||
val resultList = unevenList.windowed(2, 2, partialWindows = true)
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenUnevenWindowed_thenListIsSplit() {
|
||||
val resultList = unevenList.windowed(2, 2, partialWindows = false)
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithAscendingNumbers_thenListIsSplit() {
|
||||
val numberList = listOf(1, 2, 3, 4, 5, 6);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||
assertEquals("[[1, 2], [3, 4], [5, 6]]", resultList.values.toString())
|
||||
assertEquals("[1, 2, 3]", resultList.keys.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithAscendingNumbersUneven_thenListIsSplit() {
|
||||
val numberList = listOf(1, 2, 3, 4, 5, 6, 7);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }.values
|
||||
assertEquals("[[1, 2], [3, 4], [5, 6], [7]]", resultList.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGroupByWithRandomNumbers_thenListIsSplitInWrongWay() {
|
||||
val numberList = listOf(1, 3, 8, 20, 23, 30);
|
||||
val resultList = numberList.groupBy { (it + 1) / 2 }
|
||||
assertEquals("[[1], [3], [8], [20], [23], [30]]", resultList.values.toString())
|
||||
assertEquals("[1, 2, 4, 10, 12, 15]", resultList.keys.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWithIndexGroupBy_thenListIsSplit() {
|
||||
val resultList = evenList.withIndex()
|
||||
.groupBy { it.index / 2 }
|
||||
.map { it.value.map { it.value } }
|
||||
verifyList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenWithIndexGroupByUneven_thenListIsSplit() {
|
||||
val resultList = unevenList.withIndex()
|
||||
.groupBy { it.index / 2 }
|
||||
.map { it.value.map { it.value } }
|
||||
verifyPartialList(resultList)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenFoldIndexed_thenListIsSplit() {
|
||||
val resultList = evenList.foldIndexed(ArrayList<ArrayList<Any>>(evenList.size / 2)) { index, acc, item ->
|
||||
if (index % 2 == 0) {
|
||||
acc.add(ArrayList(2))
|
||||
}
|
||||
acc.last().add(item)
|
||||
acc
|
||||
}
|
||||
verifyList(resultList)
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
- [A guide to the “when{}” block in Kotlin](http://www.baeldung.com/kotlin-when)
|
||||
- [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety)
|
||||
- [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability)
|
||||
- [Difference Between “==” and “===” in Kotlin](http://www.baeldung.com/kotlin-equality-operators)
|
||||
- [Difference Between “==” and “===” operators in Kotlin](http://www.baeldung.com/kotlin-equality-operators)
|
||||
- [Generics in Kotlin](http://www.baeldung.com/kotlin-generics)
|
||||
- [Introduction to Kotlin Coroutines](http://www.baeldung.com/kotlin-coroutines)
|
||||
- [Destructuring Declarations in Kotlin](http://www.baeldung.com/kotlin-destructuring-declarations)
|
||||
|
@ -52,3 +52,6 @@
|
|||
- [Inline Classes in Kotlin](https://www.baeldung.com/kotlin-inline-classes)
|
||||
- [Creating Java static final Equivalents in Kotlin](https://www.baeldung.com/kotlin-java-static-final)
|
||||
- [Nested forEach in Kotlin](https://www.baeldung.com/kotlin-nested-foreach)
|
||||
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
||||
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
||||
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
|
||||
|
|
|
@ -5,6 +5,15 @@ class Country(val name : String, val cities : List<City>)
|
|||
|
||||
class City(val name : String, val streets : List<String>)
|
||||
|
||||
fun City.getStreetsWithCityName() : List<String> {
|
||||
return streets.map { "$name, $it" }.toList()
|
||||
}
|
||||
|
||||
fun Country.getCitiesWithCountryName() : List<String> {
|
||||
return cities.flatMap { it.getStreetsWithCityName() }
|
||||
.map { "$name, $it" }
|
||||
}
|
||||
|
||||
class World {
|
||||
|
||||
private val streetsOfAmsterdam = listOf("Herengracht", "Prinsengracht")
|
||||
|
@ -45,6 +54,19 @@ class World {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun allStreetsFlatMap() {
|
||||
|
||||
countries.flatMap { it.cities}
|
||||
.flatMap { it.streets}
|
||||
.forEach { println(it) }
|
||||
}
|
||||
|
||||
fun allFlatMapTable() {
|
||||
|
||||
countries.flatMap { it.getCitiesWithCountryName() }
|
||||
.forEach { println(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
|
@ -56,6 +78,10 @@ fun main(args : Array<String>) {
|
|||
world.allNested()
|
||||
|
||||
world.allTable()
|
||||
|
||||
world.allStreetsFlatMap()
|
||||
|
||||
world.allFlatMapTable()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.baeldung.kotlin.delegates
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
interface Producer {
|
||||
|
||||
fun produce(): String
|
||||
}
|
||||
|
||||
class ProducerImpl : Producer {
|
||||
|
||||
override fun produce() = "ProducerImpl"
|
||||
}
|
||||
|
||||
class EnhancedProducer(private val delegate: Producer) : Producer by delegate {
|
||||
|
||||
override fun produce() = "${delegate.produce()} and EnhancedProducer"
|
||||
}
|
||||
|
||||
interface MessageService {
|
||||
|
||||
fun processMessage(message: String): String
|
||||
}
|
||||
|
||||
class MessageServiceImpl : MessageService {
|
||||
override fun processMessage(message: String): String {
|
||||
return "MessageServiceImpl: $message"
|
||||
}
|
||||
}
|
||||
|
||||
interface UserService {
|
||||
|
||||
fun processUser(userId: String): String
|
||||
}
|
||||
|
||||
class UserServiceImpl : UserService {
|
||||
|
||||
override fun processUser(userId: String): String {
|
||||
return "UserServiceImpl: $userId"
|
||||
}
|
||||
}
|
||||
|
||||
class CompositeService : UserService by UserServiceImpl(), MessageService by MessageServiceImpl()
|
||||
|
||||
interface Service {
|
||||
|
||||
val seed: Int
|
||||
|
||||
fun serve(action: (Int) -> Unit)
|
||||
}
|
||||
|
||||
class ServiceImpl : Service {
|
||||
|
||||
override val seed = 1
|
||||
|
||||
override fun serve(action: (Int) -> Unit) {
|
||||
action(seed)
|
||||
}
|
||||
}
|
||||
|
||||
class ServiceDecorator : Service by ServiceImpl() {
|
||||
override val seed = 2
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.kotlin.delegates
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class InterfaceDelegationTest {
|
||||
|
||||
@Test
|
||||
fun `when delegated implementation is used then it works as expected`() {
|
||||
val producer = EnhancedProducer(ProducerImpl())
|
||||
assertThat(producer.produce()).isEqualTo("ProducerImpl and EnhancedProducer")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when composite delegation is used then it works as expected`() {
|
||||
val service = CompositeService()
|
||||
assertThat(service.processMessage("message")).isEqualTo("MessageServiceImpl: message")
|
||||
assertThat(service.processUser("user")).isEqualTo("UserServiceImpl: user")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when decoration is used then delegate knows nothing about it`() {
|
||||
val service = ServiceDecorator()
|
||||
service.serve {
|
||||
assertThat(it).isEqualTo(1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Introduction to GWT](http://www.baeldung.com/gwt)
|
||||
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
|
||||
|
|
|
@ -3,5 +3,4 @@
|
|||
- [Writing Custom Gradle Plugins](http://www.baeldung.com/gradle-create-plugin)
|
||||
- [Creating a Fat Jar in Gradle](http://www.baeldung.com/gradle-fat-jar)
|
||||
- [A Custom Task in Gradle](http://www.baeldung.com/gradle-custom-task)
|
||||
- [Kotlin Dependency Injection with Kodein](http://www.baeldung.com/kotlin-kodein-dependency-injection)
|
||||
- [Using JUnit 5 with Gradle](https://www.baeldung.com/junit-5-gradle)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue