Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 55 additions & 158 deletions src/main/java/fr/sandro642/github/jobs/JobGetInfos.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class JobGetInfos {
*/
private URLProvider urlBranch;

private String fullRoute = "";
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The instance variable fullRoute introduces thread safety issues. Multiple threads could concurrently call getRoutes(), params(), or query() on the same JobGetInfos instance, leading to race conditions where threads overwrite each other's route values. Consider making fullRoute a local variable passed between methods or using ThreadLocal storage.

Suggested change
private String fullRoute = "";
// Removed fullRoute instance variable for thread safety.

Copilot uses AI. Check for mistakes.

/**
* Constructor of JobGetInfos.
* Initializes the ApiClient and loads the YAML configuration.
Expand All @@ -59,196 +61,91 @@ private String getRouteName(Enum<?> routeName) {
return routeName.name().toLowerCase();
}

/**
* Get routes from the YAML file and builds the full URL.
* @param versionType Version of the API (V1_BRANCH, V2_BRANCH)
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param body Body of the request for POST (can be null for GET)
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, Enum<?> routeName, Map<String, ?> body) {
return getRoutes(versionType, methodType, getRouteName(routeName), body, null, null);
}

/**
* Get routes from the YAML file and builds the full URL with parameters.
* @param versionType Version of the API (V1_BRANCH, V2_BRANCH)
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, Enum<?> routeName) {
return getRoutes(versionType, methodType, getRouteName(routeName), null, null, null);
}

/**
* Get routes from the YAML file and builds the full URL with a request body.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, Enum<?> routeName) {
return getRoutes(null, methodType, getRouteName(routeName), null, null, null);
}

/**
* Get routes from the YAML file and builds the full URL with a request body and parameters.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param body Body of the request for POST (can be null for GET)
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, Enum<?> routeName, Map<String, ?> body) {
return getRoutes(null, methodType, getRouteName(routeName), body, null, null);
}

/**
* Get routes from the YAML file and builds the full URL with additional parameters.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param params Additional parameters for the request
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, Enum<?> routeName, Map<String, ?> body, Map<String, ?> params) {
return getRoutes(null, methodType, getRouteName(routeName), body, params, null);
}

/**
* Get routes from the YAML file and builds the full URL.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, String routeName) {
return getRoutes(null, methodType, routeName, null, null, null);
}

/**
* Récupère les routes depuis le fichier YAML et construit l'URL complète
* @param versionType Version de l'API (V1_BRANCH, V2_BRANCH)
* @param methodType Type de méthode HTTP (GET, POST)
* @param routeName Nom de la route dans le fichier YAML
* @return JobGetInfos pour chaînage
*/
public JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, String routeName) {
return getRoutes(versionType, methodType, routeName, null, null, null);
return getRoutes(null, methodType, getRouteName(routeName));
}

/**
* Get routes from the YAML file and builds the full URL with a request body.
* @param versionType Version of the API (V1_BRANCH, V2_BRANCH)
* @param versionType VersionProvider to specify API versioning
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param body Body of the request for POST (can be null for GET)
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, String routeName, Map<String, ?> body) {
return getRoutes(versionType, methodType, routeName, body, null, null);
}

/**
* Get routes from the YAML file and builds the full URL with a request body and parameters.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param body Body of the request for POST (can be null for GET)
* @param params Additional parameters for the request
* @param query Additional query parameters for the request
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, String routeName, Map<String, ?> body, Map<String, ?> params, Map<String, ?> query) {
return getRoutes(null, methodType, routeName, body, params, query);
}

/**
* Get routes from the YAML file and builds the full URL with additional parameters.
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param body Body of the request for POST (can be null for GET)
* @param params Additional parameters for the request
* @param query Additional query parameters for the request
* @return JobGetInfos for chaining
*/
public JobGetInfos getRoutes(MethodType methodType, Enum<?> routeName, Map<String, ?> body, Map<String, ?> params, Map<String, ?> query) {
return getRoutes(null, methodType, getRouteName(routeName), body, params, query);
}

