diff --git a/build.gradle b/build.gradle index 02bb697..ffc57af 100644 --- a/build.gradle +++ b/build.gradle @@ -66,6 +66,12 @@ compileJava { options.debug() } +compileTestJava { + source sourceSets.test.java + dependsOn compileJava, serviceLoaderBuild + options.encoding = 'UTF-8' +} + jar { archiveVersion = "${version}" manifest { @@ -82,7 +88,7 @@ jar { } shadowJar { destinationDirectory = file( "build/distributions" ) - //mergeServiceFiles() + mergeServiceFiles() exclude "schema/**" exclude "org/antlr/v4/gui/**" exclude "org/antlr/v4/gui/**" @@ -110,13 +116,13 @@ build.finalizedBy( renameDistributionFile ) * - https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader * This generates the META-INF/services files for the ServiceLoader as part of the `build` task */ -// serviceLoader { -// serviceInterface 'ortus.boxlang.runtime.bifs.BIF' -// serviceInterface 'ortus.boxlang.runtime.components.Component' -// serviceInterface 'ortus.boxlang.runtime.async.tasks.IScheduler' -// serviceInterface 'ortus.boxlang.runtime.cache.providers.ICacheProvider' -// serviceInterface 'ortus.boxlang.runtime.events.IInterceptor' -// } +serviceLoader { + serviceInterface 'ortus.boxlang.runtime.bifs.BIF' + serviceInterface 'ortus.boxlang.runtime.components.Component' + serviceInterface 'ortus.boxlang.runtime.async.tasks.IScheduler' + serviceInterface 'ortus.boxlang.runtime.cache.providers.ICacheProvider' + serviceInterface 'ortus.boxlang.runtime.events.IInterceptor' +} /** * Token Replacements for files diff --git a/src/main/java/ortus/boxlang/web/WebErrorHandler.java b/src/main/java/ortus/boxlang/web/WebErrorHandler.java index e2d586c..1ad1595 100644 --- a/src/main/java/ortus/boxlang/web/WebErrorHandler.java +++ b/src/main/java/ortus/boxlang/web/WebErrorHandler.java @@ -34,6 +34,7 @@ import ortus.boxlang.runtime.types.exceptions.LockException; import ortus.boxlang.runtime.types.exceptions.MissingIncludeException; import ortus.boxlang.runtime.util.FRTransService; +import ortus.boxlang.web.context.WebRequestBoxContext; /** * I handle default errors for a web request diff --git a/src/main/java/ortus/boxlang/web/WebRequestExecutor.java b/src/main/java/ortus/boxlang/web/WebRequestExecutor.java index b23c6d4..cf6b3c2 100644 --- a/src/main/java/ortus/boxlang/web/WebRequestExecutor.java +++ b/src/main/java/ortus/boxlang/web/WebRequestExecutor.java @@ -29,6 +29,7 @@ import ortus.boxlang.runtime.types.exceptions.AbortException; import ortus.boxlang.runtime.types.exceptions.MissingIncludeException; import ortus.boxlang.runtime.util.FRTransService; +import ortus.boxlang.web.context.WebRequestBoxContext; /** * I handle running a web request diff --git a/src/main/java/ortus/boxlang/web/bifs/Forward.java b/src/main/java/ortus/boxlang/web/bifs/Forward.java new file mode 100644 index 0000000..7b53c07 --- /dev/null +++ b/src/main/java/ortus/boxlang/web/bifs/Forward.java @@ -0,0 +1,63 @@ +/** + * [BoxLang] + * + * Copyright [2024] [Ortus Solutions, Corp] + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" + * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +package ortus.boxlang.web.bifs; + +import io.undertow.server.HttpServerExchange; +import ortus.boxlang.runtime.bifs.BIF; +import ortus.boxlang.runtime.bifs.BoxBIF; +import ortus.boxlang.runtime.context.IBoxContext; +import ortus.boxlang.runtime.scopes.ArgumentsScope; +import ortus.boxlang.runtime.scopes.Key; +import ortus.boxlang.runtime.types.Argument; +import ortus.boxlang.web.context.WebRequestBoxContext; + +@BoxBIF +public class Forward extends BIF { + + /** + * Constructor + */ + public Forward() { + super(); + declaredArguments = new Argument[] { + new Argument( true, Argument.STRING, Key.template ) + }; + } + + /** + * + * Leads the request to a different page. + * This function acts like the location functionality except that the relocation is done directly on the server and not the browser + * + * @param context The context in which the BIF is being invoked. + * @param arguments Argument scope for the BIF. + * + * @argument.template The logical path to which the request should be forwarded to. + * + */ + @SuppressWarnings( "deprecation" ) + public Object _invoke( IBoxContext context, ArgumentsScope arguments ) { + String templatePath = arguments.getAsString( Key.template ); + WebRequestBoxContext requestContext = context.getParentOfType( WebRequestBoxContext.class ); + HttpServerExchange exchange = requestContext.getExchange(); + + exchange.setRequestPath( templatePath ); + exchange.setRelativePath( templatePath ); + exchange.dispatch(); + + return null; + } + +} diff --git a/src/main/java/ortus/boxlang/web/WebRequestBoxContext.java b/src/main/java/ortus/boxlang/web/context/WebRequestBoxContext.java similarity index 99% rename from src/main/java/ortus/boxlang/web/WebRequestBoxContext.java rename to src/main/java/ortus/boxlang/web/context/WebRequestBoxContext.java index 08dbdac..a41659a 100644 --- a/src/main/java/ortus/boxlang/web/WebRequestBoxContext.java +++ b/src/main/java/ortus/boxlang/web/context/WebRequestBoxContext.java @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package ortus.boxlang.web; +package ortus.boxlang.web.context; import java.io.IOException; import java.net.URI; diff --git a/src/test/java/ortus/boxlang/web/bifs/ForwardTest.java b/src/test/java/ortus/boxlang/web/bifs/ForwardTest.java new file mode 100644 index 0000000..a4e4718 --- /dev/null +++ b/src/test/java/ortus/boxlang/web/bifs/ForwardTest.java @@ -0,0 +1,70 @@ +package ortus.boxlang.web.bifs; + +import static org.junit.Assert.assertThrows; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import ortus.boxlang.runtime.BoxRuntime; +import ortus.boxlang.runtime.context.IBoxContext; +import ortus.boxlang.runtime.context.ScriptingRequestBoxContext; +import ortus.boxlang.runtime.scopes.IScope; +import ortus.boxlang.runtime.scopes.Key; +import ortus.boxlang.runtime.scopes.VariablesScope; +import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException; + +public class ForwardTest { + + static BoxRuntime runtime; + IBoxContext context; + IScope variables; + static Key result = new Key( "result" ); + + @BeforeAll + public static void setUp() { + runtime = BoxRuntime.getInstance( true ); + } + + @AfterAll + public static void teardown() { + } + + @BeforeEach + public void setupEach() { + // TODO: Brad you need to simulate the web request context here please. + context = new ScriptingRequestBoxContext( runtime.getRuntimeContext() ); + variables = context.getScopeNearby( VariablesScope.name ); + } + + @Test + @DisplayName( "It should fail if the template argument is not provided" ) + public void testNoTemplate() { + // @formatter:off + assertThrows( BoxRuntimeException.class, () -> { + runtime.executeSource( + """ + forward(); + """, + context ); + } ); + // @formatter:on + } + + @Test + @Disabled( "Until Brad figures out how to do web request context tests" ) + @DisplayName( "Forward to a different page" ) + public void testForward() { + // @formatter:off + runtime.executeSource( + """ + forward( template: "/some/path" ); + """, + context ); + // @formatter:on + } + +}