Skip to content

Commit

Permalink
✨ feat: add transform4j, cookie4j unify functions #4
Browse files Browse the repository at this point in the history
  • Loading branch information
pnguyen215 committed May 19, 2024
1 parent ce222fe commit 0705351
Show file tree
Hide file tree
Showing 6 changed files with 470 additions and 1 deletion.
4 changes: 4 additions & 0 deletions plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ dependencies {
implementation group: 'com.jayway.jsonpath', name: 'json-path', version: '2.9.0'
// The "validation-api" library, version 2.0.1.Final, provides tools for validating Java objects according to defined constraints.
implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
// The Servlet API is used for creating web applications in Java.
// Including it as compileOnly means that it's necessary for compiling your code (as it might include annotations or classes used during compilation),
// but it shouldn't be packaged into the final artifact (JAR, WAR, etc.) because servlet containers, like Tomcat or Jetty, usually provide this API at runtime.
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
}
216 changes: 216 additions & 0 deletions plugin/src/main/groovy/org/unify4j/common/Cookie4j.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package org.unify4j.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Cookie4j {
protected static final Logger logger = LoggerFactory.getLogger(Cookie4j.class);

/**
* Retrieves cookies from the provided HttpServletRequest and returns them as a map of cookie names to values.
* If the request is null or contains no cookies, returns an empty map.
*
* @param request The HttpServletRequest from which to retrieve cookies.
* @return A map of cookie names to values extracted from the request.
*/
public static Map<String, String> getCookies(HttpServletRequest request) {
if (request == null || Object4j.isEmpty(request.getCookies())) {
return Collections.emptyMap();
}
return Arrays.stream(request.getCookies()).collect(Collectors.toMap(Cookie::getName, // Use cookie's name as the map key
Cookie::getValue, // Use cookie's value as the map value
(cookie1, cookie2) -> { // Merge function for handling duplicate keys
logger.info("cookie duplicated key found by cookie-1: {} and cookie-2: {}", cookie1, cookie2);
return cookie1; // Keep the value of the first cookie in case of a duplicate key
}));
}

/**
* Retrieves cookies from the provided ServletRequest and returns them as a map of cookie names to values.
* If the request is null or not of type HttpServletRequest, returns an empty map.
*
* @param request The ServletRequest from which to retrieve cookies.
* @return A map of cookie names to values extracted from the request, or an empty map if the request is null or not an HttpServletRequest.
*/
public static Map<String, String> getCookies(ServletRequest request) {
if (!(request instanceof HttpServletRequest)) {
return Collections.emptyMap();
}
return getCookies((HttpServletRequest) request);
}

/**
* Constructs a string representation of cookies present in the provided HttpServletRequest.
* The string format is "name1=value1,name2=value2,..." for all cookies.
* If the request is null or contains no cookies, returns an empty string.
*
* @param request The HttpServletRequest from which to retrieve cookies.
* @return A string representation of cookies in the format "name1=value1,name2=value2,...", or an empty string if the request is null or contains no cookies.
*/
public static String cookieString(HttpServletRequest request) {
if (request == null || Object4j.isEmpty(request.getCookies())) {
return "";
}
return Arrays.stream(request.getCookies()).map(cookie -> cookie.getName().concat("=").concat(cookie.getValue())) // Map each cookie to "name=value" format
.collect(Collectors.joining(",")); // Join all cookie strings with ","
}

/**
* Constructs a string representation of cookies present in the provided ServletRequest.
* The string format is "name1=value1,name2=value2,..." for all cookies.
* If the request is not an instance of HttpServletRequest, returns an empty string.
*
* @param request The ServletRequest from which to retrieve cookies.
* @return A string representation of cookies in the format "name1=value1,name2=value2,...", or an empty string if the request is not an instance of HttpServletRequest.
*/
public static String cookieString(ServletRequest request) {
if (!(request instanceof HttpServletRequest)) {
return "";
}
return cookieString((HttpServletRequest) request);
}

/**
* Retrieves cookies from the provided HttpServletRequest and returns them as a List of Cookie objects.
* If the request is null or does not contain any cookies, returns an empty list.
*
* @param request The HttpServletRequest from which to retrieve cookies.
* @return A List of Cookie objects extracted from the request, or an empty list if the request is null or contains no cookies.
*/
public static List<Cookie> getCollections(HttpServletRequest request) {
if (request == null) {
return Collections.emptyList();
}
return Arrays.stream(request.getCookies()).collect(Collectors.toList());
}

/**
* Checks if the provided HttpServletRequest contains all the specified cookies.
*
* @param request The HttpServletRequest object containing cookies to be checked.
* @param cookies A List of cookie names to be checked for existence.
* @return true if all specified cookies are present in the request, false otherwise.
*/
public static boolean hasCookies(HttpServletRequest request, List<String> cookies) {
if (request == null || Collection4j.isEmpty(cookies) || Object4j.isEmpty(request.getCookies())) {
return false;
}
List<String> list = Arrays.stream(request.getCookies()).map(Cookie::getName).collect(Collectors.toList());
return list.stream().flatMap(x -> cookies.stream().filter(x::equalsIgnoreCase).limit(1)).findFirst().isPresent();
}

/**
* Checks if the provided ServletRequest contains all the specified cookies.
*
* @param request The ServletRequest object containing cookies to be checked.
* @param cookies A List of cookie names to be checked for existence.
* @return true if all specified cookies are present in the request, false otherwise.
*/
public static boolean hasCookies(ServletRequest request, List<String> cookies) {
return hasCookies((HttpServletRequest) request, cookies);
}

/**
* Checks if the provided HttpServletRequest contains the specified cookie.
*
* @param request The HttpServletRequest object containing cookies to be checked.
* @param cookie The name of the cookie to be checked for existence.
* @return true if the specified cookie is present in the request, false otherwise.
*/
public static boolean hasCookie(HttpServletRequest request, String cookie) {
return hasCookies(request, Collections.singletonList(cookie));
}

/**
* Checks if the provided ServletRequest contains the specified cookie.
*
* @param request The ServletRequest object containing cookies to be checked.
* @param cookie The name of the cookie to be checked for existence.
* @return true if the specified cookie is present in the request, false otherwise.
*/
public static boolean hasCookie(ServletRequest request, String cookie) {
return hasCookies(request, Collections.singletonList(cookie));
}

/**
* Checks if the provided HttpServletRequest contains all the specified cookies.
*
* @param request The HttpServletRequest object containing cookies to be checked.
* @param cookies A variable number of cookie names to be checked for existence.
* @return true if all specified cookies are present in the request, false otherwise.
*/
public static boolean hasCookies(HttpServletRequest request, String... cookies) {
return hasCookies(request, Transform4j.fromArray2Coll(cookies));
}

/**
* Checks if the provided ServletRequest contains all the specified cookies.
*
* @param request The ServletRequest object containing cookies to be checked.
* @param cookies A variable number of cookie names to be checked for existence.
* @return true if all specified cookies are present in the request, false otherwise.
*/
public static boolean hasCookies(ServletRequest request, String... cookies) {
if (!(request instanceof HttpServletRequest)) {
return false;
}
return hasCookies((HttpServletRequest) request, cookies);
}

/**
* Checks if the provided HttpServletRequest contains the specified cookie.
*
* @param request The HttpServletRequest object containing cookies to be checked.
* @param cookie The Cookie object to be checked for existence.
* @return true if the specified cookie is present in the request, false otherwise.
*/
public static boolean hasCookie(HttpServletRequest request, Cookie cookie) {
return hasCookies(request, Collections.singletonList(cookie.getName()));
}

/**
* Checks if the provided ServletRequest contains the specified cookie.
*
* @param request The ServletRequest object containing cookies to be checked.
* @param cookie The Cookie object to be checked for existence.
* @return true if the specified cookie is present in the request, false otherwise.
*/
public static boolean hasCookie(ServletRequest request, Cookie cookie) {
if (!(request instanceof HttpServletRequest)) {
return false;
}
return hasCookie((HttpServletRequest) request, cookie);
}

/**
* Checks if the provided HttpServletRequest has any cookies.
*
* @param request The HttpServletRequest object to check for available cookies.
* @return true if the request contains cookies, false otherwise.
*/
public static boolean isAvailableCookie(HttpServletRequest request) {
return Collection4j.isNotEmptyMap(getCookies(request));
}

/**
* Checks if the provided ServletRequest has any cookies.
*
* @param request The ServletRequest object to check for available cookies.
* @return true if the request contains cookies, false otherwise.
*/
public static boolean isAvailableCookie(ServletRequest request) {
if (!(request instanceof HttpServletRequest)) {
return false;
}
return isAvailableCookie((HttpServletRequest) request);
}
}
137 changes: 137 additions & 0 deletions plugin/src/main/groovy/org/unify4j/common/Os4j.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package org.unify4j.common;

public class Os4j {
protected final static char SLASH_CHAR = '/';
protected final static char BACK_SLASH_CHAR = '\\';

/**
* Normalizes the given path by replacing all backslashes with forward slashes.
*
* @param path The path to be normalized.
* @return The normalized path with all backslashes replaced by forward slashes.
*/
public static String normalised(String path) {
return normalised(path, BACK_SLASH_CHAR, SLASH_CHAR);
}

/**
* Normalizes the given path by replacing all occurrences of the specified separator with the new separator.
*
* @param path The path to be normalized.
* @param separator The character to be replaced.
* @return The normalized path with the specified separator replaced.
*/
public static String normalised(String path, char separator) {
return normalised(path, separator, separator);
}

/**
* Normalizes the given path by replacing all occurrences of the specified separator with the new separator
* and collapsing any consecutive separators into a single separator.
*
* @param path The path to be normalized.
* @param separator The character to be replaced.
* @param newSeparator The character to replace with.
* @return The normalized path with specified changes.
*/
public static String normalised(String path, char separator, char newSeparator) {
if (String4j.isEmpty(path)) {
return path;
}
String filename = path.trim();
if (separator != newSeparator) {
filename = filename.replace(separator, newSeparator);
}
return filename.replace(String.format("\\%s{2,}", newSeparator), "\\" + newSeparator);
}

/**
* Normalizes the given path by collapsing any unnecessary segments (such as "." and "..") and
* removing redundant slashes.
*
* @param path The path to be normalized.
* @return The normalized path.
*/
public static String withNormalised(String path) {
if (String4j.isEmpty(path)) {
return path;
}
if (path.indexOf('.') == -1 && path.indexOf('/') == -1) {
return path;
}
boolean isNormalized = true;
int noSegments = 0;
int lastChar = path.length() - 1;
for (int src = lastChar; src >= 0; ) {
int slash = path.lastIndexOf('/', src);
if (slash != -1) {
if (slash == src) {
if (src != lastChar) {
isNormalized = false;
}
} else {
noSegments++;
}
} else {
noSegments++;
}
src = slash - 1;
}
int[] segments = new int[noSegments];
char[] chars = new char[path.length()];
path.getChars(0, chars.length, chars, 0);
noSegments = 0;
for (int src = 0; src < chars.length; ) {
while (src < chars.length && chars[src] == '/') {
src++;
}
if (src < chars.length) {
segments[noSegments++] = src;
while (src < chars.length && chars[src] != '/') {
src++;
}
}
}
final int DELETED = -1;
for (int segment = 0; segment < noSegments; segment++) {
int src = segments[segment];
if (chars[src++] == '.') {
if (src == chars.length || chars[src] == '/') {
segments[segment] = DELETED;
isNormalized = false;
} else {
if (chars[src++] == '.' && (src == chars.length || chars[src] == '/')) {
for (int toDelete = segment - 1; toDelete >= 0; toDelete--) {
if (segments[toDelete] != DELETED) {
if (chars[segments[toDelete]] != '.') {
segments[toDelete] = DELETED;
segments[segment] = DELETED;
isNormalized = false;
}
break;
}
}
}
}
}
}
if (isNormalized) {
return path;
} else {
int dst = (chars[0] == '/') ? 1 : 0;
for (int segment = 0; segment < noSegments; segment++) {
int segmentStart = segments[segment];
if (segmentStart != DELETED) {
for (int src = segmentStart; src < chars.length; src++) {
char ch = chars[src];
chars[dst++] = ch;
if (ch == '/') {
break;
}
}
}
}
return new String(chars, 0, dst);
}
}
}
15 changes: 14 additions & 1 deletion plugin/src/main/groovy/org/unify4j/common/Transform4j.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class Transform4j {
protected static final Logger logger = LoggerFactory.getLogger(Transform4j.class);
Expand Down Expand Up @@ -41,10 +44,20 @@ public static char[] fromArray2Chars(String[] arrays) {
* If the collection is not empty, it converts the collection to an array of strings using the toArray method.
* The returned array contains the string representations of the elements in the collection.
*/
public static String[] fromColl2StringArray(Collection<?> collection) {
public static String[] fromColl2Array(Collection<?> collection) {
if (!Collection4j.isEmpty(collection)) {
return collection.stream().map(Object::toString).toArray(String[]::new);
}
return null;
}

/**
* Converts an array of strings into a List of strings.
*
* @param strings The array of strings to convert.
* @return A List containing the strings from the input array.
*/
public static List<String> fromArray2Coll(String[] strings) {
return new ArrayList<>(Arrays.asList(strings));
}
}
Loading

0 comments on commit 0705351

Please sign in to comment.