
eu.hansolo.toolbox.Helper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of toolbox Show documentation
Show all versions of toolbox Show documentation
Toolbox contains a collection of useful tools incl. events, properties, helper classes etc.
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2016-2021 Gerrit Grunwald.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.hansolo.toolbox;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.WeekFields;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.stream.Collector;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import static eu.hansolo.toolbox.Constants.EPSILON;
import static eu.hansolo.toolbox.Constants.FLOAT_PATTERN;
import static eu.hansolo.toolbox.Constants.HEX_PATTERN;
import static eu.hansolo.toolbox.Constants.INT_PATTERN;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Helper {
private Helper() {}
private static final Matcher INT_MATCHER = INT_PATTERN.matcher("");
private static final Matcher FLOAT_MATCHER = FLOAT_PATTERN.matcher("");
private static final Matcher HEX_MATCHER = HEX_PATTERN.matcher("");
public static final T clamp(final T min, final T max, final T value) {
if (value.doubleValue() < min.doubleValue()) return min;
if (value.doubleValue() > max.doubleValue()) return max;
return value;
}
public static final int clamp(final int min, final int max, final int value) {
if (value < min) return min;
if (value > max) return max;
return value;
}
public static final long clamp(final long min, final long max, final long value) {
if (value < min) return min;
if (value > max) return max;
return value;
}
public static final double clamp(final double min, final double max, final double value) {
if (Double.compare(value, min) < 0) return min;
if (Double.compare(value, max) > 0) return max;
return value;
}
public static final Instant clamp(final Instant min, final Instant max, final Instant value) {
if (value.isBefore(min)) return min;
if (value.isAfter(max)) return max;
return value;
}
public static final LocalDateTime clamp(final LocalDateTime min, final LocalDateTime max, final LocalDateTime value) {
if (value.isBefore(min)) return min;
if (value.isAfter(max)) return max;
return value;
}
public static final LocalDate clamp(final LocalDate min, final LocalDate max, final LocalDate value) {
if (value.isBefore(min)) return min;
if (value.isAfter(max)) return max;
return value;
}
public static final double clampMin(final double min, final double value) {
if (value < min) return min;
return value;
}
public static final double clampMax(final double max, final double value) {
if (value > max) return max;
return value;
}
public static final boolean almostEqual(final double value1, final double value2, final double epsilon) {
return Math.abs(value1 - value2) < epsilon;
}
public static final double round(final double value, final int precision) {
final int SCALE = (int) Math.pow(10, precision);
return (double) Math.round(value * SCALE) / SCALE;
}
public static final double roundTo(final double value, final double target) { return target * (Math.round(value / target)); }
public static final double roundToHalf(final double value) { return Math.round(value * 2) / 2.0; }
public static final int roundDoubleToInt(final double value){
double dAbs = Math.abs(value);
int i = (int) dAbs;
double result = dAbs - (double) i;
if (result < 0.5) {
return value < 0 ? -i : i;
} else {
return value < 0 ? -(i + 1) : i + 1;
}
}
public static final boolean equals(final double a, final double b) { return a == b || Math.abs(a - b) < EPSILON; }
public static final boolean biggerThan(final double a, final double b) { return (a - b) > EPSILON; }
public static final boolean lessThan(final double a, final double b) { return (b - a) > EPSILON; }
public static final boolean isPositiveInteger(final String text) {
if (null == text || text.isEmpty()) { return false; }
return Constants.POSITIVE_INTEGER_PATTERN.matcher(text).matches();
}
public static final String trimPrefix(final String text, final String prefix) {
return text.replaceFirst(prefix, "");
}
public static final DateTimeFormatter getDateFormat(final Locale locale) {
if (Locale.US == locale) {
return DateTimeFormatter.ofPattern("MM/dd/YYYY");
} else if (Locale.CHINA == locale) {
return DateTimeFormatter.ofPattern("YYYY.MM.dd");
} else {
return DateTimeFormatter.ofPattern("dd.MM.YYYY");
}
}
public static final DateTimeFormatter getLocalizedDateFormat(final Locale locale) {
return DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withLocale(locale);
}
public static final String normalize(final String text) {
String normalized = text.replace("\u00fc", "ue")
.replace("\u00f6", "oe")
.replace("\u00e4", "ae")
.replace("\u00df", "ss");
normalized = normalized.replace("\u00dc(?=[a-z\u00fc\u00f6\u00e4\u00df ])", "Ue")
.replace("\u00d6(?=[a-z\u00fc\u00f6\u00e4\u00df ])", "Oe")
.replace("\u00c4(?=[a-z\u00fc\u00f6\u00e4\u00df ])", "Ae");
normalized = normalized.replace("\u00dc", "UE")
.replace("\u00d6", "OE")
.replace("\u00c4", "AE");
return normalized;
}
public static final int getDegrees(final double decDeg) { return (int) decDeg; }
public static final int getMinutes(final double decDeg) { return (int) ((decDeg - getDegrees(decDeg)) * 60); }
public static final double getSeconds(final double decDeg) { return (((decDeg - getDegrees(decDeg)) * 60) - getMinutes(decDeg)) * 60; }
public static final double getDecimalDeg(final int degrees, final int minutes, final double seconds) {
return (((seconds / 60) + minutes) / 60) + degrees;
}
public static final Predicate not(Predicate predicate) { return predicate.negate(); }
// Get last n elements from stream
public static Collector> lastN(int n) {
return Collector., List>of(ArrayDeque::new, (acc, t) -> {
if(acc.size() == n)
acc.pollFirst();
acc.add(t);
}, (acc1, acc2) -> {
while(acc2.size() < n && !acc1.isEmpty()) {
acc2.addFirst(acc1.pollLast());
}
return acc2;
}, ArrayList::new);
}
public static final double getDoubleFromText(final String text) {
if (null == text || text.isEmpty()) { return 0.0; }
FLOAT_MATCHER.reset(text);
String result = "";
double number = 0;
try {
while(FLOAT_MATCHER.find()) {
result = FLOAT_MATCHER.group(0);
}
number = Double.parseDouble(result);
} catch (IllegalStateException | NumberFormatException ex) {
return 0.0;
}
return number;
}
public static final int getIntFromText(final String text) {
INT_MATCHER.reset(text);
String result = "";
int number = 0;
try {
while(INT_MATCHER.find()) {
result = INT_MATCHER.group(0);
}
number = Integer.parseInt(result);
} catch (IllegalStateException | NumberFormatException ex) {
return 0;
}
return number;
}
public static final String getHexColorFromString(final String text) {
HEX_MATCHER.reset(text);
String result = "";
try {
while (HEX_MATCHER.find()) {
result = HEX_MATCHER.group(0);
}
} catch (IllegalStateException ex) {
return "-";
}
return result;
}
public static final String readFromInputStream(final InputStream inputStream) throws IOException {
StringBuilder resultStringBuilder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null) {
resultStringBuilder.append(line).append("\n");
}
}
return resultStringBuilder.toString();
}
public static final String readTextFileToString(final String filename) {
if (null == filename || !new File(filename).exists()) { throw new IllegalArgumentException("File: " + filename + " not found or null"); }
try {
Path fileObj = Path.of(filename);
return Files.readString(fileObj);
} catch (IOException e) {
return "";
}
}
public static final String readTextFileToString(final File file) {
if (null == file || !file.isFile()) { throw new IllegalArgumentException("Given file is either null or no file"); }
try {
Path fileObj = file.toPath();
return Files.readString(fileObj);
} catch (IOException e) {
return "";
}
}
public static final void saveStringToTextFile(final String filename, final String text) {
if (null == filename || filename.isEmpty()) { throw new IllegalArgumentException("filename cannot be null or empty"); }
if (null == text || text.isEmpty()) { throw new IllegalArgumentException("text cannot be null or empty"); }
try {
Files.write(Paths.get("/" + filename), text.getBytes());
} catch (IOException e) {
//System.out.println("Error saving download text file. " + e);
}
}
public static final LocalDate getFirstDayOfWeek(final int year, final int weekNumber, final Locale locale) {
return LocalDate
.of(year, 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
public static final long getEpochSecondsOfFirstDayOfWeek(final int year, final int weekNumber, final Locale locale) {
return getFirstDayOfWeek(year, weekNumber, locale).atStartOfDay().toEpochSecond(ZoneOffset.UTC);
}
public static final LocalDate getLastDayOfWeek(final int year, final int weekNumber, final Locale locale) {
return getFirstDayOfWeek(year, weekNumber, locale).plusDays(6);
}
public static final long getEpochSecondsOfLastDayOfWeek(final int year, final int weekNumber, final Locale locale) {
return getLastDayOfWeek(year, weekNumber, locale).atStartOfDay().toEpochSecond(ZoneOffset.UTC);
}
public static final int getWeekOfYear(final ZonedDateTime zonedDateTime) { return getWeekOfYear(zonedDateTime.toInstant(), zonedDateTime.getZone()); }
public static final int getWeekOfYeear(final Instant instant) { return getWeekOfYear(instant, ZoneId.systemDefault()); }
public static final int getWeekOfYear(final Instant instant, final ZoneId zoneId) { return getWeekOfYear(LocalDate.ofInstant(instant, zoneId)); }
public static final int getWeekOfYear(final LocalDateTime dateTime) { return getWeekOfYear(dateTime.toLocalDate()); }
public static final int getWeekOfYear(final LocalDate date) { return date.get(ChronoField.ALIGNED_WEEK_OF_YEAR); }
public static final int getWeekOfYear(final long epochSeconds) { return getWeekOfYear(epochSeconds, ZoneId.systemDefault()); }
public static final int getWeekOfYear(final long epochSeconds, final ZoneId zoneId) {
if (epochSeconds < 0) { throw new IllegalArgumentException("Epochseconds cannot be smaller than 0"); }
return LocalDate.ofInstant(Instant.ofEpochSecond(epochSeconds), zoneId).get(ChronoField.ALIGNED_WEEK_OF_YEAR);
}
private static final NavigableMap SUFFIXES = new TreeMap<>(Map.of(1_000L, "k",
1_000_000L, "M",
1_000_000_000L, "G",
1_000_000_000_000L, "T",
1_000_000_000_000_000L, "P",
1_000_000_000_000_000_000L, "E"));
public static final String shortenNumber(final long value) {
return shortenNumber(value, Locale.US);
}
public static final String shortenNumber(final long value, final Locale locale) {
//Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
if (value == Long.MIN_VALUE) { return shortenNumber(Long.MIN_VALUE + 1, locale); }
if (value < 0) { return "-" + shortenNumber(-value, locale); }
if (value < 1000) { return Long.toString(value); }
final Entry entry = SUFFIXES.floorEntry(value);
final Long divideBy = entry.getKey();
final String suffix = entry.getValue();
final long truncated = value / (divideBy / 10);
final boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10);
final java.text.NumberFormat formatter = java.text.NumberFormat.getNumberInstance(locale);
formatter.setMinimumFractionDigits(1);
formatter.setMaximumFractionDigits(1);
return hasDecimal ? formatter.format(truncated / 10d) + suffix : (truncated / 10) + suffix;
}
public static final > V getMaxValueInMap(final Map map) {
Entry maxEntry = Collections.max(map.entrySet(), Comparator.comparing(Entry::getValue));
return maxEntry.getValue();
}
public static final > K getKeyWithMaxValueInMap(final Map map) {
Entry maxEntry = Collections.max(map.entrySet(), Comparator.comparing(Entry::getValue));
return maxEntry.getKey();
}
public static final String secondsToHHMMString(final long seconds) {
long[] hhmmss = secondsToHHMMSS(seconds);
return String.format("%02d:%02d:%02d", hhmmss[0], hhmmss[1], hhmmss[2]);
}
public static final long[] secondsToHHMMSS(final long seconds) {
long secs = seconds % 60;
long minutes = (secs / 60) % 60;
long hours = (secs / (60 * 60)) % 24;
return new long[] { hours, minutes, secs };
}
public static final long getCRC32Checksum(final byte[] bytes) {
Checksum crc32 = new CRC32();
crc32.update(bytes, 0, bytes.length);
return crc32.getValue();
}
public static final String getMD5(final String text) { return bytesToHex(getMD5Bytes(text.getBytes(UTF_8))); }
public static final String getMD5(final byte[] bytes) {
return bytesToHex(getMD5Bytes(bytes));
}
public static final byte[] getMD5Bytes(final byte[] bytes) {
final MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
System.out.println("Error getting MD5 algorithm. " + e.getMessage());
return new byte[]{};
}
return md.digest(bytes);
}
public static final String getMD5ForFile(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("MD5");
final InputStream fis = new FileInputStream(file);
try {
int n = 0;
byte[] buffer = new byte[4096];
while (n != -1) {
n = fis.read(buffer);
if (n > 0) {
md.update(buffer, 0, n);
}
}
} finally {
fis.close();
}
byte byteData[] = md.digest();
return getMD5(bytesToHex(byteData));
}
public static final String getSHA1(final String text) { return bytesToHex(getSHA1Bytes(text.getBytes(UTF_8))); }
public static final String getSHA1(final byte[] bytes) {
return bytesToHex(getSHA1Bytes(bytes));
}
public static final byte[] getSHA1Bytes(final byte[] bytes) {
final MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
System.out.println("Error getting SHA-1 algorithm. " + e.getMessage());
return new byte[]{};
}
return md.digest(bytes);
}
public static final String getSHA1ForFile(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
final InputStream fis = new FileInputStream(file);
try {
int n = 0;
byte[] buffer = new byte[4096];
while (n != -1) {
n = fis.read(buffer);
if (n > 0) {
md.update(buffer, 0, n);
}
}
} finally {
fis.close();
}
byte byteData[] = md.digest();
return getSHA1(bytesToHex(byteData));
}
public static final String getSHA256(final String text) { return bytesToHex(getSHA256Bytes(text.getBytes(UTF_8))); }
public static final String getSHA256(final byte[] bytes) {
return bytesToHex(getSHA256Bytes(bytes));
}
public static final byte[] getSHA256Bytes(final byte[] bytes) {
final MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
System.out.println("Error getting SHA2-256 algorithm. " + e.getMessage());
return new byte[]{};
}
return md.digest(bytes);
}
public static final String getSHA256ForFile(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final InputStream fis = new FileInputStream(file);
try {
int n = 0;
byte[] buffer = new byte[4096];
while (n != -1) {
n = fis.read(buffer);
if (n > 0) {
md.update(buffer, 0, n);
}
}
} finally {
fis.close();
}
byte byteData[] = md.digest();
return getSHA256(bytesToHex(byteData));
}
public static final String getSHA3_256(final String text) { return bytesToHex(getSHA3_256Bytes(text.getBytes(UTF_8))); }
public static final String getSHA3_256(final byte[] bytes) {
return bytesToHex(getSHA3_256Bytes(bytes));
}
public static final byte[] getSHA3_256Bytes(final byte[] bytes) {
final MessageDigest md;
try {
md = MessageDigest.getInstance("SHA3-256");
} catch (NoSuchAlgorithmException e) {
System.out.println("Error getting SHA3-256 algorithm. " + e.getMessage());
return new byte[]{};
}
return md.digest(bytes);
}
public static final String getSHA3_256ForFile(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("SHA3-256");
final InputStream fis = new FileInputStream(file);
try {
int n = 0;
byte[] buffer = new byte[4096];
while (n != -1) {
n = fis.read(buffer);
if (n > 0) {
md.update(buffer, 0, n);
}
}
} finally {
fis.close();
}
byte byteData[] = md.digest();
return getSHA3_256(bytesToHex(byteData));
}
public static final String bytesToHex(final byte[] bytes) {
final StringBuilder builder = new StringBuilder();
for (byte b : bytes) { builder.append(String.format("%02x", b)); }
return builder.toString();
}
public static final Optional nonEmpty(final String text) {
return (null == text || text.length() == 0) ? Optional.empty() : Optional.ofNullable(text);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy