Skip to content

Commit

Permalink
Merge pull request #88 from ortus-boxlang/development
Browse files Browse the repository at this point in the history
v1.0.0-Beta7
  • Loading branch information
lmajano authored Jul 26, 2024
2 parents 5825670 + 4610178 commit ae314c6
Show file tree
Hide file tree
Showing 54 changed files with 1,669 additions and 167 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ on:
workflow_dispatch:
inputs:
lts:
description: 'The LTS marker'
description: "The LTS marker"
required: false
default: true
default: false
type: boolean

env:
Expand Down Expand Up @@ -166,7 +166,6 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
ref: refs/tags/v${{ env.VERSION }}


- name: Inform Slack
if: ${{ always() }}
uses: rtCamp/action-slack-notify@v2
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches:
- development

# Manual Trigger for Snapshot builds
workflow_dispatch:

#Cancel running builds if another push to branch is made while this build is running
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ dependencies {
testImplementation "com.google.truth:truth:1.+"
testImplementation "commons-cli:commons-cli:1.8.0"
// https://wiremock.org/
testImplementation "org.wiremock:wiremock:3.8.0"
testImplementation "org.wiremock:wiremock:3.9.0"
// https://mvnrepository.com/artifact/org.apache.derby/derby
testImplementation 'org.apache.derby:derby:10.17.1.0'
testImplementation 'io.undertow:undertow-core:2.3.14.Final'
testImplementation 'io.undertow:undertow-core:2.3.15.Final'

// Antlr
antlr "org.antlr:antlr4:$antlrVersion"
Expand All @@ -107,7 +107,7 @@ dependencies {
// https://mvnrepository.com/artifact/com.github.javaparser/javaparser-symbol-solver-core
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.1'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation 'org.apache.commons:commons-lang3:3.14.0'
implementation 'org.apache.commons:commons-lang3:3.15.0'
// https://mvnrepository.com/artifact/org.apache.commons/commons-text
// Many of these classes ( e.g. StringEscapeUtils ) are currently deprecated in commons-lang and others will be moved in the future
implementation 'org.apache.commons:commons-text:1.12.0'
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Fri Jul 12 11:06:57 UTC 2024
#Fri Jul 19 14:27:23 UTC 2024
antlrVersion=4.13.1
jdkVersion=21
version=1.0.0-beta6
version=1.0.0-beta7
1 change: 1 addition & 0 deletions gradle/boxlang-miniserver
Submodule boxlang-miniserver added at e5a0d8
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ private void validateParse( BoxScriptLexerCustom lexer ) {
}

// Check if there are unconsumed tokens
Token token = lexer.nextToken();
Token token = lexer._token;
while ( token.getType() != Token.EOF && ( token.getChannel() == BoxScriptLexerCustom.HIDDEN ) ) {
token = lexer.nextToken();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ private void validateParse( BoxTemplateLexerCustom lexer ) {
// the ability to check for unconsumed tokens.

// Check if there are unconsumed tokens
token = lexer.nextToken();
token = lexer._token;
while ( token.getType() != Token.EOF && ( token.getChannel() == BoxTemplateLexerCustom.HIDDEN || token.getText().isBlank() ) ) {
token = lexer.nextToken();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ private void validateParse( CFScriptLexerCustom lexer ) {
}

// Check if there are unconsumed tokens
Token token = lexer.nextToken();
Token token = lexer._token;
while ( token.getType() != Token.EOF && ( token.getChannel() == CFScriptLexerCustom.HIDDEN ) ) {
token = lexer.nextToken();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private void validateParse( CFTemplateLexerCustom lexer ) {
// the ability to check for unconsumed tokens.

// Check if there are unconsumed tokens
token = lexer.nextToken();
token = lexer._token;
while ( token.getType() != Token.EOF && ( token.getChannel() == CFTemplateLexerCustom.HIDDEN || token.getText().isBlank() ) ) {
token = lexer.nextToken();
}
Expand Down
12 changes: 8 additions & 4 deletions src/main/java/ortus/boxlang/runtime/BoxRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ private void startup() {
* @return A BoxRuntime instance
*
*/
public static synchronized BoxRuntime getInstance( Boolean debugMode ) {
public static BoxRuntime getInstance( Boolean debugMode ) {
return getInstance( debugMode, null );
}

Expand All @@ -499,7 +499,7 @@ public static synchronized BoxRuntime getInstance( Boolean debugMode ) {
* @return A BoxRuntime instance
*
*/
public static synchronized BoxRuntime getInstance( Boolean debugMode, String configPath ) {
public static BoxRuntime getInstance( Boolean debugMode, String configPath ) {
return getInstance( debugMode, configPath, DEFAULT_RUNTIME_HOME.toString() );
}

Expand All @@ -515,9 +515,13 @@ public static synchronized BoxRuntime getInstance( Boolean debugMode, String con
* @return A BoxRuntime instance
*
*/
public static synchronized BoxRuntime getInstance( Boolean debugMode, String configPath, String runtimeHome ) {
public static BoxRuntime getInstance( Boolean debugMode, String configPath, String runtimeHome ) {
if ( instance == null ) {
instance = new BoxRuntime( debugMode, configPath, runtimeHome );
synchronized ( BoxRuntime.class ) {
if ( instance == null ) {
instance = new BoxRuntime( debugMode, configPath, runtimeHome );
}
}
// We split in order to avoid circular dependencies on the runtime
instance.startup();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public abstract class BaseApplicationListener {
protected BaseApplicationListener( RequestBoxContext context ) {
this.context = context;
context.setApplicationListener( this );
this.interceptorPool = new InterceptorPool( Key.appListener )
this.interceptorPool = new InterceptorPool( Key.appListener, BoxRuntime.getInstance() )
.registerInterceptionPoint( REQUEST_INTERCEPTION_POINTS );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public MemberDescriptor(
* @return The result of the invocation
*/
public Object invoke( IBoxContext context, Object object ) {
// TODO: add arg to skip validation for incoming object which has already been vetted
return BIFDescriptor.invoke( context, new Object[] { object }, true, name );
}

Expand Down Expand Up @@ -123,6 +124,7 @@ public Object invoke( IBoxContext context, Object object, Object[] positionalArg
// System.out.println( args[ i ] );
// }

// TODO: add arg to skip validation for incoming object which has already been vetted
return BIFDescriptor.invoke( context, args, true, name );
}
}
Expand All @@ -147,6 +149,7 @@ public Object invoke( IBoxContext context, Object object, Map<Key, Object> named
}
namedArguments.put( args[ 0 ].name(), object );
}
// TODO: add arg to skip validation for incoming object which has already been vetted
return BIFDescriptor.invoke( context, namedArguments, true, name );
}

Expand Down
116 changes: 116 additions & 0 deletions src/main/java/ortus/boxlang/runtime/bifs/global/async/ThreadNew.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* [BoxLang]
*
* Copyright [2023] [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.runtime.bifs.global.async;

import java.util.Set;

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

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.context.RequestBoxContext;
import ortus.boxlang.runtime.context.ThreadBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.Function;
import ortus.boxlang.runtime.types.IStruct;
import ortus.boxlang.runtime.types.Struct;
import ortus.boxlang.runtime.types.exceptions.AbortException;
import ortus.boxlang.runtime.util.RequestThreadManager;
import ortus.boxlang.runtime.validation.Validator;

@BoxBIF
public class ThreadNew extends BIF {

/**
* Constructor
*/
public ThreadNew() {
super();
declaredArguments = new Argument[] {
new Argument( true, Argument.FUNCTION, Key.runnable ),
new Argument( false, Argument.STRUCT, Key.attributes, new Struct() ),
new Argument( false, Argument.STRING, Key._NAME, "" ),
new Argument( false, Argument.STRING, Key.priority, "normal", Set.of( Validator.valueOneOf( "high", "low", "normal" ) ) )
};
}

/**
* Creates a new thread of execution based on the passed closure/lambda.
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @arguments.runnable The closure/lambda to execute in the new thread.
*
* @arguments.attributes A struct of data to bind into the thread's scope.
*
* @argument.threadName The name of the thread to track it, if not provided a default name will be generated.
*
* @argument.priority The priority of the thread. Possible values are "high", "low", and "normal". Default is "normal".
*
* @return The newly created thread object if you want to monitor it.
*/
@Override
public Thread _invoke( IBoxContext context, ArgumentsScope arguments ) {
Function task = arguments.getAsFunction( Key.runnable );
String name = arguments.getAsString( Key._NAME );
String priority = arguments.getAsString( Key.priority );
IStruct attributes = arguments.getAsStruct( Key.attributes );
RequestThreadManager threadManager = context.getParentOfType( RequestBoxContext.class ).getThreadManager();
final Key nameKey = RequestThreadManager.ensureThreadName( name );
ThreadBoxContext tContext = threadManager.createThreadContext( context, nameKey );

// Startup the thread
return threadManager.startThread(
// The thread context to run in
tContext,
// The name of the thread as a key
nameKey,
// The thread priority
priority,
// The Runnable Proxy
() -> {
StringBuffer buffer = new StringBuffer();
Throwable exception = null;
Logger logger = LoggerFactory.getLogger( ThreadNew.class );
try {
// Execute the function using the thread context
tContext.invokeFunction( task );
} catch ( AbortException e ) {
// We log it so we can potentially find out why it was aborted
logger.debug( "Thread [{}] aborted at stacktrace: {}", nameKey.getName(), e.getStackTrace() );
} catch ( Throwable e ) {
exception = e;
logger.error( "Thread [{}] terminated with exception: {}", nameKey.getName(), e.getMessage() );
logger.error( "-> Exception", e );
} finally {
threadManager.completeThread(
nameKey,
buffer.toString(),
exception,
java.lang.Thread.interrupted()
);
}
},
// The Struct of data to bind into the thread's scope
attributes
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@
import ortus.boxlang.runtime.types.util.ListUtil;

@BoxBIF
@BoxMember( type = BoxLangType.CUSTOM, customType = java.lang.Boolean.class, name = "toJSON" )
@BoxMember( type = BoxLangType.CUSTOM2, customType = java.lang.Number.class, name = "toJSON" )
@BoxMember( type = BoxLangType.ARRAY, name = "toJSON" )
@BoxMember( type = BoxLangType.CLASS, name = "toJSON" )
@BoxMember( type = BoxLangType.LIST, name = "toJSON" )
@BoxMember( type = BoxLangType.QUERY, name = "toJSON" )
@BoxMember( type = BoxLangType.STRING, name = "toJSON" )
@BoxMember( type = BoxLangType.STRUCT, name = "toJSON" )
@BoxMember( type = BoxLangType.STRING, name = "listToJSON" )
@BoxMember( type = BoxLangType.STRING, name = "toJSON" )
public class JSONSerialize extends BIF {

/**
Expand All @@ -55,7 +56,8 @@ public JSONSerialize() {
new Argument( true, "any", Key.var ),
// NOT A BOOLEAN! Can be true, false, row, column, or struct
new Argument( false, "string", Key.queryFormat, "row" ),
new Argument( false, "boolean", Key.useSecureJSONPrefix, false ),
// Don't set this to a boolean, Lucee accepts a charset here which ColdBox passes
new Argument( false, "string", Key.useSecureJSONPrefix, false ),
new Argument( false, "boolean", Key.useCustomSerializer )
};
}
Expand All @@ -75,6 +77,8 @@ public JSONSerialize() {
* @argument.useCustomSerializer If true, the JSON string is serialized using a custom serializer. (Not used)
*/
public Object _invoke( IBoxContext context, ArgumentsScope arguments ) {
// TODO useSecureJSONPrefix - Don't assume this is a boolean, Lucee accepts a charset here which ColdBox passes

Object obj = arguments.get( Key.var );
String queryFormat = arguments.getAsString( Key.queryFormat ).toLowerCase();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* [BoxLang]
*
* Copyright [2023] [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.runtime.bifs.global.stream;

import java.util.stream.Stream;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxMember;
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.runtime.types.BoxLangType;
import ortus.boxlang.runtime.types.util.BLCollector;

@BoxMember( type = BoxLangType.STREAM )
public class ToBXArray extends BIF {

/**
* Constructor
*/
public ToBXArray() {
super();
declaredArguments = new Argument[] {
new Argument( true, "stream", Key.stream )
};
}

/**
* Collect a Java stream into a BoxLang Array
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.stream The stream to collect.
*/
public Object _invoke( IBoxContext context, ArgumentsScope arguments ) {
Stream<?> stream = arguments.getAsStream( Key.stream );
return stream.collect( BLCollector.toArray() );
}

}
Loading

0 comments on commit ae314c6

Please sign in to comment.