Merge branch 'master' into BAEL-7142-spring-ai

This commit is contained in:
Ekatereana 2023-11-27 11:01:57 +02:00
commit 2d0c011456
103 changed files with 1777 additions and 171 deletions

View File

@ -9,3 +9,4 @@
- [Migrate From Java 8 to Java 17](https://www.baeldung.com/java-migrate-8-to-17)
- [Format Multiple or Conditions in an If Statement in Java](https://www.baeldung.com/java-multiple-or-conditions-if-statement)
- [Get All Record Fields and Its Values via Reflection](https://www.baeldung.com/java-reflection-record-fields-values)
- [Context-Specific Deserialization Filters in Java 17](https://www.baeldung.com/java-context-specific-deserialization-filters)

View File

@ -10,4 +10,5 @@
- [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue)
- [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide)
- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray)
- [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)

View File

@ -4,4 +4,5 @@
- [How to Write Hashmap to CSV File](https://www.baeldung.com/java-write-hashmap-csv)
- [How to Get First or Last Entry From a LinkedHashMap in Java](https://www.baeldung.com/java-linkedhashmap-first-last-key-value-pair)
- [How to Write and Read a File with a Java HashMap](https://www.baeldung.com/java-hashmap-write-read-file)
- [Limiting the Max Size of a HashMap in Java](https://www.baeldung.com/java-hashmap-max-size)
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-6)

View File

@ -0,0 +1,25 @@
package com.baeldung.map;
import java.util.HashMap;
public class HashMapWithMaxSizeLimit<K, V> extends HashMap<K, V> {
private int maxSize = -1;
public HashMapWithMaxSizeLimit() {
super();
}
public HashMapWithMaxSizeLimit(int maxSize) {
super();
this.maxSize = maxSize;
}
@Override
public V put(K key, V value) {
if (this.maxSize == -1 || this.containsKey(key) || this.size() < this.maxSize) {
return super.put(key, value);
}
throw new RuntimeException("Max size exceeded!");
}
}

View File

@ -0,0 +1,60 @@
package com.baeldung.map;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
class LimitMaxSizeHashMapByCustomHashMapUnitTest {
private final int MAX_SIZE = 4;
private HashMapWithMaxSizeLimit<Integer, String> hashMapWithMaxSizeLimit;
@Test
void givenCustomHashMapObject_whenThereIsNoLimit_thenDoesNotThrowException() {
hashMapWithMaxSizeLimit = new HashMapWithMaxSizeLimit<Integer, String>();
assertDoesNotThrow(() -> {
for (int i = 0; i < 10000; i++) {
hashMapWithMaxSizeLimit.put(i, i + "");
}
});
}
@Test
void givenCustomHashMapObject_whenLimitNotReached_thenDoesNotThrowException() {
hashMapWithMaxSizeLimit = new HashMapWithMaxSizeLimit<Integer, String>(MAX_SIZE);
assertDoesNotThrow(() -> {
for (int i = 0; i < 4; i++) {
hashMapWithMaxSizeLimit.put(i, i + "");
}
});
}
@Test
void givenCustomHashMapObject_whenReplacingValueWhenLimitIsReached_thenDoesNotThrowException() {
hashMapWithMaxSizeLimit = new HashMapWithMaxSizeLimit<Integer, String>(MAX_SIZE);
assertDoesNotThrow(() -> {
hashMapWithMaxSizeLimit.put(1, "One");
hashMapWithMaxSizeLimit.put(2, "Two");
hashMapWithMaxSizeLimit.put(3, "Three");
hashMapWithMaxSizeLimit.put(4, "Four");
hashMapWithMaxSizeLimit.put(4, "4");
});
}
@Test
void givenCustomHashMapObject_whenLimitExceeded_thenThrowsException() {
hashMapWithMaxSizeLimit = new HashMapWithMaxSizeLimit<Integer, String>(MAX_SIZE);
Exception exception = assertThrows(RuntimeException.class, () -> {
for (int i = 0; i < 5; i++) {
hashMapWithMaxSizeLimit.put(i, i + "");
}
});
String messageThrownWhenSizeExceedsLimit = "Max size exceeded!";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.equals(messageThrownWhenSizeExceedsLimit));
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.map;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
class LimitMaxSizeHashMapByLinkedHashMapUnitTest {
@Test
void givenLinkedHashMapObject_whenAddingNewEntry_thenEldestEntryIsRemoved() {
final int MAX_SIZE = 4;
LinkedHashMap<Integer, String> linkedHashMap;
linkedHashMap = new LinkedHashMap<Integer, String>() {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest) {
return size() > MAX_SIZE;
}
};
linkedHashMap.put(1, "One");
linkedHashMap.put(2, "Two");
linkedHashMap.put(3, "Three");
linkedHashMap.put(4, "Four");
linkedHashMap.put(5, "Five");
String[] expectedArrayAfterFive = { "Two", "Three", "Four", "Five" };
assertArrayEquals(expectedArrayAfterFive, linkedHashMap.values()
.toArray());
linkedHashMap.put(6, "Six");
String[] expectedArrayAfterSix = { "Three", "Four", "Five", "Six" };
assertArrayEquals(expectedArrayAfterSix, linkedHashMap.values()
.toArray());
}
}

View File

@ -0,0 +1,141 @@
package com.baeldung.map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.Test;
class Player {
private String name;
private Integer score = 0;
public Player(String name, Integer score) {
this.name = name;
this.score = score;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Player)) {
return false;
}
Player player = (Player) o;
if (!Objects.equals(name, player.name)) {
return false;
}
return Objects.equals(score, player.score);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (score != null ? score.hashCode() : 0);
return result;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
}
public class LinkedHashMapSortByValueUnitTest {
private static LinkedHashMap<String, Integer> MY_MAP = new LinkedHashMap<>();
static {
MY_MAP.put("key a", 4);
MY_MAP.put("key b", 1);
MY_MAP.put("key c", 3);
MY_MAP.put("key d", 2);
MY_MAP.put("key e", 5);
}
private static LinkedHashMap<String, Integer> EXPECTED_MY_MAP = new LinkedHashMap<>();
static {
EXPECTED_MY_MAP.put("key b", 1);
EXPECTED_MY_MAP.put("key d", 2);
EXPECTED_MY_MAP.put("key c", 3);
EXPECTED_MY_MAP.put("key a", 4);
EXPECTED_MY_MAP.put("key e", 5);
}
private static final LinkedHashMap<String, Player> PLAYERS = new LinkedHashMap<>();
static {
PLAYERS.put("player a", new Player("Eric", 9));
PLAYERS.put("player b", new Player("Kai", 7));
PLAYERS.put("player c", new Player("Amanda", 20));
PLAYERS.put("player d", new Player("Kevin", 4));
}
private static final LinkedHashMap<String, Player> EXPECTED_PLAYERS = new LinkedHashMap<>();
static {
EXPECTED_PLAYERS.put("player d", new Player("Kevin", 4));
EXPECTED_PLAYERS.put("player b", new Player("Kai", 7));
EXPECTED_PLAYERS.put("player a", new Player("Eric", 9));
EXPECTED_PLAYERS.put("player c", new Player("Amanda", 20));
}
@Test
void whenUsingCollectionSort_thenGetExpectedResult() {
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(MY_MAP.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o1.getValue()
.compareTo(o2.getValue());
}
});
LinkedHashMap<String, Integer> result = new LinkedHashMap<>();
for (Map.Entry<String, Integer> e : entryList) {
result.put(e.getKey(), e.getValue());
}
assertEquals(EXPECTED_MY_MAP, result);
}
@Test
void whenUsingEntrycomparingByValueAndFillAMap_thenGetExpectedResult() {
LinkedHashMap<String, Integer> result = new LinkedHashMap<>();
MY_MAP.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.forEachOrdered(entry -> result.put(entry.getKey(), entry.getValue()));
assertEquals(EXPECTED_MY_MAP, result);
}
@Test
void whenUsingEntrycomparingByValueAndCollect_thenGetExpectedResult() {
LinkedHashMap<String, Integer> result = MY_MAP.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.collect(LinkedHashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), Map::putAll);
assertEquals(EXPECTED_MY_MAP, result);
}
@Test
void whenUsingEntrycomparingByValueAndComparator_thenGetExpectedResult() {
LinkedHashMap<String, Player> result = PLAYERS.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.comparing(Player::getScore)))
.collect(LinkedHashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), Map::putAll);
assertEquals(EXPECTED_PLAYERS, result);
}
}

View File

@ -1,3 +1,4 @@
### Relevant Articles:
- [Why wait() Requires Synchronization?](https://www.baeldung.com/java-wait-necessary-synchronization)
- [Working with Exceptions in Java CompletableFuture](https://www.baeldung.com/java-exceptions-completablefuture)

View File

@ -10,3 +10,4 @@ This module contains articles about converting between Java date and time object
- [Convert Between LocalDateTime and ZonedDateTime](https://www.baeldung.com/java-localdatetime-zoneddatetime)
- [Conversion From 12-Hour Time to 24-Hour Time in Java](https://www.baeldung.com/java-convert-time-format)
- [Convert Epoch Time to LocalDate and LocalDateTime](https://www.baeldung.com/java-convert-epoch-localdate)
- [Convert Timestamp String to Long in Java](https://www.baeldung.com/java-convert-timestamp-string-long)

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-ipc</artifactId>
<name>core-java-ipc</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
</project>

View File

@ -0,0 +1,32 @@
package com.baeldung.ipc;
import org.junit.jupiter.api.Test;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchKey;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
public class DirectoryLiveTest {
@Test
public void consumer() throws Exception {
WatchService watchService = FileSystems.getDefault().newWatchService();
// Set this to an appropriate directory.
Path path = Paths.get("/tmp/ipc");
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
// React to new file.
System.out.println(event);
}
key.reset();
}
}
}

View File

@ -0,0 +1,52 @@
package com.baeldung.ipc;
import org.junit.jupiter.api.Test;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
public class JmxLiveTest {
/*
* This test needs to be run with the following system properties defined:
* -Dcom.sun.management.jmxremote=true
* -Dcom.sun.management.jmxremote.port=1234
* -Dcom.sun.management.jmxremote.authenticate=false
* -Dcom.sun.management.jmxremote.ssl=false
*/
@Test
public void consumer() throws Exception {
ObjectName objectName = new ObjectName("com.baeldung.ipc:type=basic,name=test");
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
server.registerMBean(new IPCTest(), objectName);
TimeUnit.MINUTES.sleep(50);
}
@Test
public void producer() throws Exception {
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1234/jmxrmi");
try (JMXConnector jmxc = JMXConnectorFactory.connect(url, null)) {
ObjectName objectName = new ObjectName("com.baeldung.ipc:type=basic,name=test");
IPCTestMBean mbeanProxy = JMX.newMBeanProxy(jmxc.getMBeanServerConnection(), objectName, IPCTestMBean.class, true);
mbeanProxy.sendMessage("Hello");
}
}
public interface IPCTestMBean {
void sendMessage(String message);
}
class IPCTest implements IPCTestMBean {
@Override
public void sendMessage(String message) {
System.out.println("Received message: " + message);
}
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.ipc;
import org.junit.jupiter.api.Test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketsLiveTest {
@Test
public void consumer() throws Exception {
try (ServerSocket serverSocket = new ServerSocket(1234)) {
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println("Received message: " + line);
}
}
}
@Test
public void producer() throws Exception {
try (Socket clientSocket = new Socket("localhost", 1234)) {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("Hello");
String response = in.readLine();
}
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.returnfirstnonnull;
class LazyEvaluate {
String methodA() {
return null;
}
String methodB() {
return "first non null";
}
String methodC() {
return "second non null";
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.returnfirstnonempty;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class ReturnFirstNonEmptyOptionalUnitTest {
private List<Optional<String>> optionals;
@BeforeEach
public void init() {
optionals = Arrays.asList(Optional.<String> empty(), Optional.of("first non empty"), Optional.of("second non empty"));
}
@Test
void givenListOfOptionals_whenStreaming_thenReturnFirstNonEmpty() {
Optional<String> object = optionals.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
assertThat(object).contains("first non empty");
}
}

View File

@ -0,0 +1,77 @@
package com.baeldung.returnfirstnonnull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.commons.lang3.ObjectUtils;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
public class ReturnFirstNonNullLazyEvaluateUnitTest {
private final LazyEvaluate spy = Mockito.spy(new LazyEvaluate());
@Test
void givenChainOfMethods_whenUsingIfStatements_thenLazilyEvaluateMethodsUntilFirstNonNull() {
String object = spy.methodA();
if (object == null) {
object = spy.methodB();
}
if (object == null) {
object = spy.methodC();
}
assertEquals("first non null", object);
verify(spy, times(1)).methodA();
verify(spy, times(1)).methodB();
verify(spy, times(0)).methodC();
}
@Test
void givenChainOfMethods_whenUsingApacheCommonsLang3_thenReturnFirstNonNull() {
String object = ObjectUtils.getFirstNonNull(spy::methodA, spy::methodB, spy::methodC);
assertEquals("first non null", object);
verify(spy, times(1)).methodA();
verify(spy, times(1)).methodB();
verify(spy, times(0)).methodC();
}
@Test
void givenChainOfMethods_whenUsingSupplierInterface_thenLazilyEvaluateMethodsUntilFirstNonNull() {
Optional<String> object = Stream.<Supplier<String>> of(spy::methodA, spy::methodB, spy::methodC)
.map(Supplier::get)
.filter(Objects::nonNull)
.findFirst();
assertThat(object).contains("first non null");
verify(spy, times(1)).methodA();
verify(spy, times(1)).methodB();
verify(spy, times(0)).methodC();
}
@Test
void givenNonNullObjectAndFallbackMethod_whenUsingApacheCommonsLang3_thenReturnFirstNonNull() {
String nonNullObject = spy.methodB();
String object = ObjectUtils.getIfNull(nonNullObject, spy::methodC);
assertEquals("first non null", object);
verify(spy, times(0)).methodC();
}
@Test
void givenNullObjectAndFallbackMethod_whenUsingApacheCommonsLang3_thenReturnFirstNonNull() {
String nullObject = null;
String object = ObjectUtils.getIfNull(nullObject, spy::methodB);
assertEquals("first non null", object);
}
}

View File

@ -0,0 +1,81 @@
package com.baeldung.returnfirstnonnull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.apache.commons.lang3.ObjectUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
public class ReturnFirstNonNullUnitTest {
private List<String> objects;
@BeforeEach
public void init() {
objects = Arrays.asList(null, "first non null", "second nun null");
}
@Test
void givenListOfObjects_whenFilterIsLambdaNullCheckInStream_thenReturnFirstNonNull() {
Optional<String> object = objects.stream()
.filter(o -> o != null)
.findFirst();
assertThat(object).contains("first non null");
}
@Test
void givenListOfObjects_whenFilterIsMethodRefNullCheckInStream_thenReturnFirstNonNull() {
Optional<String> object = objects.stream()
.filter(Objects::nonNull)
.findFirst();
assertThat(object).contains("first non null");
}
@Test
void givenListOfObjects_whenIteratingWithForLoop_thenReturnFirstNonNull() {
String object = null;
for (int i = 0; i < objects.size(); i++) {
if (objects.get(i) != null) {
object = objects.get(i);
break;
}
}
assertEquals("first non null", object);
}
@Test
void givenListOfObjects_whenUsingApacheCommonsLang3_thenReturnFirstNonNull() {
String object = ObjectUtils.firstNonNull(objects.toArray(new String[0]));
assertEquals("first non null", object);
}
@Test
void givenListOfObjects_whenUsingGoogleGuavaIterables_thenReturnFirstNonNull() {
String object = Iterables.find(objects, Predicates.notNull());
assertEquals("first non null", object);
}
@Test
void givenTwoObjects_whenUsingGoogleGuavaMoreObjects_thenReturnFirstNonNull() {
String nullObject = null;
String nonNullObject = "first non null";
String object = MoreObjects.firstNonNull(nullObject, nonNullObject);
assertEquals("first non null", object);
}
}

View File

@ -26,13 +26,25 @@ public class Rectangle {
this.topRight = topRight;
}
public boolean isOverlapping(Rectangle other) {
// one rectangle is to the top of the other
if (this.topRight.getY() < other.bottomLeft.getY() || this.bottomLeft.getY() > other.topRight.getY()) {
public boolean isOverlapping(Rectangle comparedRectangle) {
// one rectangle is to the top of the comparedRectangle
if (this.topRight.getY() < comparedRectangle.bottomLeft.getY() || this.bottomLeft.getY() > comparedRectangle.topRight.getY()) {
return false;
}
// one rectangle is to the left of the other
if (this.topRight.getX() < other.bottomLeft.getX() || this.bottomLeft.getX() > other.topRight.getX()) {
// one rectangle is to the left of the comparedRectangle
if (this.topRight.getX() < comparedRectangle.bottomLeft.getX() || this.bottomLeft.getX() > comparedRectangle.topRight.getX()) {
return false;
}
return true;
}
public boolean isOverlappingWithoutBorders(Rectangle comparedRectangle) {
// one rectangle is to the top of the comparedRectangle
if (this.topRight.getY() <= comparedRectangle.bottomLeft.getY() || this.bottomLeft.getY() >= comparedRectangle.topRight.getY()) {
return false;
}
// one rectangle is to the left of the comparedRectangle
if (this.topRight.getX() <= comparedRectangle.bottomLeft.getX() || this.bottomLeft.getX() >= comparedRectangle.topRight.getX()) {
return false;
}
return true;

View File

@ -1,7 +1,8 @@
package com.baeldung.algorithms.rectanglesoverlap;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class RectangleUnitTest {
@ -36,4 +37,18 @@ public class RectangleUnitTest {
assertFalse(rectangle1.isOverlapping(rectangle2));
}
@Test
public void givenAdjacentRectangles_whensOverlappingCalled_shouldReturnTrue() {
Rectangle rectangle1 = new Rectangle(new Point(0, 0), new Point(5, 14));
Rectangle rectangle2 = new Rectangle(new Point(5, 0), new Point(17, 14));
assertTrue(rectangle1.isOverlapping(rectangle2));
}
@Test
public void givenAdjacentRectangles_whensOverlappingWithoutBordersCalled_shouldReturnFalse() {
Rectangle rectangle1 = new Rectangle(new Point(0, 0), new Point(5, 14));
Rectangle rectangle2 = new Rectangle(new Point(5, 0), new Point(17, 14));
assertFalse(rectangle1.isOverlappingWithoutBorders(rectangle2));
}
}

View File

@ -10,3 +10,4 @@ This module contains articles about types in Java
- [Filling a List With All Enum Values in Java](https://www.baeldung.com/java-enum-values-to-list)
- [Comparing a String to an Enum Value in Java](https://www.baeldung.com/java-comparing-string-to-enum)
- [Implementing toString() on enums in Java](https://www.baeldung.com/java-enums-tostring)
- [Checking if an Objects Type Is Enum](https://www.baeldung.com/java-check-object-enum)

View File

@ -56,7 +56,7 @@
<properties>
<apache.commons-validator.version>1.7</apache.commons-validator.version>
<jsoup.version>1.15.4</jsoup.version>
<jsoup.version>1.16.2</jsoup.version>
</properties>
</project>

View File

@ -5,3 +5,4 @@
- [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters)
- [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string)
- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence)
- [Difference Between String isEmpty() and isBlank()](https://www.baeldung.com/java-string-isempty-vs-isblank)

View File

@ -24,12 +24,6 @@
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
@ -39,7 +33,7 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.9.1</version>
<version>${liquibase.core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
@ -67,6 +61,7 @@
<maven.compiler.target>11</maven.compiler.target>
<apache.commons.lang3.version>3.13.0</apache.commons.lang3.version>
<commons-text.version>1.10.0</commons-text.version>
<liquibase.core.version>4.25.0</liquibase.core.version>
</properties>
</project>

View File

@ -1,6 +1,6 @@
package com.baeldung.centertext;
import liquibase.repackaged.org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.jupiter.api.Test;

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-string-swing</artifactId>
<name>core-java-string-swing</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<maven.compiler.source>20</maven.compiler.source>
<maven.compiler.target>20</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,55 @@
package com.baeldung.customfont;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class CustomFonts {
public static void main(String[] args) {
usingCustomFonts();
}
public static void usingCustomFonts() {
final GraphicsEnvironment GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
final List<String> AVAILABLE_FONT_FAMILY_NAMES = Arrays.asList(GE.getAvailableFontFamilyNames());
try {
final List<File> LIST = Arrays.asList(
new File("font/JetBrainsMono/JetBrainsMono-Thin.ttf"),
new File("font/JetBrainsMono/JetBrainsMono-Light.ttf"),
new File("font/Roboto/Roboto-Light.ttf"),
new File("font/Roboto/Roboto-Regular.ttf"),
new File("font/Roboto/Roboto-Medium.ttf")
);
for (File LIST_ITEM : LIST) {
if (LIST_ITEM.exists()) {
Font FONT = Font.createFont(Font.TRUETYPE_FONT, LIST_ITEM);
if (!AVAILABLE_FONT_FAMILY_NAMES.contains(FONT.getFontName())) {
GE.registerFont(FONT);
}
}
}
} catch (FontFormatException | IOException exception) {
JOptionPane.showMessageDialog(null, exception.getMessage());
}
JFrame frame = new JFrame("Custom Font Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label1 = new JLabel("TEXT1");
label1.setFont(new Font("Roboto Medium", Font.PLAIN, 17));
JLabel label2 = new JLabel("TEXT2");
label2.setFont(new Font("JetBrainsMono-Thin", Font.PLAIN, 17));
frame.add(label1);
frame.add(label2);
frame.pack();
frame.setVisible(true);
}
}

View File

@ -54,6 +54,7 @@
<module>core-java-concurrency-simple</module>
<module>core-java-datetime-string</module>
<module>core-java-io-conversions-2</module>
<module>core-java-ipc</module>
<module>core-java-jpms</module>
<module>core-java-lang-oop-constructors-2</module>
<module>core-java-methods</module>
@ -183,6 +184,7 @@
<module>core-java-string-algorithms</module>
<module>core-java-string-algorithms-2</module>
<module>core-java-string-apis</module>
<module>core-java-swing</module>
<module>core-java-string-apis-2</module>
<module>core-java-string-conversions</module>
<module>core-java-string-conversions-2</module>

View File

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

View File

@ -0,0 +1,20 @@
plugins {
id 'java'
}
group = 'org.baeldung'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation 'io.micrometer:micrometer-core:1.12.0'
}
test {
useJUnitPlatform()
}

View File

@ -0,0 +1,12 @@
# HTTP proxy settings
systemProp.http.proxyHost=localhost
systemProp.http.proxyPort=3128
systemProp.http.proxyUser=USER
systemProp.http.proxyPassword=PASSWORD
systemProp.http.nonProxyHosts=*.nonproxyrepos.com
# HTTPS proxy settings
systemProp.https.proxyHost=localhost
systemProp.https.proxyPort=3128
systemProp.https.proxyUser=USER
systemProp.https.proxyPassword=PASSWORD
systemProp.https.nonProxyHosts=*.nonproxyrepos.com

View File

@ -0,0 +1,6 @@
#Thu Nov 16 23:15:01 GMT 2023
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,2 @@
rootProject.name = 'gradle-proxy-configuration'

View File

@ -0,0 +1,64 @@
package com.baeldung.gson.multiplefields;
import java.util.Objects;
import com.google.gson.annotations.SerializedName;
public class BasicStudent {
private String name;
private transient String major;
@SerializedName("major")
private String concentration;
public BasicStudent() {
}
public BasicStudent(String name, String major, String concentration) {
this.name = name;
this.major = major;
this.concentration = concentration;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof BasicStudent))
return false;
BasicStudent student = (BasicStudent) o;
return Objects.equals(name, student.name) && Objects.equals(major, student.major) && Objects.equals(concentration, student.concentration);
}
@Override
public int hashCode() {
return Objects.hash(name, major, concentration);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public String getConcentration() {
return concentration;
}
public void setConcentration(String concentration) {
this.concentration = concentration;
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.gson.multiplefields;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
public class StudentExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes field) {
// Ignore all field values from V1 type
return field.getDeclaringClass() == StudentV1.class;
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.gson.multiplefields;
public class StudentV1 {
private String firstName;
private String lastName;
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;
}
// Default constructor for Gson
public StudentV1() {
}
public StudentV1(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}

View File

@ -0,0 +1,71 @@
package com.baeldung.gson.multiplefields;
import java.util.Objects;
import com.google.gson.annotations.Expose;
public class StudentV2 extends StudentV1 {
@Expose
private String firstName;
@Expose
private String lastName;
@Expose
private String major;
@Override
public String getFirstName() {
return firstName;
}
@Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Override
public String getLastName() {
return lastName;
}
@Override
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
// Default constructor for Gson
public StudentV2() {
}
public StudentV2(String firstName, String lastName, String major) {
this.firstName = firstName;
this.lastName = lastName;
this.major = major;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof StudentV2))
return false;
StudentV2 studentV2 = (StudentV2) o;
return Objects.equals(firstName, studentV2.firstName) && Objects.equals(lastName, studentV2.lastName) && Objects.equals(major, studentV2.major);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, major);
}
}

View File

@ -0,0 +1,65 @@
package com.baeldung.gson.multiplefields;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class GsonMultipleFieldsUnitTest {
@Test
public void givenBasicStudent_whenSerializingWithGson_thenTransientFieldNotSet() {
// Given a class with a transient field
BasicStudent student = new BasicStudent("Henry Winter", "Greek Studies", "Classical Greek Studies");
// When serializing using Gson
Gson gson = new Gson();
String json = gson.toJson(student);
// Then the deserialized instance doesn't contain the transient field value
BasicStudent deserialized = gson.fromJson(json, BasicStudent.class);
assertThat(deserialized.getMajor()).isNull();
}
@Test
public void givenStudentV2_whenSerializingWithGson_thenIllegalArgumentExceptionIsThrown() {
// Given a class with a class hierarchy that defines multiple fields with the same name
StudentV2 student = new StudentV2("Henry", "Winter", "Greek Studies");
// When serializing using Gson, then an IllegalArgumentException exception is thrown
Gson gson = new Gson();
assertThatThrownBy(() -> gson.toJson(student)).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("declares multiple JSON fields named 'firstName'");
}
@Test
public void givenStudentV2_whenSerializingWithGsonExposeAnnotation_thenSerializes() {
// Given a class with a class hierarchy that defines multiple fields with the same name
StudentV2 student = new StudentV2("Henry", "Winter", "Greek Studies");
// When serializing using Gson exclude fields without @Expose
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
.create();
// Then ensure the student can be serialized, then deserialized back into an equal instance
String json = gson.toJson(student);
assertThat(gson.fromJson(json, StudentV2.class)).isEqualTo(student);
}
@Test
public void givenStudentV2_whenSerializingWithGsonExclusionStrategy_thenSerializes() {
// Given a class with a class hierarchy that defines multiple fields with the same name
StudentV2 student = new StudentV2("Henry", "Winter", "Greek Studies");
// When serializing using Gson add an ExclusionStrategy
Gson gson = new GsonBuilder().setExclusionStrategies(new StudentExclusionStrategy())
.create();
// Then ensure the student can be serialized, then deserialized back into an equal instance
assertThat(gson.fromJson(gson.toJson(student), StudentV2.class)).isEqualTo(student);
}
}

View File

@ -22,7 +22,7 @@
</dependencies>
<properties>
<jsoup.version>1.10.2</jsoup.version>
<jsoup.version>1.16.2</jsoup.version>
</properties>
</project>

View File

@ -2,7 +2,7 @@ package com.baeldung.jsoup;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.safety.Whitelist;
import org.jsoup.safety.Safelist;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@ -13,7 +13,7 @@ public class PreservingLineBreaksUnitTest {
String strHTML = "<html><body>Hello\nworld</body></html>";
Document.OutputSettings outputSettings = new Document.OutputSettings();
outputSettings.prettyPrint(false);
String strWithNewLines = Jsoup.clean(strHTML, "", Whitelist.none(), outputSettings);
String strWithNewLines = Jsoup.clean(strHTML, "", Safelist.none(), outputSettings);
assertEquals("Hello\nworld", strWithNewLines);
}
@ -33,7 +33,7 @@ public class PreservingLineBreaksUnitTest {
jsoupDoc.select("p").before("\\n");
String str = jsoupDoc.html().replaceAll("\\\\n", "\n");
String strWithNewLines =
Jsoup.clean(str, "", Whitelist.none(), outputSettings);
Jsoup.clean(str, "", Safelist.none(), outputSettings);
assertEquals("Hello\nWorld\nParagraph", strWithNewLines);
}
}

View File

@ -197,7 +197,7 @@
<javapoet.version>1.10.0</javapoet.version>
<mockftpserver.version>2.7.1</mockftpserver.version>
<functionaljava.version>4.8.1</functionaljava.version>
<resilience4j.version>0.12.1</resilience4j.version>
<resilience4j.version>2.1.0</resilience4j.version>
<protonpack.version>1.15</protonpack.version>
<commons-net.version>3.6</commons-net.version>
<renjin.version>3.5-beta72</renjin.version>

View File

@ -43,7 +43,7 @@ public class Resilience4jUnitTest {
// Percentage of failures to start short-circuit
.failureRateThreshold(20)
// Min number of call attempts
.ringBufferSizeInClosedState(5)
.slidingWindowSize(5)
.build();
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("my");
@ -70,7 +70,7 @@ public class Resilience4jUnitTest {
Future<?> taskInProgress = callAndBlock(decorated);
try {
assertThat(bulkhead.isCallPermitted()).isFalse();
assertThat(bulkhead.tryAcquirePermission()).isFalse();
} finally {
taskInProgress.cancel(true);
}

View File

@ -111,12 +111,12 @@
<poi-scratchpad.version>3.15</poi-scratchpad.version>
<batik-transcoder.version>1.8</batik-transcoder.version>
<poi-ooxml.version>3.15</poi-ooxml.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<flying-saucer-pdf.version>9.1.20</flying-saucer-pdf.version>
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
<flying-saucer-pdf.version>9.3.1</flying-saucer-pdf.version>
<open-html-pdfbox.version>1.0.6</open-html-pdfbox.version>
<open-html-pdf-core.version>1.0.6</open-html-pdf-core.version>
<flying-saucer-pdf-openpdf.version>9.1.22</flying-saucer-pdf-openpdf.version>
<jsoup.version>1.14.2</jsoup.version>
<open-html-pdf-core.version>1.0.10</open-html-pdf-core.version>
<flying-saucer-pdf-openpdf.version>9.2.1</flying-saucer-pdf-openpdf.version>
<jsoup.version>1.16.2</jsoup.version>
</properties>
</project>

View File

@ -37,7 +37,7 @@
<properties>
<mysql-connector-java.version>5.1.6</mysql-connector-java.version>
<liquibase-maven-plugin.version>3.4.2</liquibase-maven-plugin.version>
<liquibase-maven-plugin.version>4.25.0</liquibase-maven-plugin.version>
</properties>
</project>

View File

@ -2,9 +2,7 @@
### Relevant Articles:
- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
- [Performance Difference Between save() and saveAll() in Spring Data](https://www.baeldung.com/spring-data-save-saveall)
- [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries)
- [How to Access EntityManager with Spring Data](https://www.baeldung.com/spring-data-entitymanager)
- [Difference Between JPA and Spring Data JPA](https://www.baeldung.com/spring-data-jpa-vs-jpa)
- [Differences Between Spring Data JPA findFirst() and findTop()](https://www.baeldung.com/spring-data-jpa-findfirst-vs-findtop)

View File

@ -42,11 +42,6 @@
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -1,7 +0,0 @@
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
INSERT INTO "movie" ("id", "title", "director", "rating", "duration") VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);

View File

@ -3,6 +3,7 @@
This module contains articles about repositories in Spring Data JPA
### Relevant Articles:
- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa)
- [Case Insensitive Queries with Spring Data Repository](https://www.baeldung.com/spring-data-case-insensitive-queries)
- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries)
- [Spring Data CrudRepository save() Method](https://www.baeldung.com/spring-data-crud-repository-save)
@ -10,6 +11,8 @@ This module contains articles about repositories in Spring Data JPA
- [Spring Data Composable Repositories](https://www.baeldung.com/spring-data-composable-repositories)
- [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators)
- [Calling Stored Procedures from Spring Data JPA Repositories](https://www.baeldung.com/spring-data-jpa-stored-procedures)
- [LIKE Queries in Spring JPA Repositories](https://www.baeldung.com/spring-jpa-like-queries)
- More articles: [[--> next]](../spring-data-jpa-repo-2)
### Eclipse Config

View File

@ -42,6 +42,11 @@
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,8 +1,13 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
import javax.persistence.*;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Foo implements Serializable {
@Id

View File

@ -1,4 +1,4 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@ -1,8 +1,9 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
public interface IFooDAO extends JpaRepository<Foo, Long> {

View File

@ -1,4 +1,4 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
public interface IFooService {
Foo create(Foo foo);

View File

@ -1,6 +1,9 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
import java.util.Properties;
import javax.sql.DataSource;
import com.google.common.base.Preconditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@ -16,15 +19,14 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
import com.google.common.base.Preconditions;
@Configuration
@PropertySource("classpath:persistence.properties")
@ComponentScan("com.baeldung.spring.data.persistence.repository")
@ComponentScan("com.baeldung.repository")
//@ImportResource("classpath*:*springDataConfig.xml")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.baeldung.spring.data.persistence.repository")
@EnableJpaRepositories(basePackages = "com.baeldung.repository")
public class PersistenceConfig {
@Autowired

View File

@ -1,11 +1,12 @@
package com.baeldung.spring.data.persistence.like.repository;
import com.baeldung.spring.data.persistence.like.model.Movie;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
import com.baeldung.spring.data.persistence.like.model.Movie;
public interface MovieRepository extends CrudRepository<Movie, Long> {

View File

@ -0,0 +1,9 @@
# jdbc.X
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.user=sa
jdbc.pass=sa
# hibernate.X
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=org.hibernate.dialect.H2Dialect

View File

@ -7,5 +7,5 @@
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
>
<jpa:repositories base-package="com.baeldung.spring.data.persistence.repository"/>
<jpa:repositories base-package="com.baeldung.repository"/>
</beans>

View File

@ -1,4 +1,6 @@
package com.baeldung.spring.data.persistence.repository;
package com.baeldung.repository;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -7,8 +9,6 @@ import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = PersistenceConfig.class)
public class FooServiceIntegrationTest {

View File

@ -1,7 +1,12 @@
package com.baeldung.spring.data.persistence.like;
import com.baeldung.spring.data.persistence.like.model.Movie;
import com.baeldung.spring.data.persistence.like.repository.MovieRepository;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -9,11 +14,8 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD;
import com.baeldung.spring.data.persistence.like.model.Movie;
import com.baeldung.spring.data.persistence.like.repository.MovieRepository;
@RunWith(SpringRunner.class)
@Sql(scripts = { "/test-movie-data.sql" })

View File

@ -1,2 +1,2 @@
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:h2:mem:jpa3
#spring.jpa.hibernate.ddl-auto=update
#spring.datasource.url=jdbc:h2:mem:jpa3

View File

@ -0,0 +1 @@
DELETE FROM movie;

View File

@ -0,0 +1,7 @@
INSERT INTO movie(id,title,director,rating,duration) VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132);
INSERT INTO movie(id,title,director,rating,duration) VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181);
INSERT INTO movie(id,title,director,rating,duration) VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123);
INSERT INTO movie(id,title,director,rating,duration) VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112);
INSERT INTO movie(id,title,director,rating,duration) VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102);
INSERT INTO movie(id,title,director,rating,duration) VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128);
INSERT INTO movie(id,title,director,rating,duration) VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100);

View File

@ -889,7 +889,7 @@
<module>spring-vault</module>
<module>spring-web-modules</module>
<module>spring-websockets</module>
<module>static-analysis</module>
<!-- <module>static-analysis</module> - requires additional configuration to be compiled due to the JVM strong encapsulation -->
<module>tablesaw</module>
<module>tensorflow-java</module>
<module>testing-modules</module>
@ -1134,7 +1134,7 @@
<module>spring-vault</module>
<module>spring-web-modules</module>
<module>spring-websockets</module>
<module>static-analysis</module>
<!-- <module>static-analysis</module> - requires additional configuration to be compiled due to the JVM strong encapsulation -->
<module>tablesaw</module>
<module>tensorflow-java</module>
<module>testing-modules</module>

View File

@ -66,8 +66,7 @@
</build>
<properties>
<liquibase-core.version>3.8.1</liquibase-core.version>
<liquibase.version>3.8.1</liquibase.version>
<liquibase-core.version>4.25.0</liquibase-core.version>
</properties>
</project>

View File

@ -86,6 +86,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.12.0</version> <!-- this can be removed when we migrate spring-boot-dependencies to the latest version -->
</dependency>
</dependencies>

View File

@ -74,6 +74,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.12.0</version> <!-- this can be removed when we migrate spring-boot-dependencies to the latest version -->
</dependency>
</dependencies>

View File

@ -11,9 +11,9 @@
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<artifactId>parent-boot-3</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
<relativePath>../parent-boot-3</relativePath>
</parent>
<dependencies>
@ -53,16 +53,17 @@
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
<dependency>
<groupId>org.apache.commons</groupId>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
</dependencies>
<properties>
<!-- The main class to start by executing java -jar -->
<start-class>com.baeldung.SpringDemoApplication</start-class>
<cucumber.version>7.14.0</cucumber.version>
<commons-io.version>1.3.2</commons-io.version>
<junit-vintage-engine.version>5.10.0</junit-vintage-engine.version>
<junit-vintage-engine.version>5.10.1</junit-vintage-engine.version>
</properties>
</project>

View File

@ -3,6 +3,7 @@ package com.baeldung.cucumberoptions;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@ -11,12 +12,12 @@ import org.springframework.web.bind.annotation.RestController;
public class HealthCheckController {
@GetMapping(path = "/v1/status", produces = APPLICATION_JSON_VALUE)
public HttpStatus getV1Status() {
public HttpStatusCode getV1Status() {
return ResponseEntity.ok().build().getStatusCode();
}
@GetMapping(path = "/v2/status", produces = APPLICATION_JSON_VALUE)
public HttpStatus getV2Status() {
public HttpStatusCode getV2Status() {
return ResponseEntity.ok().build().getStatusCode();
}
}

View File

@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.web.client.ResponseErrorHandler;
@ -69,7 +71,7 @@ public class SpringIntegrationTest {
@Override
public boolean hasError(ClientHttpResponse response) throws IOException {
hadError = response.getRawStatusCode() >= 400;
hadError = response.getStatusCode().value() >= 400;
return hadError;
}

View File

@ -5,6 +5,7 @@ import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@ -29,7 +30,7 @@ public class StepDefsIntegrationTest extends SpringIntegrationTest {
@Then("^the client receives status code of (\\d+)$")
public void the_client_receives_status_code_of(int statusCode) throws Throwable {
final HttpStatus currentStatusCode = latestResponse.getTheResponse().getStatusCode();
final HttpStatusCode currentStatusCode = latestResponse.getTheResponse().getStatusCode();
assertThat("status code is incorrect : " + latestResponse.getBody(), currentStatusCode.value(), is(statusCode));
}

View File

@ -3,7 +3,8 @@ package com.baeldung.cucumberoptions;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
@ -32,7 +33,7 @@ public class HealthCheckStepDefsIntegrationTest extends SpringIntegrationTest {
@Then("^the client receives (\\d+) status code$")
public void verifyStatusCode(int statusCode) throws Throwable {
final HttpStatus currentStatusCode = statusResponse.getStatusCode();
final HttpStatusCode currentStatusCode = statusResponse.getStatusCode();
assertThat(currentStatusCode.value(), is(statusCode));
}
}

View File

@ -7,4 +7,5 @@ This module contains articles about dependency injection with Spring
- [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class)
- [Spring @Component Annotation](https://www.baeldung.com/spring-component-annotation)
- [Why Is Field Injection Not Recommended?](https://www.baeldung.com/java-spring-field-injection-cons)
- [Setting a Spring Bean to Null](https://www.baeldung.com/spring-setting-bean-null)
- More articles: [[<-- prev]](../spring-di-3)

View File

@ -9,3 +9,4 @@ This module contains articles about Spring with Kafka
- [Understanding Kafka Topics and Partitions](https://www.baeldung.com/kafka-topics-partitions)
- [How to Subscribe a Kafka Consumer to Multiple Topics](https://www.baeldung.com/kafka-subscribe-consumer-multiple-topics)
- [Splitting Streams in Kafka](https://www.baeldung.com/kafka-splitting-streams)
- [Manage Kafka Consumer Groups](https://www.baeldung.com/kafka-manage-consumer-groups)

View File

@ -1,16 +1,17 @@
package com.baeldung.httpsecurityvswebsecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
public class HttpSecurityConfig {
@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// Given: HttpSecurity configured
http.authorizeRequests()
@ -27,5 +28,6 @@ public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
// When: Accessing specific URLs
// Then: Access is granted based on defined rules
return http.build();
}
}

View File

@ -1,35 +1,48 @@
package com.baeldung.httpsecurityvswebsecurity;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public class WebSecurityConfig {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.userDetailsService(userDetailsService);
AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
http.authorizeRequests()
.antMatchers("/")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin();
.antMatchers("/")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin().and()
.authenticationManager(authenticationManager)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
protected void configure(HttpSecurity http) throws Exception {
}
}

View File

@ -8,7 +8,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;

View File

@ -10,11 +10,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.saml.*;
import org.springframework.security.saml.key.KeyManager;
import org.springframework.security.saml.metadata.*;
@ -31,7 +29,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public class WebSecurityConfig {
@Value("${saml.sp}")
private String samlAudience;
@ -55,8 +53,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public SAMLDiscovery samlDiscovery() {
SAMLDiscovery idpDiscovery = new SAMLDiscovery();
return idpDiscovery;
return new SAMLDiscovery();
}
@Autowired
@ -78,19 +75,19 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Bean
public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
public SAMLProcessingFilter samlWebSSOProcessingFilter(AuthenticationManager authenticationManager) {
SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager);
samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(samlAuthSuccessHandler);
samlWebSSOProcessingFilter.setAuthenticationFailureHandler(samlAuthFailureHandler);
return samlWebSSOProcessingFilter;
}
@Bean
public FilterChainProxy samlFilter() throws Exception {
public FilterChainProxy samlFilter(SAMLProcessingFilter samlProcessingFilter) throws Exception {
List<SecurityFilterChain> chains = new ArrayList<>();
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/SSO/**"),
samlWebSSOProcessingFilter()));
samlProcessingFilter));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/discovery/**"),
samlDiscovery()));
chains.add(new DefaultSecurityFilterChain(new AntPathRequestMatcher("/saml/login/**"),
@ -102,19 +99,13 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
return new FilterChainProxy(chains);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public MetadataGeneratorFilter metadataGeneratorFilter() {
return new MetadataGeneratorFilter(metadataGenerator());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, SAMLProcessingFilter samlProcessingFilter) throws Exception {
http
.csrf()
.disable();
@ -125,8 +116,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
http
.addFilterBefore(metadataGeneratorFilter(), ChannelProcessingFilter.class)
.addFilterAfter(samlFilter(), BasicAuthenticationFilter.class)
.addFilterBefore(samlFilter(), CsrfFilter.class);
.addFilterAfter(samlProcessingFilter, BasicAuthenticationFilter.class)
.addFilterBefore(samlProcessingFilter, CsrfFilter.class);
http
.authorizeRequests()
@ -142,11 +133,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
e.printStackTrace();
}
});
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(samlAuthenticationProvider);
http.authenticationProvider(samlAuthenticationProvider);
return http.build();
}
}

View File

@ -3,7 +3,6 @@ package com.baeldung.spring;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* Spring Security Configuration.
@ -11,7 +10,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@Configuration
@EnableWebSecurity
@ImportResource({ "classpath:webSecurityConfig.xml" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public class SecurityConfig {
public SecurityConfig() {
super();

View File

@ -150,7 +150,7 @@
<properties>
<hibernate-validator.version>8.0.1.Final</hibernate-validator.version>
<deploy-path>enter-location-of-server</deploy-path>
<org.thymeleaf-version>3.0.11.RELEASE</org.thymeleaf-version>
<org.thymeleaf-version>3.1.2.RELEASE</org.thymeleaf-version>
<groovy.version>2.4.12</groovy.version>
<freemarker.version>2.3.27-incubating</freemarker.version>
<jade.version>1.2.5</jade.version>

View File

@ -51,7 +51,7 @@
<properties>
<swagger2.version>2.9.2</swagger2.version>
<resilience4j.version>1.6.1</resilience4j.version>
<resilience4j.version>2.1.0</resilience4j.version>
<springdoc.version>1.7.0</springdoc.version>
</properties>

View File

@ -135,7 +135,7 @@
<properties>
<spring-data.version>2.3.2.RELEASE</spring-data.version>
<org.thymeleaf-version>3.0.11.RELEASE</org.thymeleaf-version>
<org.thymeleaf-version>3.1.2.RELEASE</org.thymeleaf-version>
<org.thymeleaf.extras-version>3.0.4.RELEASE</org.thymeleaf.extras-version>
<thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version>
<javax.validation-version>2.0.1.Final</javax.validation-version>

View File

@ -136,7 +136,7 @@
<properties>
<spring-data.version>2.3.2.RELEASE</spring-data.version>
<org.thymeleaf-version>3.0.11.RELEASE</org.thymeleaf-version>
<org.thymeleaf-version>3.1.2.RELEASE</org.thymeleaf-version>
<org.thymeleaf.extras-version>3.0.4.RELEASE</org.thymeleaf.extras-version>
<thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version>
<javax.validation-version>2.0.1.Final</javax.validation-version>

View File

@ -0,0 +1,10 @@
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>static-analysis</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>error-prone-project</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>17</release>
<encoding>UTF-8</encoding>
<fork>true</fork>
<compilerArgs>
<arg>-XDcompilePolicy=simple</arg>
<arg>-Xplugin:ErrorProne</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_core</artifactId>
<version>${error-prone.version}</version>
</path>
<path>
<groupId>com.baeldung</groupId>
<artifactId>my-bugchecker-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,12 @@
package com.baeldung;
public class BuggyClass {
public static void main(String[] args) {
if (args.length == 0 || args[0] != null) {
new IllegalArgumentException();
}
}
public void emptyMethod() {
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung;
public class ClassWithEmptyMethod {
public void theEmptyMethod() {
}
}

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>static-analysis</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<artifactId>my-bugchecker-plugin</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>${google-auto-service.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotation</artifactId>
<version>${error-prone.version}</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_check_api</artifactId>
<version>${error-prone.version}</version>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service-annotations</artifactId>
<version>${google-auto-service.version}</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,24 @@
package com.baeldung;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
import com.sun.source.tree.MethodTree;
@AutoService(BugChecker.class)
@BugPattern(name = "EmptyMethodCheck", summary = "Empty methods should be deleted", severity = BugPattern.SeverityLevel.ERROR)
public class EmptyMethodChecker extends BugChecker implements BugChecker.MethodTreeMatcher {
@Override
public Description matchMethod(MethodTree methodTree, VisitorState visitorState) {
if (methodTree.getBody()
.getStatements()
.isEmpty()) {
return describeMatch(methodTree, SuggestedFix.delete(methodTree));
}
return Description.NO_MATCH;
}
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>static-analysis</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>pmd</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -1,37 +1,37 @@
<?xml version="1.0"?>
<ruleset name="Custom ruleset" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
This ruleset checks my code for bad stuff
</description>
<!-- We'll use the entire 'strings' ruleset -->
<rule ref="rulesets/java/strings.xml" />
<!-- Here's some rules we'll specify one at a time -->
<rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable" />
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField" />
<rule ref="rulesets/java/imports.xml/DuplicateImports" />
<rule ref="rulesets/java/basic.xml/UnnecessaryConversionTemporary" />
<!-- We want to customize this rule a bit, change the message and raise
the priority -->
<rule ref="rulesets/java/basic.xml/EmptyCatchBlock" message="Must handle exceptions">
<priority>2</priority>
</rule>
<!-- Now we'll customize a rule's property value -->
<rule ref="rulesets/java/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="5" />
</properties>
</rule>
<!-- We want everything from braces.xml except WhileLoopsMustUseBraces -->
<rule ref="rulesets/java/braces.xml">
<exclude name="WhileLoopsMustUseBraces" />
</rule>
<?xml version="1.0"?>
<ruleset name="Custom ruleset" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
This ruleset checks my code for bad stuff
</description>
<!-- We'll use the entire 'strings' ruleset -->
<rule ref="rulesets/java/strings.xml" />
<!-- Here's some rules we'll specify one at a time -->
<rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable" />
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField" />
<rule ref="rulesets/java/imports.xml/DuplicateImports" />
<rule ref="rulesets/java/basic.xml/UnnecessaryConversionTemporary" />
<!-- We want to customize this rule a bit, change the message and raise
the priority -->
<rule ref="rulesets/java/basic.xml/EmptyCatchBlock" message="Must handle exceptions">
<priority>2</priority>
</rule>
<!-- Now we'll customize a rule's property value -->
<rule ref="rulesets/java/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="5" />
</properties>
</rule>
<!-- We want everything from braces.xml except WhileLoopsMustUseBraces -->
<rule ref="rulesets/java/braces.xml">
<exclude name="WhileLoopsMustUseBraces" />
</rule>
</ruleset>

View File

@ -6,6 +6,7 @@
<artifactId>static-analysis</artifactId>
<version>1.0-SNAPSHOT</version>
<name>static-analysis</name>
<packaging>pom</packaging>
<parent>
<groupId>com.baeldung</groupId>
@ -29,4 +30,15 @@
</plugins>
</reporting>
</project>
<modules>
<module>pmd</module>
<module>my-bugchecker-plugin</module>
<module>error-prone-project</module>
</modules>
<properties>
<error-prone.version>2.23.0</error-prone.version>
<google-auto-service.version>1.0.1</google-auto-service.version>
</properties>
</project>

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