Merge pull request #2 from eugenp/master

merging
This commit is contained in:
Kıvılcım 2019-04-02 22:54:09 +03:00 committed by GitHub
commit 0a8d9fe187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
710 changed files with 58972 additions and 444 deletions

View File

@ -0,0 +1,45 @@
package com.baeldung.algorithms.relativelyprime;
import java.math.BigInteger;
class RelativelyPrime {
static boolean iterativeRelativelyPrime(int a, int b) {
return iterativeGCD(a, b) == 1;
}
static boolean recursiveRelativelyPrime(int a, int b) {
return recursiveGCD(a, b) == 1;
}
static boolean bigIntegerRelativelyPrime(int a, int b) {
return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).equals(BigInteger.ONE);
}
private static int iterativeGCD(int a, int b) {
int tmp;
while (b != 0) {
if (a < b) {
tmp = a;
a = b;
b = tmp;
}
tmp = b;
b = a % b;
a = tmp;
}
return a;
}
private static int recursiveGCD(int a, int b) {
if (b == 0) {
return a;
}
if (a < b) {
return recursiveGCD(b, a);
}
return recursiveGCD(b, a % b);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.algorithms.relativelyprime;
import org.junit.Test;
import static com.baeldung.algorithms.relativelyprime.RelativelyPrime.*;
import static org.assertj.core.api.Assertions.assertThat;
public class RelativelyPrimeUnitTest {
@Test
public void givenNonRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnFalse() {
boolean result = iterativeRelativelyPrime(45, 35);
assertThat(result).isFalse();
}
@Test
public void givenRelativelyPrimeNumbers_whenCheckingIteratively_shouldReturnTrue() {
boolean result = iterativeRelativelyPrime(500, 501);
assertThat(result).isTrue();
}
@Test
public void givenNonRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnFalse() {
boolean result = recursiveRelativelyPrime(45, 35);
assertThat(result).isFalse();
}
@Test
public void givenRelativelyPrimeNumbers_whenCheckingRecursively_shouldReturnTrue() {
boolean result = recursiveRelativelyPrime(500, 501);
assertThat(result).isTrue();
}
@Test
public void givenNonRelativelyPrimeNumbers_whenCheckingUsingBigIntegers_shouldReturnFalse() {
boolean result = bigIntegerRelativelyPrime(45, 35);
assertThat(result).isFalse();
}
@Test
public void givenRelativelyPrimeNumbers_whenCheckingBigIntegers_shouldReturnTrue() {
boolean result = bigIntegerRelativelyPrime(500, 501);
assertThat(result).isTrue();
}
}

View File

@ -1,12 +1,7 @@
issuer:
uri: http://localhost:8080/uaa
spring_profiles: postgresql,default
database.driverClassName: org.postgresql.Driver
database.url: jdbc:postgresql:uaadb2
database.username: postgres
database.password: postgres
spring_profiles: default,hsqldb
encryption:
active_key_label: CHANGE-THIS-KEY

View File

@ -1,23 +1,11 @@
# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties)
#spring.security.oauth2.client.provider.*= # OAuth provider details.
#spring.security.oauth2.client.registration.*= # OAuth client registrations.
server.port=8081
#server.servlet.context-path=/uaa-client-webapp
uaa.url=http://localhost:8080/uaa
resource.server.url=http://localhost:8082
spring.security.oauth2.client.registration.uaa.client-name=UAA OAuth2 Client
spring.security.oauth2.client.registration.uaa.client-id=client1
spring.security.oauth2.client.registration.uaa.client-secret=client1
spring.security.oauth2.client.registration.uaa.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.uaa.client-name=Web App Client
spring.security.oauth2.client.registration.uaa.client-id=webappclient
spring.security.oauth2.client.registration.uaa.client-secret=webappclientsecret
spring.security.oauth2.client.registration.uaa.scope=resource.read,resource.write,openid,profile
spring.security.oauth2.client.registration.uaa.redirect-uri=http://localhost:8081/login/oauth2/code/uaa
#spring.security.oauth2.client.registration.uaa.redirect-uri=http://localhost:8081/**
spring.security.oauth2.client.provider.uaa.token-uri=${uaa.url}/oauth/token
spring.security.oauth2.client.provider.uaa.authorization-uri=${uaa.url}/oauth/authorize
spring.security.oauth2.client.provider.uaa.jwk-set-uri=${uaa.url}/token_keys
spring.security.oauth2.client.provider.uaa.user-info-uri=${uaa.url}/userinfo
spring.security.oauth2.client.provider.uaa.user-name-attribute=user_name
spring.security.oauth2.client.provider.uaa.issuer-uri=http://localhost:8080/uaa/oauth/token

View File

@ -1,16 +1,3 @@
server.port=8082
uaa.url=http://localhost:8080/uaa
#approch1
spring.security.oauth2.resourceserver.jwt.issuer-uri=${uaa.url}/oauth/token
#approch2
#spring.security.oauth2.resourceserver.jwt.jwk-set-uri=${uaa.url}/token_key
# SECURITY OAUTH2 CLIENT (OAuth2ClientProperties)
#security.oauth2.client.client-id=client1
#security.oauth2.client.client-secret=client1
#security.oauth2.resource.jwt.key-uri=${uaa.url}/token_key
#security.oauth2.resource.token-info-uri=${uaa.url}/oauth/check_token
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/uaa/oauth/token

View File

@ -9,3 +9,5 @@
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)

View File

@ -0,0 +1,37 @@
package com.baeldung
class Person {
private String firstname
private String lastname
private Integer age
Person(String firstname, String lastname, Integer age) {
this.firstname = firstname
this.lastname = lastname
this.age = age
}
String getFirstname() {
return firstname
}
void setFirstname(String firstname) {
this.firstname = firstname
}
String getLastname() {
return lastname
}
void setLastname(String lastname) {
this.lastname = lastname
}
Integer getAge() {
return age
}
void setAge(Integer age) {
this.age = age
}
}

View File

