commit
0a8d9fe187
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung.algorithms.relativelyprime;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
class RelativelyPrime {
|
||||||
|
|
||||||
|
static boolean iterativeRelativelyPrime(int a, int b) {
|
||||||
|
return iterativeGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean recursiveRelativelyPrime(int a, int b) {
|
||||||
|
return recursiveGCD(a, b) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean bigIntegerRelativelyPrime(int a, int b) {
|
||||||
|
return BigInteger.valueOf(a).gcd(BigInteger.valueOf(b)).equals(BigInteger.ONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int iterativeGCD(int a, int b) {
|
||||||
|
int tmp;
|
||||||
|
while (b != 0) {
|
||||||
|
if (a < b) {
|
||||||
|
tmp = a;
|
||||||
|
a = b;
|
||||||
|
b = tmp;
|
||||||
|
}
|
||||||
|
tmp = b;
|
||||||
|
b = a % b;
|
||||||
|
a = tmp;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int recursiveGCD(int a, int b) {
|
||||||
|
if (b == 0) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (a < b) {
|
||||||
|
return recursiveGCD(b, a);
|
||||||
|
}
|
||||||
|
return recursiveGCD(b, a % b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,7 @@
|
|||||||
issuer:
|
issuer:
|
||||||
uri: http://localhost:8080/uaa
|
uri: http://localhost:8080/uaa
|
||||||
|
|
||||||
spring_profiles: postgresql,default
|
spring_profiles: default,hsqldb
|
||||||
|
|
||||||
database.driverClassName: org.postgresql.Driver
|
|
||||||
database.url: jdbc:postgresql:uaadb2
|
|
||||||
database.username: postgres
|
|
||||||
database.password: postgres
|
|
||||||
|
|
||||||
encryption:
|
encryption:
|
||||||
active_key_label: CHANGE-THIS-KEY
|
active_key_label: CHANGE-THIS-KEY
|
||||||
|
@ -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.port=8081
|
||||||
#server.servlet.context-path=/uaa-client-webapp
|
|
||||||
|
|
||||||
uaa.url=http://localhost:8080/uaa
|
|
||||||
resource.server.url=http://localhost:8082
|
resource.server.url=http://localhost:8082
|
||||||
|
|
||||||
spring.security.oauth2.client.registration.uaa.client-name=UAA OAuth2 Client
|
spring.security.oauth2.client.registration.uaa.client-name=Web App Client
|
||||||
spring.security.oauth2.client.registration.uaa.client-id=client1
|
spring.security.oauth2.client.registration.uaa.client-id=webappclient
|
||||||
spring.security.oauth2.client.registration.uaa.client-secret=client1
|
spring.security.oauth2.client.registration.uaa.client-secret=webappclientsecret
|
||||||
spring.security.oauth2.client.registration.uaa.authorization-grant-type=authorization_code
|
|
||||||
spring.security.oauth2.client.registration.uaa.scope=resource.read,resource.write,openid,profile
|
spring.security.oauth2.client.registration.uaa.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.issuer-uri=http://localhost:8080/uaa/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
|
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
server.port=8082
|
server.port=8082
|
||||||
|
|
||||||
uaa.url=http://localhost:8080/uaa
|
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/uaa/oauth/token
|
||||||
|
|
||||||
#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
|
|
||||||
|
@ -9,3 +9,5 @@
|
|||||||
- [A Quick Guide to Iterating a Map in Groovy](https://www.baeldung.com/groovy-map-iterating)
|
- [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)
|
- [An Introduction to Traits in Groovy](https://www.baeldung.com/groovy-traits)
|
||||||
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
- [Lists in Groovy](https://www.baeldung.com/groovy-lists)
|
||||||
|
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||||
|
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||||
|
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
37
core-groovy/src/main/groovy/com/baeldung/Person.groovy
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung
|
||||||
|
|
||||||
|
class Person {
|
||||||
|
private String firstname
|
||||||
|
private String lastname
|
||||||
|
private Integer age
|
||||||
|
|
||||||
|
Person(String firstname, String lastname, Integer age) {
|
||||||
|
this.firstname = firstname
|
||||||
|
this.lastname = lastname
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFirstname() {
|
||||||
|
return firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLastname() {
|
||||||
|
return lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getAge() {
|
||||||
|
return age
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAge(Integer age) {
|
||||||
|
this.age = age
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Closures {
|
||||||
|
|
||||||
|
def printWelcome = {
|
||||||
|
println "Welcome to Closures!"
|
||||||
|
}
|
||||||
|
|
||||||
|
def print = { name ->
|
||||||
|
println name
|
||||||
|
}
|
||||||
|
|
||||||
|
def formatToLowerCase(name) {
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
def formatToLowerCaseClosure = { name ->
|
||||||
|
return name.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
def count=0
|
||||||
|
|
||||||
|
def increaseCount = {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
def greet = {
|
||||||
|
return "Hello! ${it}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def multiply = { x, y ->
|
||||||
|
return x*y
|
||||||
|
}
|
||||||
|
|
||||||
|
def calculate = {int x, int y, String operation ->
|
||||||
|
|
||||||
|
//log closure
|
||||||
|
def log = {
|
||||||
|
println "Performing $it"
|
||||||
|
}
|
||||||
|
|
||||||
|
def result = 0
|
||||||
|
switch(operation) {
|
||||||
|
case "ADD":
|
||||||
|
log("Addition")
|
||||||
|
result = x+y
|
||||||
|
break
|
||||||
|
case "SUB":
|
||||||
|
log("Subtraction")
|
||||||
|
result = x-y
|
||||||
|
break
|
||||||
|
case "MUL":
|
||||||
|
log("Multiplication")
|
||||||
|
result = x*y
|
||||||
|
break
|
||||||
|
case "DIV":
|
||||||
|
log("Division")
|
||||||
|
result = x/y
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
def addAll = { int... args ->
|
||||||
|
return args.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
def volume(Closure areaCalculator, int... dimensions) {
|
||||||
|
if(dimensions.size() == 3) {
|
||||||
|
|
||||||
|
//consider dimension[0] = length, dimension[1] = breadth, dimension[2] = height
|
||||||
|
//for cube and cuboid
|
||||||
|
return areaCalculator(dimensions[0], dimensions[1]) * dimensions[2]
|
||||||
|
} else if(dimensions.size() == 2) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius, dimension[1] = height
|
||||||
|
//for cylinder and cone
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[1]
|
||||||
|
} else if(dimensions.size() == 1) {
|
||||||
|
|
||||||
|
//consider dimension[0] = radius
|
||||||
|
//for sphere
|
||||||
|
return areaCalculator(dimensions[0]) * dimensions[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.baeldung.closures
|
||||||
|
|
||||||
|
class Employee {
|
||||||
|
|
||||||
|
String fullName
|
||||||
|
}
|
@ -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}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,18 @@
|
|||||||
package com.baeldung.map
|
package com.baeldung.map
|
||||||
|
|
||||||
import static org.junit.Assert.*
|
import com.baeldung.Person
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.*
|
||||||
|
|
||||||
class MapUnitTest {
|
class MapUnitTest {
|
||||||
|
|
||||||
|
private final personMap = [
|
||||||
|
Regina : new Person("Regina", "Fitzpatrick", 25),
|
||||||
|
Abagail: new Person("Abagail", "Ballard", 26),
|
||||||
|
Lucian : new Person("Lucian", "Walter", 30)
|
||||||
|
]
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void whenUsingEach_thenMapIsIterated() {
|
void whenUsingEach_thenMapIsIterated() {
|
||||||
def map = [
|
def map = [
|
||||||
@ -82,4 +90,65 @@ class MapUnitTest {
|
|||||||
println "Hex Code: $entry.key = Color Name: $entry.value"
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -5,3 +5,4 @@
|
|||||||
- [Java 11 String API Additions](https://www.baeldung.com/java-11-string-api)
|
- [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)
|
- [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)
|
- [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
48
core-java-12/pom.xml
Normal 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>
|
@ -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 + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -124,11 +124,44 @@ public class Java8SortUnitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
|
public final void givenStreamCustomOrdering_whenSortingEntitiesByName_thenCorrectlySorted() {
|
||||||
|
|
||||||
final List<Human> humans = Lists.newArrayList(new Human("Sarah", 10), new Human("Jack", 12));
|
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 Comparator<Human> nameComparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
|
||||||
|
|
||||||
final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList());
|
final List<Human> sortedHumans = humans.stream().sorted(nameComparator).collect(Collectors.toList());
|
||||||
Assert.assertThat(sortedHumans.get(0), equalTo(new Human("Jack", 12)));
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,3 +27,4 @@
|
|||||||
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
|
||||||
- [Multi-Release Jar Files](https://www.baeldung.com/java-multi-release-jar)
|
- [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)
|
- [Ahead of Time Compilation (AoT)](https://www.baeldung.com/ahead-of-time-compilation)
|
||||||
|
|
||||||
|
@ -33,3 +33,4 @@
|
|||||||
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
- [Differences Between HashMap and Hashtable](https://www.baeldung.com/hashmap-hashtable-differences)
|
||||||
- [Java ArrayList vs Vector](https://www.baeldung.com/java-arraylist-vs-vector)
|
- [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)
|
- [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)
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
- [Life Cycle of a Thread in Java](http://www.baeldung.com/java-thread-lifecycle)
|
- [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)
|
- [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)
|
- [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)
|
||||||
|
@ -1,35 +1,27 @@
|
|||||||
package com.baeldung.socket.read;
|
package com.baeldung.socket.read;
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
public class Client {
|
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) {
|
public void runClient(String ip, int port) {
|
||||||
try {
|
try {
|
||||||
socket = new Socket(ip, port);
|
Socket socket = new Socket(ip, port);
|
||||||
System.out.println("Connected to server ...");
|
System.out.println("Connected to server ...");
|
||||||
in = new DataInputStream(System.in);
|
DataInputStream in = new DataInputStream(System.in);
|
||||||
out = new DataOutputStream(socket.getOutputStream());
|
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
char type = 's'; // s for string
|
char type = 's'; // s for string
|
||||||
int length = 29;
|
int length = 29;
|
||||||
String data = "This is a string of 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
|
//Sending data in TLV format
|
||||||
try {
|
|
||||||
out.writeChar(type);
|
out.writeChar(type);
|
||||||
out.writeInt(length);
|
out.writeInt(length);
|
||||||
out.write(dataInBytes);
|
out.write(dataInBytes);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,46 @@
|
|||||||
package com.baeldung.socket.read;
|
package com.baeldung.socket.read;
|
||||||
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
|
|
||||||
//Socket and input stream
|
|
||||||
private Socket socket = null;
|
|
||||||
private ServerSocket server = null;
|
|
||||||
private DataInputStream in = null;
|
|
||||||
|
|
||||||
public void runServer(int port) {
|
public void runServer(int port) {
|
||||||
//Start the server and wait for connection
|
//Start the server and wait for connection
|
||||||
try {
|
try {
|
||||||
server = new ServerSocket(port);
|
ServerSocket server = new ServerSocket(port);
|
||||||
System.out.println("Server Started. Waiting for connection ...");
|
System.out.println("Server Started. Waiting for connection ...");
|
||||||
socket = server.accept();
|
Socket socket = server.accept();
|
||||||
System.out.println("Got connection from client.");
|
System.out.println("Got connection from client.");
|
||||||
//Get input stream from socket variable and convert the same to DataInputStream
|
//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
|
//Read type and length of data
|
||||||
char dataType = in.readChar();
|
char dataType = in.readChar();
|
||||||
int length = in.readInt();
|
int length = in.readInt();
|
||||||
System.out.println("Type : "+dataType);
|
System.out.println("Type : "+dataType);
|
||||||
System.out.println("Lenght :"+length);
|
System.out.println("Lenght :"+length);
|
||||||
|
if(dataType == 's') {
|
||||||
//Read String data in bytes
|
//Read String data in bytes
|
||||||
byte[] messageByte = new byte[length];
|
byte[] messageByte = new byte[length];
|
||||||
boolean end = false;
|
boolean end = false;
|
||||||
String dataString = "";
|
StringBuilder dataString = new StringBuilder(length);
|
||||||
int totalBytesRead = 0;
|
int totalBytesRead = 0;
|
||||||
//We need to run while loop, to read all data in that stream
|
//We need to run while loop, to read all data in that stream
|
||||||
while(!end) {
|
while(!end) {
|
||||||
int currentBytesRead = in.read(messageByte);
|
int currentBytesRead = in.read(messageByte);
|
||||||
totalBytesRead = currentBytesRead + totalBytesRead;
|
totalBytesRead = currentBytesRead + totalBytesRead;
|
||||||
if(totalBytesRead <= length) {
|
if(totalBytesRead <= length) {
|
||||||
dataString += new String(messageByte,0,currentBytesRead);
|
dataString.append(new String(messageByte,0,currentBytesRead,StandardCharsets.UTF_8));
|
||||||
} else {
|
} 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) {
|
if(dataString.length()>=length) {
|
||||||
end = true;
|
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) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -6,3 +6,5 @@ This module uses Java 9, so make sure to have the JDK 9 installed to run it.
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api)
|
- [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.Process API](https://www.baeldung.com/java-process-api)
|
||||||
|
- [Guide to java.lang.ProcessBuilder API](https://www.baeldung.com/java-lang-processbuilder-api)
|
||||||
|
|
||||||
|
@ -50,3 +50,4 @@
|
|||||||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||||
- [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators)
|
- [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)
|
- [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)
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
- [Void Type in Kotlin](https://www.baeldung.com/kotlin-void-type)
|
||||||
- [How to use Kotlin Range Expressions](https://www.baeldung.com/kotlin-ranges)
|
- [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)
|
- [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)
|
||||||
|
@ -13,4 +13,66 @@
|
|||||||
<relativePath>../parent-kotlin</relativePath>
|
<relativePath>../parent-kotlin</relativePath>
|
||||||
</parent>
|
</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>
|
</project>
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
21
core-kotlin-2/src/main/kotlin/com/baeldung/range/Color.kt
Normal file
21
core-kotlin-2/src/main/kotlin/com/baeldung/range/Color.kt
Normal 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))
|
||||||
|
}
|
18
core-kotlin-2/src/main/kotlin/com/baeldung/range/Filter.kt
Normal file
18
core-kotlin-2/src/main/kotlin/com/baeldung/range/Filter.kt
Normal 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)
|
||||||
|
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
28
core-kotlin-2/src/main/kotlin/com/baeldung/range/Range.kt
Normal file
28
core-kotlin-2/src/main/kotlin/com/baeldung/range/Range.kt
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
15
core-kotlin-2/src/main/kotlin/com/baeldung/range/Step.kt
Normal file
15
core-kotlin-2/src/main/kotlin/com/baeldung/range/Step.kt
Normal 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.range
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
for (i in 1 until 9) {
|
||||||
|
print(i)
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
@ -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) }
|
||||||
|
}
|
||||||
|
}
|
@ -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 })
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
@ -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()))
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
17
core-kotlin-2/src/test/kotlin/com/baeldung/range/StepTest.kt
Normal file
17
core-kotlin-2/src/test/kotlin/com/baeldung/range/StepTest.kt
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
@ -55,3 +55,4 @@
|
|||||||
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
- [Building DSLs in Kotlin](https://www.baeldung.com/kotlin-dsl)
|
||||||
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
- [Static Methods Behavior in Kotlin](https://www.baeldung.com/kotlin-static-methods)
|
||||||
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
|
- [Inline Functions in Kotlin](https://www.baeldung.com/kotlin-inline-functions)
|
||||||
|
- [Delegation Pattern in Kotlin](https://www.baeldung.com/kotlin-delegation-pattern)
|
||||||
|
@ -12,4 +12,5 @@
|
|||||||
- [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives)
|
- [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)
|
- [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)
|
- [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)
|
||||||
|
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
|
|
||||||
### Relevant Articles:
|
### 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)
|
||||||
|
45
java-collections-maps-2/pom.xml
Normal file
45
java-collections-maps-2/pom.xml
Normal 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>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -17,3 +17,4 @@
|
|||||||
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
|
- [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)
|
- [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)
|
- [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)
|
||||||
|
24
jhipster-5/bookstore-monolith/.editorconfig
Normal file
24
jhipster-5/bookstore-monolith/.editorconfig
Normal 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
|
148
jhipster-5/bookstore-monolith/.gitattributes
vendored
Normal file
148
jhipster-5/bookstore-monolith/.gitattributes
vendored
Normal 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
145
jhipster-5/bookstore-monolith/.gitignore
vendored
Normal 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
|
5
jhipster-5/bookstore-monolith/.huskyrc
Normal file
5
jhipster-5/bookstore-monolith/.huskyrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
}
|
54
jhipster-5/bookstore-monolith/.jhipster/Book.json
Normal file
54
jhipster-5/bookstore-monolith/.jhipster/Book.json
Normal 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"
|
||||||
|
}
|
110
jhipster-5/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
110
jhipster-5/bookstore-monolith/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
BIN
jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
1
jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
1
jhipster-5/bookstore-monolith/.mvn/wrapper/maven-wrapper.properties
vendored
Normal 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
|
3
jhipster-5/bookstore-monolith/.prettierignore
Normal file
3
jhipster-5/bookstore-monolith/.prettierignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
target
|
||||||
|
package-lock.json
|
12
jhipster-5/bookstore-monolith/.prettierrc
Normal file
12
jhipster-5/bookstore-monolith/.prettierrc
Normal 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
|
34
jhipster-5/bookstore-monolith/.yo-rc.json
Normal file
34
jhipster-5/bookstore-monolith/.yo-rc.json
Normal 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
|
||||||
|
}
|
||||||
|
}
|
179
jhipster-5/bookstore-monolith/README.md
Normal file
179
jhipster-5/bookstore-monolith/README.md
Normal 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/
|
39
jhipster-5/bookstore-monolith/angular.json
Normal file
39
jhipster-5/bookstore-monolith/angular.json
Normal 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
286
jhipster-5/bookstore-monolith/mvnw
vendored
Executable 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
161
jhipster-5/bookstore-monolith/mvnw.cmd
vendored
Normal 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%
|
18244
jhipster-5/bookstore-monolith/package-lock.json
generated
Normal file
18244
jhipster-5/bookstore-monolith/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
128
jhipster-5/bookstore-monolith/package.json
Normal file
128
jhipster-5/bookstore-monolith/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
1085
jhipster-5/bookstore-monolith/pom.xml
Normal file
1085
jhipster-5/bookstore-monolith/pom.xml
Normal file
File diff suppressed because it is too large
Load Diff
5
jhipster-5/bookstore-monolith/postcss.config.js
Normal file
5
jhipster-5/bookstore-monolith/postcss.config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
require('autoprefixer')
|
||||||
|
]
|
||||||
|
}
|
7
jhipster-5/bookstore-monolith/proxy.conf.json
Normal file
7
jhipster-5/bookstore-monolith/proxy.conf.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"*": {
|
||||||
|
"target": "http://localhost:8080",
|
||||||
|
"secure": false,
|
||||||
|
"loglevel": "debug"
|
||||||
|
}
|
||||||
|
}
|
14
jhipster-5/bookstore-monolith/src/main/docker/.dockerignore
Normal file
14
jhipster-5/bookstore-monolith/src/main/docker/.dockerignore
Normal 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
|
20
jhipster-5/bookstore-monolith/src/main/docker/Dockerfile
Normal file
20
jhipster-5/bookstore-monolith/src/main/docker/Dockerfile
Normal 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
|
||||||
|
|
15
jhipster-5/bookstore-monolith/src/main/docker/app.yml
Normal file
15
jhipster-5/bookstore-monolith/src/main/docker/app.yml
Normal 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
|
@ -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" "$@"
|
13
jhipster-5/bookstore-monolith/src/main/docker/mysql.yml
Normal file
13
jhipster-5/bookstore-monolith/src/main/docker/mysql.yml
Normal 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
|
7
jhipster-5/bookstore-monolith/src/main/docker/sonar.yml
Normal file
7
jhipster-5/bookstore-monolith/src/main/docker/sonar.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
bookstore-sonar:
|
||||||
|
image: sonarqube:7.1
|
||||||
|
ports:
|
||||||
|
- 9001:9000
|
||||||
|
- 9092:9092
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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() {
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Audit specific code.
|
||||||
|
*/
|
||||||
|
package com.baeldung.jhipster5.config.audit;
|
@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Spring Framework configuration files.
|
||||||
|
*/
|
||||||
|
package com.baeldung.jhipster5.config;
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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 + '\'' +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
@ -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() +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
@ -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
Loading…
x
Reference in New Issue
Block a user