diff --git a/configuration/pom.xml b/configuration/pom.xml
index 7a6d251..a80b2ef 100644
--- a/configuration/pom.xml
+++ b/configuration/pom.xml
@@ -24,7 +24,7 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
shared-configuration
diff --git a/db/pom.xml b/db/pom.xml
index 7da2bd6..99d5f71 100644
--- a/db/pom.xml
+++ b/db/pom.xml
@@ -25,7 +25,7 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
shared-db
@@ -75,7 +75,6 @@ limitations under the License.
org.projectlombok
lombok
provided
- 1.18.12
diff --git a/jeeutil/pom.xml b/jeeutil/pom.xml
index 6f19b5b..4072621 100644
--- a/jeeutil/pom.xml
+++ b/jeeutil/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
de.muehlencord.shared
diff --git a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/GenericEnumType.java b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/GenericEnumType.java
index bebcbfa..2886f24 100644
--- a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/GenericEnumType.java
+++ b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/GenericEnumType.java
@@ -47,29 +47,29 @@ public abstract class GenericEnumType> implements UserType,
for (E e : enumValues) {
- @SuppressWarnings("unchecked")
- T value = (T) m.invoke(e);
+ @SuppressWarnings("unchecked")
+ T value = (T) m.invoke(e);
- enumMap.put(value.toString(), e);
- valueMap.put(e, value.toString());
+ enumMap.put(value.toString(), e);
+ valueMap.put(e, value.toString());
}
- this.sqlType = sqlType;
+ this.sqlType = sqlType;
}
- @Override
- public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException {
- return nullSafeGet(rs, names, owner);
- }
+ @Override
+ public Object nullSafeGet(ResultSet rs, int index, SharedSessionContractImplementor implementor, Object o) throws SQLException {
+ return nullSafeGet(rs, index, implementor);
+ }
- @Override
- public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
- nullSafeSet(st, value, index);
- }
-
- @Override
- public Object assemble(Serializable cached, Object owner) {
- return cached;
- }
+ @Override
+ public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException {
+ nullSafeSet(st, value, index);
+ }
+
+ @Override
+ public Object assemble(Serializable cached, Object owner) {
+ return cached;
+ }
@Override
public Object deepCopy(Object obj) {
@@ -94,28 +94,28 @@ public abstract class GenericEnumType> implements UserType,
}
}
- @Override
- public int hashCode(Object obj) {
- return obj.hashCode();
- }
+ @Override
+ public int hashCode(Object obj) {
+ return obj.hashCode();
+ }
- @Override
- public boolean isMutable() {
- return false;
- }
+ @Override
+ public boolean isMutable() {
+ return false;
+ }
- public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
- String value = rs.getString(names[0]);
- if (!rs.wasNull()) {
- return enumMap.get(value);
- }
- return null;
+ public Object nullSafeGet(ResultSet rs, int index, Object owner) throws SQLException {
+ String value = rs.getString(index);
+ if (!rs.wasNull()) {
+ return enumMap.get(value);
}
+ return null;
+ }
- public void nullSafeSet(PreparedStatement ps, Object obj, int index) throws SQLException {
- if (obj == null) {
- ps.setNull(index, sqlType);
- } else {
+ public void nullSafeSet(PreparedStatement ps, Object obj, int index) throws SQLException {
+ if (obj == null) {
+ ps.setNull(index, sqlType);
+ } else {
ps.setObject(index, valueMap.get(obj), sqlType);
}
}
@@ -130,9 +130,5 @@ public abstract class GenericEnumType> implements UserType,
return clazz;
}
- @Override
- public int[] sqlTypes() {
- return new int[]{sqlType};
- }
}
diff --git a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/APIErrorResponse.java b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/APIErrorResponse.java
index 814ada4..a803ed4 100644
--- a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/APIErrorResponse.java
+++ b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/APIErrorResponse.java
@@ -15,14 +15,14 @@
*/
package de.muehlencord.shared.jeeutil.restexfw;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlRootElement;
+import jakarta.xml.bind.annotation.XmlType;
+import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.ws.rs.core.Response;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
/**
*
diff --git a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ConstraintViolationEntry.java b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ConstraintViolationEntry.java
index 6e0d6a8..a19500c 100644
--- a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ConstraintViolationEntry.java
+++ b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ConstraintViolationEntry.java
@@ -15,12 +15,12 @@
*/
package de.muehlencord.shared.jeeutil.restexfw;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlRootElement;
import java.util.Iterator;
import javax.validation.ConstraintViolation;
import javax.validation.Path;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
/**
*
diff --git a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ResponseStatusAdapter.java b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ResponseStatusAdapter.java
index 29eb71b..e77fe50 100644
--- a/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ResponseStatusAdapter.java
+++ b/jeeutil/src/main/java/de/muehlencord/shared/jeeutil/restexfw/ResponseStatusAdapter.java
@@ -15,23 +15,23 @@
*/
package de.muehlencord.shared.jeeutil.restexfw;
+import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import javax.ws.rs.core.Response;
-import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.ws.rs.core.Response.Status;
/**
- *
* @author Joern Muehlencord (joern@muehlencord.de)
*/
-public class ResponseStatusAdapter extends XmlAdapter {
+public class ResponseStatusAdapter extends XmlAdapter {
- @Override
- public String marshal(Response.Status status) throws Exception {
- return status.name();
- }
+ @Override
+ public String marshal(Response.Status status) throws Exception {
+ return status.name();
+ }
- @Override
- public Response.Status unmarshal(String statusAsString) throws Exception {
- return Response.Status.valueOf(statusAsString);
- }
+ @Override
+ public Response.Status unmarshal(String statusAsString) throws Exception {
+ return Response.Status.valueOf(statusAsString);
+ }
}
diff --git a/network/pom.xml b/network/pom.xml
index 16a9dbf..0f406a9 100644
--- a/network/pom.xml
+++ b/network/pom.xml
@@ -72,7 +72,7 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
UTF-8
@@ -80,5 +80,5 @@ limitations under the License.
http://maven.apache.org
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
diff --git a/poi-util/pom.xml b/poi-util/pom.xml
index 7c798a5..04868a7 100644
--- a/poi-util/pom.xml
+++ b/poi-util/pom.xml
@@ -47,9 +47,9 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
diff --git a/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java b/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
index 71ff311..17868fa 100644
--- a/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
+++ b/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
@@ -1,323 +1,322 @@
-/*
- * Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package de.muehlencord.shared.poi;
-
-import de.muehlencord.shared.util.file.FileUtil;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
-import org.apache.poi.ss.formula.FormulaParser;
-import org.apache.poi.ss.formula.FormulaRenderer;
-import org.apache.poi.ss.formula.FormulaType;
-import org.apache.poi.ss.formula.ptg.Ptg;
-import org.apache.poi.ss.formula.ptg.RefPtgBase;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.ss.usermodel.DataValidation;
-import org.apache.poi.ss.usermodel.DataValidationHelper;
-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.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.CellRangeAddressList;
-import org.apache.poi.xssf.usermodel.XSSFDataValidation;
-import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author Joern Muehlencord (joern@muehlencord.de)
- */
-public class WorkbookApp {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(WorkbookApp.class);
-
- /**
- * the workbook to work on
- */
- protected Workbook wb;
-
- /**
- * opens the given workbook
- *
- * @param filename path and filename of the workbook to open.
- * @return the workbook loaded
- * @throws FileNotFoundException if the workbook cannot be found
- * @throws IOException if the workbook cannot be loaded
- */
- public Workbook loadWorkbook(String filename) throws IOException {
- if (filename.toLowerCase().endsWith(".xlsx")) {
- FileInputStream fis = new FileInputStream(new File(filename));
- return new XSSFWorkbook(fis);
- } else {
- POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filename));
- return new HSSFWorkbook(fs, true);
- }
- }
-
- /**
- * stores the (changed) workbook under the given filename
- *
- * @param filename the path and name of the file to store the workbook
- * under.
- * @throws FileNotFoundException if the path is not found
- * @throws IOException if the file cannot be genrated.
- */
- public void storeWorkbook(String filename) throws IOException {
- FileOutputStream fos = new FileOutputStream(new File(filename));
- wb.write(fos);
- }
-
- /**
- * stores the (changed) workbook under the given filename
- *
- * @param fileName the path and name of the file to store the workbook
- * under.
- * @param tempName a temporary name the file is stored under before it is
- * renamed to fileName. This is required as POI cannot open and store a
- * Workbook under the same name.
- * @throws FileNotFoundException if the path is not found
- * @throws IOException if the file cannot be generated.
- */
- public void storeWorkbook(String fileName, String tempName) throws IOException {
- FileOutputStream fos = new FileOutputStream(new File(tempName));
- wb.write(fos);
-
- File source = Paths.get(tempName).toFile();
- File destination = Paths.get(fileName).toFile();
- FileUtil.moveFileTo(source, destination);
- }
-
- protected void copyColumn(Sheet oldSheet, int oldColumn, Sheet newSheet, int newColumn) {
- int maxRowNum = oldSheet.getLastRowNum();
- for (int i = 0; i <= maxRowNum; i++) {
- Row currentRow = oldSheet.getRow(i);
- if (currentRow != null) {
- Cell sourceCell = currentRow.getCell(oldColumn);
- Cell destCell = currentRow.createCell(newColumn);
- copyCell(sourceCell, destCell, null); // copy to same sheet, cellStyle map not needed
-
- CellRangeAddress oldRegion = getMergedRegion(oldSheet, i, oldColumn);
- CellRangeAddress newRegion = getMergedRegion(newSheet, i, newColumn);
- if (oldRegion != null && newRegion == null) {
-
- if (oldSheet != newSheet | oldRegion.getFirstColumn() == oldColumn) {
- // region starts in this column; create new one
- int firstRow = oldRegion.getFirstRow();
- int lastRow = oldRegion.getLastRow();
- int firstColumn = oldRegion.getFirstColumn() + newColumn - oldColumn;
- int lastColumn = oldRegion.getLastColumn() + newColumn - oldColumn;
-
- newRegion = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
- newSheet.addMergedRegion(newRegion);
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Created new merged region {}", newRegion.toString());
- }
- } else {
- // region contains source column, extend column to including new column
- Integer mergedRegionIndex = getMergedRegionIndex(oldSheet, oldRegion);
- if (mergedRegionIndex != null) {
- oldSheet.removeMergedRegion(mergedRegionIndex);
- }
-
- int firstRow = oldRegion.getFirstRow();
- int lastRow = oldRegion.getLastRow();
- int firstColumn = oldRegion.getFirstColumn();
- int lastColumn = newColumn;
-
- newRegion = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
- newSheet.addMergedRegion(newRegion);
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Updated merged region from {} to ", oldRegion.toString(), newRegion.toString());
- }
- }
- }
- }
- }
- newSheet.setColumnWidth(newColumn, oldSheet.getColumnWidth(oldColumn));
- }
-
- protected void copyCell(Cell oldCell, Cell newCell, Map styleMap) {
- if (oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()) {
- newCell.setCellStyle(oldCell.getCellStyle());
- } else if (styleMap != null) {
- int stHashCode = oldCell.getCellStyle().hashCode();
- CellStyle newCellStyle = styleMap.get(stHashCode);
- if (newCellStyle == null) {
- newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
- newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
- styleMap.put(stHashCode, newCellStyle);
- }
- newCell.setCellStyle(newCellStyle);
- }
-
- switch (oldCell.getCellType()) {
- case STRING:
- newCell.setCellValue(oldCell.getStringCellValue());
- break;
- case NUMERIC:
- newCell.setCellValue(oldCell.getNumericCellValue());
- break;
- case BLANK:
- newCell.setCellType(CellType.BLANK);
- break;
- case BOOLEAN:
- newCell.setCellValue(oldCell.getBooleanCellValue());
- break;
- case ERROR:
- newCell.setCellErrorValue(oldCell.getErrorCellValue());
- break;
- case FORMULA:
- String formula = oldCell.getCellFormula();
- XSSFEvaluationWorkbook workbookWrapper = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
- /* parse formula */
- Ptg[] ptgs = FormulaParser.parse(formula, workbookWrapper, FormulaType.CELL, 0 /*sheet index*/);
- /* re-calculate cell references */
- for (Ptg ptg : ptgs) {
- //base class for cell reference "things"
- if (ptg instanceof RefPtgBase) {
- RefPtgBase ref = (RefPtgBase) ptg;
- if (ref.isColRelative()) {
- ref.setColumn(ref.getColumn() + newCell.getColumnIndex() - oldCell.getColumnIndex());
- }
- if (ref.isRowRelative()) {
- ref.setRow(ref.getRow() + +newCell.getRowIndex() - oldCell.getRowIndex());
- }
- }
- }
- formula = FormulaRenderer.toFormulaString(workbookWrapper, ptgs);
- newCell.setCellFormula(formula);
- break;
- default:
- break;
- }
-
- XSSFSheet sheet = (XSSFSheet) oldCell.getSheet();
-
- // TODO copy conditional formating
- // FIXME - does not work, it does not take care about formulas at the moment
- /*
-
- XSSFSheetConditionalFormatting conditionalFormatting = sheet.getSheetConditionalFormatting();
- int countConditionalFormatting = conditionalFormatting.getNumConditionalFormattings();
- for (int i = 0; i < countConditionalFormatting; i++) {
- XSSFConditionalFormatting currentFormatting = conditionalFormatting.getConditionalFormattingAt(i);
- CellRangeAddress[] cellRangeAddresses = currentFormatting.getFormattingRanges();
- boolean oldCellHasConditionalFormatting = false;
- for (CellRangeAddress currentCellRange : cellRangeAddresses) {
- oldCellHasConditionalFormatting = currentCellRange.containsRow(oldCell.getRowIndex()) && currentCellRange.containsColumn(oldCell.getColumnIndex());
- }
- if (oldCellHasConditionalFormatting) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Found conditional formatting for cell {} ", oldCell.getAddress().toString());
- }
-
-
-
- // add the new cell to the cell rang addresses
- CellRangeAddress[] newCellRangeAddresses = new CellRangeAddress[cellRangeAddresses.length+1];
- for (int j = 0; j < cellRangeAddresses.length; j++) {
- newCellRangeAddresses[j] = cellRangeAddresses[j];
- }
- newCellRangeAddresses[cellRangeAddresses.length] = new CellRangeAddress (newCell.getRowIndex(), newCell.getRowIndex(), newCell.getColumnIndex(), newCell.getColumnIndex());
- currentFormatting.setFormattingRanges(newCellRangeAddresses);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Copied conditional formatting to cell {}", newCell.getAddress().toString());
- }
-
- }
- }
- */
- // SheetConditionalFormatting cf = oldCell.getSheet().getSheetConditionalFormatting();
- // copy data constraints
- List dataValidations = sheet.getDataValidations();
- DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
-
- Iterator it = dataValidations.iterator();
-
- while (it.hasNext()) {
- XSSFDataValidation dataValidation = it.next();
- boolean oldCellHasDataValidation = false;
- CellRangeAddress[] cellRangeAddresses = dataValidation.getRegions().getCellRangeAddresses();
- for (CellRangeAddress currentCellRange : cellRangeAddresses) {
- oldCellHasDataValidation = currentCellRange.containsRow(oldCell.getRowIndex()) && currentCellRange.containsColumn(oldCell.getColumnIndex());
- }
- if (oldCellHasDataValidation) {
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Found data validation for cell {} ", oldCell.getAddress().toString());
- }
-
- CellRangeAddressList newCellRangeList = new CellRangeAddressList(newCell.getRowIndex(), newCell.getRowIndex(), newCell.getColumnIndex(), newCell.getColumnIndex());
- DataValidation newValidation = dataValidationHelper.createValidation(dataValidation.getValidationConstraint(), newCellRangeList);
- sheet.addValidationData(newValidation);
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Copied data validation to cell {}", newCell.getAddress().toString());
- }
- }
- }
- }
-
- protected CellRangeAddress getMergedRegion(Sheet sheet, int rowNum, int cellNum) {
- for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
- CellRangeAddress merged = sheet.getMergedRegion(i);
- if (merged.isInRange(rowNum, cellNum)) {
- return merged;
- }
- }
- return null;
- }
-
- protected Integer getMergedRegionIndex(Sheet sheet, CellRangeAddress mergedRegion) {
- for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
- CellRangeAddress merged = sheet.getMergedRegion(i);
- if ((merged.getFirstColumn() == mergedRegion.getFirstColumn())
- && (merged.getLastColumn() == mergedRegion.getLastColumn())
- && (merged.getFirstRow() == mergedRegion.getFirstRow())
- && (merged.getLastRow() == mergedRegion.getLastRow())) {
- return i;
- }
- }
- return null;
- }
-
- protected void autoResizeColumns(Sheet sheet) {
- autoResizeColumns(sheet,0);
- }
-
- protected void autoResizeColumns(Sheet sheet, int referenceRow) {
- int maxColumn = sheet.getRow(referenceRow).getPhysicalNumberOfCells();
- for (int currentColumn = 0; currentColumn < maxColumn; currentColumn++) {
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Auto resize column {}/{}", currentColumn, maxColumn);
- }
-
- sheet.autoSizeColumn(currentColumn);
- }
- }
-
-}
+/*
+ * Copyright 2019 Joern Muehlencord (joern@muehlencord.de).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.muehlencord.shared.poi;
+
+import de.muehlencord.shared.util.file.FileUtil;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.formula.FormulaParser;
+import org.apache.poi.ss.formula.FormulaRenderer;
+import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.RefPtgBase;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataValidation;
+import org.apache.poi.ss.usermodel.DataValidationHelper;
+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.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.usermodel.XSSFDataValidation;
+import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Joern Muehlencord (joern@muehlencord.de)
+ */
+public class WorkbookApp {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(WorkbookApp.class);
+
+ /**
+ * the workbook to work on
+ */
+ protected Workbook wb;
+
+ /**
+ * opens the given workbook
+ *
+ * @param filename path and filename of the workbook to open.
+ * @return the workbook loaded
+ * @throws FileNotFoundException if the workbook cannot be found
+ * @throws IOException if the workbook cannot be loaded
+ */
+ public Workbook loadWorkbook(String filename) throws IOException {
+ if (filename.toLowerCase().endsWith(".xlsx")) {
+ FileInputStream fis = new FileInputStream(new File(filename));
+ return new XSSFWorkbook(fis);
+ } else {
+ POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filename));
+ return new HSSFWorkbook(fs, true);
+ }
+ }
+
+ /**
+ * stores the (changed) workbook under the given filename
+ *
+ * @param filename the path and name of the file to store the workbook
+ * under.
+ * @throws FileNotFoundException if the path is not found
+ * @throws IOException if the file cannot be genrated.
+ */
+ public void storeWorkbook(String filename) throws IOException {
+ FileOutputStream fos = new FileOutputStream(new File(filename));
+ wb.write(fos);
+ }
+
+ /**
+ * stores the (changed) workbook under the given filename
+ *
+ * @param fileName the path and name of the file to store the workbook
+ * under.
+ * @param tempName a temporary name the file is stored under before it is
+ * renamed to fileName. This is required as POI cannot open and store a
+ * Workbook under the same name.
+ * @throws FileNotFoundException if the path is not found
+ * @throws IOException if the file cannot be generated.
+ */
+ public void storeWorkbook(String fileName, String tempName) throws IOException {
+ FileOutputStream fos = new FileOutputStream(new File(tempName));
+ wb.write(fos);
+
+ File source = Paths.get(tempName).toFile();
+ File destination = Paths.get(fileName).toFile();
+ FileUtil.moveFileTo(source, destination);
+ }
+
+ protected void copyColumn(Sheet oldSheet, int oldColumn, Sheet newSheet, int newColumn) {
+ int maxRowNum = oldSheet.getLastRowNum();
+ for (int i = 0; i <= maxRowNum; i++) {
+ Row currentRow = oldSheet.getRow(i);
+ if (currentRow != null) {
+ Cell sourceCell = currentRow.getCell(oldColumn);
+ Cell destCell = currentRow.createCell(newColumn);
+ copyCell(sourceCell, destCell, null); // copy to same sheet, cellStyle map not needed
+
+ CellRangeAddress oldRegion = getMergedRegion(oldSheet, i, oldColumn);
+ CellRangeAddress newRegion = getMergedRegion(newSheet, i, newColumn);
+ if (oldRegion != null && newRegion == null) {
+
+ if (oldSheet != newSheet | oldRegion.getFirstColumn() == oldColumn) {
+ // region starts in this column; create new one
+ int firstRow = oldRegion.getFirstRow();
+ int lastRow = oldRegion.getLastRow();
+ int firstColumn = oldRegion.getFirstColumn() + newColumn - oldColumn;
+ int lastColumn = oldRegion.getLastColumn() + newColumn - oldColumn;
+
+ newRegion = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
+ newSheet.addMergedRegion(newRegion);
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Created new merged region {}", newRegion.toString());
+ }
+ } else {
+ // region contains source column, extend column to including new column
+ Integer mergedRegionIndex = getMergedRegionIndex(oldSheet, oldRegion);
+ if (mergedRegionIndex != null) {
+ oldSheet.removeMergedRegion(mergedRegionIndex);
+ }
+
+ int firstRow = oldRegion.getFirstRow();
+ int lastRow = oldRegion.getLastRow();
+ int firstColumn = oldRegion.getFirstColumn();
+ int lastColumn = newColumn;
+
+ newRegion = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
+ newSheet.addMergedRegion(newRegion);
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Updated merged region from {} to ", oldRegion.toString(), newRegion.toString());
+ }
+ }
+ }
+ }
+ }
+ newSheet.setColumnWidth(newColumn, oldSheet.getColumnWidth(oldColumn));
+ }
+
+ protected void copyCell(Cell oldCell, Cell newCell, Map styleMap) {
+ if (oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()) {
+ newCell.setCellStyle(oldCell.getCellStyle());
+ } else if (styleMap != null) {
+ int stHashCode = oldCell.getCellStyle().hashCode();
+ CellStyle newCellStyle = styleMap.get(stHashCode);
+ if (newCellStyle == null) {
+ newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
+ newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
+ styleMap.put(stHashCode, newCellStyle);
+ }
+ newCell.setCellStyle(newCellStyle);
+ }
+
+ switch (oldCell.getCellType()) {
+ case STRING:
+ newCell.setCellValue(oldCell.getStringCellValue());
+ break;
+ case NUMERIC:
+ newCell.setCellValue(oldCell.getNumericCellValue());
+ break;
+ case BLANK:
+ newCell.setBlank();
+ break;
+ case BOOLEAN:
+ newCell.setCellValue(oldCell.getBooleanCellValue());
+ break;
+ case ERROR:
+ newCell.setCellErrorValue(oldCell.getErrorCellValue());
+ break;
+ case FORMULA:
+ String formula = oldCell.getCellFormula();
+ XSSFEvaluationWorkbook workbookWrapper = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
+ /* parse formula */
+ Ptg[] ptgs = FormulaParser.parse(formula, workbookWrapper, FormulaType.CELL, 0 /*sheet index*/);
+ /* re-calculate cell references */
+ for (Ptg ptg : ptgs) {
+ //base class for cell reference "things"
+ if (ptg instanceof RefPtgBase) {
+ RefPtgBase ref = (RefPtgBase) ptg;
+ if (ref.isColRelative()) {
+ ref.setColumn(ref.getColumn() + newCell.getColumnIndex() - oldCell.getColumnIndex());
+ }
+ if (ref.isRowRelative()) {
+ ref.setRow(ref.getRow() + +newCell.getRowIndex() - oldCell.getRowIndex());
+ }
+ }
+ }
+ formula = FormulaRenderer.toFormulaString(workbookWrapper, ptgs);
+ newCell.setCellFormula(formula);
+ break;
+ default:
+ break;
+ }
+
+ XSSFSheet sheet = (XSSFSheet) oldCell.getSheet();
+
+ // TODO copy conditional formating
+ // FIXME - does not work, it does not take care about formulas at the moment
+ /*
+
+ XSSFSheetConditionalFormatting conditionalFormatting = sheet.getSheetConditionalFormatting();
+ int countConditionalFormatting = conditionalFormatting.getNumConditionalFormattings();
+ for (int i = 0; i < countConditionalFormatting; i++) {
+ XSSFConditionalFormatting currentFormatting = conditionalFormatting.getConditionalFormattingAt(i);
+ CellRangeAddress[] cellRangeAddresses = currentFormatting.getFormattingRanges();
+ boolean oldCellHasConditionalFormatting = false;
+ for (CellRangeAddress currentCellRange : cellRangeAddresses) {
+ oldCellHasConditionalFormatting = currentCellRange.containsRow(oldCell.getRowIndex()) && currentCellRange.containsColumn(oldCell.getColumnIndex());
+ }
+ if (oldCellHasConditionalFormatting) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Found conditional formatting for cell {} ", oldCell.getAddress().toString());
+ }
+
+
+
+ // add the new cell to the cell rang addresses
+ CellRangeAddress[] newCellRangeAddresses = new CellRangeAddress[cellRangeAddresses.length+1];
+ for (int j = 0; j < cellRangeAddresses.length; j++) {
+ newCellRangeAddresses[j] = cellRangeAddresses[j];
+ }
+ newCellRangeAddresses[cellRangeAddresses.length] = new CellRangeAddress (newCell.getRowIndex(), newCell.getRowIndex(), newCell.getColumnIndex(), newCell.getColumnIndex());
+ currentFormatting.setFormattingRanges(newCellRangeAddresses);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Copied conditional formatting to cell {}", newCell.getAddress().toString());
+ }
+
+ }
+ }
+ */
+ // SheetConditionalFormatting cf = oldCell.getSheet().getSheetConditionalFormatting();
+ // copy data constraints
+ List dataValidations = sheet.getDataValidations();
+ DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
+
+ Iterator it = dataValidations.iterator();
+
+ while (it.hasNext()) {
+ XSSFDataValidation dataValidation = it.next();
+ boolean oldCellHasDataValidation = false;
+ CellRangeAddress[] cellRangeAddresses = dataValidation.getRegions().getCellRangeAddresses();
+ for (CellRangeAddress currentCellRange : cellRangeAddresses) {
+ oldCellHasDataValidation = currentCellRange.containsRow(oldCell.getRowIndex()) && currentCellRange.containsColumn(oldCell.getColumnIndex());
+ }
+ if (oldCellHasDataValidation) {
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Found data validation for cell {} ", oldCell.getAddress().toString());
+ }
+
+ CellRangeAddressList newCellRangeList = new CellRangeAddressList(newCell.getRowIndex(), newCell.getRowIndex(), newCell.getColumnIndex(), newCell.getColumnIndex());
+ DataValidation newValidation = dataValidationHelper.createValidation(dataValidation.getValidationConstraint(), newCellRangeList);
+ sheet.addValidationData(newValidation);
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Copied data validation to cell {}", newCell.getAddress().toString());
+ }
+ }
+ }
+ }
+
+ protected CellRangeAddress getMergedRegion(Sheet sheet, int rowNum, int cellNum) {
+ for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+ CellRangeAddress merged = sheet.getMergedRegion(i);
+ if (merged.isInRange(rowNum, cellNum)) {
+ return merged;
+ }
+ }
+ return null;
+ }
+
+ protected Integer getMergedRegionIndex(Sheet sheet, CellRangeAddress mergedRegion) {
+ for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+ CellRangeAddress merged = sheet.getMergedRegion(i);
+ if ((merged.getFirstColumn() == mergedRegion.getFirstColumn())
+ && (merged.getLastColumn() == mergedRegion.getLastColumn())
+ && (merged.getFirstRow() == mergedRegion.getFirstRow())
+ && (merged.getLastRow() == mergedRegion.getLastRow())) {
+ return i;
+ }
+ }
+ return null;
+ }
+
+ protected void autoResizeColumns(Sheet sheet) {
+ autoResizeColumns(sheet,0);
+ }
+
+ protected void autoResizeColumns(Sheet sheet, int referenceRow) {
+ int maxColumn = sheet.getRow(referenceRow).getPhysicalNumberOfCells();
+ for (int currentColumn = 0; currentColumn < maxColumn; currentColumn++) {
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Auto resize column {}/{}", currentColumn, maxColumn);
+ }
+
+ sheet.autoSizeColumn(currentColumn);
+ }
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index a2a0162..eb23238 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@ limitations under the License.
4.0.0
shared
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
shared
pom
@@ -74,12 +74,26 @@ limitations under the License.
- 11
- 11
+ 17
+ 17
+ 17
+ 17
UTF-8
- 1.7.32
- 2.13.0
+ 2.0.6
+ 2.14.2
+ 1.11.0
+ 1.18.26
+ 5.9.2
+ 12.0.0
+ 1.6.1
+ 4.0.1
+ 5.2.3
+ 3.9.0
+ 2.10.1
+ 5.2.2
+ 1.70
+ 6.1.7.Final
@@ -113,7 +127,7 @@ limitations under the License.
commons-net
commons-net
- 3.8.0
+ ${commons-net.version}
commons-lang3
@@ -154,7 +168,7 @@ limitations under the License.
gson
com.google.code.gson
- 2.8.9
+ ${gson.version}
jackson-annotations
@@ -176,12 +190,12 @@ limitations under the License.
shiro-core
org.apache.shiro
- 1.7.1
+ ${shiro.version}
shiro-web
org.apache.shiro
- 1.7.1
+ ${shiro.version}
javaee-api
@@ -202,39 +216,39 @@ limitations under the License.
bcprov-jdk15on
org.bouncycastle
- 1.68
+ ${bouncycastle.version}
hibernate-core
org.hibernate
jar
- 5.6.3.Final
+ ${hibernate.version}
primefaces
org.primefaces
- 10.0.0
+ ${primefaces.version}
admin-template
com.github.adminfaces
- 1.3.0
+ ${adminfaces-template.version}
omnifaces
org.omnifaces
- 3.4.1
+ ${omnifaces.version}
poi-ooxml
org.apache.poi
- 5.2.0
+ ${poi.version}
fusionauth-jwt
io.fusionauth
- 4.1.0
+ ${fusionauth.version}
@@ -242,7 +256,7 @@ limitations under the License.
lombok
org.projectlombok
provided
- 1.18.22
+ ${lombok.version}
@@ -250,7 +264,7 @@ limitations under the License.
junit-jupiter-engine
org.junit.jupiter
test
- 5.8.2
+ ${junit.version}
diff --git a/shiro-faces/pom.xml b/shiro-faces/pom.xml
index 056d40e..0b2d14d 100644
--- a/shiro-faces/pom.xml
+++ b/shiro-faces/pom.xml
@@ -24,7 +24,7 @@ limitations under the License.
de.muehlencord
shared
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
shared-shiro-faces
diff --git a/util/pom.xml b/util/pom.xml
index d9a6442..cb1209b 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -26,7 +26,7 @@ limitations under the License.
shared
de.muehlencord
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT