Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(java): ✨ allow using placeholders in the boyka config file #988

Merged
merged 3 commits into from
Feb 8, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.github.boykaframework.builders;

import static io.github.boykaframework.utils.StringUtils.interpolate;

import java.util.Map;

import io.github.boykaframework.enums.ContentType;
Expand Down Expand Up @@ -52,22 +50,4 @@ public class ApiRequest {
@Singular
private Map<String, String> queryParams;
private String userName;

/**
* Gets the authentication password.
*
* @return password
*/
public String getPassword () {
return interpolate (this.password);
}

/**
* Gets the authentication username
*
* @return user name.
*/
public String getUserName () {
return interpolate (this.userName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import io.github.boykaframework.enums.AutomationType;
import io.github.boykaframework.enums.Protocol;
import io.github.boykaframework.enums.TargetProviders;
import io.github.boykaframework.utils.StringUtils;
import lombok.Data;

/**
Expand Down Expand Up @@ -76,22 +75,4 @@ public String getConfigPath () {
return Path.of (System.getProperty ("user.dir"), this.configPath)
.toString ();
}

/**
* Gets cloud password.
*
* @return the cloud password
*/
public String getPassword () {
return StringUtils.interpolate (this.password);
}

/**
* Gets cloud user name.
*
* @return the cloud username.
*/
public String getUserName () {
return StringUtils.interpolate (this.userName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

import static io.github.boykaframework.enums.Browser.NONE;
import static io.github.boykaframework.enums.Protocol.HTTP;
import static io.github.boykaframework.enums.TargetProviders.LOCAL;
import static io.github.boykaframework.enums.WindowResizeType.NORMAL;
import static io.github.boykaframework.utils.StringUtils.interpolate;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -56,25 +54,7 @@ public class WebSetting {
private int port;
private Protocol protocol = HTTP;
private WindowResizeType resize = NORMAL;
private TargetProviders target = LOCAL;
private TargetProviders target;
private String userName;
private String version = "stable";

/**
* Gets cloud password.
*
* @return the cloud password
*/
public String getPassword () {
return interpolate (this.password);
}

/**
* Gets cloud user name.
*
* @return the cloud username.
*/
public String getUserName () {
return interpolate (this.userName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Expand All @@ -45,6 +46,8 @@ public final class JsonUtil {

static {
GSON = new GsonBuilder ().setFieldNamingPolicy (LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter (String.class, new StringPlaceholderDeserializer ())
.registerTypeAdapter (Map.class, new MapPlaceholderDeserializer ())
.setPrettyPrinting ()
.create ();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* MIT License
*
* Copyright (c) 2025, Boyka Framework
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package io.github.boykaframework.utils;

import static com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES;
import static io.github.boykaframework.utils.StringUtils.interpolate;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;

/**
* GSON Map placeholder deserializer.
*
* @author Wasiq Bhamla
* @since 04-Feb-2025
*/
class MapPlaceholderDeserializer implements JsonDeserializer<Map<String, Object>> {
@Override
public Map<String, Object> deserialize (final JsonElement jsonElement, final Type type,
final JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
final var map = jsonElement.getAsJsonObject ();
final var gson = new GsonBuilder ().setFieldNamingPolicy (LOWER_CASE_WITH_UNDERSCORES)
.setPrettyPrinting ()
.create ();
final var parsedMap = interpolateMapValues (map);
final var parsedJson = gson.toJson (parsedMap);
return gson.fromJson (parsedJson, type);
}

private void interpolateArrayValues (final Map<String, Object> result, final String key,
final JsonArray jsonArray) {
final List<Object> list = new ArrayList<> ();
jsonArray.forEach (jsonElement -> list.add (interpolate (jsonElement.getAsString ())));
result.put (key, list);
}

private Map<String, Object> interpolateMapValues (final JsonObject map) {
final Map<String, Object> result = new HashMap<> ();
map.entrySet ()
.forEach (entry -> {
final var key = entry.getKey ();
final var value = entry.getValue ();
if (value.isJsonObject ()) {
result.put (key, interpolateMapValues (value.getAsJsonObject ()));
} else if (value.isJsonArray ()) {
interpolateArrayValues (result, key, value.getAsJsonArray ());
} else if (value.isJsonPrimitive ()) {
interpolatePrimitive (result, key, value.getAsJsonPrimitive ());
} else if (value.isJsonNull ()) {
result.put (key, value.getAsJsonNull ());
}
});
return result;
}

private void interpolatePrimitive (final Map<String, Object> result, final String key, final JsonPrimitive value) {
if (value.isBoolean ()) {
result.put (key, value.getAsBoolean ());
} else if (value.isNumber ()) {
result.put (key, value.getAsNumber ());
} else if (value.isString ()) {
result.put (key, interpolate (value.getAsString ()));
} else if (value.isJsonNull ()) {
result.put (key, value.getAsJsonNull ());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.github.boykaframework.utils;

import static io.github.boykaframework.enums.Message.CONFIG_KEY_NOT_FOUND;
import static io.github.boykaframework.utils.ErrorHandler.throwError;
import static io.github.boykaframework.utils.JsonUtil.fromFile;
import static java.lang.String.join;
import static java.lang.System.getProperty;
Expand Down Expand Up @@ -55,7 +56,7 @@ public static <T> T getSetting (final Map<String, T> settings, final String key)
LOGGER.traceEntry ("Key: {}", key);
if (!settings.containsKey (key)) {
final var keys = join (", ", settings.keySet ());
ErrorHandler.throwError (CONFIG_KEY_NOT_FOUND, key, keys);
throwError (CONFIG_KEY_NOT_FOUND, key, keys);
}
return LOGGER.traceExit (settings.get (key));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* MIT License
*
* Copyright (c) 2025, Boyka Framework
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package io.github.boykaframework.utils;

import static io.github.boykaframework.utils.StringUtils.interpolate;

import java.lang.reflect.Type;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

/**
* GSON String placeholder deserializer.
*
* @author Wasiq Bhamla
* @since 04-Feb-2025
*/
class StringPlaceholderDeserializer implements JsonDeserializer<String> {
@Override
public String deserialize (final JsonElement jsonElement, final Type type,
final JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
final var placeholderValue = jsonElement.getAsString ();
return interpolate (placeholderValue);
}
}
1 change: 1 addition & 0 deletions core-java/src/test/resources/boyka-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
},
"experimental_options": {
"prefs": {
"download.default_directory": "${sys:user.home}/Downloads",
"download.prompt_for_download": false,
"safebrowsing.enabled": true
}
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@
"license": "MIT",
"private": true,
"devDependencies": {
"@commitlint/cli": "^19.6.1",
"@commitlint/config-conventional": "^19.6.0",
"@commitlint/cli": "^19.7.1",
"@commitlint/config-conventional": "^19.7.1",
"@eslint/compat": "^1.2.6",
"@lerna/child-process": "^7.4.2",
"@release-it-plugins/lerna-changelog": "^7.0.0",
"@stylistic/eslint-plugin-js": "^3.0.1",
"@stylistic/eslint-plugin-ts": "^3.0.1",
"@types/node": "^22.13.0",
"@typescript-eslint/eslint-plugin": "^8.22.0",
"@typescript-eslint/parser": "^8.22.0",
"commitlint": "^19.6.1",
"@types/node": "^22.13.1",
"@typescript-eslint/eslint-plugin": "^8.23.0",
"@typescript-eslint/parser": "^8.23.0",
"commitlint": "^19.7.1",
"eslint": "^9.19.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^10.0.1",
Expand All @@ -56,14 +56,14 @@
"lerna-version": "^6.6.2",
"lint-staged": "^15.4.3",
"lodash": "^4.17.21",
"nx": "^20.4.0",
"nx": "^20.4.1",
"prettier": "^3.4.2",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"release-it": "^18.1.2",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"typescript-eslint": "^8.22.0"
"typescript-eslint": "^8.23.0"
},
"scripts": {
"preinstall": "npx only-allow pnpm",
Expand Down
Loading
Loading