@ -0,0 +1,87 @@
package com.baeldung.closures
class Closures {
def printWelcome = {
println "Welcome to Closures!"
}
def print = { name ->
println name
}
def formatToLowerCase(name) {
return name.toLowerCase()
}
def formatToLowerCaseClosure = { name ->
return name.toLowerCase()
}
def count=0
def increaseCount = {
count++
}
def greet = {
return "Hello! ${it}"
}
def multiply = { x, y ->
return x*y
}
def calculate = {int x, int y, String operation ->
//log closure
def log = {
println "Performing $it"
}
def result = 0
switch(operation) {
case "ADD":
log("Addition")
result = x+y
break
case "SUB":
log("Subtraction")
result = x-y
break
case "MUL":
log("Multiplication")
result = x*y
break
case "DIV":
log("Division")
result = x/y
break
}
return result
}
def addAll = { int... args ->
return args.sum()
}
def volume(Closure areaCalculator, int... dimensions) {
if(dimensions.size() == 3) {
//consider dimension[0] = length, dimension[1] = breadth, dimension[2] = height
//for cube and cuboid
return areaCalculator(dimensions[0], dimensions[1]) * dimensions[2]
} else if(dimensions.size() == 2) {
//consider dimension[0] = radius, dimension[1] = height
//for cylinder and cone
return areaCalculator(dimensions[0]) * dimensions[1]
} else if(dimensions.size() == 1) {
//consider dimension[0] = radius
//for sphere
return areaCalculator(dimensions[0]) * dimensions[0]
}
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.closures
class Employee {
String fullName
}

View File

@ -0,0 +1,80 @@
package com.baeldung.closures
import spock.lang.Specification
class ClosuresUnitTest extends GroovyTestCase {
Closures closures = new Closures()
void testDeclaration() {
closures.print("Hello! Closure")
closures.formatToLowerCaseClosure("Hello! Closure")
closures.print.call("Hello! Closure")
closures.formatToLowerCaseClosure.call("Hello! Closure")
}
void testClosureVsMethods() {
assert closures.formatToLowerCase("TONY STARK") == closures.formatToLowerCaseClosure("Tony STark")
}
void testParameters() {
//implicit parameter
assert closures.greet("Alex") == "Hello! Alex"
//multiple parameters
assert closures.multiply(2, 4) == 8
assert closures.calculate(12, 4, "ADD") == 16
assert closures.calculate(12, 4, "SUB") == 8
assert closures.calculate(43, 8, "DIV") == 5.375
//varags
assert closures.addAll(12, 10, 14) == 36
}
void testClosureAsAnArgument() {
assert closures.volume({ l, b -> return l*b }, 12, 6, 10) == 720
assert closures.volume({ radius -> return Math.PI*radius*radius/3 }, 5, 10) == Math.PI * 250/3
}
void testGStringsLazyEvaluation() {
def name = "Samwell"
def welcomeMsg = "Welcome! $name"
assert welcomeMsg == "Welcome! Samwell"
// changing the name does not affect original interpolated value
name = "Tarly"
assert welcomeMsg != "Welcome! Tarly"
def fullName = "Tarly Samson"
def greetStr = "Hello! ${-> fullName}"
assert greetStr == "Hello! Tarly Samson"
// this time changing the variable affects the interpolated String's value
fullName = "Jon Smith"
assert greetStr == "Hello! Jon Smith"
}
void testClosureInLists() {
def list = [10, 11, 12, 13, 14, true, false, "BUNTHER"]
list.each {
println it
}
assert [13, 14] == list.findAll{ it instanceof Integer && it >= 13}
}
void testClosureInMaps() {
def map = [1:10, 2:30, 4:5]
assert [10, 60, 20] == map.collect{it.key * it.value}
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.lists
import com.baeldung.Person
import org.junit.Test
import static org.junit.Assert.*
class ListUnitTest {
private final personList = [
new Person("Regina", "Fitzpatrick", 25),
new Person("Abagail", "Ballard", 26),
new Person("Lucian", "Walter", 30),
]
@Test
void whenListContainsElement_thenCheckReturnsTrue() {
def list = ['a', 'b', 'c']
assertTrue(list.indexOf('a') > -1)
assertTrue(list.contains('a'))
}
@Test
void whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue() {
def list = ['a', 'b', 'c']
assertTrue('a' in list)
}
@Test
void givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList() {
assertTrue(personList.stream().anyMatch {it.age > 20})
assertFalse(personList.stream().allMatch {it.age < 30})
}
@Test
void givenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList() {
assertTrue(personList.any {it.age > 20})
assertFalse(personList.every {it.age < 30})
}
@Test
void givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements() {
assertTrue(personList.stream().filter {it.age > 20}.findAny().isPresent())
assertFalse(personList.stream().filter {it.age > 30}.findAny().isPresent())
assertTrue(personList.stream().filter {it.age > 20}.findAll().size() == 3)
assertTrue(personList.stream().filter {it.age > 30}.findAll().isEmpty())
}
@Test
void givenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements() {
assertNotNull(personList.find {it.age > 20})
assertNull(personList.find {it.age > 30})
assertTrue(personList.findAll {it.age > 20}.size() == 3)
assertTrue(personList.findAll {it.age > 30}.isEmpty())
}
}

View File

@ -1,10 +1,18 @@
package com.baeldung.map
import static org.junit.Assert.*
import com.baeldung.Person
import org.junit.Test
import static org.junit.Assert.*
class MapUnitTest {
private final personMap = [
Regina : new Person("Regina", "Fitzpatrick", 25),
Abagail: new Person("Abagail", "Ballard", 26),
Lucian : new Person("Lucian", "Walter", 30)
]
@Test
void whenUsingEach_thenMapIsIterated() {
def map = [
@ -82,4 +90,65 @@ class MapUnitTest {
println "Hex Code: $entry.key = Color Name: $entry.value"
}
}
@Test
void whenMapContainsKeyElement_thenCheckReturnsTrue() {
def map = [a: 'd', b: 'e', c: 'f']
assertTrue(map.containsKey('a'))
assertFalse(map.containsKey('e'))
assertTrue(map.containsValue('e'))
}
@Test
void whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue() {
def map = [a: 'd', b: 'e', c: 'f']
assertTrue('a' in map)
assertFalse('f' in map)
}
@Test
void whenMapContainsFalseBooleanValues_thenCheckReturnsFalse() {
def map = [a: true, b: false, c: null]
assertTrue(map.containsKey('b'))
assertTrue('a' in map)
assertFalse('b' in map)
assertFalse('c' in map)
}
@Test
void givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap() {
assertTrue(personMap.keySet().stream().anyMatch {it == "Regina"})
assertFalse(personMap.keySet().stream().allMatch {it == "Albert"})
assertFalse(personMap.values().stream().allMatch {it.age < 30})
assertTrue(personMap.entrySet().stream().anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"})
}
@Test
void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap() {
assertTrue(personMap.keySet().any {it == "Regina"})
assertFalse(personMap.keySet().every {it == "Albert"})
assertFalse(personMap.values().every {it.age < 30})
assertTrue(personMap.any {firstname, person -> firstname == "Abagail" && person.lastname == "Ballard"})
}
@Test
void givenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements() {
assertNotNull(personMap.find {it.key == "Abagail" && it.value.lastname == "Ballard"})
assertTrue(personMap.findAll {it.value.age > 20}.size() == 3)
}
@Test
void givenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements() {
assertTrue(
personMap.entrySet().stream()
.filter {it.key == "Abagail" && it.value.lastname == "Ballard"}
.findAny().isPresent())
assertTrue(
personMap.entrySet().stream()
.filter {it.value.age > 20}
.findAll().size() == 3)
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.set
import org.junit.Test
import static org.junit.Assert.assertTrue
class SetUnitTest {
@Test
void whenSetContainsElement_thenCheckReturnsTrue() {
def set = ['a', 'b', 'c'] as Set
assertTrue(set.contains('a'))
assertTrue('a' in set)
}
}

View File

@ -5,3 +5,4 @@
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
- [Java 11 Nest Based Access Control](https://www.baeldung.com/java-nest-based-access-control)
- [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client)
- [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector)

48
core-java-12/pom.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>core-java-12</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-12</name>
<packaging>jar</packaging>
<url>http://maven.apache.org</url>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source.version}</source>
<target>${maven.compiler.target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source.version>12</maven.compiler.source.version>
<maven.compiler.target.version>12</maven.compiler.target.version>
<assertj.version>3.6.1</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,71 @@
package com.baeldung.collectors;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import org.junit.Test;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.minBy;
import static java.util.stream.Collectors.teeing;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit tests for collectors additions in Java 12.
*/
public class CollectorsUnitTest {
@Test
public void whenTeeing_ItShouldCombineTheResultsAsExpected() {
List<Integer> numbers = Arrays.asList(42, 4, 2, 24);
Range range = numbers.stream()
.collect(teeing(minBy(Integer::compareTo), maxBy(Integer::compareTo), (min, max) -> new Range(min.orElse(null), max.orElse(null))));
assertThat(range).isEqualTo(new Range(2, 42));
}
/**
* Represents a closed range of numbers between {@link #min} and
* {@link #max}, both inclusive.
*/
private static class Range {
private final Integer min;
private final Integer max;
Range(Integer min, Integer max) {
this.min = min;
this.max = max;
}
Integer getMin() {
return min;
}
Integer getMax() {
return max;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Range range = (Range) o;
return Objects.equals(getMin(), range.getMin()) && Objects.equals(getMax(), range.getMax());
}
@Override
public int hashCode() {
return Objects.hash(getMin(), getMax());
}
@Override
public String toString() {
return "Range{" + "min=" + min + ", max=" + max + '}';
}
}
}

View File

@ -124,11 +124,44 @@ public class Java8SortUnitTest {
@Test
public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
final Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList());
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
}
@Test
public final void givenStreamComparatorOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
final List<Human> sortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName)).collect(Collectors.toList());
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
}
@Test
public final void givenStreamNaturalOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
final List<String> letters = Lists.newArrayList("B", "A", "C");
final List<String> reverseSortedLetters = letters.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
Assert.assertThat(reverseSortedLetters.get(0), equalTo("C"));
}
@Test
public final void givenStreamCustomOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
final Comparator<Human> reverseNameComparator = (h1, h2) -> h2.getName().compareTo(h1.getName());
final List<Human> reverseSortedHumans = humans.stream().sorted(reverseNameComparator).collect(Collectors.toList());
Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
}
@Test
public final void givenStreamComparatorOrdering_whenSortingEntitiesByNameReversed_thenCorrectlySorted() {
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
final List<Human> reverseSortedHumans = humans.stream().sorted(Comparator.comparing(Human::getName, Comparator.reverseOrder())).collect(Collectors.toList());
Assert.assertThat(reverseSortedHumans.get(0), equalTo(new Human("Sarah", 10)));
}
}

View File

@ -27,3 +27,4 @@
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)

View File

@ -33,3 +33,4 @@
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
- [Defining a Char Stack in Java](https://www.baeldung.com/java-char-stack)
- [Time Comparison of Arrays.sort(Object[]) and Arrays.sort(int[])](https://www.baeldung.com/arrays-sortobject-vs-sortint)

View File

@ -16,3 +16,4 @@
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
- [What is Thread-Safety and How to Achieve it](https://www.baeldung.com/java-thread-safety)
- [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread)

View File

@ -1,35 +1,27 @@
package com.baeldung.socket.read;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.io.*;
public class Client {
//Initialize socket, input and output stream
private Socket socket = null;
private DataInputStream in = null;
private DataOutputStream out = null;
public void runClient(String ip, int port) {
try {
socket = new Socket(ip, port);
Socket socket = new Socket(ip, port);
System.out.println("Connected to server ...");
in = new DataInputStream(System.in);
out = new DataOutputStream(socket.getOutputStream());
} catch(Exception e) {
e.printStackTrace();
}
DataInputStream in = new DataInputStream(System.in);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
char type = 's'; // s for string
int length = 29;
String data = "This is a string of length 29";
byte[] dataInBytes = data.getBytes();
byte[] dataInBytes = data.getBytes(StandardCharsets.UTF_8);
//Sending data in TLV format
try {
out.writeChar(type);
out.writeInt(length);
out.write(dataInBytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

View File

@ -1,48 +1,46 @@
package com.baeldung.socket.read;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.io.*;
public class Server {
//Socket and input stream
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in = null;
public void runServer(int port) {
//Start the server and wait for connection
try {
server = new ServerSocket(port);
ServerSocket server = new ServerSocket(port);
System.out.println("Server Started. Waiting for connection ...");
socket = server.accept();
Socket socket = server.accept();
System.out.println("Got connection from client.");
//Get input stream from socket variable and convert the same to DataInputStream
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//Read type and length of data
char dataType = in.readChar();
int length = in.readInt();
System.out.println("Type : "+dataType);
System.out.println("Lenght :"+length);
if(dataType == 's') {
//Read String data in bytes
byte[] messageByte = new byte[length];
boolean end = false;
String dataString = "";
StringBuilder dataString = new StringBuilder(length);
int totalBytesRead = 0;
//We need to run while loop, to read all data in that stream
while(!end) {
int currentBytesRead = in.read(messageByte);
totalBytesRead = currentBytesRead + totalBytesRead;
if(totalBytesRead <= length) {
dataString += new String(messageByte,0,currentBytesRead);
dataString.append(new String(messageByte,0,currentBytesRead,StandardCharsets.UTF_8));
} else {
dataString += new String(messageByte,0,length - totalBytesRead + currentBytesRead);
dataString.append(new String(messageByte,0,length - totalBytesRead + currentBytesRead,StandardCharsets.UTF_8));
}
if(dataString.length()>=length) {
end = true;
}
}
System.out.println("Read "+length+" bytes of message from client. Message = "+dataString);;
System.out.println("Read "+length+" bytes of message from client. Message = "+dataString);
}
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -6,3 +6,5 @@ This module uses Java 9, so make sure to have the JDK 9 installed to run it.
### Relevant Articles:
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
- [Guide to java.lang.Process API](https://www.baeldung.com/java-process-api)
- [Guide to java.lang.ProcessBuilder API](https://www.baeldung.com/java-lang-processbuilder-api)

View File

@ -50,3 +50,4 @@
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
- [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar)
- [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post)

View File

@ -3,4 +3,4 @@
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
- [Split a List into Parts in Kotlin](https://www.baeldung.com/kotlin-split-list-into-parts)
- [String Comparison in Kotlin](https://www.baeldung.com/kotlin-string-comparison)

View File

@ -13,4 +13,66 @@
<relativePath>../parent-kotlin</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit.platform.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<kotlin.version>1.2.71</kotlin.version>
<junit.platform.version>1.1.1</junit.platform.version>
<junit.vintage.version>5.2.0</junit.vintage.version>
<assertj.version>3.10.0</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (ch in 'a'..'f') {
print(ch)
}
println()
for (ch in 'f' downTo 'a') {
print(ch)
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.range
enum class Color(val rgb: Int) {
BLUE(0x0000FF),
GREEN(0x008000),
RED(0xFF0000),
MAGENTA(0xFF00FF),
YELLOW(0xFFFF00);
}
fun main(args: Array<String>) {
println(Color.values().toList());
val red = Color.RED
val yellow = Color.YELLOW
val range = red..yellow
println(range.contains(Color.MAGENTA))
println(range.contains(Color.BLUE))
println(range.contains(Color.GREEN))
}

View File

@ -0,0 +1,18 @@
package com.baeldung.range
fun main(args: Array<String>) {
val r = 1..10
//Apply filter
val f = r.filter { it -> it % 2 == 0 }
println(f)
//Map
val m = r.map { it -> it * it }
println(m)
//Reduce
val rdc = r.reduce { a, b -> a + b }
println(rdc)
}

View File

@ -0,0 +1,8 @@
package com.baeldung.range
fun main(args: Array<String>) {
println((1..9).first)
println((1..9 step 2).step)
println((3..9).reversed().last)
}

View File

@ -0,0 +1,14 @@
package com.baeldung.range
fun main(args: Array<String>) {
val r = 1..20
println(r.min())
println(r.max())
println(r.sum())
println(r.average())
println(r.count())
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
println(repeated.distinct())
}

View File

@ -0,0 +1,28 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (i in 1..9) {
print(i)
}
println()
for (i in 9 downTo 1) {
print(i)
}
println()
for (i in 1.rangeTo(9)) {
print(i)
}
println()
for (i in 9.downTo(1)) {
print(i)
}
println()
for (i in 1 until 9) {
print(i)
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.range
fun main(args: Array<String>) {
(1..9).reversed().forEach {
print(it)
}
println()
(1..9).reversed().step(3).forEach {
print(it)
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.range
fun main(args: Array<String>) {
for(i in 1..9 step 2){
print(i)
}
println()
for (i in 9 downTo 1 step 2){
print(i)
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.range
fun main(args: Array<String>) {
for (i in 1 until 9) {
print(i)
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class CharRangeTest {
@Test
fun testCharRange() {
assertEquals(listOf('a', 'b', 'c'), ('a'..'c').toList())
}
@Test
fun testCharDownRange() {
assertEquals(listOf('c', 'b', 'a'), ('c'.downTo('a')).toList())
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class ColorTest {
@Test
fun testEnumRange() {
println(Color.values().toList());
val red = Color.RED
val yellow = Color.YELLOW
val range = red..yellow
assertTrue { range.contains(Color.MAGENTA) }
assertFalse { range.contains(Color.BLUE) }
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class FilterTest {
val r = 1..10
@Test
fun filterTest() {
assertEquals(listOf(2, 4, 6, 8, 10), r.filter { it -> it % 2 == 0 }.toList())
}
@Test
fun mapTest() {
assertEquals(listOf(1, 4, 9, 16, 25, 36, 49, 64, 81, 100), r.map { it -> it * it }.toList())
}
@Test
fun reduceTest() {
assertEquals(55, r.reduce { a, b -> a + b })
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class FirstLastTest {
@Test
fun testFirst() {
assertEquals(1, (1..9).first)
}
@Test
fun testLast() {
assertEquals(9, (1..9).last)
}
@Test
fun testStep() {
assertEquals(2, (1..9 step 2).step)
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class OtherRangeFunctionsTest {
val r = 1..20
val repeated = listOf(1, 1, 2, 4, 4, 6, 10)
@Test
fun testMin() {
assertEquals(1, r.min())
}
@Test
fun testMax() {
assertEquals(20, r.max())
}
@Test
fun testSum() {
assertEquals(210, r.sum())
}
@Test
fun testAverage() {
assertEquals(10.5, r.average())
}
@Test
fun testCount() {
assertEquals(20, r.count())
}
@Test
fun testDistinct() {
assertEquals(listOf(1, 2, 4, 6, 10), repeated.distinct())
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class RangeTest {
@Test
fun testRange() {
assertEquals(listOf(1,2,3), (1.rangeTo(3).toList()))
}
@Test
fun testDownTo(){
assertEquals(listOf(3,2,1), (3.downTo(1).toList()))
}
@Test
fun testUntil(){
assertEquals(listOf(1,2), (1.until(3).toList()))
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class ReverseRangeTest {
@Test
fun reversedTest() {
assertEquals(listOf(9, 6, 3), (1..9).reversed().step(3).toList())
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class StepTest {
@Test
fun testStep() {
assertEquals(listOf(1, 3, 5, 7, 9), (1..9 step 2).toList())
}
@Test
fun testStepDown() {
assertEquals(listOf(9, 7, 5, 3, 1), (9 downTo 1 step 2).toList())
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung.range
import org.junit.Test
import kotlin.test.assertEquals
class UntilRangeTest {
@Test
fun testUntil() {
assertEquals(listOf(1, 2, 3, 4), (1 until 5).toList())
}
}

View File

@ -55,3 +55,4 @@
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
- [Delegation Pattern in Kotlin](https://www.baeldung.com/kotlin-delegation-pattern)

View File

@ -12,4 +12,5 @@
- [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives)
- [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject)
- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
- [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list)

View File

@ -6,4 +6,4 @@
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:
- [Mapping Multiple JSON Fields to One Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)

View File

@ -0,0 +1,45 @@
<?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>java-collections-maps-2</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>java-collections-maps-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.eclipse.collections</groupId>
<artifactId>eclipse-collections</artifactId>
<version>${eclipse-collections.version}</version>
</dependency>
<dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>8.1.0</version>
</dependency>
<dependency>
<groupId>colt</groupId>
<artifactId>colt</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<properties>
<eclipse-collections.version>8.2.0</eclipse-collections.version>
</properties>
</project>

View File

@ -0,0 +1,69 @@
package com.baeldung.map;
import cern.colt.map.AbstractIntDoubleMap;
import cern.colt.map.OpenIntDoubleHashMap;
import gnu.trove.map.TDoubleIntMap;
import gnu.trove.map.hash.TDoubleIntHashMap;
import it.unimi.dsi.fastutil.ints.Int2BooleanMap;
import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2BooleanSortedMap;
import it.unimi.dsi.fastutil.ints.Int2BooleanSortedMaps;
import org.eclipse.collections.api.map.primitive.ImmutableIntIntMap;
import org.eclipse.collections.api.map.primitive.MutableIntIntMap;
import org.eclipse.collections.api.map.primitive.MutableObjectDoubleMap;
import org.eclipse.collections.impl.factory.primitive.IntIntMaps;
import org.eclipse.collections.impl.factory.primitive.ObjectDoubleMaps;
public class PrimitiveMaps {
public static void main(String[] args) {
eclipseCollectionsMap();
troveMap();
coltMap();
fastutilMap();
}
private static void fastutilMap() {
Int2BooleanMap int2BooleanMap = new Int2BooleanOpenHashMap();
int2BooleanMap.put(1, true);
int2BooleanMap.put(7, false);
int2BooleanMap.put(4, true);
boolean value = int2BooleanMap.get(1);
Int2BooleanSortedMap int2BooleanSorted = Int2BooleanSortedMaps.EMPTY_MAP;
}
private static void coltMap() {
AbstractIntDoubleMap map = new OpenIntDoubleHashMap();
map.put(1, 4.5);
double value = map.get(1);
}
private static void eclipseCollectionsMap() {
MutableIntIntMap mutableIntIntMap = IntIntMaps.mutable.empty();
mutableIntIntMap.addToValue(1, 1);
ImmutableIntIntMap immutableIntIntMap = IntIntMaps.immutable.empty();
MutableObjectDoubleMap<String> dObject = ObjectDoubleMaps.mutable.empty();
dObject.addToValue("price", 150.5);
dObject.addToValue("quality", 4.4);
dObject.addToValue("stability", 0.8);
}
private static void troveMap() {
double[] doubles = new double[] {1.2, 4.5, 0.3};
int[] ints = new int[] {1, 4, 0};
TDoubleIntMap doubleIntMap = new TDoubleIntHashMap(doubles, ints);
doubleIntMap.put(1.2, 22);
doubleIntMap.put(4.5, 16);
doubleIntMap.adjustValue(1.2, 1);
doubleIntMap.adjustValue(4.5, 4);
doubleIntMap.adjustValue(0.3, 7);
}
}

View File

@ -17,3 +17,4 @@
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
- [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count)
- [Java 8 Streams peek() API](https://www.baeldung.com/java-streams-peek-api)
- [Working With Maps Using Streams](https://www.baeldung.com/java-maps-streams)

View File

@ -0,0 +1,24 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 4
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[package.json]
indent_style = space
indent_size = 2

View File

@ -0,0 +1,148 @@
# This file is inspired by https://github.com/alexkaratarakis/gitattributes
#
# Auto detect text files and perform LF normalization
# http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/
* text=auto
# The above will handle all files NOT found below
# These files are text and should be normalized (Convert crlf => lf)
*.bat text eol=crlf
*.coffee text
*.css text
*.cql text
*.df text
*.ejs text
*.html text
*.java text
*.js text
*.json text
*.less text
*.properties text
*.sass text
*.scss text
*.sh text eol=lf
*.sql text
*.txt text
*.ts text
*.xml text
*.yaml text
*.yml text
# Documents
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
*.markdown text
*.md text
*.adoc text
*.textile text
*.mustache text
*.csv text
*.tab text
*.tsv text
*.txt text
AUTHORS text
CHANGELOG text
CHANGES text
CONTRIBUTING text
COPYING text
copyright text
*COPYRIGHT* text
INSTALL text
license text
LICENSE text
NEWS text
readme text
*README* text
TODO text
# Graphics
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
# SVG treated as an asset (binary) by default. If you want to treat it as text,
# comment-out the following line and uncomment the line after.
*.svg binary
#*.svg text
*.eps binary
# These files are binary and should be left untouched
# (binary is a macro for -text -diff)
*.class binary
*.jar binary
*.war binary
## LINTERS
.csslintrc text
.eslintrc text
.jscsrc text
.jshintrc text
.jshintignore text
.stylelintrc text
## CONFIGS
*.conf text
*.config text
.editorconfig text
.gitattributes text
.gitconfig text
.gitignore text
.htaccess text
*.npmignore text
## HEROKU
Procfile text
.slugignore text
## AUDIO
*.kar binary
*.m4a binary
*.mid binary
*.midi binary
*.mp3 binary
*.ogg binary
*.ra binary
## VIDEO
*.3gpp binary
*.3gp binary
*.as binary
*.asf binary
*.asx binary
*.fla binary
*.flv binary
*.m4v binary
*.mng binary
*.mov binary
*.mp4 binary
*.mpeg binary
*.mpg binary
*.swc binary
*.swf binary
*.webm binary
## ARCHIVES
*.7z binary
*.gz binary
*.rar binary
*.tar binary
*.zip binary
## FONTS
*.ttf binary
*.eot binary
*.otf binary
*.woff binary
*.woff2 binary

145
jhipster-5/bookstore-monolith/.gitignore vendored Normal file
View File

@ -0,0 +1,145 @@
######################
# Project Specific
######################
/src/main/webapp/content/css/main.css
/target/www/**
/src/test/javascript/coverage/
######################
# Node
######################
/node/
node_tmp/
node_modules/
npm-debug.log.*
/.awcache/*
/.cache-loader/*
######################
# SASS
######################
.sass-cache/
######################
# Eclipse
######################
*.pydevproject
.project
.metadata
tmp/
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
.factorypath
/src/main/resources/rebel.xml
# External tool builders
.externalToolBuilders/**
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
######################
# Intellij
######################
.idea/
*.iml
*.iws
*.ipr
*.ids
*.orig
classes/
out/
######################
# Visual Studio Code
######################
.vscode/
######################
# Maven
######################
/log/
/target/
######################
# Gradle
######################
.gradle/
/build/
######################
# Package Files
######################
*.jar
*.war
*.ear
*.db
######################
# Windows
######################
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
######################
# Mac OSX
######################
.DS_Store
.svn
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
######################
# Directories
######################
/bin/
/deploy/
######################
# Logs
######################
*.log*
######################
# Others
######################
*.class
*.*~
*~
.merge_file*
######################
# Gradle Wrapper
######################
!gradle/wrapper/gradle-wrapper.jar
######################
# Maven Wrapper
######################
!.mvn/wrapper/maven-wrapper.jar
######################
# ESLint
######################
.eslintcache

View File

@ -0,0 +1,5 @@
{
"hooks": {
"pre-commit": "lint-staged"
}
}

View File

@ -0,0 +1,54 @@
{
"fluentMethods": true,
"clientRootFolder": "",
"relationships": [],
"fields": [
{
"fieldName": "title",
"fieldType": "String",
"fieldValidateRules": [
"required"
]
},
{
"fieldName": "author",
"fieldType": "String",
"fieldValidateRules": [
"required"
]
},
{
"fieldName": "published",
"fieldType": "LocalDate",
"fieldValidateRules": [
"required"
]
},
{
"fieldName": "quantity",
"fieldType": "Integer",
"fieldValidateRules": [
"required",
"min"
],
"fieldValidateRulesMin": 0
},
{
"fieldName": "price",
"fieldType": "Double",
"fieldValidateRules": [
"required",
"min"
],
"fieldValidateRulesMin": 0
}
],
"changelogDate": "20190319124041",
"dto": "mapstruct",
"searchEngine": false,
"service": "serviceImpl",
"entityTableName": "book",
"databaseType": "sql",
"jpaMetamodelFiltering": false,
"pagination": "no"
}

View File

@ -0,0 +1,110 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL =
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if (mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if (mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: : " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if (!outputFile.getParentFile().exists()) {
if (!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip

View File

@ -0,0 +1,3 @@
node_modules
target
package-lock.json

View File

@ -0,0 +1,12 @@
# Prettier configuration
printWidth: 140
singleQuote: true
tabWidth: 4
useTabs: false
# js and ts rules:
arrowParens: avoid
# jsx and tsx rules:
jsxBracketSameLine: false

View File

@ -0,0 +1,34 @@
{
"generator-jhipster": {
"promptValues": {
"packageName": "com.baeldung.jhipster5"
},
"jhipsterVersion": "5.8.2",
"applicationType": "monolith",
"baseName": "Bookstore",
"packageName": "com.baeldung.jhipster5",
"packageFolder": "com/baeldung/jhipster5",
"serverPort": "8080",
"authenticationType": "jwt",
"cacheProvider": "no",
"websocket": false,
"databaseType": "sql",
"devDatabaseType": "h2Memory",
"prodDatabaseType": "mysql",
"searchEngine": false,
"messageBroker": false,
"serviceDiscoveryType": false,
"buildTool": "maven",
"enableSwaggerCodegen": false,
"jwtSecretKey": "NDJmOTVlZjI2NzhlZDRjNmVkNTM1NDE2NjkyNDljZDJiNzBlMjI5YmZjMjY3MzdjZmZlMjI3NjE4OTRkNzc5MWYzNDNlYWMzYmJjOWRmMjc5ZWQyZTZmOWZkOTMxZWZhNWE1MTVmM2U2NjFmYjhlNDc2Y2Q3NzliMGY0YzFkNmI=",
"clientFramework": "angularX",
"useSass": true,
"clientPackageManager": "npm",
"testFrameworks": [],
"jhiPrefix": "jhi",
"entitySuffix": "",
"dtoSuffix": "DTO",
"otherModules": [],
"enableTranslation": false
}
}

View File

@ -0,0 +1,179 @@
# Bookstore
This application was generated using JHipster 5.8.2, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v5.8.2](https://www.jhipster.tech/documentation-archive/v5.8.2).
## Development
Before you can build this project, you must install and configure the following dependencies on your machine:
1. [Node.js][]: We use Node to run a development web server and build the project.
Depending on your system, you can install Node either from source or as a pre-packaged bundle.
After installing Node, you should be able to run the following command to install development tools.
You will only need to run this command when dependencies change in [package.json](package.json).
npm install
We use npm scripts and [Webpack][] as our build system.
Run the following commands in two separate terminals to create a blissful development experience where your browser
auto-refreshes when files change on your hard drive.
./mvnw
npm start
Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by
specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies.
Add the `help` flag on any command to see how you can use it. For example, `npm help update`.
The `npm run` command will list all of the scripts available to run for this project.
### Service workers
Service workers are commented by default, to enable them please uncomment the following code.
- The service worker registering script in index.html
```html
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./service-worker.js').then(function() {
console.log('Service Worker Registered');
});
}
</script>
```
Note: workbox creates the respective service worker and dynamically generate the `service-worker.js`
### Managing dependencies
For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command:
npm install --save --save-exact leaflet
To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command:
npm install --save-dev --save-exact @types/leaflet
Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them:
Edit [src/main/webapp/app/vendor.ts](src/main/webapp/app/vendor.ts) file:
```
import 'leaflet/dist/leaflet.js';
```
Edit [src/main/webapp/content/css/vendor.css](src/main/webapp/content/css/vendor.css) file:
```
@import '~leaflet/dist/leaflet.css';
```
Note: there are still few other things remaining to do for Leaflet that we won't detail here.
For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
### Using angular-cli
You can also use [Angular CLI][] to generate some custom client code.
For example, the following command:
ng generate component my-component
will generate few files:
create src/main/webapp/app/my-component/my-component.component.html
create src/main/webapp/app/my-component/my-component.component.ts
update src/main/webapp/app/app.module.ts
## Building for production
To optimize the Bookstore application for production, run:
./mvnw -Pprod clean package
This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files.
To ensure everything worked, run:
java -jar target/*.war
Then navigate to [http://localhost:8080](http://localhost:8080) in your browser.
Refer to [Using JHipster in production][] for more details.
## Testing
To launch your application's tests, run:
./mvnw clean test
### Client tests
Unit tests are run by [Jest][] and written with [Jasmine][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with:
npm test
For more information, refer to the [Running tests page][].
### Code quality
Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with:
```
docker-compose -f src/main/docker/sonar.yml up -d
```
Then, run a Sonar analysis:
```
./mvnw -Pprod clean test sonar:sonar
```
For more information, refer to the [Code quality page][].
## Using Docker to simplify development (optional)
You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
For example, to start a mysql database in a docker container, run:
docker-compose -f src/main/docker/mysql.yml up -d
To stop it and remove the container, run:
docker-compose -f src/main/docker/mysql.yml down
You can also fully dockerize your application and all the services that it depends on.
To achieve this, first build a docker image of your app by running:
./mvnw package -Pprod verify jib:dockerBuild
Then run:
docker-compose -f src/main/docker/app.yml up -d
For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications.
## Continuous Integration (optional)
To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information.
[jhipster homepage and latest documentation]: https://www.jhipster.tech
[jhipster 5.8.2 archive]: https://www.jhipster.tech/documentation-archive/v5.8.2
[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v5.8.2/development/
[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v5.8.2/docker-compose
[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v5.8.2/production/
[running tests page]: https://www.jhipster.tech/documentation-archive/v5.8.2/running-tests/
[code quality page]: https://www.jhipster.tech/documentation-archive/v5.8.2/code-quality/
[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v5.8.2/setting-up-ci/
[node.js]: https://nodejs.org/
[yarn]: https://yarnpkg.org/
[webpack]: https://webpack.github.io/
[angular cli]: https://cli.angular.io/
[browsersync]: http://www.browsersync.io/
[jest]: https://facebook.github.io/jest/
[jasmine]: http://jasmine.github.io/2.0/introduction.html
[protractor]: https://angular.github.io/protractor/
[leaflet]: http://leafletjs.com/
[definitelytyped]: http://definitelytyped.org/

View File

@ -0,0 +1,39 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"bookstore": {
"root": "",
"sourceRoot": "src/main/webapp",
"projectType": "application",
"architect": {}
}
},
"defaultProject": "bookstore",
"cli": {
"packageManager": "npm"
},
"schematics": {
"@schematics/angular:component": {
"inlineStyle": true,
"inlineTemplate": false,
"spec": false,
"prefix": "jhi",
"styleExt": "scss"
},
"@schematics/angular:directive": {
"spec": false,
"prefix": "jhi"
},
"@schematics/angular:guard": {
"spec": false
},
"@schematics/angular:pipe": {
"spec": false
},
"@schematics/angular:service": {
"spec": false
}
}
}

286
jhipster-5/bookstore-monolith/mvnw vendored Executable file
View File

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

161
jhipster-5/bookstore-monolith/mvnw.cmd vendored Normal file
View File

@ -0,0 +1,161 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
{
"name": "bookstore",
"version": "0.0.0",
"description": "Description for Bookstore",
"private": true,
"license": "UNLICENSED",
"cacheDirectories": [
"node_modules"
],
"dependencies": {
"@angular/common": "7.2.4",
"@angular/compiler": "7.2.4",
"@angular/core": "7.2.4",
"@angular/forms": "7.2.4",
"@angular/platform-browser": "7.2.4",
"@angular/platform-browser-dynamic": "7.2.4",
"@angular/router": "7.2.4",
"@fortawesome/angular-fontawesome": "0.3.0",
"@fortawesome/fontawesome-svg-core": "1.2.14",
"@fortawesome/free-solid-svg-icons": "5.7.1",
"@ng-bootstrap/ng-bootstrap": "4.0.2",
"@ngx-translate/core": "11.0.1",
"@ngx-translate/http-loader": "4.0.0",
"bootstrap": "4.2.1",
"core-js": "2.6.4",
"moment": "2.24.0",
"ng-jhipster": "0.9.1",
"ngx-cookie": "2.0.1",
"ngx-infinite-scroll": "7.0.1",
"ngx-webstorage": "2.0.1",
"rxjs": "6.4.0",
"swagger-ui": "2.2.10",
"tslib": "1.9.3",
"zone.js": "0.8.29"
},
"devDependencies": {
"@angular/cli": "7.3.1",
"@angular/compiler-cli": "7.2.4",
"@ngtools/webpack": "7.3.1",
"@types/jest": "24.0.0",
"@types/node": "10.12.24",
"angular-router-loader": "0.8.5",
"angular2-template-loader": "0.6.2",
"autoprefixer": "9.4.7",
"browser-sync": "2.26.3",
"browser-sync-webpack-plugin": "2.2.2",
"cache-loader": "2.0.1",
"codelyzer": "4.5.0",
"copy-webpack-plugin": "4.6.0",
"css-loader": "2.1.0",
"file-loader": "3.0.1",
"fork-ts-checker-webpack-plugin": "0.5.2",
"friendly-errors-webpack-plugin": "1.7.0",
"generator-jhipster": "5.8.2",
"html-loader": "0.5.5",
"html-webpack-plugin": "3.2.0",
"husky": "1.3.1",
"jest": "24.1.0",
"jest-junit": "6.2.1",
"jest-preset-angular": "6.0.2",
"jest-sonar-reporter": "2.0.0",
"lint-staged": "8.1.3",
"mini-css-extract-plugin": "0.5.0",
"moment-locales-webpack-plugin": "1.0.7",
"optimize-css-assets-webpack-plugin": "5.0.1",
"prettier": "1.16.4",
"reflect-metadata": "0.1.13",
"rimraf": "2.6.3",
"simple-progress-webpack-plugin": "1.1.2",
"style-loader": "0.23.1",
"terser-webpack-plugin": "1.2.2",
"thread-loader": "2.1.2",
"to-string-loader": "1.1.5",
"ts-loader": "5.3.3",
"tslint": "5.12.1",
"tslint-config-prettier": "1.18.0",
"tslint-loader": "3.6.0",
"typescript": "3.2.4",
"sass": "1.17.0",
"sass-loader": "7.1.0",
"postcss-loader": "3.0.0",
"xml2js": "0.4.19",
"webpack": "4.29.3",
"webpack-cli": "3.2.3",
"webpack-dev-server": "3.1.14",
"webpack-merge": "4.2.1",
"webpack-notifier": "1.7.0",
"webpack-visualizer-plugin": "0.1.11",
"workbox-webpack-plugin": "3.6.3",
"write-file-webpack-plugin": "4.5.0"
},
"engines": {
"node": ">=8.9.0"
},
"lint-staged": {
"{,src/**/}*.{md,json,ts,css,scss}": [
"prettier --write",
"git add"
]
},
"scripts": {
"prettier:format": "prettier --write \"{,src/**/}*.{md,json,ts,css,scss}\"",
"lint": "tslint --project tsconfig.json -e 'node_modules/**'",
"lint:fix": "npm run lint -- --fix",
"ngc": "ngc -p tsconfig-aot.json",
"cleanup": "rimraf target/{aot,www}",
"clean-www": "rimraf target//www/app/{src,target/}",
"start": "npm run webpack:dev",
"start-tls": "npm run webpack:dev -- --env.tls",
"serve": "npm run start",
"build": "npm run webpack:prod",
"test": "npm run lint && jest --coverage --logHeapUsage -w=2 --config src/test/javascript/jest.conf.js",
"test:watch": "npm run test -- --watch",
"webpack:dev": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --env.stats=minimal",
"webpack:dev-verbose": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --profile --progress --env.stats=normal",
"webpack:build:main": "npm run webpack -- --config webpack/webpack.dev.js --env.stats=minimal",
"webpack:build": "npm run cleanup && npm run webpack:build:main",
"webpack:prod:main": "npm run webpack -- --config webpack/webpack.prod.js --profile",
"webpack:prod": "npm run cleanup && npm run webpack:prod:main && npm run clean-www",
"webpack:test": "npm run test",
"webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
"webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js"
},
"jestSonar": {
"reportPath": "target/test-results/jest",
"reportFile": "TESTS-results-sonar.xml"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
module.exports = {
plugins: [
require('autoprefixer')
]
}

View File

@ -0,0 +1,7 @@
{
"*": {
"target": "http://localhost:8080",
"secure": false,
"loglevel": "debug"
}
}

View File

@ -0,0 +1,14 @@
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
classes/
generated-sources/
generated-test-sources/
h2db/
maven-archiver/
maven-status/
reports/
surefire-reports/
test-classes/
test-results/
www/
!*.jar
!*.war

View File

@ -0,0 +1,20 @@
FROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
JHIPSTER_SLEEP=0 \
JAVA_OPTS=""
# Add a jhipster user to run our application so that it doesn't need to run as root
RUN adduser -D -s /bin/sh jhipster
WORKDIR /home/jhipster
ADD entrypoint.sh entrypoint.sh
RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh
USER jhipster
ENTRYPOINT ["./entrypoint.sh"]
EXPOSE 8080
ADD *.war app.war

View File

@ -0,0 +1,15 @@
version: '2'
services:
bookstore-app:
image: bookstore
environment:
- _JAVA_OPTIONS=-Xmx512m -Xms256m
- SPRING_PROFILES_ACTIVE=prod,swagger
- SPRING_DATASOURCE_URL=jdbc:mysql://bookstore-mysql:3306/bookstore?useUnicode=true&characterEncoding=utf8&useSSL=false
- JHIPSTER_SLEEP=10 # gives time for the database to boot before the application
ports:
- 8080:8080
bookstore-mysql:
extends:
file: mysql.yml
service: bookstore-mysql

View File

@ -0,0 +1,4 @@
#!/bin/sh
echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/app.war" "$@"

View File

@ -0,0 +1,13 @@
version: '2'
services:
bookstore-mysql:
image: mysql:5.7.20
# volumes:
# - ~/volumes/jhipster/Bookstore/mysql/:/var/lib/mysql/
environment:
- MYSQL_USER=root
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=bookstore
ports:
- 3306:3306
command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp

View File

@ -0,0 +1,7 @@
version: '2'
services:
bookstore-sonar:
image: sonarqube:7.1
ports:
- 9001:9000
- 9092:9092

View File

@ -0,0 +1,21 @@
package com.baeldung.jhipster5;
import com.baeldung.jhipster5.config.DefaultProfileUtil;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* This is a helper Java class that provides an alternative to creating a web.xml.
* This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc.
*/
public class ApplicationWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
/**
* set a default to use when no profile is configured.
*/
DefaultProfileUtil.addDefaultProfile(application.application());
return application.sources(BookstoreApp.class);
}
}

View File

@ -0,0 +1,98 @@
package com.baeldung.jhipster5;
import com.baeldung.jhipster5.config.ApplicationProperties;
import com.baeldung.jhipster5.config.DefaultProfileUtil;
import io.github.jhipster.config.JHipsterConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
@SpringBootApplication
@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
public class BookstoreApp {
private static final Logger log = LoggerFactory.getLogger(BookstoreApp.class);
private final Environment env;
public BookstoreApp(Environment env) {
this.env = env;
}
/**
* Initializes Bookstore.
* <p>
* Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
* <p>
* You can find more information on how profiles work with JHipster on <a href="https://www.jhipster.tech/profiles/">https://www.jhipster.tech/profiles/</a>.
*/
@PostConstruct
public void initApplication() {
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
log.error("You have misconfigured your application! It should not run " +
"with both the 'dev' and 'prod' profiles at the same time.");
}
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
log.error("You have misconfigured your application! It should not " +
"run with both the 'dev' and 'cloud' profiles at the same time.");
}
}
/**
* Main method, used to run the application.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
SpringApplication app = new SpringApplication(BookstoreApp.class);
DefaultProfileUtil.addDefaultProfile(app);
Environment env = app.run(args).getEnvironment();
logApplicationStartup(env);
}
private static void logApplicationStartup(Environment env) {
String protocol = "http";
if (env.getProperty("server.ssl.key-store") != null) {
protocol = "https";
}
String serverPort = env.getProperty("server.port");
String contextPath = env.getProperty("server.servlet.context-path");
if (StringUtils.isBlank(contextPath)) {
contextPath = "/";
}
String hostAddress = "localhost";
try {
hostAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
log.warn("The host name could not be determined, using `localhost` as fallback");
}
log.info("\n----------------------------------------------------------\n\t" +
"Application '{}' is running! Access URLs:\n\t" +
"Local: \t\t{}://localhost:{}{}\n\t" +
"External: \t{}://{}:{}{}\n\t" +
"Profile(s): \t{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"),
protocol,
serverPort,
contextPath,
protocol,
hostAddress,
serverPort,
contextPath,
env.getActiveProfiles());
}
}

View File

@ -0,0 +1,98 @@
package com.baeldung.jhipster5.aop.logging;
import io.github.jhipster.config.JHipsterConstants;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import java.util.Arrays;
/**
* Aspect for logging execution of service and repository Spring components.
*
* By default, it only runs with the "dev" profile.
*/
@Aspect
public class LoggingAspect {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final Environment env;
public LoggingAspect(Environment env) {
this.env = env;
}
/**
* Pointcut that matches all repositories, services and Web REST endpoints.
*/
@Pointcut("within(@org.springframework.stereotype.Repository *)" +
" || within(@org.springframework.stereotype.Service *)" +
" || within(@org.springframework.web.bind.annotation.RestController *)")
public void springBeanPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
/**
* Pointcut that matches all Spring beans in the application's main packages.
*/
@Pointcut("within(com.baeldung.jhipster5.repository..*)"+
" || within(com.baeldung.jhipster5.service..*)"+
" || within(com.baeldung.jhipster5.web.rest..*)")
public void applicationPackagePointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
/**
* Advice that logs methods throwing exceptions.
*
* @param joinPoint join point for advice
* @param e exception
*/
@AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e);
} else {
log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL");
}
}
/**
* Advice that logs when a method is entered and exited.
*
* @param joinPoint join point for advice
* @return result
* @throws Throwable throws IllegalArgumentException
*/
@Around("applicationPackagePointcut() && springBeanPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
if (log.isDebugEnabled()) {
log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
}
try {
Object result = joinPoint.proceed();
if (log.isDebugEnabled()) {
log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(),
joinPoint.getSignature().getName(), result);
}
return result;
} catch (IllegalArgumentException e) {
log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()),
joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
throw e;
}
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.jhipster5.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties specific to Bookstore.
* <p>
* Properties are configured in the application.yml file.
* See {@link io.github.jhipster.config.JHipsterProperties} for a good example.
*/
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
}

View File

@ -0,0 +1,59 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
import io.github.jhipster.config.JHipsterProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer, SchedulingConfigurer {
private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
private final JHipsterProperties jHipsterProperties;
public AsyncConfiguration(JHipsterProperties jHipsterProperties) {
this.jHipsterProperties = jHipsterProperties;
}
@Override
@Bean(name = "taskExecutor")
public Executor getAsyncExecutor() {
log.debug("Creating Async Task Executor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(jHipsterProperties.getAsync().getCorePoolSize());
executor.setMaxPoolSize(jHipsterProperties.getAsync().getMaxPoolSize());
executor.setQueueCapacity(jHipsterProperties.getAsync().getQueueCapacity());
executor.setThreadNamePrefix("bookstore-Executor-");
return new ExceptionHandlingAsyncTaskExecutor(executor);
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(scheduledTaskExecutor());
}
@Bean
public Executor scheduledTaskExecutor() {
return Executors.newScheduledThreadPool(jHipsterProperties.getAsync().getCorePoolSize());
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.config.JHipsterConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.config.java.AbstractCloudConfig;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Configuration
@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
public class CloudDatabaseConfiguration extends AbstractCloudConfig {
private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari";
@Bean
@ConfigurationProperties(CLOUD_CONFIGURATION_HIKARI_PREFIX)
public DataSource dataSource() {
log.info("Configuring JDBC datasource from a cloud provider");
return connectionFactory().dataSource();
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.jhipster5.config;
/**
* Application constants.
*/
public final class Constants {
// Regex for acceptable logins
public static final String LOGIN_REGEX = "^[_.@A-Za-z0-9-]*$";
public static final String SYSTEM_ACCOUNT = "system";
public static final String ANONYMOUS_USER = "anonymoususer";
public static final String DEFAULT_LANGUAGE = "en";
private Constants() {
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.config.JHipsterConstants;
import io.github.jhipster.config.h2.H2ConfigurationHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.sql.SQLException;
@Configuration
@EnableJpaRepositories("com.baeldung.jhipster5.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
private final Environment env;
public DatabaseConfiguration(Environment env) {
this.env = env;
}
/**
* Open the TCP port for the H2 database, so it is available remotely.
*
* @return the H2 database TCP server
* @throws SQLException if the server failed to start
*/
@Bean(initMethod = "start", destroyMethod = "stop")
@Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
public Object h2TCPServer() throws SQLException {
String port = getValidPortForH2();
log.debug("H2 database is available on port {}", port);
return H2ConfigurationHelper.createServer(port);
}
private String getValidPortForH2() {
int port = Integer.parseInt(env.getProperty("server.port"));
if (port < 10000) {
port = 10000 + port;
} else {
if (port < 63536) {
port = port + 2000;
} else {
port = port - 2000;
}
}
return String.valueOf(port);
}
}

View File

@ -0,0 +1,20 @@
package com.baeldung.jhipster5.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Configure the converters to use the ISO format for dates by default.
*/
@Configuration
public class DateTimeFormatConfiguration implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.config.JHipsterConstants;
import org.springframework.boot.SpringApplication;
import org.springframework.core.env.Environment;
import java.util.*;
/**
* Utility class to load a Spring profile to be used as default
* when there is no <code>spring.profiles.active</code> set in the environment or as command line argument.
* If the value is not available in <code>application.yml</code> then <code>dev</code> profile will be used as default.
*/
public final class DefaultProfileUtil {
private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
private DefaultProfileUtil() {
}
/**
* Set a default to use when no profile is configured.
*
* @param app the Spring application
*/
public static void addDefaultProfile(SpringApplication app) {
Map<String, Object> defProperties = new HashMap<>();
/*
* The default profile to use when no other profiles are defined
* This cannot be set in the <code>application.yml</code> file.
* See https://github.com/spring-projects/spring-boot/issues/1219
*/
defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
app.setDefaultProperties(defProperties);
}
/**
* Get the profiles that are applied else get default profiles.
*
* @param env spring environment
* @return profiles
*/
public static String[] getActiveProfiles(Environment env) {
String[] profiles = env.getActiveProfiles();
if (profiles.length == 0) {
return env.getDefaultProfiles();
}
return profiles;
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.jhipster5.config;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.zalando.problem.ProblemModule;
import org.zalando.problem.violations.ConstraintViolationProblemModule;
@Configuration
public class JacksonConfiguration {
/**
* Support for Java date and time API.
* @return the corresponding Jackson module.
*/
@Bean
public JavaTimeModule javaTimeModule() {
return new JavaTimeModule();
}
@Bean
public Jdk8Module jdk8TimeModule() {
return new Jdk8Module();
}
/*
* Support for Hibernate types in Jackson.
*/
@Bean
public Hibernate5Module hibernate5Module() {
return new Hibernate5Module();
}
/*
* Jackson Afterburner module to speed up serialization/deserialization.
*/
@Bean
public AfterburnerModule afterburnerModule() {
return new AfterburnerModule();
}
/*
* Module for serialization/deserialization of RFC7807 Problem.
*/
@Bean
ProblemModule problemModule() {
return new ProblemModule();
}
/*
* Module for serialization/deserialization of ConstraintViolationProblem.
*/
@Bean
ConstraintViolationProblemModule constraintViolationProblemModule() {
return new ConstraintViolationProblemModule();
}
}

View File

@ -0,0 +1,50 @@
package com.baeldung.jhipster5.config;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.task.TaskExecutor;
import io.github.jhipster.config.JHipsterConstants;
import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
import liquibase.integration.spring.SpringLiquibase;
@Configuration
public class LiquibaseConfiguration {
private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class);
private final Environment env;
public LiquibaseConfiguration(Environment env) {
this.env = env;
}
@Bean
public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor,
DataSource dataSource, LiquibaseProperties liquibaseProperties) {
// Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts(liquibaseProperties.getContexts());
liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(liquibaseProperties.isDropFirst());
liquibase.setChangeLogParameters(liquibaseProperties.getParameters());
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
liquibase.setShouldRun(false);
} else {
liquibase.setShouldRun(liquibaseProperties.isEnabled());
log.debug("Configuring Liquibase");
}
return liquibase;
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class LocaleConfiguration implements WebMvcConfigurer {
@Bean(name = "localeResolver")
public LocaleResolver localeResolver() {
AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
return cookieLocaleResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
registry.addInterceptor(localeChangeInterceptor);
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.jhipster5.config;
import com.baeldung.jhipster5.aop.logging.LoggingAspect;
import io.github.jhipster.config.JHipsterConstants;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
@Configuration
@EnableAspectJAutoProxy
public class LoggingAspectConfiguration {
@Bean
@Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
public LoggingAspect loggingAspect(Environment env) {
return new LoggingAspect(env);
}
}

View File

@ -0,0 +1,154 @@
package com.baeldung.jhipster5.config;
import java.net.InetSocketAddress;
import java.util.Iterator;
import io.github.jhipster.config.JHipsterProperties;
import ch.qos.logback.classic.AsyncAppender;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.boolex.OnMarkerEvaluator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggerContextListener;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.filter.EvaluatorFilter;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.spi.FilterReply;
import net.logstash.logback.appender.LogstashTcpSocketAppender;
import net.logstash.logback.encoder.LogstashEncoder;
import net.logstash.logback.stacktrace.ShortenedThrowableConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LoggingConfiguration {
private static final String LOGSTASH_APPENDER_NAME = "LOGSTASH";
private static final String ASYNC_LOGSTASH_APPENDER_NAME = "ASYNC_LOGSTASH";
private final Logger log = LoggerFactory.getLogger(LoggingConfiguration.class);
private LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
private final String appName;
private final String serverPort;
private final JHipsterProperties jHipsterProperties;
public LoggingConfiguration(@Value("${spring.application.name}") String appName, @Value("${server.port}") String serverPort,
JHipsterProperties jHipsterProperties) {
this.appName = appName;
this.serverPort = serverPort;
this.jHipsterProperties = jHipsterProperties;
if (jHipsterProperties.getLogging().getLogstash().isEnabled()) {
addLogstashAppender(context);
addContextListener(context);
}
if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
setMetricsMarkerLogbackFilter(context);
}
}
private void addContextListener(LoggerContext context) {
LogbackLoggerContextListener loggerContextListener = new LogbackLoggerContextListener();
loggerContextListener.setContext(context);
context.addListener(loggerContextListener);
}
private void addLogstashAppender(LoggerContext context) {
log.info("Initializing Logstash logging");
LogstashTcpSocketAppender logstashAppender = new LogstashTcpSocketAppender();
logstashAppender.setName(LOGSTASH_APPENDER_NAME);
logstashAppender.setContext(context);
String customFields = "{\"app_name\":\"" + appName + "\",\"app_port\":\"" + serverPort + "\"}";
// More documentation is available at: https://github.com/logstash/logstash-logback-encoder
LogstashEncoder logstashEncoder = new LogstashEncoder();
// Set the Logstash appender config from JHipster properties
logstashAppender.addDestinations(new InetSocketAddress(jHipsterProperties.getLogging().getLogstash().getHost(), jHipsterProperties.getLogging().getLogstash().getPort()));
ShortenedThrowableConverter throwableConverter = new ShortenedThrowableConverter();
throwableConverter.setRootCauseFirst(true);
logstashEncoder.setThrowableConverter(throwableConverter);
logstashEncoder.setCustomFields(customFields);
logstashAppender.setEncoder(logstashEncoder);
logstashAppender.start();
// Wrap the appender in an Async appender for performance
AsyncAppender asyncLogstashAppender = new AsyncAppender();
asyncLogstashAppender.setContext(context);
asyncLogstashAppender.setName(ASYNC_LOGSTASH_APPENDER_NAME);
asyncLogstashAppender.setQueueSize(jHipsterProperties.getLogging().getLogstash().getQueueSize());
asyncLogstashAppender.addAppender(logstashAppender);
asyncLogstashAppender.start();
context.getLogger("ROOT").addAppender(asyncLogstashAppender);
}
// Configure a log filter to remove "metrics" logs from all appenders except the "LOGSTASH" appender
private void setMetricsMarkerLogbackFilter(LoggerContext context) {
log.info("Filtering metrics logs from all appenders except the {} appender", LOGSTASH_APPENDER_NAME);
OnMarkerEvaluator onMarkerMetricsEvaluator = new OnMarkerEvaluator();
onMarkerMetricsEvaluator.setContext(context);
onMarkerMetricsEvaluator.addMarker("metrics");
onMarkerMetricsEvaluator.start();
EvaluatorFilter<ILoggingEvent> metricsFilter = new EvaluatorFilter<>();
metricsFilter.setContext(context);
metricsFilter.setEvaluator(onMarkerMetricsEvaluator);
metricsFilter.setOnMatch(FilterReply.DENY);
metricsFilter.start();
for (ch.qos.logback.classic.Logger logger : context.getLoggerList()) {
for (Iterator<Appender<ILoggingEvent>> it = logger.iteratorForAppenders(); it.hasNext();) {
Appender<ILoggingEvent> appender = it.next();
if (!appender.getName().equals(ASYNC_LOGSTASH_APPENDER_NAME)) {
log.debug("Filter metrics logs from the {} appender", appender.getName());
appender.setContext(context);
appender.addFilter(metricsFilter);
appender.start();
}
}
}
}
/**
* Logback configuration is achieved by configuration file and API.
* When configuration file change is detected, the configuration is reset.
* This listener ensures that the programmatic configuration is also re-applied after reset.
*/
class LogbackLoggerContextListener extends ContextAwareBase implements LoggerContextListener {
@Override
public boolean isResetResistant() {
return true;
}
@Override
public void onStart(LoggerContext context) {
addLogstashAppender(context);
}
@Override
public void onReset(LoggerContext context) {
addLogstashAppender(context);
}
@Override
public void onStop(LoggerContext context) {
// Nothing to do.
}
@Override
public void onLevelChange(ch.qos.logback.classic.Logger logger, Level level) {
// Nothing to do.
}
}
}

View File

@ -0,0 +1,122 @@
package com.baeldung.jhipster5.config;
import com.baeldung.jhipster5.security.*;
import com.baeldung.jhipster5.security.jwt.*;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
import javax.annotation.PostConstruct;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Import(SecurityProblemSupport.class)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
private final TokenProvider tokenProvider;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
public SecurityConfiguration(AuthenticationManagerBuilder authenticationManagerBuilder, UserDetailsService userDetailsService, TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
this.authenticationManagerBuilder = authenticationManagerBuilder;
this.userDetailsService = userDetailsService;
this.tokenProvider = tokenProvider;
this.corsFilter = corsFilter;
this.problemSupport = problemSupport;
}
@PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/h2-console/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/books/purchase/**").authenticated()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.apply(securityConfigurerAdapter());
}
private JWTConfigurer securityConfigurerAdapter() {
return new JWTConfigurer(tokenProvider);
}
}

View File

@ -0,0 +1,170 @@
package com.baeldung.jhipster5.config;
import io.github.jhipster.config.JHipsterConstants;
import io.github.jhipster.config.JHipsterProperties;
import io.github.jhipster.config.h2.H2ConfigurationHelper;
import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
import io.undertow.UndertowOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.*;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import javax.servlet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.*;
import static java.net.URLDecoder.decode;
/**
* Configuration of web application with Servlet 3.0 APIs.
*/
@Configuration
public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<WebServerFactory> {
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
private final Environment env;
private final JHipsterProperties jHipsterProperties;
public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {
this.env = env;
this.jHipsterProperties = jHipsterProperties;
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
if (env.getActiveProfiles().length != 0) {
log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
}
EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
initCachingHttpHeadersFilter(servletContext, disps);
}
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) {
initH2Console(servletContext);
}
log.info("Web application fully configured");
}
/**
* Customize the Servlet engine: Mime types, the document root, the cache.
*/
@Override
public void customize(WebServerFactory server) {
setMimeMappings(server);
// When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
setLocationForStaticAssets(server);
/*
* Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
* HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
* See the JHipsterProperties class and your application-*.yml configuration files
* for more information.
*/
if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
server instanceof UndertowServletWebServerFactory) {
((UndertowServletWebServerFactory) server)
.addBuilderCustomizers(builder ->
builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
}
}
private void setMimeMappings(WebServerFactory server) {
if (server instanceof ConfigurableServletWebServerFactory) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
// IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
// CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
servletWebServer.setMimeMappings(mappings);
}
}
private void setLocationForStaticAssets(WebServerFactory server) {
if (server instanceof ConfigurableServletWebServerFactory) {
ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
File root;
String prefixPath = resolvePathPrefix();
root = new File(prefixPath + "target/www/");
if (root.exists() && root.isDirectory()) {
servletWebServer.setDocumentRoot(root);
}
}
}
/**
* Resolve path prefix to static resources.
*/
private String resolvePathPrefix() {
String fullExecutablePath;
try {
fullExecutablePath = decode(this.getClass().getResource("").getPath(), StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
/* try without decoding if this ever happens */
fullExecutablePath = this.getClass().getResource("").getPath();
}
String rootPath = Paths.get(".").toUri().normalize().getPath();
String extractedPath = fullExecutablePath.replace(rootPath, "");
int extractionEndIndex = extractedPath.indexOf("target/");
if (extractionEndIndex <= 0) {
return "";
}
return extractedPath.substring(0, extractionEndIndex);
}
/**
* Initializes the caching HTTP Headers Filter.
*/
private void initCachingHttpHeadersFilter(ServletContext servletContext,
EnumSet<DispatcherType> disps) {
log.debug("Registering Caching HTTP Headers Filter");
FilterRegistration.Dynamic cachingHttpHeadersFilter =
servletContext.addFilter("cachingHttpHeadersFilter",
new CachingHttpHeadersFilter(jHipsterProperties));
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/i18n/*");
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*");
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*");
cachingHttpHeadersFilter.setAsyncSupported(true);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = jHipsterProperties.getCors();
if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
log.debug("Registering CORS filter");
source.registerCorsConfiguration("/api/**", config);
source.registerCorsConfiguration("/management/**", config);
source.registerCorsConfiguration("/v2/api-docs", config);
}
return new CorsFilter(source);
}
/**
* Initializes H2 console.
*/
private void initH2Console(ServletContext servletContext) {
log.debug("Initialize H2 console");
H2ConfigurationHelper.initH2Console(servletContext);
}
}

View File

@ -0,0 +1,86 @@
package com.baeldung.jhipster5.config.audit;
import com.baeldung.jhipster5.domain.PersistentAuditEvent;
import org.springframework.boot.actuate.audit.AuditEvent;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class AuditEventConverter {
/**
* Convert a list of PersistentAuditEvent to a list of AuditEvent
*
* @param persistentAuditEvents the list to convert
* @return the converted list.
*/
public List<AuditEvent> convertToAuditEvent(Iterable<PersistentAuditEvent> persistentAuditEvents) {
if (persistentAuditEvents == null) {
return Collections.emptyList();
}
List<AuditEvent> auditEvents = new ArrayList<>();
for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
auditEvents.add(convertToAuditEvent(persistentAuditEvent));
}
return auditEvents;
}
/**
* Convert a PersistentAuditEvent to an AuditEvent
*
* @param persistentAuditEvent the event to convert
* @return the converted list.
*/
public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
if (persistentAuditEvent == null) {
return null;
}
return new AuditEvent(persistentAuditEvent.getAuditEventDate(), persistentAuditEvent.getPrincipal(),
persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData()));
}
/**
* Internal conversion. This is needed to support the current SpringBoot actuator AuditEventRepository interface
*
* @param data the data to convert
* @return a map of String, Object
*/
public Map<String, Object> convertDataToObjects(Map<String, String> data) {
Map<String, Object> results = new HashMap<>();
if (data != null) {
for (Map.Entry<String, String> entry : data.entrySet()) {
results.put(entry.getKey(), entry.getValue());
}
}
return results;
}
/**
* Internal conversion. This method will allow to save additional data.
* By default, it will save the object as string
*
* @param data the data to convert
* @return a map of String, String
*/
public Map<String, String> convertDataToStrings(Map<String, Object> data) {
Map<String, String> results = new HashMap<>();
if (data != null) {
for (Map.Entry<String, Object> entry : data.entrySet()) {
// Extract the data that will be saved.
if (entry.getValue() instanceof WebAuthenticationDetails) {
WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) entry.getValue();
results.put("remoteAddress", authenticationDetails.getRemoteAddress());
results.put("sessionId", authenticationDetails.getSessionId());
} else {
results.put(entry.getKey(), Objects.toString(entry.getValue()));
}
}
}
return results;
}
}

View File

@ -0,0 +1,4 @@
/**
* Audit specific code.
*/
package com.baeldung.jhipster5.config.audit;

View File

@ -0,0 +1,4 @@
/**
* Spring Framework configuration files.
*/
package com.baeldung.jhipster5.config;

View File

@ -0,0 +1,79 @@
package com.baeldung.jhipster5.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.envers.Audited;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.io.Serializable;
import java.time.Instant;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
/**
* Base abstract class for entities which will hold definitions for created, last modified by and created,
* last modified by date.
*/
@MappedSuperclass
@Audited
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
@CreatedBy
@Column(name = "created_by", nullable = false, length = 50, updatable = false)
@JsonIgnore
private String createdBy;
@CreatedDate
@Column(name = "created_date", updatable = false)
@JsonIgnore
private Instant createdDate = Instant.now();
@LastModifiedBy
@Column(name = "last_modified_by", length = 50)
@JsonIgnore
private String lastModifiedBy;
@LastModifiedDate
@Column(name = "last_modified_date")
@JsonIgnore
private Instant lastModifiedDate = Instant.now();
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Instant getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public Instant getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Instant lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.jhipster5.domain;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* An authority (a security role) used by Spring Security.
*/
@Entity
@Table(name = "jhi_authority")
public class Authority implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
@Size(max = 50)
@Id
@Column(length = 50)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Authority authority = (Authority) o;
return !(name != null ? !name.equals(authority.name) : authority.name != null);
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
@Override
public String toString() {
return "Authority{" +
"name='" + name + '\'' +
"}";
}
}

View File

@ -0,0 +1,153 @@
package com.baeldung.jhipster5.domain;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
/**
* A Book.
*/
@Entity
@Table(name = "book")
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "title", nullable = false)
private String title;
@NotNull
@Column(name = "author", nullable = false)
private String author;
@NotNull
@Column(name = "published", nullable = false)
private LocalDate published;
@NotNull
@Min(value = 0)
@Column(name = "quantity", nullable = false)
private Integer quantity;
@NotNull
@DecimalMin(value = "0")
@Column(name = "price", nullable = false)
private Double price;
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public Book title(String title) {
this.title = title;
return this;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public Book author(String author) {
this.author = author;
return this;
}
public void setAuthor(String author) {
this.author = author;
}
public LocalDate getPublished() {
return published;
}
public Book published(LocalDate published) {
this.published = published;
return this;
}
public void setPublished(LocalDate published) {
this.published = published;
}
public Integer getQuantity() {
return quantity;
}
public Book quantity(Integer quantity) {
this.quantity = quantity;
return this;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Double getPrice() {
return price;
}
public Book price(Double price) {
this.price = price;
return this;
}
public void setPrice(Double price) {
this.price = price;
}
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Book book = (Book) o;
if (book.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), book.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "Book{" +
"id=" + getId() +
", title='" + getTitle() + "'" +
", author='" + getAuthor() + "'" +
", published='" + getPublished() + "'" +
", quantity=" + getQuantity() +
", price=" + getPrice() +
"}";
}
}

View File

@ -0,0 +1,109 @@
package com.baeldung.jhipster5.domain;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.Instant;
import java.util.HashMap;
import java.util.Objects;
import java.util.Map;
/**
* Persist AuditEvent managed by the Spring Boot actuator.
*
* @see org.springframework.boot.actuate.audit.AuditEvent
*/
@Entity
@Table(name = "jhi_persistent_audit_event")
public class PersistentAuditEvent implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "event_id")
private Long id;
@NotNull
@Column(nullable = false)
private String principal;
@Column(name = "event_date")
private Instant auditEventDate;
@Column(name = "event_type")
private String auditEventType;
@ElementCollection
@MapKeyColumn(name = "name")
@Column(name = "value")
@CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id"))
private Map<String, String> data = new HashMap<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPrincipal() {
return principal;
}
public void setPrincipal(String principal) {
this.principal = principal;
}
public Instant getAuditEventDate() {
return auditEventDate;
}
public void setAuditEventDate(Instant auditEventDate) {
this.auditEventDate = auditEventDate;
}
public String getAuditEventType() {
return auditEventType;
}
public void setAuditEventType(String auditEventType) {
this.auditEventType = auditEventType;
}
public Map<String, String> getData() {
return data;
}
public void setData(Map<String, String> data) {
this.data = data;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PersistentAuditEvent persistentAuditEvent = (PersistentAuditEvent) o;
return !(persistentAuditEvent.getId() == null || getId() == null) && Objects.equals(getId(), persistentAuditEvent.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "PersistentAuditEvent{" +
"principal='" + principal + '\'' +
", auditEventDate=" + auditEventDate +
", auditEventType='" + auditEventType + '\'' +
'}';
}
}

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