commit
84b21162ae
5
.gitignore
vendored
5
.gitignore
vendored
@ -19,6 +19,7 @@
|
|||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
*.iws
|
*.iws
|
||||||
|
out/
|
||||||
|
|
||||||
# Mac
|
# Mac
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@ -27,6 +28,9 @@
|
|||||||
log/
|
log/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle/
|
||||||
|
|
||||||
spring-openid/src/main/resources/application.properties
|
spring-openid/src/main/resources/application.properties
|
||||||
.recommenders/
|
.recommenders/
|
||||||
/spring-hibernate4/nbproject/
|
/spring-hibernate4/nbproject/
|
||||||
@ -73,3 +77,4 @@ apache-avro/src/main/java/com/baeldung/avro/model/
|
|||||||
jta/transaction-logs/
|
jta/transaction-logs/
|
||||||
software-security/sql-injection-samples/derby.log
|
software-security/sql-injection-samples/derby.log
|
||||||
spring-soap/src/main/java/com/baeldung/springsoap/gen/
|
spring-soap/src/main/java/com/baeldung/springsoap/gen/
|
||||||
|
/report-*.json
|
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
|
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
|
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
|
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`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,18 +14,19 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.typesafe.akka</groupId>
|
<groupId>com.typesafe.akka</groupId>
|
||||||
<artifactId>akka-stream_2.11</artifactId>
|
<artifactId>akka-stream_${scala.version}</artifactId>
|
||||||
<version>${akkastreams.version}</version>
|
<version>${akkastreams.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.typesafe.akka</groupId>
|
<groupId>com.typesafe.akka</groupId>
|
||||||
<artifactId>akka-stream-testkit_2.11</artifactId>
|
<artifactId>akka-stream-testkit_${scala.version}</artifactId>
|
||||||
<version>${akkastreams.version}</version>
|
<version>${akkastreams.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<akkastreams.version>2.5.2</akkastreams.version>
|
<akkastreams.version>2.5.2</akkastreams.version>
|
||||||
|
<scala.version>2.11</scala.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -14,6 +14,5 @@
|
|||||||
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
|
||||||
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
|
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
|
||||||
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
|
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
|
||||||
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
|
||||||
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
||||||
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm)
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
<version>${org.assertj.core.version}</version>
|
<version>${org.assertj.core.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.dpaukov</groupId>
|
||||||
|
<artifactId>combinatoricslib3</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -77,7 +82,7 @@
|
|||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||||
<commons-codec.version>1.11</commons-codec.version>
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
<guava.version>25.1-jre</guava.version>
|
<guava.version>27.0.1-jre</guava.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -8,9 +8,6 @@
|
|||||||
- [Create a Sudoku Solver in Java](http://www.baeldung.com/java-sudoku)
|
- [Create a Sudoku Solver in Java](http://www.baeldung.com/java-sudoku)
|
||||||
- [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words)
|
- [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words)
|
||||||
- [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations)
|
- [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations)
|
||||||
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
|
|
||||||
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
|
|
||||||
- [An Introduction to the Theory of Big-O Notation](http://www.baeldung.com/big-o-notation)
|
|
||||||
- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap)
|
- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap)
|
||||||
- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points)
|
- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points)
|
||||||
- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines)
|
- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines)
|
||||||
@ -18,3 +15,5 @@
|
|||||||
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
||||||
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
||||||
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
|
||||||
|
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
|
||||||
|
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung.algorithms.relativelyprime;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
class RelativelyPrime {
|
||||||
|
|
||||||
|
static boolean iterativeRelativelyPrime(int a, int b) {
|
||||||
|
return iterativeGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean recursiveRelativelyPrime(int a, int b) {
|
||||||
|
return recursiveGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean bigIntegerRelativelyPrime(int a, int b) {
|
||||||
|
return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).equals(BigInteger.ONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int iterativeGCD(int a, int b) {
|
||||||
|
int tmp;
|
||||||
|
while (b != 0) {
|
||||||
|
if (a < b) {
|
||||||
|
tmp = a;
|
||||||
|
a = b;
|
||||||
|
b = tmp;
|
||||||
|
}
|
||||||
|
tmp = b;
|
||||||
|
b = a % b;
|
||||||
|
a = tmp;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int recursiveGCD(int a, int b) {
|
||||||
|
if (b == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (a < b) {
|
||||||
|
return recursiveGCD(b, a);
|
||||||
|
}
|
||||||
|
return recursiveGCD(b, a % b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
public class TreeNode {
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
private TreeNode rightChild;
|
||||||
|
private TreeNode leftChild;
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode getRightChild() {
|
||||||
|
return rightChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRightChild(TreeNode rightChild) {
|
||||||
|
this.rightChild = rightChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode getLeftChild() {
|
||||||
|
return leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeftChild(TreeNode leftChild) {
|
||||||
|
this.leftChild = leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode(int value, TreeNode leftChild, TreeNode rightChild) {
|
||||||
|
this.value = value;
|
||||||
|
this.rightChild = rightChild;
|
||||||
|
this.leftChild = leftChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TreeNode(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class TreeReverser {
|
||||||
|
|
||||||
|
public void reverseRecursive(TreeNode treeNode) {
|
||||||
|
if (treeNode == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode temp = treeNode.getLeftChild();
|
||||||
|
treeNode.setLeftChild(treeNode.getRightChild());
|
||||||
|
treeNode.setRightChild(temp);
|
||||||
|
|
||||||
|
reverseRecursive(treeNode.getLeftChild());
|
||||||
|
reverseRecursive(treeNode.getRightChild());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reverseIterative(TreeNode treeNode) {
|
||||||
|
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
|
||||||
|
|
||||||
|
if (treeNode != null) {
|
||||||
|
queue.add(treeNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
|
||||||
|
TreeNode node = queue.poll();
|
||||||
|
if (node.getLeftChild() != null)
|
||||||
|
queue.add(node.getLeftChild());
|
||||||
|
if (node.getRightChild() != null)
|
||||||
|
queue.add(node.getRightChild());
|
||||||
|
|
||||||
|
TreeNode temp = node.getLeftChild();
|
||||||
|
node.setLeftChild(node.getRightChild());
|
||||||
|
node.setRightChild(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(TreeNode root) {
|
||||||
|
if (root == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer(String.valueOf(root.getValue())).append(" ");
|
||||||
|
|
||||||
|
buffer.append(toString(root.getLeftChild()));
|
||||||
|
buffer.append(toString(root.getRightChild()));
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.baeldung.algorithms.relativelyprime;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static com.baeldung.algorithms.relativelyprime.RelativelyPrime.*;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class RelativelyPrimeUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = iterativeRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = iterativeRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = recursiveRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = recursiveRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNonRelativelyPrimeNumbers_whenCheckingUsingBigIntegers_shouldReturnFalse() {
|
||||||
|
|
||||||
|
boolean result = bigIntegerRelativelyPrime(45, 35);
|
||||||
|
assertThat(result).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenRelativelyPrimeNumbers_whenCheckingBigIntegers_shouldReturnTrue() {
|
||||||
|
|
||||||
|
boolean result = bigIntegerRelativelyPrime(500, 501);
|
||||||
|
assertThat(result).isTrue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.algorithms.reversingtree;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TreeReverserUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTreeWhenReversingRecursivelyThenReversed() {
|
||||||
|
TreeReverser reverser = new TreeReverser();
|
||||||
|
|
||||||
|
TreeNode treeNode = createBinaryTree();
|
||||||
|
|
||||||
|
reverser.reverseRecursive(treeNode);
|
||||||
|
|
||||||
|
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||||
|
.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTreeWhenReversingIterativelyThenReversed() {
|
||||||
|
TreeReverser reverser = new TreeReverser();
|
||||||
|
|
||||||
|
TreeNode treeNode = createBinaryTree();
|
||||||
|
|
||||||
|
reverser.reverseIterative(treeNode);
|
||||||
|
|
||||||
|
assertEquals("4 7 9 6 2 3 1", reverser.toString(treeNode)
|
||||||
|
.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeNode createBinaryTree() {
|
||||||
|
|
||||||
|
TreeNode leaf1 = new TreeNode(1);
|
||||||
|
TreeNode leaf2 = new TreeNode(3);
|
||||||
|
TreeNode leaf3 = new TreeNode(6);
|
||||||
|
TreeNode leaf4 = new TreeNode(9);
|
||||||
|
|
||||||
|
TreeNode nodeRight = new TreeNode(7, leaf3, leaf4);
|
||||||
|
TreeNode nodeLeft = new TreeNode(2, leaf1, leaf2);
|
||||||
|
|
||||||
|
TreeNode root = new TreeNode(4, nodeLeft, nodeRight);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
4
algorithms-miscellaneous-3/.gitignore
vendored
Normal file
4
algorithms-miscellaneous-3/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/target/
|
||||||
|
.settings/
|
||||||
|
.classpath
|
||||||
|
.project
|
6
algorithms-miscellaneous-3/README.md
Normal file
6
algorithms-miscellaneous-3/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
|
||||||
|
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
|
||||||
|
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
|
||||||
|
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
|
39
algorithms-miscellaneous-3/pom.xml
Normal file
39
algorithms-miscellaneous-3/pom.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<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>algorithms-miscellaneous-3</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>algorithms-miscellaneous-3</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${org.assertj.core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>${exec-maven-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,14 @@
|
|||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.antlr</groupId>
|
||||||
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
|
<version>${antlr.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@ -44,13 +52,7 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.antlr</groupId>
|
|
||||||
<artifactId>antlr4-runtime</artifactId>
|
|
||||||
<version>${antlr.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<properties>
|
<properties>
|
||||||
<antlr.version>4.7.1</antlr.version>
|
<antlr.version>4.7.1</antlr.version>
|
||||||
<mojo.version>3.0.0</mojo.version>
|
<mojo.version>3.0.0</mojo.version>
|
||||||
|
@ -12,9 +12,18 @@
|
|||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<dependencies>
|
||||||
<cxf-version>3.2.0</cxf-version>
|
<dependency>
|
||||||
</properties>
|
<groupId>org.apache.cxf</groupId>
|
||||||
|
<artifactId>cxf-rt-rs-client</artifactId>
|
||||||
|
<version>${cxf-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cxf</groupId>
|
||||||
|
<artifactId>cxf-rt-rs-sse</artifactId>
|
||||||
|
<version>${cxf-version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
@ -45,17 +54,8 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<properties>
|
||||||
<dependency>
|
<cxf-version>3.2.0</cxf-version>
|
||||||
<groupId>org.apache.cxf</groupId>
|
</properties>
|
||||||
<artifactId>cxf-rt-rs-client</artifactId>
|
|
||||||
<version>${cxf-version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.cxf</groupId>
|
|
||||||
<artifactId>cxf-rt-rs-sse</artifactId>
|
|
||||||
<version>${cxf-version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -13,11 +13,28 @@
|
|||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<dependencies>
|
||||||
<liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version>
|
|
||||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
<dependency>
|
||||||
<openliberty-version>18.0.0.2</openliberty-version>
|
<groupId>javax.ws.rs</groupId>
|
||||||
</properties>
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.enterprise</groupId>
|
||||||
|
<artifactId>cdi-api</artifactId>
|
||||||
|
<version>2.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.json.bind</groupId>
|
||||||
|
<artifactId>javax.json.bind-api</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>${project.artifactId}</finalName>
|
<finalName>${project.artifactId}</finalName>
|
||||||
@ -59,27 +76,10 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<properties>
|
||||||
|
<liberty-maven-plugin.version>2.4.2</liberty-maven-plugin.version>
|
||||||
<dependency>
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
<groupId>javax.ws.rs</groupId>
|
<openliberty-version>18.0.0.2</openliberty-version>
|
||||||
<artifactId>javax.ws.rs-api</artifactId>
|
</properties>
|
||||||
<version>2.1</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.enterprise</groupId>
|
|
||||||
<artifactId>cdi-api</artifactId>
|
|
||||||
<version>2.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.json.bind</groupId>
|
|
||||||
<artifactId>javax.json.bind-api</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,7 +3,3 @@
|
|||||||
## Core Java Cookbooks and Examples
|
## Core Java Cookbooks and Examples
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
|
||||||
- [Java - Reading a Large File Efficiently](http://www.baeldung.com/java-read-lines-large-file)
|
|
||||||
- [Java InputStream to String](http://www.baeldung.com/convert-input-stream-to-string)
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class GeodeSamplesIntegrationTest {
|
public class GeodeSamplesLiveTest {
|
||||||
|
|
||||||
ClientCache cache = null;
|
ClientCache cache = null;
|
||||||
Region<String, String> region = null;
|
Region<String, String> region = null;
|
@ -7,6 +7,12 @@
|
|||||||
<name>apache-meecrowave</name>
|
<name>apache-meecrowave</name>
|
||||||
<description>A sample REST API application with Meecrowave</description>
|
<description>A sample REST API application with Meecrowave</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-core -->
|
<!-- https://mvnrepository.com/artifact/org.apache.meecrowave/meecrowave-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -54,7 +60,6 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<junit.version>4.10</junit.version>
|
|
||||||
<meecrowave-junit.version>1.2.0</meecrowave-junit.version>
|
<meecrowave-junit.version>1.2.0</meecrowave-junit.version>
|
||||||
<okhttp.version>3.10.0</okhttp.version>
|
<okhttp.version>3.10.0</okhttp.version>
|
||||||
<meecrowave-jpa.version>1.2.1</meecrowave-jpa.version>
|
<meecrowave-jpa.version>1.2.1</meecrowave-jpa.version>
|
||||||
|
@ -17,7 +17,7 @@ import okhttp3.Request;
|
|||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
|
||||||
@RunWith(MonoMeecrowave.Runner.class)
|
@RunWith(MonoMeecrowave.Runner.class)
|
||||||
public class ArticleEndpointsTest {
|
public class ArticleEndpointsUnitTest {
|
||||||
|
|
||||||
@ConfigurationInject
|
@ConfigurationInject
|
||||||
private Meecrowave.Builder config;
|
private Meecrowave.Builder config;
|
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)
|
21
apache-olingo/Samples.md
Normal file
21
apache-olingo/Samples.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
## OData test URLs
|
||||||
|
|
||||||
|
This following table contains test URLs that can be used with the Olingo V2 demo project.
|
||||||
|
|
||||||
|
| URL | Description |
|
||||||
|
|------------------------------------------|-------------------------------------------------|
|
||||||
|
| `http://localhost:8180/odata/$metadata` | fetch OData metadata document |
|
||||||
|
| `http://localhost:8180/odata/CarMakers?$top=10&$skip=10` | Get 10 entities starting at offset 10 |
|
||||||
|
| `http://localhost:8180/odata/CarMakers?$count` | Return total count of entities in this set |
|
||||||
|
| `http://localhost:8180/odata/CarMakers?$filter=startswith(Name,'B')` | Return entities where the *Name* property starts with 'B' |
|
||||||
|
| `http://localhost:8180/odata/CarModels?$filter=Year eq 2008 and CarMakerDetails/Name eq 'BWM'` | Return *CarModel* entities where the *Name* property of its maker starts with 'B' |
|
||||||
|
| `http://localhost:8180/odata/CarModels(1L)?$expand=CarMakerDetails` | Return the *CarModel* with primary key '1', along with its maker|
|
||||||
|
| `http://localhost:8180/odata/CarModels(1L)?$select=Name,Sku` | Return the *CarModel* with primary key '1', returing only its *Name* and *Sku* properties |
|
||||||
|
| `http://localhost:8180/odata/CarModels?$orderBy=Name asc,Sku desc` | Return *CarModel* entities, ordered by the their *Name* and *Sku* properties |
|
||||||
|
| `http://localhost:8180/odata/CarModels?$format=json` | Return *CarModel* entities, using a JSON representation|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
29
apache-olingo/olingo2/.gitignore
vendored
Normal file
29
apache-olingo/olingo2/.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
HELP.md
|
||||||
|
/target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
93
apache-olingo/olingo2/pom.xml
Normal file
93
apache-olingo/olingo2/pom.xml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>org.baeldung.examples.olingo2</groupId>
|
||||||
|
<artifactId>olingo2-sample</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>olingo2-sample</name>
|
||||||
|
<description>Sample Olingo 2 Project</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<olingo2.version>2.0.11</olingo2.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jersey</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Olingo 2 Dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.olingo</groupId>
|
||||||
|
<artifactId>olingo-odata2-core</artifactId>
|
||||||
|
<version>${olingo2.version}</version>
|
||||||
|
<!-- Avoid jax-rs version conflict by excluding Olingo's version -->
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>javax.ws.rs</groupId>
|
||||||
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.olingo</groupId>
|
||||||
|
<artifactId>olingo-odata2-jpa-processor-core</artifactId>
|
||||||
|
<version>${olingo2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.olingo</groupId>
|
||||||
|
<artifactId>olingo-odata2-jpa-processor-ref</artifactId>
|
||||||
|
<version>${olingo2.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.eclipse.persistence</groupId>
|
||||||
|
<artifactId>eclipselink</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,298 @@
|
|||||||
|
package org.baeldung.examples.olingo2;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.persistence.EntityGraph;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.persistence.FlushModeType;
|
||||||
|
import javax.persistence.LockModeType;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import javax.persistence.StoredProcedureQuery;
|
||||||
|
import javax.persistence.SynchronizationType;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
|
import javax.persistence.criteria.CriteriaDelete;
|
||||||
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.CriteriaUpdate;
|
||||||
|
import javax.persistence.metamodel.Metamodel;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.apache.olingo.odata2.api.processor.ODataContext;
|
||||||
|
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
|
||||||
|
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory;
|
||||||
|
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
|
||||||
|
import org.baeldung.examples.olingo2.JerseyConfig.EntityManagerFilter;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||||
|
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ODataJPAServiceFactory implementation for our sample domain
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CarsODataJPAServiceFactory.class);
|
||||||
|
|
||||||
|
public CarsODataJPAServiceFactory() {
|
||||||
|
// Enable detailed error messages (useful for debugging)
|
||||||
|
setDetailErrors(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be called by Olingo on every request to
|
||||||
|
* initialize the ODataJPAContext that will be used.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException {
|
||||||
|
|
||||||
|
log.info("[I32] >>> initializeODataJPAContext()");
|
||||||
|
ODataJPAContext ctx = getODataJPAContext();
|
||||||
|
ODataContext octx = ctx.getODataContext();
|
||||||
|
HttpServletRequest request = (HttpServletRequest)octx.getParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT);
|
||||||
|
EntityManager em = (EntityManager)request.getAttribute(EntityManagerFilter.EM_REQUEST_ATTRIBUTE);
|
||||||
|
|
||||||
|
// Here we're passing the EM that was created by the EntityManagerFilter (see JerseyConfig)
|
||||||
|
ctx.setEntityManager(new EntityManagerWrapper(em));
|
||||||
|
ctx.setPersistenceUnitName("default");
|
||||||
|
|
||||||
|
// We're managing the EM's lifecycle, so we must inform Olingo that it should not
|
||||||
|
// try to manage transactions and/or persistence sessions
|
||||||
|
ctx.setContainerManaged(true);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class EntityManagerWrapper implements EntityManager {
|
||||||
|
|
||||||
|
private EntityManager delegate;
|
||||||
|
|
||||||
|
public void persist(Object entity) {
|
||||||
|
log.info("[I68] persist: entity.class=" + entity.getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
delegate.persist(entity);
|
||||||
|
// delegate.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T merge(T entity) {
|
||||||
|
log.info("[I74] merge: entity.class=" + entity.getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
return delegate.merge(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Object entity) {
|
||||||
|
log.info("[I78] remove: entity.class=" + entity.getClass()
|
||||||
|
.getSimpleName());
|
||||||
|
delegate.remove(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T find(Class<T> entityClass, Object primaryKey) {
|
||||||
|
return delegate.find(entityClass, primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
|
||||||
|
return delegate.find(entityClass, primaryKey, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) {
|
||||||
|
return delegate.find(entityClass, primaryKey, lockMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) {
|
||||||
|
return delegate.find(entityClass, primaryKey, lockMode, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getReference(Class<T> entityClass, Object primaryKey) {
|
||||||
|
return delegate.getReference(entityClass, primaryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() {
|
||||||
|
delegate.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlushMode(FlushModeType flushMode) {
|
||||||
|
delegate.setFlushMode(flushMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlushModeType getFlushMode() {
|
||||||
|
return delegate.getFlushMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lock(Object entity, LockModeType lockMode) {
|
||||||
|
delegate.lock(entity, lockMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) {
|
||||||
|
delegate.lock(entity, lockMode, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(Object entity) {
|
||||||
|
delegate.refresh(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(Object entity, Map<String, Object> properties) {
|
||||||
|
delegate.refresh(entity, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(Object entity, LockModeType lockMode) {
|
||||||
|
delegate.refresh(entity, lockMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refresh(Object entity, LockModeType lockMode, Map<String, Object> properties) {
|
||||||
|
delegate.refresh(entity, lockMode, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
delegate.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detach(Object entity) {
|
||||||
|
delegate.detach(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object entity) {
|
||||||
|
return delegate.contains(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockModeType getLockMode(Object entity) {
|
||||||
|
return delegate.getLockMode(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(String propertyName, Object value) {
|
||||||
|
delegate.setProperty(propertyName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getProperties() {
|
||||||
|
return delegate.getProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createQuery(String qlString) {
|
||||||
|
return delegate.createQuery(qlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
|
||||||
|
return delegate.createQuery(criteriaQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createQuery(CriteriaUpdate updateQuery) {
|
||||||
|
return delegate.createQuery(updateQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createQuery(CriteriaDelete deleteQuery) {
|
||||||
|
return delegate.createQuery(deleteQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass) {
|
||||||
|
return delegate.createQuery(qlString, resultClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createNamedQuery(String name) {
|
||||||
|
return delegate.createNamedQuery(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) {
|
||||||
|
return delegate.createNamedQuery(name, resultClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createNativeQuery(String sqlString) {
|
||||||
|
return delegate.createNativeQuery(sqlString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createNativeQuery(String sqlString, Class resultClass) {
|
||||||
|
return delegate.createNativeQuery(sqlString, resultClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query createNativeQuery(String sqlString, String resultSetMapping) {
|
||||||
|
return delegate.createNativeQuery(sqlString, resultSetMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StoredProcedureQuery createNamedStoredProcedureQuery(String name) {
|
||||||
|
return delegate.createNamedStoredProcedureQuery(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StoredProcedureQuery createStoredProcedureQuery(String procedureName) {
|
||||||
|
return delegate.createStoredProcedureQuery(procedureName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) {
|
||||||
|
return delegate.createStoredProcedureQuery(procedureName, resultClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) {
|
||||||
|
return delegate.createStoredProcedureQuery(procedureName, resultSetMappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void joinTransaction() {
|
||||||
|
delegate.joinTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isJoinedToTransaction() {
|
||||||
|
return delegate.isJoinedToTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T unwrap(Class<T> cls) {
|
||||||
|
return delegate.unwrap(cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getDelegate() {
|
||||||
|
return delegate.getDelegate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
log.info("[I229] close");
|
||||||
|
delegate.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOpen() {
|
||||||
|
boolean isOpen = delegate.isOpen();
|
||||||
|
log.info("[I236] isOpen: " + isOpen);
|
||||||
|
return isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTransaction getTransaction() {
|
||||||
|
log.info("[I240] getTransaction()");
|
||||||
|
return delegate.getTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityManagerFactory getEntityManagerFactory() {
|
||||||
|
return delegate.getEntityManagerFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CriteriaBuilder getCriteriaBuilder() {
|
||||||
|
return delegate.getCriteriaBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Metamodel getMetamodel() {
|
||||||
|
return delegate.getMetamodel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> EntityGraph<T> createEntityGraph(Class<T> rootType) {
|
||||||
|
return delegate.createEntityGraph(rootType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityGraph<?> createEntityGraph(String graphName) {
|
||||||
|
return delegate.createEntityGraph(graphName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityGraph<?> getEntityGraph(String graphName) {
|
||||||
|
return delegate.getEntityGraph(graphName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass) {
|
||||||
|
return delegate.getEntityGraphs(entityClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityManagerWrapper(EntityManager delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
package org.baeldung.examples.olingo2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.EntityTransaction;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.container.ContainerRequestContext;
|
||||||
|
import javax.ws.rs.container.ContainerRequestFilter;
|
||||||
|
import javax.ws.rs.container.ContainerResponseContext;
|
||||||
|
import javax.ws.rs.container.ContainerResponseFilter;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
import org.apache.olingo.odata2.api.ODataServiceFactory;
|
||||||
|
import org.apache.olingo.odata2.core.rest.ODataRootLocator;
|
||||||
|
import org.apache.olingo.odata2.core.rest.app.ODataApplication;
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jersey JAX-RS configuration
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ApplicationPath("/odata")
|
||||||
|
public class JerseyConfig extends ResourceConfig {
|
||||||
|
|
||||||
|
|
||||||
|
public JerseyConfig(CarsODataJPAServiceFactory serviceFactory, EntityManagerFactory emf) {
|
||||||
|
|
||||||
|
ODataApplication app = new ODataApplication();
|
||||||
|
|
||||||
|
app
|
||||||
|
.getClasses()
|
||||||
|
.forEach( c -> {
|
||||||
|
// Avoid using the default RootLocator, as we want
|
||||||
|
// a Spring Managed one
|
||||||
|
if ( !ODataRootLocator.class.isAssignableFrom(c)) {
|
||||||
|
register(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
register(new CarsRootLocator(serviceFactory));
|
||||||
|
register( new EntityManagerFilter(emf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This filter handles the EntityManager transaction lifecycle.
|
||||||
|
* @author Philippe
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Provider
|
||||||
|
public static class EntityManagerFilter implements ContainerRequestFilter, ContainerResponseFilter {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(EntityManagerFilter.class);
|
||||||
|
public static final String EM_REQUEST_ATTRIBUTE = EntityManagerFilter.class.getName() + "_ENTITY_MANAGER";
|
||||||
|
|
||||||
|
private final EntityManagerFactory emf;
|
||||||
|
|
||||||
|
@Context
|
||||||
|
private HttpServletRequest httpRequest;
|
||||||
|
|
||||||
|
public EntityManagerFilter(EntityManagerFactory emf) {
|
||||||
|
this.emf = emf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filter(ContainerRequestContext ctx) throws IOException {
|
||||||
|
log.info("[I60] >>> filter");
|
||||||
|
EntityManager em = this.emf.createEntityManager();
|
||||||
|
httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, em);
|
||||||
|
|
||||||
|
// Start a new transaction unless we have a simple GET
|
||||||
|
if (!"GET".equalsIgnoreCase(ctx.getMethod())) {
|
||||||
|
em.getTransaction()
|
||||||
|
.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
|
||||||
|
|
||||||
|
log.info("[I68] <<< filter");
|
||||||
|
EntityManager em = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE);
|
||||||
|
|
||||||
|
if (!"GET".equalsIgnoreCase(requestContext.getMethod())) {
|
||||||
|
EntityTransaction t = em.getTransaction();
|
||||||
|
if (t.isActive()) {
|
||||||
|
if (!t.getRollbackOnly()) {
|
||||||
|
t.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
em.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Path("/")
|
||||||
|
public static class CarsRootLocator extends ODataRootLocator {
|
||||||
|
|
||||||
|
private CarsODataJPAServiceFactory serviceFactory;
|
||||||
|
|
||||||
|
public CarsRootLocator(CarsODataJPAServiceFactory serviceFactory) {
|
||||||
|
this.serviceFactory = serviceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ODataServiceFactory getServiceFactory() {
|
||||||
|
return this.serviceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package org.baeldung.examples.olingo2;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Olingo2SampleApplication extends SpringBootServletInitializer {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Olingo2SampleApplication.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
package org.baeldung.examples.olingo2.domain;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "car_maker")
|
||||||
|
public class CarMaker {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "maker", orphanRemoval = true, cascade = CascadeType.ALL)
|
||||||
|
private List<CarModel> models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the models
|
||||||
|
*/
|
||||||
|
public List<CarModel> getModels() {
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param models the models to set
|
||||||
|
*/
|
||||||
|
public void setModels(List<CarModel> models) {
|
||||||
|
this.models = models;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||||
|
result = prime * result + ((models == null) ? 0 : models.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
CarMaker other = (CarMaker) obj;
|
||||||
|
if (id == null) {
|
||||||
|
if (other.id != null)
|
||||||
|
return false;
|
||||||
|
} else if (!id.equals(other.id))
|
||||||
|
return false;
|
||||||
|
if (models == null) {
|
||||||
|
if (other.models != null)
|
||||||
|
return false;
|
||||||
|
} else if (!models.equals(other.models))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,159 @@
|
|||||||
|
package org.baeldung.examples.olingo2.domain;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "car_model")
|
||||||
|
public class CarModel {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Integer year;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String sku;
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "maker_fk")
|
||||||
|
private CarMaker maker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the year
|
||||||
|
*/
|
||||||
|
public Integer getYear() {
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param year the year to set
|
||||||
|
*/
|
||||||
|
public void setYear(Integer year) {
|
||||||
|
this.year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sku
|
||||||
|
*/
|
||||||
|
public String getSku() {
|
||||||
|
return sku;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sku the sku to set
|
||||||
|
*/
|
||||||
|
public void setSku(String sku) {
|
||||||
|
this.sku = sku;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maker
|
||||||
|
*/
|
||||||
|
public CarMaker getMaker() {
|
||||||
|
return maker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maker the maker to set
|
||||||
|
*/
|
||||||
|
public void setMaker(CarMaker maker) {
|
||||||
|
this.maker = maker;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||||
|
result = prime * result + ((maker == null) ? 0 : maker.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + ((sku == null) ? 0 : sku.hashCode());
|
||||||
|
result = prime * result + ((year == null) ? 0 : year.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
CarModel other = (CarModel) obj;
|
||||||
|
if (id == null) {
|
||||||
|
if (other.id != null)
|
||||||
|
return false;
|
||||||
|
} else if (!id.equals(other.id))
|
||||||
|
return false;
|
||||||
|
if (maker == null) {
|
||||||
|
if (other.maker != null)
|
||||||
|
return false;
|
||||||
|
} else if (!maker.equals(other.maker))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
if (sku == null) {
|
||||||
|
if (other.sku != null)
|
||||||
|
return false;
|
||||||
|
} else if (!sku.equals(other.sku))
|
||||||
|
return false;
|
||||||
|
if (year == null) {
|
||||||
|
if (other.year != null)
|
||||||
|
return false;
|
||||||
|
} else if (!year.equals(other.year))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
apache-olingo/olingo2/src/main/resources/application.yml
Normal file
12
apache-olingo/olingo2/src/main/resources/application.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
spring:
|
||||||
|
jersey:
|
||||||
|
application-path: /odata
|
||||||
|
|
||||||
|
jpa:
|
||||||
|
show-sql: true
|
||||||
|
open-in-view: false
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: update
|
12
apache-olingo/olingo2/src/main/resources/data.sql
Normal file
12
apache-olingo/olingo2/src/main/resources/data.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
insert into car_maker(id,name) values (1,'Special Motors');
|
||||||
|
insert into car_maker(id,name) values (2,'BWM');
|
||||||
|
insert into car_maker(id,name) values (3,'Dolores');
|
||||||
|
|
||||||
|
insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018);
|
||||||
|
insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008);
|
||||||
|
|
||||||
|
insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008);
|
||||||
|
insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009);
|
||||||
|
insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008);
|
||||||
|
|
||||||
|
alter sequence hibernate_sequence restart with 100;
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.baeldung.examples.olingo2;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class Olingo2SampleApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
256
apache-olingo/olingo2/src/test/resources/olingo2-queries.json
Normal file
256
apache-olingo/olingo2/src/test/resources/olingo2-queries.json
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "afa8e1e5-ab0e-4f1d-8b99-b7d1f091f975",
|
||||||
|
"name": "OLingo2 - Cars",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "GET Metadata",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/$metadata"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GET All CarMakers",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarMakers"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GET Makers with Pagination",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/odata/CarMakers?$top=1&$orderby=Name&$skip=3",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"odata",
|
||||||
|
"CarMakers"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "$top",
|
||||||
|
"value": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "$orderby",
|
||||||
|
"value": "Name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "$skip",
|
||||||
|
"value": "3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GET Makers and Models",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/odata/CarMakers?$expand=CarModelDetails",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"odata",
|
||||||
|
"CarMakers"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "$expand",
|
||||||
|
"value": "CarModelDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GET Makers with filter",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/json",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "http://localhost:8080/odata/CarMakers?$filter=Name eq 'BWM'&$expand=CarModelDetails",
|
||||||
|
"protocol": "http",
|
||||||
|
"host": [
|
||||||
|
"localhost"
|
||||||
|
],
|
||||||
|
"port": "8080",
|
||||||
|
"path": [
|
||||||
|
"odata",
|
||||||
|
"CarMakers"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "$filter",
|
||||||
|
"value": "Name eq 'BWM'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "$expand",
|
||||||
|
"value": "CarModelDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Create CarMaker",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"name": "Content-Type",
|
||||||
|
"value": "application/atom+xml",
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"value": "application/atom+xml",
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \r\n<entry xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"\r\n xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" \r\n xmlns=\"http://www.w3.org/2005/Atom\">\r\n <title type=\"text\"></title> \r\n <updated>2019-04-02T21:36:47Z</updated>\r\n <author> \r\n <name /> \r\n </author> \r\n <category term=\"default.CarMaker\"\r\n scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" /> \r\n <content type=\"application/xml\"> \r\n <m:properties>\r\n <d:Name>Lucien</d:Name>\r\n </m:properties> \r\n </content> \r\n</entry>"
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarMakers"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Create CarModel",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"name": "Content-Type",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \r\n<entry xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"\r\n xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" \r\n xmlns=\"http://www.w3.org/2005/Atom\">\r\n <title type=\"text\"></title> \r\n <updated>2019-04-02T21:36:47Z</updated>\r\n <author> \r\n <name /> \r\n </author> \r\n <link href=\"CarModels(1L)/CarMakerDetails\" \r\n rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/CarMakerDetails\" \r\n title=\"CarMakerDetails\" \r\n type=\"application/atom+xml;type=entry\"></link> \r\n <category term=\"default.CarModel\"\r\n scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" /> \r\n <content type=\"application/xml\"> \r\n <m:properties>\r\n\t <d:Name>Tata</d:Name>\r\n\t <d:Sku>TT101</d:Sku>\r\n\t <d:Year>2018</d:Year>\r\n </m:properties> \r\n </content> \r\n</entry>"
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarModels"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Update CarMaker",
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"name": "Content-Type",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "<?xml version=\"1.0\" encoding=\"utf-8\" ?> \r\n<entry xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\"\r\n xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" \r\n xmlns=\"http://www.w3.org/2005/Atom\">\r\n <title type=\"text\"></title> \r\n <updated>2019-04-02T21:36:47Z</updated>\r\n <author> \r\n <name /> \r\n </author> \r\n <category term=\"default.CarMaker\"\r\n scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\" /> \r\n <content type=\"application/xml\"> \r\n <m:properties>\r\n <d:Id>5</d:Id>\r\n <d:Name>KaiserWagen</d:Name>\r\n </m:properties> \r\n </content> \r\n</entry>"
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarMakers(5L)"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "All CarModels",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarModels"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete CarModel",
|
||||||
|
"request": {
|
||||||
|
"method": "DELETE",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"name": "Content-Type",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "Accept",
|
||||||
|
"type": "text",
|
||||||
|
"value": "application/atom+xml"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": ""
|
||||||
|
},
|
||||||
|
"url": "http://localhost:8080/odata/CarModels(100L)"
|
||||||
|
},
|
||||||
|
"response": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -59,7 +59,6 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<jstl.version>1.2</jstl.version>
|
|
||||||
<org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version>
|
<org.apache.httpcomponents.version>4.5.2</org.apache.httpcomponents.version>
|
||||||
<velocity-version>1.7</velocity-version>
|
<velocity-version>1.7</velocity-version>
|
||||||
<velocity-tools-version>2.0</velocity-tools-version>
|
<velocity-tools-version>2.0</velocity-tools-version>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.baeldung.autofactory.provided;
|
package com.baeldung.autofactory.provided;
|
||||||
|
|
||||||
|
import com.baeldung.autofactory.model.Camera;
|
||||||
import com.google.auto.factory.AutoFactory;
|
import com.google.auto.factory.AutoFactory;
|
||||||
import com.google.auto.factory.Provided;
|
import com.google.auto.factory.Provided;
|
||||||
import javafx.scene.Camera;
|
|
||||||
|
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
- [AWS S3 with Java](http://www.baeldung.com/aws-s3-java)
|
- [AWS S3 with Java](http://www.baeldung.com/aws-s3-java)
|
||||||
- [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda)
|
- [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda)
|
||||||
- [Managing EC2 Instances in Java](http://www.baeldung.com/ec2-java)
|
- [Managing EC2 Instances in Java](http://www.baeldung.com/ec2-java)
|
||||||
- [http://www.baeldung.com/aws-s3-multipart-upload](https://github.com/eugenp/tutorials/tree/master/aws)
|
|
||||||
- [Multipart Uploads in Amazon S3 with Java](http://www.baeldung.com/aws-s3-multipart-upload)
|
- [Multipart Uploads in Amazon S3 with Java](http://www.baeldung.com/aws-s3-multipart-upload)
|
||||||
- [Integration Testing with a Local DynamoDB Instance](http://www.baeldung.com/dynamodb-local-integration-tests)
|
- [Integration Testing with a Local DynamoDB Instance](http://www.baeldung.com/dynamodb-local-integration-tests)
|
||||||
- [Using the JetS3t Java Client With Amazon S3](http://www.baeldung.com/jets3t-amazon-s3)
|
- [Using the JetS3t Java Client With Amazon S3](http://www.baeldung.com/jets3t-amazon-s3)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Deploy Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure)
|
- [Deploy a Spring Boot App to Azure](http://www.baeldung.com/spring-boot-azure)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Blade - A Complete GuideBook](http://www.baeldung.com/blade)
|
- [Blade – A Complete Guidebook](http://www.baeldung.com/blade)
|
||||||
|
|
||||||
Run Integration Tests with `mvn integration-test`
|
Run Integration Tests with `mvn integration-test`
|
21
cas/pom.xml
Normal file
21
cas/pom.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>cas</artifactId>
|
||||||
|
<name>cas</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>..</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>cas-secured-app</module>
|
||||||
|
<module>cas-server</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
</project>
|
@ -27,7 +27,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-core</artifactId>
|
<artifactId>hamcrest-core</artifactId>
|
||||||
<version>${hamcrest-core.version}</version>
|
<version>${org.hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -64,7 +64,6 @@
|
|||||||
<cdi-api.version>2.0.SP1</cdi-api.version>
|
<cdi-api.version>2.0.SP1</cdi-api.version>
|
||||||
<weld-se-core.version>3.0.5.Final</weld-se-core.version>
|
<weld-se-core.version>3.0.5.Final</weld-se-core.version>
|
||||||
<aspectjweaver.version>1.9.2</aspectjweaver.version>
|
<aspectjweaver.version>1.9.2</aspectjweaver.version>
|
||||||
<hamcrest-core.version>1.3</hamcrest-core.version>
|
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
<spring.version>5.1.2.RELEASE</spring.version>
|
<spring.version>5.1.2.RELEASE</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
12
clojure/ring/.gitignore
vendored
Normal file
12
clojure/ring/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/target
|
||||||
|
/classes
|
||||||
|
/checkouts
|
||||||
|
profiles.clj
|
||||||
|
pom.xml
|
||||||
|
pom.xml.asc
|
||||||
|
*.jar
|
||||||
|
*.class
|
||||||
|
/.lein-*
|
||||||
|
/.nrepl-port
|
||||||
|
.hgignore
|
||||||
|
.hg/
|
19
clojure/ring/README.md
Normal file
19
clojure/ring/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Clojure Ring Examples
|
||||||
|
|
||||||
|
This project acts as a set of examples for the Clojure Ring library.
|
||||||
|
|
||||||
|
## Runing the examples
|
||||||
|
|
||||||
|
The examples can all be run from the Leiningen REPL.
|
||||||
|
|
||||||
|
Firstly, start the REPL with `lein repl`. Then the examples can be executed with:
|
||||||
|
|
||||||
|
* `(run simple-handler)` - A simple handler that just echos a constant string to the client
|
||||||
|
* `(run check-ip-handler)` - A handler that echos the clients IP Address back to them
|
||||||
|
* `(run echo-handler)` - A handler that echos the value of the "input" parameter back
|
||||||
|
* `(run request-count-handler)` - A handler with a session that tracks how many times this session has requested this handler
|
||||||
|
|
||||||
|
In all cases, the handlers can be accessed on http://localhost:3000.
|
||||||
|
|
||||||
|
## Relevant Articles
|
||||||
|
- [Writing Clojure Webapps with Ring](https://www.baeldung.com/clojure-ring)
|
8
clojure/ring/project.clj
Normal file
8
clojure/ring/project.clj
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
(defproject baeldung-ring "0.1.0-SNAPSHOT"
|
||||||
|
:dependencies [[org.clojure/clojure "1.10.0"]
|
||||||
|
[ring/ring-core "1.7.1"]
|
||||||
|
[ring/ring-jetty-adapter "1.7.1"]
|
||||||
|
[ring/ring-devel "1.7.1"]]
|
||||||
|
:plugins [[lein-ring "0.12.5"]]
|
||||||
|
:ring {:handler ring.core/simple-handler}
|
||||||
|
:repl-options {:init-ns ring.core})
|
48
clojure/ring/src/ring/core.clj
Normal file
48
clojure/ring/src/ring/core.clj
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
(ns ring.core
|
||||||
|
(:use ring.adapter.jetty
|
||||||
|
[ring.middleware.content-type]
|
||||||
|
[ring.middleware.cookies]
|
||||||
|
[ring.middleware.params]
|
||||||
|
[ring.middleware.session]
|
||||||
|
[ring.middleware.session.cookie]
|
||||||
|
[ring.util.response]))
|
||||||
|
|
||||||
|
;; Handler that just echos back the string "Hello World"
|
||||||
|
(defn simple-handler [request]
|
||||||
|
{:status 200
|
||||||
|
:headers {"Content-Type" "text/plain"}
|
||||||
|
:body "Hello World"})
|
||||||
|
|
||||||
|
;; Handler that echos back the clients IP Address
|
||||||
|
;; This demonstrates building responses properly, and extracting values from the request
|
||||||
|
(defn check-ip-handler [request]
|
||||||
|
(content-type
|
||||||
|
(response (:remote-addr request))
|
||||||
|
"text/plain"))
|
||||||
|
|
||||||
|
;; Handler that echos back the incoming parameter "input"
|
||||||
|
;; This demonstrates middleware chaining and accessing parameters
|
||||||
|
(def echo-handler
|
||||||
|
(-> (fn [{params :params}]
|
||||||
|
(content-type
|
||||||
|
(response (get params "input"))
|
||||||
|
"text/plain"))
|
||||||
|
(wrap-params {:encoding "UTF-8"})
|
||||||
|
))
|
||||||
|
|
||||||
|
;; Handler that keeps track of how many times each session has accessed the service
|
||||||
|
;; This demonstrates cookies and sessions
|
||||||
|
(def request-count-handler
|
||||||
|
(-> (fn [{session :session}]
|
||||||
|
(let [count (:count session 0)
|
||||||
|
session (assoc session :count (inc count))]
|
||||||
|
(-> (response (str "You accessed this page " count " times."))
|
||||||
|
(assoc :session session))))
|
||||||
|
wrap-cookies
|
||||||
|
(wrap-session {:cookie-attrs {:max-age 3600}})
|
||||||
|
))
|
||||||
|
|
||||||
|
;; Run the provided handler on port 3000
|
||||||
|
(defn run
|
||||||
|
[h]
|
||||||
|
(run-jetty h {:port 3000}))
|
3
cloud-foundry-uaa/README.md
Normal file
3
cloud-foundry-uaa/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
### Revelant Articles
|
||||||
|
|
||||||
|
- [A Quick Guide To Using Cloud Foundry UAA](https://www.baeldung.com/cloud-foundry-uaa)
|
68
cloud-foundry-uaa/cf-uaa-config/uaa.yml
Normal file
68
cloud-foundry-uaa/cf-uaa-config/uaa.yml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
issuer:
|
||||||
|
uri: http://localhost:8080/uaa
|
||||||
|
|
||||||
|
spring_profiles: default,hsqldb
|
||||||
|
|
||||||
|
encryption:
|
||||||
|
active_key_label: CHANGE-THIS-KEY
|
||||||
|
encryption_keys:
|
||||||
|
- label: CHANGE-THIS-KEY
|
||||||
|
passphrase: CHANGEME
|
||||||
|
|
||||||
|
login:
|
||||||
|
serviceProviderKey: |
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXQIBAAKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5
|
||||||
|
L39WqS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vA
|
||||||
|
fpOwznoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQAB
|
||||||
|
AoGAVOj2Yvuigi6wJD99AO2fgF64sYCm/BKkX3dFEw0vxTPIh58kiRP554Xt5ges
|
||||||
|
7ZCqL9QpqrChUikO4kJ+nB8Uq2AvaZHbpCEUmbip06IlgdA440o0r0CPo1mgNxGu
|
||||||
|
lhiWRN43Lruzfh9qKPhleg2dvyFGQxy5Gk6KW/t8IS4x4r0CQQD/dceBA+Ndj3Xp
|
||||||
|
ubHfxqNz4GTOxndc/AXAowPGpge2zpgIc7f50t8OHhG6XhsfJ0wyQEEvodDhZPYX
|
||||||
|
kKBnXNHzAkEAyCA76vAwuxqAd3MObhiebniAU3SnPf2u4fdL1EOm92dyFs1JxyyL
|
||||||
|
gu/DsjPjx6tRtn4YAalxCzmAMXFSb1qHfwJBAM3qx3z0gGKbUEWtPHcP7BNsrnWK
|
||||||
|
vw6By7VC8bk/ffpaP2yYspS66Le9fzbFwoDzMVVUO/dELVZyBnhqSRHoXQcCQQCe
|
||||||
|
A2WL8S5o7Vn19rC0GVgu3ZJlUrwiZEVLQdlrticFPXaFrn3Md82ICww3jmURaKHS
|
||||||
|
N+l4lnMda79eSp3OMmq9AkA0p79BvYsLshUJJnvbk76pCjR28PK4dV1gSDUEqQMB
|
||||||
|
qy45ptdwJLqLJCeNoR0JUcDNIRhOCuOPND7pcMtX6hI/
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
serviceProviderKeyPassword: password
|
||||||
|
serviceProviderCertificate: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDSTCCArKgAwIBAgIBADANBgkqhkiG9w0BAQQFADB8MQswCQYDVQQGEwJhdzEO
|
||||||
|
MAwGA1UECBMFYXJ1YmExDjAMBgNVBAoTBWFydWJhMQ4wDAYDVQQHEwVhcnViYTEO
|
||||||
|
MAwGA1UECxMFYXJ1YmExDjAMBgNVBAMTBWFydWJhMR0wGwYJKoZIhvcNAQkBFg5h
|
||||||
|
cnViYUBhcnViYS5hcjAeFw0xNTExMjAyMjI2MjdaFw0xNjExMTkyMjI2MjdaMHwx
|
||||||
|
CzAJBgNVBAYTAmF3MQ4wDAYDVQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAM
|
||||||
|
BgNVBAcTBWFydWJhMQ4wDAYDVQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAb
|
||||||
|
BgkqhkiG9w0BCQEWDmFydWJhQGFydWJhLmFyMIGfMA0GCSqGSIb3DQEBAQUAA4GN
|
||||||
|
ADCBiQKBgQDHtC5gUXxBKpEqZTLkNvFwNGnNIkggNOwOQVNbpO0WVHIivig5L39W
|
||||||
|
qS9u0hnA+O7MCA/KlrAR4bXaeVVhwfUPYBKIpaaTWFQR5cTR1UFZJL/OF9vAfpOw
|
||||||
|
znoD66DDCnQVpbCjtDYWX+x6imxn8HCYxhMol6ZnTbSsFW6VZjFMjQIDAQABo4Ha
|
||||||
|
MIHXMB0GA1UdDgQWBBTx0lDzjH/iOBnOSQaSEWQLx1syGDCBpwYDVR0jBIGfMIGc
|
||||||
|
gBTx0lDzjH/iOBnOSQaSEWQLx1syGKGBgKR+MHwxCzAJBgNVBAYTAmF3MQ4wDAYD
|
||||||
|
VQQIEwVhcnViYTEOMAwGA1UEChMFYXJ1YmExDjAMBgNVBAcTBWFydWJhMQ4wDAYD
|
||||||
|
VQQLEwVhcnViYTEOMAwGA1UEAxMFYXJ1YmExHTAbBgkqhkiG9w0BCQEWDmFydWJh
|
||||||
|
QGFydWJhLmFyggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYvBJ
|
||||||
|
0HOZbbHClXmGUjGs+GS+xC1FO/am2suCSYqNB9dyMXfOWiJ1+TLJk+o/YZt8vuxC
|
||||||
|
KdcZYgl4l/L6PxJ982SRhc83ZW2dkAZI4M0/Ud3oePe84k8jm3A7EvH5wi5hvCkK
|
||||||
|
RpuRBwn3Ei+jCRouxTbzKPsuCVB+1sNyxMTXzf0=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
#The secret that an external login server will use to authenticate to the uaa using the id `login`
|
||||||
|
LOGIN_SECRET: loginsecret
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
token:
|
||||||
|
signing-key: |
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAqUeygEfDGxI6c1VDQ6xIyUSLrP6iz1y97iHFbtXSxXaArL4a
|
||||||
|
...
|
||||||
|
v6Mtt5LcRAAVP7pemunTdju4h8Q/noKYlVDVL30uLYUfKBL4UKfOBw==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
verification-key: |
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUeygEfDGxI6c1VDQ6xI
|
||||||
|
...
|
||||||
|
AwIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
38
cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml
Normal file
38
cloud-foundry-uaa/cf-uaa-oauth2-client/pom.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?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.example</groupId>
|
||||||
|
<artifactId>cf-uaa-oauth2-client</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>uaa-client-webapp</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.client;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CFUAAOAuth2ClientApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CFUAAOAuth2ClientApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.client;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
||||||
|
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
||||||
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||||
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CFUAAOAuth2ClientController {
|
||||||
|
|
||||||
|
@Value("${resource.server.url}")
|
||||||
|
private String remoteResourceServer;
|
||||||
|
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
private OAuth2AuthorizedClientService authorizedClientService;
|
||||||
|
|
||||||
|
public CFUAAOAuth2ClientController(OAuth2AuthorizedClientService authorizedClientService) {
|
||||||
|
this.authorizedClientService = authorizedClientService;
|
||||||
|
this.restTemplate = new RestTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/")
|
||||||
|
public String index(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||||
|
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||||
|
|
||||||
|
String response = "Hello, " + authenticationToken.getPrincipal().getName();
|
||||||
|
response += "</br></br>";
|
||||||
|
response += "Here is your accees token :</br>" + oAuth2AccessToken.getTokenValue();
|
||||||
|
response += "</br>";
|
||||||
|
response += "</br>You can use it to call these Resource Server APIs:";
|
||||||
|
response += "</br></br>";
|
||||||
|
response += "<a href='/read'>Call Resource Server Read API</a>";
|
||||||
|
response += "</br>";
|
||||||
|
response += "<a href='/write'>Call Resource Server Write API</a>";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/read")
|
||||||
|
public String read(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
String url = remoteResourceServer + "/read";
|
||||||
|
return callResourceServer(authenticationToken, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/write")
|
||||||
|
public String write(OAuth2AuthenticationToken authenticationToken) {
|
||||||
|
String url = remoteResourceServer + "/write";
|
||||||
|
return callResourceServer(authenticationToken, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String callResourceServer(OAuth2AuthenticationToken authenticationToken, String url) {
|
||||||
|
OAuth2AuthorizedClient oAuth2AuthorizedClient = this.authorizedClientService.loadAuthorizedClient(authenticationToken.getAuthorizedClientRegistrationId(), authenticationToken.getName());
|
||||||
|
OAuth2AccessToken oAuth2AccessToken = oAuth2AuthorizedClient.getAccessToken();
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.add("Authorization", "Bearer " + oAuth2AccessToken.getTokenValue());
|
||||||
|
|
||||||
|
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
|
||||||
|
ResponseEntity<String> responseEntity = null;
|
||||||
|
|
||||||
|
String response = null;
|
||||||
|
try {
|
||||||
|
responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
|
||||||
|
response = responseEntity.getBody();
|
||||||
|
} catch (HttpClientErrorException e) {
|
||||||
|
response = e.getMessage();
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
server.port=8081
|
||||||
|
|
||||||
|
resource.server.url=http://localhost:8082
|
||||||
|
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-name=Web App Client
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-id=webappclient
|
||||||
|
spring.security.oauth2.client.registration.uaa.client-secret=webappclientsecret
|
||||||
|
spring.security.oauth2.client.registration.uaa.scope=resource.read,resource.write,openid,profile
|
||||||
|
|
||||||
|
spring.security.oauth2.client.provider.uaa.issuer-uri=http://localhost:8080/uaa/oauth/token
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
tintin
|
38
cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml
Normal file
38
cloud-foundry-uaa/cf-uaa-oauth2-resource-server/pom.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?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.cfuaa</groupId>
|
||||||
|
<artifactId>cf-uaa-oauth2-resource-server</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>cf-uaa-oauth2-resource-server</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CFUAAOAuth2ResourceServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CFUAAOAuth2ResourceServerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class CFUAAOAuth2ResourceServerRestController {
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index(@AuthenticationPrincipal Jwt jwt) {
|
||||||
|
return String.format("Hello, %s!", jwt.getSubject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/read")
|
||||||
|
public String read(JwtAuthenticationToken jwtAuthenticationToken) {
|
||||||
|
return "Hello write: " + jwtAuthenticationToken.getTokenAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/write")
|
||||||
|
public String write(Principal principal) {
|
||||||
|
return "Hello write: " + principal.getName();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.cfuaa.oauth2.resourceserver;
|
||||||
|
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class CFUAAOAuth2ResourceServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/read/**").hasAuthority("SCOPE_resource.read")
|
||||||
|
.antMatchers("/write/**").hasAuthority("SCOPE_resource.write")
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
.and()
|
||||||
|
.oauth2ResourceServer()
|
||||||
|
.jwt();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
server.port=8082
|
||||||
|
|
||||||
|
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/uaa/oauth/token
|
8
core-groovy-2/README.md
Normal file
8
core-groovy-2/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Groovy
|
||||||
|
|
||||||
|
## 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)
|
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>
|
||||||
|
|
187
core-groovy-2/pom.xml
Normal file
187
core-groovy-2/pom.xml
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<?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.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>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
<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();
|
||||||
|
}
|
||||||
|
}
|
5
core-groovy-2/src/main/resources/articleEmail.template
Normal file
5
core-groovy-2/src/main/resources/articleEmail.template
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Dear <% out << (user) %>,
|
||||||
|
Please read the requested article below.
|
||||||
|
<% out << (articleText) %>
|
||||||
|
From,
|
||||||
|
<% out << (signature) %>
|
3
core-groovy-2/src/main/resources/email.template
Normal file
3
core-groovy-2/src/main/resources/email.template
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Dear $user,
|
||||||
|
Thanks for subscribing our services.
|
||||||
|
${signature}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.baeldung.defkeyword
|
||||||
|
|
||||||
|
import org.codehaus.groovy.runtime.NullObject
|
||||||
|
import org.codehaus.groovy.runtime.typehandling.GroovyCastException
|
||||||
|
|
||||||
|
import groovy.transform.TypeChecked
|
||||||
|
import groovy.transform.TypeCheckingMode
|
||||||
|
|
||||||
|
@TypeChecked
|
||||||
|
class DefUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
def id
|
||||||
|
def firstName = "Samwell"
|
||||||
|
def listOfCountries = ['USA', 'UK', 'FRANCE', 'INDIA']
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
def multiply(x, y) {
|
||||||
|
return x*y
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testDefVariableDeclaration() {
|
||||||
|
|
||||||
|
def list
|
||||||
|
assert list.getClass() == org.codehaus.groovy.runtime.NullObject
|
||||||
|
assert list.is(null)
|
||||||
|
|
||||||
|
list = [1,2,4]
|
||||||
|
assert list instanceof ArrayList
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testTypeVariables() {
|
||||||
|
int rate = 200
|
||||||
|
try {
|
||||||
|
rate = [12] //GroovyCastException
|
||||||
|
rate = "nill" //GroovyCastException
|
||||||
|
} catch(GroovyCastException) {
|
||||||
|
println "Cannot assign anything other than integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeChecked(TypeCheckingMode.SKIP)
|
||||||
|
void testDefVariableMultipleAssignment() {
|
||||||
|
def rate
|
||||||
|
assert rate == null
|
||||||
|
assert rate.getClass() == org.codehaus.groovy.runtime.NullObject
|
||||||
|
|
||||||
|
rate = 12
|
||||||
|
assert rate instanceof Integer
|
||||||
|
|
||||||
|
rate = "Not Available"
|
||||||
|
assert rate instanceof String
|
||||||
|
|
||||||
|
rate = [1, 4]
|
||||||
|
assert rate instanceof List
|
||||||
|
|
||||||
|
assert divide(12, 3) instanceof BigDecimal
|
||||||
|
assert divide(1, 0) instanceof String
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def divide(int x, int y) {
|
||||||
|
if(y==0) {
|
||||||
|
return "Should not divide by 0"
|
||||||
|
} else {
|
||||||
|
return x/y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def greetMsg() {
|
||||||
|
println "Hello! I am Groovy"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testDefVsType() {
|
||||||
|
def int count
|
||||||
|
assert count instanceof Integer
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.strings
|
||||||
|
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
class StringMatchingSpec extends Specification {
|
||||||
|
|
||||||
|
def "pattern operator example"() {
|
||||||
|
given: "a pattern"
|
||||||
|
def p = ~'foo'
|
||||||
|
|
||||||
|
expect:
|
||||||
|
p instanceof Pattern
|
||||||
|
|
||||||
|
and: "you can use slash strings to avoid escaping of blackslash"
|
||||||
|
def digitPattern = ~/\d*/
|
||||||
|
digitPattern.matcher('4711').matches()
|
||||||
|
}
|
||||||
|
|
||||||
|
def "match operator example"() {
|
||||||
|
expect:
|
||||||
|
'foobar' ==~ /.*oba.*/
|
||||||
|
|
||||||
|
and: "matching is strict"
|
||||||
|
!('foobar' ==~ /foo/)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "find operator example"() {
|
||||||
|
when: "using the find operator"
|
||||||
|
def matcher = 'foo and bar, baz and buz' =~ /(\w+) and (\w+)/
|
||||||
|
|
||||||
|
then: "will find groups"
|
||||||
|
matcher.size() == 2
|
||||||
|
|
||||||
|
and: "can access groups using array"
|
||||||
|
matcher[0][0] == 'foo and bar'
|
||||||
|
matcher[1][2] == 'buz'
|
||||||
|
|
||||||
|
and: "you can use it as a predicate"
|
||||||
|
'foobarbaz' =~ /bar/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package com.baeldung.templateengine
|
||||||
|
|
||||||
|
import groovy.text.SimpleTemplateEngine
|
||||||
|
import groovy.text.StreamingTemplateEngine
|
||||||
|
import groovy.text.GStringTemplateEngine
|
||||||
|
import groovy.text.XmlTemplateEngine
|
||||||
|
import groovy.text.XmlTemplateEngine
|
||||||
|
import groovy.text.markup.MarkupTemplateEngine
|
||||||
|
import groovy.text.markup.TemplateConfiguration
|
||||||
|
|
||||||
|
class TemplateEnginesUnitTest extends GroovyTestCase {
|
||||||
|
|
||||||
|
def bindMap = [user: "Norman", signature: "Baeldung"]
|
||||||
|
|
||||||
|
void testSimpleTemplateEngine() {
|
||||||
|
def smsTemplate = 'Dear <% print user %>, Thanks for reading our Article. ${signature}'
|
||||||
|
def smsText = new SimpleTemplateEngine().createTemplate(smsTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert smsText.toString() == "Dear Norman, Thanks for reading our Article. Baeldung"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testStreamingTemplateEngine() {
|
||||||
|
def articleEmailTemplate = new File('src/main/resources/articleEmail.template')
|
||||||
|
bindMap.articleText = """1. Overview
|
||||||
|
This is a tutorial article on Template Engines""" //can be a string larger than 64k
|
||||||
|
|
||||||
|
def articleEmailText = new StreamingTemplateEngine().createTemplate(articleEmailTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert articleEmailText.toString() == """Dear Norman,
|
||||||
|
Please read the requested article below.
|
||||||
|
1. Overview
|
||||||
|
This is a tutorial article on Template Engines
|
||||||
|
From,
|
||||||
|
Baeldung"""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testGStringTemplateEngine() {
|
||||||
|
def emailTemplate = new File('src/main/resources/email.template')
|
||||||
|
def emailText = new GStringTemplateEngine().createTemplate(emailTemplate).make(bindMap)
|
||||||
|
|
||||||
|
assert emailText.toString() == "Dear Norman,\nThanks for subscribing our services.\nBaeldung"
|
||||||
|
}
|
||||||
|
|
||||||
|
void testXmlTemplateEngine() {
|
||||||
|
def emailXmlTemplate = '''<xs xmlns:gsp='groovy-server-pages'>
|
||||||
|
<gsp:scriptlet>def emailContent = "Thanks for subscribing our services."</gsp:scriptlet>
|
||||||
|
<email>
|
||||||
|
<greet>Dear ${user}</greet>
|
||||||
|
<content><gsp:expression>emailContent</gsp:expression></content>
|
||||||
|
<signature>${signature}</signature>
|
||||||
|
</email>
|
||||||
|
</xs>'''
|
||||||
|
def emailXml = new XmlTemplateEngine().createTemplate(emailXmlTemplate).make(bindMap)
|
||||||
|
println emailXml.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMarkupTemplateEngineHtml() {
|
||||||
|
def emailHtmlTemplate = """html {
|
||||||
|
head {
|
||||||
|
title('Service Subscription Email')
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
p('Dear Norman')
|
||||||
|
p('Thanks for subscribing our services.')
|
||||||
|
p('Baeldung')
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
|
|
||||||
|
def emailHtml = new MarkupTemplateEngine().createTemplate(emailHtmlTemplate).make()
|
||||||
|
println emailHtml.toString()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMarkupTemplateEngineXml() {
|
||||||
|
def emailXmlTemplate = """xmlDeclaration()
|
||||||
|
xs{
|
||||||
|
email {
|
||||||
|
greet('Dear Norman')
|
||||||
|
content('Thanks for subscribing our services.')
|
||||||
|
signature('Baeldung')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
TemplateConfiguration config = new TemplateConfiguration()
|
||||||
|
config.autoIndent = true
|
||||||
|
config.autoEscape = true
|
||||||
|
config.autoNewLine = true
|
||||||
|
|
||||||
|
def emailXml = new MarkupTemplateEngine(config).createTemplate(emailXmlTemplate).make()
|
||||||
|
|
||||||
|
println emailXml.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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>
|
6
core-groovy-collections/README.md
Normal file
6
core-groovy-collections/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Groovy
|
||||||
|
|
||||||
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Maps in Groovy](https://www.baeldung.com/groovy-maps)
|
||||||
|
|
131
core-groovy-collections/pom.xml
Normal file
131
core-groovy-collections/pom.xml
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
<?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-collections</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>core-groovy-collections</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.codehaus.groovy</groupId>
|
||||||
|
<artifactId>groovy</artifactId>
|
||||||
|
<version>${groovy.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>
|
||||||
|
</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>
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<url>http://jcenter.bintray.com</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,148 @@
|
|||||||
|
package com.baeldung.map;
|
||||||
|
|
||||||
|
import static groovy.test.GroovyAssert.*
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class MapTest{
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void createMap() {
|
||||||
|
|
||||||
|
def emptyMap = [:]
|
||||||
|
assertNotNull(emptyMap)
|
||||||
|
|
||||||
|
assertTrue(emptyMap instanceof java.util.LinkedHashMap)
|
||||||
|
|
||||||
|
def map = [name:"Jerry", age: 42, city: "New York"]
|
||||||
|
assertTrue(map.size() == 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addItemsToMap() {
|
||||||
|
|
||||||
|
def map = [name:"Jerry"]
|
||||||
|
|
||||||
|
map["age"] = 42
|
||||||
|
|
||||||
|
map.city = "New York"
|
||||||
|
|
||||||
|
def hobbyLiteral = "hobby"
|
||||||
|
def hobbyMap = [(hobbyLiteral): "Singing"]
|
||||||
|
map.putAll(hobbyMap)
|
||||||
|
|
||||||
|
assertTrue(map == [name:"Jerry", age: 42, city: "New York", hobby:"Singing"])
|
||||||
|
assertTrue(hobbyMap.hobby == "Singing")
|
||||||
|
assertTrue(hobbyMap[hobbyLiteral] == "Singing")
|
||||||
|
|
||||||
|
map.plus([1:20]) // returns new map
|
||||||
|
|
||||||
|
map << [2:30]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getItemsFromMap() {
|
||||||
|
|
||||||
|
def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]
|
||||||
|
|
||||||
|
assertTrue(map["name"] == "Jerry")
|
||||||
|
|
||||||
|
assertTrue(map.name == "Jerry")
|
||||||
|
|
||||||
|
def propertyAge = "age"
|
||||||
|
assertTrue(map[propertyAge] == 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void removeItemsFromMap() {
|
||||||
|
|
||||||
|
def map = [1:20, a:30, 2:42, 4:34, ba:67, 6:39, 7:49]
|
||||||
|
|
||||||
|
def minusMap = map.minus([2:42, 4:34]);
|
||||||
|
assertTrue(minusMap == [1:20, a:30, ba:67, 6:39, 7:49])
|
||||||
|
|
||||||
|
minusMap.removeAll{it -> it.key instanceof String}
|
||||||
|
assertTrue( minusMap == [ 1:20, 6:39, 7:49])
|
||||||
|
|
||||||
|
minusMap.retainAll{it -> it.value %2 == 0}
|
||||||
|
assertTrue( minusMap == [1:20])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void iteratingOnMaps(){
|
||||||
|
def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]
|
||||||
|
|
||||||
|
map.each{ entry -> println "$entry.key: $entry.value" }
|
||||||
|
|
||||||
|
map.eachWithIndex{ entry, i -> println "$i $entry.key: $entry.value" }
|
||||||
|
|
||||||
|
map.eachWithIndex{ key, value, i -> println "$i $key: $value" }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void filteringAndSearchingMaps(){
|
||||||
|
def map = [name:"Jerry", age: 42, city: "New York", hobby:"Singing"]
|
||||||
|
|
||||||
|
assertTrue(map.find{ it.value == "New York"}.key == "city")
|
||||||
|
|
||||||
|
assertTrue(map.findAll{ it.value == "New York"} == [city : "New York"])
|
||||||
|
|
||||||
|
map.grep{it.value == "New York"}.each{ it -> assertTrue(it.key == "city" && it.value == "New York")}
|
||||||
|
|
||||||
|
assertTrue(map.every{it -> it.value instanceof String} == false)
|
||||||
|
|
||||||
|
assertTrue(map.any{it -> it.value instanceof String} == true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void collect(){
|
||||||
|
|
||||||
|
def map = [1: [name:"Jerry", age: 42, city: "New York"],
|
||||||
|
2: [name:"Long", age: 25, city: "New York"],
|
||||||
|
3: [name:"Dustin", age: 29, city: "New York"],
|
||||||
|
4: [name:"Dustin", age: 34, city: "New York"]]
|
||||||
|
|
||||||
|
def names = map.collect{entry -> entry.value.name} // returns only list
|
||||||
|
assertTrue(names == ["Jerry", "Long", "Dustin", "Dustin"])
|
||||||
|
|
||||||
|
def uniqueNames = map.collect([] as HashSet){entry -> entry.value.name}
|
||||||
|
assertTrue(uniqueNames == ["Jerry", "Long", "Dustin"] as Set)
|
||||||
|
|
||||||
|
def idNames = map.collectEntries{key, value -> [key, value.name]}
|
||||||
|
assertTrue(idNames == [1:"Jerry", 2: "Long", 3:"Dustin", 4: "Dustin"])
|
||||||
|
|
||||||
|
def below30Names = map.findAll{it.value.age < 30}.collect{key, value -> value.name}
|
||||||
|
assertTrue(below30Names == ["Long", "Dustin"])
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void group(){
|
||||||
|
def map = [1:20, 2: 40, 3: 11, 4: 93]
|
||||||
|
|
||||||
|
def subMap = map.groupBy{it.value % 2}
|
||||||
|
println subMap
|
||||||
|
assertTrue(subMap == [0:[1:20, 2:40 ], 1:[3:11, 4:93]])
|
||||||
|
|
||||||
|
def keySubMap = map.subMap([1, 2])
|
||||||
|
assertTrue(keySubMap == [1:20, 2:40])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sorting(){
|
||||||
|
def map = [ab:20, a: 40, cb: 11, ba: 93]
|
||||||
|
|
||||||
|
def naturallyOrderedMap = map.sort()
|
||||||
|
assertTrue([a:40, ab:20, ba:93, cb:11] == naturallyOrderedMap)
|
||||||
|
|
||||||
|
def compSortedMap = map.sort({ k1, k2 -> k1 <=> k2 } as Comparator)
|
||||||
|
assertTrue([a:40, ab:20, ba:93, cb:11] == compSortedMap)
|
||||||
|
|
||||||
|
def cloSortedMap = map.sort({ it1, it2 -> it1.value <=> it1.value })
|
||||||
|
assertTrue([cb:11, ab:20, a:40, ba:93] == cloSortedMap)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
core-groovy/.gitignore
vendored
Normal file
1
core-groovy/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/src/main/resources/ioSerializedObject.txt
|
@ -4,3 +4,12 @@
|
|||||||
|
|
||||||
- [JDBC with Groovy](http://www.baeldung.com/jdbc-groovy)
|
- [JDBC with Groovy](http://www.baeldung.com/jdbc-groovy)
|
||||||
- [Working with JSON in Groovy](http://www.baeldung.com/groovy-json)
|
- [Working with JSON in Groovy](http://www.baeldung.com/groovy-json)
|
||||||
|
- [Reading a File in Groovy](https://www.baeldung.com/groovy-file-read)
|
||||||
|
- [Types of Strings in Groovy](https://www.baeldung.com/groovy-strings)
|
||||||
|
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
||||||
|
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
||||||
|
- [Closures in Groovy](https://www.baeldung.com/groovy-closures)
|
||||||
|
- [Finding Elements in Collections in Groovy](https://www.baeldung.com/groovy-collections-find-elements)
|
||||||
|
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
||||||
|
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||||
|
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung
|
||||||
|
|
||||||
|
class Person {
|
||||||
|
private String firstname
|
||||||
|
private String lastname
|
||||||
|
private Integer age
|
||||||
|
|
||||||
|
Person(String firstname, String lastname, Integer age) {
|
||||||
|
this.firstname = firstname
|
||||||
|
this.lastname = lastname
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFirstname() {
|
||||||
|
return firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLastname() {
|
||||||
|
return lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getAge() {
|
||||||
|
return age
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAge(Integer age) {
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Closures {
|
||||||
|
|
||||||
|
def printWelcome = {
|
||||||
|
println "Welcome to Closures!"
|
||||||
|
}
|
||||||
|
|
||||||
|
def print = { name ->
|
||||||
|
println name
|
||||||
|
}
|
||||||
|
|
||||||
|
def formatToLowerCase(name) {
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
def formatToLowerCaseClosure = { name ->
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
def count=0
|
||||||
|
|
||||||
|
def increaseCount = {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
def greet = {
|
||||||
|
return "Hello! ${it}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def multiply = { x, y ->
|
||||||
|
return x*y
|
||||||
|
}
|
||||||
|
|
||||||
|
def calculate = {int x, int y, String operation ->
|
||||||
|
|
||||||
|
//log closure
|
||||||
|
def log = {
|
||||||
|
println "Performing $it"
|
||||||
|
}
|
||||||
|
|
||||||
|
def result = 0
|
||||||
|
switch(operation) {
|
||||||
|
case "ADD":
|
||||||
|
log("Addition")
|
||||||
|
result = x+y
|
||||||
|
break
|
||||||
|
case "SUB":
|
||||||
|
log("Subtraction")
|
||||||
|
result = x-y
|
||||||
|
break
|
||||||
|
case "MUL":
|
||||||
|
log("Multiplication")
|
||||||
|
result = x*y
|
||||||
|
break
|
||||||
|
case "DIV":
|
||||||
|
log("Division")
|
||||||
|
result = x/y
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
def addAll = { int... args ->
|
||||||
|
return args.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
def volume(Closure areaCalculator, int... dimensions) {
|
||||||
|
if(dimensions.size() == 3) {
|
||||||
|
|
||||||
|
//consider dimension[0] = length, dimension[1] = breadth, dimension[2] = height
|
||||||
|
//for cube and cuboid
|
||||||
|
return areaCalculator(dimensions[0], dimensions[1]) * dimensions[2]
|
||||||
|
} else if(dimensions.size() == 2) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius, dimension[1] = height
|
||||||
|
//for cylinder and cone
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[1]
|
||||||
|
} else if(dimensions.size() == 1) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius
|
||||||
|
//for sphere
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Employee {
|
||||||
|
|
||||||
|
String fullName
|
||||||
|
}
|
8
core-groovy/src/main/groovy/com/baeldung/io/Task.groovy
Normal file
8
core-groovy/src/main/groovy/com/baeldung/io/Task.groovy
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.io
|
||||||
|
|
||||||
|
class Task implements Serializable {
|
||||||
|
String description
|
||||||
|
Date startDate
|
||||||
|
Date dueDate
|
||||||
|
int status
|
||||||
|
}
|
BIN
core-groovy/src/main/resources/binaryExample.jpg
Normal file
BIN
core-groovy/src/main/resources/binaryExample.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
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