Tools.java
package com.nonononoki.alovoa;
import com.nonononoki.alovoa.config.SecurityConfig;
import com.nonononoki.alovoa.entity.User;
import com.nonononoki.alovoa.entity.user.UserImage;
import com.nonononoki.alovoa.entity.user.UserProfilePicture;
import com.nonononoki.alovoa.model.AlovoaException;
import com.nonononoki.alovoa.service.UserService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.MimeType;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
public class Tools {
private Tools() throws AlovoaException {
throw new AlovoaException("no_contructor");
}
public static final float BASE64FACTOR = 0.75f;
private static final int BILLION = 1000000000;
public static final int MILLION = 1000000;
public static final int THOUSAND = 1000;
public static final String B64IMAGEPREFIX = "data:image/";
public static final String B64AUDIOPREFIX = "data:audio/";
public static final String B64PREFIX = ";base64,";
public static final String TEST = "test";
public static final String PROD = "prod";
public static final String DEV = "dev";
public static final String MAIL_TEST_DOMAIN = "@mailinator.com";
public static final String TEMP_EMAIL_FILE_NAME = "temp-mail.txt";
public static final int AGE_LEGAL = 18;
public static final long GENDER_MALE_ID = 1;
public static final long GENDER_FEMALE_ID = 2;
public static final long GENDER_OTHER_ID = 3;
public static final double REFERRED_AMOUNT = 0.5;
public static String cleanEmail(String email) {
if (email == null) {
return null;
}
return email.toLowerCase();
}
public static Locale getUserLocale(User user) {
String language = user.getLanguage();
if (language != null) {
return StringUtils.parseLocale(language);
} else {
return Locale.ENGLISH;
}
}
public static Date ageToDate(int age) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, age * (-1));
return calendar.getTime();
}
public static Date localDateToDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
public static LocalDate dateToLocalDate(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
public static LocalDateTime dateToLocalDateTime(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
}
public static int calcUserAge(User user) {
LocalDate currentDate = LocalDate.now();
return Period.between(Tools.dateToLocalDate(user.getDates().getDateOfBirth()), currentDate).getYears();
}
public static int calcUserAge(Date dateOfBirth) {
LocalDate currentDate = LocalDate.now();
return Period.between(Tools.dateToLocalDate(dateOfBirth), currentDate).getYears();
}
public static String inputStreamToString(InputStream inputStream) throws IOException {
return StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
}
public static String getResourceText(String path) throws IOException {
Resource resource = new ClassPathResource(path);
return inputStreamToString(resource.getInputStream());
}
public static byte[] resourceToBytes(String path) throws IOException {
Resource resource = new ClassPathResource(path);
return StreamUtils.copyToByteArray(resource.getInputStream());
}
public static String resourceToB64(String path) throws IOException {
return Base64.getEncoder().encodeToString(resourceToBytes(path));
}
public static String imageToB64(String path, String mime) throws IOException {
String b64 = resourceToB64(path);
return B64IMAGEPREFIX + mime + B64PREFIX + b64;
}
public static boolean isTextContainingLineFromFile(String path, String text) throws IOException {
String content = getResourceText(path);
String[] lines = content.split(System.lineSeparator());
for (int i = 0; i < lines.length; i++) {
if (text.contains(lines[i])) {
return true;
}
}
return false;
}
public static boolean binaryStringToBoolean(String b) {
return !"0".equals(b);
}
public static int getDistanceToUser(User user, User currUser) {
try {
return calcDistanceKm(user.getLocationLatitude(), user.getLocationLongitude(),
currUser.getLocationLatitude(), currUser.getLocationLongitude());
} catch (Exception e) {
return 99999;
}
}
// https://stackoverflow.com/a/45732035
// CC BY-SA 3.0, Pedro Silva
public static Double getBase64Size(String base64String) {
double result = -1.0;
if (!base64String.isEmpty()) {
int padding = 0;
if (base64String.endsWith("==")) {
padding = 2;
} else {
if (base64String.endsWith("="))
padding = 1;
}
result = Math.ceil((double) base64String.length() / 4) * 3 - padding;
}
return result;
}
// https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula/12600225#12600225
public static final double AVERAGE_RADIUS_OF_EARTH_KM = 6371;
public static int calcDistanceKm(double userLat, double userLng, double venueLat, double venueLng) {
double latDistance = Math.toRadians(userLat - venueLat);
double lngDistance = Math.toRadians(userLng - venueLng);
double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + Math.cos(Math.toRadians(userLat))
* Math.cos(Math.toRadians(venueLat)) * Math.sin(lngDistance / 2) * Math.sin(lngDistance / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (int) (Math.round(AVERAGE_RADIUS_OF_EARTH_KM * c));
}
public static boolean usersCompatible(User user1, User user2, boolean ignoreIntention) {
if (user2.getPreferedGenders() == null || user1.getPreferedGenders() == null || user1.getDates() == null
|| user2.getDates() == null) {
return false;
}
int user1Age = calcUserAge(user1);
int user2Age = calcUserAge(user2);
boolean compatible;
try {
compatible = (user2.getLikes() != null && user2.getLikes().stream().filter(u -> u.getUserTo() != null)
.map(u -> u.getUserTo().getId()).anyMatch(u ->
Objects.equals(u, user1.getId()))) || user2Age < AGE_LEGAL == user1Age < AGE_LEGAL
&& user2.getPreferedGenders().contains(user1.getGender())
&& user1.getPreferedGenders().contains(user2.getGender()) && user1.getPreferedMaxAge() >= user2Age
&& user1.getPreferedMinAge() <= user2Age && user2.getPreferedMaxAge() >= user1Age
&& user2.getPreferedMinAge() <= user1Age
&& (ignoreIntention || user2.getIntention().getId().equals(user1.getIntention().getId()));
} catch (Exception e) {
compatible = false;
}
return compatible;
}
// This method subtracts user date of birth with passed preferred min/max age
public static int convertPrefAgeToRelativeYear(Date userDateOfBirth, int prefAge) {
LocalDate currentDate = LocalDate.now();
return prefAge - Period.between(Tools.dateToLocalDate(userDateOfBirth), currentDate).getYears();
}
public static int convertPrefAgeToExactYear(Date userDateOfBirth, int prefAge) {
LocalDate currentDate = LocalDate.now();
return Period.between(Tools.dateToLocalDate(userDateOfBirth), currentDate).getYears() + prefAge;
}
private static final String STR_NUM_BILLION = "B";
private static final String STR_NUM_MILLION = "M";
private static final String STR_NUM_THOUSAND = "K";
public static String largeNumberToString(long num) {
if (num < THOUSAND) {
return String.valueOf(num);
}
DecimalFormat df = new DecimalFormat("#.###");
df.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
if (num >= BILLION) {
double d = (double) num / BILLION;
return df.format(d) + STR_NUM_BILLION;
} else if (num >= MILLION) {
double d = (double) num / MILLION;
return df.format(d) + STR_NUM_MILLION;
} else {
double d = (double) num / THOUSAND;
return df.format(d) + STR_NUM_THOUSAND;
}
}
public static String getCountryEmoji(String countryIso) {
if (countryIso != null) {
int firstLetter = Character.codePointAt(countryIso, 0) - 0x41 + 0x1F1E6;
int secondLetter = Character.codePointAt(countryIso, 1) - 0x41 + 0x1F1E6;
return new String(Character.toChars(firstLetter)) + new String(Character.toChars(secondLetter));
}
return null;
}
public static boolean isURLValid(String urlString) {
try {
URL url = new URL(urlString);
url.toURI();
return true;
} catch (Exception e) {
return false;
}
}
public static String getAuthParams(SecurityConfig securityConfig, String httpSessionId, String username,
String firstName, int page, String password) {
String cookieData = securityConfig.getOAuthRememberMeServices().getRememberMeCookieData(username, password);
StringBuilder builder = new StringBuilder();
builder.append("?remember-me=").append(cookieData).append("&jsessionid=").append(httpSessionId).append("&page=")
.append(page);
if (firstName != null) {
builder.append("&firstName=").append(firstName);
}
return builder.toString();
}
public static UUID getProfilePictureUUID(UserProfilePicture image, UserService userService) {
UUID uuid = image.getUuid();
if (uuid == null) {
uuid = UUID.randomUUID();
userService.updateProfilePictureUUID(image, uuid);
}
return uuid;
}
public static UUID getImageUUID(UserImage image, UserService userService) {
UUID uuid = image.getUuid();
if (uuid == null) {
uuid = UUID.randomUUID();
userService.updateImageUUID(image, uuid);
}
return uuid;
}
public static UUID getUserUUID(User user, UserService userService) {
UUID uuid = user.getUuid();
if (uuid == null) {
uuid = UUID.randomUUID();
userService.updateUUID(user, uuid);
}
return uuid;
}
public static String getAuthParams(SecurityConfig securityConfig, String httpSessionId, String username,
String firstName, int page) {
return getAuthParams(securityConfig, httpSessionId, username, firstName, page, null);
}
public static String buildMimeTypeString(MimeType mimeType) {
return mimeType.getType() + "/" + mimeType.getSubtype();
}
}