package net.gepafin.tendermanagement.util; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.model.request.GlobalFilters; import org.apache.commons.collections4.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.json.JsonReadFeature; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import feign.FeignException; import io.micrometer.common.util.StringUtils; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientForbiddenException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import static org.apache.commons.lang3.StringUtils.isEmpty; public class Utils { // @Autowired // private static TokenProvider tokenProvider; public static final Logger log = LoggerFactory.getLogger(Utils.class); private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .registerModule(new JavaTimeModule()).disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); public static U convertObject(T source, Class destinationClass) { try { return mapper.convertValue(source, destinationClass); } catch (Exception e) { log.error("Error converting object: " + e.getMessage(), e); } return null; } public static List convertSourceListToDestinationList(List sourceList, Class destinationClass) { try { return sourceList.stream() .map(source -> mapper.convertValue(source, destinationClass)) .collect(Collectors.toList()); } catch (Exception e) { log.error("Error converting list: " + e.getMessage(), e); } return null; } public static List convertSourceToList(T source, Class destinationClass) { try { // Convert single source object to a single-element list of destination type return List.of(mapper.convertValue(source, destinationClass)); } catch (Exception e) { log.error("Error converting single object to list: " + e.getMessage(), e); } return null; } public static String extractFileName(String filePath) { if (filePath == null || filePath.isEmpty()) { return null; } int lastSlashIndex = filePath.lastIndexOf('/'); if (lastSlashIndex >= 0 && lastSlashIndex < filePath.length() - 1) { return filePath.substring(lastSlashIndex + 1); } else { return filePath; } } public static String decodeBase64String(String decodedString) { if (StringUtils.isBlank(decodedString)) { return decodedString; } byte[] decode = Base64.getDecoder().decode(decodedString.getBytes(StandardCharsets.UTF_8)); return new String(decode, StandardCharsets.UTF_8); } public static void setIfNotNull(Consumer setter, T value) { if (value != null) { setter.accept(value); } } public static void setIfUpdated(Supplier getter, Consumer setter, T newValue) { T currentValue = getter.get(); if (newValue != null && !newValue.equals(currentValue)) { setter.accept(newValue); } } public static String convertListToJsonString(List list) { try { return mapper.writeValueAsString(list); } catch (JsonProcessingException e) { e.printStackTrace(); // Handle exception or throw a custom exception return null; } } public static List convertJsonStringToList(String jsonString, Class clazz) { try { TypeReference> typeRef = new TypeReference>() { @Override public Type getType() { return TypeFactory.defaultInstance().constructCollectionType(List.class, clazz); } }; return mapper.readValue(jsonString, typeRef); } catch (Exception e) { e.printStackTrace(); // Handle the exception appropriately (e.g., throw a custom exception) return null; } } public static String convertMapIntoJsonString(Map map) { try { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); mapper.enable(SerializationFeature.INDENT_OUTPUT); if (MapUtils.isNotEmpty(map)) { return mapper.writeValueAsString(map); } } catch (JsonProcessingException e) { log.error(e.getMessage()); } return null; } public static Map convertIntoJson(String jsonString) { if (jsonString != null && !jsonString.isEmpty()) { try { ObjectMapper mapper = new ObjectMapper(); mapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true); return mapper.readValue(jsonString, Map.class); } catch (Exception e) { log.error(e.getMessage()); } } return null; } public static U convertSourceObjectToDestinationObject(T source, Class destinationClass) { try { mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); mapper.registerModule(new JavaTimeModule()); return mapper.convertValue(source, destinationClass); } catch (Exception e) { log.error("Error converting object: " + e.getMessage(), e); } return null; } public static void retainOnlySpecificFields(T requestObject, List retainFields) throws IllegalAccessException { // Get all declared fields of the request object's class Field[] fields = requestObject.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); // To allow access to private fields // Check if the field is in the retainFields list if (!retainFields.contains(field.getName())) { field.set(requestObject, null); // Set the field to null if not in the retain list } } } public static String encodeData(String data) { return Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); } public static String decodeData(String token) { byte[] decodedBytes = Base64.getDecoder().decode(token); return new String(decodedBytes, StandardCharsets.UTF_8); } public static String generateSecureSamlToken() { SecureRandom secureRandom = new SecureRandom(); byte[] tokenBytes = new byte[24]; secureRandom.nextBytes(tokenBytes); String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); log.debug("Generated secure token: {}", token); return token; } public static String generateSecureToken() { SecureRandom secureRandom = new SecureRandom(); byte[] tokenBytes = new byte[5]; secureRandom.nextBytes(tokenBytes); String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); log.debug("Generated secure token: {}", token); return token; } public static Map> convertStringIntoMap(String jsonString) { try { return mapper.readValue(jsonString, new TypeReference>>() { }); } catch (Exception e) { log.error("Error converting object: " + e.getMessage(), e); return null; } } public static void callException(Integer staus, FeignException ex) { switch (staus) { case 400: throw new FeignClientValidationException(HttpStatus.valueOf(staus), ex.getMessage()); case 401: throw new FeignClientUnauthorizedException(HttpStatus.valueOf(staus), ex.getMessage()); case 403: throw new FeignClientForbiddenException(HttpStatus.valueOf(staus), ex.getMessage()); case 404: throw new FeignClientNotFoundException(HttpStatus.valueOf(staus), ex.getMessage()); default: log.error("Exception occured :- {0}", ex); throw ex; } } public static Boolean isValidEmail(String email) { String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; if (email == null || email.isEmpty()) { return false; } Pattern pattern = Pattern.compile(EMAIL_REGEX); return pattern.matcher(email).matches(); } public static String randomKey(Integer range) { String data = String.valueOf(System.currentTimeMillis()); return data.substring(data.length() - range); } public static String convertObjectToJsonString(Object object) { try { // Check if the object is a string if (object instanceof String) { String str = (String) object; // Return null if the string is null or empty if (str != null && !str.trim().isEmpty()) { return str; // Return the non-empty string } else { return null; // Return null for null or empty string } } else if (object != null) { // Convert non-string objects (arrays, objects) to JSON strings return mapper.writeValueAsString(object); } return null; // Return null if the object is null } catch (JsonProcessingException e) { log.error("Error while converting object to string: {}", e.getMessage(), e); return null; // Return null in case of exception } } public static Object getFieldValueAsObject(String fieldValue) { ObjectMapper mapper = new ObjectMapper(); try { // Check if the string is a valid JSON object, array, or simple string if (fieldValue.startsWith("{")) { // Convert to a Map (representing an object) return mapper.readValue(fieldValue, Map.class); } else if (fieldValue.startsWith("[")) { // Convert to a List (representing an array) return mapper.readValue(fieldValue, List.class); } else { // Return the raw string (it's a simple value) return fieldValue; } } catch (JsonProcessingException e) { log.error("Error while converting string to object: {}", e.getMessage(), e); return fieldValue; // If there's an error, return the raw string } } public static Map> parseJsonContent(String jsonContent) { ObjectMapper objectMapper = new ObjectMapper(); try { return mapper.readValue(jsonContent, HashMap.class); } catch (Exception exception) { log.error(exception.getMessage()); } return new HashMap<>(); } // Utility method to replace placeholders with their values, handling nulls public static String replacePlaceholders(String text, Map placeholders) { if (text == null) { return ""; } for (Map.Entry entry : placeholders.entrySet()) { text = replaceNull(text, entry.getKey(), entry.getValue()); } return text; } // Method to safely replace nulls with an empty string or a default value private static String replaceNull(String text, String target, String replacement) { return text.replace(target, replacement != null ? replacement : ""); } public static String getClientIpAddress(HttpServletRequest request) { String header = request.getHeader("X-Forwarded-For"); if (org.apache.commons.lang3.StringUtils.isBlank(header)) { return request.getRemoteAddr(); } return new StringTokenizer(header, ",").nextToken().trim(); } public static List convertJsonToList(String json, TypeReference> typeRef) { ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.readValue(json, typeRef); } catch (IOException e) { e.printStackTrace(); return Collections.emptyList(); } } public static String convertObjectToJson(Object obj) { try { if(obj == null){return null;} return new ObjectMapper().writeValueAsString(obj); } catch (JsonProcessingException e) { log.error("Failed to convert object to JSON: {}", e.getMessage(), e); throw new RuntimeException("Failed to convert object to JSON", e);}} public static String replaceSpacesWithUnderscores(String content) { if (content == null) { return null; } return content.trim().replace(" ", "_"); } public static List> convertJsonStringIntoJsonList(String jsonString) { try { if(isEmpty(jsonString)) { return new ArrayList<>(); } ObjectMapper mapper = new ObjectMapper(); mapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true); return mapper.readValue(jsonString, List.class); } catch (Exception e) { log.error(e.getMessage()); } return null; } public static String convertToString(Object input) { if (input == null) { return "null"; // Return string "null" for null input } if (input instanceof String) { return (String) input; // Return the string directly if input is a string } if (input instanceof Collection) { // Handle collections (List, Set, etc.) return convertCollectionToString((Collection) input); } if (input instanceof Map) { // Handle maps return convertMapToString((Map) input); } // For other types (like Integer, Boolean, etc.), use toString() return input.toString(); } private static String convertCollectionToString(Collection collection) { try { return mapper.writeValueAsString(collection); // Convert the collection to a JSON string } catch (JsonProcessingException e) { throw new RuntimeException("Error converting collection to string", e); } } private static String convertMapToString(Map map) { try { return mapper.writeValueAsString(map); // Convert the map to a JSON string } catch (JsonProcessingException e) { throw new RuntimeException("Error converting map to string", e); } } public static boolean isValidDateString(String dateStr) { Pattern datePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"); return datePattern.matcher(dateStr).matches(); } // Method to convert a valid date string to the "dd-MM-yyyy" format public static String formatDateString(String dateStr) { String originalFormatPattern = "yyyy-MM-dd'T'HH:mm:ss"; String targetFormatPattern = "dd-MM-yyyy"; try { SimpleDateFormat originalFormat = new SimpleDateFormat(originalFormatPattern); Date date = originalFormat.parse(dateStr); SimpleDateFormat targetFormat = new SimpleDateFormat(targetFormatPattern); return targetFormat.format(date); } catch (ParseException e) { log.error("error while prcoessing date formate"); return null; } } // public static String convertItalianAmountToDouble(String amount) throws NumberFormatException { // // Step 1: Remove the thousands separator and replace the decimal separator // String normalizedAmount = amount.replace(".", "").replace(",", "."); // // // Step 2: Parse the string to a double // double value = Double.parseDouble(normalizedAmount); // if (value <= 0) { // return amount; // } // // Step 3: Format the double to 2 decimal places // DecimalFormat decimalFormat = new DecimalFormat("#.00"); // return decimalFormat.format(value); // Return formatted string // } public static String convertToItalianFormat(String amount) { try { // Step 1: Sanitize and standardize the input String sanitizedAmount = amount.trim(); if (sanitizedAmount.matches("\\d")) { return sanitizedAmount; } // Step 2: Handle Italian-style input (e.g., "37.192,00") if (sanitizedAmount.contains(".") && sanitizedAmount.contains(",")) { // Assume the period is a thousand separator and the comma is a decimal separator sanitizedAmount = sanitizedAmount.replace(".", "").replace(",", "."); } else if (sanitizedAmount.contains(",")) { // If the input contains only a comma, treat it as a decimal separator sanitizedAmount = sanitizedAmount.replace(",", "."); } // Step 3: Parse the cleaned-up string into a double double parsedAmount = Double.parseDouble(sanitizedAmount); // Step 4: Format the parsed amount to Italian format NumberFormat italianFormat = NumberFormat.getInstance(Locale.ITALY); italianFormat.setMinimumFractionDigits(2); italianFormat.setMaximumFractionDigits(2); return italianFormat.format(parsedAmount); } catch (NumberFormatException e) { // In case of any issues with parsing, return a default or error message return "Invalid amount format"; } } public static boolean isItalianFormattedAmount(String input) { // Regular expression to match Italian-style amounts (e.g., 41.003,00 or 123,45) String sanitizedInput = input.replace(",", ""); // Step 2: Check if the remaining string is a whole number String wholeNumberPattern = "^\\d+$"; // Regex to match whole numbers return sanitizedInput.matches(wholeNumberPattern); } public static String encryptCredential(String value) { try { if(Boolean.FALSE.equals(isEmpty(value))) { IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] encrypted = cipher.doFinal(value.getBytes()); return Base64.getEncoder().encodeToString(encrypted); } } catch (Exception ex) { log.error("Exception occured while encrypt credential :- {0}", ex); } return null; } public static String decryptCredential(String encrypted) { try { if(Boolean.FALSE.equals(isEmpty(encrypted))) { IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted)); return new String(original); } } catch (Exception ex) { // log.error("Exception occured while decrypt credential :- {0}", ex); return encrypted; } return null; } public static String listToCommaSeparatedString(List list) { return String.join(", ", list.stream().map(String::valueOf).toList()); } public static String convertEntityToJsonForLogging(Object entity) { if (entity == null) { return null; } try { JsonNode entityNode = mapper.valueToTree(entity); ObjectNode objectNode = (ObjectNode) entityNode; Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(ManyToOne.class) || field.isAnnotationPresent(OneToMany.class) || field.isAnnotationPresent( OneToOne.class) || field.isAnnotationPresent(ManyToMany.class)) { objectNode.remove(field.getName()); } } return mapper.writeValueAsString(objectNode); } catch (JsonProcessingException e) { log.error("Failed to parse entity in json {}", e.getMessage()); return null; } } public static T getClonedEntityForData(T entity) { if (entity == null) { return null; } try { String json = mapper.writeValueAsString(entity); @SuppressWarnings("unchecked") T clonedEntity = (T) mapper.readValue(json, entity.getClass()); return clonedEntity; } catch (Exception e) { log.error("Failed to clone entity {}", e.getMessage()); return null; } } public static void setHttpServletRequestForScheduler() { MockHttpServletRequest mockRequest = new MockHttpServletRequest(); mockRequest.setRequestURI("/scheduled"); mockRequest.setMethod("POST"); ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); RequestContextHolder.setRequestAttributes(attributes); } public static void clearHttpServletRequest() { // Clear the RequestContextHolder after task execution RequestContextHolder.resetRequestAttributes(); } public static String generateAuthTokenForLoginToOdessa() { try { // Your weak secret key String secretKey = GepafinConstant.AUTH_JWT_SECRET_KEY; // Header String header = GepafinConstant.JWT_ALGO_HEADER; String encodedHeader = Base64.getUrlEncoder().withoutPadding().encodeToString(header.getBytes(StandardCharsets.UTF_8)); // Payload String payload = "{\"iat\":" + (System.currentTimeMillis() / 1000) + "}"; String encodedPayload = Base64.getUrlEncoder().withoutPadding().encodeToString(payload.getBytes(StandardCharsets.UTF_8)); // Combine header and payload String dataToSign = encodedHeader + "." + encodedPayload; // Sign the token manually Mac mac = Mac.getInstance(GepafinConstant.HMAC_ALGO); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), GepafinConstant.HMAC_ALGO); mac.init(secretKeySpec); byte[] signatureBytes = mac.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8)); String signature = Base64.getUrlEncoder().withoutPadding().encodeToString(signatureBytes); // Return the final JWT return dataToSign + "." + signature; } catch (Exception e) { throw new RuntimeException("Failed to generate JWT token", e); } } // public static void setHttpServletRequestForNdgProcess(HttpServletRequest originalRequest) { // // // Validate original request // if (originalRequest == null) { // throw new IllegalArgumentException("Original request cannot be null."); // } // // // Create a mock request // Claims tokenClaims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(originalRequest)); // MockHttpServletRequest mockRequest = new MockHttpServletRequest(); // mockRequest.setRequestURI(originalRequest.getRequestURI()); // mockRequest.setMethod(originalRequest.getMethod()); // // // Copy essential headers and attributes from the original request // Enumeration headerNames = originalRequest.getHeaderNames(); // while (headerNames.hasMoreElements()) { // String headerName = headerNames.nextElement(); // String headerValue = originalRequest.getHeader(headerName); // if (headerValue != null) { // mockRequest.addHeader(headerName, headerValue); // } // } // // // Set a specific attribute if required // if (originalRequest.getAttribute(GepafinConstant.USER_ACTION_ID) != null) { // mockRequest.setAttribute(GepafinConstant.USER_ACTION_ID, originalRequest.getAttribute(GepafinConstant.USER_ACTION_ID)); // } // // ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); // RequestContextHolder.setRequestAttributes(attributes); // // Log successful context setting // log.info("Successfully set mock request for NDG process with URI: {}", mockRequest.getRequestURI()); // } public static Long extractHubIdFromPayload(String payload) { Long hubId; try { String[] parts = payload.split(":"); if (parts.length > 2) { hubId = Long.valueOf(parts[2]); return hubId; } else { hubId = null; } } catch (Exception e) { throw new RuntimeException("No Hub id present in payload", e); } return null; } // Method to convert a JSON string to an object of type T public static T convertStringToObject(String jsonString, Class clazz) { try { return mapper.readValue(jsonString, clazz); } catch (Exception e) { e.printStackTrace(); // Handle the exception appropriately (e.g., throw a custom exception) return null; } } // Method to convert an object of type T to a JSON string public static String convertObjectToString(T object) { try { return mapper.writeValueAsString(object); } catch (Exception e) { e.printStackTrace(); // Handle the exception appropriately (e.g., throw a custom exception) return null; } } public static String createChannelForUserAndCompany(Long userId, Long companyId) { return GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId + GepafinConstant.COMPANY_PREFIX + companyId; } public static GlobalFilters setPageNumberAndLimit(GlobalFilters globalFilters){ if (globalFilters == null) { if (globalFilters.getLimit() == null || globalFilters.getLimit() <= 0) { globalFilters.setLimit(GepafinConstant.DEFAULT_PAGE_LIMIT); } if (globalFilters.getPage() == null || globalFilters.getPage() <= 0) { globalFilters.setPage(GepafinConstant.DEFAULT_PAGE); } } return globalFilters; } public static Map parseErrorResponse(String responseBody) { if (StringUtils.isBlank(responseBody)) { return defaultErrorResponse(); } try { return mapper.readValue(responseBody, Map.class); } catch (Exception e) { log.error("Failed to parse error response: {}", e.getMessage(), e); return defaultErrorResponse(); } } private static Map defaultErrorResponse() { return Collections.singletonMap("message", Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); } }