diff --git a/algorithms-miscellaneous-5/pom.xml b/algorithms-miscellaneous-5/pom.xml index 32ecce58a6..c68ac96c38 100644 --- a/algorithms-miscellaneous-5/pom.xml +++ b/algorithms-miscellaneous-5/pom.xml @@ -34,11 +34,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/algorithms-miscellaneous-6/pom.xml b/algorithms-miscellaneous-6/pom.xml index 6d5f211c8a..a9eb75cf1e 100644 --- a/algorithms-miscellaneous-6/pom.xml +++ b/algorithms-miscellaneous-6/pom.xml @@ -19,11 +19,6 @@ guava ${guava.version} - - org.junit.platform - junit-platform-commons - ${junit-platform.version} - org.assertj assertj-core diff --git a/algorithms-sorting-2/pom.xml b/algorithms-sorting-2/pom.xml index b673af9d70..c9bec354f3 100644 --- a/algorithms-sorting-2/pom.xml +++ b/algorithms-sorting-2/pom.xml @@ -29,12 +29,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/algorithms-sorting/pom.xml b/algorithms-sorting/pom.xml index b853fd80ee..e916d0aae5 100644 --- a/algorithms-sorting/pom.xml +++ b/algorithms-sorting/pom.xml @@ -30,12 +30,6 @@ ${lombok.version} provided - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java new file mode 100644 index 0000000000..4d97fe50cb --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/cellstyle/CellStyleHandler.java @@ -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); + } +} diff --git a/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx new file mode 100644 index 0000000000..29f128211b Binary files /dev/null and b/apache-poi/src/main/resources/cellstyle/CellStyleHandlerTest.xlsx differ diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java new file mode 100644 index 0000000000..e131db8e56 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/cellstyle/CellStyleHandlerUnitTest.java @@ -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(); + } +} diff --git a/atomikos/pom.xml b/atomikos/pom.xml index cb10168c0d..cd798825d1 100644 --- a/atomikos/pom.xml +++ b/atomikos/pom.xml @@ -71,12 +71,6 @@ derby ${derby.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.transaction diff --git a/core-java-modules/core-java-17/pom.xml b/core-java-modules/core-java-17/pom.xml index f1f4edc484..b1811ecf7f 100644 --- a/core-java-modules/core-java-17/pom.xml +++ b/core-java-modules/core-java-17/pom.xml @@ -38,32 +38,35 @@ ${maven.compiler.target.version} - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire.plugin.version} - - --enable-preview - 1 - - - - org.apache.maven.surefire - surefire-api - ${surefire.plugin.version} - - - + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.plugin.version} + + + --enable-preview + --enable-native-access=core.java + 1 + + + + + org.apache.maven.surefire + surefire-api + ${surefire.plugin.version} + + + 17 17 - 17 - 3.8.1 - 3.0.0-M5 - 3.17.2 + 17 + 3.8.1 + 3.0.0-M5 + 3.17.2 \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java new file mode 100644 index 0000000000..0890b025be --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP356.java @@ -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 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); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java new file mode 100644 index 0000000000..2bc3a664d1 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP406.java @@ -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"; + }; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java new file mode 100644 index 0000000000..0fc3d6f467 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP409.java @@ -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; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java new file mode 100644 index 0000000000..8c998629c9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP412.java @@ -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."); + } +} + + diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java new file mode 100644 index 0000000000..aaccc4a665 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/features/JEP414.java @@ -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 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]; + } + } + +} diff --git a/core-java-modules/core-java-17/src/main/java/module-info.java b/core-java-modules/core-java-17/src/main/java/module-info.java new file mode 100644 index 0000000000..b1ce62aa68 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module core.java { + requires jdk.incubator.vector; + requires jdk.incubator.foreign; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/compile_c.sh b/core-java-modules/core-java-17/src/main/resources/compile_c.sh new file mode 100755 index 0000000000..d2e0629cc5 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/compile_c.sh @@ -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/ \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/main/resources/print_name.c b/core-java-modules/core-java-17/src/main/resources/print_name.c new file mode 100644 index 0000000000..7bda12e352 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/resources/print_name.c @@ -0,0 +1,8 @@ +#include +#include + +char* printName(char *name) { + char* newString = (char*)malloc((15 + sizeof(name))*sizeof(char)); + sprintf(newString, "Your name is %s", name); + return newString; +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java new file mode 100644 index 0000000000..b4f61a6f24 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP356UnitTest.java @@ -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)); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java new file mode 100644 index 0000000000..87e6f3bec6 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP406UnitTest.java @@ -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); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java new file mode 100644 index 0000000000..41380ec2bb --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP409UnitTest.java @@ -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(); + }; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java new file mode 100644 index 0000000000..66e7d952c7 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP412UnitTest.java @@ -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); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java new file mode 100644 index 0000000000..459344d907 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/features/JEP414UnitTest.java @@ -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; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..29b6eb1bee --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/ByteHexadecimalConversionUnitTest.java @@ -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); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java new file mode 100644 index 0000000000..6f26a8351c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/PrimitiveTypeHexadecimalConversionUnitTest.java @@ -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); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java new file mode 100644 index 0000000000..28189d0e8c --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/StringFormattingUnitTest.java @@ -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})); + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java new file mode 100644 index 0000000000..c2a33fb4b5 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/hexformat/UppercaseLowercaseOutputUnitTest.java @@ -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; + } +} diff --git a/core-java-modules/core-java-collections-maps-4/pom.xml b/core-java-modules/core-java-collections-maps-4/pom.xml index 1835e3ceac..2109804ff0 100644 --- a/core-java-modules/core-java-collections-maps-4/pom.xml +++ b/core-java-modules/core-java-collections-maps-4/pom.xml @@ -1,34 +1,55 @@ - 4.0.0 - core-java-collections-maps-4 - 0.1.0-SNAPSHOT - core-java-collections-maps-4 - jar + 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"> + 4.0.0 + core-java-collections-maps-4 + 0.1.0-SNAPSHOT + core-java-collections-maps-4 + jar - - com.baeldung.core-java-modules - core-java-modules - 0.0.1-SNAPSHOT - ../pom.xml - + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + ../pom.xml + + + + UTF-8 + 1.8 + 1.8 + - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - - !performance - - - - - + + + junit + junit + ${junit.version} + test + + + org.hamcrest + hamcrest-all + ${hamcrest-all.version} + test + + - + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + + !performance + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java new file mode 100644 index 0000000000..410758405e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Address.java @@ -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; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java new file mode 100644 index 0000000000..2ab54ff17c --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/Employee.java @@ -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; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java new file mode 100644 index 0000000000..53781b0bc1 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/MapsUtil.java @@ -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 buildInnerMap(List batterList) { + Map innerBatterMap = new HashMap(); + + int index = 1; + for (String item : batterList) { + innerBatterMap.put(index, item); + index++; + } + + return innerBatterMap; + } + + public Map> createNestedMapfromStream(List listEmployee) { + Map> employeeAddressMap = listEmployee.stream() + .collect(Collectors.groupingBy(e -> e.getAddress().getAddressId(), + Collectors.toMap(f -> f.getAddress().getAddressLocation(), Employee::getEmployeeName))); + return employeeAddressMap; + } + + public Map> createNestedObjectMap(List listEmployee) { + Map> 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 flattenMap(Map source) { + Map converted = new HashMap<>(); + + for (Entry entry : source.entrySet()) { + if (entry.getValue() instanceof Map) { + flattenMap((Map) entry.getValue()) + .forEach((key, value) -> converted.put(entry.getKey() + "." + key, value)); + } else { + converted.put(entry.getKey().toString(), entry.getValue().toString()); + } + } + return converted; + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java new file mode 100644 index 0000000000..ce63b72527 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/main/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClass.java @@ -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 batterList = new ArrayList<>(); + Map> outerBakedGoodsMap = new HashMap<>(); + Map> outerBakedGoodsMap2 = new HashMap<>(); + Map> outerBakedGoodsMap3 = new HashMap<>(); + Map> 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() { + { + 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 listEmployee = new ArrayList(); + + 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> employeeAddressMap = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap = mUtil.createNestedObjectMap(listEmployee); + Map> 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> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> employeeMap1 = mUtil.createNestedObjectMap(listEmployee); + + System.out.println(employeeMap.equals(employeeMap1)); + System.out.println(employeeMap.equals(employeeMap2)); + + for (Map.Entry> outerBakedGoodsMapEntrySet : outerBakedGoodsMap.entrySet()) { + Map valueMap = outerBakedGoodsMapEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + for (Map.Entry> employeeEntrySet : employeeAddressMap.entrySet()) { + Map valueMap = employeeEntrySet.getValue(); + System.out.println(valueMap.entrySet()); + } + + System.out.println("Employee Address Map Flattened: " + mUtil.flattenMap(employeeAddressMap)); + + System.out.println(employeeAddressMap.equals(employeeAddressMap1)); + } + +} diff --git a/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java new file mode 100644 index 0000000000..a86e329bea --- /dev/null +++ b/core-java-modules/core-java-collections-maps-4/src/test/java/com/baeldung/nestedhashmaps/NestedHashMapExamplesClassUnitTest.java @@ -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 batterList = new ArrayList<>(); + private List listEmployee = new ArrayList(); + private Map> actualBakedGoodsMap = new HashMap<>(); + private Map> actualEmployeeAddressMap = new HashMap<>(); + private Map> 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> setup() { + Map> expectedMap = new HashMap<>(); + expectedMap.put(Integer.valueOf(100), new HashMap() { + { + put("Misty Lanes", "Balin"); + } + }); + expectedMap.put(Integer.valueOf(200), new HashMap() { + { + put("Bag End", "Bilbo Baggins"); + } + }); + expectedMap.put(Integer.valueOf(156), new HashMap() { + { + put("Brambles Lane", "Bofur"); + } + }); + expectedMap.put(Integer.valueOf(124), new HashMap() { + { + put("Timbuktoo", "Thorin Oakenshield"); + } + }); + expectedMap.put(Integer.valueOf(23), new HashMap() { + { + put("Rivendell", "Elrond"); + } + }); + + return expectedMap; + } + + @Test + public void whenCreateNestedHashMapwithStreams_thenNestedMap() { + + Map> expectedMap = setup(); + + assertThat(actualEmployeeAddressMap, equalTo(expectedMap)); + } + + @Test + public void whenCompareTwoHashMapswithDifferenctValues_usingEquals_thenFail() { + Map> outerBakedGoodsMap2 = new HashMap<>(); + outerBakedGoodsMap2.put("Eclair", mUtil.buildInnerMap(batterList)); + outerBakedGoodsMap2.put("Donut", mUtil.buildInnerMap(batterList)); + assertNotEquals(outerBakedGoodsMap2, actualBakedGoodsMap); + + Map> outerBakedGoodsMap3 = new HashMap>(); + 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> employeeAddressMap1 = mUtil.createNestedMapfromStream(listEmployee); + + Map> 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> 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> expectedMap = setupAddressObjectMap(); + assertNotSame(expectedMap, actualEmployeeMap); + assertNotEquals(expectedMap, actualEmployeeMap); + + } + + @Test + public void whenCompareTwoHashMapsUsingEquals_thenSuccess() { + Map> outerBakedGoodsMap4 = new HashMap<>(); + outerBakedGoodsMap4.putAll(actualBakedGoodsMap); + + assertEquals(actualBakedGoodsMap, outerBakedGoodsMap4); + + Map> 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() { + { + 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() { + { + put(1, "Dark Chocolate"); + } + }); + + assertNotEquals(actualBakedGoodsMap.get("Eclair"), null); + actualBakedGoodsMap.remove("Eclair"); + assertEquals(actualBakedGoodsMap.get("Eclair"), null); + } + + @Test + public void whenFlattenMap_thenRemovesNesting() { + + Map flattenedBakedGoodsMap = mUtil.flattenMap(actualBakedGoodsMap); + assertThat(flattenedBakedGoodsMap, IsMapContaining.hasKey("Donut.2")); + + Map 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> setupAddressObjectMap() { + + Map> expectedMap = new HashMap<>(); + + expectedMap.put(1, new HashMap() { + { + put(124, new Address(124, "Timbuktoo")); + } + }); + expectedMap.put(2, new HashMap() { + { + put(100, new Address(100, "Misty Lanes")); + } + }); + expectedMap.put(3, new HashMap() { + { + put(156, new Address(156, "Brambles Lane")); + } + }); + expectedMap.put(4, new HashMap() { + { + put(200, new Address(200, "Bag End")); + } + }); + expectedMap.put(5, new HashMap() { + { + put(23, new Address(23, "Rivendell")); + } + }); + return expectedMap; + } + +} diff --git a/core-java-modules/core-java-jndi/pom.xml b/core-java-modules/core-java-jndi/pom.xml index 1728c0b5d9..6b7c4e1359 100644 --- a/core-java-modules/core-java-jndi/pom.xml +++ b/core-java-modules/core-java-jndi/pom.xml @@ -41,6 +41,18 @@ h2 ${h2.version} + + org.apache.directory.server + apacheds-test-framework + ${apacheds.version} + test + + + org.assertj + assertj-core + 3.21.0 + test + @@ -59,6 +71,7 @@ 5.0.9.RELEASE 1.4.199 + 2.0.0.AM26 1.8 1.8 diff --git a/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java new file mode 100644 index 0000000000..5a675c62c9 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/java/com/baeldung/jndi/ldap/auth/JndiLdapAuthManualTest.java @@ -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 environment) throws Exception { + DirContext context = new InitialDirContext(environment); + context.close(); + } + + @Test + public void givenPreloadedLDAPUserJoe_whenAuthUserWithCorrectPW_thenAuthSucceeds() throws Exception { + + Hashtable environment = new Hashtable(); + 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 environment = new Hashtable(); + 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 environment = new Hashtable(); + 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 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 environment = new Hashtable(); + 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 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(); + } +} diff --git a/core-java-modules/core-java-jndi/src/test/resources/logback.xml b/core-java-modules/core-java-jndi/src/test/resources/logback.xml new file mode 100644 index 0000000000..e55b365ba4 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/core-java-modules/core-java-jndi/src/test/resources/users.ldif b/core-java-modules/core-java-jndi/src/test/resources/users.ldif new file mode 100644 index 0000000000..c1996586d5 --- /dev/null +++ b/core-java-modules/core-java-jndi/src/test/resources/users.ldif @@ -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 diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java new file mode 100644 index 0000000000..62dbdef297 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Customer.java @@ -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); + } +} diff --git a/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java new file mode 100644 index 0000000000..02ce2220ba --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/main/java/com/baeldung/constructorchaining/Person.java @@ -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); + } +} diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java new file mode 100644 index 0000000000..ad00ea65b8 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/CustomerUnitTest.java @@ -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()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java new file mode 100644 index 0000000000..8322917951 --- /dev/null +++ b/core-java-modules/core-java-lang-4/src/test/java/com/baeldung/constructorchaining/PersonUnitTest.java @@ -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()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java new file mode 100644 index 0000000000..0d9d3b6431 --- /dev/null +++ b/core-java-modules/core-java-string-algorithms-2/src/test/java/com/baeldung/isuppercase/StringFirstCharacterUppercase.java @@ -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))); + } +} diff --git a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java index c8f8fc2d98..2da8955645 100644 --- a/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java +++ b/core-java-modules/core-java-string-operations-3/src/test/java/com/baeldung/multipledelimiterssplit/MultipleDelimitersSplitUnitTest.java @@ -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 expected = Arrays.asList(expectedArray); - Iterable names = Splitter.on(Pattern.compile(";|:|-")).split(example); + Iterable 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 expected = Arrays.asList(expectedArray); - Iterable names = Splitter.onPattern(";|:|-").split(example); + Iterable names = Splitter.onPattern("[;:-]").split(example); Assertions.assertEquals(4, Iterators.size(names.iterator())); Assertions.assertIterableEquals(expected, names); } diff --git a/core-java-modules/core-java/pom.xml b/core-java-modules/core-java/pom.xml index db2b1edc70..42262be29a 100644 --- a/core-java-modules/core-java/pom.xml +++ b/core-java-modules/core-java/pom.xml @@ -61,6 +61,11 @@ moneta ${javamoney.moneta.version} + + org.springframework + spring-core + ${spring.core.version} + @@ -187,6 +192,7 @@ 3.0.0-M1 1.8 1.8 + 4.3.20.RELEASE \ No newline at end of file diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java new file mode 100644 index 0000000000..bfaa91313c --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/util/MySerializationUtils.java @@ -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 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 deserialize(byte[] b, Class 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; + } +} diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java new file mode 100644 index 0000000000..a8c4009386 --- /dev/null +++ b/core-java-modules/core-java/src/test/java/com/baeldung/serialization/SerializationUnitTest.java @@ -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)); + } +} diff --git a/docker/docker-sample-app/Dockerfile b/docker/docker-sample-app/Dockerfile new file mode 100644 index 0000000000..71fc1a29d9 --- /dev/null +++ b/docker/docker-sample-app/Dockerfile @@ -0,0 +1,3 @@ +FROM openjdk:11 +COPY target/docker-sample-app-0.0.1.jar app.jar +ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/docker/docker-sample-app/README.md b/docker/docker-sample-app/README.md new file mode 100644 index 0000000000..6aeaa1d2a3 --- /dev/null +++ b/docker/docker-sample-app/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- How to Get Docker-Compose to Always Use the Latest Image diff --git a/docker/docker-sample-app/docker-compose-build-image.yaml b/docker/docker-sample-app/docker-compose-build-image.yaml new file mode 100644 index 0000000000..27c1d8ee44 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-build-image.yaml @@ -0,0 +1,8 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + build: . + ports: + - "8080:8080" diff --git a/docker/docker-sample-app/docker-compose-with-image.yaml b/docker/docker-sample-app/docker-compose-with-image.yaml new file mode 100644 index 0000000000..9a8822f762 --- /dev/null +++ b/docker/docker-sample-app/docker-compose-with-image.yaml @@ -0,0 +1,9 @@ +version: '2.4' +services: + db: + image: postgres + my_app: + image: "eugen/test-app:latest" + ports: + - "8080:8080" + diff --git a/docker/docker-sample-app/pom.xml b/docker/docker-sample-app/pom.xml new file mode 100644 index 0000000000..6841fabcee --- /dev/null +++ b/docker/docker-sample-app/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + com.baeldung.docker + docker + 0.0.1 + + + docker-sample-app + docker-sample-app + Demo project for Spring Boot and Docker + + + 11 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java new file mode 100644 index 0000000000..e7ff52015c --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/DockAppApplication.java @@ -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); + } + +} diff --git a/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java new file mode 100644 index 0000000000..d46c57e606 --- /dev/null +++ b/docker/docker-sample-app/src/main/java/com/baeldung/docker/app/endpoint/MyController.java @@ -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"; + } +} diff --git a/docker/docker-sample-app/src/main/resources/application.properties b/docker/docker-sample-app/src/main/resources/application.properties new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/docker/docker-sample-app/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java new file mode 100644 index 0000000000..7220766988 --- /dev/null +++ b/docker/docker-sample-app/src/test/java/com/baeldung/docker/app/DockAppApplicationUnitTest.java @@ -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() { + } + +} diff --git a/docker/pom.xml b/docker/pom.xml index 3fcc9ca94f..f481f1b8b7 100644 --- a/docker/pom.xml +++ b/docker/pom.xml @@ -25,6 +25,7 @@ docker-internal-dto docker-spring-boot + docker-sample-app diff --git a/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml index 1a49ced021..bcccc136a4 100644 --- a/google-web-toolkit/pom.xml +++ b/google-web-toolkit/pom.xml @@ -44,12 +44,6 @@ gwt-dev provided - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/grpc/pom.xml b/grpc/pom.xml index f034b2b517..6f0c3b5c91 100644 --- a/grpc/pom.xml +++ b/grpc/pom.xml @@ -37,12 +37,6 @@ ${io.grpc.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - javax.annotation javax.annotation-api diff --git a/guest/junit5-example/pom.xml b/guest/junit5-example/pom.xml index a88f739891..cc52b0e3d7 100644 --- a/guest/junit5-example/pom.xml +++ b/guest/junit5-example/pom.xml @@ -40,15 +40,8 @@ + org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - - math diff --git a/json-2/pom.xml b/json-2/pom.xml index 53d67320ba..b4301c41e5 100644 --- a/json-2/pom.xml +++ b/json-2/pom.xml @@ -24,12 +24,6 @@ jsoniter ${jsoniter.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.assertj assertj-core diff --git a/junit5/pom.xml b/junit5/pom.xml index b9804408a2..00b04ea292 100644 --- a/junit5/pom.xml +++ b/junit5/pom.xml @@ -8,8 +8,8 @@ junit5 - parent-modules com.baeldung + parent-modules 1.0.0-SNAPSHOT @@ -18,19 +18,4 @@ 8 - - - org.junit.jupiter - junit-jupiter-api - 5.8.1 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.8.1 - test - - - \ No newline at end of file diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 3db34709e7..dd48453a8c 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -14,12 +14,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.kafka kafka-streams @@ -92,6 +86,10 @@ commons-codec commons-codec + + junit + junit + @@ -104,6 +102,12 @@ flink-test-utils_2.11 ${flink.version} test + + + junit + junit + + org.slf4j diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index a9c340b319..954f666785 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -61,12 +61,6 @@ netty-all ${netty.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.apache.tomcat diff --git a/libraries/pom.xml b/libraries/pom.xml index 4ecf82aa87..b2e429ff65 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -146,12 +146,6 @@ jmh-core ${jmh-core.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - info.debatty java-lsh diff --git a/maven-modules/maven-integration-test/pom.xml b/maven-modules/maven-integration-test/pom.xml index 4283baf63b..01be0ad1a4 100644 --- a/maven-modules/maven-integration-test/pom.xml +++ b/maven-modules/maven-integration-test/pom.xml @@ -26,12 +26,6 @@ jersey-hk2 ${jersey.version} - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/maven-modules/maven-properties/pom.xml b/maven-modules/maven-properties/pom.xml index b3169a7fb0..88e13a0fb8 100644 --- a/maven-modules/maven-properties/pom.xml +++ b/maven-modules/maven-properties/pom.xml @@ -14,15 +14,6 @@ ../.. - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - - - diff --git a/micronaut/pom.xml b/micronaut/pom.xml index f36f565a94..019bd6ab29 100644 --- a/micronaut/pom.xml +++ b/micronaut/pom.xml @@ -64,12 +64,6 @@ ${logback.version} runtime - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - io.projectreactor reactor-core diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 8e8dbba54d..42081fa115 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -58,11 +58,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - @@ -97,7 +92,6 @@ 1.9.1 3.4.0 - 2.22.2 \ No newline at end of file diff --git a/parent-java/pom.xml b/parent-java/pom.xml index ae6eeb40a9..4e5081393c 100644 --- a/parent-java/pom.xml +++ b/parent-java/pom.xml @@ -40,23 +40,10 @@ - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - 31.0.1-jre 2.3.7 2.2 - 2.22.2 \ No newline at end of file diff --git a/parent-spring-4/pom.xml b/parent-spring-4/pom.xml index 630fa0baf3..a36e1060ed 100644 --- a/parent-spring-4/pom.xml +++ b/parent-spring-4/pom.xml @@ -24,15 +24,6 @@ - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - org.codehaus.cargo @@ -57,7 +48,6 @@ 4.3.27.RELEASE 1.6.1 - 2.22.2 \ No newline at end of file diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml index 01e8671099..1263a56e2b 100644 --- a/parent-spring-5/pom.xml +++ b/parent-spring-5/pom.xml @@ -23,23 +23,10 @@ - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - - 5.3.9 5.2.3.RELEASE 1.5.10.RELEASE - 2.22.2 \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml index ad649d58d8..0eb4b8075d 100644 --- a/persistence-modules/java-jpa-3/pom.xml +++ b/persistence-modules/java-jpa-3/pom.xml @@ -68,12 +68,6 @@ ${assertj.version} test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - org.testcontainers postgresql diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index c3df8866b1..4d42ff54cd 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -99,9 +99,6 @@ 5.2.17.Final 42.2.20 - - - 2.22.2 \ No newline at end of file diff --git a/pom.xml b/pom.xml index f2a53f38b7..01b55d48f9 100644 --- a/pom.xml +++ b/pom.xml @@ -113,11 +113,6 @@ - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform-surefire-provider.version} - org.junit.jupiter junit-jupiter-engine @@ -1398,8 +1393,7 @@ 1.2.6 - - 2.21.0 + 2.22.2 3.8.1 3.0.0 1.8 diff --git a/restx/pom.xml b/restx/pom.xml index ea9f927563..57736f60cd 100644 --- a/restx/pom.xml +++ b/restx/pom.xml @@ -113,12 +113,6 @@ - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 1b2f6ffa06..0e4c2fe60b 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -46,7 +46,7 @@ spring-boot-groovy spring-boot-jasypt - spring-boot-keycloak + spring-boot-libraries spring-boot-libraries-2 spring-boot-logging-log4j2 diff --git a/spring-ejb/ejb-beans/pom.xml b/spring-ejb/ejb-beans/pom.xml index 10bc6d3104..6f20d949b0 100644 --- a/spring-ejb/ejb-beans/pom.xml +++ b/spring-ejb/ejb-beans/pom.xml @@ -80,12 +80,6 @@ arquillian-junit-container test - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - test - joda-time @@ -141,7 +135,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} always diff --git a/spring-jenkins-pipeline/pom.xml b/spring-jenkins-pipeline/pom.xml index 6f00dd5820..4e84bb8c70 100644 --- a/spring-jenkins-pipeline/pom.xml +++ b/spring-jenkins-pipeline/pom.xml @@ -62,6 +62,7 @@ + org.apache.maven.plugins maven-surefire-plugin diff --git a/spring-security-modules/spring-ldap/pom.xml b/spring-security-modules/spring-ldap/pom.xml index 44f754673f..086be2df5a 100644 --- a/spring-security-modules/spring-ldap/pom.xml +++ b/spring-security-modules/spring-ldap/pom.xml @@ -106,7 +106,6 @@ org.apache.maven.plugins maven-surefire-plugin - ${maven-surefire-plugin.version} integration-test diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java index f8acdfe2ac..226459db75 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/MvcConfig.java @@ -1,18 +1,20 @@ package com.baeldung.spring; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration -public class MvcConfig extends WebMvcConfigurerAdapter { +@ComponentScan(basePackages = { "com.baeldung.spring" }) +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -22,8 +24,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/anonymous.html"); registry.addViewController("/login.html"); @@ -35,7 +35,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/WEB-INF/view/react/build/static/"); - + registry.addResourceHandler("/*.js").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.json").addResourceLocations("/WEB-INF/view/react/build/"); registry.addResourceHandler("/*.ico").addResourceLocations("/WEB-INF/view/react/build/"); diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java new file mode 100644 index 0000000000..4084df9698 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/RestController.java @@ -0,0 +1,31 @@ +package com.baeldung.spring; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/rest") +public class RestController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RestController.class); + + @GetMapping + public ResponseEntity get(HttpServletRequest request) { + CsrfToken token = (CsrfToken) request.getAttribute("_csrf"); + LOGGER.info("{}={}", token.getHeaderName(), token.getToken()); + return ResponseEntity.ok().build(); + } + + @PostMapping + public ResponseEntity post(HttpServletRequest request) { + // Same impl as GET for testing purpose + return this.get(request); + } +} diff --git a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java index 7b67028647..d560589cce 100644 --- a/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-react/src/main/java/com/baeldung/spring/SecSecurityConfig.java @@ -7,6 +7,7 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; @Configuration @EnableWebSecurity @@ -21,11 +22,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.inMemoryAuthentication() - .withUser("user1").password("user1Pass").roles("USER") + .withUser("user1").password("{noop}user1Pass").roles("USER") .and() - .withUser("user2").password("user2Pass").roles("USER") + .withUser("user2").password("{noop}user2Pass").roles("USER") .and() - .withUser("admin").password("admin0Pass").roles("ADMIN"); + .withUser("admin").password("{noop}admin0Pass").roles("ADMIN"); // @formatter:on } @@ -33,11 +34,11 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() + .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and() .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/anonymous*").anonymous() - .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico").permitAll() + .antMatchers(HttpMethod.GET, "/index*", "/static/**", "/*.js", "/*.json", "/*.ico", "/rest").permitAll() .anyRequest().authenticated() .and() .formLogin() diff --git a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml index 25f3f36d1a..2cc702de59 100644 --- a/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml +++ b/spring-security-modules/spring-security-web-react/src/main/resources/logback.xml @@ -12,7 +12,7 @@ - + diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp index c9d88cbc9b..d64f80a5cb 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/homepage.jsp @@ -1,11 +1,30 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> - + + +

This is the body of the sample view

+
+

CSRF Testing

+
+ CSRF Token: + + +
+
+
+   + +
+
+
Request Result:

+
+ +

Roles

This text is only visible to a user

@@ -22,5 +41,26 @@ ">Logout + \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js new file mode 100644 index 0000000000..657cc31f41 --- /dev/null +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/csrf.js @@ -0,0 +1,3 @@ +window.getCsrfToken = () => { + return document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1'); +} diff --git a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html index 0c3f78d7b3..6d4894da42 100644 --- a/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html +++ b/spring-security-modules/spring-security-web-react/src/main/webapp/WEB-INF/view/react/public/index.html @@ -6,6 +6,7 @@ +