/**
* Get routes from the YAML file and builds the full URL with additional parameters.
* @param versionType Version of the API (V1_BRANCH, V2_BRANCH)
* @param methodType Type of HTTP method (GET, POST)
* @param routeName Name of the route in the YAML file
* @param params Additional parameters for the request
* @param query Additional query parameters for the request
* @return JobGetInfos for chaining
*/
public <R> JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, R routeName, Map<String, ?> body, Map<String, ?> params, Map<String, ?> query) {
public <R> JobGetInfos getRoutes(VersionProvider versionType, MethodType methodType, R routeName) {
try {
String route = connectLib.getRoute(routeName.toString().toLowerCase());

String fullRoute;

if (versionType != null && versionType.getVersion() != null) {
String cleanRoute = route.startsWith("/") ? route.substring(1) : route;
fullRoute = "/" + versionType.getVersion() + "/" + cleanRoute;
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Inconsistent use of this keyword: line 87 assigns to fullRoute without this, while line 89 uses this.fullRoute. For better code consistency and readability, use this.fullRoute in both places.

Suggested change
fullRoute = "/" + versionType.getVersion() + "/" + cleanRoute;
this.fullRoute = "/" + versionType.getVersion() + "/" + cleanRoute;

Copilot uses AI. Check for mistakes.
} else {
fullRoute = route;
this.fullRoute = route;
}

if (params != null && !params.isEmpty()) {
for (Map.Entry<String, ?> entry : params.entrySet()) {
String paramKey = "{" + entry.getKey() + "}";
String paramValue = entry.getValue().toString();
fullRoute = fullRoute.replace(paramKey, paramValue);
}
}
connectLib.StoreAndRetrieve().store.put("currentRoute", this.fullRoute);
connectLib.StoreAndRetrieve().store.put("currentMethod", methodType);

// New query string handling logic
if (query != null && !query.isEmpty()) {
// Pattern for capturing parameters between $
Pattern pattern = Pattern.compile("\\$([^$]+)\\$");
Matcher matcher = pattern.matcher(fullRoute);

StringBuilder queryString = new StringBuilder("?");
boolean firstParam = true;

// Iterate through all matches (parameters between $)
while (matcher.find()) {
String paramName = matcher.group(1); // Get parameter name without $

// Check if this parameter exists in the query map
if (query.containsKey(paramName)) {
if (!firstParam) {
queryString.append("&");
}
queryString.append(paramName).append("=").append(query.get(paramName));
firstParam = false;
}
}
connectLib.Logger().INFO(connectLib.LangManager().getMessage(CategoriesType.JOBS_PACKAGE, "getroutes.maderoute", "route", fullRoute));
} catch (Exception e) {
connectLib.Logger().ERROR(connectLib.LangManager().getMessage(CategoriesType.JOBS_PACKAGE, "getroutes.error", "exception", e.getMessage()));
}
return this;
}

// Append query string to the route only if parameters were added
if (queryString.length() > 1) {
// Clean the route by removing $parameter$ placeholders and extra &
String cleanRoute = fullRoute.replaceAll("\\$[^$]+\\$", "").replaceAll("&+", "");
fullRoute = cleanRoute + queryString.toString();
}
}
public JobGetInfos body(Map<?, ?> body) {
connectLib.StoreAndRetrieve().store.put("currentBody", body);
return this;
}
Comment on lines +102 to +105
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation for the newly added public method body(). Add JavaDoc to describe its purpose, parameters, and return value to maintain consistency with the existing codebase documentation standards.

Copilot uses AI. Check for mistakes.

connectLib.StoreAndRetrieve().store.put("currentRoute", fullRoute);
connectLib.StoreAndRetrieve().store.put("currentMethod", methodType);
public JobGetInfos params(Map<?, ?> params) {
if (params == null || params.isEmpty()) return this;

if (body != null) {
connectLib.StoreAndRetrieve().store.put("currentBody", body);
}
for (Map.Entry<?, ?> entry : params.entrySet()) {
String paramKey = "{" + entry.getKey() + "}";
String paramValue = entry.getValue() == null ? "" : entry.getValue().toString();
this.fullRoute = this.fullRoute.replace(paramKey, paramValue);
}

connectLib.StoreAndRetrieve().store.put("currentParams", params);
connectLib.StoreAndRetrieve().store.put("currentRoute", this.fullRoute);
return this;
}
Comment on lines +107 to +119
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation for the newly added public method params(). Add JavaDoc to describe its purpose, parameters, and return value to maintain consistency with the existing codebase documentation standards.

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +119
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The params() method modifies this.fullRoute but will fail if getRoutes() hasn't been called first, as fullRoute is initialized to empty string. This creates a fragile method call order dependency. Consider validating that fullRoute is not empty or documenting the required call order.

Copilot uses AI. Check for mistakes.

public JobGetInfos query(Map<?, ?> query) {
if (query == null || query.isEmpty()) return this;

if (params != null) {
connectLib.StoreAndRetrieve().store.put("currentParams", params);
Pattern pattern = Pattern.compile("\\$([^$]+)\\$");
Matcher matcher = pattern.matcher(this.fullRoute);

StringBuilder queryString = new StringBuilder("?");
boolean firstParam = true;

while (matcher.find()) {
String paramName = matcher.group(1);
if (query.containsKey(paramName)) {
if (!firstParam) {
queryString.append("&");
}
Object value = query.get(paramName);
queryString.append(paramName).append("=").append(value == null ? "" : value.toString());
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query parameter values are not URL-encoded before being appended to the query string. Special characters in parameter values (e.g., spaces, &, =) will cause malformed URLs or incorrect query strings. Use URLEncoder.encode(value.toString(), StandardCharsets.UTF_8) to properly encode the values.

Copilot uses AI. Check for mistakes.
firstParam = false;
}
}

connectLib.Logger().INFO(connectLib.LangManager().getMessage(CategoriesType.JOBS_PACKAGE, "getroutes.maderoute", "route", fullRoute));
} catch (Exception e) {
connectLib.Logger().ERROR(connectLib.LangManager().getMessage(CategoriesType.JOBS_PACKAGE, "getroutes.error", "exception", e.getMessage()));
if (queryString.length() > 1) {
String cleanRoute = this.fullRoute.replaceAll("\\$[^$]+\\$", "").replaceAll("&+", "");
this.fullRoute = cleanRoute + queryString.toString();
}

connectLib.StoreAndRetrieve().store.put("currentRoute", this.fullRoute);
connectLib.StoreAndRetrieve().store.put("currentQuery", query);
return this;
}
Comment on lines +121 to 150
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation for the newly added public method query(). Add JavaDoc to describe its purpose, parameters, and return value to maintain consistency with the existing codebase documentation standards.

Copilot uses AI. Check for mistakes.
Comment on lines +121 to 150
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query() method modifies this.fullRoute but will fail if getRoutes() hasn't been called first, as fullRoute is initialized to empty string. This creates a fragile method call order dependency. Consider validating that fullRoute is not empty or documenting the required call order.

Copilot uses AI. Check for mistakes.

Expand Down
39 changes: 36 additions & 3 deletions src/test/java/fr/sandro642/github/test/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public class MainTest {
public enum TestRoutes implements RouteImport {
HELLO("/hello"),
GREET("greet$name$"),
REQUEST_TOKEN("/auth/request/token")
REQUEST_TOKEN("/auth/request/token"),
SESSION_PUSH("/auth/link/app/{sessionId}")
;

final String route;
Expand Down Expand Up @@ -131,7 +132,7 @@ public void testUseFullRoute() {
);

CompletableFuture<ApiFactory> factoryCompletableFuture = connectLib.JobGetInfos()
.getRoutes(MethodType.GET, TestRoutes.GREET, null, null, query)
.getRoutes(MethodType.GET, TestRoutes.GREET)
.execute();

ApiFactory response = factoryCompletableFuture.get(5, TimeUnit.SECONDS);
Expand Down Expand Up @@ -171,6 +172,14 @@ public void testLangType() {
}
}

private String code_session;

@Test
public void testProd() {
testSpecData();

pushsession();
}

@Test
public void testSpecData() {
Expand All @@ -191,6 +200,31 @@ public void testSpecData() {

System.out.println(apiFactory.getSpecData("data", "accessToken"));

this.code_session = (String) apiFactory.getSpecData("data", "sessionCode");
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential NullPointerException: this.code_session could be null if testSpecData() hasn't been executed first or if the API response doesn't contain the expected data. Add null checking before using this variable, especially since test execution order isn't guaranteed.

Copilot uses AI. Check for mistakes.

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void pushsession() {
try {

Map<?,?> params = Map.of(
"sessionId", this.code_session
);

CompletableFuture<ApiFactory> apiFactoryCompletableFuture = connectLib.JobGetInfos()
.getRoutes(TestCustomVersion.V1_API, MethodType.POST, TestRoutes.SESSION_PUSH)
.urlBranch(ExampleUrlBranch.PROD)
.params(params)
.getResponse();

ApiFactory apiFactory = apiFactoryCompletableFuture.get(5, TimeUnit.SECONDS);

System.out.println("Réponse brute: " + apiFactory.display());

} catch (Exception e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -218,5 +252,4 @@ public void startAppServices() {
}
}


}