/* * Copyright (C) 2004-2015 L2J Server * * This file is part of L2J Server. * * L2J Server is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * L2J Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package com.l2jserver.util; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.time.DayOfWeek; import java.time.LocalDateTime; import java.time.temporal.TemporalAdjusters; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.logging.Logger; /** * Useful utilities common to L2J Server. */ public final class Util { private static final Logger _log = Logger.getLogger(Util.class.getName()); private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' }; /** * Checks if a host name is internal * @param host the host name to check * @return true: host name is internal
* false: host name is external */ public static boolean isInternalHostname(String host) { try { InetAddress addr = InetAddress.getByName(host); return addr.isSiteLocalAddress() || addr.isLoopbackAddress(); } catch (UnknownHostException e) { _log.warning("Util: " + e.getMessage()); } return false; } /** * Method to generate the hexadecimal representation of a byte array.
* 16 bytes per row, while ascii chars or "." is shown at the end of the line. * @param data the byte array to be represented in hexadecimal representation * @param len the number of bytes to represent in hexadecimal representation * @return byte array represented in hexadecimal format */ public static String printData(byte[] data, int len) { return new String(HexUtils.bArr2HexEdChars(data, len)); } /** * This call is equivalent to Util.printData(data, data.length) * @see Util#printData(byte[],int) * @param data data to represent in hexadecimal * @return byte array represented in hexadecimal format */ public static String printData(byte[] data) { return printData(data, data.length); } /** * Method to represent the remaining bytes of a ByteBuffer as hexadecimal * @param buf ByteBuffer to represent the remaining bytes of as hexadecimal * @return hexadecimal representation of remaining bytes of the ByteBuffer */ public static String printData(ByteBuffer buf) { byte[] data = new byte[buf.remaining()]; buf.get(data); String hex = Util.printData(data, data.length); buf.position(buf.position() - data.length); return hex; } /** * Method to generate a random sequence of bytes returned as byte array * @param size number of random bytes to generate * @return byte array with sequence of random bytes */ public static byte[] generateHex(int size) { byte[] array = new byte[size]; Rnd.nextBytes(array); return array; } /** * Method to get the stack trace of a Throwable into a String * @param t Throwable to get the stacktrace from * @return stack trace from Throwable as String */ public static String getStackTrace(Throwable t) { StringWriter sw = new StringWriter(); t.printStackTrace(new PrintWriter(sw)); return sw.toString(); } /** * Replaces most invalid characters for the given string with an underscore. * @param str the string that may contain invalid characters * @return the string with invalid character replaced by underscores */ public static String replaceIllegalCharacters(String str) { String valid = str; for (char c : ILLEGAL_CHARACTERS) { valid = valid.replace(c, '_'); } return valid; } /** * Verify if a file name is valid. * @param name the name of the file * @return {@code true} if the file name is valid, {@code false} otherwise */ public static boolean isValidFileName(String name) { final File f = new File(name); try { f.getCanonicalPath(); return true; } catch (IOException e) { return false; } } /** * Split words with a space. * @param input the string to split * @return the split string */ public static String splitWords(String input) { return input.replaceAll("(\\p{Ll})(\\p{Lu})", "$1 $2"); } /** * Gets the next or same closest date from the specified days in {@code daysOfWeek Array} at specified {@code hour} and {@code min}. * @param daysOfWeek the days of week * @param hour the hour * @param min the min * @return the next or same date from the days of week at specified time * @throws IllegalArgumentException if the {@code daysOfWeek Array} is empty. */ public static LocalDateTime getNextClosestDateTime(DayOfWeek[] daysOfWeek, int hour, int min) throws IllegalArgumentException { return getNextClosestDateTime(Arrays.asList(daysOfWeek), hour, min); } /** * Gets the next or same closest date from the specified days in {@code daysOfWeek List} at specified {@code hour} and {@code min}. * @param daysOfWeek the days of week * @param hour the hour * @param min the min * @return the next or same date from the days of week at specified time * @throws IllegalArgumentException if the {@code daysOfWeek List} is empty. */ public static LocalDateTime getNextClosestDateTime(List daysOfWeek, int hour, int min) throws IllegalArgumentException { if (daysOfWeek.isEmpty()) { throw new IllegalArgumentException("daysOfWeek should not be empty."); } final LocalDateTime dateNow = LocalDateTime.now(); final LocalDateTime dateNowWithDifferentTime = dateNow.withHour(hour).withMinute(min).withSecond(0); // @formatter:off return daysOfWeek.stream() .map(d -> dateNowWithDifferentTime.with(TemporalAdjusters.nextOrSame(d))) .filter(d -> d.isAfter(dateNow)) .min(Comparator.naturalOrder()) .orElse(dateNowWithDifferentTime.with(TemporalAdjusters.next(daysOfWeek.get(0)))); // @formatter:on } /** * This method translates map to function * @param key type of the map and argument of the function * @param value type of the map and return type of the function * @param map the input map * @return a function which returns map.get(arg) */ public static Function mapToFunction(Map map) { return key -> map.get(key); } }