Merge branch 'eugenmaster'
This commit is contained in:
commit
130d0878e7
11
README.md
11
README.md
|
@ -20,17 +20,22 @@ In additional to Spring, the following technologies are in focus: `core Java`, `
|
|||
|
||||
Building the project
|
||||
====================
|
||||
To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false`
|
||||
To do the full build, do: `mvn clean install`
|
||||
|
||||
|
||||
Building a single module
|
||||
====================
|
||||
To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory
|
||||
To build a specific module run the command: `mvn clean install` in the module directory
|
||||
|
||||
|
||||
Running a Spring Boot module
|
||||
====================
|
||||
To run a Spring Boot module run the command: `mvn spring-boot:run -Dgib.enabled=false` in the module directory
|
||||
To run a Spring Boot module run the command: `mvn spring-boot:run` in the module directory
|
||||
|
||||
#Running Tests
|
||||
|
||||
The command `mvn clean install` will run the unit tests in a module.
|
||||
To run the integration tests, use the command `mvn clean install -Pintegration-lite-first`
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,3 +15,5 @@
|
|||
- [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)
|
||||
- [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)
|
||||
|
|
|
@ -4,4 +4,3 @@
|
|||
- [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)
|
||||
- [An Introduction to the Theory of Big-O Notation](http://www.baeldung.com/big-o-notation)
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Graph {
|
||||
|
||||
private List<Vertex> vertices;
|
||||
|
||||
public Graph() {
|
||||
this.vertices = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Graph(List<Vertex> vertices) {
|
||||
this.vertices = vertices;
|
||||
}
|
||||
|
||||
public void addVertex(Vertex vertex) {
|
||||
this.vertices.add(vertex);
|
||||
}
|
||||
|
||||
public void addEdge(Vertex from, Vertex to) {
|
||||
from.addNeighbour(to);
|
||||
}
|
||||
|
||||
public boolean hasCycle() {
|
||||
for (Vertex vertex : vertices) {
|
||||
if (!vertex.isVisited() && hasCycle(vertex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasCycle(Vertex sourceVertex) {
|
||||
sourceVertex.setBeingVisited(true);
|
||||
|
||||
for (Vertex neighbour : sourceVertex.getAdjacencyList()) {
|
||||
if (neighbour.isBeingVisited()) {
|
||||
// backward edge exists
|
||||
return true;
|
||||
} else if (!neighbour.isVisited() && hasCycle(neighbour)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sourceVertex.setBeingVisited(false);
|
||||
sourceVertex.setVisited(true);
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.algorithms.graphcycledetection.domain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Vertex {
|
||||
|
||||
private String label;
|
||||
|
||||
private boolean visited;
|
||||
|
||||
private boolean beingVisited;
|
||||
|
||||
private List<Vertex> adjacencyList;
|
||||
|
||||
public Vertex(String label) {
|
||||
this.label = label;
|
||||
this.adjacencyList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public boolean isVisited() {
|
||||
return visited;
|
||||
}
|
||||
|
||||
public void setVisited(boolean visited) {
|
||||
this.visited = visited;
|
||||
}
|
||||
|
||||
public boolean isBeingVisited() {
|
||||
return beingVisited;
|
||||
}
|
||||
|
||||
public void setBeingVisited(boolean beingVisited) {
|
||||
this.beingVisited = beingVisited;
|
||||
}
|
||||
|
||||
public List<Vertex> getAdjacencyList() {
|
||||
return adjacencyList;
|
||||
}
|
||||
|
||||
public void setAdjacencyList(List<Vertex> adjacencyList) {
|
||||
this.adjacencyList = adjacencyList;
|
||||
}
|
||||
|
||||
public void addNeighbour(Vertex adjacent) {
|
||||
this.adjacencyList.add(adjacent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.algorithms.graphcycledetection;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.algorithms.graphcycledetection.domain.Graph;
|
||||
import com.baeldung.algorithms.graphcycledetection.domain.Vertex;
|
||||
|
||||
public class GraphCycleDetectionUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenCycleExists_thenReturnTrue() {
|
||||
|
||||
Vertex vertexA = new Vertex("A");
|
||||
Vertex vertexB = new Vertex("B");
|
||||
Vertex vertexC = new Vertex("C");
|
||||
Vertex vertexD = new Vertex("D");
|
||||
|
||||
Graph graph = new Graph();
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addVertex(vertexD);
|
||||
|
||||
graph.addEdge(vertexA, vertexB);
|
||||
graph.addEdge(vertexB, vertexC);
|
||||
graph.addEdge(vertexC, vertexA);
|
||||
graph.addEdge(vertexD, vertexC);
|
||||
|
||||
assertTrue(graph.hasCycle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenNoCycleExists_thenReturnFalse() {
|
||||
|
||||
Vertex vertexA = new Vertex("A");
|
||||
Vertex vertexB = new Vertex("B");
|
||||
Vertex vertexC = new Vertex("C");
|
||||
Vertex vertexD = new Vertex("D");
|
||||
|
||||
Graph graph = new Graph();
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addVertex(vertexD);
|
||||
|
||||
graph.addEdge(vertexA, vertexB);
|
||||
graph.addEdge(vertexB, vertexC);
|
||||
graph.addEdge(vertexA, vertexC);
|
||||
graph.addEdge(vertexD, vertexC);
|
||||
|
||||
assertFalse(graph.hasCycle());
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@ import java.util.stream.Stream;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class GeodeSamplesIntegrationTest {
|
||||
public class GeodeSamplesLiveTest {
|
||||
|
||||
ClientCache cache = null;
|
||||
Region<String, String> region = null;
|
|
@ -0,0 +1,3 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [OData Protocol Guide](https://www.baeldung.com/odata)
|
|
@ -44,11 +44,6 @@
|
|||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
@ -68,16 +63,6 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>olingo-odata2-api</artifactId>
|
||||
<version>${olingo2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>olingo-odata2-jpa-processor-api</artifactId>
|
||||
<version>${olingo2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>olingo-odata2-jpa-processor-core</artifactId>
|
||||
|
|
|
@ -12,25 +12,104 @@ import javax.persistence.OneToMany;
|
|||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name="car_maker")
|
||||
@Table(name = "car_maker")
|
||||
public class CarMaker {
|
||||
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
|
||||
@NotNull
|
||||
@Column(name="name")
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy="maker",
|
||||
orphanRemoval = true,
|
||||
cascade=CascadeType.ALL)
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.baeldung.examples.olingo2.domain;
|
||||
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
@ -11,28 +10,150 @@ import javax.persistence.ManyToOne;
|
|||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name="car_model")
|
||||
@Table(name = "car_model")
|
||||
public class CarModel {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.AUTO)
|
||||
@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")
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
server:
|
||||
port: 8180
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
jersey:
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
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/
|
|
@ -1,95 +0,0 @@
|
|||
<?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.olingo4</groupId>
|
||||
<artifactId>olingo4-sample</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>olingo4-sample</name>
|
||||
<description>Sample Olingo 4 Project</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<odata.version>4.5.0</odata.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-server-api</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-server-core</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-commons-api</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.olingo</groupId>
|
||||
<artifactId>odata-commons-core</artifactId>
|
||||
<version>${odata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,20 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Default implementation for ODataFactory
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class DefaultODataFactory implements ODataFactory {
|
||||
|
||||
@Override
|
||||
public OData newInstance() {
|
||||
return OData.newInstance();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.OData;
|
||||
|
||||
public interface ODataFactory {
|
||||
|
||||
public OData newInstance();
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
|
||||
public interface ODataHttpHandlerFactory {
|
||||
|
||||
ODataHttpHandler newInstance();
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@Builder
|
||||
public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory {
|
||||
|
||||
|
||||
private final ODataFactory odataFactory;
|
||||
private final CsdlEdmProvider edmProvider;
|
||||
private final List<Processor> processors;
|
||||
|
||||
public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory,CsdlEdmProvider edmProvider, List<Processor> processors) {
|
||||
this.odataFactory = odataFactory;
|
||||
this.edmProvider = edmProvider;
|
||||
this.processors = processors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ODataHttpHandler newInstance() {
|
||||
|
||||
OData odata = odataFactory.newInstance();
|
||||
ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList());
|
||||
ODataHttpHandler handler = odata.createHandler(metadata);
|
||||
|
||||
// Register all available processors
|
||||
processors.forEach(p -> handler.register(p));
|
||||
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;
|
||||
import org.apache.olingo.server.api.processor.Processor;
|
||||
import org.baeldung.examples.olingo4.ODataHttpHandlerFactoryImpl.ODataHttpHandlerFactoryImplBuilder;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ODataServiceConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean<HttpServlet> odataServletRegistration(ODataHttpHandlerFactory factory) {
|
||||
ServletRegistrationBean<HttpServlet> srb =
|
||||
new ServletRegistrationBean<>(new ODataServlet(factory), "/odata/*");
|
||||
srb.setLoadOnStartup(1);
|
||||
return srb;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List<Processor> processors) {
|
||||
return new ODataHttpHandlerFactoryImplBuilder()
|
||||
.edmProvider(edmProvider)
|
||||
.odataFactory(odataFactory)
|
||||
.processors(processors)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.EntityTransaction;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.olingo.server.api.ODataHttpHandler;
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
public class ODataServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final ODataHttpHandlerFactory odataHttpHandlerFactory;
|
||||
|
||||
|
||||
public ODataServlet(ODataHttpHandlerFactory factory) {
|
||||
this.odataHttpHandlerFactory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
|
||||
ODataHttpHandler handler = odataHttpHandlerFactory.newInstance();
|
||||
handler.process(req, resp);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.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;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@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;
|
||||
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.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;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@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.EAGER )
|
||||
@JoinColumn(name="maker_fk")
|
||||
private CarMaker maker;
|
||||
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.edm;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.sql.Time;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class EdmTypeMapper {
|
||||
|
||||
public EdmPrimitiveTypeKind java2edm(Class<?> clazz) {
|
||||
EdmPrimitiveTypeKind result = java2edm.get(clazz);
|
||||
if ( result == null ) {
|
||||
throw new IllegalArgumentException("[E19] Unsupported class mapping: class=" + clazz);
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Static map used generate attribute metadada based on Java types
|
||||
static Map<Class<?>,EdmPrimitiveTypeKind> java2edm = Collections
|
||||
.unmodifiableMap(Stream.of(
|
||||
new SimpleEntry<>(Boolean.class,EdmPrimitiveTypeKind.Boolean),
|
||||
new SimpleEntry<>(Byte.class,EdmPrimitiveTypeKind.SByte),
|
||||
new SimpleEntry<>(Date.class,EdmPrimitiveTypeKind.Date),
|
||||
new SimpleEntry<>(Time.class,EdmPrimitiveTypeKind.TimeOfDay),
|
||||
new SimpleEntry<>(Number.class,EdmPrimitiveTypeKind.Decimal),
|
||||
new SimpleEntry<>(Float.class,EdmPrimitiveTypeKind.Single),
|
||||
new SimpleEntry<>(Double.class,EdmPrimitiveTypeKind.Double),
|
||||
new SimpleEntry<>(UUID.class,EdmPrimitiveTypeKind.Guid),
|
||||
new SimpleEntry<>(Short.class,EdmPrimitiveTypeKind.Int16),
|
||||
new SimpleEntry<>(Integer.class,EdmPrimitiveTypeKind.Int32),
|
||||
new SimpleEntry<>(Long.class,EdmPrimitiveTypeKind.Int64),
|
||||
new SimpleEntry<>(String.class,EdmPrimitiveTypeKind.String)
|
||||
|
||||
).collect(Collectors.toMap((e)-> e.getKey(),(e)-> e.getValue())));
|
||||
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.edm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.Attribute.PersistentAttributeType;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.Metamodel;
|
||||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.FullQualifiedName;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlEntityType;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef;
|
||||
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
|
||||
import org.apache.olingo.commons.api.ex.ODataException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JpaEdmProvider extends CsdlAbstractEdmProvider {
|
||||
|
||||
EntityManagerFactory emf;
|
||||
|
||||
//
|
||||
private EdmTypeMapper typeMapper;
|
||||
|
||||
// Service Namespace
|
||||
public static final String NAMESPACE = "Baeldung.OData";
|
||||
|
||||
// EDM Container
|
||||
public static final String CONTAINER_NAME = "Cars";
|
||||
public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME);
|
||||
|
||||
// Caches of OData types by it fully qualified name
|
||||
private Map<FullQualifiedName, CsdlEntityType> cdslName2Type = new HashMap<>();
|
||||
|
||||
public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) {
|
||||
this.emf = emf;
|
||||
this.typeMapper = mapper;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntitySet(org.apache.olingo.commons.api.edm.FullQualifiedName, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException {
|
||||
|
||||
if (entityContainer.equals(CONTAINER)) {
|
||||
|
||||
EntityType<?> e = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.filter((ent) -> (ent.getName() + "s")
|
||||
.equals(entitySetName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (e != null) {
|
||||
CsdlEntitySet entitySet = new CsdlEntitySet();
|
||||
entitySet
|
||||
.setName(entitySetName)
|
||||
.setType(new FullQualifiedName(NAMESPACE, e.getName()));
|
||||
return entitySet;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainerInfo(org.apache.olingo.commons.api.edm.FullQualifiedName)
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException {
|
||||
|
||||
// This method is invoked when displaying the Service Document at e.g. http://localhost:8080/DemoService/DemoService.svc
|
||||
if (entityContainerName == null || entityContainerName.equals(CONTAINER)) {
|
||||
CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo();
|
||||
entityContainerInfo.setContainerName(CONTAINER);
|
||||
return entityContainerInfo;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getSchemas()
|
||||
*/
|
||||
@Override
|
||||
public List<CsdlSchema> getSchemas() throws ODataException {
|
||||
// create Schema
|
||||
CsdlSchema schema = new CsdlSchema();
|
||||
schema.setNamespace(NAMESPACE);
|
||||
|
||||
// add EntityTypes
|
||||
List<CsdlEntityType> entityTypes = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.map((e) -> {
|
||||
try {
|
||||
return getEntityType(new FullQualifiedName(NAMESPACE, e.getName()));
|
||||
} catch (ODataException oe) {
|
||||
throw new RuntimeException(oe);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
schema.setEntityTypes(entityTypes);
|
||||
|
||||
// add EntityContainer
|
||||
schema.setEntityContainer(getEntityContainer());
|
||||
|
||||
// finally
|
||||
List<CsdlSchema> schemas = new ArrayList<CsdlSchema>();
|
||||
schemas.add(schema);
|
||||
|
||||
return schemas;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainer()
|
||||
*/
|
||||
@Override
|
||||
public CsdlEntityContainer getEntityContainer() throws ODataException {
|
||||
|
||||
|
||||
// add EntityTypes
|
||||
List<CsdlEntitySet> entitySets = emf.getMetamodel()
|
||||
.getEntities()
|
||||
.stream()
|
||||
.map((e) -> {
|
||||
try {
|
||||
// Here we use a simple mapping strategy to map entity types to entity set names:
|
||||
return getEntitySet(CONTAINER, e.getName() + "s");
|
||||
} catch (ODataException oe) {
|
||||
throw new RuntimeException(oe);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// create EntityContainer
|
||||
CsdlEntityContainer entityContainer = new CsdlEntityContainer();
|
||||
entityContainer.setName(CONTAINER_NAME);
|
||||
entityContainer.setEntitySets(entitySets);
|
||||
|
||||
return entityContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException {
|
||||
|
||||
CsdlEntityType result = cdslName2Type.get(entityTypeName);
|
||||
if ( result != null ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Metamodel mm = emf.getMetamodel();
|
||||
result = mm.getEntities()
|
||||
.stream()
|
||||
.filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName())))
|
||||
.map(et -> buildODataType(et))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// save for future use
|
||||
cdslName2Type.put(entityTypeName, result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a JPA type to its OData counterpart.
|
||||
* @param et
|
||||
* @return
|
||||
*/
|
||||
protected CsdlEntityType buildODataType(EntityType<?> et) {
|
||||
|
||||
CsdlEntityType result = new CsdlEntityType();
|
||||
result.setName(et.getName());
|
||||
|
||||
// Process simple properties
|
||||
List<CsdlProperty> properties = et.getDeclaredSingularAttributes()
|
||||
.stream()
|
||||
.filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC)
|
||||
.map(attr -> buildBasicAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
result.setProperties(properties);
|
||||
|
||||
// Process Ids
|
||||
List<CsdlPropertyRef> ids = et.getDeclaredSingularAttributes()
|
||||
.stream()
|
||||
.filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId())
|
||||
.map(attr -> buildRefAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
result.setKey(ids);
|
||||
|
||||
// Process 1:N navs
|
||||
List<CsdlNavigationProperty> navs = et.getDeclaredPluralAttributes()
|
||||
.stream()
|
||||
.map(attr -> buildNavAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
result.setNavigationProperties(navs);
|
||||
|
||||
// Process N:1 navs
|
||||
List<CsdlNavigationProperty> navs2 = et.getDeclaredSingularAttributes()
|
||||
.stream()
|
||||
.filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE)
|
||||
.map(attr -> buildNavAttribute(et, attr))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
result.getNavigationProperties().addAll(navs2);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private CsdlProperty buildBasicAttribute(EntityType<?> et, SingularAttribute<?, ?> attr) {
|
||||
|
||||
CsdlProperty p = new CsdlProperty().setName(attr.getName())
|
||||
.setType(typeMapper.java2edm(attr.getJavaType())
|
||||
.getFullQualifiedName())
|
||||
.setNullable(et.getDeclaredSingularAttribute(attr.getName())
|
||||
.isOptional());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private CsdlPropertyRef buildRefAttribute(EntityType<?> et, SingularAttribute<?, ?> attr) {
|
||||
|
||||
CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Build NavProperty for 1:N or M:N associations
|
||||
private CsdlNavigationProperty buildNavAttribute(EntityType<?> et, PluralAttribute<?, ?, ?> attr) {
|
||||
|
||||
CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName())
|
||||
.setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName()))
|
||||
.setCollection(true)
|
||||
.setNullable(false);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Build NavProperty for N:1 associations
|
||||
private CsdlNavigationProperty buildNavAttribute(EntityType<?> et, SingularAttribute<?, ?> attr) {
|
||||
|
||||
CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName())
|
||||
.setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName()))
|
||||
.setCollection(false)
|
||||
.setNullable(attr.isOptional());
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.processor;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.EntityCollection;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataLibraryException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
|
||||
import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.SerializerResult;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.baeldung.examples.olingo4.repository.RepositoryRegistry;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JpaEntityCollectionProcessor implements CountEntityCollectionProcessor {
|
||||
|
||||
private OData odata;
|
||||
private ServiceMetadata serviceMetadata;
|
||||
private EntityManagerFactory emf;
|
||||
private RepositoryRegistry repositoryRegistry;
|
||||
private JpaEntityMapper entityMapper;
|
||||
|
||||
public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry, JpaEntityMapper entityMapper) {
|
||||
this.emf = emf;
|
||||
this.repositoryRegistry = repositoryRegistry;
|
||||
this.entityMapper = entityMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(OData odata, ServiceMetadata serviceMetadata) {
|
||||
this.odata = odata;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
// 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI)
|
||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
|
||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||
|
||||
// 2nd: fetch the data from backend for this requested EntitySetName
|
||||
// it has to be delivered as EntitySet object
|
||||
EntityCollection entitySet = getData(edmEntitySet, uriInfo);
|
||||
|
||||
// 3rd: create a serializer based on the requested format (json)
|
||||
ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||
|
||||
// 4th: Now serialize the content: transform from the EntitySet object to InputStream
|
||||
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
|
||||
ContextURL contextUrl = ContextURL.with()
|
||||
.entitySet(edmEntitySet)
|
||||
.build();
|
||||
|
||||
final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName();
|
||||
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with()
|
||||
.id(id)
|
||||
.contextURL(contextUrl)
|
||||
.build();
|
||||
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts);
|
||||
InputStream serializedContent = serializerResult.getContent();
|
||||
|
||||
// Finally: configure the response object: set the body, headers and status code
|
||||
response.setContent(serializedContent);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
// 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI)
|
||||
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
|
||||
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet
|
||||
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
|
||||
|
||||
// 2nd: fetch the data from backend for this requested EntitySetName
|
||||
Long count = getCount(edmEntitySet, uriInfo);
|
||||
|
||||
// Finally: configure the response object: set the body, headers and status code
|
||||
response.setContent(new ByteArrayInputStream(count.toString().getBytes()));
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to retrieve all entities of an entity set from an the backend database
|
||||
* @param edmEntitySet
|
||||
* @param uriInfo
|
||||
* @return
|
||||
*/
|
||||
protected EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
|
||||
|
||||
EdmEntityType type = edmEntitySet.getEntityType();
|
||||
JpaRepository<?, ?> repo = (JpaRepository<?, ?>)repositoryRegistry.getRepositoryForEntity(type);
|
||||
EntityCollection result = new EntityCollection();
|
||||
|
||||
repo.findAll()
|
||||
.stream()
|
||||
.forEach((it) -> result.getEntities()
|
||||
.add(entityMapper.map2entity(edmEntitySet, it)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to get the total size of an entity set
|
||||
* @param edmEntitySet
|
||||
* @param uriInfo
|
||||
* @return
|
||||
*/
|
||||
protected Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) {
|
||||
|
||||
EdmEntityType type = edmEntitySet.getEntityType();
|
||||
JpaRepository<?, ?> repo = (JpaRepository<?, ?>)repositoryRegistry.getRepositoryForEntity(type);
|
||||
EntityCollection result = new EntityCollection();
|
||||
|
||||
return repo.count();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4.processor;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.data.Property;
|
||||
import org.apache.olingo.commons.api.data.ValueType;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <p>Helper class that converts a JPA entity into an OData entity using
|
||||
* available metadata from the JPA's EntityManagerFactory.</p>
|
||||
*
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class JpaEntityMapper {
|
||||
|
||||
private EntityManagerFactory emf;
|
||||
|
||||
public JpaEntityMapper(EntityManagerFactory emf) {
|
||||
this.emf = emf;
|
||||
}
|
||||
|
||||
|
||||
public Entity map2entity(EdmEntitySet edmEntitySet, Object entry) {
|
||||
|
||||
EntityType<?> et = emf.getMetamodel()
|
||||
.entity(entry.getClass());
|
||||
|
||||
|
||||
Entity e = new Entity();
|
||||
try {
|
||||
et.getDeclaredSingularAttributes().stream()
|
||||
.forEach( (attr) -> {
|
||||
if ( !attr.isAssociation()) {
|
||||
Object v = getPropertyValue(entry,attr.getName());
|
||||
Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v);
|
||||
e.addProperty(p);
|
||||
|
||||
if ( attr.isId()) {
|
||||
e.setId(createId(edmEntitySet.getName(),v));
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
throw new ODataRuntimeException("[E141] Unable to create OData entity", ex);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
public Object getPropertyValue(Object entry, String name) {
|
||||
try {
|
||||
return PropertyUtils.getProperty(entry,name);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPropertyValue(Object entry, String name,Object value) {
|
||||
try {
|
||||
PropertyUtils.setProperty(entry,name,value);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private URI createId(String entitySetName, Object id) {
|
||||
try {
|
||||
return new URI(entitySetName + "(" + String.valueOf(id) + ")");
|
||||
} catch (URISyntaxException e) {
|
||||
throw new ODataRuntimeException("[E177] Unable to create URI", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,304 +0,0 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4.processor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
|
||||
import org.apache.olingo.commons.api.data.ContextURL;
|
||||
import org.apache.olingo.commons.api.data.Entity;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntitySet;
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
|
||||
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
|
||||
import org.apache.olingo.commons.api.format.ContentType;
|
||||
import org.apache.olingo.commons.api.http.HttpHeader;
|
||||
import org.apache.olingo.commons.api.http.HttpStatusCode;
|
||||
import org.apache.olingo.server.api.OData;
|
||||
import org.apache.olingo.server.api.ODataApplicationException;
|
||||
import org.apache.olingo.server.api.ODataLibraryException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.ServiceMetadata;
|
||||
import org.apache.olingo.server.api.processor.EntityProcessor;
|
||||
import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
|
||||
import org.apache.olingo.server.api.serializer.ODataSerializer;
|
||||
import org.apache.olingo.server.api.serializer.SerializerResult;
|
||||
import org.apache.olingo.server.api.uri.UriInfo;
|
||||
import org.apache.olingo.server.api.uri.UriParameter;
|
||||
import org.apache.olingo.server.api.uri.UriResource;
|
||||
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
|
||||
import org.apache.olingo.server.api.uri.UriResourceNavigation;
|
||||
import org.baeldung.examples.olingo4.repository.EdmEntityRepository;
|
||||
import org.baeldung.examples.olingo4.repository.RepositoryRegistry;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* JpaEntityProcessor adapter.
|
||||
* <p>This implementation is heavily based on the Tutorial available
|
||||
* at Olingo's site. It is meant to be an starting point for an actual implementation.</p>
|
||||
* <p>Please note that many features from a full-fledged are missing
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
public class JpaEntityProcessor implements EntityProcessor {
|
||||
|
||||
private EntityManagerFactory emf;
|
||||
private OData odata;
|
||||
private ServiceMetadata serviceMetadata;
|
||||
private RepositoryRegistry registry;
|
||||
private JpaEntityMapper entityMapper;
|
||||
|
||||
public JpaEntityProcessor(EntityManagerFactory emf, RepositoryRegistry registry, JpaEntityMapper entityMapper) {
|
||||
this.emf = emf;
|
||||
this.registry = registry;
|
||||
this.entityMapper = entityMapper;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.server.api.processor.Processor#init(org.apache.olingo.server.api.OData, org.apache.olingo.server.api.ServiceMetadata)
|
||||
*/
|
||||
@Override
|
||||
public void init(OData odata, ServiceMetadata serviceMetadata) {
|
||||
this.odata = odata;
|
||||
this.serviceMetadata = serviceMetadata;
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.server.api.processor.EntityProcessor#readEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType)
|
||||
*/
|
||||
@Override
|
||||
public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
// First, we have to figure out which entity is requested
|
||||
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
|
||||
InputStream entityStream;
|
||||
|
||||
UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
|
||||
EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet();
|
||||
List<UriParameter> rootPredicates = rootResourceEntitySet.getKeyPredicates();
|
||||
|
||||
if ( resourceParts.size() == 1 ) {
|
||||
entityStream = readRootEntity(rootEntitySet,rootPredicates,responseFormat);
|
||||
}
|
||||
else if ( resourceParts.size() == 2 ) {
|
||||
UriResource part = resourceParts.get(1);
|
||||
if ( !(part instanceof UriResourceNavigation)) {
|
||||
throw new ODataRuntimeException("[E103] part type not supported: class=" + part.getClass().getName());
|
||||
}
|
||||
|
||||
UriResourceNavigation navSegment = (UriResourceNavigation)part;
|
||||
entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat);
|
||||
}
|
||||
else {
|
||||
// For now, we'll only allow navigation just to directly linked navs
|
||||
throw new ODataApplicationException("[E109] Multi-level navigation not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
|
||||
}
|
||||
|
||||
//4. configure the response object
|
||||
response.setContent(entityStream);
|
||||
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Lookup the EntitySet associated with an EntityType
|
||||
// In our example, we assume we have only one entityset for each entity type
|
||||
private EdmEntitySet entitySetFromType(EdmEntityType type) {
|
||||
return serviceMetadata
|
||||
.getEdm()
|
||||
.getEntityContainer()
|
||||
.getEntitySets()
|
||||
.stream()
|
||||
.filter((s) -> s.getEntityType().getName().equals(type.getName()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new ODataRuntimeException("[E144] No entity set found for type " + type.getFullQualifiedName()));
|
||||
}
|
||||
|
||||
//
|
||||
// private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) {
|
||||
// return entityType.getProperty(property.getName()) != null && property.isCollection();
|
||||
//}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private InputStream readRootEntity(EdmEntitySet entitySet, List<UriParameter> keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
EdmEntityType type = entitySet.getEntityType();
|
||||
JpaRepository repo = registry.getRepositoryForEntity(type);
|
||||
|
||||
// Get key value
|
||||
Long keyValue = getEntityKey(keyPredicates);
|
||||
Optional<Object> entry = repo.findById(keyValue);
|
||||
if ( !entry.isPresent()) {
|
||||
throw new ODataApplicationException(
|
||||
"[E116] NO entity found for the given key",
|
||||
HttpStatusCode.NOT_FOUND.getStatusCode(),
|
||||
Locale.ENGLISH);
|
||||
}
|
||||
|
||||
Entity e = entityMapper.map2entity(entitySet, entry.get());
|
||||
return serializeEntity(entitySet,e,responseFormat);
|
||||
}
|
||||
|
||||
private InputStream serializeEntity(EdmEntitySet entitySet, Entity entity,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
ContextURL contextUrl = ContextURL.with().entitySet(entitySet).build();
|
||||
// expand and select currently not supported
|
||||
EntitySerializerOptions options = EntitySerializerOptions
|
||||
.with()
|
||||
.contextURL(contextUrl)
|
||||
.build();
|
||||
|
||||
ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||
|
||||
SerializerResult serializerResult = serializer.entity(serviceMetadata, entitySet.getEntityType(), entity, options);
|
||||
return serializerResult.getContent();
|
||||
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// protected InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List<UriParameter> rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException {
|
||||
//
|
||||
// Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates);
|
||||
// try {
|
||||
// Collection<Object> set = (Collection<Object>)PropertyUtils.getProperty(jpaEntity, property.getName());
|
||||
// EdmEntitySet entitySet = entitySetFromType(property.getType());
|
||||
// ContextURL contextUrl = ContextURL
|
||||
// .with()
|
||||
// .entitySet(entitySet)
|
||||
// .build();
|
||||
//
|
||||
// EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions
|
||||
// .with()
|
||||
// .contextURL(contextUrl)
|
||||
// .build();
|
||||
//
|
||||
// EntityCollection result = new EntityCollection();
|
||||
//
|
||||
// set.stream()
|
||||
// .map((o) -> this.entityMapper.map2entity(entitySet, o))
|
||||
// .forEach((e) -> result.getEntities().add(e));
|
||||
//
|
||||
// ODataSerializer serializer = odata.createSerializer(responseFormat);
|
||||
// SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options);
|
||||
// return serializerResult.getContent();
|
||||
// }
|
||||
// catch(Exception ex) {
|
||||
// throw new ODataRuntimeException("[E181] Error accessing database", ex);
|
||||
// }
|
||||
// }
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet entitySet, List<UriParameter> rootPredicates, EdmNavigationProperty property, List<UriParameter> parentPredicates, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
|
||||
|
||||
JpaRepository<Object,Object> repo = (JpaRepository<Object,Object>)registry.getRepositoryForEntity(entitySet.getEntityType());
|
||||
EdmEntityRepository<Object> relatedRepo = (EdmEntityRepository<Object>)registry.getRepositoryForEntity(property.getType());
|
||||
|
||||
// We assume here that we have a bi-directional 1:N relationship, so we'll
|
||||
// always have a property in the child entity that points to the parent
|
||||
Class<?> rootClass = ((EdmEntityRepository)repo).getEntityClass();
|
||||
Class<?> relatedClass = ((EdmEntityRepository)relatedRepo).getEntityClass();
|
||||
|
||||
SingularAttribute fk = emf.getMetamodel()
|
||||
.entity(rootClass)
|
||||
.getSingularAttributes()
|
||||
.stream()
|
||||
.filter((attr) -> {
|
||||
boolean b = attr.isAssociation() && attr.getJavaType().isAssignableFrom(relatedClass);
|
||||
return b;
|
||||
})
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if ( fk == null ) {
|
||||
throw new ODataRuntimeException("[E230] No singular attribute of child class '" + relatedClass.getName() + "' found" );
|
||||
}
|
||||
|
||||
Long pkValue = getEntityKey(rootPredicates);
|
||||
EntityManager em = this.emf.createEntityManager();
|
||||
try {
|
||||
// Read data from DB
|
||||
Object root = em.find(rootClass, pkValue);
|
||||
Object related = this.entityMapper.getPropertyValue(root, fk.getName());
|
||||
|
||||
EdmEntitySet relatedEntitySet = entitySetFromType(property.getType());
|
||||
Entity e = entityMapper.map2entity(relatedEntitySet, related);
|
||||
return serializeEntity(relatedEntitySet,e,responseFormat);
|
||||
}
|
||||
finally {
|
||||
em.close();
|
||||
}
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// private Object readJPAEntity(EdmEntitySet edmEntitySet, List<UriParameter> keyPredicates) throws ODataApplicationException {
|
||||
// EdmEntityType type = edmEntitySet.getEntityType();
|
||||
// JpaRepository<Object,Object> repo = (JpaRepository<Object,Object>)registry.getRepositoryForEntity(type);
|
||||
//
|
||||
// // Get key value
|
||||
// Object keyValue = getEntityKey(type,keyPredicates);
|
||||
// Object entry = repo
|
||||
// .findById(keyValue)
|
||||
// .orElseThrow(
|
||||
// () -> new ODataApplicationException("[E116] NO entity found for the given key",
|
||||
// HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH));
|
||||
//
|
||||
// return entry;
|
||||
// }
|
||||
|
||||
private Long getEntityKey(List<UriParameter> keyPredicates) {
|
||||
|
||||
if ( keyPredicates.size() > 1 ) {
|
||||
throw new ODataRuntimeException("[E131] Composite keys are not supported");
|
||||
}
|
||||
|
||||
// For now, we'll assume we only have numeric keys.
|
||||
UriParameter keyParam = keyPredicates.get(0);
|
||||
try {
|
||||
return Long.parseLong(keyParam.getText());
|
||||
}
|
||||
catch(NumberFormatException nfe) {
|
||||
throw new ODataRuntimeException("[E140] Invalid key value. Only numeric keys are supported by this service");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.server.api.processor.EntityProcessor#createEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType)
|
||||
*/
|
||||
@Override
|
||||
public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.server.api.processor.EntityProcessor#updateEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType)
|
||||
*/
|
||||
@Override
|
||||
public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.olingo.server.api.processor.EntityProcessor#deleteEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo)
|
||||
*/
|
||||
@Override
|
||||
public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import org.baeldung.examples.olingo4.domain.CarMaker;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CarMakerRepository extends EdmEntityRepository<CarMaker>, JpaRepository<CarMaker, Long>, JpaSpecificationExecutor<CarMaker> {
|
||||
|
||||
public default String getEdmEntityName() { return CarMaker.class.getSimpleName();}
|
||||
@Override
|
||||
default Class<CarMaker> getEntityClass() {
|
||||
return CarMaker.class;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.examples.olingo4.domain.CarModel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CarModelRepository extends EdmEntityRepository<CarModel>, JpaRepository<CarModel, Long>, JpaSpecificationExecutor<CarModel> {
|
||||
|
||||
public List<CarModel> findByMakerId(Long makerId);
|
||||
|
||||
public default String getEdmEntityName() { return CarModel.class.getSimpleName();}
|
||||
|
||||
@Override
|
||||
default Class<CarModel> getEntityClass() {
|
||||
return CarModel.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
|
||||
/**
|
||||
* @author Philippe
|
||||
*
|
||||
*/
|
||||
public interface EdmEntityRepository<E> {
|
||||
|
||||
public String getEdmEntityName();
|
||||
public Class<E> getEntityClass();
|
||||
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package org.baeldung.examples.olingo4.repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.olingo.commons.api.edm.EdmEntityType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RepositoryRegistry {
|
||||
|
||||
private Map<String,JpaRepository<?,?>> repositoriesByClassName = new HashMap<>();
|
||||
|
||||
public RepositoryRegistry(List<EdmEntityRepository<?>> allRepositories) {
|
||||
|
||||
allRepositories.stream()
|
||||
.forEach((r) ->
|
||||
repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository<?,?>)r));
|
||||
|
||||
}
|
||||
|
||||
|
||||
public JpaRepository<?,?> getRepositoryForEntity(EdmEntityType entityType) {
|
||||
JpaRepository<?,?> repo = repositoriesByClassName.get(entityType.getName());
|
||||
return repo;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
jpa:
|
||||
show-sql: true
|
||||
open-in-view: true
|
||||
hibernate:
|
||||
ddl-auto: update
|
|
@ -1,12 +0,0 @@
|
|||
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;
|
|
@ -1,16 +0,0 @@
|
|||
package org.baeldung.examples.olingo4;
|
||||
|
||||
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 Olingo4SampleApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/target
|
||||
/classes
|
||||
/checkouts
|
||||
profiles.clj
|
||||
pom.xml
|
||||
pom.xml.asc
|
||||
*.jar
|
||||
*.class
|
||||
/.lein-*
|
||||
/.nrepl-port
|
||||
.hgignore
|
||||
.hg/
|
|
@ -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)
|
|
@ -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})
|
|
@ -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,5 +3,6 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [String Matching in Groovy](http://www.baeldung.com/)
|
||||
- [Groovy def Keyword]
|
||||
|
||||
- [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)
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-groovy-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>core-groovy-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>${hsqldb.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>${spock-core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<scriptSourceDirectory>src/main/groovy</scriptSourceDirectory>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>generateStubs</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>generateTestStubs</goal>
|
||||
<goal>compileTests</goal>
|
||||
<goal>removeStubs</goal>
|
||||
<goal>removeTestStubs</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<!-- any version of Groovy \>= 1.5.0 should work here -->
|
||||
<version>${groovy.version}</version>
|
||||
<scope>runtime</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>junit5</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test5.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20.1</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven Assembly Plugin: needed to run the jar through command line -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<!-- get all project dependencies -->
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<!-- MainClass in mainfest make a executable jar -->
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.baeldung.MyJointCompilationApp</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- bind to the packaging phase -->
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<hsqldb.version>2.4.0</hsqldb.version>
|
||||
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<java.version>1.8</java.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<groovy.version>2.5.7</groovy.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-groovy-2</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
@ -15,25 +15,20 @@
|
|||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<version>${groovy-all.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-dateutil</artifactId>
|
||||
<version>${groovy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-sql</artifactId>
|
||||
<version>${groovy-sql.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
|
@ -56,21 +51,35 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<scriptSourceDirectory>src/main/groovy</scriptSourceDirectory>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmavenplus</groupId>
|
||||
<artifactId>gmavenplus-plugin</artifactId>
|
||||
<version>${gmavenplus-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>addSources</goal>
|
||||
<goal>addTestSources</goal>
|
||||
<goal>compile</goal>
|
||||
<goal>compileTests</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>3.3.0-01</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<compilerId>groovy-eclipse-compiler</compilerId>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-compiler</artifactId>
|
||||
<version>3.3.0-01</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-eclipse-batch</artifactId>
|
||||
<version>${groovy.version}-01</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
|
@ -101,13 +110,42 @@
|
|||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.20.1</version>
|
||||
<configuration>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
<useFile>false</useFile>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Spec.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven Assembly Plugin: needed to run the jar through command line -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<!-- get all project dependencies -->
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<!-- MainClass in mainfest make a executable jar -->
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>com.baeldung.MyJointCompilationApp</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<!-- bind to the packaging phase -->
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -118,14 +156,32 @@
|
|||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>bintray</id>
|
||||
<name>Groovy Bintray</name>
|
||||
<url>https://dl.bintray.com/groovy/maven</url>
|
||||
<releases>
|
||||
<!-- avoid automatic updates -->
|
||||
<updatePolicy>never</updatePolicy>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
<properties>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<groovy.version>2.5.6</groovy.version>
|
||||
<groovy-all.version>2.5.6</groovy-all.version>
|
||||
<groovy-sql.version>2.5.6</groovy-sql.version>
|
||||
<hsqldb.version>2.4.0</hsqldb.version>
|
||||
<spock-core.version>1.1-groovy-2.4</spock-core.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<commons-lang3.version>3.9</commons-lang3.version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
<groovy.version>2.5.7</groovy.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung
|
||||
|
||||
def calcSum(x, y) {
|
||||
x + y
|
||||
}
|
||||
|
||||
def calcSum2(x, y) {
|
||||
// DANGER! The variable "log" may be undefined
|
||||
log.info "Executing $x + $y"
|
||||
// DANGER! This method doesn't exist!
|
||||
calcSum3()
|
||||
// DANGER! The logged variable "z" is undefined!
|
||||
log.info("Logging an undefined variable: $z")
|
||||
}
|
||||
|
||||
calcSum(1,5)
|
|
@ -0,0 +1,120 @@
|
|||
package com.baeldung;
|
||||
|
||||
import groovy.lang.*;
|
||||
import groovy.util.GroovyScriptEngine;
|
||||
import groovy.util.ResourceException;
|
||||
import groovy.util.ScriptException;
|
||||
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import javax.script.ScriptEngine;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
public class MyJointCompilationApp {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(MyJointCompilationApp.class);
|
||||
private final GroovyClassLoader loader;
|
||||
private final GroovyShell shell;
|
||||
private final GroovyScriptEngine engine;
|
||||
private final ScriptEngine engineFromFactory;
|
||||
|
||||
public MyJointCompilationApp() {
|
||||
loader = new GroovyClassLoader(this.getClass().getClassLoader());
|
||||
shell = new GroovyShell(loader, new Binding());
|
||||
|
||||
URL url = null;
|
||||
try {
|
||||
url = new File("src/main/groovy/com/baeldung/").toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
LOG.error("Exception while creating url", e);
|
||||
}
|
||||
engine = new GroovyScriptEngine(new URL[] {url}, this.getClass().getClassLoader());
|
||||
engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine();
|
||||
}
|
||||
|
||||
private void addWithCompiledClasses(int x, int y) {
|
||||
LOG.info("Executing {} + {}", x, y);
|
||||
Object result1 = new CalcScript().calcSum(x, y);
|
||||
LOG.info("Result of CalcScript.calcSum() method is {}", result1);
|
||||
|
||||
Object result2 = new CalcMath().calcSum(x, y);
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result2);
|
||||
}
|
||||
|
||||
private void addWithGroovyShell(int x, int y) throws IOException {
|
||||
Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy"));
|
||||
LOG.info("Executing {} + {}", x, y);
|
||||
Object result = script.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcScript.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyShellRun() throws IOException {
|
||||
Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy"));
|
||||
LOG.info("Executing script run method");
|
||||
Object result = script.run();
|
||||
LOG.info("Result of CalcScript.run() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyClassLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException {
|
||||
Class calcClass = loader.parseClass(
|
||||
new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"));
|
||||
GroovyObject calc = (GroovyObject) calcClass.newInstance();
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x + 14, y + 14 });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithGroovyScriptEngine(int x, int y) throws IllegalAccessException,
|
||||
InstantiationException, ResourceException, ScriptException {
|
||||
Class<GroovyObject> calcClass = engine.loadScriptByName("CalcMath.groovy");
|
||||
GroovyObject calc = calcClass.newInstance();
|
||||
//WARNING the following will throw a ClassCastException
|
||||
//((CalcMath)calc).calcSum(1,2);
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithEngineFactory(int x, int y) throws IllegalAccessException,
|
||||
InstantiationException, javax.script.ScriptException, FileNotFoundException {
|
||||
Class calcClass = (Class) engineFromFactory.eval(
|
||||
new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")));
|
||||
GroovyObject calc = (GroovyObject) calcClass.newInstance();
|
||||
Object result = calc.invokeMethod("calcSum", new Object[] { x, y });
|
||||
LOG.info("Result of CalcMath.calcSum() method is {}", result);
|
||||
}
|
||||
|
||||
private void addWithStaticCompiledClasses() {
|
||||
LOG.info("Running the Groovy classes compiled statically...");
|
||||
addWithCompiledClasses(5, 10);
|
||||
|
||||
}
|
||||
|
||||
private void addWithDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException,
|
||||
ResourceException, ScriptException, javax.script.ScriptException {
|
||||
LOG.info("Invocation of a dynamic groovy script...");
|
||||
addWithGroovyShell(5, 10);
|
||||
LOG.info("Invocation of the run method of a dynamic groovy script...");
|
||||
addWithGroovyShellRun();
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyClassLoader...");
|
||||
addWithGroovyClassLoader(10, 30);
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine...");
|
||||
addWithGroovyScriptEngine(15, 0);
|
||||
LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine JSR223...");
|
||||
addWithEngineFactory(5, 6);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws InstantiationException, IllegalAccessException,
|
||||
ResourceException, ScriptException, IOException, javax.script.ScriptException {
|
||||
MyJointCompilationApp myJointCompilationApp = new MyJointCompilationApp();
|
||||
LOG.info("Example of addition operation via Groovy scripts integration with Java.");
|
||||
myJointCompilationApp.addWithStaticCompiledClasses();
|
||||
myJointCompilationApp.addWithDynamicCompiledClasses();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
Dear <% out << (user) %>,
|
||||
Please read the requested article below.
|
||||
<% out << (articleText) %>
|
||||
From,
|
||||
<% out << (signature) %>
|
|
@ -0,0 +1,3 @@
|
|||
Dear $user,
|
||||
Thanks for subscribing our services.
|
||||
${signature}
|
|
@ -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>
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
## Relevant articles:
|
||||
|
||||
- [Maps in Groovy](http://www.baeldung.com/)
|
||||
- [Maps in Groovy](https://www.baeldung.com/groovy-maps)
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
## Relevant Articles
|
||||
|
||||
- [Extending an Array’s Length](https://www.baeldung.com/java-array-add-element-at-the-end)
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.array.conversions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class StreamArrayConversion {
|
||||
|
||||
public static String[] stringStreamToStringArrayUsingFunctionalInterface(Stream<String> stringStream) {
|
||||
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
|
||||
@Override
|
||||
public String[] apply(int value) {
|
||||
return new String[value];
|
||||
}
|
||||
};
|
||||
|
||||
return stringStream.toArray(intFunction);
|
||||
}
|
||||
|
||||
public static String[] stringStreamToStringArrayUsingMethodReference(Stream<String> stringStream) {
|
||||
return stringStream.toArray(String[]::new);
|
||||
}
|
||||
|
||||
public static String[] stringStreamToStringArrayUsingLambda(Stream<String> stringStream) {
|
||||
return stringStream.toArray(value -> new String[value]);
|
||||
}
|
||||
|
||||
public static Integer[] integerStreamToIntegerArray(Stream<Integer> integerStream) {
|
||||
return integerStream.toArray(Integer[]::new);
|
||||
}
|
||||
|
||||
public static int[] intStreamToPrimitiveIntArray(Stream<Integer> integerStream) {
|
||||
return integerStream.mapToInt(i -> i).toArray();
|
||||
}
|
||||
|
||||
public static Stream<String> stringArrayToStreamUsingArraysStream(String[] stringArray) {
|
||||
return Arrays.stream(stringArray);
|
||||
}
|
||||
|
||||
public static Stream<String> stringArrayToStreamUsingStreamOf(String[] stringArray) {
|
||||
return Stream.of(stringArray);
|
||||
}
|
||||
|
||||
public static IntStream primitiveIntArrayToStreamUsingArraysStream(int[] intArray) {
|
||||
return Arrays.stream(intArray);
|
||||
}
|
||||
|
||||
public static Stream<int[]> primitiveIntArrayToStreamUsingStreamOf(int[] intArray) {
|
||||
return Stream.of(intArray);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.array.conversions;
|
||||
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.intStreamToPrimitiveIntArray;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.integerStreamToIntegerArray;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingFunctionalInterface;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingLambda;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.stringStreamToStringArrayUsingMethodReference;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.stringArrayToStreamUsingArraysStream;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.stringArrayToStreamUsingStreamOf;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.primitiveIntArrayToStreamUsingArraysStream;
|
||||
import static com.baeldung.array.conversions.StreamArrayConversion.primitiveIntArrayToStreamUsingStreamOf;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.Test;
|
||||
|
||||
public class StreamArrayConversionUnitTest {
|
||||
|
||||
private String[] stringArray = new String[]{"baeldung", "convert", "to", "string", "array"};
|
||||
private Integer[] integerArray = new Integer[]{1, 2, 3, 4, 5, 6, 7};
|
||||
private int[] intPrimitiveArray = new int[]{1, 2, 3, 4, 5, 6, 7};
|
||||
|
||||
@Test
|
||||
public void givenStringStream_thenConvertToStringArrayUsingFunctionalInterface() {
|
||||
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||
assertArrayEquals(stringArray, stringStreamToStringArrayUsingFunctionalInterface(stringStream));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringStream_thenConvertToStringArrayUsingMethodReference() {
|
||||
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||
assertArrayEquals(stringArray, stringStreamToStringArrayUsingMethodReference(stringStream));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringStream_thenConvertToStringArrayUsingLambda() {
|
||||
Stream<String> stringStream = Stream.of("baeldung", "convert", "to", "string", "array");
|
||||
assertArrayEquals(stringArray, stringStreamToStringArrayUsingLambda(stringStream));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntegerStream_thenConvertToIntegerArray() {
|
||||
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7);
|
||||
assertArrayEquals(integerArray, integerStreamToIntegerArray(integerStream));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIntStream_thenConvertToIntegerArray() {
|
||||
Stream<Integer> integerStream = IntStream.rangeClosed(1, 7).boxed();
|
||||
assertArrayEquals(intPrimitiveArray, intStreamToPrimitiveIntArray(integerStream));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringArray_whenConvertedTwoWays_thenConvertedStreamsAreEqual() {
|
||||
assertTrue(Iterators
|
||||
.elementsEqual(stringArrayToStreamUsingArraysStream(stringArray).iterator(),
|
||||
stringArrayToStreamUsingStreamOf(stringArray).iterator()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveArray_whenConvertedTwoWays_thenConvertedStreamsAreNotEqual() {
|
||||
assertFalse(Iterators.elementsEqual(
|
||||
primitiveIntArrayToStreamUsingArraysStream(intPrimitiveArray).iterator(),
|
||||
primitiveIntArrayToStreamUsingStreamOf(intPrimitiveArray).iterator()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
### Relevant Articles:
|
||||
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-lambda-effectively-final-local-variables)
|
|
@ -1,3 +1,5 @@
|
|||
## Relevant articles:
|
||||
|
||||
- [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms)
|
||||
- [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel)
|
||||
- [Understanding the NumberFormatException in Java](https://www.baeldung.com/java-number-format-exception)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.set;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CopySets {
|
||||
|
||||
// Using Java 10
|
||||
public static <T> Set<T> copyBySetCopyOf(Set<T> original) {
|
||||
Set<T> copy = Set.copyOf(original);
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,3 +7,5 @@
|
|||
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
|
||||
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)
|
||||
- [Guide to jlink](https://www.baeldung.com/jlink)
|
||||
- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference)
|
||||
- [Transforming an Empty String into an Empty Optional](https://www.baeldung.com/java-empty-string-to-empty-optional)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<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">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>core-java-11</artifactId>
|
||||
|
@ -12,7 +14,7 @@
|
|||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -21,6 +23,12 @@
|
|||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -41,6 +49,7 @@
|
|||
<maven.compiler.source.version>11</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>11</maven.compiler.target.version>
|
||||
<guava.version>27.1-jre</guava.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.predicate.not;
|
||||
|
||||
public class Person {
|
||||
private static final int ADULT_AGE = 18;
|
||||
|
||||
private int age;
|
||||
|
||||
public Person(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public boolean isAdult() {
|
||||
return age >= ADULT_AGE;
|
||||
}
|
||||
|
||||
public boolean isNotAdult() {
|
||||
return !isAdult();
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import junit.framework.TestSuite;
|
|||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
public class AppTest
|
||||
public class AppUnitTest
|
||||
extends TestCase
|
||||
{
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ public class AppTest
|
|||
*
|
||||
* @param testName name of the test case
|
||||
*/
|
||||
public AppTest( String testName )
|
||||
public AppUnitTest(String testName )
|
||||
{
|
||||
super( testName );
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class AppTest
|
|||
*/
|
||||
public static Test suite()
|
||||
{
|
||||
return new TestSuite( AppTest.class );
|
||||
return new TestSuite( AppUnitTest.class );
|
||||
}
|
||||
|
||||
/**
|
|
@ -32,7 +32,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class HttpClientTest {
|
||||
public class HttpClientUnitTest {
|
||||
|
||||
@Test
|
||||
public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException {
|
|
@ -19,7 +19,7 @@ import java.time.Duration;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpRequestTest {
|
||||
public class HttpRequestUnitTest {
|
||||
|
||||
@Test
|
||||
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
|
@ -14,7 +14,7 @@ import java.net.http.HttpResponse;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
public class HttpResponseTest {
|
||||
public class HttpResponseUnitTest {
|
||||
|
||||
@Test
|
||||
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
|
@ -0,0 +1,61 @@
|
|||
package com.baeldung.predicate.not;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class PersonUnitTest {
|
||||
private List<Person> people;
|
||||
|
||||
@BeforeEach
|
||||
void preparePeople() {
|
||||
people = Arrays.asList(
|
||||
new Person(1),
|
||||
new Person(18),
|
||||
new Person(2)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeople_whenFilterIsAdult_thenOneResult() {
|
||||
List<Person> adults = people.stream()
|
||||
.filter(Person::isAdult)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(adults).size().isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeople_whenFilterIsAdultNegated_thenTwoResults() {
|
||||
List<Person> nonAdults = people.stream()
|
||||
.filter(person -> !person.isAdult())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(nonAdults).size().isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeople_whenFilterIsNotAdult_thenTwoResults() {
|
||||
List<Person> nonAdults = people.stream()
|
||||
.filter(Person::isNotAdult)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(nonAdults).size().isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenPeople_whenFilterNotIsAdult_thenTwoResults() {
|
||||
List<Person> nonAdults = people.stream()
|
||||
.filter(not(Person::isAdult))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(nonAdults).size().isEqualTo(2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class StringAPITest {
|
||||
|
||||
@Test
|
||||
public void whenPositiveArgument_thenReturnIndentedString() {
|
||||
String multilineStr = "This is\na multiline\nstring.";
|
||||
String outputStr = " This is\n a multiline\n string.\n";
|
||||
|
||||
String postIndent = multilineStr.indent(3);
|
||||
|
||||
assertThat(postIndent, equalTo(outputStr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenNegativeArgument_thenReturnReducedIndentedString() {
|
||||
String multilineStr = " This is\n a multiline\n string.";
|
||||
String outputStr = " This is\n a multiline\n string.\n";
|
||||
|
||||
String postIndent = multilineStr.indent(-2);
|
||||
|
||||
assertThat(postIndent, equalTo(outputStr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTransformUsingLamda_thenReturnTransformedString() {
|
||||
String result = "hello".transform(input -> input + " world!");
|
||||
|
||||
assertThat(result, equalTo("hello world!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenTransformUsingParseInt_thenReturnInt() {
|
||||
int result = "42".transform(Integer::parseInt);
|
||||
|
||||
assertThat(result, equalTo(42));
|
||||
}
|
||||
}
|
|
@ -4,3 +4,5 @@
|
|||
|
||||
### Relevant Articles:
|
||||
- [Anonymous Classes in Java](http://www.baeldung.com/)
|
||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
||||
- [Run JAR Application With Command Line Arguments](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
<artifactId>icu4j</artifactId>
|
||||
<version>${icu.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package com.baeldung.delay;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Delay {
|
||||
|
||||
public static void main(String args[]) throws InterruptedException {
|
||||
|
||||
threadSleep(4, 1);
|
||||
|
||||
timeunitSleep(4, 1);
|
||||
|
||||
delayedServiceTask(5);
|
||||
|
||||
fixedRateServiceTask(5);
|
||||
|
||||
System.out.println("Done.");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
private static void threadSleep(Integer iterations, Integer secondsToSleep) {
|
||||
|
||||
for (Integer i = 0; i < iterations; i++) {
|
||||
|
||||
System.out.println("This is loop iteration number " + i.toString());
|
||||
|
||||
try {
|
||||
Thread.sleep(secondsToSleep * 1000);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void timeunitSleep(Integer iterations, Integer secondsToSleep) {
|
||||
|
||||
for (Integer i = 0; i < iterations; i++) {
|
||||
|
||||
System.out.println("This is loop iteration number " + i.toString());
|
||||
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(secondsToSleep);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void delayedServiceTask(Integer delayInSeconds) {
|
||||
|
||||
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
executorService.schedule(Delay::someTask1, delayInSeconds, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
private static void fixedRateServiceTask(Integer delayInSeconds) {
|
||||
|
||||
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
ScheduledFuture<?> sf = executorService.scheduleAtFixedRate(Delay::someTask2, 0, delayInSeconds,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(20);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
sf.cancel(true);
|
||||
|
||||
}
|
||||
|
||||
private static void someTask1() {
|
||||
System.out.println("Task 1 completed.");
|
||||
}
|
||||
|
||||
private static void someTask2() {
|
||||
System.out.println("Task 2 completed.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<persistence-unit
|
||||
name="com.baeldung.optionalReturnType"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
<description>Persist Optional Return Type Demo</description>
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.baeldung.optionalReturnType.User</class>
|
||||
<class>com.baeldung.optionalReturnType.UserOptional</class>
|
||||
<!--
|
||||
<class>com.baeldung.optionalReturnType.UserOptionalField</class>
|
||||
-->
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="javax.persistence.jdbc.driver"
|
||||
value="org.h2.Driver" />
|
||||
<property name="javax.persistence.jdbc.url"
|
||||
value="jdbc:h2:mem:test" />
|
||||
<property name="javax.persistence.jdbc.user" value="sa" />
|
||||
<property name="javax.persistence.jdbc.password" value="" />
|
||||
<property name="hibernate.dialect"
|
||||
value="org.hibernate.dialect.H2Dialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||
<property name="show_sql" value="true" />
|
||||
<property name="hibernate.temp.use_jdbc_metadata_defaults"
|
||||
value="false" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
|
@ -101,7 +101,7 @@ public class OptionalChainingUnitTest {
|
|||
}
|
||||
|
||||
private Optional<String> createOptional(String input) {
|
||||
if (input == null || input == "" || input == "empty") {
|
||||
if (input == null || "".equals(input) || "empty".equals(input)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
||||
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||
- [Java 9 Process API Improvements](https://www.baeldung.com/java-9-process-api)
|
||||
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
|
||||
|
||||
|
||||
- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new)
|
||||
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
|
||||
- [Java 9 Optional API Additions](https://www.baeldung.com/java-9-optional)
|
||||
- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture)
|
||||
- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api)
|
||||
- [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods)
|
||||
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
||||
- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity)
|
||||
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api)
|
||||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||
- [Filtering a Stream of Optionals in Java](https://www.baeldung.com/java-filter-stream-of-optional)
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
public class Slf4jLogger implements System.Logger {
|
||||
|
||||
|
@ -74,26 +75,27 @@ public class Slf4jLogger implements System.Logger {
|
|||
if (!isLoggable(level)) {
|
||||
return;
|
||||
}
|
||||
String message = MessageFormat.format(format, params);
|
||||
|
||||
switch (level) {
|
||||
case TRACE:
|
||||
logger.trace(format, params);
|
||||
logger.trace(message);
|
||||
break;
|
||||
case DEBUG:
|
||||
logger.debug(format, params);
|
||||
logger.debug(message);
|
||||
break;
|
||||
case INFO:
|
||||
logger.info(format, params);
|
||||
logger.info(message);
|
||||
break;
|
||||
case WARNING:
|
||||
logger.warn(format, params);
|
||||
logger.warn(message);
|
||||
break;
|
||||
case ERROR:
|
||||
logger.error(format, params);
|
||||
logger.error(message);
|
||||
break;
|
||||
case ALL:
|
||||
default:
|
||||
logger.info(format, params);
|
||||
logger.info(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,3 +15,4 @@
|
|||
- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection)
|
||||
- [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays)
|
||||
- [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array)
|
||||
- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
=========
|
||||
|
||||
## Core Java Collections Array List Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Immutable ArrayList in Java](http://www.baeldung.com/java-immutable-list)
|
||||
- [Guide to the Java ArrayList](http://www.baeldung.com/java-arraylist)
|
||||
- [Add Multiple Items to an Java ArrayList](http://www.baeldung.com/java-add-items-array-list)
|
||||
- [ClassCastException: Arrays$ArrayList cannot be cast to ArrayList](https://www.baeldung.com/java-classcastexception-arrays-arraylist)
|
||||
- [Multi Dimensional ArrayList in Java](https://www.baeldung.com/java-multi-dimensional-arraylist)
|
|
@ -0,0 +1,46 @@
|
|||
<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-java-collections-array-list</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-collections-array-list</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.java.list;
|
||||
|
||||
public class Flower {
|
||||
|
||||
private String name;
|
||||
private int petals;
|
||||
|
||||
public Flower(String name, int petals) {
|
||||
this.name = name;
|
||||
this.petals = petals;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getPetals() {
|
||||
return petals;
|
||||
}
|
||||
|
||||
public void setPetals(int petals) {
|
||||
this.petals = petals;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,17 @@
|
|||
=========
|
||||
|
||||
## Core Java Collections List Cookbooks and Examples
|
||||
|
||||
### Relevant Articles:
|
||||
- [Check If Two Lists are Equal in Java](http://www.baeldung.com/java-test-a-list-for-ordinality-and-equality)
|
||||
- [Java 8 Streams: Find Items From One List Based On Values From Another List](https://www.baeldung.com/java-streams-find-list-items)
|
||||
- [A Guide to the Java LinkedList](http://www.baeldung.com/java-linkedlist)
|
||||
- [Java List UnsupportedOperationException](http://www.baeldung.com/java-list-unsupported-operation-exception)
|
||||
- [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line)
|
||||
- [Ways to Iterate Over a List in Java](https://www.baeldung.com/java-iterate-list)
|
||||
- [Flattening Nested Collections in Java](http://www.baeldung.com/java-flatten-nested-collections)
|
||||
- [Intersection of Two Lists in Java](https://www.baeldung.com/java-lists-intersection)
|
||||
- [Determine If All Elements Are the Same in a Java List](https://www.baeldung.com/java-list-all-equal)
|
||||
- [List of Primitive Integer Values in Java](https://www.baeldung.com/java-list-primitive-int)
|
||||
- [Performance Comparison of Primitive Lists in Java](https://www.baeldung.com/java-list-primitive-performance)
|
||||
- [Filtering a Java Collection by a List](https://www.baeldung.com/java-filter-collection-by-list)
|
|
@ -0,0 +1,76 @@
|
|||
<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-java-collections-list-2</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>core-java-collections-list-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-java</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sf.trove4j</groupId>
|
||||
<artifactId>trove4j</artifactId>
|
||||
<version>${trove4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.unimi.dsi</groupId>
|
||||
<artifactId>fastutil</artifactId>
|
||||
<version>${fastutil.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>colt</groupId>
|
||||
<artifactId>colt</artifactId>
|
||||
<version>${colt.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
<trove4j.version>3.0.2</trove4j.version>
|
||||
<fastutil.version>8.1.0</fastutil.version>
|
||||
<colt.version>1.2.0</colt.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue