diff --git a/README.md b/README.md index b827f3f..9214958 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ For adding a library only: com.instancify.scriptify core - 1.4.0-SNAPSHOT + 1.4.1-SNAPSHOT ``` @@ -30,12 +30,12 @@ For adding a library with JS for Rhino or GraalVM: com.instancify.scriptify script-js-rhino - 1.4.0-SNAPSHOT + 1.4.1-SNAPSHOT com.instancify.scriptify script-js-graalvm - 1.4.0-SNAPSHOT + 1.4.1-SNAPSHOT ``` ## Gradle @@ -49,11 +49,11 @@ maven { For adding a library only: ```groovy -implementation "com.instancify.scriptify:core:1.4.0-SNAPSHOT" +implementation "com.instancify.scriptify:core:1.4.1-SNAPSHOT" ``` For adding a library with JS for Rhino or GraalVM: ```groovy -implementation "com.instancify.scriptify:script-js-rhino:1.4.0-SNAPSHOT" -implementation "com.instancify.scriptify:script-js-graalvm:1.4.0-SNAPSHOT" +implementation "com.instancify.scriptify:script-js-rhino:1.4.1-SNAPSHOT" +implementation "com.instancify.scriptify:script-js-graalvm:1.4.1-SNAPSHOT" ``` \ No newline at end of file diff --git a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgTypeException.java b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgTypeException.java deleted file mode 100644 index 2b073e4..0000000 --- a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgTypeException.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.instancify.scriptify.api.exception; - -import java.util.Collection; -import java.util.stream.Collectors; - -/** - * Exception for script function argument type mismatches. - */ -public class ScriptFunctionArgTypeException extends ScriptFunctionException { - - /** - * Creates an exception when argument types don't match. - * - * @param required The expected type - * @param provided The type that was given - */ - public ScriptFunctionArgTypeException(Class required, Class provided) { - super("Required argument type: " + required + ", passed: " + provided); - } - - /** - * Creates an exception when argument types don't match. - * - * @param required The expected types - * @param provided The type that was given - */ - public ScriptFunctionArgTypeException(Collection> required, Class provided) { - super("Required argument types: " + createRequiredClassNames(required) + ", passed: " + provided); - } - - private static String createRequiredClassNames(Collection> required) { - return required.stream().map(Class::getName).collect(Collectors.joining(" or ")); - } -} diff --git a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgsCountException.java b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgsCountException.java deleted file mode 100644 index a767f6e..0000000 --- a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgsCountException.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.instancify.scriptify.api.exception; - -/** - * Exception for when the count of arguments in a script function call is incorrect. - */ -public class ScriptFunctionArgsCountException extends ScriptFunctionException { - - /** - * Creates an exception when the number of arguments doesn't match. - * - * @param required The expected number of arguments - * @param provided The number of arguments actually provided - */ - public ScriptFunctionArgsCountException(int required, int provided) { - super("Required number of arguments: " + required + ", passed: " + provided); - } -} diff --git a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentCountMismatchException.java b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentCountMismatchException.java new file mode 100644 index 0000000..cb246e7 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentCountMismatchException.java @@ -0,0 +1,26 @@ +package com.instancify.scriptify.api.exception; + +/** + * Exception thrown when a function is called with + * an incorrect number of arguments. + */ +public class ScriptFunctionArgumentCountMismatchException extends ScriptFunctionException { + + /** + * Creates a new exception for a mismatch in argument count. + * + * @param functionName The name of the function + * @param expectedMin The minimum number of expected arguments + * @param expectedMax The maximum number of expected arguments + * @param provided The number of arguments actually provided + */ + public ScriptFunctionArgumentCountMismatchException( + String functionName, + int expectedMin, + int expectedMax, + int provided + ) { + super("Function '" + functionName + "' expects between " + + expectedMin + " and " + expectedMax + " arguments, but got " + provided); + } +} diff --git a/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentTypeMismatchException.java b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentTypeMismatchException.java new file mode 100644 index 0000000..bdc5909 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/exception/ScriptFunctionArgumentTypeMismatchException.java @@ -0,0 +1,28 @@ +package com.instancify.scriptify.api.exception; + +/** + * Exception thrown when a function is called with arguments + * of incompatible types. + */ +public class ScriptFunctionArgumentTypeMismatchException extends ScriptFunctionException { + + /** + * Creates a new exception for an argument type mismatch. + * + * @param functionName The name of the function + * @param index The index of the argument that failed validation + * @param expected The expected type of the argument + * @param actual The actual type of the provided argument + */ + public ScriptFunctionArgumentTypeMismatchException( + String functionName, + int index, + Class expected, + Class actual + ) { + super("Function '" + functionName + "' argument #" + index + + " expected type " + expected.getName() + + " but got " + (actual == null ? "null" : actual.getName())); + } +} + diff --git a/api/src/main/java/com/instancify/scriptify/api/script/constant/ScriptConstantManager.java b/api/src/main/java/com/instancify/scriptify/api/script/constant/ScriptConstantManager.java index 0141ba1..0933546 100644 --- a/api/src/main/java/com/instancify/scriptify/api/script/constant/ScriptConstantManager.java +++ b/api/src/main/java/com/instancify/scriptify/api/script/constant/ScriptConstantManager.java @@ -1,6 +1,7 @@ package com.instancify.scriptify.api.script.constant; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; import java.util.Map; @@ -14,7 +15,7 @@ public interface ScriptConstantManager { * * @return A map where keys are constant names and values are ScriptConstant instances */ - Map getConstants(); + @UnmodifiableView Map getConstants(); /** * Gets a specific constant by its name. diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunction.java b/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunction.java index a6c86b3..6613498 100644 --- a/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunction.java +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunction.java @@ -1,10 +1,6 @@ package com.instancify.scriptify.api.script.function; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Represents a function that can be used within scripts. @@ -17,14 +13,4 @@ public interface ScriptFunction { * @return The function's name */ @NotNull String getName(); - - /** - * Invokes the function with the provided arguments. - * - * @param script The script in which the function will be invoked - * @param args The arguments to pass to the function - * @return The result of the function execution - * @throws ScriptFunctionException If there's an error during invocation - */ - @Nullable Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException; } diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunctionManager.java b/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunctionManager.java index 62cc0f9..e615048 100644 --- a/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunctionManager.java +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/ScriptFunctionManager.java @@ -1,6 +1,8 @@ package com.instancify.scriptify.api.script.function; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; import java.util.Map; @@ -14,7 +16,7 @@ public interface ScriptFunctionManager { * * @return A map where keys are function names and values are ScriptFunction instances */ - Map getFunctions(); + @UnmodifiableView Map getFunctions(); /** * Gets a specific function by its name. @@ -22,7 +24,7 @@ public interface ScriptFunctionManager { * @param name The name of the function to retrieve * @return The ScriptFunction associated with the name, or null if not found */ - default @Nullable ScriptFunction getFunction(String name) { + default @Nullable ScriptFunctionDefinition getFunction(String name) { return this.getFunctions().get(name); } diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Argument.java b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Argument.java new file mode 100644 index 0000000..c12d4da --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Argument.java @@ -0,0 +1,14 @@ +package com.instancify.scriptify.api.script.function.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Argument { + String name(); + + boolean required() default true; +} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/ExecuteAt.java b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/ExecuteAt.java new file mode 100644 index 0000000..1669483 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/ExecuteAt.java @@ -0,0 +1,12 @@ +package com.instancify.scriptify.api.script.function.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ExecuteAt { + +} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Executor.java b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Executor.java new file mode 100644 index 0000000..2584113 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/annotation/Executor.java @@ -0,0 +1,12 @@ +package com.instancify.scriptify.api.script.function.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface Executor { + +} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/argument/ScriptFunctionArgument.java b/api/src/main/java/com/instancify/scriptify/api/script/function/argument/ScriptFunctionArgument.java deleted file mode 100644 index 1bcfad6..0000000 --- a/api/src/main/java/com/instancify/scriptify/api/script/function/argument/ScriptFunctionArgument.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.instancify.scriptify.api.script.function.argument; - -/** - * Represents an argument that can be passed to a script function. - */ -public interface ScriptFunctionArgument { - - /** - * Retrieves the value of this argument. - * - * @return The value of the argument - */ - Object getValue(); - - /** - * Retrieves type the of value of this argument. - * - * @return Type the value of the argument - */ - default Class getType() { - return this.getValue().getClass(); - } - - /** - * Checks if the value of this argument is an instance of the specified class. - * - * @param classOf The class to check against - * @return true if the value is an instance of the given class, false otherwise - */ - default boolean is(Class classOf) { - return classOf.isInstance(getValue()); - } - - /** - * Casts the value of this argument to the specified class type. - * - * @param The type to cast to - * @param classOf The class representing the type to cast to - * @return The value cast to the specified type - * @throws ClassCastException if the value cannot be cast to the specified type - */ - default T as(Class classOf) { - return classOf.cast(getValue()); - } - - /** - * Creates a new ScriptFunctionArgument with the given value. - * - * @param value The value to be wrapped as an argument - * @return A new ScriptFunctionArgument instance - */ - static ScriptFunctionArgument of(Object value) { - return new ScriptFunctionArgument() { - @Override - public Object getValue() { - return value; - } - - @Override - public String toString() { - return value.toString(); - } - }; - } -} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionArgumentDefinition.java b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionArgumentDefinition.java new file mode 100644 index 0000000..4c104f4 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionArgumentDefinition.java @@ -0,0 +1,28 @@ +package com.instancify.scriptify.api.script.function.definition; + +/** + * Represents a single argument in a script function definition. + */ +public interface ScriptFunctionArgumentDefinition { + + /** + * Retrieves the name of this argument. + * + * @return The argument name + */ + String getName(); + + /** + * Indicates whether this argument is required. + * + * @return true if the argument must be provided, false if it is optional + */ + boolean isRequired(); + + /** + * Retrieves the expected Java type of this argument. + * + * @return The argument type + */ + Class getType(); +} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionDefinition.java b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionDefinition.java new file mode 100644 index 0000000..7313db6 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionDefinition.java @@ -0,0 +1,35 @@ +package com.instancify.scriptify.api.script.function.definition; + +import com.instancify.scriptify.api.script.function.ScriptFunction; + +import java.util.List; + +/** + * Represents the definition of a {@link ScriptFunction}, including + * its available executors parsed from annotated methods. + */ +public interface ScriptFunctionDefinition { + + /** + * Retrieves the underlying script function. + * + * @return The associated {@link ScriptFunction} + */ + ScriptFunction getFunction(); + + /** + * Retrieves all executors available for this function. + * + * @return A list of {@link ScriptFunctionExecutor} instances + */ + List getExecutors(); + + /** + * Finds an executor matching the given argument types. + * + * @param arguments the argument types to match + * @return the matching {@link ScriptFunctionExecutor} + * @throws IllegalArgumentException if you cannot find a matching executor + */ + ScriptFunctionExecutor getExecutor(Class... arguments); +} diff --git a/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionExecutor.java b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionExecutor.java new file mode 100644 index 0000000..a931d64 --- /dev/null +++ b/api/src/main/java/com/instancify/scriptify/api/script/function/definition/ScriptFunctionExecutor.java @@ -0,0 +1,41 @@ +package com.instancify.scriptify.api.script.function.definition; + +import com.instancify.scriptify.api.exception.ScriptFunctionException; +import com.instancify.scriptify.api.script.Script; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * Represents an executable method of a script function, + * responsible for invoking the annotated logic. + */ +public interface ScriptFunctionExecutor { + + Method getMethod(); + + /** + * Retrieves the argument definitions for this executor. + * + * @return a list of {@link ScriptFunctionArgumentDefinition} + */ + List getArguments(); + + /** + * Checks whether this executor matches the given argument types. + * + * @param types the argument types to match + * @return true if the executor is compatible, false otherwise + */ + boolean matches(Class... types); + + /** + * Executes this function with the given script context and arguments. + * + * @param script The script instance to pass to the executor + * @param args The function arguments + * @return The result of execution + * @throws ScriptFunctionException if execution fails or arguments are invalid + */ + Object execute(Script script, Object... args) throws ScriptFunctionException; +} diff --git a/build.gradle.kts b/build.gradle.kts index f856ba6..b428289 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ java { allprojects { group = "com.instancify.scriptify" - version = "1.4.0-SNAPSHOT" + version = "1.4.1-SNAPSHOT" } subprojects { diff --git a/security/build.gradle.kts b/common/build.gradle.kts similarity index 75% rename from security/build.gradle.kts rename to common/build.gradle.kts index 70f5c43..943bd6a 100644 --- a/security/build.gradle.kts +++ b/common/build.gradle.kts @@ -7,5 +7,5 @@ repositories { } dependencies { - api(project(":api")) + api(project(":core")) } \ No newline at end of file diff --git a/common/src/main/java/com/instancify/scriptify/common/script/constant/CommonConstantManager.java b/common/src/main/java/com/instancify/scriptify/common/script/constant/CommonConstantManager.java new file mode 100644 index 0000000..480cd48 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/constant/CommonConstantManager.java @@ -0,0 +1,13 @@ +package com.instancify.scriptify.common.script.constant; + +import com.instancify.scriptify.core.script.constant.StandardConstantManager; +import com.instancify.scriptify.core.script.constant.impl.ScriptConstantBaseDir; +import com.instancify.scriptify.core.script.constant.impl.ScriptConstantOsName; + +public class CommonConstantManager extends StandardConstantManager { + + public CommonConstantManager() { + this.register(new ScriptConstantOsName()); + this.register(new ScriptConstantBaseDir()); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantBaseDir.java b/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantBaseDir.java new file mode 100644 index 0000000..790729f --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantBaseDir.java @@ -0,0 +1,22 @@ +package com.instancify.scriptify.common.script.constant.impl; + +import com.instancify.scriptify.api.script.constant.ScriptConstant; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Paths; + +/** + * Represents a constant with base dir + */ +public class ScriptConstantBaseDir implements ScriptConstant { + + @Override + public @NotNull String getName() { + return "baseDir"; + } + + @Override + public Object getValue() { + return Paths.get("").toAbsolutePath().toString(); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantOsName.java b/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantOsName.java new file mode 100644 index 0000000..2362724 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/constant/impl/ScriptConstantOsName.java @@ -0,0 +1,20 @@ +package com.instancify.scriptify.common.script.constant.impl; + +import com.instancify.scriptify.api.script.constant.ScriptConstant; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a constant with os name + */ +public class ScriptConstantOsName implements ScriptConstant { + + @Override + public @NotNull String getName() { + return "osName"; + } + + @Override + public Object getValue() { + return System.getProperty("os.name"); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/CommonFunctionManager.java b/common/src/main/java/com/instancify/scriptify/common/script/function/CommonFunctionManager.java new file mode 100644 index 0000000..6428d9e --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/CommonFunctionManager.java @@ -0,0 +1,53 @@ +package com.instancify.scriptify.common.script.function; + +import com.instancify.scriptify.common.script.function.impl.crypto.ScriptFunctionBase64Decode; +import com.instancify.scriptify.common.script.function.impl.crypto.ScriptFunctionBase64Encode; +import com.instancify.scriptify.common.script.function.impl.crypto.ScriptFunctionMD5; +import com.instancify.scriptify.common.script.function.impl.crypto.ScriptFunctionSHA256; +import com.instancify.scriptify.common.script.function.impl.file.*; +import com.instancify.scriptify.common.script.function.impl.os.ScriptFunctionEnv; +import com.instancify.scriptify.common.script.function.impl.os.ScriptFunctionExecCommand; +import com.instancify.scriptify.common.script.function.impl.random.*; +import com.instancify.scriptify.common.script.function.impl.util.*; +import com.instancify.scriptify.common.script.function.impl.zip.ScriptFunctionSmartUnzipFile; +import com.instancify.scriptify.common.script.function.impl.zip.ScriptFunctionSmartZipFile; +import com.instancify.scriptify.common.script.function.impl.zip.ScriptFunctionUnzipFile; +import com.instancify.scriptify.common.script.function.impl.zip.ScriptFunctionZipFile; +import com.instancify.scriptify.core.script.function.StandardFunctionManager; + +public class CommonFunctionManager extends StandardFunctionManager { + + public CommonFunctionManager() { + this.register(new ScriptFunctionPrint()); + this.register(new ScriptFunctionExistsFile()); + this.register(new ScriptFunctionDeleteFile()); + this.register(new ScriptFunctionMoveFile()); + this.register(new ScriptFunctionListFiles()); + this.register(new ScriptFunctionReadFile()); + this.register(new ScriptFunctionWriteFile()); + this.register(new ScriptFunctionZipFile()); + this.register(new ScriptFunctionUnzipFile()); + this.register(new ScriptFunctionSmartZipFile()); + this.register(new ScriptFunctionSmartUnzipFile()); + this.register(new ScriptFunctionNormalizePath()); + this.register(new ScriptFunctionBase64Encode()); + this.register(new ScriptFunctionBase64Decode()); + this.register(new ScriptFunctionDownloadFromUrl()); + this.register(new ScriptFunctionJoinPath()); + this.register(new ScriptFunctionRandomUUID()); + this.register(new ScriptFunctionRandomInteger()); + this.register(new ScriptFunctionRandomLong()); + this.register(new ScriptFunctionRandomFloat()); + this.register(new ScriptFunctionRandomDouble()); + this.register(new ScriptFunctionMD5()); + this.register(new ScriptFunctionSHA256()); + this.register(new ScriptFunctionExecCommand()); + this.register(new ScriptFunctionEnv()); + this.register(new ScriptFunctionShuffleArray()); + this.register(new ScriptFunctionListOf()); + this.register(new ScriptFunctionSetOf()); + this.register(new ScriptFunctionArrayOf()); + this.register(new ScriptFunctionRegexPattern()); + this.register(new ScriptFunctionRegexMatch()); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Decode.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Decode.java new file mode 100644 index 0000000..3327e84 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Decode.java @@ -0,0 +1,27 @@ +package com.instancify.scriptify.common.script.function.impl.crypto; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +/** + * Represents a function to decode base64 to string + */ +public class ScriptFunctionBase64Decode implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "base64decode"; + } + + @ExecuteAt + public String execute( + @Argument(name = "string") String string + ) { + return new String(Base64.getDecoder().decode(string), StandardCharsets.UTF_8); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Encode.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Encode.java new file mode 100644 index 0000000..61f0a9a --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionBase64Encode.java @@ -0,0 +1,26 @@ +package com.instancify.scriptify.common.script.function.impl.crypto; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Base64; + +/** + * Represents a function to encode string to base64 + */ +public class ScriptFunctionBase64Encode implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "base64encode"; + } + + @ExecuteAt + public String execute( + @Argument(name = "string") String string + ) { + return Base64.getEncoder().encodeToString(string.getBytes()); + } +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionMD5.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionMD5.java similarity index 51% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionMD5.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionMD5.java index 824f3b7..dce2fa6 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionMD5.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionMD5.java @@ -1,11 +1,8 @@ -package com.instancify.scriptify.core.script.function.impl.crypto; +package com.instancify.scriptify.common.script.function.impl.crypto; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; import org.jetbrains.annotations.NotNull; import java.math.BigInteger; @@ -17,21 +14,16 @@ * Represents a function to generate md5 hash for string */ public class ScriptFunctionMD5 implements ScriptFunction { + @Override public @NotNull String getName() { return "md5"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String input)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - + @ExecuteAt + public String execute( + @Argument(name = "input") String input + ) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8)); @@ -44,7 +36,7 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr } return hashtext; } catch (NoSuchAlgorithmException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } } } diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionSHA256.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionSHA256.java similarity index 52% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionSHA256.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionSHA256.java index 08ac8b0..038778a 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionSHA256.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/crypto/ScriptFunctionSHA256.java @@ -1,11 +1,8 @@ -package com.instancify.scriptify.core.script.function.impl.crypto; +package com.instancify.scriptify.common.script.function.impl.crypto; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; import org.jetbrains.annotations.NotNull; import java.math.BigInteger; @@ -17,21 +14,16 @@ * Represents a function to generate sha256 hash for string */ public class ScriptFunctionSHA256 implements ScriptFunction { + @Override public @NotNull String getName() { return "sha256"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String input)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - + @ExecuteAt + public String execute( + @Argument(name = "input") String input + ) { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8)); @@ -44,7 +36,7 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr } return hashtext; } catch (NoSuchAlgorithmException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } } } diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDeleteFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDeleteFile.java similarity index 50% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDeleteFile.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDeleteFile.java index 36bd64e..e644c7a 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDeleteFile.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDeleteFile.java @@ -1,11 +1,10 @@ -package com.instancify.scriptify.core.script.function.impl.file; +package com.instancify.scriptify.common.script.function.impl.file; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -20,25 +19,14 @@ public class ScriptFunctionDeleteFile implements ScriptFunction { return "deleteFile"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length > 2 || args.length < 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - if (!(args[0].getValue() instanceof String filePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - if (args.length == 1) { - return script.getSecurityManager().getFileSystem().getFile(filePath).delete(); - } - - if (!(args[1].getValue() instanceof Boolean recursive)) { - throw new ScriptFunctionArgTypeException(Boolean.class, args[1].getType()); - } - + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "filePath") String filePath, + @Argument(name = "recursive", required = false) Boolean recursive + ) { File file = script.getSecurityManager().getFileSystem().getFile(filePath); - if (recursive) { + if (recursive != null && recursive) { return deleteDirectoryRecursively(file); } else { return file.delete(); diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDownloadFromUrl.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDownloadFromUrl.java new file mode 100644 index 0000000..bc4b456 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionDownloadFromUrl.java @@ -0,0 +1,40 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; + +/** + * Represents a function to download file from url + */ +public class ScriptFunctionDownloadFromUrl implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "downloadFromUrl"; + } + + @ExecuteAt + public void execute( + @Executor Script script, + @Argument(name = "url") String url, + @Argument(name = "filePath") String filePath + ) { + try (InputStream in = new URI(url).toURL().openStream()) { + File targetPath = script.getSecurityManager().getFileSystem().getFile(filePath); + Files.copy(in, targetPath.toPath()); + } catch (IOException | URISyntaxException e) { + throw new RuntimeException(e); + } + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionExistsFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionExistsFile.java new file mode 100644 index 0000000..e3ffaa0 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionExistsFile.java @@ -0,0 +1,29 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.nio.file.Files; + +/** + * Represents a function to check the existence of a file + */ +public class ScriptFunctionExistsFile implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "existsFile"; + } + + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "filePath") String filePath + ) { + return Files.exists(script.getSecurityManager().getFileSystem().getPath(filePath)); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionJoinPath.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionJoinPath.java new file mode 100644 index 0000000..dc98ef6 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionJoinPath.java @@ -0,0 +1,32 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a function to join path + */ +public class ScriptFunctionJoinPath implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "joinPath"; + } + + @ExecuteAt + public String execute( + @Argument(name = "args") String... args + ) { + StringBuilder path = new StringBuilder(); + for (String arg : args) { + if (path.isEmpty()) { + path.append(arg); + } else { + path.append('/').append(arg); + } + } + return path.toString(); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionListFiles.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionListFiles.java new file mode 100644 index 0000000..1bc0f31 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionListFiles.java @@ -0,0 +1,36 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.Arrays; +import java.util.Objects; + +/** + * Represents a function to get all files in a folder + */ +public class ScriptFunctionListFiles implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "listFiles"; + } + + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "filePath") String filePath + ) { + File folder = script.getSecurityManager().getFileSystem().getFile(filePath); + if (folder.isDirectory()) { + return Arrays.stream(Objects.requireNonNull(folder.listFiles())).map(File::getAbsolutePath).toList(); + } else { + throw new RuntimeException("File is not a folder"); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionMoveFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionMoveFile.java new file mode 100644 index 0000000..5caa306 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionMoveFile.java @@ -0,0 +1,31 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * Represents a function to move file + */ +public class ScriptFunctionMoveFile implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "moveFile"; + } + + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "original") String originalFilePath, + @Argument(name = "target") String targetFilePath + ) { + File fileToMove = script.getSecurityManager().getFileSystem().getFile(originalFilePath); + return fileToMove.renameTo(script.getSecurityManager().getFileSystem().getFile(targetFilePath)); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionNormalizePath.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionNormalizePath.java new file mode 100644 index 0000000..ef5a27e --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionNormalizePath.java @@ -0,0 +1,21 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +public class ScriptFunctionNormalizePath implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "normalizePath"; + } + + @ExecuteAt + public String execute( + @Argument(name = "path") String path + ) { + return path.replace('\\', '/'); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionReadFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionReadFile.java new file mode 100644 index 0000000..51e890f --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionReadFile.java @@ -0,0 +1,34 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Files; + +/** + * Represents a function to read the contents of a file + */ +public class ScriptFunctionReadFile implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "readFile"; + } + + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "filePath") String filePath + ) { + try { + return Files.readString(script.getSecurityManager().getFileSystem().getPath(filePath)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionWriteFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionWriteFile.java new file mode 100644 index 0000000..b784bc1 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/file/ScriptFunctionWriteFile.java @@ -0,0 +1,36 @@ +package com.instancify.scriptify.common.script.function.impl.file; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Files; + +/** + * Represents a function to write the contents of a file + */ +public class ScriptFunctionWriteFile implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "writeFile"; + } + + @ExecuteAt + public Object execute( + @Executor Script script, + @Argument(name = "filePath") String filePath, + @Argument(name = "fileContent") String fileContent + ) { + try { + return Files.writeString(script.getSecurityManager().getFileSystem().getPath(filePath), fileContent); + } catch (IOException e) { + throw new RuntimeException(e); + + } + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionEnv.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionEnv.java new file mode 100644 index 0000000..4249d4e --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionEnv.java @@ -0,0 +1,24 @@ +package com.instancify.scriptify.common.script.function.impl.os; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +/** + * Represents a function to get environment variable value + */ +public class ScriptFunctionEnv implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "env"; + } + + @ExecuteAt + public String execute( + @Argument(name = "name") String name + ) { + return System.getenv(name); + } +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionExecCommand.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionExecCommand.java similarity index 57% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionExecCommand.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionExecCommand.java index bb9cef3..ed73166 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionExecCommand.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/os/ScriptFunctionExecCommand.java @@ -1,11 +1,8 @@ -package com.instancify.scriptify.core.script.function.impl.os; +package com.instancify.scriptify.common.script.function.impl.os; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; import org.jetbrains.annotations.NotNull; import java.io.BufferedReader; @@ -22,16 +19,10 @@ public class ScriptFunctionExecCommand implements ScriptFunction { return "execCommand"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String input)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - + @ExecuteAt + public String execute( + @Argument(name = "input") String input + ) { try { Process process = Runtime.getRuntime().exec(input); @@ -49,7 +40,7 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr } return message.toString(); } catch (IOException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } } } diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomDouble.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomDouble.java new file mode 100644 index 0000000..3be5abd --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomDouble.java @@ -0,0 +1,34 @@ +package com.instancify.scriptify.common.script.function.impl.random; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +/** + * Represents a function to generate random double number + */ +public class ScriptFunctionRandomDouble implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "randomDouble"; + } + + @ExecuteAt + public double execute( + @Argument(name = "max") Double max + ) { + return new Random().nextDouble(max); + } + + @ExecuteAt + public double execute( + @Argument(name = "min") Double min, + @Argument(name = "max") Double max + ) { + return new Random().nextDouble(min, max); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomFloat.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomFloat.java new file mode 100644 index 0000000..df1b79e --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomFloat.java @@ -0,0 +1,34 @@ +package com.instancify.scriptify.common.script.function.impl.random; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +/** + * Represents a function to generate random float number + */ +public class ScriptFunctionRandomFloat implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "randomFloat"; + } + + @ExecuteAt + public float execute( + @Argument(name = "max") Float max + ) { + return new Random().nextFloat(max); + } + + @ExecuteAt + public float execute( + @Argument(name = "min") Float min, + @Argument(name = "max") Float max + ) { + return new Random().nextFloat(min, max); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomInteger.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomInteger.java new file mode 100644 index 0000000..ac676be --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomInteger.java @@ -0,0 +1,34 @@ +package com.instancify.scriptify.common.script.function.impl.random; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +/** + * Represents a function to generate random integer number + */ +public class ScriptFunctionRandomInteger implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "randomInt"; + } + + @ExecuteAt + public int execute( + @Argument(name = "max") Integer max + ) { + return new Random().nextInt(max); + } + + @ExecuteAt + public int execute( + @Argument(name = "min") Integer min, + @Argument(name = "max") Integer max + ) { + return new Random().nextInt(min, max); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomLong.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomLong.java new file mode 100644 index 0000000..b217e3c --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomLong.java @@ -0,0 +1,34 @@ +package com.instancify.scriptify.common.script.function.impl.random; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +/** + * Represents a function to generate random long number + */ +public class ScriptFunctionRandomLong implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "randomLong"; + } + + @ExecuteAt + public long execute( + @Argument(name = "max") Long max + ) { + return new Random().nextLong(max); + } + + @ExecuteAt + public long execute( + @Argument(name = "min") Long min, + @Argument(name = "max") Long max + ) { + return new Random().nextLong(min, max); + } +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomUUID.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomUUID.java similarity index 50% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomUUID.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomUUID.java index 34762b9..ffd71c8 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomUUID.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/random/ScriptFunctionRandomUUID.java @@ -1,9 +1,7 @@ -package com.instancify.scriptify.core.script.function.impl.random; +package com.instancify.scriptify.common.script.function.impl.random; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -18,8 +16,8 @@ public class ScriptFunctionRandomUUID implements ScriptFunction { return "randomUUID"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { + @ExecuteAt + public String execute() { return UUID.randomUUID().toString(); } } diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionArrayOf.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionArrayOf.java new file mode 100644 index 0000000..495298a --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionArrayOf.java @@ -0,0 +1,26 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +/** + * Represents a function to create an array from the passed arguments + */ +public class ScriptFunctionArrayOf implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "arrayOf"; + } + + @ExecuteAt + public Object[] execute( + @Argument(name = "args") Object... args + ) { + return Arrays.stream(args).toArray(); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionListOf.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionListOf.java new file mode 100644 index 0000000..ee7310b --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionListOf.java @@ -0,0 +1,27 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +/** + * Represents a function to create a list from the passed arguments + */ +public class ScriptFunctionListOf implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "listOf"; + } + + @ExecuteAt + public List execute( + @Argument(name = "args") Object... args + ) { + return Arrays.asList(args); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionPrint.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionPrint.java new file mode 100644 index 0000000..d9ab03e --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionPrint.java @@ -0,0 +1,27 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Represents a function for outputting messages to the console + */ +public class ScriptFunctionPrint implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "print"; + } + + @ExecuteAt + public void execute( + @Argument(name = "args") Object... args + ) { + System.out.println(Arrays.stream(args).map(Object::toString).collect(Collectors.joining(" "))); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexMatch.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexMatch.java new file mode 100644 index 0000000..9e96898 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexMatch.java @@ -0,0 +1,35 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +/** + * Represents a function to match regex pattern + */ +public class ScriptFunctionRegexMatch implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "regex_match"; + } + + @ExecuteAt + public boolean execute( + @Argument(name = "regex") String regex, + @Argument(name = "value") String value + ) { + return Pattern.compile(regex).matcher(value).matches(); + } + + @ExecuteAt + public boolean execute( + @Argument(name = "pattern") Pattern pattern, + @Argument(name = "value") String value + ) { + return pattern.matcher(value).matches(); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexPattern.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexPattern.java new file mode 100644 index 0000000..a29dd2c --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionRegexPattern.java @@ -0,0 +1,26 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +/** + * Represents a function to compile regex pattern. + */ +public class ScriptFunctionRegexPattern implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "regex_pattern"; + } + + @ExecuteAt + public Pattern execute( + @Argument(name = "pattern") String pattern + ) { + return Pattern.compile(pattern); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionSetOf.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionSetOf.java new file mode 100644 index 0000000..6cd241d --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionSetOf.java @@ -0,0 +1,28 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Represents a function to create a set from the passed arguments + */ +public class ScriptFunctionSetOf implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "setOf"; + } + + @ExecuteAt + public Set execute( + @Argument(name = "args") Object... args + ) { + return new HashSet<>(Arrays.asList(args)); + } +} diff --git a/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionShuffleArray.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionShuffleArray.java new file mode 100644 index 0000000..fd725d3 --- /dev/null +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/util/ScriptFunctionShuffleArray.java @@ -0,0 +1,30 @@ +package com.instancify.scriptify.common.script.function.impl.util; + +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a function to shuffle an array + */ +public class ScriptFunctionShuffleArray implements ScriptFunction { + + @Override + public @NotNull String getName() { + return "shuffleArray"; + } + + @ExecuteAt + public List execute( + @Argument(name = "array") List array + ) { + List list = new ArrayList<>(array); + Collections.shuffle(list); + return list; + } +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java similarity index 68% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java index a3fc5f2..b670137 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartUnzipFile.java @@ -1,11 +1,10 @@ -package com.instancify.scriptify.core.script.function.impl.zip; +package com.instancify.scriptify.common.script.function.impl.zip; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -27,30 +26,19 @@ public class ScriptFunctionSmartUnzipFile implements ScriptFunction { return "smartUnzipFile"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 3) { - throw new ScriptFunctionArgsCountException(3, args.length); - } - - if (!(args[0].getValue() instanceof String compressedFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String decompressedPath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - if (!(args[2].getValue() instanceof List patterns)) { - throw new ScriptFunctionArgTypeException(List.class, args[2].getType()); - } - + @ExecuteAt + public void execute( + @Executor Script script, + @Argument(name = "compressedFilePath") String compressedFilePath, + @Argument(name = "decompressedPath") String decompressedPath, + @Argument(name = "patterns") List patterns + ) { try { - File fileCompressed = new File(compressedFilePath); - File fileDecompressed = new File(decompressedPath); + File fileCompressed = script.getSecurityManager().getFileSystem().getFile(compressedFilePath); + File fileDecompressed = script.getSecurityManager().getFileSystem().getFile(decompressedPath); // Convert patterns to regex patterns List regexPatterns = patterns.stream() - .filter(String.class::isInstance) - .map(String.class::cast) .map(Pattern::compile) .toList(); @@ -88,10 +76,8 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr zis.closeEntry(); } } catch (IOException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } - - return null; } private File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartZipFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartZipFile.java similarity index 63% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartZipFile.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartZipFile.java index c658a6f..1b3a182 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionSmartZipFile.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionSmartZipFile.java @@ -1,11 +1,10 @@ -package com.instancify.scriptify.core.script.function.impl.zip; +package com.instancify.scriptify.common.script.function.impl.zip; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -13,6 +12,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -27,36 +27,25 @@ public class ScriptFunctionSmartZipFile implements ScriptFunction { return "smartZipFile"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 3) { - throw new ScriptFunctionArgsCountException(3, args.length); - } - - if (!(args[0].getValue() instanceof String filesPath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String compressedFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - if (!(args[2].getValue() instanceof List patterns)) { - throw new ScriptFunctionArgTypeException(List.class, args[2].getType()); - } - + @ExecuteAt + public void execute( + @Executor Script script, + @Argument(name = "filesPath") String filesPath, + @Argument(name = "compressedFilePath") String compressedFilePath, + @Argument(name = "patterns") List patterns + ) { try { - File filesToZip = new File(filesPath); - File compressedFile = new File(compressedFilePath); + File filesToZip = script.getSecurityManager().getFileSystem().getFile(filesPath); + File compressedFile = script.getSecurityManager().getFileSystem().getFile(compressedFilePath); FileOutputStream fos = new FileOutputStream(compressedFile); ZipOutputStream zipOut = new ZipOutputStream(fos); List regexPatterns = patterns.stream() - .filter(String.class::isInstance) - .map(String.class::cast) .map(Pattern::compile) .toList(); if (filesToZip.isDirectory()) { - for (File file : filesToZip.listFiles()) { + for (File file : Objects.requireNonNull(filesToZip.listFiles())) { String fileName = file.getName(); boolean matches = regexPatterns.stream().anyMatch(pattern -> pattern.matcher(fileName).matches()); @@ -69,10 +58,8 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr zipOut.close(); fos.close(); } catch (IOException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } - - return null; } private void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException { diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionUnzipFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionUnzipFile.java similarity index 67% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionUnzipFile.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionUnzipFile.java index 60f6580..bf01da4 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionUnzipFile.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionUnzipFile.java @@ -1,11 +1,10 @@ -package com.instancify.scriptify.core.script.function.impl.zip; +package com.instancify.scriptify.common.script.function.impl.zip; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -25,22 +24,15 @@ public class ScriptFunctionUnzipFile implements ScriptFunction { return "unzipFile"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(2, args.length); - } - - if (!(args[0].getValue() instanceof String compressedFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String decompressedPath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - + @ExecuteAt + public void execute( + @Executor Script script, + @Argument(name = "compressedFilePath") String compressedFilePath, + @Argument(name = "decompressedPath") String decompressedPath + ) { try { - File fileCompressed = new File(compressedFilePath); - File fileDecompressed = new File(decompressedPath); + File fileCompressed = script.getSecurityManager().getFileSystem().getFile(compressedFilePath); + File fileDecompressed = script.getSecurityManager().getFileSystem().getFile(decompressedPath); byte[] buffer = new byte[1024]; ZipInputStream zis = new ZipInputStream(new FileInputStream(fileCompressed)); @@ -72,10 +64,8 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr zis.closeEntry(); zis.close(); } catch (IOException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } - - return null; } private File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionZipFile.java b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionZipFile.java similarity index 63% rename from core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionZipFile.java rename to common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionZipFile.java index f93cb86..8f3b09f 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/zip/ScriptFunctionZipFile.java +++ b/common/src/main/java/com/instancify/scriptify/common/script/function/impl/zip/ScriptFunctionZipFile.java @@ -1,11 +1,10 @@ -package com.instancify.scriptify.core.script.function.impl.zip; +package com.instancify.scriptify.common.script.function.impl.zip; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -25,22 +24,15 @@ public class ScriptFunctionZipFile implements ScriptFunction { return "zipFile"; } - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(2, args.length); - } - - if (!(args[0].getValue() instanceof String filePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String compressedFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - + @ExecuteAt + public void execute( + @Executor Script script, + @Argument(name = "filePath") String filePath, + @Argument(name = "compressedFilePath") String compressedFilePath + ) { try { - File fileToZip = new File(filePath); - File compressedFile = new File(compressedFilePath); + File fileToZip = script.getSecurityManager().getFileSystem().getFile(filePath); + File compressedFile = script.getSecurityManager().getFileSystem().getFile(compressedFilePath); FileOutputStream fos = new FileOutputStream(compressedFile); ZipOutputStream zipOut = new ZipOutputStream(fos); @@ -49,10 +41,8 @@ public Object invoke(Script script, ScriptFunctionArgument[] args) throws Scr zipOut.close(); fos.close(); } catch (IOException e) { - throw new ScriptFunctionException(e); + throw new RuntimeException(e); } - - return null; } private void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException { diff --git a/core/src/main/java/com/instancify/scriptify/core/script/constant/StandardConstantManager.java b/core/src/main/java/com/instancify/scriptify/core/script/constant/StandardConstantManager.java index e889c42..b460636 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/constant/StandardConstantManager.java +++ b/core/src/main/java/com/instancify/scriptify/core/script/constant/StandardConstantManager.java @@ -2,9 +2,9 @@ import com.instancify.scriptify.api.script.constant.ScriptConstant; import com.instancify.scriptify.api.script.constant.ScriptConstantManager; -import com.instancify.scriptify.core.script.constant.impl.ScriptConstantBaseDir; -import com.instancify.scriptify.core.script.constant.impl.ScriptConstantOsName; +import org.jetbrains.annotations.UnmodifiableView; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -12,14 +12,9 @@ public class StandardConstantManager implements ScriptConstantManager { private final Map constants = new HashMap<>(); - public StandardConstantManager() { - this.register(new ScriptConstantOsName()); - this.register(new ScriptConstantBaseDir()); - } - @Override - public Map getConstants() { - return constants; + public @UnmodifiableView Map getConstants() { + return Collections.unmodifiableMap(constants); } @Override diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/StandardFunctionManager.java b/core/src/main/java/com/instancify/scriptify/core/script/function/StandardFunctionManager.java index 162c577..81e618a 100644 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/StandardFunctionManager.java +++ b/core/src/main/java/com/instancify/scriptify/core/script/function/StandardFunctionManager.java @@ -2,72 +2,29 @@ import com.instancify.scriptify.api.script.function.ScriptFunction; import com.instancify.scriptify.api.script.function.ScriptFunctionManager; -import com.instancify.scriptify.core.script.function.impl.util.*; -import com.instancify.scriptify.core.script.function.impl.crypto.ScriptFunctionBase64Decode; -import com.instancify.scriptify.core.script.function.impl.crypto.ScriptFunctionBase64Encode; -import com.instancify.scriptify.core.script.function.impl.crypto.ScriptFunctionMD5; -import com.instancify.scriptify.core.script.function.impl.crypto.ScriptFunctionSHA256; -import com.instancify.scriptify.core.script.function.impl.file.*; -import com.instancify.scriptify.core.script.function.impl.os.ScriptFunctionEnv; -import com.instancify.scriptify.core.script.function.impl.os.ScriptFunctionExecCommand; -import com.instancify.scriptify.core.script.function.impl.random.*; -import com.instancify.scriptify.core.script.function.impl.zip.ScriptFunctionSmartUnzipFile; -import com.instancify.scriptify.core.script.function.impl.zip.ScriptFunctionSmartZipFile; -import com.instancify.scriptify.core.script.function.impl.zip.ScriptFunctionUnzipFile; -import com.instancify.scriptify.core.script.function.impl.zip.ScriptFunctionZipFile; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; +import com.instancify.scriptify.core.script.function.definition.ScriptFunctionDefinitionImpl; +import org.jetbrains.annotations.UnmodifiableView; +import java.util.Collections; import java.util.HashMap; import java.util.Map; public class StandardFunctionManager implements ScriptFunctionManager { - private final Map functions = new HashMap<>(); - - public StandardFunctionManager() { - this.register(new ScriptFunctionPrint()); - this.register(new ScriptFunctionExistsFile()); - this.register(new ScriptFunctionDeleteFile()); - this.register(new ScriptFunctionMoveFile()); - this.register(new ScriptFunctionListFiles()); - this.register(new ScriptFunctionReadFile()); - this.register(new ScriptFunctionWriteFile()); - this.register(new ScriptFunctionZipFile()); - this.register(new ScriptFunctionUnzipFile()); - this.register(new ScriptFunctionSmartUnzipFile()); - this.register(new ScriptFunctionSmartZipFile()); - this.register(new ScriptFunctionNormalizePath()); - this.register(new ScriptFunctionBase64Encode()); - this.register(new ScriptFunctionBase64Decode()); - this.register(new ScriptFunctionDownloadFromUrl()); - this.register(new ScriptFunctionJoinPath()); - this.register(new ScriptFunctionRandomUUID()); - this.register(new ScriptFunctionRandomInteger()); - this.register(new ScriptFunctionRandomLong()); - this.register(new ScriptFunctionRandomFloat()); - this.register(new ScriptFunctionRandomDouble()); - this.register(new ScriptFunctionMD5()); - this.register(new ScriptFunctionSHA256()); - this.register(new ScriptFunctionExecCommand()); - this.register(new ScriptFunctionEnv()); - this.register(new ScriptFunctionShuffleArray()); - this.register(new ScriptFunctionListOf()); - this.register(new ScriptFunctionSetOf()); - this.register(new ScriptFunctionArrayOf()); - this.register(new ScriptFunctionRegexPattern()); - this.register(new ScriptFunctionRegexMatch()); - } + private final Map functions = new HashMap<>(); @Override - public Map getFunctions() { - return functions; + public @UnmodifiableView Map getFunctions() { + return Collections.unmodifiableMap(functions); } @Override public void register(ScriptFunction function) { if (!functions.containsKey(function.getName())) { - functions.put(function.getName(), function); + functions.put(function.getName(), new ScriptFunctionDefinitionImpl(function)); } else { - throw new IllegalStateException("The function with this name already exists"); + throw new IllegalStateException("The function with name '" + function.getName() + "' already exists"); } } @@ -76,7 +33,7 @@ public void remove(String name) { if (functions.containsKey(name)) { functions.remove(name); } else { - throw new IllegalArgumentException("The function with this name does not exist"); + throw new IllegalArgumentException("The function with name '" + name + "' does not exist"); } } } \ No newline at end of file diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionArgumentDefinitionImpl.java b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionArgumentDefinitionImpl.java new file mode 100644 index 0000000..23fa8cd --- /dev/null +++ b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionArgumentDefinitionImpl.java @@ -0,0 +1,15 @@ +package com.instancify.scriptify.core.script.function.definition; + +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionArgumentDefinition; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; + +@Getter +@AllArgsConstructor +@ToString +public class ScriptFunctionArgumentDefinitionImpl implements ScriptFunctionArgumentDefinition { + private final String name; + private final boolean required; + private final Class type; +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionDefinitionImpl.java b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionDefinitionImpl.java new file mode 100644 index 0000000..82e876f --- /dev/null +++ b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionDefinitionImpl.java @@ -0,0 +1,103 @@ +package com.instancify.scriptify.core.script.function.definition; + +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; +import com.instancify.scriptify.api.script.function.annotation.Executor; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionArgumentDefinition; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionExecutor; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class ScriptFunctionDefinitionImpl implements ScriptFunctionDefinition { + + private final ScriptFunction function; + private final List executors = new ArrayList<>(); + + public ScriptFunctionDefinitionImpl(ScriptFunction function) { + this.function = function; + this.parseExecutors(); + } + + private void parseExecutors() { + for (Method method : function.getClass().getDeclaredMethods()) { + if (!method.isAnnotationPresent(ExecuteAt.class)) continue; + + List arguments = new ArrayList<>(); + int executorIndex = -1; + + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + + if (parameter.isAnnotationPresent(Executor.class)) { + if (executorIndex != -1) { + throw new IllegalStateException("Multiple @Executor parameters not allowed"); + } + if (!Script.class.isAssignableFrom(parameter.getType())) { + throw new IllegalStateException("@Executor must be of type Script"); + } + executorIndex = i; + continue; + } + + Argument argAnn = parameter.getAnnotation(Argument.class); + if (argAnn != null) { + arguments.add(new ScriptFunctionArgumentDefinitionImpl( + argAnn.name(), + argAnn.required(), + parameter.getType() + )); + } else { + throw new IllegalStateException("All parameters except @Executor must be annotated with @Argument"); + } + } + + // Checking the order of arguments (required cannot come after optional) + boolean foundOptional = false; + for (ScriptFunctionArgumentDefinition def : arguments) { + if (!def.isRequired()) { + foundOptional = true; + } else if (foundOptional) { + throw new IllegalStateException("Required argument cannot follow an optional argument"); + } + } + + method.setAccessible(true); + executors.add(new ScriptFunctionExecutorImpl(function, method, executorIndex, arguments)); + } + + if (executors.isEmpty()) { + throw new IllegalStateException("No executors defined"); + } + } + + @Override + public ScriptFunction getFunction() { + return function; + } + + @Override + public List getExecutors() { + return executors; + } + + @Override + public ScriptFunctionExecutor getExecutor(Class... arguments) { + for (ScriptFunctionExecutor executor : executors) { + if (executor.matches(arguments)) { + return executor; + } + } + throw new IllegalArgumentException("No matching function for arguments: " + + Arrays.stream(arguments).map(Class::getName).collect(Collectors.joining(", "))); + } + +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionExecutorImpl.java b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionExecutorImpl.java new file mode 100644 index 0000000..1297f0a --- /dev/null +++ b/core/src/main/java/com/instancify/scriptify/core/script/function/definition/ScriptFunctionExecutorImpl.java @@ -0,0 +1,92 @@ +package com.instancify.scriptify.core.script.function.definition; + +import com.instancify.scriptify.api.exception.ScriptFunctionArgumentCountMismatchException; +import com.instancify.scriptify.api.exception.ScriptFunctionArgumentTypeMismatchException; +import com.instancify.scriptify.api.exception.ScriptFunctionException; +import com.instancify.scriptify.api.script.Script; +import com.instancify.scriptify.api.script.function.ScriptFunction; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionArgumentDefinition; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionExecutor; +import lombok.Getter; + +import java.lang.reflect.Method; +import java.util.List; + +@Getter +public class ScriptFunctionExecutorImpl implements ScriptFunctionExecutor { + + private final ScriptFunction owner; + private final Method method; + private final int executorIndex; + private final List arguments; + + public ScriptFunctionExecutorImpl(ScriptFunction owner, Method method, int executorIndex, List arguments) { + this.owner = owner; + this.method = method; + this.executorIndex = executorIndex; + this.arguments = arguments; + } + + @Override + public boolean matches(Class... types) { + if (types.length > arguments.size()) return false; + + for (int i = 0; i < types.length; i++) { + if (!arguments.get(i).getType().isAssignableFrom(types[i])) { + return false; + } + } + + for (int i = types.length; i < arguments.size(); i++) { + if (arguments.get(i).isRequired()) { + return false; + } + } + return true; + } + + @Override + public Object execute(Script script, Object... args) throws ScriptFunctionException { + // Checking the number of arguments + int minArgs = (int) arguments.stream().filter(ScriptFunctionArgumentDefinition::isRequired).count(); + int maxArgs = arguments.size(); + if (args.length < minArgs || args.length > maxArgs) { + throw new ScriptFunctionArgumentCountMismatchException( + owner.getName(), minArgs, maxArgs, args.length + ); + } + + // Checking argument types + for (int i = 0; i < args.length; i++) { + Class expected = arguments.get(i).getType(); + Object actual = args[i]; + if (actual != null && !expected.isAssignableFrom(actual.getClass())) { + throw new ScriptFunctionArgumentTypeMismatchException( + owner.getName(), i, expected, actual.getClass() + ); + } + } + + try { + Object[] finalArgs; + + if (executorIndex >= 0) { + finalArgs = new Object[arguments.size() + 1]; + for (int i = 0, j = 0; i < finalArgs.length; i++) { + if (i == executorIndex) { + finalArgs[i] = script; + } else { + finalArgs[i] = (j < args.length) ? args[j] : null; + j++; + } + } + } else { + finalArgs = args; + } + + return method.invoke(owner, finalArgs); + } catch (Exception e) { + throw new ScriptFunctionException("Failed to execute script function '" + owner.getName() + "'", e); + } + } +} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Decode.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Decode.java deleted file mode 100644 index 274c166..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Decode.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.crypto; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; - -/** - * Represents a function to decode base64 to string - */ -public class ScriptFunctionBase64Decode implements ScriptFunction { - @Override - public @NotNull String getName() { - return "base64decode"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String str)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getClass()); - } - - return new String(Base64.getDecoder().decode(str), StandardCharsets.UTF_8); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Encode.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Encode.java deleted file mode 100644 index 7c30e0c..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/crypto/ScriptFunctionBase64Encode.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.crypto; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Base64; - -/** - * Represents a function to encode string to base64 - */ -public class ScriptFunctionBase64Encode implements ScriptFunction { - @Override - public @NotNull String getName() { - return "base64encode"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String str)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - return Base64.getEncoder().encodeToString(str.getBytes()); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDownloadFromUrl.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDownloadFromUrl.java deleted file mode 100644 index 92a8ed9..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionDownloadFromUrl.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.Files; - -/** - * Represents a function to download file from url - */ -public class ScriptFunctionDownloadFromUrl implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "downloadFromUrl"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(2, args.length); - } - - if (!(args[0].getValue() instanceof String url)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String filePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - - try (InputStream in = new URI(url).toURL().openStream()) { - File targetPath = script.getSecurityManager().getFileSystem().getFile(filePath); - Files.copy(in, targetPath.toPath()); - } catch (IOException | URISyntaxException e) { - throw new RuntimeException(e); - } - - return null; - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionExistsFile.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionExistsFile.java deleted file mode 100644 index 4d81a93..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionExistsFile.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Represents a function to check the existence of a file - */ -public class ScriptFunctionExistsFile implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "existsFile"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length == 1) { - if (args[0].getValue() instanceof String filePath) { - return Files.exists(script.getSecurityManager().getFileSystem().getPath(filePath)); - } else { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - } else { - throw new ScriptFunctionArgsCountException(1, args.length); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionJoinPath.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionJoinPath.java deleted file mode 100644 index 55ee2f8..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionJoinPath.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -/** - * Represents a function to join path - */ -public class ScriptFunctionJoinPath implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "joinPath"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - String path = ""; - for (ScriptFunctionArgument arg : args) { - if (arg.getValue() instanceof String segment) { - if (path.isEmpty()) { - path += segment; - } else { - path += '/' + segment; - } - } else { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - } - return path; - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionListFiles.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionListFiles.java deleted file mode 100644 index bc0477c..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionListFiles.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.util.Arrays; -import java.util.Objects; - -/** - * Represents a function to get all files in a folder - */ -public class ScriptFunctionListFiles implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "listFiles"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length == 1) { - if (args[0].getValue() instanceof String filePath) { - File folder = script.getSecurityManager().getFileSystem().getFile(filePath); - if (folder.isDirectory()) { - return Arrays.stream(Objects.requireNonNull(folder.listFiles())).map(File::getAbsolutePath).toList(); - } else { - throw new ScriptFunctionException("File is not a folder"); - } - } else { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - } else { - throw new ScriptFunctionArgsCountException(1, args.length); - } - } -} \ No newline at end of file diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionMoveFile.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionMoveFile.java deleted file mode 100644 index 3a4dc36..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionMoveFile.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.io.File; - -/** - * Represents a function to move file - */ -public class ScriptFunctionMoveFile implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "moveFile"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(2, args.length); - } - - if (!(args[0].getValue() instanceof String originalFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - if (!(args[1].getValue() instanceof String targetFilePath)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - - File fileToMove = script.getSecurityManager().getFileSystem().getFile(originalFilePath); - return fileToMove.renameTo(script.getSecurityManager().getFileSystem().getFile(targetFilePath)); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionNormalizePath.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionNormalizePath.java deleted file mode 100644 index 890cd1c..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionNormalizePath.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -public class ScriptFunctionNormalizePath implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "normalizePath"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String path)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - return path.replace('\\', '/'); - } -} \ No newline at end of file diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionReadFile.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionReadFile.java deleted file mode 100644 index abcaa45..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionReadFile.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -/** - * Represents a function to read the contents of a file - */ -public class ScriptFunctionReadFile implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "readFile"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length == 1) { - if (args[0].getValue() instanceof String filePath) { - try { - return Files.readString(script.getSecurityManager().getFileSystem().getPath(filePath)); - } catch (IOException e) { - throw new ScriptFunctionException(e); - } - } else { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - } else { - throw new ScriptFunctionArgsCountException(1, args.length); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionWriteFile.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionWriteFile.java deleted file mode 100644 index f2f2b60..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/file/ScriptFunctionWriteFile.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.file; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.nio.file.Files; - -/** - * Represents a function to write the contents of a file - */ -public class ScriptFunctionWriteFile implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "writeFile"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length == 2) { - if (args[0].getValue() instanceof String filePath && args[1].getValue() instanceof String fileContent) { - try { - return Files.writeString(script.getSecurityManager().getFileSystem().getPath(filePath), fileContent); - } catch (IOException e) { - throw new ScriptFunctionException(e); - } - } else { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - } else { - throw new ScriptFunctionArgsCountException(2, args.length); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionEnv.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionEnv.java deleted file mode 100644 index 2d11365..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/os/ScriptFunctionEnv.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.os; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -/** - * Represents a function to get environment variable value - */ -public class ScriptFunctionEnv implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "env"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String name)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - return System.getenv(name); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomDouble.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomDouble.java deleted file mode 100644 index 3c7d8bc..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomDouble.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.random; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Random; - -/** - * Represents a function to generate random double number - */ -public class ScriptFunctionRandomDouble implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "randomDouble"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - Random random = new Random(); - if (args.length > 2 || args.length < 1) throw new ScriptFunctionArgsCountException(1, args.length); - - if (args.length == 1) { - if (args[0].getValue() instanceof Number max) { - return random.nextDouble(max.doubleValue()); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } - - if (args[0].getValue() instanceof Number min) { - if (args[1].getValue() instanceof Number max) { - return random.nextDouble(max.doubleValue() - min.doubleValue()) + min.doubleValue(); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[1].getType()); - } - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomFloat.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomFloat.java deleted file mode 100644 index 7201231..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomFloat.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.random; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Random; - -/** - * Represents a function to generate random float number - */ -public class ScriptFunctionRandomFloat implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "randomFloat"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - Random random = new Random(); - if (args.length > 2 || args.length < 1) throw new ScriptFunctionArgsCountException(1, args.length); - - if (args.length == 1) { - if (args[0].getValue() instanceof Number max) { - return random.nextFloat(max.floatValue()); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } - - if (args[0].getValue() instanceof Number min) { - if (args[1].getValue() instanceof Number max) { - return random.nextFloat(max.floatValue() - min.floatValue()) + min.floatValue(); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[1].getType()); - } - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomInteger.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomInteger.java deleted file mode 100644 index a7c4ab8..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomInteger.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.random; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Random; - -/** - * Represents a function to generate random integer number - */ -public class ScriptFunctionRandomInteger implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "randomInt"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - Random random = new Random(); - if (args.length > 2 || args.length < 1) throw new ScriptFunctionArgsCountException(1, args.length); - - if (args.length == 1) { - if (args[0].getValue() instanceof Number max) { - return random.nextInt(max.intValue()); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } - - if (args[0].getValue() instanceof Number min) { - if (args[1].getValue() instanceof Number max) { - return random.nextInt(max.intValue() - min.intValue()) + min.intValue(); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[1].getType()); - } - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomLong.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomLong.java deleted file mode 100644 index 123555f..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/random/ScriptFunctionRandomLong.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.random; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Random; - -/** - * Represents a function to generate random long number - */ -public class ScriptFunctionRandomLong implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "randomLong"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - Random random = new Random(); - if (args.length > 2 || args.length < 1) throw new ScriptFunctionArgsCountException(1, args.length); - - if (args.length == 1) { - if (args[0].getValue() instanceof Number max) { - return random.nextLong(max.longValue()); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } - - if (args[0].getValue() instanceof Number min) { - if (args[1].getValue() instanceof Number max) { - return random.nextLong(max.longValue() - min.longValue()) + min.longValue(); - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[1].getType()); - } - } else { - throw new ScriptFunctionArgTypeException(Number.class, args[0].getType()); - } - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionArrayOf.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionArrayOf.java deleted file mode 100644 index 8cb8a84..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionArrayOf.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; - -/** - * Represents a function to create an array from the passed arguments - */ -public class ScriptFunctionArrayOf implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "arrayOf"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - return Arrays.stream(args).map(ScriptFunctionArgument::getValue).toArray(); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionListOf.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionListOf.java deleted file mode 100644 index 79b3221..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionListOf.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; - -/** - * Represents a function to create a list from the passed arguments - */ -public class ScriptFunctionListOf implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "listOf"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - return Arrays.stream(args).map(ScriptFunctionArgument::getValue).toList(); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionPrint.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionPrint.java deleted file mode 100644 index a0ff55c..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionPrint.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * Represents a function for outputting messages to the console - */ -public class ScriptFunctionPrint implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "print"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) { - System.out.println(Arrays.stream(args).map(arg -> arg.getValue().toString()).collect(Collectors.joining(" "))); - return null; - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexMatch.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexMatch.java deleted file mode 100644 index 9526663..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexMatch.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; -import java.util.regex.Pattern; - -/** - * Represents a function to match regex pattern - */ -public class ScriptFunctionRegexMatch implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "regex_match"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - Pattern pattern; - if (args[0].getValue() instanceof String regex) { - pattern = Pattern.compile(regex); - } else if (args[0].getValue() instanceof Pattern) { - pattern = (Pattern) args[0].getValue(); - } else { - throw new ScriptFunctionArgTypeException(Set.of(String.class, Pattern.class), args[0].getType()); - } - - if (!(args[1].getValue() instanceof String value)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - - return pattern.matcher(value).matches(); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexPattern.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexPattern.java deleted file mode 100644 index 76f7293..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionRegexPattern.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Pattern; - -/** - * Represents a function to compile regex pattern. - */ -public class ScriptFunctionRegexPattern implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "regex_pattern"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof String pattern)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - return Pattern.compile(pattern); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionSetOf.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionSetOf.java deleted file mode 100644 index ef26939..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionSetOf.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.stream.Collectors; - -/** - * Represents a function to create a set from the passed arguments - */ -public class ScriptFunctionSetOf implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "setOf"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - return Arrays.stream(args).map(ScriptFunctionArgument::getValue).collect(Collectors.toUnmodifiableSet()); - } -} diff --git a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionShuffleArray.java b/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionShuffleArray.java deleted file mode 100644 index 6aa22bf..0000000 --- a/core/src/main/java/com/instancify/scriptify/core/script/function/impl/util/ScriptFunctionShuffleArray.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.instancify.scriptify.core.script.function.impl.util; - -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Represents a function to shuffle an array - */ -public class ScriptFunctionShuffleArray implements ScriptFunction { - - @Override - public @NotNull String getName() { - return "shuffleArray"; - } - - @Override - public Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 1) { - throw new ScriptFunctionArgsCountException(1, args.length); - } - - if (!(args[0].getValue() instanceof List array)) { - throw new ScriptFunctionArgTypeException(List.class, args[0].getType()); - } - - List list = new ArrayList(array); - Collections.shuffle(list); - - return list; - } -} diff --git a/security/src/main/java/com/instancify/scriptify/security/SecurityFileSystemImpl.java b/core/src/main/java/com/instancify/scriptify/core/script/security/SecurityFileSystemImpl.java similarity index 93% rename from security/src/main/java/com/instancify/scriptify/security/SecurityFileSystemImpl.java rename to core/src/main/java/com/instancify/scriptify/core/script/security/SecurityFileSystemImpl.java index fe963b1..9f87eca 100644 --- a/security/src/main/java/com/instancify/scriptify/security/SecurityFileSystemImpl.java +++ b/core/src/main/java/com/instancify/scriptify/core/script/security/SecurityFileSystemImpl.java @@ -1,4 +1,4 @@ -package com.instancify.scriptify.security; +package com.instancify.scriptify.core.script.security; import com.instancify.scriptify.api.script.security.SecurityFileSystem; import com.instancify.scriptify.api.script.security.SecurityPathAccessor; diff --git a/security/src/main/java/com/instancify/scriptify/security/SecurityPathAccessorImpl.java b/core/src/main/java/com/instancify/scriptify/core/script/security/SecurityPathAccessorImpl.java similarity index 98% rename from security/src/main/java/com/instancify/scriptify/security/SecurityPathAccessorImpl.java rename to core/src/main/java/com/instancify/scriptify/core/script/security/SecurityPathAccessorImpl.java index 3aea9d8..b4667a0 100644 --- a/security/src/main/java/com/instancify/scriptify/security/SecurityPathAccessorImpl.java +++ b/core/src/main/java/com/instancify/scriptify/core/script/security/SecurityPathAccessorImpl.java @@ -1,4 +1,4 @@ -package com.instancify.scriptify.security; +package com.instancify.scriptify.core.script.security; import com.instancify.scriptify.api.script.security.ScriptSecurityManager; import com.instancify.scriptify.api.script.security.SecurityPathAccessor; diff --git a/security/src/main/java/com/instancify/scriptify/security/StandardSecurityManager.java b/core/src/main/java/com/instancify/scriptify/core/script/security/StandardSecurityManager.java similarity index 96% rename from security/src/main/java/com/instancify/scriptify/security/StandardSecurityManager.java rename to core/src/main/java/com/instancify/scriptify/core/script/security/StandardSecurityManager.java index cf5e971..574ab6e 100644 --- a/security/src/main/java/com/instancify/scriptify/security/StandardSecurityManager.java +++ b/core/src/main/java/com/instancify/scriptify/core/script/security/StandardSecurityManager.java @@ -1,4 +1,4 @@ -package com.instancify.scriptify.security; +package com.instancify.scriptify.core.script.security; import com.instancify.scriptify.api.script.security.ScriptSecurityManager; import com.instancify.scriptify.api.script.security.SecurityPathAccessor; diff --git a/http/src/main/java/com/instancify/scriptify/http/script/function/impl/ScriptFunctionCreateHttpRequest.java b/http/src/main/java/com/instancify/scriptify/http/script/function/impl/ScriptFunctionCreateHttpRequest.java index 0f88d2b..bf34c13 100644 --- a/http/src/main/java/com/instancify/scriptify/http/script/function/impl/ScriptFunctionCreateHttpRequest.java +++ b/http/src/main/java/com/instancify/scriptify/http/script/function/impl/ScriptFunctionCreateHttpRequest.java @@ -1,14 +1,10 @@ package com.instancify.scriptify.http.script.function.impl; -import com.instancify.scriptify.api.exception.ScriptFunctionArgTypeException; -import com.instancify.scriptify.api.exception.ScriptFunctionArgsCountException; -import com.instancify.scriptify.api.exception.ScriptFunctionException; -import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.annotation.Argument; +import com.instancify.scriptify.api.script.function.annotation.ExecuteAt; import com.instancify.scriptify.http.script.function.data.HttpRequest; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Represents a function create http request @@ -20,20 +16,11 @@ public class ScriptFunctionCreateHttpRequest implements ScriptFunction { return "createHttpRequest"; } - @Override - public @Nullable Object invoke(Script script, ScriptFunctionArgument[] args) throws ScriptFunctionException { - if (args.length != 2) { - throw new ScriptFunctionArgsCountException(2, args.length); - } - - if (!(args[0].getValue() instanceof String url)) { - throw new ScriptFunctionArgTypeException(String.class, args[0].getType()); - } - - if (!(args[1].getValue() instanceof String method)) { - throw new ScriptFunctionArgTypeException(String.class, args[1].getType()); - } - + @ExecuteAt + public HttpRequest execute( + @Argument(name = "url") String url, + @Argument(name = "method") String method + ) { return new HttpRequest(url, method); } } diff --git a/script-js-graalvm/build.gradle.kts b/script-js-graalvm/build.gradle.kts index 05daa86..6c13dec 100644 --- a/script-js-graalvm/build.gradle.kts +++ b/script-js-graalvm/build.gradle.kts @@ -7,7 +7,7 @@ repositories { } dependencies { - api(project(":security")) + api(project(":core")) api("org.graalvm.polyglot:polyglot:24.1.1") api("org.graalvm.polyglot:js:24.1.1") } \ No newline at end of file diff --git a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsFunction.java b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsFunction.java index f21920e..6323f8f 100644 --- a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsFunction.java +++ b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsFunction.java @@ -2,37 +2,87 @@ import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionExecutor; import org.graalvm.polyglot.Value; import org.graalvm.polyglot.proxy.ProxyExecutable; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; public class JsFunction implements ProxyExecutable { private final Script script; - private final ScriptFunction function; + private final ScriptFunctionDefinition definition; - public JsFunction(Script script, ScriptFunction function) { + public JsFunction(Script script, ScriptFunctionDefinition definition) { this.script = script; - this.function = function; + this.definition = definition; } @Override public Object execute(Value... arguments) { - ScriptFunctionArgument[] args = new ScriptFunctionArgument[arguments.length]; + Object[] args = new Object[arguments.length]; for (int i = 0; i < arguments.length; i++) { - args[i] = ScriptFunctionArgument.of(convertValue(arguments[i])); + args[i] = convertValue(arguments[i]); } + try { - return function.invoke(script, args); + ScriptFunctionExecutor executor = findMatchingExecutor(args); + return executor.execute(script, adaptArgsForExecutor(executor, args)); } catch (ScriptFunctionException e) { throw new RuntimeException(e); } } + private ScriptFunctionExecutor findMatchingExecutor(Object[] args) { + for (ScriptFunctionExecutor executor : definition.getExecutors()) { + int paramCount = executor.getArguments().size(); + if (executor.getMethod().isVarArgs()) { + if (args.length >= paramCount - 1) { + return executor; + } + } else { + if (args.length == paramCount) { + return executor; + } + } + } + throw new IllegalArgumentException("No matching executor found for arguments"); + } + + private Object[] adaptArgsForExecutor(ScriptFunctionExecutor executor, Object[] args) { + var method = executor.getMethod(); + var paramTypes = method.getParameterTypes(); + + if (paramTypes.length == 0) { + return new Object[0]; + } + + if (!method.isVarArgs()) { + return args; + } + + var fixedCount = paramTypes.length - 1; + var finalArgs = new Object[paramTypes.length]; + + for (int i = 0; i < fixedCount; i++) { + finalArgs[i] = i < args.length ? args[i] : null; + } + + var varargType = paramTypes[fixedCount].getComponentType(); + var varargCount = Math.max(0, args.length - fixedCount); + var varargArray = Array.newInstance(varargType, varargCount); + + for (int i = 0; i < varargCount; i++) { + Array.set(varargArray, i, args[fixedCount + i]); + } + + finalArgs[fixedCount] = varargArray; + return finalArgs; + } + /** * Converts the Value object to the appropriate Java type. */ diff --git a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java index a63beb6..0b18261 100644 --- a/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java +++ b/script-js-graalvm/src/main/java/com/instancify/scriptify/script/JsScript.java @@ -5,10 +5,12 @@ import com.instancify.scriptify.api.script.ScriptObject; import com.instancify.scriptify.api.script.constant.ScriptConstant; import com.instancify.scriptify.api.script.constant.ScriptConstantManager; -import com.instancify.scriptify.api.script.function.ScriptFunction; import com.instancify.scriptify.api.script.function.ScriptFunctionManager; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; import com.instancify.scriptify.api.script.security.ScriptSecurityManager; -import com.instancify.scriptify.security.StandardSecurityManager; +import com.instancify.scriptify.core.script.constant.StandardConstantManager; +import com.instancify.scriptify.core.script.function.StandardFunctionManager; +import com.instancify.scriptify.core.script.security.StandardSecurityManager; import org.graalvm.polyglot.Context; import org.graalvm.polyglot.HostAccess; import org.graalvm.polyglot.Value; @@ -16,8 +18,8 @@ public class JsScript implements Script { private final ScriptSecurityManager securityManager = new StandardSecurityManager(); - private ScriptFunctionManager functionManager; - private ScriptConstantManager constantManager; + private ScriptFunctionManager functionManager = new StandardFunctionManager(); + private ScriptConstantManager constantManager = new StandardConstantManager(); @Override public ScriptSecurityManager getSecurityManager() { @@ -71,8 +73,8 @@ public Value eval(String script) throws ScriptException { Value bindings = context.getBindings("js"); if (functionManager != null) { - for (ScriptFunction function : functionManager.getFunctions().values()) { - bindings.putMember(function.getName(), new JsFunction(this, function)); + for (ScriptFunctionDefinition definition : functionManager.getFunctions().values()) { + bindings.putMember(definition.getFunction().getName(), new JsFunction(this, definition)); } } diff --git a/script-js-rhino/build.gradle.kts b/script-js-rhino/build.gradle.kts index 3a03bcf..0e1519b 100644 --- a/script-js-rhino/build.gradle.kts +++ b/script-js-rhino/build.gradle.kts @@ -7,6 +7,6 @@ repositories { } dependencies { - api(project(":security")) + api(project(":core")) api("org.mozilla:rhino:1.8.0") } \ No newline at end of file diff --git a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsFunction.java b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsFunction.java index 2fc0c75..d1b1628 100644 --- a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsFunction.java +++ b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsFunction.java @@ -1,35 +1,87 @@ package com.instancify.scriptify.script; +import com.instancify.scriptify.api.exception.ScriptFunctionException; import com.instancify.scriptify.api.script.Script; -import com.instancify.scriptify.api.script.function.ScriptFunction; -import com.instancify.scriptify.api.script.function.argument.ScriptFunctionArgument; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionExecutor; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.Scriptable; +import java.lang.reflect.Array; +import java.util.Arrays; + public class JsFunction implements Function { - private final Script script; - private final ScriptFunction function; + private final Script script; + private final ScriptFunctionDefinition definition; - public JsFunction(Script script, ScriptFunction function) { + public JsFunction(Script script, ScriptFunctionDefinition definition) { this.script = script; - this.function = function; + this.definition = definition; } @Override public Object call(Context context, Scriptable scriptable, Scriptable scriptable1, Object[] arguments) { - ScriptFunctionArgument[] args = new ScriptFunctionArgument[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - args[i] = ScriptFunctionArgument.of(arguments[i]); - } + Class[] types = Arrays.stream(arguments) + .map(arg -> arg == null ? Object.class : arg.getClass()) + .toArray(Class[]::new); + try { - return function.invoke(script, args); - } catch (Exception e) { + ScriptFunctionExecutor executor = findMatchingExecutor(arguments); + return executor.execute(script, adaptArgsForExecutor(executor, arguments)); + } catch (ScriptFunctionException e) { throw Context.throwAsScriptRuntimeEx(e); } } + private ScriptFunctionExecutor findMatchingExecutor(Object[] args) { + for (ScriptFunctionExecutor executor : definition.getExecutors()) { + int paramCount = executor.getArguments().size(); + if (executor.getMethod().isVarArgs()) { + if (args.length >= paramCount - 1) { + return executor; + } + } else { + if (args.length == paramCount) { + return executor; + } + } + } + throw new IllegalArgumentException("No matching executor found for arguments"); + } + + private Object[] adaptArgsForExecutor(ScriptFunctionExecutor executor, Object[] args) { + var method = executor.getMethod(); + var paramTypes = method.getParameterTypes(); + + if (paramTypes.length == 0) { + return new Object[0]; + } + + if (!method.isVarArgs()) { + return args; + } + + var fixedCount = paramTypes.length - 1; + var finalArgs = new Object[paramTypes.length]; + + for (int i = 0; i < fixedCount; i++) { + finalArgs[i] = i < args.length ? args[i] : null; + } + + var varargType = paramTypes[fixedCount].getComponentType(); + var varargCount = Math.max(0, args.length - fixedCount); + var varargArray = Array.newInstance(varargType, varargCount); + + for (int i = 0; i < varargCount; i++) { + Array.set(varargArray, i, args[fixedCount + i]); + } + + finalArgs[fixedCount] = varargArray; + return finalArgs; + } + @Override public Scriptable construct(Context context, Scriptable scriptable, Object[] objects) { return null; diff --git a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java index a9943ea..bda70dd 100644 --- a/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java +++ b/script-js-rhino/src/main/java/com/instancify/scriptify/script/JsScript.java @@ -4,10 +4,12 @@ import com.instancify.scriptify.api.script.Script; import com.instancify.scriptify.api.script.constant.ScriptConstant; import com.instancify.scriptify.api.script.constant.ScriptConstantManager; -import com.instancify.scriptify.api.script.function.ScriptFunction; import com.instancify.scriptify.api.script.function.ScriptFunctionManager; +import com.instancify.scriptify.api.script.function.definition.ScriptFunctionDefinition; import com.instancify.scriptify.api.script.security.ScriptSecurityManager; -import com.instancify.scriptify.security.StandardSecurityManager; +import com.instancify.scriptify.core.script.constant.StandardConstantManager; +import com.instancify.scriptify.core.script.function.StandardFunctionManager; +import com.instancify.scriptify.core.script.security.StandardSecurityManager; import org.mozilla.javascript.Context; import org.mozilla.javascript.ScriptableObject; @@ -15,8 +17,8 @@ public class JsScript implements Script { private final Context context = Context.enter(); private final ScriptSecurityManager securityManager = new StandardSecurityManager(); - private ScriptFunctionManager functionManager; - private ScriptConstantManager constantManager; + private ScriptFunctionManager functionManager = new StandardFunctionManager(); + private ScriptConstantManager constantManager = new StandardConstantManager(); public JsScript() { context.setWrapFactory(new JsWrapFactory()); @@ -58,8 +60,8 @@ public Object eval(String script) throws ScriptException { } if (functionManager != null) { - for (ScriptFunction function : functionManager.getFunctions().values()) { - scope.put(function.getName(), scope, new JsFunction(this, function)); + for (ScriptFunctionDefinition definition : functionManager.getFunctions().values()) { + scope.put(definition.getFunction().getName(), scope, new JsFunction(this, definition)); } } diff --git a/settings.gradle.kts b/settings.gradle.kts index df8de18..11e590a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,7 @@ rootProject.name = "instancify-Scriptify" include("api") include("core") -include("security") +include("common") include("script-js-graalvm") include("script-js-rhino") include("http")