Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -9,4 +9,6 @@ This module contains articles about Apache POI.
|
||||
- [Numeric Format Using POI](https://www.baeldung.com/apache-poi-numeric-format)
|
||||
- [Microsoft Word Processing in Java with Apache POI](https://www.baeldung.com/java-microsoft-word-with-apache-poi)
|
||||
- [Creating a MS PowerPoint Presentation in Java](https://www.baeldung.com/apache-poi-slideshow)
|
||||
- [Finding the Last Row in an Excel Spreadsheet From Java](https://www.baeldung.com/java-excel-find-last-row)
|
||||
- [Setting Formulas in Excel with Apache POI](https://www.baeldung.com/java-apache-poi-set-formulas)
|
||||
- More articles: [[<-- prev]](../apache-poi)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<poi.version>5.0.0</poi.version>
|
||||
<poi.version>5.2.0</poi.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
+25
-26
@@ -1,26 +1,25 @@
|
||||
package com.baeldung.poi.excel.setformula;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExcelFormula {
|
||||
public double setFormula(String fileLocation, XSSFWorkbook wb, String formula) throws IOException {
|
||||
XSSFSheet sheet = wb.getSheetAt(0);
|
||||
int lastCellNum = sheet.getRow(0).getLastCellNum();
|
||||
XSSFCell formulaCell = sheet.getRow(0).createCell(lastCellNum);
|
||||
formulaCell.setCellFormula(formula);
|
||||
XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||
formulaEvaluator.evaluateFormulaCell(formulaCell);
|
||||
FileOutputStream fileOut = new FileOutputStream(new File(fileLocation));
|
||||
wb.write(fileOut);
|
||||
wb.close();
|
||||
fileOut.close();
|
||||
return formulaCell.getNumericCellValue();
|
||||
}
|
||||
}
|
||||
package com.baeldung.poi.excel.setformula;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ExcelFormula {
|
||||
public double setFormula(String fileLocation, XSSFWorkbook wb, String formula) throws IOException {
|
||||
XSSFSheet sheet = wb.getSheetAt(0);
|
||||
int lastCellNum = sheet.getRow(0).getLastCellNum();
|
||||
XSSFCell formulaCell = sheet.getRow(0).createCell(lastCellNum);
|
||||
formulaCell.setCellFormula(formula);
|
||||
XSSFFormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator();
|
||||
formulaEvaluator.evaluateFormulaCell(formulaCell);
|
||||
FileOutputStream fileOut = new FileOutputStream(fileLocation);
|
||||
wb.write(fileOut);
|
||||
wb.close();
|
||||
fileOut.close();
|
||||
return formulaCell.getNumericCellValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.baeldung.poi.excel.lastrow;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class LastRowUnitTest {
|
||||
private static final String FILE_NAME = "lastRowTest.xlsx";
|
||||
private String fileLocation;
|
||||
|
||||
@Before
|
||||
public void setup() throws URISyntaxException {
|
||||
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExampleGrid_whenGetRow_thenReturnRowObjectIfModified() throws IOException {
|
||||
Workbook workbook = new XSSFWorkbook(fileLocation);
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
assertEquals(7, sheet.getLastRowNum());
|
||||
assertEquals(6, sheet.getPhysicalNumberOfRows());
|
||||
|
||||
assertNotNull(sheet.getRow(0));
|
||||
assertNotNull(sheet.getRow(1));
|
||||
assertNotNull(sheet.getRow(2));
|
||||
assertNotNull(sheet.getRow(3));
|
||||
assertNull(sheet.getRow(4));
|
||||
assertNull(sheet.getRow(5));
|
||||
assertNotNull(sheet.getRow(6));
|
||||
assertNotNull(sheet.getRow(7));
|
||||
assertNull(sheet.getRow(8));
|
||||
|
||||
assertSame(sheet.getRow(7), getLastRowFromSheet(sheet));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptySheet_whenGetRow_thenReturnNull() throws IOException {
|
||||
Workbook workbook = new XSSFWorkbook(fileLocation);
|
||||
Sheet sheet = workbook.getSheetAt(1);
|
||||
|
||||
assertEquals(-1, sheet.getLastRowNum());
|
||||
assertEquals(0, sheet.getPhysicalNumberOfRows());
|
||||
|
||||
assertNull(sheet.getRow(0));
|
||||
|
||||
assertSame(sheet.getRow(0), getLastRowFromSheet(sheet));
|
||||
}
|
||||
|
||||
public static Row getLastRowFromSheet(Sheet sheet) {
|
||||
Row lastRow = null;
|
||||
int lastRowNum = sheet.getLastRowNum();
|
||||
if (lastRowNum >= 0) {
|
||||
lastRow = sheet.getRow(lastRowNum);
|
||||
}
|
||||
return lastRow;
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -3,18 +3,19 @@ package com.baeldung.poi.excel.setformula;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class ExcelFormulaUnitTest {
|
||||
private static String FILE_NAME = "com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx";
|
||||
private static final String FILE_NAME = "com/baeldung/poi/excel/setformula/SetFormulaTest.xlsx";
|
||||
|
||||
private String fileLocation;
|
||||
private ExcelFormula excelFormula;
|
||||
|
||||
@@ -26,7 +27,7 @@ class ExcelFormulaUnitTest {
|
||||
|
||||
@Test
|
||||
void givenExcelData_whenSetFormula_thenSuccess() throws IOException {
|
||||
FileInputStream inputStream = new FileInputStream(new File(fileLocation));
|
||||
FileInputStream inputStream = new FileInputStream(fileLocation);
|
||||
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
|
||||
XSSFSheet sheet = wb.getSheetAt(0);
|
||||
double resultColumnA = 0;
|
||||
@@ -46,6 +47,6 @@ class ExcelFormulaUnitTest {
|
||||
|
||||
double resultValue = excelFormula.setFormula(fileLocation, wb, sumFormulaForColumnA + "-" + sumFormulaForColumnB);
|
||||
|
||||
Assert.assertEquals(resultColumnA - resultColumnB, resultValue, 0d);
|
||||
assertEquals(resultColumnA - resultColumnB, resultValue, 0d);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -8,7 +8,6 @@ This module contains articles about Apache POI.
|
||||
- [Merge Cells in Excel Using Apache POI](https://www.baeldung.com/java-apache-poi-merge-cells)
|
||||
- [Get String Value of Excel Cell with Apache POI](https://www.baeldung.com/java-apache-poi-cell-string-value)
|
||||
- [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)
|
||||
- [Set Background Color of a Cell with Apache POI](https://www.baeldung.com/apache-poi-background-color)
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
package com.baeldung.poi.excel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
public class ExcelUtility {
|
||||
<<<<<<< HEAD
|
||||
private static final String ENDLINE = System.getProperty("line.separator");
|
||||
|
||||
public static String readExcel(String filePath) throws IOException {
|
||||
File file = new File(filePath);
|
||||
FileInputStream inputStream = null;
|
||||
StringBuilder toReturn = new StringBuilder();
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
|
||||
for (Sheet sheet : baeuldungWorkBook) {
|
||||
toReturn.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
toReturn.append("Worksheet :")
|
||||
.append(sheet.getSheetName())
|
||||
.append(ENDLINE);
|
||||
toReturn.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
int firstRow = sheet.getFirstRowNum();
|
||||
int lastRow = sheet.getLastRowNum();
|
||||
for (int index = firstRow + 1; index <= lastRow; index++) {
|
||||
Row row = sheet.getRow(index);
|
||||
toReturn.append("|| ");
|
||||
for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
|
||||
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||||
printCellValue(cell, toReturn);
|
||||
}
|
||||
toReturn.append(" ||")
|
||||
.append(ENDLINE);
|
||||
}
|
||||
}
|
||||
inputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
return toReturn.toString();
|
||||
}
|
||||
|
||||
public static void printCellValue(Cell cell, StringBuilder toReturn) {
|
||||
CellType cellType = cell.getCellType()
|
||||
.equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() : cell.getCellType();
|
||||
if (cellType.equals(CellType.STRING)) {
|
||||
toReturn.append(cell.getStringCellValue())
|
||||
.append(" | ");
|
||||
}
|
||||
if (cellType.equals(CellType.NUMERIC)) {
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
toReturn.append(cell.getDateCellValue())
|
||||
.append(" | ");
|
||||
} else {
|
||||
toReturn.append(cell.getNumericCellValue())
|
||||
.append(" | ");
|
||||
}
|
||||
}
|
||||
if (cellType.equals(CellType.BOOLEAN)) {
|
||||
toReturn.append(cell.getBooleanCellValue())
|
||||
.append(" | ");
|
||||
}
|
||||
}
|
||||
=======
|
||||
private static final String ENDLINE = System.getProperty("line.separator");
|
||||
|
||||
public static String readExcel(String filePath) throws IOException {
|
||||
File file = new File(filePath);
|
||||
FileInputStream inputStream = null;
|
||||
StringBuilder toReturn = new StringBuilder();
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream);
|
||||
for (Sheet sheet : baeuldungWorkBook) {
|
||||
toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE);
|
||||
toReturn.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
int firstRow = sheet.getFirstRowNum();
|
||||
int lastRow = sheet.getLastRowNum();
|
||||
for (int index = firstRow + 1; index <= lastRow; index++) {
|
||||
Row row = sheet.getRow(index);
|
||||
toReturn.append("|| ");
|
||||
for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) {
|
||||
Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||||
printCellValue(cell, toReturn);
|
||||
}
|
||||
toReturn.append(" ||").append(ENDLINE);
|
||||
}
|
||||
}
|
||||
inputStream.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
return toReturn.toString();
|
||||
}
|
||||
|
||||
public static void printCellValue(Cell cell, StringBuilder toReturn) {
|
||||
CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType()
|
||||
: cell.getCellType();
|
||||
if (cellType.equals(CellType.STRING)) {
|
||||
toReturn.append(cell.getStringCellValue()).append(" | ");
|
||||
}
|
||||
if (cellType.equals(CellType.NUMERIC)) {
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
toReturn.append(cell.getDateCellValue()).append(" | ");
|
||||
} else {
|
||||
toReturn.append(cell.getNumericCellValue()).append(" | ");
|
||||
}
|
||||
}
|
||||
if (cellType.equals(CellType.BOOLEAN)) {
|
||||
toReturn.append(cell.getBooleanCellValue()).append(" | ");
|
||||
}
|
||||
}
|
||||
>>>>>>> master
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package com.baeldung.poi.excel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExcelUtilityUnitTest {
|
||||
<<<<<<< HEAD
|
||||
private static final String FILE_NAME = "baeldung.xlsx";
|
||||
private String fileLocation;
|
||||
private static final String ENDLINE = System.getProperty("line.separator");
|
||||
private StringBuilder output;
|
||||
|
||||
@Before
|
||||
public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
|
||||
output = new StringBuilder();
|
||||
output.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
output.append("Worksheet :Sheet1")
|
||||
.append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name1 | Surname1 | 3.55696564113E11 | ")
|
||||
.append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
|
||||
.toString())
|
||||
.append(" | ‡ | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name2 | Surname2 | 5.646513512E9 | ")
|
||||
.append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021")
|
||||
.toString())
|
||||
.append(" | false | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name3 | Surname3 | 3.55696564113E11 | ")
|
||||
.append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021")
|
||||
.toString())
|
||||
.append(" | 7.17039641738E11 | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
output.append("Worksheet :Sheet2")
|
||||
.append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||")
|
||||
.append(ENDLINE);
|
||||
|
||||
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME)
|
||||
.toURI())
|
||||
.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
|
||||
assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringPath_whenReadExcel_thenThrowException() {
|
||||
assertThrows(IOException.class, () -> {
|
||||
ExcelUtility.readExcel("baeldung");
|
||||
});
|
||||
}
|
||||
=======
|
||||
private static final String FILE_NAME = "baeldung.xlsx";
|
||||
private String fileLocation;
|
||||
private static final String ENDLINE = System.getProperty("line.separator");
|
||||
private StringBuilder output;
|
||||
|
||||
@Before
|
||||
public void setupUnitTest() throws IOException, URISyntaxException, ParseException {
|
||||
output = new StringBuilder();
|
||||
output.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
output.append("Worksheet :Sheet1").append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 | ||")
|
||||
.append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
output.append("Worksheet :Sheet2").append(ENDLINE);
|
||||
output.append("--------------------------------------------------------------------").append(ENDLINE);
|
||||
output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||").append(ENDLINE);
|
||||
|
||||
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException {
|
||||
assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringPath_whenReadExcel_thenThrowException() {
|
||||
assertThrows(IOException.class, () -> {
|
||||
ExcelUtility.readExcel("baeldung");
|
||||
});
|
||||
}
|
||||
>>>>>>> master
|
||||
|
||||
}
|
||||
@@ -9,4 +9,5 @@ This module contains articles about Java 8 core features
|
||||
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
||||
- [Interface With Default Methods vs Abstract Class](https://www.baeldung.com/java-interface-default-method-vs-abstract-class)
|
||||
- [Convert Between Byte Array and UUID in Java](https://www.baeldung.com/java-byte-array-to-uuid)
|
||||
- [Create a Simple “Rock-Paper-Scissors” Game in Java](https://www.baeldung.com/java-rock-paper-scissors)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-8)
|
||||
|
||||
+1
-1
@@ -22,6 +22,6 @@ class RandomDatesUnitTest {
|
||||
LocalDate end = LocalDate.now();
|
||||
|
||||
LocalDate random = RandomDates.between(start, end);
|
||||
assertThat(random).isAfter(start).isBefore(end);
|
||||
assertThat(random).isAfterOrEqualTo(start).isBefore(end);
|
||||
}
|
||||
}
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
/**
|
||||
* This class shows examples of how you should use the lock
|
||||
*
|
||||
*/
|
||||
public class ExampleUsage {
|
||||
|
||||
void doWithSimpleExclusiveLock(String key) {
|
||||
SimpleExclusiveLockByKey simpleExclusiveLockByKey = new SimpleExclusiveLockByKey();
|
||||
if (simpleExclusiveLockByKey.tryLock(key)) {
|
||||
try {
|
||||
// do stuff
|
||||
} finally {
|
||||
// it is very important to unlock in the finally block to avoid locking keys forever
|
||||
simpleExclusiveLockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A concrete example can be found in the unit tests
|
||||
void doWithLock(String key) {
|
||||
LockByKey lockByKey = new LockByKey();
|
||||
lockByKey.lock(key);
|
||||
try {
|
||||
// do stuff
|
||||
} finally {
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
// It works exactly the same as with locks
|
||||
void doWithSemaphore(String key) {
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
try {
|
||||
// do stuff
|
||||
} finally {
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class LockByKey {
|
||||
|
||||
private static class LockWrapper {
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private final AtomicInteger numberOfThreadsInQueue = new AtomicInteger(1);
|
||||
|
||||
private LockWrapper addThreadInQueue() {
|
||||
numberOfThreadsInQueue.incrementAndGet();
|
||||
return this;
|
||||
}
|
||||
|
||||
private int removeThreadFromQueue() {
|
||||
return numberOfThreadsInQueue.decrementAndGet();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static ConcurrentHashMap<String, LockWrapper> locks = new ConcurrentHashMap<String, LockWrapper>();
|
||||
|
||||
public void lock(String key) {
|
||||
LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue());
|
||||
lockWrapper.lock.lock();
|
||||
}
|
||||
|
||||
public void unlock(String key) {
|
||||
LockWrapper lockWrapper = locks.get(key);
|
||||
lockWrapper.lock.unlock();
|
||||
if (lockWrapper.removeThreadFromQueue() == 0) {
|
||||
// NB : We pass in the specific value to remove to handle the case where another thread would queue right before the removal
|
||||
locks.remove(key, lockWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SimpleExclusiveLockByKey {
|
||||
|
||||
private static Set<String> usedKeys= ConcurrentHashMap.newKeySet();
|
||||
|
||||
public boolean tryLock(String key) {
|
||||
return usedKeys.add(key);
|
||||
}
|
||||
|
||||
public void unlock(String key) {
|
||||
usedKeys.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class SimultaneousEntriesLockByKey {
|
||||
|
||||
private static final int ALLOWED_THREADS = 2;
|
||||
|
||||
private static ConcurrentHashMap<String, Semaphore> semaphores = new ConcurrentHashMap<String, Semaphore>();
|
||||
|
||||
public void lock(String key) {
|
||||
Semaphore semaphore = semaphores.compute(key, (k, v) -> v == null ? new Semaphore(ALLOWED_THREADS) : v);
|
||||
semaphore.acquireUninterruptibly();
|
||||
}
|
||||
|
||||
public void unlock(String key) {
|
||||
Semaphore semaphore = semaphores.get(key);
|
||||
semaphore.release();
|
||||
if (semaphore.availablePermits() == ALLOWED_THREADS) {
|
||||
semaphores.remove(key, semaphore);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class LockByKeyUnitTest {
|
||||
|
||||
@Test
|
||||
void givenNoLockedKey_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
AtomicBoolean threadWasExecuted = new AtomicBoolean(false);
|
||||
Thread thread = new Thread(() -> {
|
||||
String key = "key";
|
||||
LockByKey lockByKey = new LockByKey();
|
||||
lockByKey.lock(key);
|
||||
try {
|
||||
threadWasExecuted.set(true);
|
||||
} finally {
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
thread.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(threadWasExecuted.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLockedKey_WhenLock_ThenFailure() throws InterruptedException {
|
||||
String key = "key";
|
||||
LockByKey lockByKey = new LockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
LockByKey otherLockByKey = new LockByKey();
|
||||
otherLockByKey.lock(key);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertFalse(anotherThreadWasExecuted.get());
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAnotherKeyLocked_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
String key = "key";
|
||||
LockByKey lockByKey = new LockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
String anotherKey = "anotherKey";
|
||||
LockByKey otherLockByKey = new LockByKey();
|
||||
otherLockByKey.lock(anotherKey);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(anotherKey);
|
||||
}
|
||||
});
|
||||
try {
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(anotherThreadWasExecuted.get());
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUnlockedKey_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
String key = "key";
|
||||
LockByKey lockByKey = new LockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
LockByKey otherLockByKey = new LockByKey();
|
||||
otherLockByKey.lock(key);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
lockByKey.unlock(key);
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(anotherThreadWasExecuted.get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SimpleExclusiveLockByKeyUnitTest {
|
||||
|
||||
@BeforeEach
|
||||
void cleanUpLocks() throws Exception {
|
||||
Field field = SimpleExclusiveLockByKey.class.getDeclaredField("usedKeys");
|
||||
field.setAccessible(true);
|
||||
field.set(null, ConcurrentHashMap.newKeySet());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNoLockedKey_WhenTryLock_ThenSuccess() {
|
||||
SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey();
|
||||
assertTrue(lockByKey.tryLock("key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLockedKey_WhenTryLock_ThenFailure() {
|
||||
String key = "key";
|
||||
SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey();
|
||||
lockByKey.tryLock(key);
|
||||
assertFalse(lockByKey.tryLock(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAnotherKeyLocked_WhenTryLock_ThenSuccess() {
|
||||
SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey();
|
||||
lockByKey.tryLock("other");
|
||||
assertTrue(lockByKey.tryLock("key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUnlockedKey_WhenTryLock_ThenSuccess() {
|
||||
String key = "key";
|
||||
SimpleExclusiveLockByKey lockByKey = new SimpleExclusiveLockByKey();
|
||||
lockByKey.tryLock(key);
|
||||
lockByKey.unlock(key);
|
||||
assertTrue(lockByKey.tryLock(key));
|
||||
}
|
||||
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package com.baeldung.lockbykey;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SimultaneousEntriesLockByKeyUnitTest {
|
||||
|
||||
@Test
|
||||
void givenNoKeyUsed_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
AtomicBoolean threadWasExecuted = new AtomicBoolean(false);
|
||||
Thread thread = new Thread(() -> {
|
||||
String key = "key";
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
try {
|
||||
threadWasExecuted.set(true);
|
||||
} finally {
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
thread.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(threadWasExecuted.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenKeyLockedWithRemainingPermits_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
String key = "key";
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
SimultaneousEntriesLockByKey otherLockByKeyWithSemaphore = new SimultaneousEntriesLockByKey();
|
||||
otherLockByKeyWithSemaphore.lock(key);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKeyWithSemaphore.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(anotherThreadWasExecuted.get());
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenKeyLockedWithNoRemainingPermits_WhenLock_ThenFailure() throws InterruptedException {
|
||||
String key = "key";
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey1 = new Thread(() -> {
|
||||
SimultaneousEntriesLockByKey otherLockByKeyWithSemaphore = new SimultaneousEntriesLockByKey();
|
||||
otherLockByKeyWithSemaphore.lock(key);
|
||||
try {
|
||||
Thread.sleep(200); // make sure this thread will release the lock after the assertion
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
} finally {
|
||||
otherLockByKeyWithSemaphore.unlock(key);
|
||||
}
|
||||
});
|
||||
Thread threadLockingOnAnotherKey2 = new Thread(() -> {
|
||||
SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey();
|
||||
try {
|
||||
Thread.sleep(50); // make sure thread1 will acquire the key first
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
otherLockByKey.lock(key);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
threadLockingOnAnotherKey1.start();
|
||||
threadLockingOnAnotherKey2.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertFalse(anotherThreadWasExecuted.get());
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAnotherKeyLocked_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
String key = "key";
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
String anotherKey = "anotherKey";
|
||||
SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey();
|
||||
otherLockByKey.lock(anotherKey);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(anotherKey);
|
||||
}
|
||||
});
|
||||
try {
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(anotherThreadWasExecuted.get());
|
||||
lockByKey.unlock(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUnlockedKey_WhenLock_ThenSuccess() throws InterruptedException {
|
||||
String key = "key";
|
||||
SimultaneousEntriesLockByKey lockByKey = new SimultaneousEntriesLockByKey();
|
||||
lockByKey.lock(key);
|
||||
AtomicBoolean anotherThreadWasExecuted = new AtomicBoolean(false);
|
||||
Thread threadLockingOnAnotherKey = new Thread(() -> {
|
||||
SimultaneousEntriesLockByKey otherLockByKey = new SimultaneousEntriesLockByKey();
|
||||
otherLockByKey.lock(key);
|
||||
try {
|
||||
anotherThreadWasExecuted.set(true);
|
||||
} finally {
|
||||
otherLockByKey.unlock(key);
|
||||
}
|
||||
});
|
||||
try {
|
||||
lockByKey.unlock(key);
|
||||
threadLockingOnAnotherKey.start();
|
||||
Thread.sleep(100);
|
||||
} finally {
|
||||
assertTrue(anotherThreadWasExecuted.get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+6
-1
@@ -7,7 +7,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class IllegalMonitorStateExceptionUnitTest {
|
||||
/**
|
||||
* Needs to be run manually in order to demonstrate the IllegalMonitorStateException scenarios.
|
||||
*
|
||||
* There are some intermittent test failures in Jenkins that require further investigation.
|
||||
*/
|
||||
public class IllegalMonitorStateExceptionManualTest {
|
||||
|
||||
@Test
|
||||
void whenSyncSenderAndSyncReceiverAreUsed_thenIllegalMonitorExceptionShouldNotBeThrown() throws InterruptedException {
|
||||
@@ -7,4 +7,5 @@ This module contains articles about core Java input and output (IO)
|
||||
- [Java File Separator vs File Path Separator](https://www.baeldung.com/java-file-vs-file-path-separator)
|
||||
- [Simulate touch Command in Java](https://www.baeldung.com/java-simulate-touch-command)
|
||||
- [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream)
|
||||
- [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-3)
|
||||
|
||||
+5
@@ -67,12 +67,17 @@ public class EmailService {
|
||||
MimeBodyPart mimeBodyPart = new MimeBodyPart();
|
||||
mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
|
||||
|
||||
String msgStyled = "This is my <b style='color:red;'>bold-red email</b> using JavaMailer";
|
||||
MimeBodyPart mimeBodyPartWithStyledText = new MimeBodyPart();
|
||||
mimeBodyPartWithStyledText.setContent(msgStyled, "text/html; charset=utf-8");
|
||||
|
||||
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
|
||||
|
||||
attachmentBodyPart.attachFile(getFile());
|
||||
|
||||
Multipart multipart = new MimeMultipart();
|
||||
multipart.addBodyPart(mimeBodyPart);
|
||||
multipart.addBodyPart(mimeBodyPartWithStyledText);
|
||||
multipart.addBodyPart(attachmentBodyPart);
|
||||
|
||||
message.setContent(multipart);
|
||||
|
||||
+9
-1
@@ -36,6 +36,7 @@ public class EmailServiceLiveTest {
|
||||
MimeMessage receivedMessage = receivedMessages[0];
|
||||
assertEquals("Mail Subject", subjectFromMessage(receivedMessage));
|
||||
assertEquals("This is my first email using JavaMailer", emailTextFrom(receivedMessage));
|
||||
assertEquals("This is my <b style='color:red;'>bold-red email</b> using JavaMailer", emailStyledTextFrom(receivedMessage));
|
||||
assertEquals("sample attachment content", attachmentContentsFrom(receivedMessage));
|
||||
}
|
||||
|
||||
@@ -50,9 +51,16 @@ public class EmailServiceLiveTest {
|
||||
.toString();
|
||||
}
|
||||
|
||||
private static String emailStyledTextFrom(MimeMessage receivedMessage) throws IOException, MessagingException {
|
||||
return ((MimeMultipart) receivedMessage.getContent())
|
||||
.getBodyPart(1)
|
||||
.getContent()
|
||||
.toString();
|
||||
}
|
||||
|
||||
private static String attachmentContentsFrom(MimeMessage receivedMessage) throws Exception {
|
||||
return ((MimeMultipart) receivedMessage.getContent())
|
||||
.getBodyPart(1)
|
||||
.getBodyPart(2)
|
||||
.getContent()
|
||||
.toString();
|
||||
}
|
||||
|
||||
@@ -12,4 +12,5 @@ This module contains articles about core Java non-blocking input and output (IO)
|
||||
- [Java NIO DatagramChannel](https://www.baeldung.com/java-nio-datagramchannel)
|
||||
- [Java – Path vs File](https://www.baeldung.com/java-path-vs-file)
|
||||
- [What Is the Difference Between NIO and NIO.2?](https://www.baeldung.com/java-nio-vs-nio-2)
|
||||
- [Guide to ByteBuffer](https://www.baeldung.com/java-bytebuffer)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-nio)
|
||||
|
||||
@@ -5,3 +5,4 @@ This module contains articles about GraphQL with Java
|
||||
## Relevant articles:
|
||||
|
||||
- [Introduction to GraphQL](https://www.baeldung.com/graphql)
|
||||
- [Make a Call to a GraphQL Service from a Java Application](https://www.baeldung.com/java-call-graphql-service)
|
||||
|
||||
@@ -11,5 +11,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
- [How to Set TLS Version in Apache HttpClient](https://www.baeldung.com/apache-httpclient-tls)
|
||||
- [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string)
|
||||
- [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies)
|
||||
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/java-httpclient-enable-logging)
|
||||
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging)
|
||||
- More articles: [[<-- prev]](../httpclient)
|
||||
|
||||
@@ -11,7 +11,7 @@ This module contains articles about HTTPClient that are part of the HTTPClient E
|
||||
- [Custom HTTP Header with the HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
|
||||
- [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication)
|
||||
- [Posting with HttpClient](https://www.baeldung.com/httpclient-post-http-request)
|
||||
- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/java-httpclient-parameters)
|
||||
- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters)
|
||||
|
||||
|
||||
### Running the Tests
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>mvc-2.0</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<name>mvc-2.0</name>
|
||||
|
||||
<properties>
|
||||
<jakartaee-api.version>9.0.0</jakartaee-api.version>
|
||||
<krazo.version>2.0.0</krazo.version>
|
||||
<jakarta.mvc-api.version>2.0.0</jakarta.mvc-api.version>
|
||||
<junit.jupiter.version>5.8.2</junit.jupiter.version>
|
||||
<local.glassfish.home>C:/glassfish6</local.glassfish.home>
|
||||
<local.glassfish.user>admin</local.glassfish.user>
|
||||
<local.glassfish.domain>mvn-domain</local.glassfish.domain>
|
||||
<mockito.version>1.10.19</mockito.version>
|
||||
<local.glassfish.passfile>
|
||||
${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
|
||||
</local.glassfish.passfile>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>jakarta.platform</groupId>
|
||||
<artifactId>jakarta.jakartaee-web-api</artifactId>
|
||||
<version>${jakartaee-api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.mvc</groupId>
|
||||
<artifactId>jakarta.mvc-api</artifactId>
|
||||
<version>${jakarta.mvc-api.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.krazo</groupId>
|
||||
<artifactId>krazo-jersey</artifactId>
|
||||
<version>${krazo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>mvc-2.0</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.glassfish.maven.plugin</groupId>
|
||||
<artifactId>maven-glassfish-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
|
||||
<user>admin</user>
|
||||
<!-- <passwordFile>${local.glassfish.passfile}</passwordFile>-->
|
||||
<adminPassword>password</adminPassword>
|
||||
|
||||
<domain>
|
||||
<name>${local.glassfish.domain}</name>
|
||||
<httpPort>8080</httpPort>
|
||||
<adminPort>4848</adminPort>
|
||||
|
||||
</domain>
|
||||
<components>
|
||||
<component>
|
||||
<name>${project.artifactId}</name>
|
||||
<artifact>target/${project.build.finalName}.war</artifact>
|
||||
|
||||
</component>
|
||||
</components>
|
||||
<debug>true</debug>
|
||||
<terse>false</terse>
|
||||
<echo>true</echo>
|
||||
|
||||
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.mvc.RedirectScoped;
|
||||
import jakarta.mvc.binding.MvcBinding;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import jakarta.ws.rs.FormParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Named("user")
|
||||
@RedirectScoped
|
||||
public class User implements Serializable {
|
||||
@MvcBinding
|
||||
@Null
|
||||
private String id;
|
||||
|
||||
@MvcBinding
|
||||
@NotNull
|
||||
@Size(min = 1, message = "Name cannot be blank")
|
||||
@FormParam("name")
|
||||
private String name;
|
||||
|
||||
@MvcBinding
|
||||
@Min(value = 18, message = "The minimum age of the user should be 18 years")
|
||||
@FormParam("age")
|
||||
private int age;
|
||||
|
||||
@MvcBinding
|
||||
@Email(message = "The email cannot be blank and should be in a valid format")
|
||||
@Size(min=3, message = "Email cannot be empty")
|
||||
@FormParam("email")
|
||||
private String email;
|
||||
|
||||
@MvcBinding
|
||||
@Null
|
||||
@FormParam("phone")
|
||||
private String phone;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.eclipse.krazo;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
|
||||
/**
|
||||
* Default JAX-RS application listening on /app
|
||||
*/
|
||||
@ApplicationPath("/app")
|
||||
public class UserApplication extends Application {
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user