Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
fa8dee2985
|
@ -2,7 +2,6 @@ package com.baeldung.datetime;
|
|||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Period;
|
||||
|
||||
public class UseDuration {
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.application;
|
||||
|
||||
import com.baeldung.defaultstaticinterfacemethods.model.Car;
|
||||
import com.baeldung.defaultstaticinterfacemethods.model.Vehicle;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Vehicle car = new Car("BMW");
|
||||
System.out.println(car.getBrand());
|
||||
System.out.println(car.speedUp());
|
||||
System.out.println(car.slowDown());
|
||||
System.out.println(car.turnAlarmOn());
|
||||
System.out.println(car.turnAlarmOff());
|
||||
System.out.println(Vehicle.getHorsePower(2500, 480));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||
|
||||
public interface Alarm {
|
||||
|
||||
default String turnAlarmOn() {
|
||||
return "Turning the alarm on.";
|
||||
}
|
||||
|
||||
default String turnAlarmOff() {
|
||||
return "Turning the alarm off.";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||
|
||||
public class Car implements Vehicle {
|
||||
|
||||
private final String brand;
|
||||
|
||||
public Car(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String speedUp() {
|
||||
return "The car is speeding up.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String slowDown() {
|
||||
return "The car is slowing down.";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||
|
||||
public class Motorbike implements Vehicle {
|
||||
|
||||
private final String brand;
|
||||
|
||||
public Motorbike(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String speedUp() {
|
||||
return "The motorbike is speeding up.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String slowDown() {
|
||||
return "The motorbike is slowing down.";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||
|
||||
public class MultiAlarmCar implements Vehicle, Alarm {
|
||||
|
||||
private final String brand;
|
||||
|
||||
public MultiAlarmCar(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String speedUp() {
|
||||
return "The motorbike is speeding up.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String slowDown() {
|
||||
return "The mootorbike is slowing down.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String turnAlarmOn() {
|
||||
return Vehicle.super.turnAlarmOn() + " " + Alarm.super.turnAlarmOn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String turnAlarmOff() {
|
||||
return Vehicle.super.turnAlarmOff() + " " + Alarm.super.turnAlarmOff();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.defaultstaticinterfacemethods.model;
|
||||
|
||||
public interface Vehicle {
|
||||
|
||||
String getBrand();
|
||||
|
||||
String speedUp();
|
||||
|
||||
String slowDown();
|
||||
|
||||
default String turnAlarmOn() {
|
||||
return "Turning the vehice alarm on.";
|
||||
}
|
||||
|
||||
default String turnAlarmOff() {
|
||||
return "Turning the vehicle alarm off.";
|
||||
}
|
||||
|
||||
static int getHorsePower(int rpm, int torque) {
|
||||
return (rpm * torque) / 5252;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.iterators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Source code https://github.com/eugenp/tutorials
|
||||
*
|
||||
* @author Santosh Thakur
|
||||
*/
|
||||
|
||||
public class Iterators {
|
||||
|
||||
public static int failFast1() {
|
||||
ArrayList<Integer> numbers = new ArrayList<>();
|
||||
|
||||
numbers.add(10);
|
||||
numbers.add(20);
|
||||
numbers.add(30);
|
||||
numbers.add(40);
|
||||
|
||||
Iterator<Integer> iterator = numbers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Integer number = iterator.next();
|
||||
numbers.add(50);
|
||||
}
|
||||
|
||||
return numbers.size();
|
||||
}
|
||||
|
||||
public static int failFast2() {
|
||||
ArrayList<Integer> numbers = new ArrayList<>();
|
||||
numbers.add(10);
|
||||
numbers.add(20);
|
||||
numbers.add(30);
|
||||
numbers.add(40);
|
||||
|
||||
Iterator<Integer> iterator = numbers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next() == 30) {
|
||||
// will not throw Exception
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("using iterator's remove method = " + numbers);
|
||||
|
||||
iterator = numbers.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next() == 40) {
|
||||
// will throw Exception on
|
||||
// next call of next() method
|
||||
numbers.remove(2);
|
||||
}
|
||||
}
|
||||
|
||||
return numbers.size();
|
||||
}
|
||||
|
||||
public static int failSafe1() {
|
||||
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
|
||||
|
||||
map.put("First", 10);
|
||||
map.put("Second", 20);
|
||||
map.put("Third", 30);
|
||||
map.put("Fourth", 40);
|
||||
|
||||
Iterator<String> iterator = map.keySet()
|
||||
.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
String key = iterator.next();
|
||||
map.put("Fifth", 50);
|
||||
}
|
||||
|
||||
return map.size();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.stream;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
class PrimitiveStreams {
|
||||
|
||||
int min(int[] integers) {
|
||||
return Arrays.stream(integers).min().getAsInt();
|
||||
}
|
||||
|
||||
int max(int... integers) {
|
||||
return IntStream.of(integers).max().getAsInt();
|
||||
}
|
||||
|
||||
int sum(int... integers) {
|
||||
return IntStream.of(integers).sum();
|
||||
}
|
||||
|
||||
double avg(int... integers) {
|
||||
return IntStream.of(integers).average().getAsDouble();
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package com.baeldung.streamApi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.baeldung.counter;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
|
@ -18,8 +19,18 @@ public class CounterStatistics {
|
|||
private static final Map<String, MutableInteger> counterWithMutableIntMap = new HashMap<>();
|
||||
private static final Map<String, int[]> counterWithIntArrayMap = new HashMap<>();
|
||||
private static final Map<String, Long> counterWithLongWrapperMap = new HashMap<>();
|
||||
private static final Map<String, Long> counterWithLongWrapperStreamMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
CounterUtil.COUNTRY_NAMES = new String[10000];
|
||||
final String prefix = "NewString";
|
||||
Random random = new Random();
|
||||
for (int i=0; i<10000; i++) {
|
||||
CounterUtil.COUNTRY_NAMES[i] = new String(prefix + random.nextInt(1000));
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@Benchmark
|
||||
public void wrapperAsCounter() {
|
||||
CounterUtil.counterWithWrapperObject(counterMap);
|
||||
}
|
||||
|
@ -28,6 +39,11 @@ public class CounterStatistics {
|
|||
public void lambdaExpressionWithWrapper() {
|
||||
CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void parallelStreamWithWrapper() {
|
||||
CounterUtil.counterWithParallelStreamAndWrapper(counterWithLongWrapperStreamMap);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void mutableIntegerAsCounter() {
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.stream.Stream;
|
|||
|
||||
public class CounterUtil {
|
||||
|
||||
private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
|
||||
public static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
|
||||
|
||||
public static void counterWithWrapperObject(Map<String, Integer> counterMap) {
|
||||
for (String country : COUNTRY_NAMES) {
|
||||
|
@ -15,9 +15,14 @@ public class CounterUtil {
|
|||
}
|
||||
|
||||
public static void counterWithLambdaAndWrapper(Map<String, Long> counterMap) {
|
||||
counterMap.putAll(Stream.of(COUNTRY_NAMES)
|
||||
Stream.of(COUNTRY_NAMES)
|
||||
.collect(Collectors.groupingBy(k -> k, () -> counterMap, Collectors.counting()));
|
||||
}
|
||||
|
||||
public static void counterWithParallelStreamAndWrapper(Map<String, Long> counterMap) {
|
||||
Stream.of(COUNTRY_NAMES)
|
||||
.parallel()
|
||||
.collect(Collectors.groupingBy(k -> k, Collectors.counting())));
|
||||
.collect(Collectors.groupingBy(k -> k, () -> counterMap, Collectors.counting()));
|
||||
}
|
||||
|
||||
public static class MutableInteger {
|
||||
|
@ -38,24 +43,15 @@ public class CounterUtil {
|
|||
|
||||
public static void counterWithMutableInteger(Map<String, MutableInteger> counterMap) {
|
||||
for (String country : COUNTRY_NAMES) {
|
||||
MutableInteger oldValue = counterMap.get(country);
|
||||
if (oldValue != null) {
|
||||
oldValue.increment();
|
||||
} else {
|
||||
counterMap.put(country, new MutableInteger(1));
|
||||
}
|
||||
counterMap.compute(country, (k, v) -> v == null ? new MutableInteger(0) : v)
|
||||
.increment();
|
||||
}
|
||||
}
|
||||
|
||||
public static void counterWithPrimitiveArray(Map<String, int[]> counterMap) {
|
||||
for (String country : COUNTRY_NAMES) {
|
||||
int[] oldCounter = counterMap.get(country);
|
||||
if (oldCounter != null) {
|
||||
oldCounter[0] += 1;
|
||||
} else {
|
||||
counterMap.put(country, new int[] { 1 });
|
||||
}
|
||||
counterMap.compute(country, (k, v) -> v == null ? new int[] { 0 } : v)[0]++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import java.time.LocalDate;
|
|||
import java.time.LocalTime;
|
||||
import java.time.Month;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.time.DayOfWeek;
|
|||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package com.baeldung.defaultistaticinterfacemethods.test;
|
||||
|
||||
import com.baeldung.defaultstaticinterfacemethods.model.Car;
|
||||
import com.baeldung.defaultstaticinterfacemethods.model.Motorbike;
|
||||
import com.baeldung.defaultstaticinterfacemethods.model.Vehicle;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
public class StaticDefaulInterfaceMethodUnitTest {
|
||||
|
||||
private static Car car;
|
||||
private static Motorbike motorbike;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpCarInstance() {
|
||||
car = new Car("BMW");
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpMotorbikeInstance() {
|
||||
motorbike = new Motorbike("Yamaha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCarInstace_whenBrandisBMW_thenOneAssertion() {
|
||||
assertThat(car.getBrand()).isEqualTo("BMW");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCarInstance_whenCallingSpeedUp_thenOneAssertion() {
|
||||
assertThat(car.speedUp()).isEqualTo("The car is speeding up.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCarInstance_whenCallingSlowDown_thenOneAssertion() {
|
||||
assertThat(car.slowDown()).isEqualTo("The car is slowing down.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCarInstance_whenCallingTurnAlarmOn_thenOneAssertion() {
|
||||
assertThat(car.turnAlarmOn()).isEqualTo("Turning the vehice alarm on.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCarInstance_whenCallingTurnAlarmOff_thenOneAssertion() {
|
||||
assertThat(car.turnAlarmOff()).isEqualTo("Turning the vehicle alarm off.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVehicleInterface_whenCallinggetHorsePower_thenOneAssertion() {
|
||||
assertThat(Vehicle.getHorsePower(2500, 480)).isEqualTo(228);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMooorbikeInstace_whenBrandisYamaha_thenOneAssertion() {
|
||||
assertThat(motorbike.getBrand()).isEqualTo("Yamaha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMotorbikeInstance_whenCallingSpeedUp_thenOneAssertion() {
|
||||
assertThat(motorbike.speedUp()).isEqualTo("The motorbike is speeding up.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMotorbikeInstance_whenCallingSlowDown_thenOneAssertion() {
|
||||
assertThat(motorbike.slowDown()).isEqualTo("The motorbike is slowing down.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMotorbikeInstance_whenCallingTurnAlarmOn_thenOneAssertion() {
|
||||
assertThat(motorbike.turnAlarmOn()).isEqualTo("Turning the vehice alarm on.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMotorbikeInstance_whenCallingTurnAlarmOff_thenOneAssertion() {
|
||||
assertThat(motorbike.turnAlarmOff()).isEqualTo("Turning the vehicle alarm off.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.iterators;
|
||||
|
||||
import static com.baeldung.iterators.Iterators.failFast1;
|
||||
import static com.baeldung.iterators.Iterators.failFast2;
|
||||
import static com.baeldung.iterators.Iterators.failSafe1;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Source code https://github.com/eugenp/tutorials
|
||||
*
|
||||
* @author Santosh Thakur
|
||||
*/
|
||||
|
||||
public class IteratorsTest {
|
||||
|
||||
@Test
|
||||
public void whenFailFast_ThenThrowsException() {
|
||||
assertThatThrownBy(() -> {
|
||||
failFast1();
|
||||
}).isInstanceOf(ConcurrentModificationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFailFast_ThenThrowsExceptionInSecondIteration() {
|
||||
assertThatThrownBy(() -> {
|
||||
failFast2();
|
||||
}).isInstanceOf(ConcurrentModificationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFailSafe_ThenDoesNotThrowException() {
|
||||
assertThat(failSafe1()).isGreaterThanOrEqualTo(0);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,6 @@ import java.util.Comparator;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import lombok.Data;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class Java8ComparatorUnitTest {
|
||||
|
@ -134,8 +133,7 @@ public class Java8ComparatorUnitTest {
|
|||
|
||||
@Test
|
||||
public void whenThenComparing_thenSortedByAgeName() {
|
||||
Comparator<Employee> employee_Age_Name_Comparator = Comparator.comparing(Employee::getAge)
|
||||
.thenComparing(Employee::getName);
|
||||
Comparator<Employee> employee_Age_Name_Comparator = Comparator.comparing(Employee::getAge).thenComparing(Employee::getName);
|
||||
|
||||
Arrays.sort(someMoreEmployees, employee_Age_Name_Comparator);
|
||||
// System.out.println(Arrays.toString(someMoreEmployees));
|
||||
|
@ -144,8 +142,7 @@ public class Java8ComparatorUnitTest {
|
|||
|
||||
@Test
|
||||
public void whenThenComparing_thenSortedByNameAge() {
|
||||
Comparator<Employee> employee_Name_Age_Comparator = Comparator.comparing(Employee::getName)
|
||||
.thenComparingInt(Employee::getAge);
|
||||
Comparator<Employee> employee_Name_Age_Comparator = Comparator.comparing(Employee::getName).thenComparingInt(Employee::getAge);
|
||||
|
||||
Arrays.sort(someMoreEmployees, employee_Name_Age_Comparator);
|
||||
// System.out.println(Arrays.toString(someMoreEmployees));
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package com.baeldung.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PrimitiveStreamsUnitTest {
|
||||
|
||||
private PrimitiveStreams streams = new PrimitiveStreams();
|
||||
|
||||
@Test
|
||||
public void givenAnArrayOfIntegersWhenMinIsCalledThenCorrectMinIsReturned() {
|
||||
int[] integers = new int[] {20, 98, 12, 7, 35};
|
||||
int min = streams.min(integers); // returns 7
|
||||
|
||||
assertEquals(7, min);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnArrayOfIntegersWhenMaxIsCalledThenCorrectMaxIsReturned() {
|
||||
int max = streams.max(20, 98, 12, 7, 35);
|
||||
|
||||
assertEquals(98, max);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnArrayOfIntegersWhenSumIsCalledThenCorrectSumIsReturned() {
|
||||
int sum = streams.sum(20, 98, 12, 7, 35);
|
||||
|
||||
assertEquals(172, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnArrayOfIntegersWhenAvgIsCalledThenCorrectAvgIsReturned() {
|
||||
double avg = streams.avg(20, 98, 12, 7, 35);
|
||||
|
||||
assertTrue(34.4 == avg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenARangeOfIntegersWhenIntStreamSumIsCalledThenCorrectSumIsReturned() {
|
||||
int sum = IntStream.range(1, 10).sum();
|
||||
|
||||
assertEquals(45, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenARangeClosedOfIntegersWhenIntStreamSumIsCalledThenCorrectSumIsReturned() {
|
||||
int sum = IntStream.rangeClosed(1, 10).sum();
|
||||
|
||||
assertEquals(55, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenARangeWhenForEachIsCalledThenTheIndicesWillBePrinted() {
|
||||
IntStream.rangeClosed(1, 5).parallel().forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() {
|
||||
|
||||
int sum = Arrays.asList(33,45).stream().mapToInt(a -> a).sum();
|
||||
|
||||
assertEquals(78, sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnIntStreamThenGetTheEvenIntegers() {
|
||||
List<Integer> evenInts = IntStream.rangeClosed(1, 10)
|
||||
.filter(i -> i % 2 == 0)
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Integer> expected = IntStream.of(2, 4, 6, 8, 10).boxed().collect(Collectors.toList());
|
||||
|
||||
assertEquals(expected, evenInts);
|
||||
}
|
||||
|
||||
class Person {
|
||||
private int age;
|
||||
|
||||
Person(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return age;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package com.baeldung.temporaladjusters;
|
||||
|
||||
import com.baeldung.temporaladjuster.CustomTemporalAdjuster;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
|
|
@ -19,3 +19,4 @@
|
|||
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
||||
- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
|
||||
- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime)
|
||||
- [Java 9 Variable Handles Demistyfied](http://www.baeldung.com/java-variable-handles)
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package com.baeldung.java9.varhandles;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class VariableHandlesTest {
|
||||
|
||||
public int publicTestVariable = 1;
|
||||
private int privateTestVariable = 1;
|
||||
public int variableToSet = 1;
|
||||
public int variableToCompareAndSet = 1;
|
||||
public int variableToGetAndAdd = 0;
|
||||
public byte variableToBitwiseOr = 0;
|
||||
|
||||
@Test
|
||||
public void whenVariableHandleForPublicVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
|
||||
|
||||
assertThat(publicIntHandle.coordinateTypes().size() == 1);
|
||||
assertThat(publicIntHandle.coordinateTypes().get(0) == VariableHandles.class);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVariableHandleForPrivateVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle privateIntHandle = MethodHandles
|
||||
.privateLookupIn(VariableHandlesTest.class, MethodHandles.lookup())
|
||||
.findVarHandle(VariableHandlesTest.class, "privateTestVariable", int.class);
|
||||
|
||||
assertThat(privateIntHandle.coordinateTypes().size() == 1);
|
||||
assertThat(privateIntHandle.coordinateTypes().get(0) == VariableHandlesTest.class);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenVariableHandleForArrayVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle arrayVarHandle = MethodHandles
|
||||
.arrayElementVarHandle(int[].class);
|
||||
|
||||
assertThat(arrayVarHandle.coordinateTypes().size() == 2);
|
||||
assertThat(arrayVarHandle.coordinateTypes().get(0) == int[].class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVarHandle_whenGetIsInvoked_ThenValueOfVariableIsReturned() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
|
||||
|
||||
assertThat((int) publicIntHandle.get(this) == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVarHandle_whenSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "variableToSet", int.class);
|
||||
publicIntHandle.set(this, 15);
|
||||
|
||||
assertThat((int) publicIntHandle.get(this) == 15);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVarHandle_whenCompareAndSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "variableToCompareAndSet", int.class);
|
||||
publicIntHandle.compareAndSet(this, 1, 100);
|
||||
|
||||
assertThat((int) publicIntHandle.get(this) == 100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVarHandle_whenGetAndAddIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "variableToGetAndAdd", int.class);
|
||||
int before = (int) publicIntHandle.getAndAdd(this, 200);
|
||||
|
||||
assertThat(before == 0);
|
||||
assertThat((int) publicIntHandle.get(this) == 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenVarHandle_whenGetAndBitwiseOrIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||
VarHandle publicIntHandle = MethodHandles
|
||||
.lookup()
|
||||
.in(VariableHandlesTest.class)
|
||||
.findVarHandle(VariableHandlesTest.class, "variableToBitwiseOr", byte.class);
|
||||
byte before = (byte) publicIntHandle.getAndBitwiseOr(this, (byte) 127);
|
||||
|
||||
assertThat(before == 0);
|
||||
assertThat(variableToBitwiseOr == 127);
|
||||
}
|
||||
}
|
|
@ -126,3 +126,7 @@
|
|||
- [Java – Append Data to a File](http://www.baeldung.com/java-append-to-file)
|
||||
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)
|
||||
- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter)
|
||||
- [Batch Processing in JDBC](http://www.baeldung.com/jdbc-batch-processing)
|
||||
- [Check if a Java Array Contains a Value](http://www.baeldung.com/java-array-contains-value)
|
||||
- [How to Invert an Array in Java](http://www.baeldung.com/java-invert-array)
|
||||
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
|
||||
|
|
|
@ -1,496 +1,495 @@
|
|||
<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</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
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</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>core-java</name>
|
||||
<name>core-java</name>
|
||||
|
||||
<dependencies>
|
||||
<dependencies>
|
||||
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.collections</groupId>
|
||||
<artifactId>collections-generic</artifactId>
|
||||
<version>${collections-generic.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.collections</groupId>
|
||||
<artifactId>collections-generic</artifactId>
|
||||
<version>${collections-generic.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.decimal4j</groupId>
|
||||
<artifactId>decimal4j</artifactId>
|
||||
<version>${decimal4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.decimal4j</groupId>
|
||||
<artifactId>decimal4j</artifactId>
|
||||
<version>${decimal4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bouncycastle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>${bouncycastle.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.unix4j</groupId>
|
||||
<artifactId>unix4j-command</artifactId>
|
||||
<version>${unix4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.unix4j</groupId>
|
||||
<artifactId>unix4j-command</artifactId>
|
||||
<version>${unix4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.googlecode.grep4j</groupId>
|
||||
<artifactId>grep4j</artifactId>
|
||||
<version>${grep4j.version}</version>
|
||||
</dependency>
|
||||
<!-- web -->
|
||||
<dependency>
|
||||
<groupId>com.googlecode.grep4j</groupId>
|
||||
<artifactId>grep4j</artifactId>
|
||||
<version>${grep4j.version}</version>
|
||||
</dependency>
|
||||
<!-- web -->
|
||||
|
||||
<!-- marshalling -->
|
||||
<!-- marshalling -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
<!-- <scope>runtime</scope> -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<!-- <scope>runtime</scope> --> <!-- some spring dependencies need to compile against jcl -->
|
||||
</dependency>
|
||||
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- logging -->
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.17</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
<!-- <scope>runtime</scope> -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
<!-- <scope>runtime</scope> --> <!-- some spring dependencies need to compile against jcl -->
|
||||
</dependency>
|
||||
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>${org.slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test scoped -->
|
||||
<!-- test scoped -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<version>${org.hamcrest.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>${org.hamcrest.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<version>${org.hamcrest.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>${org.hamcrest.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.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>${avaitility.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>${avaitility.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.javamoney</groupId>
|
||||
<artifactId>moneta</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javamoney</groupId>
|
||||
<artifactId>moneta</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.owasp.esapi</groupId>
|
||||
<artifactId>esapi</artifactId>
|
||||
<version>2.1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.196</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.messaging.mq</groupId>
|
||||
<artifactId>fscontext</artifactId>
|
||||
<version>${fscontext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.codepoetics</groupId>
|
||||
<artifactId>protonpack</artifactId>
|
||||
<version>${protonpack.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>one.util</groupId>
|
||||
<artifactId>streamex</artifactId>
|
||||
<version>${streamex.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vavr</groupId>
|
||||
<artifactId>vavr</artifactId>
|
||||
<version>${vavr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.3.4.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.esapi</groupId>
|
||||
<artifactId>esapi</artifactId>
|
||||
<version>2.1.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.messaging.mq</groupId>
|
||||
<artifactId>fscontext</artifactId>
|
||||
<version>${fscontext.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.codepoetics</groupId>
|
||||
<artifactId>protonpack</artifactId>
|
||||
<version>${protonpack.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>one.util</groupId>
|
||||
<artifactId>streamex</artifactId>
|
||||
<version>${streamex.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vavr</groupId>
|
||||
<artifactId>vavr</artifactId>
|
||||
<version>${vavr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>1.19</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.3.4.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>1.5.8.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.4.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>core-java</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<build>
|
||||
<finalName>core-java</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*LongRunningUnitTest.java</exclude>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
</excludes>
|
||||
<testFailureIgnore>true</testFailureIgnore>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*LongRunningUnitTest.java</exclude>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
</excludes>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>libs/</classpathPrefix>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>${project.build.directory}/libs</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>libs/</classpathPrefix>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.jolira</groupId>
|
||||
<artifactId>onejar-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<configuration>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
<attachToBuild>true</attachToBuild>
|
||||
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>one-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>spring-boot</classifier>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.jolira</groupId>
|
||||
<artifactId>onejar-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<configuration>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
<attachToBuild>true</attachToBuild>
|
||||
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>one-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>spring-boot</classifier>
|
||||
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
<arguments>
|
||||
<argument>-Xmx300m</argument>
|
||||
<argument>-XX:+UseParallelGC</argument>
|
||||
<argument>-classpath</argument>
|
||||
<classpath />
|
||||
<argument>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<configuration>
|
||||
<executable>java</executable>
|
||||
<mainClass>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</mainClass>
|
||||
<arguments>
|
||||
<argument>-Xmx300m</argument>
|
||||
<argument>-XX:+UseParallelGC</argument>
|
||||
<argument>-classpath</argument>
|
||||
<classpath/>
|
||||
<argument>com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*ManualTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
<!-- <phase>integration-test</phase> -->
|
||||
<phase>none</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classpathScope>test</classpathScope>
|
||||
<executable>java</executable>
|
||||
<arguments>
|
||||
<argument>-classpath</argument>
|
||||
<classpath />
|
||||
<argument>org.openjdk.jmh.Main</argument>
|
||||
<argument>.*</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-benchmarks</id>
|
||||
<!-- <phase>integration-test</phase>-->
|
||||
<phase>none</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classpathScope>test</classpathScope>
|
||||
<executable>java</executable>
|
||||
<arguments>
|
||||
<argument>-classpath</argument>
|
||||
<classpath/>
|
||||
<argument>org.openjdk.jmh.Main</argument>
|
||||
<argument>.*</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<!-- marshalling -->
|
||||
<jackson.version>2.8.5</jackson.version>
|
||||
<properties>
|
||||
<!-- marshalling -->
|
||||
<jackson.version>2.8.5</jackson.version>
|
||||
|
||||
<!-- logging -->
|
||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||
<logback.version>1.1.7</logback.version>
|
||||
<!-- logging -->
|
||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||
<logback.version>1.1.7</logback.version>
|
||||
|
||||
<!-- util -->
|
||||
<guava.version>22.0</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<bouncycastle.version>1.55</bouncycastle.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<decimal4j.version>1.0.3</decimal4j.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<collections-generic.version>4.01</collections-generic.version>
|
||||
<unix4j.version>0.4</unix4j.version>
|
||||
<grep4j.version>1.8.7</grep4j.version>
|
||||
<lombok.version>1.16.12</lombok.version>
|
||||
<fscontext.version>4.6-b01</fscontext.version>
|
||||
<protonpack.version>1.13</protonpack.version>
|
||||
<streamex.version>0.6.5</streamex.version>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
<!-- util -->
|
||||
<guava.version>22.0</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<bouncycastle.version>1.55</bouncycastle.version>
|
||||
<commons-codec.version>1.10</commons-codec.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<decimal4j.version>1.0.3</decimal4j.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<collections-generic.version>4.01</collections-generic.version>
|
||||
<unix4j.version>0.4</unix4j.version>
|
||||
<grep4j.version>1.8.7</grep4j.version>
|
||||
<lombok.version>1.16.12</lombok.version>
|
||||
<fscontext.version>4.6-b01</fscontext.version>
|
||||
<protonpack.version>1.13</protonpack.version>
|
||||
<streamex.version>0.6.5</streamex.version>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
|
||||
<!-- testing -->
|
||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<mockito.version>2.8.9</mockito.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
|
||||
<!-- testing -->
|
||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<mockito.version>2.8.9</mockito.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
|
||||
<!-- maven plugins -->
|
||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
</project>
|
||||
<!-- maven plugins -->
|
||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -25,7 +25,9 @@ public class ArrayInverter {
|
|||
}
|
||||
|
||||
public Object[] invertUsingStreams(final Object[] array) {
|
||||
return IntStream.range(1, array.length + 1).mapToObj(i -> array[array.length - i]).toArray();
|
||||
return IntStream.rangeClosed(1, array.length)
|
||||
.mapToObj(i -> array[array.length - i])
|
||||
.toArray();
|
||||
}
|
||||
|
||||
public void invertUsingCommonsLang(Object[] array) {
|
||||
|
|
|
@ -10,78 +10,60 @@ import java.util.concurrent.TimeUnit;
|
|||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
public class SearchArrayTest {
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class SearchData {
|
||||
static int count = 1000;
|
||||
static String[] strings = seedArray(1000);
|
||||
}
|
||||
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayLoop() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
searchLoop(strings, "T");
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
searchLoop(SearchData.strings, "T");
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayAllocNewList() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
searchList(strings, "W");
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
searchList(SearchData.strings, "T");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayAllocNewSet() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
searchSet(strings, "S");
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
searchSet(SearchData.strings, "T");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayReuseList() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
|
||||
List<String> asList = Arrays.asList(strings);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
asList.contains("W");
|
||||
List<String> asList = Arrays.asList(SearchData.strings);
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
asList.contains("T");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayReuseSet() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
Set<String> asSet = new HashSet<>(Arrays.asList(strings));
|
||||
for (int i = 0; i < count; i++) {
|
||||
asSet.contains("S");
|
||||
Set<String> asSet = new HashSet<>(Arrays.asList(SearchData.strings));
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
asSet.contains("T");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Benchmark
|
||||
public void searchArrayBinarySearch() {
|
||||
|
||||
int count = 1000;
|
||||
String[] strings = seedArray(count);
|
||||
Arrays.sort(strings);
|
||||
|
||||
long startTime = System.nanoTime();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Arrays.binarySearch(strings, "A");
|
||||
Arrays.sort(SearchData.strings);
|
||||
for (int i = 0; i < SearchData.count; i++) {
|
||||
Arrays.binarySearch(SearchData.strings, "T");
|
||||
}
|
||||
long duration = System.nanoTime() - startTime;
|
||||
//System.out.println("Binary search: " + duration / 10000);
|
||||
|
||||
}
|
||||
|
||||
private boolean searchList(String[] strings, String searchString) {
|
||||
|
@ -101,8 +83,7 @@ public class SearchArrayTest {
|
|||
return false;
|
||||
}
|
||||
|
||||
private String[] seedArray(int length) {
|
||||
|
||||
private static String[] seedArray(int length) {
|
||||
String[] strings = new String[length];
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < length; i++)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.cipher;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
|
||||
public class Encryptor {
|
||||
|
||||
public byte[] encryptMessage(byte[] message, byte[] keyBytes) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
byte[] encryptedMessage = cipher.doFinal(message);
|
||||
return encryptedMessage;
|
||||
}
|
||||
|
||||
public byte[] encryptMessage(byte[] message, Certificate publicKeyCertificate) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKeyCertificate);
|
||||
byte[] encryptedMessage = cipher.doFinal(message);
|
||||
return encryptedMessage;
|
||||
}
|
||||
|
||||
public byte[] decryptMessage(byte[] encryptedMessage, byte[] keyBytes) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
SecretKey secretKey = new SecretKeySpec(keyBytes, "AES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
byte[] clearMessage = cipher.doFinal(encryptedMessage);
|
||||
return clearMessage;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.initializationguide;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class User implements Serializable, Cloneable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
static String forum;
|
||||
private String name;
|
||||
private int id;
|
||||
|
||||
{
|
||||
id = 0;
|
||||
System.out.println("Instance Initializer");
|
||||
}
|
||||
|
||||
static {
|
||||
forum = "Java";
|
||||
System.out.println("Static Initializer");
|
||||
}
|
||||
|
||||
public User(String name, int id) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public User() {
|
||||
System.out.println("Constructor");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.baeldung.jdbc;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BatchProcessing {
|
||||
|
||||
private final String[] EMPLOYEES = new String[]{"Zuck","Mike","Larry","Musk","Steve"};
|
||||
private final String[] DESIGNATIONS = new String[]{"CFO","CSO","CTO","CEO","CMO"};
|
||||
private final String[] ADDRESSES = new String[]{"China","York","Diego","Carolina","India"};
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public void getConnection(){
|
||||
try {
|
||||
Class.forName("org.hsqldb.jdbcDriver");
|
||||
connection = DriverManager.getConnection("jdbc:hsqldb:file:C:\\EMPLOYEEDB", "SA", "");
|
||||
connection.setAutoCommit(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
public void createTables(){
|
||||
try {
|
||||
connection.createStatement().executeUpdate("create table EMPLOYEE (ID VARCHAR(36), NAME VARCHAR(45), DESIGNATION VARCHAR(15))");
|
||||
connection.createStatement().executeUpdate("create table EMP_ADDRESS (ID VARCHAR(36), EMP_ID VARCHAR(36), ADDRESS VARCHAR(45))");
|
||||
System.out.println("Tables Created!!!");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
public void useStatement(){
|
||||
try {
|
||||
String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) VALUES ('%s','%s','%s');";
|
||||
String insertEmployeeAddrSQL = "INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) VALUES ('%s','%s','%s');";
|
||||
Statement statement = connection.createStatement();
|
||||
for(int i = 0; i < EMPLOYEES.length; i++){
|
||||
String employeeId = UUID.randomUUID().toString();
|
||||
statement.addBatch(String.format(insertEmployeeSQL, employeeId, EMPLOYEES[i],DESIGNATIONS[i]));
|
||||
statement.addBatch(String.format(insertEmployeeAddrSQL, UUID.randomUUID().toString(),employeeId,ADDRESSES[i]));
|
||||
}
|
||||
statement.executeBatch();
|
||||
connection.commit();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
connection.rollback();
|
||||
} catch (SQLException ex) {
|
||||
System.out.println("Error during rollback");
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
public void usePreparedStatement(){
|
||||
try {
|
||||
String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) VALUES (?,?,?);";
|
||||
String insertEmployeeAddrSQL = "INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) VALUES (?,?,?);";
|
||||
PreparedStatement employeeStmt = connection.prepareStatement(insertEmployeeSQL);
|
||||
PreparedStatement empAddressStmt = connection.prepareStatement(insertEmployeeAddrSQL);
|
||||
for(int i = 0; i < EMPLOYEES.length; i++){
|
||||
String employeeId = UUID.randomUUID().toString();
|
||||
employeeStmt.setString(1,employeeId);
|
||||
employeeStmt.setString(2,EMPLOYEES[i]);
|
||||
employeeStmt.setString(3,DESIGNATIONS[i]);
|
||||
employeeStmt.addBatch();
|
||||
|
||||
empAddressStmt.setString(1,UUID.randomUUID().toString());
|
||||
empAddressStmt.setString(2,employeeId);
|
||||
empAddressStmt.setString(3,ADDRESSES[i]);
|
||||
empAddressStmt.addBatch();
|
||||
}
|
||||
employeeStmt.executeBatch();
|
||||
empAddressStmt.executeBatch();
|
||||
connection.commit();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
connection.rollback();
|
||||
} catch (SQLException ex) {
|
||||
System.out.println("Error during rollback");
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
BatchProcessing batchProcessing = new BatchProcessing();
|
||||
batchProcessing.getConnection();
|
||||
batchProcessing.createTables();
|
||||
batchProcessing.useStatement();
|
||||
batchProcessing.usePreparedStatement();
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ public class GenericFile {
|
|||
}
|
||||
|
||||
public String getFileInfo() {
|
||||
return String.format("File Name: %s\n" + " Extension: %s\n" + " Date Created: %s\n" + " Version: %s\n", this.getName(), this.getExtension(), this.getDateCreated(), this.getVersion());
|
||||
return "Generic File Impl";
|
||||
}
|
||||
|
||||
public Object read() {
|
||||
|
|
|
@ -30,7 +30,7 @@ public class ImageFile extends GenericFile {
|
|||
}
|
||||
|
||||
public String getFileInfo() {
|
||||
return String.format(" %s Height: %d\n Width: %d", super.getFileInfo(), this.getHeight(), this.getWidth());
|
||||
return "Image File Impl";
|
||||
}
|
||||
|
||||
public String read() {
|
||||
|
|
|
@ -21,7 +21,7 @@ public class TextFile extends GenericFile {
|
|||
}
|
||||
|
||||
public String getFileInfo() {
|
||||
return String.format(" %s Word Count: %d", super.getFileInfo(), wordCount);
|
||||
return "Text File Impl";
|
||||
}
|
||||
|
||||
public String read() {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
public class FileCopy {
|
||||
|
||||
public static void copyFileUsingStream(File source, File dest) throws IOException {
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
is = new FileInputStream(source);
|
||||
os = new FileOutputStream(dest);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = is.read(buffer)) > 0) {
|
||||
os.write(buffer, 0, length);
|
||||
}
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
|
||||
public static void copyFileUsingChannel(File source, File dest) throws IOException {
|
||||
FileChannel sourceChannel = null;
|
||||
FileChannel destChannel = null;
|
||||
sourceChannel = new FileInputStream(source).getChannel();
|
||||
destChannel = new FileOutputStream(dest).getChannel();
|
||||
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
|
||||
sourceChannel.close();
|
||||
destChannel.close();
|
||||
}
|
||||
|
||||
public static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
|
||||
FileUtils.copyFile(source, dest);
|
||||
}
|
||||
|
||||
public static void copyFileUsingJavaFiles(File source, File dest) throws IOException {
|
||||
Files.copy(source.toPath(), dest.toPath());
|
||||
}
|
||||
|
||||
}
|
|
@ -16,29 +16,23 @@ public class BinaryTree {
|
|||
return;
|
||||
}
|
||||
|
||||
Node parent = root;
|
||||
Node current = root;
|
||||
addRecursive(root, value);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
private Node addRecursive(Node current, int value) {
|
||||
|
||||
if (newNode.value < parent.value) {
|
||||
current = parent.left;
|
||||
|
||||
if (current == null) {
|
||||
parent.left = newNode;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
current = parent.right;
|
||||
|
||||
if (current == null) {
|
||||
parent.right = newNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parent = current;
|
||||
if (current == null) {
|
||||
return new Node(value);
|
||||
}
|
||||
|
||||
if (value < current.value) {
|
||||
current.left = addRecursive(current.left, value);
|
||||
} else {
|
||||
current.right = addRecursive(current.right, value);
|
||||
}
|
||||
|
||||
return current;
|
||||
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
@ -46,115 +40,69 @@ public class BinaryTree {
|
|||
}
|
||||
|
||||
public boolean containsNode(int value) {
|
||||
|
||||
Node current = root;
|
||||
|
||||
while (current != null) {
|
||||
|
||||
if (value == current.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value < current.value) {
|
||||
current = current.left;
|
||||
} else {
|
||||
current = current.right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
return containsNodeRecursive(root, value);
|
||||
}
|
||||
|
||||
public void delete(int value) {
|
||||
private boolean containsNodeRecursive(Node current, int value) {
|
||||
|
||||
Node current = root;
|
||||
Node parent = root;
|
||||
Node nodeToDelete = null;
|
||||
boolean isLeftChild = false;
|
||||
|
||||
while (nodeToDelete == null && current != null) {
|
||||
|
||||
if (value == current.value) {
|
||||
nodeToDelete = current;
|
||||
} else if (value < current.value) {
|
||||
parent = current;
|
||||
current = current.left;
|
||||
isLeftChild = true;
|
||||
} else {
|
||||
parent = current;
|
||||
current = current.right;
|
||||
isLeftChild = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (nodeToDelete == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Case 1: no children
|
||||
if (nodeToDelete.left == null && nodeToDelete.right == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = null;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = null;
|
||||
} else {
|
||||
parent.right = null;
|
||||
}
|
||||
}
|
||||
// Case 2: only 1 child
|
||||
else if (nodeToDelete.right == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = nodeToDelete.left;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = nodeToDelete.left;
|
||||
} else {
|
||||
parent.right = nodeToDelete.left;
|
||||
}
|
||||
} else if (nodeToDelete.left == null) {
|
||||
if (nodeToDelete == root) {
|
||||
root = nodeToDelete.right;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = nodeToDelete.right;
|
||||
} else {
|
||||
parent.right = nodeToDelete.right;
|
||||
}
|
||||
}
|
||||
// Case 3: 2 children
|
||||
else if (nodeToDelete.left != null && nodeToDelete.right != null) {
|
||||
Node replacement = findReplacement(nodeToDelete);
|
||||
if (nodeToDelete == root) {
|
||||
root = replacement;
|
||||
} else if (isLeftChild) {
|
||||
parent.left = replacement;
|
||||
} else {
|
||||
parent.right = replacement;
|
||||
}
|
||||
if (current == null) {
|
||||
return false;
|
||||
} else if (value == current.value) {
|
||||
return true;
|
||||
} else if (value < current.value) {
|
||||
return containsNodeRecursive(current.left, value);
|
||||
} else {
|
||||
return containsNodeRecursive(current.right, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Node findReplacement(Node nodeToDelete) {
|
||||
public void delete(int value) {
|
||||
deleteRecursive(root, value);
|
||||
}
|
||||
|
||||
Node replacement = nodeToDelete;
|
||||
Node parentReplacement = nodeToDelete;
|
||||
Node current = nodeToDelete.right;
|
||||
|
||||
while (current != null) {
|
||||
parentReplacement = replacement;
|
||||
replacement = current;
|
||||
current = current.left;
|
||||
private Node deleteRecursive(Node current, int value) {
|
||||
if (current == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (replacement != nodeToDelete.right) {
|
||||
parentReplacement.left = replacement.right;
|
||||
replacement.right = nodeToDelete.right;
|
||||
if (value == current.value) {
|
||||
// Case 1: no children
|
||||
if (current.left == null && current.right == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Case 2: only 1 child
|
||||
if (current.right == null) {
|
||||
return current.left;
|
||||
}
|
||||
|
||||
if (current.left == null) {
|
||||
return current.right;
|
||||
}
|
||||
|
||||
// Case 3: 2 children
|
||||
int smallestValue = findSmallestValue(current.right);
|
||||
current.value = smallestValue;
|
||||
current.right = deleteRecursive(current.right, smallestValue);
|
||||
return current;
|
||||
|
||||
} else if (value < current.value) {
|
||||
current.left = deleteRecursive(current.left, value);
|
||||
return current;
|
||||
} else {
|
||||
current.right = deleteRecursive(current.right, value);
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
private int findSmallestValue(Node root) {
|
||||
|
||||
if (root.left == null) {
|
||||
return root.value;
|
||||
}
|
||||
|
||||
replacement.left = nodeToDelete.left;
|
||||
|
||||
return replacement;
|
||||
return findSmallestValue(root.left);
|
||||
}
|
||||
|
||||
public void traverseInOrder(Node node) {
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.cipher;
|
||||
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class EncryptorUnitTest {
|
||||
private String encKeyString;
|
||||
private String message;
|
||||
private String certificateString;
|
||||
private Encryptor encryptor;
|
||||
|
||||
@Before
|
||||
public void init(){
|
||||
encKeyString = "1234567890123456";
|
||||
message = "This is a secret message";
|
||||
encryptor = new Encryptor();
|
||||
certificateString = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n" +
|
||||
"A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n" +
|
||||
"MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n" +
|
||||
"YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n" +
|
||||
"ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n" +
|
||||
"CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n" +
|
||||
"ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n" +
|
||||
"+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n" +
|
||||
"MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n" +
|
||||
"C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n" +
|
||||
"kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n" +
|
||||
"jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n" +
|
||||
"evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEncryptionKey_whenMessageIsPassedToEncryptor_thenMessageIsEncrypted() throws Exception {
|
||||
byte[] encryptedMessage = encryptor.encryptMessage(message.getBytes(),encKeyString.getBytes());
|
||||
|
||||
assertThat(encryptedMessage).isNotNull();
|
||||
assertThat(encryptedMessage.length % 32).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCertificateWithPublicKey_whenMessageIsPassedToEncryptor_thenMessageIsEncrypted() throws Exception {
|
||||
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
InputStream is = new ByteArrayInputStream(certificateString.getBytes());
|
||||
X509Certificate certificate = (X509Certificate) factory.generateCertificate(is);
|
||||
|
||||
byte[] encryptedMessage = encryptor.encryptMessage(message.getBytes(),certificate);
|
||||
|
||||
assertThat(encryptedMessage).isNotNull();
|
||||
assertThat(encryptedMessage.length % 128).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEncryptionKey_whenMessageIsEncrypted_thenDecryptMessage() throws Exception{
|
||||
byte[] encryptedMessageBytes = encryptor.encryptMessage(message.getBytes(),encKeyString.getBytes());
|
||||
|
||||
byte[] clearMessageBytes = encryptor.decryptMessage(encryptedMessageBytes, encKeyString.getBytes());
|
||||
|
||||
assertThat(message).isEqualTo(new String(clearMessageBytes));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.collection;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WhenComparingTreeMapVsHashMap {
|
||||
|
||||
@Test
|
||||
public void whenInsertObjectsTreeMap_thenNaturalOrder() {
|
||||
Map<Integer, String> treemap = new TreeMap<>();
|
||||
treemap.put(3, "TreeMap");
|
||||
treemap.put(2, "vs");
|
||||
treemap.put(1, "HashMap");
|
||||
Assert.assertThat(treemap.keySet(), Matchers.contains(1, 2, 3));
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void whenInsertNullInTreeMap_thenException() {
|
||||
Map<Integer, String> treemap = new TreeMap<>();
|
||||
treemap.put(null, "NullPointerException");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertObjectsHashMap_thenRandomOrder() {
|
||||
Map<Integer, String> hashmap = new HashMap<>();
|
||||
hashmap.put(3, "TreeMap");
|
||||
hashmap.put(2, "vs");
|
||||
hashmap.put(1, "HashMap");
|
||||
Assert.assertThat(hashmap.keySet(), Matchers.containsInAnyOrder(1, 2, 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInsertNullInHashMap_thenInsertsNull() {
|
||||
Map<Integer, String> hashmap = new HashMap<>();
|
||||
hashmap.put(null, null);
|
||||
Assert.assertNull(hashmap.get(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHashMapAndTreeMap_whenputDuplicates_thenOnlyUnique() {
|
||||
Map<Integer, String> treeMap = new HashMap<>();
|
||||
treeMap.put(1, "Baeldung");
|
||||
treeMap.put(1, "Baeldung");
|
||||
|
||||
Assert.assertTrue(treeMap.size() == 1);
|
||||
|
||||
Map<Integer, String> treeMap2 = new TreeMap<>();
|
||||
treeMap2.put(1, "Baeldung");
|
||||
treeMap2.put(1, "Baeldung");
|
||||
|
||||
Assert.assertTrue(treeMap2.size() == 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
package com.baeldung.collection;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class WhenUsingTreeSet {
|
||||
|
||||
private static class Element {
|
||||
private Integer id;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private Comparator<Element> comparator = (ele1, ele2) -> {
|
||||
return ele1.getId()
|
||||
.compareTo(ele2.getId());
|
||||
};
|
||||
|
||||
@Test
|
||||
public void whenAddingElement_shouldAddElement() {
|
||||
Set<String> treeSet = new TreeSet<>();
|
||||
Assert.assertTrue(treeSet.add("String Added"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingForElement_shouldSearchForElement() {
|
||||
Set<String> treeSetContains = new TreeSet<>();
|
||||
treeSetContains.add("String Added");
|
||||
Assert.assertTrue(treeSetContains.contains("String Added"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRemovingElement_shouldRemoveElement() {
|
||||
Set<String> removeFromTreeSet = new TreeSet<>();
|
||||
removeFromTreeSet.add("String Added");
|
||||
Assert.assertTrue(removeFromTreeSet.remove("String Added"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenClearingTreeSet_shouldClearTreeSet() {
|
||||
Set<String> clearTreeSet = new TreeSet<>();
|
||||
clearTreeSet.add("String Added");
|
||||
clearTreeSet.clear();
|
||||
Assert.assertTrue(clearTreeSet.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingTheSizeOfTreeSet_shouldReturnThesize() {
|
||||
Set<String> treeSetSize = new TreeSet<>();
|
||||
treeSetSize.add("String Added");
|
||||
Assert.assertEquals(1, treeSetSize.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingForEmptyTreeSet_shouldCheckForEmpty() {
|
||||
Set<String> emptyTreeSet = new TreeSet<>();
|
||||
Assert.assertTrue(emptyTreeSet.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenIteratingTreeSet_shouldIterateTreeSetInAscendingOrder() {
|
||||
Set<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add("Second");
|
||||
treeSet.add("Third");
|
||||
Iterator<String> itr = treeSet.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenIteratingTreeSet_shouldIterateTreeSetInDescendingOrder() {
|
||||
TreeSet<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add("Second");
|
||||
treeSet.add("Third");
|
||||
Iterator<String> itr = treeSet.descendingIterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = ConcurrentModificationException.class)
|
||||
public void whenModifyingTreeSetWhileIterating_shouldThrowException() {
|
||||
Set<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add("Second");
|
||||
treeSet.add("Third");
|
||||
Iterator<String> itr = treeSet.iterator();
|
||||
while (itr.hasNext()) {
|
||||
itr.next();
|
||||
treeSet.remove("Second");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRemovingElementUsingIterator_shouldRemoveElement() {
|
||||
Set<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add("Second");
|
||||
treeSet.add("Third");
|
||||
Iterator<String> itr = treeSet.iterator();
|
||||
while (itr.hasNext()) {
|
||||
String element = itr.next();
|
||||
if (element.equals("Second"))
|
||||
itr.remove();
|
||||
}
|
||||
Assert.assertEquals(2, treeSet.size());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void whenAddingNullToNonEmptyTreeSet_shouldThrowException() {
|
||||
Set<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingFirstElement_shouldReturnFirstElement() {
|
||||
TreeSet<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
Assert.assertEquals("First", treeSet.first());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCheckingLastElement_shouldReturnLastElement() {
|
||||
TreeSet<String> treeSet = new TreeSet<>();
|
||||
treeSet.add("First");
|
||||
treeSet.add("Last");
|
||||
Assert.assertEquals("Last", treeSet.last());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingComparator_shouldSortAndInsertElements() {
|
||||
Set<Element> treeSet = new TreeSet<>(comparator);
|
||||
Element ele1 = new Element();
|
||||
ele1.setId(100);
|
||||
Element ele2 = new Element();
|
||||
ele2.setId(200);
|
||||
|
||||
treeSet.add(ele1);
|
||||
treeSet.add(ele2);
|
||||
|
||||
System.out.println(treeSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingHeadSet_shouldReturnElementsLessThanSpecifiedElement() {
|
||||
Set<Element> treeSet = new TreeSet<>(comparator);
|
||||
Element ele1 = new Element();
|
||||
ele1.setId(100);
|
||||
Element ele2 = new Element();
|
||||
ele2.setId(200);
|
||||
|
||||
treeSet.add(ele1);
|
||||
treeSet.add(ele2);
|
||||
|
||||
System.out.println(treeSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingSubSet_shouldReturnSubSetElements() {
|
||||
SortedSet<Integer> treeSet = new TreeSet<>();
|
||||
treeSet.add(1);
|
||||
treeSet.add(2);
|
||||
treeSet.add(3);
|
||||
treeSet.add(4);
|
||||
treeSet.add(5);
|
||||
treeSet.add(6);
|
||||
|
||||
Set<Integer> expectedSet = new TreeSet<>();
|
||||
expectedSet.add(2);
|
||||
expectedSet.add(3);
|
||||
expectedSet.add(4);
|
||||
expectedSet.add(5);
|
||||
|
||||
Set<Integer> subSet = treeSet.subSet(2, 6);
|
||||
Assert.assertEquals(expectedSet, subSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingHeadSet_shouldReturnHeadSetElements() {
|
||||
SortedSet<Integer> treeSet = new TreeSet<>();
|
||||
treeSet.add(1);
|
||||
treeSet.add(2);
|
||||
treeSet.add(3);
|
||||
treeSet.add(4);
|
||||
treeSet.add(5);
|
||||
treeSet.add(6);
|
||||
|
||||
Set<Integer> subSet = treeSet.headSet(6);
|
||||
Assert.assertEquals(subSet, treeSet.subSet(1, 6));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingTailSet_shouldReturnTailSetElements() {
|
||||
NavigableSet<Integer> treeSet = new TreeSet<>();
|
||||
treeSet.add(1);
|
||||
treeSet.add(2);
|
||||
treeSet.add(3);
|
||||
treeSet.add(4);
|
||||
treeSet.add(5);
|
||||
treeSet.add(6);
|
||||
|
||||
Set<Integer> subSet = treeSet.tailSet(3);
|
||||
Assert.assertEquals(subSet, treeSet.subSet(3, true, 6, true));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.initializationguide;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class UserTest {
|
||||
|
||||
@Test
|
||||
public void givenUserInstance_whenIntializedWithNew_thenInstanceIsNotNull() {
|
||||
User user = new User("Alice", 1);
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserInstance_whenInitializedWithReflection_thenInstanceIsNotNull() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
|
||||
User user = User.class.getConstructor(String.class, int.class)
|
||||
.newInstance("Alice", 2);
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserInstance_whenCopiedWithClone_thenExactMatchIsCreated() throws CloneNotSupportedException {
|
||||
User user = new User("Alice", 3);
|
||||
User clonedUser = (User) user.clone();
|
||||
assertThat(clonedUser).isEqualTo(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserInstance_whenValuesAreNotInitialized_thenUserNameAndIdReturnDefault() {
|
||||
User user = new User();
|
||||
assertThat(user.getName()).isNull();
|
||||
assertThat(user.getId() == 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.baeldung.jdbc;
|
||||
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.Statement;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BatchProcessingTest {
|
||||
|
||||
|
||||
@InjectMocks
|
||||
private BatchProcessing target = new BatchProcessing();
|
||||
|
||||
@Mock
|
||||
private Connection connection;
|
||||
|
||||
@Mock
|
||||
private Statement statement;
|
||||
|
||||
@Mock
|
||||
private PreparedStatement employeeStatement;
|
||||
|
||||
@Mock
|
||||
private PreparedStatement employeeAddressStatement;
|
||||
|
||||
@Before
|
||||
public void before(){
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void when_useStatement_thenInsertData_success() throws Exception {
|
||||
Mockito.when(connection.createStatement()).thenReturn(statement);
|
||||
target.useStatement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_useStatement_ifThrowException_thenCatchException() throws Exception {
|
||||
Mockito.when(connection.createStatement()).thenThrow(new RuntimeException());
|
||||
target.useStatement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_usePreparedStatement_thenInsertData_success() throws Exception {
|
||||
String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) VALUES (?,?,?);";
|
||||
String insertEmployeeAddrSQL = "INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) VALUES (?,?,?);";
|
||||
Mockito.when(connection.prepareStatement(insertEmployeeSQL)).thenReturn(employeeStatement);
|
||||
Mockito.when(connection.prepareStatement(insertEmployeeAddrSQL)).thenReturn(employeeAddressStatement);
|
||||
target.usePreparedStatement();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_usePreparedStatement_ifThrowException_thenCatchException() throws Exception {
|
||||
String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) VALUES (?,?,?);";
|
||||
String insertEmployeeAddrSQL = "INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) VALUES (?,?,?);";
|
||||
Mockito.when(connection.prepareStatement(insertEmployeeSQL)).thenReturn(employeeStatement);
|
||||
Mockito.when(connection.prepareStatement(insertEmployeeAddrSQL)).thenThrow(new RuntimeException());
|
||||
target.usePreparedStatement();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.stream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class FileCopyTest {
|
||||
|
||||
@Test
|
||||
public void whenUsingStream_thenCopyFile() throws IOException {
|
||||
File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_stream.txt");
|
||||
File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_stream.txt");
|
||||
FileCopy.copyFileUsingStream(src, dest);
|
||||
assertTrue(dest.exists());
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingFiles_thenCopyFile() throws IOException {
|
||||
File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_files.txt");
|
||||
File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_files.txt");
|
||||
FileCopy.copyFileUsingJavaFiles(src, dest);
|
||||
assertTrue(dest.exists());
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingChannel_thenCopyFile() throws IOException {
|
||||
File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_channel.txt");
|
||||
File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_channel.txt");
|
||||
FileCopy.copyFileUsingChannel(src, dest);
|
||||
assertTrue(dest.exists());
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingApache_thenCopyFile() throws IOException {
|
||||
File src = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "src" + File.separator + "test_apache.txt");
|
||||
File dest = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + "copyTest" + File.separator + "dest" + File.separator + "test_apache.txt");
|
||||
FileCopy.copyFileUsingApacheCommonsIO(src, dest);
|
||||
assertTrue(dest.exists());
|
||||
dest.delete();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
files will be copied here and then deleted
|
||||
remove `file.delete()` to see the files here
|
|
@ -0,0 +1 @@
|
|||
apache
|
|
@ -0,0 +1 @@
|
|||
channel
|
|
@ -0,0 +1 @@
|
|||
files
|
|
@ -0,0 +1 @@
|
|||
stream
|
|
@ -1 +0,0 @@
|
|||
## Relevant articles:
|
|
@ -0,0 +1,24 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
|
@ -0,0 +1,58 @@
|
|||
<?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>flyway-callbacks</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>flyway-callbacks</name>
|
||||
<description>Flyway Callbacks Demo</description>
|
||||
|
||||
<parent>
|
||||
<artifactId>parent-boot-5</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-5</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>5.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,33 @@
|
|||
package com.baeldung.flywaycallbacks;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.flywaydb.core.api.MigrationInfo;
|
||||
import org.flywaydb.core.api.callback.BaseFlywayCallback;
|
||||
|
||||
public class ExampleFlywayCallback extends BaseFlywayCallback {
|
||||
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Override
|
||||
public void afterEachMigrate(Connection connection, MigrationInfo info) {
|
||||
log.info("> afterEachMigrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterMigrate(Connection connection) {
|
||||
log.info("> afterMigrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEachMigrate(Connection connection, MigrationInfo info) {
|
||||
log.info("> beforeEachMigrate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeMigrate(Connection connection) {
|
||||
log.info("> beforeMigrate");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.flywaycallbacks;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class FlywayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FlywayApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SELECT 1
|
|
@ -0,0 +1 @@
|
|||
SELECT 1
|
|
@ -0,0 +1,5 @@
|
|||
create table table_one (
|
||||
id numeric,
|
||||
name varchar(50),
|
||||
constraint pk_table_one primary key (id)
|
||||
);
|
|
@ -0,0 +1,5 @@
|
|||
create table table_two (
|
||||
id numeric,
|
||||
name varchar(50),
|
||||
constraint pk_table_two primary key (id)
|
||||
);
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level %logger{36} - %message%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.flywaycallbacks;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
@ContextConfiguration(classes = FlywayCallbackTestConfig.class)
|
||||
public class FlywayApplicationTest {
|
||||
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Test
|
||||
public void migrateWithNoCallbacks() {
|
||||
logTestBoundary("migrateWithNoCallbacks");
|
||||
Flyway flyway = new Flyway();
|
||||
flyway.setDataSource(dataSource);
|
||||
flyway.setLocations("db/migration");
|
||||
flyway.migrate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateWithJavaCallbacks() {
|
||||
logTestBoundary("migrateWithJavaCallbacks");
|
||||
Flyway flyway = new Flyway();
|
||||
flyway.setDataSource(dataSource);
|
||||
flyway.setLocations("db/migration");
|
||||
flyway.setCallbacks(new ExampleFlywayCallback());
|
||||
flyway.migrate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateWithSqlCallbacks() {
|
||||
logTestBoundary("migrateWithSqlCallbacks");
|
||||
Flyway flyway = new Flyway();
|
||||
flyway.setDataSource(dataSource);
|
||||
flyway.setLocations("db/migration", "db/callbacks");
|
||||
flyway.migrate();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void migrateWithSqlAndJavaCallbacks() {
|
||||
logTestBoundary("migrateWithSqlAndJavaCallbacks");
|
||||
Flyway flyway = new Flyway();
|
||||
flyway.setDataSource(dataSource);
|
||||
flyway.setLocations("db/migration", "db/callbacks");
|
||||
flyway.setCallbacks(new ExampleFlywayCallback());
|
||||
flyway.migrate();
|
||||
}
|
||||
|
||||
private void logTestBoundary(String testName) {
|
||||
System.out.println("\n");
|
||||
log.info("> " + testName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.flywaycallbacks;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
@Configuration
|
||||
public class FlywayCallbackTestConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource createDatasource() {
|
||||
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
|
||||
return dbBuilder.setType(EmbeddedDatabaseType.H2)
|
||||
.setName("DATABASE")
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@
|
|||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.194</version>
|
||||
<version>1.4.196</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package com.baeldung.hibernate;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
|
||||
import com.baeldung.hibernate.pojo.Supplier;
|
||||
|
||||
/**
|
||||
* Hello world!
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// NOTE: this is just for boostrap testing for multitenancy.
|
||||
System.out.println("Checking the system.");
|
||||
SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
|
||||
Session currentSession = sessionFactory.withOptions().tenantIdentifier("h2db1").openSession();
|
||||
Transaction transaction = currentSession.getTransaction();
|
||||
transaction.begin();
|
||||
currentSession.createCriteria(Supplier.class).list().stream().forEach(System.out::println);
|
||||
transaction.commit();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package com.baeldung.hibernate;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
|
||||
public class ConfigurableMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||
|
||||
private final Map<String, ConnectionProvider> connectionProviderMap =
|
||||
new HashMap<>();
|
||||
|
||||
|
||||
public ConfigurableMultiTenantConnectionProvider(
|
||||
Map<String, ConnectionProvider> connectionProviderMap) {
|
||||
this.connectionProviderMap.putAll( connectionProviderMap );
|
||||
}
|
||||
@Override
|
||||
protected ConnectionProvider getAnyConnectionProvider() {
|
||||
System.out.println("Any");
|
||||
return connectionProviderMap.values().iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||
System.out.println("Specific");
|
||||
return connectionProviderMap.get( tenantIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String tenantIdentifier) throws SQLException {
|
||||
Connection connection = super.getConnection(tenantIdentifier);
|
||||
// uncomment to see option 2 for SCHEMA strategy.
|
||||
//connection.createStatement().execute("SET SCHEMA '" + tenantIdentifier + "'");
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
package com.baeldung.hibernate;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
|
||||
import com.baeldung.hibernate.pojo.Supplier;
|
||||
|
||||
public class HibernateMultiTenantUtil {
|
||||
private static SessionFactory sessionFactory;
|
||||
private static Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
|
||||
private static final String[] tenantDBNames = { "mydb1", "mydb2" };
|
||||
|
||||
public static SessionFactory getSessionFactory() throws UnsupportedTenancyException, IOException {
|
||||
if (sessionFactory == null) {
|
||||
// Configuration configuration = new Configuration().configure();
|
||||
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||
sessionFactory = makeSessionFactory(serviceRegistry);
|
||||
|
||||
}
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
|
||||
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||
for (Class annotatedClasses : getAnnotatedClasses()) {
|
||||
metadataSources.addAnnotatedClass(annotatedClasses);
|
||||
}
|
||||
|
||||
Metadata metadata = metadataSources.buildMetadata();
|
||||
return metadata.getSessionFactoryBuilder()
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
private static Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Supplier.class };
|
||||
}
|
||||
|
||||
private static ServiceRegistry configureServiceRegistry() throws UnsupportedTenancyException, IOException {
|
||||
|
||||
// Properties properties = configuration.getProperties();
|
||||
Properties properties = getProperties();
|
||||
|
||||
connectionProviderMap = setUpConnectionProviders(properties, tenantDBNames);
|
||||
properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, new ConfigurableMultiTenantConnectionProvider(connectionProviderMap));
|
||||
|
||||
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Properties getProperties() throws IOException {
|
||||
Properties properties = new Properties();
|
||||
URL propertiesURL = Thread.currentThread()
|
||||
.getContextClassLoader()
|
||||
.getResource("hibernate-multitenancy.properties");
|
||||
FileInputStream inputStream = new FileInputStream(propertiesURL.getFile());
|
||||
properties.load(inputStream);
|
||||
System.out.println("LOADED PROPERTIES FROM hibernate.properties");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static Map<String, ConnectionProvider> setUpConnectionProviders(Properties properties, String[] tenantNames) throws UnsupportedTenancyException {
|
||||
Map<String, ConnectionProvider> providerMap = new HashMap<>();
|
||||
for (String tenant : tenantNames) {
|
||||
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||
|
||||
String tenantStrategy = properties.getProperty("hibernate.multiTenancy");
|
||||
System.out.println("Strategy:" + tenantStrategy);
|
||||
properties.put(Environment.URL, tenantUrl(properties.getProperty(Environment.URL), tenant, tenantStrategy));
|
||||
System.out.println("URL:" + properties.getProperty(Environment.URL));
|
||||
connectionProvider.configure(properties);
|
||||
System.out.println("Tenant:" + tenant);
|
||||
providerMap.put(tenant, connectionProvider);
|
||||
|
||||
}
|
||||
System.out.println("Added connections for:");
|
||||
providerMap.keySet()
|
||||
.stream()
|
||||
.forEach(System.out::println);
|
||||
return providerMap;
|
||||
}
|
||||
|
||||
private static Object tenantUrl(String originalUrl, String tenant, String tenantStrategy) throws UnsupportedTenancyException {
|
||||
if (tenantStrategy.toUpperCase()
|
||||
.equals("DATABASE")) {
|
||||
return originalUrl.replace(DEFAULT_DB_NAME, tenant);
|
||||
} else if (tenantStrategy.toUpperCase()
|
||||
.equals("SCHEMA")) {
|
||||
return originalUrl + String.format(SCHEMA_TOKEN, tenant);
|
||||
} else {
|
||||
throw new UnsupportedTenancyException("Not yet supported");
|
||||
}
|
||||
}
|
||||
|
||||
public static final String SCHEMA_TOKEN = ";INIT=CREATE SCHEMA IF NOT EXISTS %1$s\\;SET SCHEMA %1$s";
|
||||
public static final String DEFAULT_DB_NAME = "mydb1";
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package com.baeldung.hibernate.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface GenericDao<T> {
|
||||
|
||||
void save (T entity);
|
||||
void delete (T Entity);
|
||||
T findByName(String name);
|
||||
List<T> findAll();
|
||||
void populate();
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
package com.baeldung.hibernate.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.criterion.Expression;
|
||||
|
||||
import com.baeldung.hibernate.pojo.Supplier;
|
||||
|
||||
public class SupplierDao implements GenericDao<Supplier>{
|
||||
private SessionFactory sessionFactory;
|
||||
private String tenant;
|
||||
|
||||
public SupplierDao(SessionFactory sessionFactory, String tenant) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
this.tenant = tenant;
|
||||
populate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Supplier entity) {
|
||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
||||
session.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Supplier supplier) {
|
||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
||||
session.delete(supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier findByName(String name) {
|
||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
||||
List<Supplier> fetchedSuppliers = session.createCriteria(Supplier.class).add(Expression.eq("name", name)).list();
|
||||
if (fetchedSuppliers.size()>0) {
|
||||
return fetchedSuppliers.get(0);
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Supplier> findAll() {
|
||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
||||
return session.createCriteria(Supplier.class).list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate() {
|
||||
System.out.println("Init DB1");
|
||||
Session session = sessionFactory.withOptions().tenantIdentifier(tenant).openSession();
|
||||
Transaction transaction = session.getTransaction();
|
||||
|
||||
transaction.begin();
|
||||
session.createSQLQuery("DROP ALL OBJECTS").executeUpdate();
|
||||
session
|
||||
.createSQLQuery(
|
||||
"create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))")
|
||||
.executeUpdate();
|
||||
Supplier genertedSupplier = generateEntityForTenant(tenant);
|
||||
System.out.println("Inserting Supplier"+genertedSupplier);
|
||||
save (genertedSupplier);
|
||||
|
||||
}
|
||||
|
||||
private Supplier generateEntityForTenant(String forTenant) {
|
||||
if (forTenant.equals("mydb1")) {
|
||||
return new Supplier ("John","USA");
|
||||
}
|
||||
return new Supplier ("Miller","UK");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package com.baeldung.hibernate.pojo;
|
||||
// Generated Feb 9, 2017 11:31:36 AM by Hibernate Tools 5.1.0.Final
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
|
||||
/**
|
||||
* Suppliers generated by hbm2java
|
||||
*/
|
||||
@Entity(name = "Supplier")
|
||||
@Table(name ="Supplier")
|
||||
public class Supplier implements java.io.Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String country;
|
||||
|
||||
public Supplier() {
|
||||
}
|
||||
|
||||
public Supplier(String name, String country) {
|
||||
this.name = name;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuffer().append("[").append(id).append(",").append(name).append(",").append(country).append("]").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return name.equals(((Supplier) obj).getName());
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package com.baeldung.hibernate;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.hibernate.dao.SupplierDao;
|
||||
import com.baeldung.hibernate.pojo.Supplier;
|
||||
|
||||
import static org.junit.Assert.assertNull;;
|
||||
|
||||
public class MultiTenantDaoHibernateIntegrationTest {
|
||||
@Test
|
||||
public void givenDBMode_whenFetchingSuppliersByName_thenChecking() throws UnsupportedTenancyException, IOException {
|
||||
SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory();
|
||||
|
||||
SupplierDao myDb1Dao = new SupplierDao(sessionFactory, "mydb1");
|
||||
Supplier db1SupplierName = myDb1Dao.findByName("John");
|
||||
|
||||
// finding the same supplier name in another tenant
|
||||
// and we should not be able to find in there and both dbs are different.
|
||||
SupplierDao myDb2Dao = new SupplierDao(sessionFactory, "mydb2");
|
||||
Supplier db2SupplierName = myDb2Dao.findByName(db1SupplierName.getName());
|
||||
|
||||
assertNull(db2SupplierName);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.hibernate.multitenancy;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity(name = "Car")
|
||||
@Table(name = "Car")
|
||||
public class Car implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1015320564683423342L;
|
||||
|
||||
private String brand;
|
||||
|
||||
@Id
|
||||
public String getBrand() {
|
||||
return brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) {
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.baeldung.hibernate.multitenancy;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||
|
||||
public abstract class MultitenancyIntegrationTest {
|
||||
|
||||
public abstract String getPropertyFile();
|
||||
|
||||
@Mock
|
||||
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Before
|
||||
public void setup() throws IOException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
Mockito.when(currentTenantIdentifierResolver.validateExistingCurrentSessions())
|
||||
.thenReturn(false);
|
||||
|
||||
Properties properties = getHibernateProperties();
|
||||
properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
|
||||
|
||||
sessionFactory = buildSessionFactory(properties);
|
||||
|
||||
initTenant(TenantIdNames.MYDB1);
|
||||
initTenant(TenantIdNames.MYDB2);
|
||||
}
|
||||
|
||||
protected void initTenant(String tenantId) {
|
||||
whenCurrentTenantIs(tenantId);
|
||||
createCarTable();
|
||||
}
|
||||
|
||||
protected void whenCurrentTenantIs(String tenantId) {
|
||||
Mockito.when(currentTenantIdentifierResolver.resolveCurrentTenantIdentifier())
|
||||
.thenReturn(tenantId);
|
||||
}
|
||||
|
||||
protected void whenAddCar(String brand) {
|
||||
Session session = sessionFactory.openSession();
|
||||
Transaction tx = session.beginTransaction();
|
||||
Car car = new Car();
|
||||
car.setBrand(brand);
|
||||
session.save(car);
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
protected void thenCarFound(String brand) {
|
||||
Session session = sessionFactory.openSession();
|
||||
assertNotNull(session.get(Car.class, brand));
|
||||
}
|
||||
|
||||
protected void thenCarNotFound(String brand) {
|
||||
Session session = sessionFactory.openSession();
|
||||
assertNull(session.get(Car.class, brand));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void createCarTable() {
|
||||
Session session = sessionFactory.openSession();
|
||||
Transaction tx = session.beginTransaction();
|
||||
session.createSQLQuery("drop table Car if exists")
|
||||
.executeUpdate();
|
||||
session.createSQLQuery("create table Car (brand varchar(255) primary key)")
|
||||
.executeUpdate();
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
private Properties getHibernateProperties() throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(getClass().getResourceAsStream(getPropertyFile()));
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static SessionFactory buildSessionFactory(Properties properties) {
|
||||
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(properties)
|
||||
.build();
|
||||
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||
metadataSources.addAnnotatedClass(Car.class);
|
||||
return metadataSources.buildMetadata()
|
||||
.buildSessionFactory();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.hibernate.multitenancy.database;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||
|
||||
public class DatabaseApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||
|
||||
@Override
|
||||
public String getPropertyFile() {
|
||||
return "/hibernate-database-multitenancy.properties";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDatabaseApproach_whenAddingEntries_thenOnlyAddedToConcreteDatabase() throws IOException {
|
||||
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||
whenAddCar("myCar");
|
||||
thenCarFound("myCar");
|
||||
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||
thenCarNotFound("myCar");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.hibernate.multitenancy.database;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MapMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||
|
||||
private final Map<String, ConnectionProvider> connectionProviderMap = new HashMap<>();
|
||||
|
||||
public MapMultiTenantConnectionProvider() throws IOException {
|
||||
initConnectionProviderForTenant(TenantIdNames.MYDB1);
|
||||
initConnectionProviderForTenant(TenantIdNames.MYDB2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider getAnyConnectionProvider() {
|
||||
return connectionProviderMap.values()
|
||||
.iterator()
|
||||
.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||
return connectionProviderMap.get(tenantIdentifier);
|
||||
}
|
||||
|
||||
private void initConnectionProviderForTenant(String tenantId) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(getClass().getResourceAsStream(String.format("/hibernate-database-%s.properties", tenantId)));
|
||||
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||
connectionProvider.configure(properties);
|
||||
this.connectionProviderMap.put(tenantId, connectionProvider);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.baeldung.hibernate.multitenancy.database;
|
||||
|
||||
public class TenantIdNames {
|
||||
public static final String MYDB1 = "mydb1";
|
||||
public static final String MYDB2 = "mydb2";
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.hibernate.multitenancy.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.hibernate.multitenancy.MultitenancyIntegrationTest;
|
||||
import com.baeldung.hibernate.multitenancy.database.TenantIdNames;
|
||||
|
||||
public class SchemaApproachMultitenancyIntegrationTest extends MultitenancyIntegrationTest {
|
||||
|
||||
@Override
|
||||
public String getPropertyFile() {
|
||||
return "/hibernate-schema-multitenancy.properties";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSchemaApproach_whenAddingEntries_thenOnlyAddedToConcreteSchema() throws IOException {
|
||||
whenCurrentTenantIs(TenantIdNames.MYDB1);
|
||||
whenAddCar("Ferrari");
|
||||
thenCarFound("Ferrari");
|
||||
whenCurrentTenantIs(TenantIdNames.MYDB2);
|
||||
thenCarNotFound("Ferrari");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.hibernate.multitenancy.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
|
||||
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.junit.Assert;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class SchemaMultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
|
||||
|
||||
private final ConnectionProvider connectionProvider = initConnectionProvider();
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider getAnyConnectionProvider() {
|
||||
return connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
|
||||
return connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String tenantIdentifier) throws SQLException {
|
||||
Connection connection = super.getConnection(tenantIdentifier);
|
||||
connection.createStatement()
|
||||
.execute(String.format("SET SCHEMA %s;", tenantIdentifier));
|
||||
return connection;
|
||||
}
|
||||
|
||||
private ConnectionProvider initConnectionProvider() {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(getClass().getResourceAsStream("/hibernate-schema-multitenancy.properties"));
|
||||
} catch (IOException e) {
|
||||
Assert.fail("Error loading resource. Cause: " + e.getMessage());
|
||||
}
|
||||
|
||||
DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||
connectionProvider.configure(properties);
|
||||
return connectionProvider;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.baeldung.hibernate.multitenancy.schema;
|
||||
|
||||
public class TenantIdNames {
|
||||
public static final String MYDB1 = "mydb1";
|
||||
public static final String MYDB2 = "mydb2";
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
hibernate.multiTenancy=DATABASE
|
||||
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.database.MapMultiTenantConnectionProvider
|
|
@ -0,0 +1,4 @@
|
|||
hibernate.connection.driver_class=org.h2.Driver
|
||||
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||
hibernate.connection.username=sa
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
@ -0,0 +1,4 @@
|
|||
hibernate.connection.driver_class=org.h2.Driver
|
||||
hibernate.connection.url=jdbc:h2:mem:mydb2;DB_CLOSE_DELAY=-1
|
||||
hibernate.connection.username=sa
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
@ -1,9 +0,0 @@
|
|||
hibernate.connection.driver_class=org.h2.Driver
|
||||
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
|
||||
hibernate.connection.username=sa
|
||||
hibernate.connection.autocommit=true
|
||||
jdbc.password=
|
||||
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
hibernate.show_sql=true
|
||||
hibernate.multiTenancy=DATABASE
|
|
@ -0,0 +1,7 @@
|
|||
hibernate.connection.driver_class=org.h2.Driver
|
||||
hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS MYDB1\\;CREATE SCHEMA IF NOT EXISTS MYDB2\\;
|
||||
hibernate.connection.username=sa
|
||||
hibernate.connection.autocommit=true
|
||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
hibernate.multiTenancy=SCHEMA
|
||||
hibernate.multi_tenant_connection_provider=com.baeldung.hibernate.multitenancy.schema.SchemaMultiTenantConnectionProvider
|
|
@ -0,0 +1,17 @@
|
|||
## Influx SDK Tutorial Project
|
||||
|
||||
### Relevant Article:
|
||||
- [Introduction to using InfluxDB with Java](http://www.baeldung.com/using-influxdb-with-java/)
|
||||
|
||||
### Overview
|
||||
This Maven project contains the Java code for the article linked above.
|
||||
|
||||
### Package Organization
|
||||
Java classes for the intro tutorial are in the
|
||||
org.baeldung.influxdb package.
|
||||
|
||||
|
||||
### Running the tests
|
||||
The test class expects an InfluxDB server to be available on localhost, at the default port of 8086 and with the default "admin" credentials.
|
||||
|
||||
```
|
|
@ -0,0 +1,44 @@
|
|||
<?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>influxdb</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>influxdb</name>
|
||||
<description>InfluxDB SDK Tutorial</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.influxdb</groupId>
|
||||
<artifactId>influxdb-java</artifactId>
|
||||
<version>${influxdb.sdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<!-- Check for the most recent available version: https://projectlombok.org/changelog.html -->
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<influxdb.sdk.version>2.8</influxdb.sdk.version>
|
||||
<lombok.version>1.16.18</lombok.version>
|
||||
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.influxdb;
|
||||
|
||||
import lombok.Data;
|
||||
import org.influxdb.annotation.Column;
|
||||
import org.influxdb.annotation.Measurement;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Data
|
||||
@Measurement(name = "memory")
|
||||
public class MemoryPoint {
|
||||
|
||||
@Column(name = "time")
|
||||
private Instant time;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "free")
|
||||
private Long free;
|
||||
|
||||
@Column(name = "used")
|
||||
private Long used;
|
||||
|
||||
@Column(name = "buffer")
|
||||
private Long buffer;
|
||||
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package com.baeldung.influxdb;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.influxdb.InfluxDB;
|
||||
import org.influxdb.InfluxDBFactory;
|
||||
import org.influxdb.InfluxDBIOException;
|
||||
import org.influxdb.dto.*;
|
||||
import org.influxdb.impl.InfluxDBResultMapper;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@Slf4j
|
||||
public class InfluxDBConnectionLiveTest {
|
||||
|
||||
@Test
|
||||
public void whenCorrectInfoDatabaseConnects() {
|
||||
|
||||
InfluxDB connection = connectDatabase();
|
||||
assertTrue(pingServer(connection));
|
||||
}
|
||||
|
||||
private InfluxDB connectDatabase() {
|
||||
|
||||
// Connect to database assumed on localhost with default credentials.
|
||||
return InfluxDBFactory.connect("http://127.0.0.1:8086", "admin", "admin");
|
||||
|
||||
}
|
||||
|
||||
private boolean pingServer(InfluxDB influxDB) {
|
||||
try {
|
||||
// Ping and check for version string
|
||||
Pong response = influxDB.ping();
|
||||
if (response.getVersion().equalsIgnoreCase("unknown")) {
|
||||
log.error("Error pinging server.");
|
||||
return false;
|
||||
} else {
|
||||
log.info("Database version: {}", response.getVersion());
|
||||
return true;
|
||||
}
|
||||
} catch (InfluxDBIOException idbo) {
|
||||
log.error("Exception while pinging database: ", idbo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDatabaseCreatedDatabaseChecksOk() {
|
||||
|
||||
InfluxDB connection = connectDatabase();
|
||||
|
||||
// Create "baeldung and check for it
|
||||
connection.createDatabase("baeldung");
|
||||
assertTrue(connection.databaseExists("baeldung"));
|
||||
|
||||
// Verify that nonsense databases are not there
|
||||
assertFalse(connection.databaseExists("foobar"));
|
||||
|
||||
// Drop "baeldung" and check again
|
||||
connection.deleteDatabase("baeldung");
|
||||
assertFalse(connection.databaseExists("baeldung"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPointsWrittenPointsExists() throws Exception {
|
||||
|
||||
InfluxDB connection = connectDatabase();
|
||||
|
||||
String dbName = "baeldung";
|
||||
connection.createDatabase(dbName);
|
||||
|
||||
// Need a retention policy before we can proceed
|
||||
connection.createRetentionPolicy("defaultPolicy", "baeldung", "30d", 1, true);
|
||||
|
||||
// Since we are doing a batch thread, we need to set this as a default
|
||||
connection.setRetentionPolicy("defaultPolicy");
|
||||
|
||||
// Enable batch mode
|
||||
connection.enableBatch(10, 10, TimeUnit.MILLISECONDS);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Point point = Point.measurement("memory")
|
||||
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
|
||||
.addField("name", "server1")
|
||||
.addField("free", 4743656L)
|
||||
.addField("used", 1015096L)
|
||||
.addField("buffer", 1010467L)
|
||||
.build();
|
||||
|
||||
connection.write(dbName, "defaultPolicy", point);
|
||||
Thread.sleep(2);
|
||||
|
||||
}
|
||||
|
||||
// Unfortunately, the sleep inside the loop doesn't always add enough time to insure
|
||||
// that Influx's batch thread flushes all of the writes and this sometimes fails without
|
||||
// another brief pause.
|
||||
Thread.sleep(10);
|
||||
|
||||
List<MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung");
|
||||
|
||||
assertEquals(10, memoryPointList.size());
|
||||
|
||||
// Turn off batch and clean up
|
||||
connection.disableBatch();
|
||||
connection.deleteDatabase("baeldung");
|
||||
connection.close();
|
||||
|
||||
}
|
||||
|
||||
private List<MemoryPoint> getPoints(InfluxDB connection, String query, String databaseName) {
|
||||
|
||||
// Run the query
|
||||
Query queryObject = new Query(query, databaseName);
|
||||
QueryResult queryResult = connection.query(queryObject);
|
||||
|
||||
// Map it
|
||||
InfluxDBResultMapper resultMapper = new InfluxDBResultMapper();
|
||||
return resultMapper.toPOJO(queryResult, MemoryPoint.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void whenBatchWrittenBatchExists() {
|
||||
|
||||
InfluxDB connection = connectDatabase();
|
||||
|
||||
String dbName = "baeldung";
|
||||
connection.createDatabase(dbName);
|
||||
|
||||
// Need a retention policy before we can proceed
|
||||
// Since we are doing batches, we need not set it
|
||||
connection.createRetentionPolicy("defaultPolicy", "baeldung", "30d", 1, true);
|
||||
|
||||
|
||||
BatchPoints batchPoints = BatchPoints
|
||||
.database(dbName)
|
||||
.retentionPolicy("defaultPolicy")
|
||||
.build();
|
||||
Point point1 = Point.measurement("memory")
|
||||
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
|
||||
.addField("free", 4743656L)
|
||||
.addField("used", 1015096L)
|
||||
.addField("buffer", 1010467L)
|
||||
.build();
|
||||
Point point2 = Point.measurement("memory")
|
||||
.time(System.currentTimeMillis() - 100, TimeUnit.MILLISECONDS)
|
||||
.addField("free", 4743696L)
|
||||
.addField("used", 1016096L)
|
||||
.addField("buffer", 1008467L)
|
||||
.build();
|
||||
batchPoints.point(point1);
|
||||
batchPoints.point(point2);
|
||||
connection.write(batchPoints);
|
||||
|
||||
List<MemoryPoint> memoryPointList = getPoints(connection, "Select * from memory", "baeldung");
|
||||
|
||||
assertEquals(2, memoryPointList.size());
|
||||
assertTrue(4743696L == memoryPointList.get(0).getFree());
|
||||
|
||||
|
||||
memoryPointList = getPoints(connection, "Select * from memory order by time desc", "baeldung");
|
||||
|
||||
assertEquals(2, memoryPointList.size());
|
||||
assertTrue(4743656L == memoryPointList.get(0).getFree());
|
||||
|
||||
// Clean up database
|
||||
connection.deleteDatabase("baeldung");
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -30,7 +30,7 @@
|
|||
- [Introduction to Neuroph](http://www.baeldung.com/neuroph)
|
||||
- [Guide to Apache Commons CircularFifoQueue](http://www.baeldung.com/commons-circular-fifo-queue)
|
||||
- [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss)
|
||||
- [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception)
|
||||
- [Introduction to NoException](http://www.baeldung.com/introduction-to-noexception)
|
||||
- [Introduction to PCollections](http://www.baeldung.com/java-pcollections)
|
||||
- [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly)
|
||||
- [Apache Commons Chain](http://www.baeldung.com/apache-commons-chain)
|
||||
|
|
|
@ -612,16 +612,16 @@
|
|||
<artifactId>caffeine</artifactId>
|
||||
<version>${caffeine.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.58</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.58</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
<version>1.58</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.58</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client</artifactId>
|
||||
|
@ -654,6 +654,29 @@
|
|||
<artifactId>google-api-services-sheets</artifactId>
|
||||
<version>${google-sheets.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-streams</artifactId>
|
||||
<version>${kafka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>${kafka.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.kafka</groupId>
|
||||
<artifactId>kafka-clients</artifactId>
|
||||
<version>${kafka.version}</version>
|
||||
<classifier>test</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
@ -669,6 +692,10 @@
|
|||
<name>bintray</name>
|
||||
<url>http://dl.bintray.com/cuba-platform/main</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>Apache Staging</id>
|
||||
<url>https://repository.apache.org/content/groups/staging</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<googleclient.version>1.23.0</googleclient.version>
|
||||
|
@ -729,5 +756,6 @@
|
|||
<caffeine.version>2.5.5</caffeine.version>
|
||||
<google-api.version>1.23.0</google-api.version>
|
||||
<google-sheets.version>v4-rev493-1.21.0</google-sheets.version>
|
||||
<kafka.version>1.0.0</kafka.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,62 @@
|
|||
package com.baeldung.kafkastreams;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.common.serialization.Serde;
|
||||
import org.apache.kafka.common.serialization.Serdes;
|
||||
import org.apache.kafka.streams.KafkaStreams;
|
||||
import org.apache.kafka.streams.StreamsConfig;
|
||||
import org.apache.kafka.streams.kstream.KStream;
|
||||
import org.apache.kafka.streams.kstream.KStreamBuilder;
|
||||
import org.apache.kafka.streams.kstream.KTable;
|
||||
import org.apache.kafka.test.TestUtils;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class KafkaStreamsLiveTest {
|
||||
private String bootstrapServers = "localhost:9092";
|
||||
|
||||
@Test
|
||||
@Ignore("it needs to have kafka broker running on local")
|
||||
public void shouldTestKafkaStreams() throws InterruptedException {
|
||||
//given
|
||||
String inputTopic = "inputTopic";
|
||||
|
||||
Properties streamsConfiguration = new Properties();
|
||||
streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-live-test");
|
||||
streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
|
||||
streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||
streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
|
||||
streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 1000);
|
||||
streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
// Use a temporary directory for storing state, which will be automatically removed after the test.
|
||||
streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath());
|
||||
|
||||
//when
|
||||
KStreamBuilder builder = new KStreamBuilder();
|
||||
KStream<String, String> textLines = builder.stream(inputTopic);
|
||||
Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS);
|
||||
|
||||
KTable<String, Long> wordCounts = textLines
|
||||
.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase())))
|
||||
.groupBy((key, word) -> word)
|
||||
.count();
|
||||
|
||||
wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count));
|
||||
|
||||
String outputTopic = "outputTopic";
|
||||
final Serde<String> stringSerde = Serdes.String();
|
||||
final Serde<Long> longSerde = Serdes.Long();
|
||||
wordCounts.to(stringSerde, longSerde, outputTopic);
|
||||
|
||||
KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration);
|
||||
streams.start();
|
||||
|
||||
//then
|
||||
Thread.sleep(30000);
|
||||
streams.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/index/
|
|
@ -0,0 +1,80 @@
|
|||
package com.baeldung.lucene;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.StringField;
|
||||
import org.apache.lucene.document.TextField;
|
||||
import org.apache.lucene.index.DirectoryReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
import org.apache.lucene.queryparser.classic.ParseException;
|
||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
public class LuceneFileSearch {
|
||||
|
||||
private Directory indexDirectory;
|
||||
private StandardAnalyzer analyzer;
|
||||
|
||||
public LuceneFileSearch(Directory fsDirectory, StandardAnalyzer analyzer) {
|
||||
super();
|
||||
this.indexDirectory = fsDirectory;
|
||||
this.analyzer = analyzer;
|
||||
}
|
||||
|
||||
public void addFileToIndex(String filepath) throws IOException, URISyntaxException {
|
||||
|
||||
Path path = Paths.get(getClass().getClassLoader().getResource(filepath).toURI());
|
||||
File file = path.toFile();
|
||||
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
|
||||
IndexWriter indexWriter = new IndexWriter(indexDirectory, indexWriterConfig);
|
||||
Document document = new Document();
|
||||
|
||||
FileReader fileReader = new FileReader(file);
|
||||
document.add(new TextField("contents", fileReader));
|
||||
document.add(new StringField("path", file.getPath(), Field.Store.YES));
|
||||
document.add(new StringField("filename", file.getName(), Field.Store.YES));
|
||||
|
||||
indexWriter.addDocument(document);
|
||||
|
||||
indexWriter.close();
|
||||
}
|
||||
|
||||
public List<Document> searchFiles(String inField, String queryString) {
|
||||
try {
|
||||
Query query = new QueryParser(inField, analyzer).parse(queryString);
|
||||
|
||||
IndexReader indexReader = DirectoryReader.open(indexDirectory);
|
||||
IndexSearcher searcher = new IndexSearcher(indexReader);
|
||||
TopDocs topDocs = searcher.search(query, 10);
|
||||
List<Document> documents = new ArrayList<>();
|
||||
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
|
||||
documents.add(searcher.doc(scoreDoc.doc));
|
||||
}
|
||||
|
||||
return documents;
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.lucene;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.FSDirectory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LuceneFileSearchTest {
|
||||
|
||||
@Test
|
||||
public void givenSearchQueryWhenFetchedFileNamehenCorrect() throws IOException, URISyntaxException {
|
||||
String indexPath = "index";
|
||||
String dataPath = "data/file1.txt";
|
||||
|
||||
Directory directory = FSDirectory.open(Paths.get(indexPath));
|
||||
LuceneFileSearch luceneFileSearch = new LuceneFileSearch(directory, new StandardAnalyzer());
|
||||
|
||||
luceneFileSearch.addFileToIndex(dataPath);
|
||||
|
||||
List<Document> docs = luceneFileSearch.searchFiles("contents", "consectetur");
|
||||
|
||||
Assert.assertEquals("file1.txt", docs.get(0).get("filename"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
Cras auctor viverra arcu, id consequat diam posuere id. Pellentesque hendrerit felis tortor, et ornare nibh ullamcorper sed. Aenean sed mauris vitae purus auctor gravida. Nam aliquam egestas orci, sit amet imperdiet leo porttitor quis. Integer commodo sodales orci, ultrices vulputate arcu vestibulum non. Nunc at tellus id urna tristique ultrices in in massa. Vestibulum laoreet ullamcorper nulla vel porttitor. Duis blandit commodo elit at consequat. Vestibulum faucibus lectus eget mi tincidunt, quis molestie lacus mollis. Duis elementum urna eros, non iaculis est facilisis in. Praesent et neque vel ipsum viverra euismod ac ac metus. Ut vitae libero ex.
|
||||
|
||||
Proin consectetur, neque nec feugiat facilisis, metus libero mollis arcu, id pharetra nibh sapien in elit. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam pulvinar fringilla orci in posuere. Duis ut turpis dignissim nisl eleifend posuere nec a massa. Cras fringilla iaculis ipsum a aliquet. Nunc ultrices nisl ipsum, vitae consectetur tellus vehicula in. Aliquam lacinia elit nec scelerisque dapibus. Duis pharetra mauris vitae quam tincidunt, viverra iaculis orci iaculis. Nunc gravida sem arcu, et mollis leo porttitor nec. Ut dictum tempor est, at fringilla ex feugiat sed. Nullam purus mi, aliquet eu libero ut, finibus efficitur metus.
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant articles
|
||||
|
||||
- [A Guide to EclipseLink with Spring](http://www.baeldung.com/spring-eclipselink)
|
|
@ -0,0 +1,80 @@
|
|||
<?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>spring-data-eclipselink</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<name>spring-data-eclipselink</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<spring.version>1.5.9.RELEASE</spring.version>
|
||||
<eclipselink.version>2.7.0</eclipselink.version>
|
||||
<h2.version>1.4.196</h2.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
<artifactId>org.eclipse.persistence.jpa</artifactId>
|
||||
<version>${eclipselink.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<version>${h2.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.eclipselink.springdata;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class EclipselinkSpringDataApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EclipselinkSpringDataApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.eclipselink.springdata;
|
||||
|
||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
|
||||
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
|
||||
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by adam.
|
||||
*/
|
||||
@Configuration
|
||||
public class JpaConfiguration extends JpaBaseConfiguration {
|
||||
|
||||
protected JpaConfiguration(DataSource dataSource, JpaProperties properties, ObjectProvider<JtaTransactionManager> jtaTransactionManager, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
|
||||
super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
|
||||
return new EclipseLinkJpaVendorAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, Object> getVendorProperties() {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put(PersistenceUnitProperties.WEAVING, detectWeavingMode());
|
||||
map.put(PersistenceUnitProperties.DDL_GENERATION, "drop-and-create-tables");
|
||||
return map;
|
||||
}
|
||||
|
||||
private String detectWeavingMode() {
|
||||
return InstrumentationLoadTimeWeaver.isInstrumentationAvailable() ? "true" : "static";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.eclipselink.springdata.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Created by adam.
|
||||
*/
|
||||
@Entity
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
private Long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.eclipselink.springdata.repo;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import com.baeldung.eclipselink.springdata.model.Person;
|
||||
|
||||
/**
|
||||
* Created by adam.
|
||||
*/
|
||||
public interface PersonsRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
Person findByFirstName(String firstName);
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
spring.datasource.url=jdbc:h2:mem:test
|
||||
spring.jpa.show-sql=true
|
|
@ -0,0 +1,51 @@
|
|||
package com.baeldung.eclipselink.springdata.repo;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.eclipselink.springdata.model.Person;
|
||||
import com.baeldung.eclipselink.springdata.repo.PersonsRepository;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
|
||||
/**
|
||||
* Created by adam.
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
|
||||
public class PersonsRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private PersonsRepository personsRepository;
|
||||
|
||||
@Test
|
||||
public void givenPerson_whenSave_thenAddOnePersonToDB() {
|
||||
personsRepository.save(new Person());
|
||||
assertThat(personsRepository.findAll().spliterator().getExactSizeIfKnown(), equalTo(1l));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersons_whenSearch_thenFindOk() {
|
||||
Person person1 = new Person();
|
||||
person1.setFirstName("Adam");
|
||||
|
||||
Person person2 = new Person();
|
||||
person2.setFirstName("Dave");
|
||||
|
||||
personsRepository.save(person1);
|
||||
personsRepository.save(person2);
|
||||
|
||||
Person foundPerson = personsRepository.findByFirstName("Adam");
|
||||
|
||||
assertThat(foundPerson.getFirstName(), equalTo("Adam"));
|
||||
assertThat(foundPerson.getId(), notNullValue());
|
||||
}
|
||||
|
||||
}
|
3
pom.xml
3
pom.xml
|
@ -80,6 +80,7 @@
|
|||
|
||||
<module>image-processing</module>
|
||||
<module>immutables</module>
|
||||
<module>influxdb</module>
|
||||
|
||||
<module>jackson</module>
|
||||
<!-- <module>persistence-modules/java-cassandra</module> -->
|
||||
|
@ -171,6 +172,7 @@
|
|||
<module>persistence-modules/spring-hibernate-3</module>
|
||||
<module>spring-hibernate4</module>
|
||||
<module>persistence-modules/spring-hibernate-5</module>
|
||||
<module>persistence-modules/spring-data-eclipselink</module>
|
||||
<module>spring-integration</module>
|
||||
<module>spring-jenkins-pipeline</module>
|
||||
<module>spring-jersey</module>
|
||||
|
@ -263,6 +265,7 @@
|
|||
<module>deeplearning4j</module>
|
||||
<module>spring-boot-admin</module>
|
||||
<module>lucene</module>
|
||||
<module>vraptor</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue