Merge branch 'master' into JAVA-8204

This commit is contained in:
freelansam 2021-11-09 18:20:05 +05:30 committed by GitHub
commit 77e3e6a419
209 changed files with 3217 additions and 1314 deletions

View File

@ -34,11 +34,6 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>${junit-platform.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -19,11 +19,6 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>${junit-platform.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -29,12 +29,6 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -30,12 +30,6 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -12,3 +12,4 @@ This module contains articles about Apache POI
- [Read Excel Cell Value Rather Than Formula With Apache POI](https://www.baeldung.com/apache-poi-read-cell-value-formula)
- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas)
- [Insert a Row in Excel Using Apache POI](https://www.baeldung.com/apache-poi-insert-excel-row)
- [Multiline Text in Excel Cell Using Apache POI](https://www.baeldung.com/apache-poi-write-multiline-text)

View File

@ -0,0 +1,30 @@
package com.baeldung.poi.excel.cellstyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
public class CellStyleHandler {
public void changeCellBackgroundColor(Cell cell) {
CellStyle cellStyle = cell.getCellStyle();
if(cellStyle == null) {
cellStyle = cell.getSheet().getWorkbook().createCellStyle();
}
cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(cellStyle);
}
public void changeCellBackgroundColorWithPattern(Cell cell) {
CellStyle cellStyle = cell.getCellStyle();
if(cellStyle == null) {
cellStyle = cell.getSheet().getWorkbook().createCellStyle();
}
cellStyle.setFillBackgroundColor(IndexedColors.BLACK.index);
cellStyle.setFillPattern(FillPatternType.BIG_SPOTS);
cellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
cell.setCellStyle(cellStyle);
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.poi.excel.cellstyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Before;
import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import static org.junit.Assert.assertEquals;
public class CellStyleHandlerUnitTest {
private static final String FILE_NAME = "cellstyle/CellStyleHandlerTest.xlsx";
private static final int SHEET_INDEX = 0;
private static final int ROW_INDEX = 0;
private static final int CELL_INDEX = 0;
private String fileLocation;
private CellStyleHandler cellStyleHandler;
@Before
public void setup() throws URISyntaxException {
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
cellStyleHandler = new CellStyleHandler();
}
@Test
public void givenWorkbookCell_whenChangeCellBackgroundColor() throws IOException {
Workbook workbook = new XSSFWorkbook(fileLocation);
Sheet sheet = workbook.getSheetAt(SHEET_INDEX);
Row row = sheet.getRow(ROW_INDEX);
Cell cell = row.getCell(CELL_INDEX);
cellStyleHandler.changeCellBackgroundColor(cell);
assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor());
workbook.close();
}
@Test
public void givenWorkbookCell_whenChangeCellBackgroundColorWithPattern() throws IOException {
Workbook workbook = new XSSFWorkbook(fileLocation);
Sheet sheet = workbook.getSheetAt(SHEET_INDEX);
Row row = sheet.getRow(ROW_INDEX);
Cell cell = row.getCell(CELL_INDEX + 1);
cellStyleHandler.changeCellBackgroundColorWithPattern(cell);
assertEquals(IndexedColors.LIGHT_BLUE.index, cell.getCellStyle().getFillForegroundColor());
workbook.close();
}
}

View File

@ -71,12 +71,6 @@
<artifactId>derby</artifactId>
<version>${derby.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- the JTA API -->
<dependency>
<groupId>javax.transaction</groupId>

View File

@ -31,24 +31,6 @@
<artifactId>mockserver-junit-jupiter</artifactId>
<version>${mockserver.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>

View File

@ -21,18 +21,6 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -27,18 +27,6 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -28,18 +28,6 @@
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -23,18 +23,6 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -56,6 +44,7 @@
<version>${surefire.plugin.version}</version>
<configuration>
<argLine>--enable-preview</argLine>
<argLine>--enable-native-access=core.java</argLine>
<forkCount>1</forkCount>
</configuration>
<dependencies>

View File

@ -0,0 +1,20 @@
package com.baeldung.features;
import java.util.random.RandomGeneratorFactory;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class JEP356 {
public Stream<String> getAllAlgorithms() {
return RandomGeneratorFactory.all().map(RandomGeneratorFactory::name);
}
public IntStream getPseudoInts(String algorithm, int streamSize) {
// returns an IntStream with size @streamSize of random numbers generated using the @algorithm
// where the lower bound is 0 and the upper is 100 (exclusive)
return RandomGeneratorFactory.of(algorithm)
.create()
.ints(streamSize, 0,100);
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.features;
import com.baeldung.features.JEP409.Circle;
import com.baeldung.features.JEP409.Shape;
import com.baeldung.features.JEP409.Triangle;
public class JEP406 {
static record Human (String name, int age, String profession) {}
public String checkObject(Object obj) {
return switch (obj) {
case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession());
case Circle c -> "This is a circle";
case Shape s -> "It is just a shape";
case null -> "It is null";
default -> "It is an object";
};
}
public String checkShape(Shape shape) {
return switch (shape) {
case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle";
case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle";
default -> "Just a normal shape";
};
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.features;
public class JEP409 {
sealed interface Shape permits Rectangle, Circle, Square, Triangle {
int getNumberOfSides();
}
static final class Rectangle implements Shape {
@Override
public int getNumberOfSides() {
return 4;
}
}
static final class Circle implements Shape {
@Override
public int getNumberOfSides() {
return 0;
}
}
static final class Square implements Shape {
@Override
public int getNumberOfSides() {
return 4;
}
}
static non-sealed class Triangle implements Shape {
@Override
public int getNumberOfSides() {
return 3;
}
}
}

View File

@ -0,0 +1,56 @@
package com.baeldung.features;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.SymbolLookup;
import java.io.IOException;
import java.lang.invoke.MethodType;
import static jdk.incubator.foreign.ResourceScope.newImplicitScope;
public class JEP412 {
private static final SymbolLookup libLookup;
static {
var resource = JEP412.class.getResource("/compile_c.sh");
try {
var process = new ProcessBuilder("sh", resource.getPath()).start();
while (process.isAlive()) {}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
var path = JEP412.class.getResource("/print_name.so").getPath();
System.load(path);
libLookup = SymbolLookup.loaderLookup();
}
public String getPrintNameFormat(String name){
var printMethod = libLookup.lookup("printName");
if (printMethod.isPresent()) {
var methodReference = CLinker.getInstance()
.downcallHandle(
printMethod.get(),
MethodType.methodType(MemoryAddress.class, MemoryAddress.class),
FunctionDescriptor.of(CLinker.C_POINTER, CLinker.C_POINTER)
);
try {
var nativeString = CLinker.toCString(name, newImplicitScope());
var invokeReturn = methodReference.invoke(nativeString.address());
var memoryAddress = (MemoryAddress) invokeReturn;
return CLinker.toJavaString(memoryAddress);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
throw new RuntimeException("printName function not found.");
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.features;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorSpecies;
public class JEP414 {
private static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
public void newVectorComputation(float[] a, float[] b, float[] c) {
for (var i = 0; i < a.length; i += SPECIES.length()) {
var m = SPECIES.indexInRange(i, a.length);
var va = FloatVector.fromArray(SPECIES, a, i, m);
var vb = FloatVector.fromArray(SPECIES, b, i, m);
var vc = va.mul(vb);
vc.intoArray(c, i, m);
}
}
public void commonVectorComputation(float[] a, float[] b, float[] c) {
for (var i = 0; i < a.length; i ++) {
c[i] = a[i] * b[i];
}
}
}

View File

@ -0,0 +1,4 @@
module core.java {
requires jdk.incubator.vector;
requires jdk.incubator.foreign;
}

View File

@ -0,0 +1,9 @@
#!/bin/bash
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
gcc -c -fPIC $SCRIPTPATH/print_name.c
gcc -shared -rdynamic -o print_name.so print_name.o
mv print_name.so $SCRIPTPATH/
mv print_name.o $SCRIPTPATH/

View File

@ -0,0 +1,8 @@
#include<stdio.h>
#include<stdlib.h>
char* printName(char *name) {
char* newString = (char*)malloc((15 + sizeof(name))*sizeof(char));
sprintf(newString, "Your name is %s", name);
return newString;
}

View File

@ -0,0 +1,19 @@
package com.baeldung.features;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class JEP356UnitTest {
@Test
void getPseudoInts_whenUsingAlgorithmXoroshiro128PlusPlus_shouldReturnStreamOfRandomInteger() {
var algorithm = "Xoshiro256PlusPlus";
var streamSize = 100;
JEP356 jep356 = new JEP356();
jep356.getPseudoInts(algorithm, streamSize)
.forEach(value -> assertThat(value).isLessThanOrEqualTo(99));
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.features;
import com.baeldung.features.JEP406.Human;
import com.baeldung.features.JEP409.Square;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class JEP406UnitTest {
@Test
void checkObject_shouldMatchWithHuman() {
var jep406 = new JEP406();
var human = new Human("John", 31, "Developer");
var checkResult = jep406.checkObject(human);
assertEquals("Name: John, age: 31 and profession: Developer", checkResult);
}
@Test
void checkShape_shouldMatchWithShape() {
var jep406 = new JEP406();
var square = new Square();
var checkResult = jep406.checkShape(square);
assertEquals("Just a normal shape", checkResult);
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.features;
import com.baeldung.features.JEP409.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
class JEP409UnitTest {
static class WeirdTriangle extends Triangle {
@Override public int getNumberOfSides() {
return 40;
}
}
@Test
void testSealedClass_shouldInvokeRightClass() {
Shape shape = spy(new WeirdTriangle());
int numberOfSides = getNumberOfSides(shape);
assertEquals(40, numberOfSides);
verify(shape).getNumberOfSides();
}
int getNumberOfSides(Shape shape) {
return switch (shape) {
case WeirdTriangle t -> t.getNumberOfSides();
case Circle c -> c.getNumberOfSides();
case Triangle t -> t.getNumberOfSides();
case Rectangle r -> r.getNumberOfSides();
case Square s -> s.getNumberOfSides();
};
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.features;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class JEP412UnitTest {
@Test
void getPrintNameFormat_whenPassingAName_shouldReceiveItFormatted() {
var jep412 = new JEP412();
var formattedName = jep412.getPrintNameFormat("John");
assertEquals("Your name is John", formattedName);
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.features;
import org.junit.jupiter.api.Test;
import static java.util.stream.Collectors.toList;
import static org.junit.jupiter.api.Assertions.assertEquals;
class JEP414UnitTest {
@Test
void vectorComputation_shouldMultiplyVectors() {
var jep414 = new JEP414();
float[] a = initArray(100);
float[] b = initArray(100);
float[] c = new float[100];
float[] d = new float[100];
jep414.newVectorComputation(a, b, c);
jep414.commonVectorComputation(a, b, d);
for (int i = 0; i < a.length; i++) {
assertEquals(c[i], d[i]);
}
}
private float[] initArray(int size) {
final var jep356 = new JEP356();
final var values = new float[size];
final var pseudoInts = jep356.getPseudoInts("Xoshiro256PlusPlus", size).mapToObj(Float::valueOf).collect(toList());
for (int i = 0; i < pseudoInts.size(); i++) {
values[i] = pseudoInts.get(i);
}
return values;
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.hexformat;
import java.util.HexFormat;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ByteHexadecimalConversionUnitTest {
private HexFormat hexFormat = HexFormat.of();
@Test
void givenInitialisedHexFormat_whenHexStringIsPassed_thenByteArrayRepresentationIsReturned() {
byte[] hexBytes = hexFormat.parseHex("ABCDEF0123456789");
assertArrayEquals(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119 }, hexBytes);
}
@Test
void givenInitialisedHexFormat_whenByteArrayIsPassed_thenHexStringRepresentationIsReturned() {
String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
assertEquals("abcdef0123456789", bytesAsString);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.hexformat;
import java.util.HexFormat;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PrimitiveTypeHexadecimalConversionUnitTest {
private HexFormat hexFormat = HexFormat.of();
@Test
void givenInitialisedHexFormat_whenPrimitiveByteIsPassed_thenHexStringRepresentationIsReturned() {
String fromByte = hexFormat.toHexDigits((byte)64);
assertEquals("40", fromByte);
}
@Test
void givenInitialisedHexFormat_whenPrimitiveLongIsPassed_thenHexStringRepresentationIsReturned() {
String fromLong = hexFormat.toHexDigits(1234_5678_9012_3456L);
assertEquals("000462d53c8abac0", fromLong);
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.hexformat;
import java.util.HexFormat;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class StringFormattingUnitTest {
private HexFormat hexFormat = HexFormat.of().withPrefix("[").withSuffix("]").withDelimiter(", ");
@Test
public void givenInitialisedHexFormatWithFormattedStringOptions_whenByteArrayIsPassed_thenHexStringRepresentationFormattedCorrectlyIsReturned() {
assertEquals("[48], [0c], [11]", hexFormat.formatHex(new byte[] {72, 12, 17}));
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.hexformat;
import java.util.HexFormat;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class UppercaseLowercaseOutputUnitTest {
@Test
public void givenInitialisedHexFormat_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() {
HexFormat hexFormat = HexFormat.of();
String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
assertTrue(isLowerCase(bytesAsString));
}
@Test
public void givenInitialisedHexFormatWithUpperCaseOption_whenByteArrayIsPassed_thenLowerCaseHexStringRepresentationIsReturned() {
HexFormat hexFormat = HexFormat.of().withUpperCase();
String bytesAsString = hexFormat.formatHex(new byte[] { -85, -51, -17, 1, 35, 69, 103, -119});
assertTrue(isUpperCase(bytesAsString));
}
private boolean isLowerCase(String str) {
char[] charArray = str.toCharArray();
for (int i=0; i < charArray.length; i++) {
if (Character.isUpperCase(charArray[i]))
return false;
}
return true;
}
private boolean isUpperCase(String str) {
char[] charArray = str.toCharArray();
for (int i=0; i < charArray.length; i++) {
if (Character.isLowerCase(charArray[i]))
return false;
}
return true;
}
}

View File

@ -1,34 +1,55 @@
<?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-collections-maps-4</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-collections-maps-4</name>
<packaging>jar</packaging>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-collections-maps-4</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>core-java-collections-maps-4</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<parent>
<groupId>com.baeldung.core-java-modules</groupId>
<artifactId>core-java-modules</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<!-- those tests are not made for CI purposes, but for manual testing -->
<groups>!performance</groups>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest-all.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<!-- those tests are not made for CI purposes, but for manual testing -->
<groups>!performance</groups>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,32 @@
package com.baeldung.nestedhashmaps;
public class Address {
private Integer addressId;
private String addressLocation;
public Address() {
}
public Address(Integer addressId, String addressLocation) {
this.addressId = addressId;
this.addressLocation = addressLocation;
}
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
public String getAddressLocation() {
return addressLocation;
}
public void setAddressLocation(String addressLocation) {
this.addressLocation = addressLocation;
}
}

View File

@ -0,0 +1,43 @@
package com.baeldung.nestedhashmaps;
public class Employee {
private Integer employeeId;
private Address address;
private String employeeName;
public Employee() {
super();
}
public Employee(Integer employeeId, Address address, String employeeName) {
this.employeeId = employeeId;
this.address = address;
this.employeeName = employeeName;
}
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
}

View File

@ -0,0 +1,57 @@
package com.baeldung.nestedhashmaps;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public class MapsUtil {
MapsUtil() {
super();
}
public Map<Integer, String> buildInnerMap(List<String> batterList) {
Map<Integer, String> innerBatterMap = new HashMap<Integer, String>();
int index = 1;
for (String item : batterList) {
innerBatterMap.put(index, item);
index++;
}
return innerBatterMap;
}
public Map<Integer, Map<String, String>> createNestedMapfromStream(List<Employee> listEmployee) {
Map<Integer, Map<String, String>> employeeAddressMap = listEmployee.stream()
.collect(Collectors.groupingBy(e -> e.getAddress().getAddressId(),
Collectors.toMap(f -> f.getAddress().getAddressLocation(), Employee::getEmployeeName)));
return employeeAddressMap;
}
public Map<Integer, Map<Integer, Address>> createNestedObjectMap(List<Employee> listEmployee) {
Map<Integer, Map<Integer, Address>> employeeMap = new HashMap<>();
employeeMap = listEmployee.stream().collect(Collectors.groupingBy((Employee emp) -> emp.getEmployeeId(),
Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress())));
return employeeMap;
}
public Map<String, String> flattenMap(Map<?, ?> source) {
Map<String, String> converted = new HashMap<>();
for (Entry<?, ?> entry : source.entrySet()) {
if (entry.getValue() instanceof Map) {
flattenMap((Map<String, Object>) entry.getValue())
.forEach((key, value) -> converted.put(entry.getKey() + "." + key, value));
} else {
converted.put(entry.getKey().toString(), entry.getValue().toString());
}
}
return converted;
}
}

View File

@ -0,0 +1,118 @@
package com.baeldung.nestedhashmaps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
public class NestedHashMapExamplesClass {
public static void main(String[] args) {
MapsUtil mUtil = new MapsUtil();
List<String> batterList = new ArrayList<>();
Map<String, Map<Integer, String>> outerBakedGoodsMap = new HashMap<>();
Map<String, Map<Integer, String>> outerBakedGoodsMap2 = new HashMap<>();
Map<String, Map<Integer, String>> outerBakedGoodsMap3 = new HashMap<>();
Map<String, Map<Integer, String>> outerBakedGoodsMap4 = new HashMap<>();
batterList.add("Mulberry");
batterList.add("Cranberry");
batterList.add("Blackberry");
batterList.add("Mixed fruit");
batterList.add("Orange");
outerBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList));
batterList.clear();
batterList.add("Candy");
batterList.add("Dark Chocolate");
batterList.add("Chocolate");
batterList.add("Jam filled");
batterList.add("Pineapple");
outerBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList));
outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList));
outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList));
outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList));
batterList.clear();
batterList.add("Banana");
batterList.add("Red Velvet");
batterList.add("Blackberry");
batterList.add("Passion fruit");
batterList.add("Kiwi");
outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList));
outerBakedGoodsMap4.putAll(outerBakedGoodsMap);
System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap2));
System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap3));
System.out.println(outerBakedGoodsMap.equals(outerBakedGoodsMap4));
outerBakedGoodsMap.get("Cake")
.put(6, "Cranberry");
System.out.println(outerBakedGoodsMap);
outerBakedGoodsMap.get("Cake")
.remove(5);
System.out.println(outerBakedGoodsMap);
outerBakedGoodsMap.put("Eclair", new HashMap<Integer, String>() {
{
put(1, "Dark Chocolate");
}
});
System.out.println(outerBakedGoodsMap);
outerBakedGoodsMap.remove("Eclair");
System.out.println(outerBakedGoodsMap);
System.out.println("Baked Goods Map Flattened: " + mUtil.flattenMap(outerBakedGoodsMap));
// Employees Map
List<Employee> listEmployee = new ArrayList<Employee>();
listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
listEmployee.add(new Employee(3, new Address(156, "Bramles Lane"), "Bofur"));
listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
Map<Integer, Map<String, String>> employeeAddressMap = mUtil.createNestedMapfromStream(listEmployee);
Map<Integer, Map<Integer, Address>> employeeMap = mUtil.createNestedObjectMap(listEmployee);
Map<Integer, Map<Integer, Address>> employeeMap2 = mUtil.createNestedObjectMap(listEmployee);
listEmployee.clear();
listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield"));
listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin"));
listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur"));
listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins"));
listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond"));
Map<Integer, Map<String, String>> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee);
Map<Integer, Map<Integer, Address>> employeeMap1 = mUtil.createNestedObjectMap(listEmployee);
System.out.println(employeeMap.equals(employeeMap1));
System.out.println(employeeMap.equals(employeeMap2));
for (Map.Entry<String, Map<Integer, String>> outerBakedGoodsMapEntrySet : outerBakedGoodsMap.entrySet()) {
Map<Integer, String> valueMap = outerBakedGoodsMapEntrySet.getValue();
System.out.println(valueMap.entrySet());
}
for (Map.Entry<Integer, Map<String, String>> employeeEntrySet : employeeAddressMap.entrySet()) {
Map<String, String> valueMap = employeeEntrySet.getValue();
System.out.println(valueMap.entrySet());
}
System.out.println("Employee Address Map Flattened: " + mUtil.flattenMap(employeeAddressMap));
System.out.println(employeeAddressMap.equals(employeeAddressMap1));
}
}

View File

@ -0,0 +1,243 @@
package com.baeldung.nestedhashmaps;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertThat;
import org.hamcrest.collection.IsMapContaining;
public class NestedHashMapExamplesClassUnitTest {
private MapsUtil mUtil = new MapsUtil();
private List<String> batterList = new ArrayList<>();
private List<Employee> listEmployee = new ArrayList<Employee>();
private Map<String, Map<Integer, String>> actualBakedGoodsMap = new HashMap<>();
private Map<Integer, Map<String, String>> actualEmployeeAddressMap = new HashMap<>();
private Map<Integer, Map<Integer, Address>> actualEmployeeMap = new HashMap<>();
@Test
public void whenCreateNestedHashMap_thenNestedMap() {
assertThat(mUtil.buildInnerMap(batterList), is(notNullValue()));
Assert.assertEquals(actualBakedGoodsMap.keySet().size(), 2);
Assert.assertThat(actualBakedGoodsMap, IsMapContaining.hasValue(equalTo(mUtil.buildInnerMap(batterList))));
}
private Map<Integer, Map<String, String>> setup() {
Map<Integer, Map<String, String>> expectedMap = new HashMap<>();
expectedMap.put(Integer.valueOf(100), new HashMap<String, String>() {
{
put("Misty Lanes", "Balin");
}
});
expectedMap.put(Integer.valueOf(200), new HashMap<String, String>() {
{
put("Bag End", "Bilbo Baggins");
}
});
expectedMap.put(Integer.valueOf(156), new HashMap<String, String>() {
{
put("Brambles Lane", "Bofur");
}
});
expectedMap.put(Integer.valueOf(124), new HashMap<String, String>() {
{
put("Timbuktoo", "Thorin Oakenshield");
}
});
expectedMap.put(Integer.valueOf(23), new HashMap<String, String>() {
{
put("Rivendell", "Elrond");
}
});
return expectedMap;
}
@Test
public void whenCreateNestedHashMapwithStreams_thenNestedMap() {
Map<Integer, Map<String, String>> expectedMap = setup();
assertThat(actualEmployeeAddressMap, equalTo(expectedMap));
}
@Test
public void whenCompareTwoHashMapswithDifferenctValues_usingEquals_thenFail() {
Map<String, Map<Integer, String>> outerBakedGoodsMap2 = new HashMap<>();
outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList));
outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList));
assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap);
Map<String, Map<Integer, String>> outerBakedGoodsMap3 = new HashMap<String, Map<Integer, String>>();
outerBakedGoodsMap3.put("Cake", mUtil.buildInnerMap(batterList));
batterList = new ArrayList<>();
batterList = Arrays.asList("Banana", "Red Velvet", "Blackberry", "Passion fruit", "Kiwi");
outerBakedGoodsMap3.put("Donut", mUtil.buildInnerMap(batterList));
assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap);
listEmployee.clear();
listEmployee.add(new Employee(1, new Address(500, "Timbuktoo"), "Thorin Oakenshield"));
listEmployee.add(new Employee(2, new Address(600, "Misty Lanes"), "Balin"));
listEmployee.add(new Employee(3, new Address(700, "Bramles Lane"), "Bofur"));
listEmployee.add(new Employee(4, new Address(800, "Bag End"), "Bilbo Baggins"));
listEmployee.add(new Employee(5, new Address(900, "Rivendell"), "Elrond"));
Map<Integer, Map<String, String>> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee);
Map<Integer, Map<Integer, Address>> employeeMap1 = mUtil.createNestedObjectMap(listEmployee);
assertNotEquals(employeeAddressMap1, actualEmployeeAddressMap);
assertNotEquals(employeeMap1, actualEmployeeMap);
}
@Test
public void whencomparingDifferentObjectValuesUsingEquals_thenFail() {
listEmployee.clear();
listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur"));
listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
Map<Integer, Map<Integer, Object>> employeeMap1 = listEmployee.stream().collect(Collectors.groupingBy(
(Employee emp) -> emp.getEmployeeId(),
Collectors.toMap((Employee emp) -> emp.getAddress().getAddressId(), fEmpObj -> fEmpObj.getAddress())));
assertNotSame(employeeMap1, actualEmployeeMap);
assertNotEquals(employeeMap1, actualEmployeeMap);
Map<Integer, Map<Integer, Address>> expectedMap = setupAddressObjectMap();
assertNotSame(expectedMap, actualEmployeeMap);
assertNotEquals(expectedMap, actualEmployeeMap);
}
@Test
public void whenCompareTwoHashMapsUsingEquals_thenSuccess() {
Map<String, Map<Integer, String>> outerBakedGoodsMap4 = new HashMap<>();
outerBakedGoodsMap4.putAll(actualBakedGoodsMap);
assertEquals(actualBakedGoodsMap, outerBakedGoodsMap4);
Map<Integer, Map<Integer, Address>> employeeMap1 = new HashMap<>();
employeeMap1.putAll(actualEmployeeMap);
assertEquals(actualEmployeeMap, employeeMap1);
}
@Test
public void whenAddElementinHashMaps_thenSuccess() {
assertEquals(actualBakedGoodsMap.get("Cake").size(), 5);
actualBakedGoodsMap.get("Cake").put(6, "Cranberry");
assertEquals(actualBakedGoodsMap.get("Cake").size(), 6);
}
@Test
public void whenDeleteElementinHashMaps_thenSuccess() {
assertNotEquals(actualBakedGoodsMap.get("Cake").get(5), null);
actualBakedGoodsMap.get("Cake").remove(5);
assertEquals(actualBakedGoodsMap.get("Cake").get(5), null);
actualBakedGoodsMap.put("Eclair", new HashMap<Integer, String>() {
{
put(1, "Dark Chocolate");
}
});
assertNotEquals(actualBakedGoodsMap.get("Eclair").get(1), null);
actualBakedGoodsMap.get("Eclair").remove(1);
assertEquals(actualBakedGoodsMap.get("Eclair").get(1), null);
actualBakedGoodsMap.put("Eclair", new HashMap<Integer, String>() {
{
put(1, "Dark Chocolate");
}
});
assertNotEquals(actualBakedGoodsMap.get("Eclair"), null);
actualBakedGoodsMap.remove("Eclair");
assertEquals(actualBakedGoodsMap.get("Eclair"), null);
}
@Test
public void whenFlattenMap_thenRemovesNesting() {
Map<String, String> flattenedBakedGoodsMap = mUtil.flattenMap(actualBakedGoodsMap);
assertThat(flattenedBakedGoodsMap, IsMapContaining.hasKey("Donut.2"));
Map<String, String> flattenedEmployeeAddressMap = mUtil.flattenMap(actualEmployeeAddressMap);
assertThat(flattenedEmployeeAddressMap, IsMapContaining.hasKey("200.Bag End"));
}
@Before
public void buildMaps() {
batterList = Arrays.asList("Mulberry", "Cranberry", "Blackberry", "Mixed fruit", "Orange");
actualBakedGoodsMap.put("Cake", mUtil.buildInnerMap(batterList));
batterList = new ArrayList<>();
batterList = Arrays.asList("Candy", "Dark Chocolate", "Chocolate", "Jam filled", "Pineapple");
actualBakedGoodsMap.put("Donut", mUtil.buildInnerMap(batterList));
listEmployee.add(new Employee(1, new Address(124, "Timbuktoo"), "Thorin Oakenshield"));
listEmployee.add(new Employee(2, new Address(100, "Misty Lanes"), "Balin"));
listEmployee.add(new Employee(3, new Address(156, "Brambles Lane"), "Bofur"));
listEmployee.add(new Employee(4, new Address(200, "Bag End"), "Bilbo Baggins"));
listEmployee.add(new Employee(5, new Address(23, "Rivendell"), "Elrond"));
actualEmployeeAddressMap = mUtil.createNestedMapfromStream(listEmployee);
actualEmployeeMap = mUtil.createNestedObjectMap(listEmployee);
}
private Map<Integer, Map<Integer, Address>> setupAddressObjectMap() {
Map<Integer, Map<Integer, Address>> expectedMap = new HashMap<>();
expectedMap.put(1, new HashMap<Integer, Address>() {
{
put(124, new Address(124, "Timbuktoo"));
}
});
expectedMap.put(2, new HashMap<Integer, Address>() {
{
put(100, new Address(100, "Misty Lanes"));
}
});
expectedMap.put(3, new HashMap<Integer, Address>() {
{
put(156, new Address(156, "Brambles Lane"));
}
});
expectedMap.put(4, new HashMap<Integer, Address>() {
{
put(200, new Address(200, "Bag End"));
}
});
expectedMap.put(5, new HashMap<Integer, Address>() {
{
put(23, new Address(23, "Rivendell"));
}
});
return expectedMap;
}
}

View File

@ -15,11 +15,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.googlecode.thread-weaver</groupId>
<artifactId>threadweaver</artifactId>
@ -31,6 +26,12 @@
<artifactId>tempus-fugit</artifactId>
<version>${tempus-fugit.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.multithreadedtc</groupId>

View File

@ -2,3 +2,4 @@
### Relevant Articles:
- [Java Naming and Directory Interface Overview](https://www.baeldung.com/jndi)
- [LDAP Authentication Using Pure Java](https://www.baeldung.com/java-ldap-auth)

View File

@ -15,23 +15,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
@ -58,6 +41,18 @@
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-test-framework</artifactId>
<version>${apacheds.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -76,6 +71,7 @@
<properties>
<spring.version>5.0.9.RELEASE</spring.version>
<h2.version>1.4.199</h2.version>
<apacheds.version>2.0.0.AM26</apacheds.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
</properties>

View File

@ -0,0 +1,165 @@
package com.baeldung.jndi.ldap.auth;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ApplyLdifFiles;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(FrameworkRunner.class)
@CreateLdapServer(transports = { @CreateTransport(protocol = "LDAP", address = "localhost", port = 10390)})
@CreateDS(
allowAnonAccess = false, partitions = {@CreatePartition(name = "TestPartition", suffix = "dc=baeldung,dc=com")})
@ApplyLdifFiles({"users.ldif"})
// class marked as manual test, as it has to run independently from the other unit tests in the module
public class JndiLdapAuthManualTest extends AbstractLdapTestUnit {
private static void authenticateUser(Hashtable<String, String> environment) throws Exception {
DirContext context = new InitialDirContext(environment);
context.close();
}
@Test
public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
environment.put(Context.SECURITY_CREDENTIALS, "12345");
assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
}
@Test
public void givenPreloadedLDAPUserJoe_whenAuthUserWithWrongPW_thenAuthFails() throws Exception {
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, "cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
environment.put(Context.SECURITY_CREDENTIALS, "wronguserpw");
assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
}
@Test
public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception {
// first authenticate against LDAP as admin to search up DN of user : Joe Simms
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
environment.put(Context.SECURITY_CREDENTIALS, "secret");
DirContext adminContext = new InitialDirContext(environment);
// define the search filter to find the person with CN : Joe Simms
String filter = "(&(objectClass=person)(cn=Joe Simms))";
// declare the attributes we want returned for the object being searched
String[] attrIDs = { "cn" };
// define the search controls
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(attrIDs);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// search for User with filter cn=Joe Simms
NamingEnumeration<SearchResult> searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
if (searchResults.hasMore()) {
SearchResult result = (SearchResult) searchResults.next();
Attributes attrs = result.getAttributes();
String distinguishedName = result.getNameInNamespace();
assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
String commonName = attrs.get("cn").toString();
assertThat(commonName).isEqualTo("cn: Joe Simms");
// authenticate new context with DN for user Joe Simms, using correct password
environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
environment.put(Context.SECURITY_CREDENTIALS, "12345");
assertThatCode(() -> authenticateUser(environment)).doesNotThrowAnyException();
}
adminContext.close();
}
@Test
public void givenPreloadedLDAPUserJoe_whenSearchAndAuthUserWithWrongPW_thenAuthFails() throws Exception {
// first authenticate against LDAP as admin to search up DN of user : Joe Simms
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.put(Context.PROVIDER_URL, "ldap://localhost:10390");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
environment.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
environment.put(Context.SECURITY_CREDENTIALS, "secret");
DirContext adminContext = new InitialDirContext(environment);
// define the search filter to find the person with CN : Joe Simms
String filter = "(&(objectClass=person)(cn=Joe Simms))";
// declare the attributes we want returned for the object being searched
String[] attrIDs = { "cn" };
// define the search controls
SearchControls searchControls = new SearchControls();
searchControls.setReturningAttributes(attrIDs);
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// search for User with filter cn=Joe Simms
NamingEnumeration<SearchResult> searchResults = adminContext.search("dc=baeldung,dc=com", filter, searchControls);
if (searchResults.hasMore()) {
SearchResult result = (SearchResult) searchResults.next();
Attributes attrs = result.getAttributes();
String distinguishedName = result.getNameInNamespace();
assertThat(distinguishedName).isEqualTo("cn=Joe Simms,ou=Users,dc=baeldung,dc=com");
String commonName = attrs.get("cn").toString();
assertThat(commonName).isEqualTo("cn: Joe Simms");
// authenticate new context with DN for user Joe Simms, using wrong password
environment.put(Context.SECURITY_PRINCIPAL, distinguishedName);
environment.put(Context.SECURITY_CREDENTIALS, "wronguserpassword");
assertThatExceptionOfType(AuthenticationException.class).isThrownBy(() -> authenticateUser(environment));
}
adminContext.close();
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -0,0 +1,20 @@
version: 1
dn: dc=baeldung,dc=com
objectClass: domain
objectClass: top
dc: baeldung
dn: ou=Users,dc=baeldung,dc=com
objectClass: organizationalUnit
objectClass: top
ou: Users
dn: cn=Joe Simms,ou=Users,dc=baeldung,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
cn: Joe Simms
sn: Simms
uid: user1
userPassword: 12345

View File

@ -15,11 +15,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
@ -31,11 +26,23 @@
<artifactId>jol-core</artifactId>
<version>${jol-core.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
<properties>
<assertj.version>3.6.1</assertj.version>
<jol-core.version>0.10</jol-core.version>
<reflections.version>0.10.2</reflections.version>
<guava.version>31.0.1-jre</guava.version>
</properties>
</project>
</project>

View File

@ -0,0 +1,35 @@
package com.baeldung.loadedclasslisting;
import java.io.IOException;
import java.util.Set;
import java.util.stream.Collectors;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
public class ListLoadedClass {
public ImmutableSet<ClassInfo> listClassLoaded() throws IOException {
return ClassPath.from(ListLoadedClass.class.getClassLoader())
.getAllClasses();
}
public Set<Class> listClassLoaded(String packageName) throws IOException {
return ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream()
.filter(clazz -> clazz.getPackageName().equals(packageName))
.map(ClassInfo::load)
.collect(Collectors.toSet());
}
public Set<Class> findAllClassesUsingReflectionsLibrary(String packageName) {
Reflections reflections = new Reflections(packageName, new SubTypesScanner(false));
return reflections.getSubTypesOf(Object.class)
.stream()
.collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.loadedclasslisting;
import java.io.IOException;
import java.util.Set;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import com.baeldung.loadedclasslisting.ListLoadedClass;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
public class ListLoadedClassUnitTest {
private static final String PACKAGE_NAME = "com.baeldung.loadedclasslisting";
@Test
public void when_findAllClassesUsingReflectionsLibrary_thenSuccess() {
ListLoadedClass instance = new ListLoadedClass();
Set<Class> classes = instance.findAllClassesUsingReflectionsLibrary(PACKAGE_NAME);
Assertions.assertEquals(4, classes.size());
}
@Test
public void when_findAllClassesUsingGuavaLibrary_InPackage_thenSuccess() throws IOException {
ListLoadedClass instance = new ListLoadedClass();
Set<Class> classes = instance.listClassLoaded(PACKAGE_NAME);
Assertions.assertEquals(4, classes.size());
}
@Test
public void when_findAllClassesUsingGuavaLibrary_thenSuccess() throws IOException {
ListLoadedClass instance = new ListLoadedClass();
Set<ClassInfo> classes = instance.listClassLoaded();
Assertions.assertTrue(4<classes.size());
}
}

View File

@ -15,11 +15,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>

View File

@ -0,0 +1,34 @@
package com.baeldung.constructorchaining;
import java.util.Objects;
public class Customer extends Person {
private final String loyaltyCardId;
public Customer(String firstName, String lastName, int age, String loyaltyCardId) {
this(firstName, null, lastName, age, loyaltyCardId);
}
public Customer(String firstName, String middleName, String lastName, int age, String loyaltyCardId) {
super(firstName, middleName, lastName, age);
this.loyaltyCardId = loyaltyCardId;
}
public String getLoyaltyCardId() {
return loyaltyCardId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Customer customer = (Customer) o;
return Objects.equals(loyaltyCardId, customer.loyaltyCardId);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), loyaltyCardId);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.constructorchaining;
import java.util.Objects;
public class Person {
private final String firstName;
private final String middleName;
private final String lastName;
private final int age;
public Person(String firstName, String lastName, int age) {
this(firstName, null, lastName, age);
}
public Person(String firstName, String middleName, String lastName, int age) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getMiddleName() {
return middleName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(firstName, person.firstName) && Objects.equals(middleName, person.middleName) && Objects.equals(lastName, person.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, middleName, lastName, age);
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.constructorchaining;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class CustomerUnitTest {
@Test
public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() {
Customer mark = new Customer("Mark", "Johnson", 23, "abcd1234");
assertEquals(23, mark.getAge());
assertEquals("Mark", mark.getFirstName());
assertEquals("Johnson", mark.getLastName());
assertEquals("abcd1234", mark.getLoyaltyCardId());
assertNull(mark.getMiddleName());
}
@Test
public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() {
Customer mark = new Customer("Mark", "Andrew", "Johnson", 23, "abcd1234");
assertEquals(23, mark.getAge());
assertEquals("Mark", mark.getFirstName());
assertEquals("Andrew", mark.getMiddleName());
assertEquals("Johnson", mark.getLastName());
assertEquals("abcd1234", mark.getLoyaltyCardId());
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.constructorchaining;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class PersonUnitTest {
@Test
public void givenNameLastNameAndAge_whenUsingDedicatedConstructor_shouldInitializeFieldsAndNullifyMiddleName() {
Person mark = new Person("Mark", "Johnson", 23);
assertEquals(23, mark.getAge());
assertEquals("Mark", mark.getFirstName());
assertEquals("Johnson", mark.getLastName());
assertNull(mark.getMiddleName());
}
@Test
public void givenAllFieldsRequired_whenUsingDedicatedConstructor_shouldInitializeAllFields() {
Person mark = new Person("Mark", "Andrew", "Johnson", 23);
assertEquals(23, mark.getAge());
assertEquals("Mark", mark.getFirstName());
assertEquals("Andrew", mark.getMiddleName());
assertEquals("Johnson", mark.getLastName());
}
}

View File

@ -35,11 +35,6 @@
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>

View File

@ -15,51 +15,45 @@
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</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>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</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>
</dependencies>
<dependencies>
<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>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</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>
</dependencies>
<build>
<finalName>core-java-os</finalName>

View File

@ -0,0 +1,86 @@
package com.baeldung.crypto;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.GeneralSecurityException;
import com.baeldung.crypto.utils.CryptoUtils;
public class CryptoDriver {
public byte[] ecbEncrypt(SecretKey key, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
public byte[] ecbDecrypt(SecretKey key, byte[] cipherText) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
public byte[] cbcEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public byte[] cbcDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public byte[] cfbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public byte[] cfbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public byte[] ofbEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public byte[] ofbDecrypt(SecretKey key, IvParameterSpec iv, byte[] cipherText) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/OFB32/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public byte[][] ctrEncrypt(SecretKey key, IvParameterSpec iv, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return new byte[][] { cipher.getIV(), cipher.doFinal(data) };
}
public byte[] ctrDecrypt(SecretKey key, byte[] iv, byte[] cipherText) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return cipher.doFinal(cipherText);
}
public byte[][] gcmEncrypt(SecretKey key, byte[] iv, byte[] data) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] ciphertext = cipher.doFinal(data);
return new byte[][] { iv, ciphertext };
}
public byte[] gcmDecrypt(SecretKey key, byte[] iv, byte[] ciphertext) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] plaintext = cipher.doFinal(ciphertext);
return plaintext;
}
}

View File

@ -0,0 +1,53 @@
package com.baeldung.crypto.utils;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
public class CryptoUtils {
public static SecretKey generateKey() throws GeneralSecurityException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
return keyGenerator.generateKey();
}
public static IvParameterSpec getIV() {
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[128 / 8];
byte[] nonce = new byte[96 / 8];
secureRandom.nextBytes(nonce);
System.arraycopy(nonce, 0, iv, 0, nonce.length);
return new IvParameterSpec(nonce);
}
public static IvParameterSpec getIVSecureRandom(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {
SecureRandom random = SecureRandom.getInstanceStrong();
byte[] iv = new byte[Cipher.getInstance(algorithm)
.getBlockSize()];
random.nextBytes(iv);
return new IvParameterSpec(iv);
}
public static IvParameterSpec getIVInternal(Cipher cipher) throws InvalidParameterSpecException {
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class)
.getIV();
return new IvParameterSpec(iv);
}
public static byte[] getRandomIVWithSize(int size) {
byte[] nonce = new byte[size];
new SecureRandom().nextBytes(nonce);
return nonce;
}
}

View File

@ -0,0 +1,86 @@
package com.baeldung.crypto;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.GeneralSecurityException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.baeldung.crypto.utils.CryptoUtils;
public class CryptoDriverIVUnitTest{
private CryptoDriver driver = new CryptoDriver();
private String TEST_DATA = "Encrypt this for testing";
@Test
public void givenString_whenAesEcb_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
byte[] plaintext = TEST_DATA.getBytes();
byte[] ciphertext = driver.ecbEncrypt(key, plaintext);
byte[] decryptedtext = driver.ecbDecrypt(key, ciphertext);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
@Test
public void givenString_whenAesCbc_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES");
byte[] plaintext = TEST_DATA.getBytes();
byte[] ciphertext = driver.cbcEncrypt(key, iv, plaintext);
byte[] decryptedtext = driver.cbcDecrypt(key, iv, ciphertext);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
@Test
public void givenString_whenAesCfb_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CFB/NoPadding");
byte[] plaintext = TEST_DATA.getBytes();
byte[] ciphertext = driver.cfbEncrypt(key, iv, plaintext);
byte[] decryptedtext = driver.cfbDecrypt(key, iv, ciphertext);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
@Test
public void givenString_whenAesOfb_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/OFB32/PKCS5Padding");
byte[] plaintext = TEST_DATA.getBytes();
byte[] ciphertext = driver.ofbEncrypt(key, iv, plaintext);
byte[] decryptedtext = driver.ofbDecrypt(key, iv, ciphertext);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
@Test
public void givenString_whenAesCtr_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CTR/NoPadding");
byte[] plaintext = TEST_DATA.getBytes();
byte[][] ciphertext = driver.ctrEncrypt(key, iv, plaintext);
byte[] decryptedtext = driver.ctrDecrypt(key, ciphertext[0], ciphertext[1]);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
@Test
void givenString_whenAesGcm_thenSuccess() throws GeneralSecurityException {
SecretKey key = CryptoUtils.generateKey();
byte[] iv = CryptoUtils.getRandomIVWithSize(12);
byte[] plaintext = (TEST_DATA).getBytes();
byte[][] ciphertext = driver.gcmEncrypt(key, iv, plaintext);
byte[] decryptedtext = driver.gcmDecrypt(key, ciphertext[0], ciphertext[1]);
Assertions.assertEquals(new String(decryptedtext), TEST_DATA);
}
}

View File

@ -30,11 +30,6 @@
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -0,0 +1,32 @@
package com.baeldung.isuppercase;
import com.google.common.base.Ascii;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.matchesPattern;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class StringFirstCharacterUppercase {
@Test
public void givenString_whenCheckingWithCharacterIsUpperCase_thenStringCapitalized() {
String example = "Katie";
Assertions.assertTrue(Character.isUpperCase(example.charAt(0)));
}
@Test
public void givenString_whenCheckingWithRegex_thenStringCapitalized() {
String example = "Katie";
String regEx = "[A-Z]\\w*";
assertThat(example, matchesPattern(regEx));
}
@Test
public void givenString_whenCheckingWithGuava_thenStringCapitalized() {
String example = "Katie";
Assertions.assertTrue(Ascii.isUpperCase(example.charAt(0)));
}
}

View File

@ -26,11 +26,6 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>

View File

@ -20,11 +20,6 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>

View File

@ -7,3 +7,5 @@
- [Validate String as Filename in Java](https://www.baeldung.com/java-validate-filename)
- [Count Spaces in a Java String](https://www.baeldung.com/java-string-count-spaces)
- [Remove Accents and Diacritics From a String in Java](https://www.baeldung.com/java-remove-accents-from-text)
- [Remove Beginning and Ending Double Quotes from a String](https://www.baeldung.com/java-remove-start-end-double-quote)
- [Splitting a Java String by Multiple Delimiters](https://www.baeldung.com/java-string-split-multiple-delimiters)

View File

@ -0,0 +1,20 @@
package com.baeldung.firstword;
public class FirstWordGetter {
public static void main(String[] args) {
String input = "Roberto \"I wish you a bug-free day\"";
System.out.println("Using split: " + getFirstWordUsingSplit(input));
System.out.println("Using subString: " + getFirstWordUsingSubString(input));
}
public static String getFirstWordUsingSubString(String input) {
int index = input.contains(" ") ? input.indexOf(" ") : 0;
return input.substring(0, index);
}
public static String getFirstWordUsingSplit(String input) {
String[] tokens = input.split(" ", 2);
return tokens[0];
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.firstword;
import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSplit;
import static com.baeldung.firstword.FirstWordGetter.getFirstWordUsingSubString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class FirstWordGetterUnitTest {
@Test
public void givenString_whenSplit_thenFirstWordIsReturned() {
assertEquals("Roberto", getFirstWordUsingSplit("Roberto \"I wish you a bug-free day\""));
}
@Test
public void givenStringWithNoSpace_whenSplit_thenFirstWordIsReturned() {
assertEquals("StringWithNoSpace", getFirstWordUsingSplit("StringWithNoSpace"));
}
@Test
public void givenString_whenPassedToSubstring_thenFirstWordIsReturned() {
assertEquals("Roberto", getFirstWordUsingSubString("Roberto \"I wish you a bug-free day\""));
}
@Test
public void givenStringWithNoSpace_whenPassedToSubstring_thenFirstWordIsReturned() {
assertEquals("", getFirstWordUsingSubString("StringWithNoSpace"));
}
}

View File

@ -17,7 +17,7 @@ public class MultipleDelimitersSplitUnitTest {
@Test
public void givenString_whenSplittingByMultipleDelimitersWithRegEx_thenStringSplit() {
String example = "Mary;Thomas:Jane-Kate";
String[] names = example.split(";|:|-");
String[] names = example.split("[;:-]");
String[] expectedNames = new String[]{"Mary", "Thomas", "Jane", "Kate"};
Assertions.assertEquals(4, names.length);
Assertions.assertArrayEquals(expectedNames, names);
@ -38,7 +38,7 @@ public class MultipleDelimitersSplitUnitTest {
String example = "Mary;Thomas:Jane-Kate";
String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"};
Iterable<String> expected = Arrays.asList(expectedArray);
Iterable<String> names = Splitter.on(Pattern.compile(";|:|-")).split(example);
Iterable<String> names = Splitter.on(Pattern.compile("[;:-]")).split(example);
Assertions.assertEquals(4, Iterators.size(names.iterator()));
Assertions.assertIterableEquals(expected, names);
}
@ -48,7 +48,7 @@ public class MultipleDelimitersSplitUnitTest {
String example = "Mary;Thomas:Jane-Kate";
String[] expectedArray = new String[]{"Mary", "Thomas", "Jane", "Kate"};
Iterable<String> expected = Arrays.asList(expectedArray);
Iterable<String> names = Splitter.onPattern(";|:|-").split(example);
Iterable<String> names = Splitter.onPattern("[;:-]").split(example);
Assertions.assertEquals(4, Iterators.size(names.iterator()));
Assertions.assertIterableEquals(expected, names);
}

View File

@ -74,8 +74,8 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<argLine>
-javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
@ -96,8 +96,6 @@
<asspectj.version>1.8.9</asspectj.version>
<powermock.version>2.0.7</powermock.version>
<jmockit.version>1.44</jmockit.version>
<!-- plugins -->
<maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
</properties>
</project>

View File

@ -61,6 +61,11 @@
<artifactId>moneta</artifactId>
<version>${javamoney.moneta.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.core.version}</version>
</dependency>
</dependencies>
<build>
@ -187,6 +192,7 @@
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<source.version>1.8</source.version>
<target.version>1.8</target.version>
<spring.core.version>4.3.20.RELEASE</spring.core.version>
</properties>
</project>

View File

@ -0,0 +1,44 @@
package com.baeldung.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class MySerializationUtils {
public static <T extends Serializable> byte[] serialize(T obj) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
oos.close();
return baos.toByteArray();
}
public static <T extends Serializable> T deserialize(byte[] b, Class<T> cl) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(bais);
Object o = ois.readObject();
return cl.cast(o);
}
public static boolean isSerializable(Class<?> it) {
boolean serializable = it.isPrimitive() || it.isInterface() || Serializable.class.isAssignableFrom(it);
if (!serializable) {
return serializable;
}
Field[] declaredFields = it.getDeclaredFields();
for (Field field : declaredFields) {
if (Modifier.isVolatile(field.getModifiers()) || Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
continue;
}
Class<?> fieldType = field.getType();
return isSerializable(fieldType);
}
return serializable;
}
}

View File

@ -0,0 +1,111 @@
package com.baeldung.serialization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.apache.commons.lang3.SerializationUtils;
import org.junit.Test;
import com.baeldung.util.MySerializationUtils;
public class SerializationUnitTest {
@Test(expected = NotSerializableException.class)
public void whenSerializing_ThenThrowsError() throws IOException {
Address address = new Address();
address.setHouseNumber(10);
FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt");
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
objectOutputStream.writeObject(address);
}
}
@Test
public void whenSerializingAndDeserializing_ThenObjectIsTheSame() throws IOException, ClassNotFoundException {
Person p = new Person();
p.setAge(20);
p.setName("Joe");
FileOutputStream fileOutputStream = new FileOutputStream("yofile.txt");
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
objectOutputStream.writeObject(p);
}
FileInputStream fileInputStream = new FileInputStream("yofile.txt");
try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
Person p2 = (Person) objectInputStream.readObject();
assertEquals(p2.getAge(), p.getAge());
assertEquals(p2.getName(), p.getName());
}
}
@Test(expected = ClassCastException.class)
public void whenSerializingUsingApacheCommons_ThenThrowsError() {
Address address = new Address();
address.setHouseNumber(10);
SerializationUtils.serialize((Serializable) address);
}
@Test
public void whenSerializingAndDeserializingUsingApacheCommons_ThenObjectIsTheSame() {
Person p = new Person();
p.setAge(20);
p.setName("Joe");
byte[] serialize = SerializationUtils.serialize(p);
Person p2 = (Person) SerializationUtils.deserialize(serialize);
assertEquals(p2.getAge(), p.getAge());
assertEquals(p2.getName(), p.getName());
}
@Test(expected = ClassCastException.class)
public void whenSerializingUsingSpringSerializationUtils_ThenThrowsError() {
Address address = new Address();
address.setHouseNumber(10);
org.springframework.util.SerializationUtils.serialize((Serializable) address);
}
@Test
public void whenSerializingAndDeserializingUsingSpringSerializationUtils_ThenObjectIsTheSame() {
Person p = new Person();
p.setAge(20);
p.setName("Joe");
byte[] serialize = org.springframework.util.SerializationUtils.serialize(p);
Person p2 = (Person) org.springframework.util.SerializationUtils.deserialize(serialize);
assertEquals(p2.getAge(), p.getAge());
assertEquals(p2.getName(), p.getName());
}
@Test(expected = ClassCastException.class)
public void whenSerializingUsingCustomSerializationUtils_ThenThrowsError() throws IOException {
Address address = new Address();
address.setHouseNumber(10);
MySerializationUtils.serialize((Serializable) address);
}
@Test
public void whenSerializingAndDeserializingUsingCustomSerializationUtils_ThenObjectIsTheSame() throws IOException, ClassNotFoundException {
Person p = new Person();
p.setAge(20);
p.setName("Joe");
byte[] serialize = MySerializationUtils.serialize(p);
Person p2 = MySerializationUtils.deserialize(serialize, Person.class);
assertEquals(p2.getAge(), p.getAge());
assertEquals(p2.getName(), p.getName());
}
@Test
public void whenSerializingUsingCustomSerializationUtils_ThanOk() {
assertFalse(MySerializationUtils.isSerializable(Address.class));
assertTrue(MySerializationUtils.isSerializable(Person.class));
assertTrue(MySerializationUtils.isSerializable(Integer.class));
}
}

View File

@ -99,6 +99,7 @@
<module>core-java-reflection-2</module>
<module>core-java-security</module>
<module>core-java-security-2</module>
<module>core-java-security-3</module>
<module>core-java-streams</module>
<module>core-java-streams-2</module>
<module>core-java-streams-3</module>
@ -134,8 +135,4 @@
</dependencies>
</dependencyManagement>
<properties>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
</properties>
</project>

View File

@ -0,0 +1,3 @@
FROM openjdk:11
COPY target/docker-sample-app-0.0.1.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- How to Get Docker-Compose to Always Use the Latest Image

View File

@ -0,0 +1,8 @@
version: '2.4'
services:
db:
image: postgres
my_app:
build: .
ports:
- "8080:8080"

View File

@ -0,0 +1,9 @@
version: '2.4'
services:
db:
image: postgres
my_app:
image: "eugen/test-app:latest"
ports:
- "8080:8080"

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung.docker</groupId>
<artifactId>docker</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>docker-sample-app</artifactId>
<name>docker-sample-app</name>
<description>Demo project for Spring Boot and Docker</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>

View File

@ -0,0 +1,13 @@
package com.baeldung.docker.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DockAppApplication {
public static void main(String[] args) {
SpringApplication.run(DockAppApplication.class, args);
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.docker.app.endpoint;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping
public String version() {
return "1.7";
}
}

View File

@ -0,0 +1,13 @@
package com.baeldung.docker.app;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DockAppApplicationUnitTest {
@Test
void contextLoads() {
}
}

View File

@ -25,6 +25,7 @@
<modules>
<module>docker-internal-dto</module>
<module>docker-spring-boot</module>
<module>docker-sample-app</module>
</modules>
</project>

View File

@ -144,18 +144,6 @@
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>

View File

@ -44,12 +44,6 @@
<artifactId>gwt-dev</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -37,12 +37,6 @@
<version>${io.grpc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>

View File

@ -26,18 +26,6 @@
<version>${commons-lang3.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -14,21 +14,6 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>guava-collections-map</finalName>
<resources>

View File

@ -15,18 +15,6 @@
<dependencies>
<!-- test scoped -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -31,18 +31,6 @@
<version>${jool.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -13,21 +13,6 @@
<version>0.0.1-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>guava-io</finalName>
<resources>

View File

@ -20,18 +20,6 @@
<version>${commons-lang3.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -34,22 +34,9 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<guava.version>29.0-jre</guava.version>
</properties>

View File

@ -40,15 +40,8 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit-platform-surefire-provider.version}</version>
</dependency>
</dependencies>
<configuration>
<properties>
<excludeTags>math</excludeTags>

View File

@ -10,4 +10,5 @@ This module contains articles about Jackson conversions.
- [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
- [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast)
- [Deserialize Snake Case to Camel Case With Jackson](https://www.baeldung.com/jackson-deserialize-snake-to-camel-case)
- More articles: [[<-- prev]](../jackson-conversions)

View File

@ -0,0 +1,22 @@
package com.baeldung.jackson.snakecase;
public class User {
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;
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.jackson.snakecase;
import com.fasterxml.jackson.annotation.JsonProperty;
public class UserWithPropertyNames {
@JsonProperty("first_name")
private String firstName;
@JsonProperty("last_name")
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;
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.jackson.snakecase;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class UserWithSnakeStrategy {
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;
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.jackson.snakecase;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SnakeCaseUnitTest {
private static final String JSON = "{\"first_name\": \"Jackie\", \"last_name\": \"Chan\"}";
@Test(expected = UnrecognizedPropertyException.class)
public void whenExceptionThrown_thenExpectationSatisfied() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readValue(JSON, User.class);
}
@Test
public void givenSnakeCaseJson_whenParseWithJsonPropertyAnnotation_thenGetExpectedObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
UserWithPropertyNames user = objectMapper.readValue(JSON, UserWithPropertyNames.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
}
@Test
public void givenSnakeCaseJson_whenParseWithJsonNamingAnnotation_thenGetExpectedObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
UserWithSnakeStrategy user = objectMapper.readValue(JSON, UserWithSnakeStrategy.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
}
@Test
public void givenSnakeCaseJson_whenParseWithCustomMapper_thenGetExpectedObject() throws Exception {
ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
User user = objectMapper.readValue(JSON, User.class);
assertEquals("Jackie", user.getFirstName());
assertEquals("Chan", user.getLastName());
}
}

View File

@ -35,18 +35,6 @@
<artifactId>jackson-dataformat-xml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -22,18 +22,6 @@
<version>${jackson.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>

View File

@ -32,12 +32,6 @@
<artifactId>modelmapper</artifactId>
<version>${modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>

View File

@ -1136,7 +1136,7 @@
<maven-enforcer-plugin.version>3.0.0-M2</maven-enforcer-plugin.version>
<maven-idea-plugin.version>2.2.1</maven-idea-plugin.version>
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
<maven-surefire-plugin.version>2.22.1</maven-surefire-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
<jib-maven-plugin.version>0.9.11</jib-maven-plugin.version>
<frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>

View File

@ -1054,7 +1054,6 @@
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<maven-enforcer-plugin.version>3.0.0-M2</maven-enforcer-plugin.version>
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
<maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
<jib-maven-plugin.version>0.9.11</jib-maven-plugin.version>
<frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>

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