Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-14776
This commit is contained in:
commit
142e6f18ef
11
README.md
11
README.md
@ -20,17 +20,22 @@ In additional to Spring, the following technologies are in focus: `core Java`, `
|
||||
|
||||
Building the project
|
||||
====================
|
||||
To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false`
|
||||
To do the full build, do: `mvn clean install`
|
||||
|
||||
|
||||
Building a single module
|
||||
====================
|
||||
To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory
|
||||
To build a specific module run the command: `mvn clean install` in the module directory
|
||||
|
||||
|
||||
Running a Spring Boot module
|
||||
====================
|
||||
To run a Spring Boot module run the command: `mvn spring-boot:run -Dgib.enabled=false` in the module directory
|
||||
To run a Spring Boot module run the command: `mvn spring-boot:run` in the module directory
|
||||
|
||||
#Running Tests
|
||||
|
||||
The command `mvn clean install` will run the unit tests in a module.
|
||||
To run the integration tests, use the command `mvn clean install -Pintegration-lite-first`
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Graph {
|
||||
|
||||
private List<Vertex> vertices;
|
||||
|
||||
public Graph() {
|
||||
this.vertices = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Graph(List<Vertex> vertices) {
|
||||
this.vertices = vertices;
|
||||
}
|
||||
|
||||
public void addVertex(Vertex vertex) {
|
||||
this.vertices.add(vertex);
|
||||
}
|
||||
|
||||
public void addEdge(Vertex from, Vertex to) {
|
||||
from.addNeighbour(to);
|
||||
}
|
||||
|
||||
public boolean hasCycle() {
|
||||
for (Vertex vertex : vertices) {
|
||||
if (!vertex.isVisited() && hasCycle(vertex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasCycle(Vertex sourceVertex) {
|
||||
sourceVertex.setBeingVisited(true);
|
||||
|
||||
for (Vertex neighbour : sourceVertex.getAdjacencyList()) {
|
||||
if (neighbour.isBeingVisited()) {
|
||||
// backward edge exists
|
||||
return true;
|
||||
} else if (!neighbour.isVisited() && hasCycle(neighbour)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sourceVertex.setBeingVisited(false);
|
||||
sourceVertex.setVisited(true);
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Vertex {
|
||||
|
||||
private String label;
|
||||
|
||||
private boolean visited;
|
||||
|
||||
private boolean beingVisited;
|
||||
|
||||
private List<Vertex> adjacencyList;
|
||||
|
||||
public Vertex(String label) {
|
||||
this.label = label;
|
||||
this.adjacencyList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public boolean isVisited() {
|
||||
return visited;
|
||||
}
|
||||
|
||||
public void setVisited(boolean visited) {
|
||||
this.visited = visited;
|
||||
}
|
||||
|
||||
public boolean isBeingVisited() {
|
||||
return beingVisited;
|
||||
}
|
||||
|
||||
public void setBeingVisited(boolean beingVisited) {
|
||||
this.beingVisited = beingVisited;
|
||||
}
|
||||
|
||||
public List<Vertex> getAdjacencyList() {
|
||||
return adjacencyList;
|
||||
}
|
||||
|
||||
public void setAdjacencyList(List<Vertex> adjacencyList) {
|
||||
this.adjacencyList = adjacencyList;
|
||||
}
|
||||
|
||||
public void addNeighbour(Vertex adjacent) {
|
||||
this.adjacencyList.add(adjacent);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.baeldung.algorithms.graphcycledetection;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.algorithms.graphcycledetection.domain.Graph;
|
||||
import com.baeldung.algorithms.graphcycledetection.domain.Vertex;
|
||||
|
||||
public class GraphCycleDetectionUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenCycleExists_thenReturnTrue() {
|
||||
|
||||
Vertex vertexA = new Vertex("A");
|
||||
Vertex vertexB = new Vertex("B");
|
||||
Vertex vertexC = new Vertex("C");
|
||||
Vertex vertexD = new Vertex("D");
|
||||
|
||||
Graph graph = new Graph();
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addVertex(vertexD);
|
||||
|
||||
graph.addEdge(vertexA, vertexB);
|
||||
graph.addEdge(vertexB, vertexC);
|
||||
graph.addEdge(vertexC, vertexA);
|
||||
graph.addEdge(vertexD, vertexC);
|
||||
|
||||
assertTrue(graph.hasCycle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenNoCycleExists_thenReturnFalse() {
|
||||
|
||||
Vertex vertexA = new Vertex("A");
|
||||
Vertex vertexB = new Vertex("B");
|
||||
Vertex vertexC = new Vertex("C");
|
||||
Vertex vertexD = new Vertex("D");
|
||||
|
||||
Graph graph = new Graph();
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addVertex(vertexD);
|
||||
|
||||
graph.addEdge(vertexA, vertexB);
|
||||
graph.addEdge(vertexB, vertexC);
|
||||
graph.addEdge(vertexA, vertexC);
|
||||
graph.addEdge(vertexD, vertexC);
|
||||
|
||||
assertFalse(graph.hasCycle());
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class GeodeSamplesIntegrationTest {
|
||||
public class GeodeSamplesLiveTest {
|
||||
|
||||
ClientCache cache = null;
|
||||
Region<String, String> region = null;
|
3
apache-olingo/README.md
Normal file
3
apache-olingo/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [OData Protocol Guide](https://www.baeldung.com/odata)
|
@ -3,5 +3,6 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [String Matching in Groovy](http://www.baeldung.com/)
|
||||
- [Template Engines in Groovy](https://www.baeldung.com/groovy-template-engines)
|
||||
- [Groovy def Keyword](https://www.baeldung.com/groovy-def-keyword)
|
||||
- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching)
|
||||
- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching)
|
178
core-groovy-2/gmavenplus-pom.xml
Normal file
178
core-groovy-2/gmavenplus-pom.xml
Normal file
@ -0,0 +1,178 @@
|
||||
<?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>
|
||||
<artifactId>core-groovy-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>core-groovy-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>${hsqldb.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>${spock-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<scriptSourceDirectory>src/main/groovy</scriptSourceDirectory>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>generateStubs</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>generateTestStubs</goal>
|
||||
<goal>compileTests</goal>
|
||||
<goal>removeStubs</goal>
|
||||
<goal>removeTestStubs</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<!-- any version of Groovy \>= 1.5.0 should work here -->
|
||||
<version>${groovy.version}</version>
|
||||
<scope>runtime</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>junit5</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test5.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20.1</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven Assembly Plugin: needed to run the jar through command line -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<!-- get all project dependencies -->
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<!-- MainClass in mainfest make a executable jar -->
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.baeldung.MyJointCompilationApp</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- bind to the packaging phase -->
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<hsqldb.version>2.4.0</hsqldb.version>
|
||||
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<java.version>1.8</java.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<groovy.version>2.5.7</groovy.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?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">
|
||||
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>core-groovy-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
@ -15,25 +15,20 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy-all.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-dateutil</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-sql</artifactId>
|
||||
<version>${groovy-sql.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
@ -56,21 +51,35 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<scriptSourceDirectory>src/main/groovy</scriptSourceDirectory>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>${gmavenplus-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>compileTests</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>3.3.0-01</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<compilerId>groovy-eclipse-compiler</compilerId>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>3.3.0-01</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-batch</artifactId>
|
||||
<version>${groovy.version}-01</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
@ -101,13 +110,42 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20.1</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven Assembly Plugin: needed to run the jar through command line -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<!-- get all project dependencies -->
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<!-- MainClass in mainfest make a executable jar -->
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.baeldung.MyJointCompilationApp</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- bind to the packaging phase -->
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -118,14 +156,32 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>bintray</id>
|
||||
<name>Groovy Bintray</name>
|
||||
<url>https://dl.bintray.com/groovy/maven</url>
|
||||
<releases>
|
||||
<!-- avoid automatic updates -->
|
||||
<updatePolicy>never</updatePolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
<properties>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<groovy.version>2.5.6</groovy.version>
|
||||
<groovy-all.version>2.5.6</groovy-all.version>
|
||||
<groovy-sql.version>2.5.6</groovy-sql.version>
|
||||
<hsqldb.version>2.4.0</hsqldb.version>
|
||||
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<groovy.version>2.5.7</groovy.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
|
25
core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy
Normal file
25
core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy
Normal file
@ -0,0 +1,25 @@
|
||||
package com.baeldung
|
||||
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class CalcMath {
|
||||
def log = LoggerFactory.getLogger(this.getClass())
|
||||
|
||||
def calcSum(x, y) {
|
||||
log.info "Executing $x + $y"
|
||||
x + y
|
||||
}
|
||||
|
||||
/**
|
||||
* example of method that in java would throw error at compile time
|
||||
* @param x
|
||||
* @param y
|
||||
* @return
|
||||
*/
|
||||
def calcSum2(x, y) {
|
||||
log.info "Executing $x + $y"
|
||||
// DANGER! This won't throw a compilation issue and fail only at runtime!!!
|
||||
calcSum3()
|
||||
log.info("Logging an undefined variable: $z")
|
||||
}
|
||||
}
|
16
core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy
Normal file
16
core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy
Normal file
@ -0,0 +1,16 @@
|
||||
package com.baeldung
|
||||
|
||||
def calcSum(x, y) {
|
||||
x + y
|
||||
}
|
||||
|
||||
def calcSum2(x, y) {
|
||||
// DANGER! The variable "log" may be undefined
|
||||
log.info "Executing $x + $y"
|
||||
// DANGER! This method doesn't exist!
|
||||
calcSum3()
|
||||
// DANGER! The logged variable "z" is undefined!
|
||||
log.info("Logging an undefined variable: $z")
|
||||
}
|
||||
|
||||
calcSum(1,5)
|
@ -0,0 +1,120 @@
|
||||
package com.baeldung;
|
||||
|
||||
import groovy.lang.*;
|
||||
import groovy.util.GroovyScriptEngine;
|
||||
import groovy.util.ResourceException;
|
||||
import groovy.util.ScriptException;
|
||||
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import javax.script.ScriptEngine;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
public class MyJointCompilationApp {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(MyJointCompilationApp.class);
|
||||
private final GroovyClassLoader loader;
|
||||
private final GroovyShell shell;
|
||||
private final GroovyScriptEngine engine;
|
||||
private final ScriptEngine engineFromFactory;
|
||||
|
||||
public MyJointCompilationApp() {
|
||||
loader = new GroovyClassLoader(this.getClass().getClassLoader());
|
||||
shell = new GroovyShell(loader, new Binding());
|
||||
|
||||
URL url = null;
|
||||
try {
|
||||
url = new File("src/main/groovy/com/baeldung/").toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
LOG.error("Exception while creating url", e);
|
||||
}
|
||||
engine = new GroovyScriptEngine(new URL[] {url}, this.getClass().getClassLoader());
|
||||
engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine();
|
||||
}
|
||||
|
||||
private void addWithCompiledClasses(int x, int y) {
|
||||
LOG.info("Executing {} + {}", x, y);
|
||||
Object result1 = new CalcScript().calcSum(x, y);
|
||||
LOG.info("Result of CalcScript.calcSum() method is {}", result1);
|
||||
|
||||
Object result2 = new CalcMath().calcSum(x, y);
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result2);
|
||||
}
|
||||
|
||||
private void addWithGroovyShell(int x, int y) throws IOException {
|
||||
Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy"));
|
||||
LOG.info("Executing {} + {}", x, y);
|
||||
Object result = script.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcScript.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyShellRun() throws IOException {
|
||||
Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy"));
|
||||
LOG.info("Executing script run method");
|
||||
Object result = script.run();
|
||||
LOG.info("Result of CalcScript.run() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyClassLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException {
|
||||
Class calcClass = loader.parseClass(
|
||||
new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"));
|
||||
GroovyObject calc = (GroovyObject) calcClass.newInstance();
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x + 14, y + 14 });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyScriptEngine(int x, int y) throws IllegalAccessException,
|
||||
InstantiationException, ResourceException, ScriptException {
|
||||
Class<GroovyObject> calcClass = engine.loadScriptByName("CalcMath.groovy");
|
||||
GroovyObject calc = calcClass.newInstance();
|
||||
//WARNING the following will throw a ClassCastException
|
||||
//((CalcMath)calc).calcSum(1,2);
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithEngineFactory(int x, int y) throws IllegalAccessException,
|
||||
InstantiationException, javax.script.ScriptException, FileNotFoundException {
|
||||
Class calcClass = (Class) engineFromFactory.eval(
|
||||
new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")));
|
||||
GroovyObject calc = (GroovyObject) calcClass.newInstance();
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithStaticCompiledClasses() {
|
||||
LOG.info("Running the Groovy classes compiled statically...");
|
||||
addWithCompiledClasses(5, 10);
|
||||
|
||||
}
|
||||
|
||||
private void addWithDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException,
|
||||
ResourceException, ScriptException, javax.script.ScriptException {
|
||||
LOG.info("Invocation of a dynamic groovy script...");
|
||||
addWithGroovyShell(5, 10);
|
||||
LOG.info("Invocation of the run method of a dynamic groovy script...");
|
||||
addWithGroovyShellRun();
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyClassLoader...");
|
||||
addWithGroovyClassLoader(10, 30);
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine...");
|
||||
addWithGroovyScriptEngine(15, 0);
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine JSR223...");
|
||||
addWithEngineFactory(5, 6);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InstantiationException, IllegalAccessException,
|
||||
ResourceException, ScriptException, IOException, javax.script.ScriptException {
|
||||
MyJointCompilationApp myJointCompilationApp = new MyJointCompilationApp();
|
||||
LOG.info("Example of addition operation via Groovy scripts integration with Java.");
|
||||
myJointCompilationApp.addWithStaticCompiledClasses();
|
||||
myJointCompilationApp.addWithDynamicCompiledClasses();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.baeldung.xml
|
||||
|
||||
import groovy.xml.MarkupBuilder
|
||||
import groovy.xml.XmlUtil
|
||||
import spock.lang.Specification
|
||||
|
||||
class MarkupBuilderUnitTest extends Specification {
|
||||
|
||||
def xmlFile = getClass().getResource("articles_short_formatted.xml")
|
||||
|
||||
def "Should create XML properly"() {
|
||||
given: "Node structures"
|
||||
|
||||
when: "Using MarkupBuilderUnitTest to create com.baeldung.xml structure"
|
||||
def writer = new StringWriter()
|
||||
new MarkupBuilder(writer).articles {
|
||||
article {
|
||||
title('First steps in Java')
|
||||
author(id: '1') {
|
||||
firstname('Siena')
|
||||
lastname('Kerr')
|
||||
}
|
||||
'release-date'('2018-12-01')
|
||||
}
|
||||
article {
|
||||
title('Dockerize your SpringBoot application')
|
||||
author(id: '2') {
|
||||
firstname('Jonas')
|
||||
lastname('Lugo')
|
||||
}
|
||||
'release-date'('2018-12-01')
|
||||
}
|
||||
}
|
||||
|
||||
then: "Xml is created properly"
|
||||
XmlUtil.serialize(writer.toString()) == XmlUtil.serialize(xmlFile.text)
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.baeldung.xml
|
||||
|
||||
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
class XmlParserUnitTest extends Specification {
|
||||
|
||||
def xmlFile = getClass().getResourceAsStream("articles.xml")
|
||||
|
||||
@Shared
|
||||
def parser = new XmlParser()
|
||||
|
||||
def "Should read XML file properly"() {
|
||||
given: "XML file"
|
||||
|
||||
when: "Using XmlParser to read file"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
then: "Xml is loaded properly"
|
||||
articles.'*'.size() == 4
|
||||
articles.article[0].author.firstname.text() == "Siena"
|
||||
articles.article[2].'release-date'.text() == "2018-06-12"
|
||||
articles.article[3].title.text() == "Java 12 insights"
|
||||
articles.article.find { it.author.'@id'.text() == "3" }.author.firstname.text() == "Daniele"
|
||||
}
|
||||
|
||||
|
||||
def "Should add node to existing com.baeldung.xml using NodeBuilder"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Adding node to com.baeldung.xml"
|
||||
def articleNode = new NodeBuilder().article(id: '5') {
|
||||
title('Traversing XML in the nutshell')
|
||||
author {
|
||||
firstname('Martin')
|
||||
lastname('Schmidt')
|
||||
}
|
||||
'release-date'('2019-05-18')
|
||||
}
|
||||
articles.append(articleNode)
|
||||
|
||||
then: "Node is added to com.baeldung.xml properly"
|
||||
articles.'*'.size() == 5
|
||||
articles.article[4].title.text() == "Traversing XML in the nutshell"
|
||||
}
|
||||
|
||||
def "Should replace node"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Adding node to com.baeldung.xml"
|
||||
def articleNode = new NodeBuilder().article(id: '5') {
|
||||
title('Traversing XML in the nutshell')
|
||||
author {
|
||||
firstname('Martin')
|
||||
lastname('Schmidt')
|
||||
}
|
||||
'release-date'('2019-05-18')
|
||||
}
|
||||
articles.article[0].replaceNode(articleNode)
|
||||
|
||||
then: "Node is added to com.baeldung.xml properly"
|
||||
articles.'*'.size() == 4
|
||||
articles.article[0].title.text() == "Traversing XML in the nutshell"
|
||||
}
|
||||
|
||||
def "Should modify node"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Changing value of one of the nodes"
|
||||
articles.article.each { it.'release-date'[0].value = "2019-05-18" }
|
||||
|
||||
then: "XML is updated"
|
||||
articles.article.findAll { it.'release-date'.text() != "2019-05-18" }.isEmpty()
|
||||
}
|
||||
|
||||
def "Should remove article from com.baeldung.xml"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Removing all articles but with id==3"
|
||||
articles.article
|
||||
.findAll { it.author.'@id'.text() != "3" }
|
||||
.each { articles.remove(it) }
|
||||
|
||||
then: "There is only one article left"
|
||||
articles.children().size() == 1
|
||||
articles.article[0].author.'@id'.text() == "3"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.baeldung.xml
|
||||
|
||||
|
||||
import groovy.xml.XmlUtil
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
|
||||
class XmlSlurperUnitTest extends Specification {
|
||||
|
||||
def xmlFile = getClass().getResourceAsStream("articles.xml")
|
||||
|
||||
@Shared
|
||||
def parser = new XmlSlurper()
|
||||
|
||||
def "Should read XML file properly"() {
|
||||
given: "XML file"
|
||||
|
||||
when: "Using XmlSlurper to read file"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
then: "Xml is loaded properly"
|
||||
articles.'*'.size() == 4
|
||||
articles.article[0].author.firstname == "Siena"
|
||||
articles.article[2].'release-date' == "2018-06-12"
|
||||
articles.article[3].title == "Java 12 insights"
|
||||
articles.article.find { it.author.'@id' == "3" }.author.firstname == "Daniele"
|
||||
}
|
||||
|
||||
def "Should add node to existing com.baeldung.xml"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Adding node to com.baeldung.xml"
|
||||
articles.appendNode {
|
||||
article(id: '5') {
|
||||
title('Traversing XML in the nutshell')
|
||||
author {
|
||||
firstname('Martin')
|
||||
lastname('Schmidt')
|
||||
}
|
||||
'release-date'('2019-05-18')
|
||||
}
|
||||
}
|
||||
|
||||
articles = parser.parseText(XmlUtil.serialize(articles))
|
||||
|
||||
then: "Node is added to com.baeldung.xml properly"
|
||||
articles.'*'.size() == 5
|
||||
articles.article[4].title == "Traversing XML in the nutshell"
|
||||
}
|
||||
|
||||
def "Should modify node"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Changing value of one of the nodes"
|
||||
articles.article.each { it.'release-date' = "2019-05-18" }
|
||||
|
||||
then: "XML is updated"
|
||||
articles.article.findAll { it.'release-date' != "2019-05-18" }.isEmpty()
|
||||
}
|
||||
|
||||
def "Should replace node"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Replacing node"
|
||||
articles.article[0].replaceNode {
|
||||
article(id: '5') {
|
||||
title('Traversing XML in the nutshell')
|
||||
author {
|
||||
firstname('Martin')
|
||||
lastname('Schmidt')
|
||||
}
|
||||
'release-date'('2019-05-18')
|
||||
}
|
||||
}
|
||||
|
||||
articles = parser.parseText(XmlUtil.serialize(articles))
|
||||
|
||||
then: "Node is replaced properly"
|
||||
articles.'*'.size() == 4
|
||||
articles.article[0].title == "Traversing XML in the nutshell"
|
||||
}
|
||||
|
||||
def "Should remove article from com.baeldung.xml"() {
|
||||
given: "XML object"
|
||||
def articles = parser.parse(xmlFile)
|
||||
|
||||
when: "Removing all articles but with id==3"
|
||||
articles.article
|
||||
.findAll { it.author.'@id' != "3" }
|
||||
.replaceNode {}
|
||||
|
||||
articles = parser.parseText(XmlUtil.serialize(articles))
|
||||
|
||||
then: "There is only one article left"
|
||||
articles.children().size() == 1
|
||||
articles.article[0].author.'@id' == "3"
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<articles>
|
||||
<article>
|
||||
<title>First steps in Java</title>
|
||||
<author id='1'>
|
||||
<firstname>Siena</firstname>
|
||||
<lastname>Kerr</lastname>
|
||||
</author>
|
||||
<release-date>2018-12-01</release-date>
|
||||
</article>
|
||||
<article>
|
||||
<title>Dockerize your SpringBoot application</title>
|
||||
<author id='2'>
|
||||
<firstname>Jonas</firstname>
|
||||
<lastname>Lugo</lastname>
|
||||
</author>
|
||||
<release-date>2018-12-01</release-date>
|
||||
</article>
|
||||
<article>
|
||||
<title>SpringBoot tutorial</title>
|
||||
<author id='3'>
|
||||
<firstname>Daniele</firstname>
|
||||
<lastname>Ferguson</lastname>
|
||||
</author>
|
||||
<release-date>2018-06-12</release-date>
|
||||
</article>
|
||||
<article>
|
||||
<title>Java 12 insights</title>
|
||||
<author id='1'>
|
||||
<firstname>Siena</firstname>
|
||||
<lastname>Kerr</lastname>
|
||||
</author>
|
||||
<release-date>2018-07-22</release-date>
|
||||
</article>
|
||||
</articles>
|
@ -0,0 +1,18 @@
|
||||
<articles>
|
||||
<article>
|
||||
<title>First steps in Java</title>
|
||||
<author id='1'>
|
||||
<firstname>Siena</firstname>
|
||||
<lastname>Kerr</lastname>
|
||||
</author>
|
||||
<release-date>2018-12-01</release-date>
|
||||
</article>
|
||||
<article>
|
||||
<title>Dockerize your SpringBoot application</title>
|
||||
<author id='2'>
|
||||
<firstname>Jonas</firstname>
|
||||
<lastname>Lugo</lastname>
|
||||
</author>
|
||||
<release-date>2018-12-01</release-date>
|
||||
</article>
|
||||
</articles>
|
@ -1,15 +0,0 @@
|
||||
package com.baeldung.error;
|
||||
|
||||
public class ErrorGenerator {
|
||||
public void throwException() throws Exception {
|
||||
throw new Exception("checked");
|
||||
}
|
||||
|
||||
public void throwRuntimeException() {
|
||||
throw new RuntimeException("unchecked");
|
||||
}
|
||||
|
||||
public void throwError() {
|
||||
throw new Error("unchecked");
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package com.baeldung.error;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ErrorGeneratorUnitTest {
|
||||
|
||||
private ErrorGenerator errorGenerator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
errorGenerator = new ErrorGenerator();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckedException_thenIsCaughtByCatchException() {
|
||||
try {
|
||||
errorGenerator.throwException();
|
||||
} catch (Exception e) {
|
||||
// caught! -> test pass
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUncheckedException_thenIsCaughtByCatchException() {
|
||||
try {
|
||||
errorGenerator.throwRuntimeException();
|
||||
} catch (Exception e) {
|
||||
// caught! -> test pass
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = Error.class)
|
||||
public void whenError_thenIsNotCaughtByCatchException() {
|
||||
try {
|
||||
errorGenerator.throwError();
|
||||
} catch (Exception e) {
|
||||
Assert.fail(); // errors are not caught by catch exception
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenError_thenIsCaughtByCatchError() {
|
||||
try {
|
||||
errorGenerator.throwError();
|
||||
} catch (Error e) {
|
||||
// caught! -> test pass
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms)
|
||||
- [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel)
|
||||
- [Understanding the NumberFormatException in Java](https://www.baeldung.com/java-number-format-exception)
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.baeldung.set;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CopySets {
|
||||
|
||||
// Using Java 10
|
||||
public static <T> Set<T> copyBySetCopyOf(Set<T> original) {
|
||||
Set<T> copy = Set.copyOf(original);
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
@ -7,4 +7,5 @@
|
||||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||
- [Guide to jlink](https://www.baeldung.com/jlink)
|
||||
- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference)
|
||||
- [Transforming an Empty String into an Empty Optional](https://www.baeldung.com/java-empty-string-to-empty-optional)
|
||||
|
@ -3,5 +3,6 @@
|
||||
## Core Java 8 Cookbooks and Examples (part 2)
|
||||
|
||||
### Relevant Articles:
|
||||
- [Anonymous Classes in Java](https://www.baeldung.com/java-anonymous-classes)
|
||||
- [Anonymous Classes in Java](http://www.baeldung.com/)
|
||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
||||
- [Run JAR Application With Command Line Arguments](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||
|
@ -30,7 +30,6 @@
|
||||
<artifactId>icu4j</artifactId>
|
||||
<version>${icu.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<persistence-unit
|
||||
name="com.baeldung.optionalReturnType"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
<description>Persist Optional Return Type Demo</description>
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.baeldung.optionalReturnType.User</class>
|
||||
<class>com.baeldung.optionalReturnType.UserOptional</class>
|
||||
<!--
|
||||
<class>com.baeldung.optionalReturnType.UserOptionalField</class>
|
||||
-->
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver"
|
||||
value="org.h2.Driver" />
|
||||
<property name="javax.persistence.jdbc.url"
|
||||
value="jdbc:h2:mem:test" />
|
||||
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||
<property name="javax.persistence.jdbc.password" value="" />
|
||||
<property name="hibernate.dialect"
|
||||
value="org.hibernate.dialect.H2Dialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||
<property name="show_sql" value="true" />
|
||||
<property name="hibernate.temp.use_jdbc_metadata_defaults"
|
||||
value="false" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
@ -28,6 +28,6 @@
|
||||
- [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods)
|
||||
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
||||
- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity)
|
||||
- [Java 9 Platform Module API](https://www.baeldung.com/java-9-module-api)
|
||||
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api)
|
||||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||
- [Filtering a Stream of Optionals in Java](https://www.baeldung.com/java-filter-stream-of-optional)
|
||||
|
@ -75,7 +75,7 @@ public class Slf4jLogger implements System.Logger {
|
||||
if (!isLoggable(level)) {
|
||||
return;
|
||||
}
|
||||
String message = MessageFormat.format (format, params);
|
||||
String message = MessageFormat.format(format, params);
|
||||
|
||||
switch (level) {
|
||||
case TRACE:
|
||||
|
@ -15,3 +15,4 @@
|
||||
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
||||
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
|
||||
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)
|
||||
- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array)
|
||||
|
@ -24,10 +24,20 @@
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-collections4.version>4.3</commons-collections4.version>
|
||||
<guava.version>27.1-jre</guava.version>
|
||||
</properties>
|
||||
</project>
|
||||
</project>
|
@ -0,0 +1,59 @@
|
||||
package com.baeldung.set;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class CopySets {
|
||||
|
||||
// Copy Constructor
|
||||
public static <T> Set<T> copyByConstructor(Set<T> original) {
|
||||
Set<T> copy = new HashSet<>(original);
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Set.addAll
|
||||
public static <T> Set<T> copyBySetAddAll(Set<T> original) {
|
||||
Set<T> copy = new HashSet<>();
|
||||
copy.addAll(original);
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Set.clone
|
||||
public static <T> Set<T> copyBySetClone(HashSet<T> original) {
|
||||
Set<T> copy = (Set<T>) original.clone();
|
||||
return copy;
|
||||
}
|
||||
|
||||
// JSON
|
||||
public static <T> Set<T> copyByJson(Set<T> original) {
|
||||
Gson gson = new Gson();
|
||||
String jsonStr = gson.toJson(original);
|
||||
Set<T> copy = gson.fromJson(jsonStr, Set.class);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Apache Commons Lang
|
||||
public static <T extends Serializable> Set<T> copyByApacheCommonsLang(Set<T> original) {
|
||||
Set<T> copy = new HashSet<>();
|
||||
for (T item : original) {
|
||||
copy.add((T) SerializationUtils.clone(item));
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Collectors.toSet
|
||||
public static <T extends Serializable> Set<T> copyByCollectorsToSet(Set<T> original) {
|
||||
Set<T> copy = original.stream()
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.baeldung.delay;
|
||||
package com.baeldung.concurrent.delay;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@ -61,6 +61,7 @@ public class Delay {
|
||||
|
||||
executorService.schedule(Delay::someTask1, delayInSeconds, TimeUnit.SECONDS);
|
||||
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
private static void fixedRateServiceTask(Integer delayInSeconds) {
|
||||
@ -78,6 +79,7 @@ public class Delay {
|
||||
|
||||
sf.cancel(true);
|
||||
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
private static void someTask1() {
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.error;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ErrorGeneratorUnitTest {
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void whenError_thenIsNotCaughtByCatchException() {
|
||||
try {
|
||||
throw new AssertionError();
|
||||
} catch (Exception e) {
|
||||
Assert.fail(); // errors are not caught by catch exception
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenError_thenIsCaughtByCatchError() {
|
||||
try {
|
||||
throw new AssertionError();
|
||||
} catch (Error e) {
|
||||
// caught! -> test pass
|
||||
}
|
||||
}
|
||||
}
|
3
core-java-modules/core-java-lambdas/README.md
Normal file
3
core-java-modules/core-java-lambdas/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables)
|
3
core-java-modules/core-java-nio/README.md
Normal file
3
core-java-modules/core-java-nio/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [Determine File Creating Date in Java](https://www.baeldung.com/file-creation-date-java)
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.creationdate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CreationDateResolver {
|
||||
|
||||
public Instant resolveCreationTimeWithBasicAttributes(Path path) {
|
||||
try {
|
||||
final BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
|
||||
final FileTime fileTime = attr.creationTime();
|
||||
|
||||
return fileTime.toInstant();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("An issue occured went wrong when resolving creation time", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Instant> resolveCreationTimeWithAttribute(Path path) {
|
||||
try {
|
||||
final FileTime creationTime = (FileTime) Files.getAttribute(path, "creationTime");
|
||||
|
||||
return Optional
|
||||
.ofNullable(creationTime)
|
||||
.map((FileTime::toInstant));
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("An issue occured went wrong when resolving creation time", ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.baeldung.creationdate;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class CreationDateResolverUnitTest {
|
||||
|
||||
private final CreationDateResolver creationDateResolver = new CreationDateResolver();
|
||||
|
||||
@Test
|
||||
public void givenFile_whenGettingCreationDateTimeFromBasicAttributes_thenReturnDate() throws Exception {
|
||||
|
||||
final File file = File.createTempFile("createdFile", ".txt");
|
||||
final Path path = file.toPath();
|
||||
|
||||
final Instant response = creationDateResolver.resolveCreationTimeWithBasicAttributes(path);
|
||||
|
||||
assertTrue(Instant
|
||||
.now()
|
||||
.isAfter(response));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFile_whenGettingCreationDateTimeFromAttribute_thenReturnDate() throws Exception {
|
||||
|
||||
final File file = File.createTempFile("createdFile", ".txt");
|
||||
final Path path = file.toPath();
|
||||
|
||||
final Optional<Instant> response = creationDateResolver.resolveCreationTimeWithAttribute(path);
|
||||
|
||||
response.ifPresent((value) -> {
|
||||
assertTrue(Instant
|
||||
.now()
|
||||
.isAfter(value));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
5
core-java-modules/core-java-optional/README.md
Normal file
5
core-java-modules/core-java-optional/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
=========
|
||||
|
||||
## Core Java Optional
|
||||
|
||||
### Relevant Articles:
|
53
core-java-modules/core-java-optional/pom.xml
Normal file
53
core-java-modules/core-java-optional/pom.xml
Normal file
@ -0,0 +1,53 @@
|
||||
<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>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>core-java-optional</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<hibernate.core.version>5.4.0.Final</hibernate.core.version>
|
||||
<h2database.version>1.4.197</h2database.version>
|
||||
<jackson.databind.version>2.9.8</jackson.databind.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${hibernate.core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2database.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.databind.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<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>
|
||||
</project>
|
@ -0,0 +1,41 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class HandleOptionalTypeExample {
|
||||
static Map<String, User> usersByName = new HashMap();
|
||||
static {
|
||||
User user1 = new User();
|
||||
user1.setUserId(1l);
|
||||
user1.setFirstName("baeldung");
|
||||
usersByName.put("baeldung", user1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
changeUserName("baeldung", "baeldung-new");
|
||||
changeUserName("user", "user-new");
|
||||
}
|
||||
|
||||
public static void changeUserName(String oldFirstName, String newFirstName) {
|
||||
Optional<User> userOpt = findUserByName(oldFirstName);
|
||||
if (userOpt.isPresent()) {
|
||||
User user = userOpt.get();
|
||||
user.setFirstName(newFirstName);
|
||||
|
||||
System.out.println("user with name " + oldFirstName + " is changed to " + user.getFirstName());
|
||||
} else {
|
||||
// user is missing
|
||||
System.out.println("user with name " + oldFirstName + " is not found.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<User> findUserByName(String name) {
|
||||
// look up the user in the database, the user object below could be null
|
||||
User user = usersByName.get(name);
|
||||
Optional<User> opt = Optional.ofNullable(user);
|
||||
|
||||
return opt;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class OptionalToJsonExample {
|
||||
public static void main(String[] args) {
|
||||
UserOptional user = new UserOptional();
|
||||
user.setUserId(1l);
|
||||
user.setFirstName("Bael Dung");
|
||||
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
try {
|
||||
System.out.print("user in json is:" + om.writeValueAsString(user));
|
||||
} catch (JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
public class PersistOptionalTypeExample {
|
||||
static String persistenceUnit = "com.baeldung.optionalReturnType";
|
||||
static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit);
|
||||
|
||||
static EntityManager entityManager = emf.createEntityManager();
|
||||
|
||||
// to run this app, uncomment the follow line in META-INF/persistence.xml
|
||||
// <class>com.baeldung.optionalReturnType.UserOptionalField</class>
|
||||
public static void main(String[] args) {
|
||||
UserOptionalField user1 = new UserOptionalField();
|
||||
user1.setUserId(1l);
|
||||
user1.setFirstName(Optional.of("Bael Dung"));
|
||||
entityManager.persist(user1);
|
||||
|
||||
UserOptional user2 = entityManager.find(UserOptional.class, 1l);
|
||||
System.out.print("User2.firstName:" + user2.getFirstName());
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
public class PersistOptionalTypeExample2 {
|
||||
static String persistenceUnit = "com.baeldung.optionalReturnType";
|
||||
static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit);
|
||||
|
||||
static EntityManager em = emf.createEntityManager();
|
||||
|
||||
public static void main(String[] args) {
|
||||
UserOptional user1 = new UserOptional();
|
||||
user1.setUserId(1l);
|
||||
user1.setFirstName("Bael Dung");
|
||||
em.persist(user1);
|
||||
|
||||
UserOptional user2 = em.find(UserOptional.class, 1l);
|
||||
System.out.print("User2.firstName:" + user2.getFirstName());
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.Persistence;
|
||||
|
||||
public class PersistUserExample {
|
||||
static String persistenceUnit = "com.baeldung.optionalReturnType";
|
||||
static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit);
|
||||
|
||||
static EntityManager em = emf.createEntityManager();
|
||||
|
||||
public static void main(String[] args) {
|
||||
User user1 = new User();
|
||||
user1.setUserId(1l);
|
||||
user1.setFirstName("Bael Dung");
|
||||
em.persist(user1);
|
||||
|
||||
User user2 = em.find(User.class, 1l);
|
||||
System.out.print("User2.firstName:" + user2.getFirstName());
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public class SerializeOptionalTypeExample {
|
||||
public static void main(String[] args) {
|
||||
User user1 = new User();
|
||||
user1.setUserId(1l);
|
||||
user1.setFirstName("baeldung");
|
||||
|
||||
serializeObject(user1, "user1.ser");
|
||||
|
||||
UserOptionalField user2 = new UserOptionalField();
|
||||
user2.setUserId(1l);
|
||||
user2.setFirstName(Optional.of("baeldung"));
|
||||
|
||||
serializeObject(user2, "user2.ser");
|
||||
|
||||
}
|
||||
|
||||
public static void serializeObject(Object object, String fileName) {
|
||||
// Serialization
|
||||
try {
|
||||
FileOutputStream file = new FileOutputStream(fileName);
|
||||
ObjectOutputStream out = new ObjectOutputStream(file);
|
||||
|
||||
out.writeObject(object);
|
||||
|
||||
out.close();
|
||||
file.close();
|
||||
|
||||
System.out.println("Object " + object.toString() + " has been serialized to file " + fileName);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User implements Serializable {
|
||||
@Id
|
||||
private long userId;
|
||||
|
||||
private String firstName;
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class UserOptional implements Serializable {
|
||||
@Id
|
||||
private long userId;
|
||||
|
||||
@Column(nullable = true)
|
||||
private String firstName;
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Optional<String> getFirstName() {
|
||||
return Optional.ofNullable(firstName);
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
Optional.ofNullable(firstName);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.optionalReturnType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class UserOptionalField implements Serializable {
|
||||
@Id
|
||||
private long userId;
|
||||
|
||||
private Optional<String> firstName;
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Optional<String> getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(Optional<String> firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
}
|
@ -51,4 +51,5 @@
|
||||
- [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)
|
||||
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)
|
||||
- [How to Find an Exception’s Root Cause in Java](https://www.baeldung.com/java-exception-root-cause)
|
||||
- [Convert Hex to ASCII in Java](https://www.baeldung.com/java-convert-hex-to-ascii)
|
||||
|
@ -1 +0,0 @@
|
||||
### Relevant Articles:
|
@ -19,7 +19,7 @@ public class Graph {
|
||||
|
||||
void removeVertex(String label) {
|
||||
Vertex v = new Vertex(label);
|
||||
adjVertices.values().stream().map(e -> e.remove(v)).collect(Collectors.toList());
|
||||
adjVertices.values().stream().forEach(e -> e.remove(v));
|
||||
adjVertices.remove(new Vertex(label));
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,31 @@
|
||||
package com.baeldung.graph;
|
||||
|
||||
import org.junit.Assert;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GraphTraversalUnitTest {
|
||||
public class GraphUnitTest {
|
||||
@Test
|
||||
public void givenAGraph_whenTraversingDepthFirst_thenExpectedResult() {
|
||||
Graph graph = createGraph();
|
||||
Assert.assertEquals("[Bob, Rob, Maria, Alice, Mark]",
|
||||
assertEquals("[Bob, Rob, Maria, Alice, Mark]",
|
||||
GraphTraversal.depthFirstTraversal(graph, "Bob").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAGraph_whenTraversingBreadthFirst_thenExpectedResult() {
|
||||
Graph graph = createGraph();
|
||||
Assert.assertEquals("[Bob, Alice, Rob, Mark, Maria]",
|
||||
assertEquals("[Bob, Alice, Rob, Mark, Maria]",
|
||||
GraphTraversal.breadthFirstTraversal(graph, "Bob").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAGraph_whenRemoveVertex_thenVertedNotFound() {
|
||||
Graph graph = createGraph();
|
||||
assertEquals("[Bob, Alice, Rob, Mark, Maria]",
|
||||
GraphTraversal.breadthFirstTraversal(graph, "Bob").toString());
|
||||
|
||||
graph.removeVertex("Maria");
|
||||
assertEquals("[Bob, Alice, Rob, Mark]",
|
||||
GraphTraversal.breadthFirstTraversal(graph, "Bob").toString());
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
<modules>
|
||||
<module>pre-jpms</module>
|
||||
<module>core-java-exceptions</module>
|
||||
<module>core-java-optional</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
@ -9,19 +9,3 @@ interface Document {
|
||||
|
||||
fun getType() = "document"
|
||||
}
|
||||
|
||||
class TextDocument : Document {
|
||||
override fun getType() = "text"
|
||||
|
||||
fun transformList(list : List<Number>) : List<Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
var list : List<@JvmWildcard Any> = ArrayList()
|
||||
}
|
||||
|
||||
class XmlDocument(d : Document) : Document by d
|
||||
|
@ -0,0 +1,16 @@
|
||||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
class TextDocument : Document {
|
||||
override fun getType() = "text"
|
||||
|
||||
fun transformList(list : List<Number>) : List<Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> {
|
||||
return list.filter { n -> n.toInt() > 1 }
|
||||
}
|
||||
|
||||
var list : List<@JvmWildcard Any> = ArrayList()
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.jvmannotations
|
||||
|
||||
import java.util.*
|
||||
|
||||
class XmlDocument(d : Document) : Document by d
|
@ -3,6 +3,8 @@ package com.baeldung.range
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
import com.baeldung.jvmannotations.*;
|
||||
|
||||
class DocumentTest {
|
||||
|
||||
@Test
|
||||
|
@ -1,3 +1,5 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Persisting DDD Aggregates](https://www.baeldung.com/spring-persisting-ddd-aggregates)
|
||||
- [Double Dispatch in DDD](https://www.baeldung.com/ddd-double-dispatch)
|
||||
- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
|
||||
|
61
docker/docker-compose.yml
Normal file
61
docker/docker-compose.yml
Normal file
@ -0,0 +1,61 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
## VOLUME CONTAINER-TO-CONTAINER AND HOST-TO-CONTAINER TEST ##
|
||||
|
||||
volumes-example-service:
|
||||
image: alpine:latest
|
||||
container_name: volumes-example-service
|
||||
volumes:
|
||||
- /tmp:/my-volumes/host-volume
|
||||
- /home:/my-volumes/readonly-host-volume:ro
|
||||
- my-named-global-volume:/my-volumes/named-global-volume
|
||||
tty: true # Needed to keep the container running
|
||||
|
||||
another-volumes-example-service:
|
||||
image: alpine:latest
|
||||
container_name: another-volumes-example-service
|
||||
volumes:
|
||||
- my-named-global-volume:/another-path/the-same-named-global-volume
|
||||
tty: true # Needed to keep the container running
|
||||
|
||||
## NETWORK CONTAINER-TO-CONTAINER TEST ##
|
||||
|
||||
network-example-service:
|
||||
image: karthequian/helloworld:latest
|
||||
container_name: network-example-service
|
||||
networks:
|
||||
- my-shared-network
|
||||
|
||||
another-service-in-the-same-network:
|
||||
image: alpine:latest
|
||||
container_name: another-service-in-the-same-network
|
||||
networks:
|
||||
- my-shared-network
|
||||
|
||||
tty: true # Needed to keep the container running
|
||||
|
||||
another-service-in-its-own-network:
|
||||
image: alpine:latest
|
||||
container_name: another-service-in-its-own-network
|
||||
networks:
|
||||
- my-private-network
|
||||
tty: true # Needed to keep the container running
|
||||
|
||||
## NETWORK HOST-TO-CONTAINER TEST ##
|
||||
|
||||
network-example-service-available-to-host-on-port-1337:
|
||||
image: karthequian/helloworld:latest
|
||||
container_name: network-example-service-available-to-host-on-port-1337
|
||||
networks:
|
||||
- my-shared-network
|
||||
ports:
|
||||
- "1337:80"
|
||||
|
||||
volumes:
|
||||
my-named-global-volume:
|
||||
|
||||
networks:
|
||||
my-shared-network: {}
|
||||
my-private-network: {}
|
@ -28,6 +28,13 @@
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
<version>2.9.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CSV -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-csv</artifactId>
|
||||
<version>2.9.8</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Allow use of LocalDate -->
|
||||
<dependency>
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.baeldung.jackson.csv;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.baeldung.jackson.entities.OrderLine;
|
||||
import com.baeldung.jackson.mixin.OrderLineForCsv;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.MappingIterator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
||||
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
|
||||
import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder;
|
||||
|
||||
public class JsonCsvConverter {
|
||||
|
||||
public static void JsonToCsv(File jsonFile, File csvFile) throws IOException {
|
||||
JsonNode jsonTree = new ObjectMapper().readTree(jsonFile);
|
||||
|
||||
Builder csvSchemaBuilder = CsvSchema.builder();
|
||||
JsonNode firstObject = jsonTree.elements().next();
|
||||
firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} );
|
||||
CsvSchema csvSchema = csvSchemaBuilder
|
||||
.build()
|
||||
.withHeader();
|
||||
|
||||
CsvMapper csvMapper = new CsvMapper();
|
||||
csvMapper.writerFor(JsonNode.class)
|
||||
.with(csvSchema)
|
||||
.writeValue(csvFile, jsonTree);
|
||||
}
|
||||
|
||||
public static void csvToJson(File csvFile, File jsonFile) throws IOException {
|
||||
CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader();
|
||||
CsvMapper csvMapper = new CsvMapper();
|
||||
MappingIterator<OrderLine> orderLines = csvMapper.readerFor(OrderLine.class)
|
||||
.with(orderLineSchema)
|
||||
.readValues(csvFile);
|
||||
|
||||
new ObjectMapper()
|
||||
.configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
.writeValue(jsonFile, orderLines.readAll());
|
||||
}
|
||||
|
||||
public static void JsonToFormattedCsv(File jsonFile, File csvFile) throws IOException {
|
||||
CsvMapper csvMapper = new CsvMapper();
|
||||
CsvSchema csvSchema = csvMapper
|
||||
.schemaFor(OrderLineForCsv.class)
|
||||
.withHeader();
|
||||
csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class);
|
||||
|
||||
OrderLine[] orderLines = new ObjectMapper()
|
||||
.readValue(jsonFile, OrderLine[].class);
|
||||
csvMapper.writerFor(OrderLine[].class)
|
||||
.with(csvSchema)
|
||||
.writeValue(csvFile, orderLines);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.baeldung.jackson.mixin;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonPropertyOrder({
|
||||
"count",
|
||||
"name"
|
||||
})
|
||||
public abstract class OrderLineForCsv {
|
||||
|
||||
@JsonProperty("name")
|
||||
private String item;
|
||||
|
||||
@JsonProperty("count")
|
||||
private int quantity;
|
||||
|
||||
@JsonIgnore
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
|
||||
}
|
3
jackson-2/src/main/resources/orderLines.csv
Normal file
3
jackson-2/src/main/resources/orderLines.csv
Normal file
@ -0,0 +1,3 @@
|
||||
item,quantity,unitPrice
|
||||
"No. 9 Sprockets",12,1.23
|
||||
"Widget (10mm)",4,3.45
|
|
9
jackson-2/src/main/resources/orderLines.json
Normal file
9
jackson-2/src/main/resources/orderLines.json
Normal file
@ -0,0 +1,9 @@
|
||||
[ {
|
||||
"item" : "No. 9 Sprockets",
|
||||
"quantity" : 12,
|
||||
"unitPrice" : 1.23
|
||||
}, {
|
||||
"item" : "Widget (10mm)",
|
||||
"quantity" : 4,
|
||||
"unitPrice" : 3.45
|
||||
} ]
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.jackson.csv;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
|
||||
public class CsvUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenJsonInput_thenWriteCsv() throws JsonParseException, JsonMappingException, IOException {
|
||||
JsonCsvConverter.JsonToCsv(new File("src/main/resources/orderLines.json"),
|
||||
new File("src/main/resources/csvFromJson.csv"));
|
||||
|
||||
assertEquals(readFile("src/main/resources/csvFromJson.csv"),
|
||||
readFile("src/test/resources/expectedCsvFromJson.csv"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCsvInput_thenWritesJson() throws JsonParseException, JsonMappingException, IOException {
|
||||
JsonCsvConverter.csvToJson(new File("src/main/resources/orderLines.csv"),
|
||||
new File("src/main/resources/jsonFromCsv.json"));
|
||||
|
||||
assertEquals(readFile("src/main/resources/jsonFromCsv.json"),
|
||||
readFile("src/test/resources/expectedJsonFromCsv.json"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJsonInput_thenWriteFormattedCsvOutput() throws JsonParseException, JsonMappingException, IOException {
|
||||
JsonCsvConverter.JsonToFormattedCsv(new File("src/main/resources/orderLines.json"),
|
||||
new File("src/main/resources/formattedCsvFromJson.csv"));
|
||||
|
||||
assertEquals(readFile("src/main/resources/formattedCsvFromJson.csv"),
|
||||
readFile("src/test/resources/expectedFormattedCsvFromJson.csv"));
|
||||
|
||||
}
|
||||
|
||||
private List<String> readFile(String filename) throws IOException {
|
||||
return Files.readLines(new File(filename), Charset.forName("utf-8"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
;
|
3
jackson-2/src/test/resources/expectedCsvFromJson.csv
Normal file
3
jackson-2/src/test/resources/expectedCsvFromJson.csv
Normal file
@ -0,0 +1,3 @@
|
||||
item,quantity,unitPrice
|
||||
"No. 9 Sprockets",12,1.23
|
||||
"Widget (10mm)",4,3.45
|
|
@ -0,0 +1,3 @@
|
||||
count,name
|
||||
12,"No. 9 Sprockets"
|
||||
4,"Widget (10mm)"
|
|
9
jackson-2/src/test/resources/expectedJsonFromCsv.json
Normal file
9
jackson-2/src/test/resources/expectedJsonFromCsv.json
Normal file
@ -0,0 +1,9 @@
|
||||
[ {
|
||||
"item" : "No. 9 Sprockets",
|
||||
"quantity" : 12,
|
||||
"unitPrice" : 1.23
|
||||
}, {
|
||||
"item" : "Widget (10mm)",
|
||||
"quantity" : 4,
|
||||
"unitPrice" : 3.45
|
||||
} ]
|
@ -0,0 +1,48 @@
|
||||
package com.baeldung.convertToMap;
|
||||
|
||||
public class Book {
|
||||
private String name;
|
||||
private int releaseYear;
|
||||
private String isbn;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book{" +
|
||||
"name='" + name + '\'' +
|
||||
", releaseYear=" + releaseYear +
|
||||
", isbn='" + isbn + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getReleaseYear() {
|
||||
return releaseYear;
|
||||
}
|
||||
|
||||
public void setReleaseYear(int releaseYear) {
|
||||
this.releaseYear = releaseYear;
|
||||
}
|
||||
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public void setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
}
|
||||
|
||||
public Book(String name, int releaseYear, String isbn) {
|
||||
this.name = name;
|
||||
this.releaseYear = releaseYear;
|
||||
this.isbn = isbn;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package com.baeldung.convertToMap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConvertToMap {
|
||||
public Map<String, String> listToMap(List<Book> books) {
|
||||
return books.stream().collect(Collectors.toMap(Book::getIsbn, Book::getName));
|
||||
}
|
||||
|
||||
public Map<Integer, Book> listToMapWithDupKeyError(List<Book> books) {
|
||||
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity()));
|
||||
}
|
||||
|
||||
public Map<Integer, Book> listToMapWithDupKey(List<Book> books) {
|
||||
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), (existing, replacement) -> existing));
|
||||
}
|
||||
|
||||
public Map<Integer, Book> listToConcurrentMap(List<Book> books) {
|
||||
return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), (o1, o2) -> o1, ConcurrentHashMap::new));
|
||||
}
|
||||
|
||||
public TreeMap<String, Book> listToSortedMap(List<Book> books) {
|
||||
return books.stream()
|
||||
.sorted(Comparator.comparing(Book::getName))
|
||||
.collect(Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.convertToMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class ConvertToMapUnitTest {
|
||||
|
||||
private List<Book> bookList;
|
||||
private ConvertToMap convertToMap = new ConvertToMap();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
bookList = new ArrayList<>();
|
||||
bookList.add(new Book("The Fellowship of the Ring", 1954, "0395489318"));
|
||||
bookList.add(new Book("The Two Towers", 1954, "0345339711"));
|
||||
bookList.add(new Book("The Return of the King", 1955, "0618129111"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertFromListToMap() {
|
||||
assertTrue(convertToMap.listToMap(bookList).size() == 3);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void whenMapHasDuplicateKey_without_merge_function_then_runtime_exception() {
|
||||
convertToMap.listToMapWithDupKeyError(bookList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMapHasDuplicateKeyThenMergeFunctionHandlesCollision() {
|
||||
Map<Integer, Book> booksByYear = convertToMap.listToMapWithDupKey(bookList);
|
||||
assertEquals(2, booksByYear.size());
|
||||
assertEquals("0395489318", booksByYear.get(1954).getIsbn());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreateConcurrentHashMap() {
|
||||
assertTrue(convertToMap.listToConcurrentMap(bookList) instanceof ConcurrentHashMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMapisSorted() {
|
||||
assertTrue(convertToMap.listToSortedMap(bookList).firstKey().equals("The Fellowship of the Ring"));
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ import org.junit.Test;
|
||||
/**
|
||||
* BAEL-2832: Different ways to check if a Substring could be found in a String.
|
||||
*/
|
||||
public class SubstringSearch {
|
||||
public class SubstringSearchUnitTest {
|
||||
|
||||
@Test
|
||||
public void searchSubstringWithIndexOf() {
|
@ -6,3 +6,4 @@
|
||||
- [A Guide to Java EE Web-Related Annotations](http://www.baeldung.com/javaee-web-annotations)
|
||||
- [Introduction to Testing with Arquillian](http://www.baeldung.com/arquillian)
|
||||
- [Java EE 7 Batch Processing](https://www.baeldung.com/java-ee-7-batch-processing)
|
||||
- [The Difference Between CDI and EJB Singleton](https://www.baeldung.com/jee-cdi-vs-ejb-singleton)
|
||||
|
@ -3,3 +3,4 @@
|
||||
- [Bean Validation in Jersey](https://www.baeldung.com/jersey-bean-validation)
|
||||
- [Set a Response Body in JAX-RS](https://www.baeldung.com/jax-rs-response)
|
||||
- [Exploring the Jersey Test Framework](https://www.baeldung.com/jersey-test)
|
||||
- [Explore Jersey Request Parameters](https://www.baeldung.com/jersey-request-parameters)
|
||||
|
@ -26,6 +26,7 @@ public class FruitResourceIntegrationTest extends JerseyTest {
|
||||
protected Application configure() {
|
||||
enable(TestProperties.LOG_TRAFFIC);
|
||||
enable(TestProperties.DUMP_ENTITY);
|
||||
forceSet(TestProperties.CONTAINER_PORT, "0");
|
||||
|
||||
ViewApplicationConfig config = new ViewApplicationConfig();
|
||||
config.register(FruitExceptionMapper.class);
|
||||
|
@ -1,3 +1,4 @@
|
||||
## Relevant articles:
|
||||
|
||||
- [Jackson Support for Kotlin](https://www.baeldung.com/jackson-kotlin)
|
||||
- [Introduction to RxKotlin](https://www.baeldung.com/rxkotlin)
|
||||
|
120
kotlin-quasar/pom.xml
Normal file
120
kotlin-quasar/pom.xml
Normal file
@ -0,0 +1,120 @@
|
||||
<?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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>kotlin-quasar</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>kotlin-quasar</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.paralleluniverse</groupId>
|
||||
<artifactId>quasar-core</artifactId>
|
||||
<version>${quasar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.paralleluniverse</groupId>
|
||||
<artifactId>quasar-actors</artifactId>
|
||||
<version>${quasar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.paralleluniverse</groupId>
|
||||
<artifactId>quasar-reactive-streams</artifactId>
|
||||
<version>${quasar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.paralleluniverse</groupId>
|
||||
<artifactId>quasar-kotlin</artifactId>
|
||||
<version>${quasar.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>getClasspathFilenames</id>
|
||||
<goals>
|
||||
<goal>properties</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.1</version>
|
||||
<configuration>
|
||||
<argLine>-Dco.paralleluniverse.fibers.verifyInstrumentation=true</argLine>
|
||||
<argLine>-javaagent:${co.paralleluniverse:quasar-core:jar}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<configuration>
|
||||
<workingDirectory>target/classes</workingDirectory>
|
||||
<executable>echo</executable>
|
||||
<arguments>
|
||||
<argument>-javaagent:${co.paralleluniverse:quasar-core:jar}</argument>
|
||||
<argument>-classpath</argument> <classpath/>
|
||||
<argument>com.baeldung.quasar.QuasarHelloWorldKt</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<quasar.version>0.8.0</quasar.version>
|
||||
<kotlin.version>1.3.31</kotlin.version>
|
||||
</properties>
|
||||
</project>
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.fibers.Fiber
|
||||
import co.paralleluniverse.strands.SuspendableRunnable
|
||||
|
||||
|
||||
/**
|
||||
* Entrypoint into the application
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
class Runnable : SuspendableRunnable {
|
||||
override fun run() {
|
||||
println("Hello")
|
||||
}
|
||||
}
|
||||
val result = Fiber<Void>(Runnable()).start()
|
||||
result.join()
|
||||
println("World")
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.kotlin.fiber
|
||||
import co.paralleluniverse.strands.channels.Channels
|
||||
import co.paralleluniverse.strands.channels.Selector
|
||||
import com.google.common.base.Function
|
||||
import org.junit.Test
|
||||
|
||||
class ChannelsTest {
|
||||
@Test
|
||||
fun createChannel() {
|
||||
Channels.newChannel<String>(0, // The size of the channel buffer
|
||||
Channels.OverflowPolicy.BLOCK, // The policy for when the buffer is full
|
||||
true, // Whether we should optimize for a single message producer
|
||||
true) // Whether we should optimize for a single message consumer
|
||||
}
|
||||
|
||||
@Test
|
||||
fun blockOnMessage() {
|
||||
val channel = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!channel.isClosed) {
|
||||
val message = channel.receive()
|
||||
println("Received: $message")
|
||||
}
|
||||
println("Stopped receiving messages")
|
||||
}
|
||||
|
||||
channel.send("Hello")
|
||||
channel.send("World")
|
||||
|
||||
channel.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selectReceiveChannels() {
|
||||
val channel1 = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
val channel2 = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!channel1.isClosed && !channel2.isClosed) {
|
||||
val received = Selector.select(Selector.receive(channel1), Selector.receive(channel2))
|
||||
|
||||
println("Received: $received")
|
||||
}
|
||||
}
|
||||
|
||||
fiber @Suspendable {
|
||||
for (i in 0..10) {
|
||||
channel1.send("Channel 1: $i")
|
||||
}
|
||||
}
|
||||
|
||||
fiber @Suspendable {
|
||||
for (i in 0..10) {
|
||||
channel2.send("Channel 2: $i")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selectSendChannels() {
|
||||
val channel1 = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
val channel2 = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
|
||||
fiber @Suspendable {
|
||||
for (i in 0..10) {
|
||||
Selector.select(
|
||||
Selector.send(channel1, "Channel 1: $i"),
|
||||
Selector.send(channel2, "Channel 2: $i")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!channel1.isClosed) {
|
||||
val msg = channel1.receive()
|
||||
println("Read: $msg")
|
||||
}
|
||||
}
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!channel2.isClosed) {
|
||||
val msg = channel2.receive()
|
||||
println("Read: $msg")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tickerChannel() {
|
||||
val channel = Channels.newChannel<String>(3, Channels.OverflowPolicy.DISPLACE)
|
||||
|
||||
for (i in 0..10) {
|
||||
val tickerConsumer = Channels.newTickerConsumerFor(channel)
|
||||
fiber @Suspendable {
|
||||
while (!tickerConsumer.isClosed) {
|
||||
val message = tickerConsumer.receive()
|
||||
println("Received on $i: $message")
|
||||
}
|
||||
println("Stopped receiving messages on $i")
|
||||
}
|
||||
}
|
||||
|
||||
for (i in 0..50) {
|
||||
channel.send("Message $i")
|
||||
}
|
||||
|
||||
channel.close()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun transformOnSend() {
|
||||
val channel = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!channel.isClosed) {
|
||||
val message = channel.receive()
|
||||
println("Received: $message")
|
||||
}
|
||||
println("Stopped receiving messages")
|
||||
}
|
||||
|
||||
val transformOnSend = Channels.mapSend(channel, Function<String, String> { msg: String? -> msg?.toUpperCase() })
|
||||
|
||||
transformOnSend.send("Hello")
|
||||
transformOnSend.send("World")
|
||||
|
||||
channel.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun transformOnReceive() {
|
||||
val channel = Channels.newChannel<String>(0, Channels.OverflowPolicy.BLOCK, true, true)
|
||||
|
||||
val transformOnReceive = Channels.map(channel, Function<String, String> { msg: String? -> msg?.reversed() })
|
||||
|
||||
fiber @Suspendable {
|
||||
while (!transformOnReceive.isClosed) {
|
||||
val message = transformOnReceive.receive()
|
||||
println("Received: $message")
|
||||
}
|
||||
println("Stopped receiving messages")
|
||||
}
|
||||
|
||||
|
||||
channel.send("Hello")
|
||||
channel.send("World")
|
||||
|
||||
channel.close()
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.strands.dataflow.Val
|
||||
import co.paralleluniverse.strands.dataflow.Var
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class DataflowTest {
|
||||
@Test
|
||||
fun testValVar() {
|
||||
val a = Var<Int>()
|
||||
val b = Val<Int>()
|
||||
|
||||
val c = Var<Int> { a.get() + b.get() }
|
||||
val d = Var<Int> { a.get() * b.get() }
|
||||
|
||||
// (a*b) - (a+b)
|
||||
val initialResult = Val<Int> { d.get() - c.get() }
|
||||
val currentResult = Var<Int> { d.get() - c.get() }
|
||||
|
||||
a.set(2)
|
||||
b.set(4)
|
||||
|
||||
Assert.assertEquals(2, initialResult.get())
|
||||
Assert.assertEquals(2, currentResult.get())
|
||||
|
||||
a.set(3)
|
||||
|
||||
TimeUnit.SECONDS.sleep(1)
|
||||
|
||||
Assert.assertEquals(2, initialResult.get())
|
||||
Assert.assertEquals(5, currentResult.get())
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.fibers.Fiber
|
||||
import co.paralleluniverse.fibers.FiberAsync
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.kotlin.fiber
|
||||
import co.paralleluniverse.strands.Strand
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.math.BigDecimal
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
interface PiCallback {
|
||||
fun success(result: BigDecimal)
|
||||
fun failure(error: Exception)
|
||||
}
|
||||
|
||||
fun computePi(callback: PiCallback) {
|
||||
println("Starting calculations")
|
||||
TimeUnit.SECONDS.sleep(2)
|
||||
println("Finished calculations")
|
||||
callback.success(BigDecimal("3.14"))
|
||||
}
|
||||
|
||||
class PiAsync : PiCallback, FiberAsync<BigDecimal, Exception>() {
|
||||
override fun success(result: BigDecimal) {
|
||||
asyncCompleted(result)
|
||||
}
|
||||
|
||||
override fun failure(error: Exception) {
|
||||
asyncFailed(error)
|
||||
}
|
||||
|
||||
override fun requestAsync() {
|
||||
computePi(this)
|
||||
}
|
||||
}
|
||||
|
||||
class PiAsyncTest {
|
||||
@Test
|
||||
fun testPi() {
|
||||
val result = fiber @Suspendable {
|
||||
val pi = PiAsync()
|
||||
println("Waiting to get PI on: " + Fiber.currentFiber().name)
|
||||
val result = pi.run()
|
||||
println("Got PI")
|
||||
|
||||
result
|
||||
}.get()
|
||||
|
||||
Assert.assertEquals(BigDecimal("3.14"), result)
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.fibers.Fiber
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.kotlin.fiber
|
||||
import co.paralleluniverse.strands.SuspendableCallable
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class SuspendableCallableTest {
|
||||
@Test
|
||||
fun createFiber() {
|
||||
class Callable : SuspendableCallable<String> {
|
||||
override fun run(): String {
|
||||
println("Inside Fiber")
|
||||
return "Hello"
|
||||
}
|
||||
}
|
||||
val result = Fiber<String>(Callable()).start()
|
||||
|
||||
Assert.assertEquals("Hello", result.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFiberLambda() {
|
||||
val lambda: (() -> String) = {
|
||||
println("Inside Fiber Lambda")
|
||||
"Hello"
|
||||
}
|
||||
val result = Fiber<String>(lambda)
|
||||
result.start()
|
||||
|
||||
Assert.assertEquals("Hello", result.get())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFiberDsl() {
|
||||
val result = fiber @Suspendable {
|
||||
TimeUnit.SECONDS.sleep(5)
|
||||
println("Inside Fiber DSL")
|
||||
"Hello"
|
||||
}
|
||||
|
||||
Assert.assertEquals("Hello", result.get())
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baeldung.quasar
|
||||
|
||||
import co.paralleluniverse.fibers.Fiber
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import co.paralleluniverse.kotlin.fiber
|
||||
import co.paralleluniverse.strands.SuspendableRunnable
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
|
||||
class SuspensableRunnableTest {
|
||||
@Test
|
||||
fun createFiber() {
|
||||
class Runnable : SuspendableRunnable {
|
||||
override fun run() {
|
||||
println("Inside Fiber")
|
||||
}
|
||||
}
|
||||
val result = Fiber<Void>(Runnable()).start()
|
||||
result.join()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFiberLambda() {
|
||||
val result = Fiber<Void> {
|
||||
println("Inside Fiber Lambda")
|
||||
}
|
||||
result.start()
|
||||
result.join()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFiberDsl() {
|
||||
fiber @Suspendable {
|
||||
println("Inside Fiber DSL")
|
||||
}.join()
|
||||
}
|
||||
|
||||
@Test(expected = TimeoutException::class)
|
||||
fun fiberTimeout() {
|
||||
fiber @Suspendable {
|
||||
TimeUnit.SECONDS.sleep(5)
|
||||
println("Inside Fiber DSL")
|
||||
}.join(2, TimeUnit.SECONDS)
|
||||
}
|
||||
}
|
@ -55,6 +55,39 @@
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Dependencies for response decoder with okhttp -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.9.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
<version>3.14.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>edu.uci.ics</groupId>
|
||||
<artifactId>crawler4j</artifactId>
|
||||
<version>${crawler4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
@ -62,6 +95,7 @@
|
||||
<classgraph.version>4.8.28</classgraph.version>
|
||||
<jbpm.version>6.0.0.Final</jbpm.version>
|
||||
<picocli.version>3.9.6</picocli.version>
|
||||
<crawler4j.version>4.4.0</crawler4j.version>
|
||||
<spring-boot-starter.version>2.1.4.RELEASE</spring-boot-starter.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
public class CrawlerStatistics {
|
||||
private int processedPageCount = 0;
|
||||
private int totalLinksCount = 0;
|
||||
|
||||
public void incrementProcessedPageCount() {
|
||||
processedPageCount++;
|
||||
}
|
||||
|
||||
public void incrementTotalLinksCount(int linksCount) {
|
||||
totalLinksCount += linksCount;
|
||||
}
|
||||
|
||||
public int getProcessedPageCount() {
|
||||
return processedPageCount;
|
||||
}
|
||||
|
||||
public int getTotalLinksCount() {
|
||||
return totalLinksCount;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import edu.uci.ics.crawler4j.crawler.Page;
|
||||
import edu.uci.ics.crawler4j.crawler.WebCrawler;
|
||||
import edu.uci.ics.crawler4j.parser.HtmlParseData;
|
||||
import edu.uci.ics.crawler4j.url.WebURL;
|
||||
|
||||
public class HtmlCrawler extends WebCrawler {
|
||||
|
||||
private final static Pattern EXCLUSIONS = Pattern.compile(".*(\\.(css|js|xml|gif|jpg|png|mp3|mp4|zip|gz|pdf))$");
|
||||
|
||||
private CrawlerStatistics stats;
|
||||
|
||||
public HtmlCrawler(CrawlerStatistics stats) {
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldVisit(Page referringPage, WebURL url) {
|
||||
String urlString = url.getURL().toLowerCase();
|
||||
return !EXCLUSIONS.matcher(urlString).matches()
|
||||
&& urlString.startsWith("https://www.baeldung.com/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Page page) {
|
||||
String url = page.getWebURL().getURL();
|
||||
stats.incrementProcessedPageCount();
|
||||
|
||||
if (page.getParseData() instanceof HtmlParseData) {
|
||||
HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
|
||||
String title = htmlParseData.getTitle();
|
||||
String text = htmlParseData.getText();
|
||||
String html = htmlParseData.getHtml();
|
||||
Set<WebURL> links = htmlParseData.getOutgoingUrls();
|
||||
stats.incrementTotalLinksCount(links.size());
|
||||
|
||||
System.out.printf("Page with title '%s' %n", title);
|
||||
System.out.printf(" Text length: %d %n", text.length());
|
||||
System.out.printf(" HTML length: %d %n", html.length());
|
||||
System.out.printf(" %d outbound links %n", links.size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlController;
|
||||
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
|
||||
|
||||
public class HtmlCrawlerController {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File crawlStorage = new File("src/test/resources/crawler4j");
|
||||
CrawlConfig config = new CrawlConfig();
|
||||
config.setCrawlStorageFolder(crawlStorage.getAbsolutePath());
|
||||
config.setMaxDepthOfCrawling(2);
|
||||
|
||||
int numCrawlers = 12;
|
||||
|
||||
PageFetcher pageFetcher = new PageFetcher(config);
|
||||
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
|
||||
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
|
||||
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
|
||||
|
||||
controller.addSeed("https://www.baeldung.com/");
|
||||
|
||||
CrawlerStatistics stats = new CrawlerStatistics();
|
||||
CrawlController.WebCrawlerFactory<HtmlCrawler> factory = () -> new HtmlCrawler(stats);
|
||||
|
||||
controller.start(factory, numCrawlers);
|
||||
System.out.printf("Crawled %d pages %n", stats.getProcessedPageCount());
|
||||
System.out.printf("Total Number of outbound links = %d %n", stats.getTotalLinksCount());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import edu.uci.ics.crawler4j.crawler.Page;
|
||||
import edu.uci.ics.crawler4j.crawler.WebCrawler;
|
||||
import edu.uci.ics.crawler4j.parser.BinaryParseData;
|
||||
import edu.uci.ics.crawler4j.url.WebURL;
|
||||
|
||||
public class ImageCrawler extends WebCrawler {
|
||||
private final static Pattern EXCLUSIONS = Pattern.compile(".*(\\.(css|js|xml|gif|png|mp3|mp4|zip|gz|pdf))$");
|
||||
|
||||
private static final Pattern IMG_PATTERNS = Pattern.compile(".*(\\.(jpg|jpeg))$");
|
||||
|
||||
private File saveDir;
|
||||
|
||||
public ImageCrawler(File saveDir) {
|
||||
this.saveDir = saveDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldVisit(Page referringPage, WebURL url) {
|
||||
String urlString = url.getURL().toLowerCase();
|
||||
if (EXCLUSIONS.matcher(urlString).matches()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IMG_PATTERNS.matcher(urlString).matches()
|
||||
|| urlString.startsWith("https://www.baeldung.com/")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Page page) {
|
||||
String url = page.getWebURL().getURL();
|
||||
if (IMG_PATTERNS.matcher(url).matches()
|
||||
&& page.getParseData() instanceof BinaryParseData) {
|
||||
String extension = url.substring(url.lastIndexOf("."));
|
||||
int contentLength = page.getContentData().length;
|
||||
|
||||
System.out.printf("Extension is '%s' with content length %d %n", extension, contentLength);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlController;
|
||||
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
|
||||
|
||||
public class ImageCrawlerController {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File crawlStorage = new File("src/test/resources/crawler4j");
|
||||
CrawlConfig config = new CrawlConfig();
|
||||
config.setCrawlStorageFolder(crawlStorage.getAbsolutePath());
|
||||
config.setIncludeBinaryContentInCrawling(true);
|
||||
config.setMaxPagesToFetch(500);
|
||||
|
||||
File saveDir = new File("src/test/resources/crawler4j");
|
||||
|
||||
int numCrawlers = 12;
|
||||
|
||||
PageFetcher pageFetcher = new PageFetcher(config);
|
||||
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
|
||||
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
|
||||
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
|
||||
|
||||
controller.addSeed("https://www.baeldung.com/");
|
||||
|
||||
CrawlController.WebCrawlerFactory<ImageCrawler> factory = () -> new ImageCrawler(saveDir);
|
||||
|
||||
controller.start(factory, numCrawlers);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.baeldung.crawler4j;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlConfig;
|
||||
import edu.uci.ics.crawler4j.crawler.CrawlController;
|
||||
import edu.uci.ics.crawler4j.fetcher.PageFetcher;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig;
|
||||
import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer;
|
||||
|
||||
public class MultipleCrawlerController {
|
||||
public static void main(String[] args) throws Exception {
|
||||
File crawlStorageBase = new File("src/test/resources/crawler4j");
|
||||
CrawlConfig htmlConfig = new CrawlConfig();
|
||||
CrawlConfig imageConfig = new CrawlConfig();
|
||||
|
||||
htmlConfig.setCrawlStorageFolder(new File(crawlStorageBase, "html").getAbsolutePath());
|
||||
imageConfig.setCrawlStorageFolder(new File(crawlStorageBase, "image").getAbsolutePath());
|
||||
imageConfig.setIncludeBinaryContentInCrawling(true);
|
||||
|
||||
htmlConfig.setMaxPagesToFetch(500);
|
||||
imageConfig.setMaxPagesToFetch(1000);
|
||||
|
||||
PageFetcher pageFetcherHtml = new PageFetcher(htmlConfig);
|
||||
PageFetcher pageFetcherImage = new PageFetcher(imageConfig);
|
||||
|
||||
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
|
||||
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcherHtml);
|
||||
|
||||
CrawlController htmlController = new CrawlController(htmlConfig, pageFetcherHtml, robotstxtServer);
|
||||
CrawlController imageController = new CrawlController(imageConfig, pageFetcherImage, robotstxtServer);
|
||||
|
||||
htmlController.addSeed("https://www.baeldung.com/");
|
||||
imageController.addSeed("https://www.baeldung.com/");
|
||||
|
||||
CrawlerStatistics stats = new CrawlerStatistics();
|
||||
CrawlController.WebCrawlerFactory<HtmlCrawler> htmlFactory = () -> new HtmlCrawler(stats);
|
||||
|
||||
File saveDir = new File("src/test/resources/crawler4j");
|
||||
CrawlController.WebCrawlerFactory<ImageCrawler> imageFactory = () -> new ImageCrawler(saveDir);
|
||||
|
||||
imageController.startNonBlocking(imageFactory, 7);
|
||||
htmlController.startNonBlocking(htmlFactory, 10);
|
||||
|
||||
|
||||
htmlController.waitUntilFinish();
|
||||
System.out.printf("Crawled %d pages %n", stats.getProcessedPageCount());
|
||||
System.out.printf("Total Number of outbound links = %d %n", stats.getTotalLinksCount());
|
||||
|
||||
imageController.waitUntilFinish();
|
||||
System.out.printf("Image Crawler is finished.");
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.baeldung.okhttp;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class ResponseDecoderUnitTest {
|
||||
|
||||
@Rule public ExpectedException exceptionRule = ExpectedException.none();
|
||||
|
||||
@Rule public MockWebServer server = new MockWebServer();
|
||||
|
||||
SimpleEntity sampleResponse;
|
||||
|
||||
MockResponse mockResponse;
|
||||
|
||||
OkHttpClient client;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
sampleResponse = new SimpleEntity("Baeldung");
|
||||
client = new OkHttpClient.Builder().build();
|
||||
mockResponse = new MockResponse()
|
||||
.setResponseCode(200)
|
||||
.setHeader("Content-Type", "application/json")
|
||||
.setBody(new Gson().toJson(sampleResponse));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJacksonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception {
|
||||
server.enqueue(mockResponse);
|
||||
Request request = new Request.Builder()
|
||||
.url(server.url(""))
|
||||
.build();
|
||||
ResponseBody responseBody = client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
.body();
|
||||
|
||||
Assert.assertNotNull(responseBody);
|
||||
Assert.assertNotEquals(0, responseBody.contentLength());
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
SimpleEntity entity = objectMapper.readValue(responseBody.string(), SimpleEntity.class);
|
||||
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertEquals(sampleResponse.getName(), entity.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGsonDecoder_whenGetByteStreamOfResponse_thenExpectSimpleEntity() throws Exception {
|
||||
server.enqueue(mockResponse);
|
||||
Request request = new Request.Builder()
|
||||
.url(server.url(""))
|
||||
.build();
|
||||
ResponseBody responseBody = client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
.body();
|
||||
|
||||
Assert.assertNotNull(responseBody);
|
||||
Assert.assertNotEquals(0, responseBody.contentLength());
|
||||
|
||||
Gson gson = new Gson();
|
||||
SimpleEntity entity = gson.fromJson(new InputStreamReader(responseBody.byteStream()), SimpleEntity.class);
|
||||
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertEquals(sampleResponse.getName(), entity.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGsonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception {
|
||||
server.enqueue(mockResponse);
|
||||
Request request = new Request.Builder()
|
||||
.url(server.url(""))
|
||||
.build();
|
||||
ResponseBody responseBody = client
|
||||
.newCall(request)
|
||||
.execute()
|
||||
.body();
|
||||
|
||||
Assert.assertNotNull(responseBody);
|
||||
|
||||
Gson gson = new Gson();
|
||||
SimpleEntity entity = gson.fromJson(responseBody.string(), SimpleEntity.class);
|
||||
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertEquals(sampleResponse.getName(), entity.getName());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.okhttp;
|
||||
|
||||
public class SimpleEntity {
|
||||
protected String name;
|
||||
|
||||
public SimpleEntity(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//no-arg constructor, getters and setters here
|
||||
|
||||
public SimpleEntity() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -263,6 +263,16 @@
|
||||
<groupId>org.apache.storm</groupId>
|
||||
<artifactId>storm-core</artifactId>
|
||||
<version>${storm.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class BackupCreatorIntegrationTest {
|
||||
@ -88,7 +89,7 @@ public class BackupCreatorIntegrationTest {
|
||||
SerializationSchema<Backup> serializationSchema = new BackupSerializationSchema();
|
||||
byte[] backupProcessed = serializationSchema.serialize(backup);
|
||||
|
||||
assertEquals(backupSerialized, backupProcessed);
|
||||
assertArrayEquals(backupSerialized, backupProcessed);
|
||||
}
|
||||
|
||||
private static class CollectingSink implements SinkFunction<Backup> {
|
||||
|
@ -59,5 +59,6 @@ class FtpClient {
|
||||
void downloadFile(String source, String destination) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(destination);
|
||||
ftp.retrieveFile(source, out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class AdderMethodDirtiesContextIntegrationTest {
|
||||
@Test
|
||||
public void _1_givenNumber_whenAdd_thenSumWrong() {
|
||||
adderServiceSteps.whenAdd();
|
||||
adderServiceSteps.sumWrong();
|
||||
adderServiceSteps.summedUp();
|
||||
}
|
||||
|
||||
@Rule
|
||||
|
@ -78,7 +78,7 @@
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<id>integration-lite-first</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -23,7 +23,7 @@ public class MapAppenderIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception {
|
||||
logger.info("Test from {}", this.getClass()
|
||||
logger.error("Error log message from {}", this.getClass()
|
||||
.getSimpleName());
|
||||
LoggerContext context = LoggerContext.getContext(false);
|
||||
Configuration config = context.getConfiguration();
|
||||
|
@ -16,3 +16,4 @@
|
||||
- [Multi-Module Project with Maven](https://www.baeldung.com/maven-multi-module)
|
||||
- [Maven Enforcer Plugin](https://www.baeldung.com/maven-enforcer-plugin)
|
||||
- [Eclipse Error: web.xml is missing and failOnMissingWebXml is set to true](https://www.baeldung.com/eclipse-error-web-xml-missing)
|
||||
- [Guide to Maven Profiles](https://www.baeldung.com/maven-profiles)
|
||||
|
@ -1,6 +0,0 @@
|
||||
### Relevant Articles:
|
||||
- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern)
|
||||
- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java)
|
||||
- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern)
|
||||
- [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle)
|
||||
- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check)
|
@ -1,3 +1,5 @@
|
||||
### Relevant Articles
|
||||
|
||||
- [The Mediator Pattern in Java](https://www.baeldung.com/java-mediator-pattern)
|
||||
- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern)
|
||||
- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user