From cc0b268cf0caf3c63927542404ae14b2dc0059b3 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Wed, 28 May 2025 23:32:46 -0600 Subject: [PATCH 1/9] WIP: All tests passing that don't use ORM or objectSave --- server-boxlang@1.json | 2 +- system/core/events/EventPoolManager.cfc | 2 + system/core/util/Util.cfc | 5 +- system/ioc/Builder.cfc | 6 +- system/ioc/config/Mapping.cfc | 214 ++++++++++++------ .../modules/HTMLHelper/models/HTMLHelper.cfc | 23 +- system/testing/BaseInterceptorTest.cfc | 20 +- system/testing/BaseModelTest.cfc | 10 +- system/testing/BaseTestCase.cfc | 2 +- system/web/services/InterceptorService.cfc | 2 + 10 files changed, 202 insertions(+), 84 deletions(-) diff --git a/server-boxlang@1.json b/server-boxlang@1.json index d1fac1cb7..207220816 100644 --- a/server-boxlang@1.json +++ b/server-boxlang@1.json @@ -29,6 +29,6 @@ "BOXLANG_DEBUG":true }, "scripts":{ - "onServerInitialInstall":"install bx-mail,bx-pdf,bx-mysql,bx-esapi,bx-orm@be --noSave" + "onServerInitialInstall":"install bx-mail,bx-pdf,bx-mysql,bx-esapi,testbox@be --noSave" } } diff --git a/system/core/events/EventPoolManager.cfc b/system/core/events/EventPoolManager.cfc index 1e53f2efd..ea9e77cd7 100644 --- a/system/core/events/EventPoolManager.cfc +++ b/system/core/events/EventPoolManager.cfc @@ -230,6 +230,8 @@ component accessors="true" { if ( structKeyExists( arguments.metadata, "extends" ) AND + !structIsEmpty( arguments.metadata.extends ) + AND NOT listFindNoCase( getStopRecursionClasses(), arguments.metadata.extends.name ) ) { parseMetadata( arguments.metadata.extends, arguments.eventsFound ); diff --git a/system/core/util/Util.cfc b/system/core/util/Util.cfc index aa5c7e110..e9481f315 100644 --- a/system/core/util/Util.cfc +++ b/system/core/util/Util.cfc @@ -416,13 +416,16 @@ component { if ( isObject( arguments.component ) ) { arguments.md = getMetadata( arguments.component ); } else { - arguments.md = getComponentMetadata( arguments.component ); + arguments.md = server.keyExists( "boxlang" ) ? getClassMetadata( arguments.component ) : getComponentMetadata( + arguments.component + ); } } // If it has a parent, stop and calculate it first, unless of course, we've reached a class we shouldn't recurse into. if ( structKeyExists( arguments.md, "extends" ) && + !structIsEmpty( arguments.md.extends ) && arguments.md.type eq "component" && stopClassRecursion( md.extends.name, arguments.stopRecursions ) EQ FALSE ) { diff --git a/system/ioc/Builder.cfc b/system/ioc/Builder.cfc index b18616b12..c29aa2670 100644 --- a/system/ioc/Builder.cfc +++ b/system/ioc/Builder.cfc @@ -1036,9 +1036,9 @@ component serializable="false" accessors="true" { var baseObject = variables.injector.buildInstance( arguments.mapping ); variables.mixerUtil.start( baseObject ); variables.injector.autowire( - target = baseObject, - mapping = arguments.mapping, - targetID: arguments.mapping.getName() + target = baseObject, + mapping = arguments.mapping, + targetID = arguments.mapping.getName() ); // Mix them up baby! diff --git a/system/ioc/config/Mapping.cfc b/system/ioc/config/Mapping.cfc index aa6f80431..c873357c0 100644 --- a/system/ioc/config/Mapping.cfc +++ b/system/ioc/config/Mapping.cfc @@ -622,17 +622,20 @@ component accessors="true" { // Process persistence if not set already by configuration as it takes precedence if ( !len( variables.scope ) ) { // Singleton Processing - if ( structKeyExists( md, "singleton" ) ) { + if ( hasAnnotationValue( md, "singleton" ) ) { variables.scope = arguments.binder.SCOPES.SINGLETON; } // Registered Scope Processing - if ( structKeyExists( md, "scope" ) ) { - variables.scope = md.scope; + if ( hasAnnotationValue( md, "scope" ) ) { + variables.scope = getAnnotationValue( md, "scope" ); } // CacheBox scope processing if cachebox annotation found, or cache annotation found if ( - structKeyExists( md, "cacheBox" ) OR ( - structKeyExists( md, "cache" ) AND isBoolean( md.cache ) AND md.cache + hasAnnotationValue( md, "cacheBox" ) OR ( + hasAnnotationValue( md, "cache" ) AND isBoolean( getAnnotationValue( md, "cache", "" ) ) AND getAnnotationValue( + md, + "cache" + ) ) ) { variables.scope = arguments.binder.SCOPES.CACHEBOX; @@ -655,29 +658,37 @@ component accessors="true" { // default it first variables.cache.provider = "default"; // Now check the annotations for the provider - if ( structKeyExists( md, "cacheBox" ) AND len( md.cacheBox ) ) { - variables.cache.provider = md.cacheBox; + if ( hasAnnotationValue( md, "cacheBox" ) AND len( getAnnotationValue( md, "cacheBox", "" ) ) ) { + variables.cache.provider = getAnnotationValue( md, "cacheBox" ); } } // Check if timeouts set by configuration or discovery if ( !len( variables.cache.timeout ) ) { // Discovery by annocations - if ( structKeyExists( md, "cachetimeout" ) AND isNumeric( md.cacheTimeout ) ) { - variables.cache.timeout = md.cacheTimeout; + if ( + hasAnnotationValue( md, "cachetimeout" ) AND isNumeric( + getAnnotationValue( md, "cacheTimeout", "" ) + ) + ) { + variables.cache.timeout = getAnnotationValue( md, "cacheTimeout" ); } } // Check if lastAccessTimeout set by configuration or discovery if ( !len( variables.cache.lastAccessTimeout ) ) { // Discovery by annocations - if ( structKeyExists( md, "cacheLastAccessTimeout" ) AND isNumeric( md.cacheLastAccessTimeout ) ) { - variables.cache.lastAccessTimeout = md.cacheLastAccessTimeout; + if ( + hasAnnotationValue( md, "cacheLastAccessTimeout" ) AND isNumeric( + getAnnotationValue( md, "cacheLastAccessTimeout", "" ) + ) + ) { + variables.cache.lastAccessTimeout = getAnnotationValue( md, "cacheLastAccessTimeout" ); } } } // Alias annotations if found, then append them as aliases. - if ( structKeyExists( md, "alias" ) ) { - var thisAliases = listToArray( md.alias ); + if ( hasAnnotationValue( md, "alias" ) ) { + var thisAliases = listToArray( getAnnotationValue( md, "alias", "" ) ); variables.alias.addAll( thisAliases ); // register alias references on binder var mappings = arguments.binder.getMappings(); @@ -688,7 +699,7 @@ component accessors="true" { // eagerInit annotation only if not overridden if ( !len( variables.eagerInit ) ) { - if ( structKeyExists( md, "eagerInit" ) ) { + if ( hasAnnotationValue( md, "eagerInit" ) ) { variables.eagerInit = true; } else { // defaults to lazy loading @@ -698,10 +709,18 @@ component accessors="true" { // threadSafe wiring annotation if ( !len( variables.threadSafe ) ) { - if ( structKeyExists( md, "threadSafe" ) AND NOT len( md.threadSafe ) ) { + if ( + hasAnnotationValue( md, "threadSafe" ) AND NOT len( + getAnnotationValue( md, "threadSafe", "" ) + ) + ) { variables.threadSafe = true; - } else if ( structKeyExists( md, "threadSafe" ) AND len( md.threadSafe ) AND isBoolean( md.threadSafe ) ) { - variables.threadSafe = md.threadSafe; + } else if ( + hasAnnotationValue( md, "threadSafe" ) AND len( getAnnotationValue( md, "threadSafe", "" ) ) AND isBoolean( + getAnnotationValue( md, "threadSafe", "" ) + ) + ) { + variables.threadSafe = getAnnotationValue( md, "threadSafe" ); } else { // defaults to non thread safe wiring variables.threadSafe = false; @@ -710,14 +729,14 @@ component accessors="true" { // mixins annotation only if not overridden if ( NOT arrayLen( variables.mixins ) ) { - if ( structKeyExists( md, "mixins" ) ) { - variables.mixins = listToArray( md.mixins ); + if ( hasAnnotationValue( md, "mixins" ) ) { + variables.mixins = listToArray( getAnnotationValue( md, "mixins", "" ) ); } } // Delegates by Metadata and by Explicit Definition - if ( md.keyExists( "delegates" ) && len( md.delegates.trim() ) ) { - processComponentDelegates( md.delegates.trim() ); + if ( hasAnnotationValue( md, "delegates" ) && len( getAnnotationValue( md, "delegates" ).trim() ) ) { + processComponentDelegates( getAnnotationValue( md, "delegates" ).trim() ); } if ( hasDelegates() ) { processComponentDelegates( variables.delegates ); @@ -726,8 +745,8 @@ component accessors="true" { // autowire only if not overridden if ( !len( variables.autowire ) ) { // Check if autowire annotation found or autowire already set - if ( structKeyExists( md, "autowire" ) and isBoolean( md.autowire ) ) { - variables.autoWire = md.autowire; + if ( hasAnnotationValue( md, "autowire" ) and isBoolean( getAnnotationValue( md, "autowire", "" ) ) ) { + variables.autoWire = getAnnotationValue( md, "autowire" ); } else { // default to true variables.autoWire = true; @@ -736,8 +755,8 @@ component accessors="true" { // look for parent metadata referring to an abstract parent (by alias) to copy // dependencies and definitions from - if ( structKeyExists( md, "parent" ) and len( trim( md.parent ) ) ) { - arguments.binder.parent( alias: md.parent ); + if ( hasAnnotationValue( md, "parent" ) and len( trim( getAnnotationValue( md, "parent" ) ) ) ) { + arguments.binder.parent( alias: getAnnotationValue( md, "parent" ) ); } // Only process if autowiring @@ -748,7 +767,7 @@ component accessors="true" { // AOP AutoBinding only if both @classMatcher and @methodMatcher exist if ( - isAspectAutoBinding() AND structKeyExists( md, "classMatcher" ) AND structKeyExists( + isAspectAutoBinding() AND hasAnnotationValue( md, "classMatcher" ) AND hasAnnotationValue( md, "methodMatcher" ) @@ -964,46 +983,55 @@ component accessors="true" { */ private function processPropertyMetadata( required metadata ){ // Injection / Delegation Definition - if ( arguments.metadata.keyExists( "inject" ) ) { + if ( hasAnnotationValue( arguments.metadata, "inject" ) ) { addDIProperty( - name : arguments.metadata.name, - dsl : ( len( arguments.metadata.inject ) ? arguments.metadata.inject : "model" ), - scope : ( arguments.metadata.keyExists( "scope" ) ? arguments.metadata.scope : "variables" ), - required : ( arguments.metadata.keyExists( "required" ) ? arguments.metadata.required : true ), - type : ( arguments.metadata.keyExists( "type" ) ? arguments.metadata.type : "any" ), - delegate : arguments.metadata.keyExists( "delegate" ), + name: arguments.metadata.name, + dsl : ( + len( getAnnotationValue( arguments.metadata, "inject" ) ) ? getAnnotationValue( + arguments.metadata, + "inject" + ) : "model" + ), + scope : getAnnotationValue( arguments.metadata, "scope", "variables" ), + required : getAnnotationValue( arguments.metadata, "required", true ), + type : getAnnotationValue( arguments.metadata, "type", "any" ), + delegate : hasAnnotationValue( arguments.metadata, "delegate" ), delegatePrefix: ( // Verify it exists, if it does and no length then use the property name by convention - arguments.metadata.keyExists( "delegatePrefix" ) ? ( - len( arguments.metadata.delegatePrefix ) ? arguments.metadata.delegatePrefix : arguments.metadata.name + hasAnnotationValue( arguments.metadata, "delegatePrefix" ) ? ( + len( getAnnotationValue( arguments.metadata, "delegatePrefix" ) ) ? getAnnotationValue( + arguments.metadata, + "delegatePrefix" + ) : arguments.metadata.name ) : "" ), delegateSuffix: ( // Verify it exists, if it does and no length then use the property name by convention - arguments.metadata.keyExists( "delegateSuffix" ) ? ( - len( arguments.metadata.delegateSuffix ) ? arguments.metadata.delegateSuffix : arguments.metadata.name + hasAnnotationValue( arguments.metadata, "delegateSuffix" ) ? ( + len( getAnnotationValue( arguments.metadata, "delegateSuffix" ) ) ? getAnnotationValue( + arguments.metadata, + "delegateSuffix" + ) : arguments.metadata.name ) : "" ), - delegateExcludes: ( - arguments.metadata.keyExists( "delegateExcludes" ) ? arguments.metadata.delegateExcludes.listToArray() : [] - ), - delegateIncludes: arguments.metadata.keyExists( "delegate" ) ? arguments.metadata.delegate.listToArray() : [] + delegateExcludes: getAnnotationValue( arguments.metadata, "delegateExcludes", "" ).listToArray(), + delegateIncludes: getAnnotationValue( arguments.metadata, "delegate", "" ).listToArray() ); } // end injection processing // Lazy processes - var isLazy = arguments.metadata.keyExists( "lazy" ); - var isLazyUnlocked = arguments.metadata.keyExists( "lazyNoLock" ) + var isLazy = hasAnnotationValue( arguments.metadata, "lazy" ); + var isLazyUnlocked = hasAnnotationValue( arguments.metadata, "lazyNoLock" ) if ( isLazy || isLazyUnlocked ) { // Detect Builder Name var builderName = ""; - if ( isLazy && len( arguments.metadata.lazy ) ) { - builderName &= arguments.metadata.lazy; - } else if ( isLazyUnlocked && len( arguments.metadata.lazyNoLock ) ) { - builderName &= arguments.metadata.lazyNoLock; + if ( isLazy && len( getAnnotationValue( arguments.metadata, "lazy" ) ) ) { + builderName &= getAnnotationValue( arguments.metadata, "lazy" ); + } else if ( isLazyUnlocked && len( getAnnotationValue( arguments.metadata, "lazyNoLock" ) ) ) { + builderName &= getAnnotationValue( arguments.metadata, "lazyNoLock" ); } else { // By convention build{propertyName} builderName &= "build#arguments.metadata.name#"; @@ -1017,15 +1045,61 @@ component accessors="true" { } // Observer Properties - if ( arguments.metadata.keyExists( "observed" ) ) { + if ( hasAnnotationValue( arguments.metadata, "observed" ) ) { // Register it variables.observedProperties.append( { "name" : arguments.metadata.name, - "observer" : len( arguments.metadata.observed ) ? arguments.metadata.observed : "#arguments.metadata.name#Observer" + "observer" : len( getAnnotationValue( arguments.metadata, "observed", "" ) ) ? getAnnotationValue( + arguments.metadata, + "observed", + "" + ) : "#arguments.metadata.name#Observer" } ); } } + private boolean function hasAnnotationValue( required struct metadata, required string key ){ + // Check if the property has an annotations struct + if ( structKeyExists( metadata, "annotations" ) && structKeyExists( metadata.annotations, key ) ) { + return true; + } + + // Check if the property has a documentation struct + if ( structKeyExists( metadata, "documentation" ) && structKeyExists( metadata.documentation, key ) ) { + return true; + } + + // Check if the property has the key directly + else if ( structKeyExists( metadata, key ) ) { + return true; + } + + return false; + } + + private any function getAnnotationValue( + required struct metadata, + required string key, + any defaultValue + ){ + // Check if the property has an annotations struct + if ( structKeyExists( metadata, "annotations" ) && structKeyExists( metadata.annotations, key ) ) { + return metadata.annotations[ key ]; + } + + // Check if the property has an documentation struct + if ( structKeyExists( metadata, "documentation" ) && structKeyExists( metadata.documentation, key ) ) { + return metadata.documentation[ key ]; + } + + // Check if the property has the key directly + else if ( structKeyExists( metadata, key ) ) { + return metadata[ key ]; + } + // Return default value + return defaultValue; + } + /** * Process a function's metadata for DI Injection * @@ -1037,13 +1111,18 @@ component accessors="true" { // Process parameters for constructor injection for ( var thisParam in arguments.metadata.parameters ) { // Check injection annotation, if not found then no injection - if ( structKeyExists( thisParam, "inject" ) ) { + if ( hasAnnotationValue( thisParam, "inject" ) ) { // ADD Constructor argument addDIConstructorArgument( - name : thisParam.name, - dsl : ( len( thisParam.inject ) ? thisParam.inject : "model" ), - required: ( structKeyExists( thisParam, "required" ) ? thisParam.required : false ), - type : ( structKeyExists( thisParam, "type" ) ? thisParam.type : "any" ) + name: thisParam.name, + dsl : ( + len( getAnnotationValue( thisParam, "inject" ) ) ? getAnnotationValue( + thisParam, + "inject" + ) : "model" + ), + required: getAnnotationValue( thisParam, "required", false ), + type : getAnnotationValue( thisParam, "type", "any" ) ); } } @@ -1052,23 +1131,32 @@ component accessors="true" { } // Setter discovery, MUST be inject annotation marked to be processed. - if ( left( arguments.metadata.name, 3 ) eq "set" AND structKeyExists( arguments.metadata, "inject" ) ) { + if ( left( arguments.metadata.name, 3 ) eq "set" AND hasAnnotationValue( arguments.metadata, "inject" ) ) { // Add to setter to mappings and recursion lookup addDISetter( name: right( arguments.metadata.name, len( arguments.metadata.name ) - 3 ), - dsl : ( len( arguments.metadata.inject ) ? arguments.metadata.inject : "model" ) + dsl : ( + len( getAnnotationValue( arguments.metadata, "inject" ) ) ? getAnnotationValue( + arguments.metadata, + "inject" + ) : "model" + ) ); dependencies[ arguments.metadata.name ] = "setter"; } // Provider Methods Discovery - if ( structKeyExists( arguments.metadata, "provider" ) AND len( arguments.metadata.provider ) ) { - addProviderMethod( arguments.metadata.name, arguments.metadata.provider ); + if ( + hasAnnotationValue( arguments.metadata, "provider" ) AND len( + getAnnotationValue( arguments.metadata, "provider" ) + ) + ) { + addProviderMethod( arguments.metadata.name, getAnnotationValue( arguments.metadata, "provider" ) ); dependencies[ arguments.metadata.name ] = "provider"; } // onDIComplete Method Discovery - if ( structKeyExists( arguments.metadata, "onDIComplete" ) ) { + if ( hasAnnotationValue( arguments.metadata, "onDIComplete" ) ) { arrayAppend( variables.onDIComplete, arguments.metadata.name ); dependencies[ arguments.metadata.name ] = "onDIComplete"; } @@ -1093,10 +1181,10 @@ component accessors="true" { arguments.metadata.properties // Only process wirebox properties .filter( function( thisProperty ){ - return arguments.thisProperty.keyExists( "inject" ) || - arguments.thisProperty.keyExists( "lazyNoLock" ) || - arguments.thisProperty.keyExists( "observed" ) || - ( arguments.thisProperty.keyExists( "lazy" ) && !arguments.thisProperty.keyExists( "fieldType" ) ) + return hasAnnotationValue( thisProperty, "inject" ) || + hasAnnotationValue( thisProperty, "lazyNoLock" ) || + hasAnnotationValue( thisProperty, "observed" ) || + ( hasAnnotationValue( thisProperty, "lazy" ) && !hasAnnotationValue( thisProperty, "fieldType" ) ) } ) // Process each property .each( processPropertyMetadata ); diff --git a/system/modules/HTMLHelper/models/HTMLHelper.cfc b/system/modules/HTMLHelper/models/HTMLHelper.cfc index e68a48ae6..ab0c85cba 100755 --- a/system/modules/HTMLHelper/models/HTMLHelper.cfc +++ b/system/modules/HTMLHelper/models/HTMLHelper.cfc @@ -205,16 +205,21 @@ component buffer = buffer ); - // Prepare content output - if ( len( arguments.content ) ) { - // Value Encoding - if ( variables.settings.encodeValues ) { - arguments.content = encodeForHTML( arguments.content ); + try { + // Prepare content output + if ( len( arguments.content ) ) { + // Value Encoding + if ( variables.settings.encodeValues ) { + arguments.content = encodeForHTML( arguments.content ); + } + // Output tag + content + buffer.append( ">#arguments.content#" ); + } else { + buffer.append( ">" ); } - // Output tag + content - buffer.append( ">#arguments.content#" ); - } else { - buffer.append( ">" ); + } catch ( any e ) { + writeDump( var = arguments ); + rethrow; } // Return HTML diff --git a/system/testing/BaseInterceptorTest.cfc b/system/testing/BaseInterceptorTest.cfc index adb8be6fc..f2a3f7401 100644 --- a/system/testing/BaseInterceptorTest.cfc +++ b/system/testing/BaseInterceptorTest.cfc @@ -22,7 +22,11 @@ component extends="coldbox.system.testing.BaseTestCase" { } // Check for interceptor else throw exception - if ( NOT structKeyExists( md, "interceptor" ) ) { + if ( + NOT structKeyExists( md, "interceptor" ) && NOT ( + structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "interceptor" ) + ) + ) { throw( "interceptor annotation not found on component tag", "Please declare a 'interceptor=path' annotation", @@ -30,15 +34,23 @@ component extends="coldbox.system.testing.BaseTestCase" { ); } // Check for application helper - if ( structKeyExists( md, "applicationHelper" ) ) { + if ( + structKeyExists( md, "applicationHelper" ) || ( + structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "applicationHelper" ) + ) + ) { // inflate it, since it can't be an array in metadata - applicationHelper = listToArray( md.applicationHelper ); + applicationHelper = listToArray( + structKeyExists( md, "annotations" ) ? md.annotations.applicationHelper : md.applicationHelper + ); } // Check if user setup interceptor properties on scope param variables.configProperties = {}; // Create interceptor with Mocking capabilities - variables.interceptor = mockBox.createMock( md.interceptor ); + variables.interceptor = mockBox.createMock( + structKeyExists( md, "annotations" ) ? md.annotations.interceptor : md.interceptor + ); // Create Mock Objects variables.mockController = mockBox.createMock( "coldbox.system.testing.mock.web.MockController" ); diff --git a/system/testing/BaseModelTest.cfc b/system/testing/BaseModelTest.cfc index 4cfcfb932..6dc69d17a 100644 --- a/system/testing/BaseModelTest.cfc +++ b/system/testing/BaseModelTest.cfc @@ -21,9 +21,15 @@ component extends="coldbox.system.testing.BaseTestCase" { } // Check for model path annotation, and use it if declared. - if ( structKeyExists( md, "model" ) ) { + if ( + structKeyExists( md, "model" ) || ( + structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "model" ) + ) + ) { // Create model with Mocking capabilities - variables.model = mockBox.createMock( md.model ); + variables.model = mockBox.createMock( + structKeyExists( md, "annotations" ) ? md.annotations.model : md.model + ); } // Create Mock Objects diff --git a/system/testing/BaseTestCase.cfc b/system/testing/BaseTestCase.cfc index 95fb83cf9..4c5bb4234 100755 --- a/system/testing/BaseTestCase.cfc +++ b/system/testing/BaseTestCase.cfc @@ -256,7 +256,7 @@ component extends="testbox.system.compat.framework.TestCase" accessors="true" { mockRC.init( properties = rcProps, controller = mockController ); // return decorator context - if ( structKeyExists( arguments, "decorator" ) ) { + if ( structKeyExists( arguments, "decorator" ) && !isNull( arguments.decorator ) ) { return getMockBox().createMock( arguments.decorator ).init( mockRC, mockController ); } diff --git a/system/web/services/InterceptorService.cfc b/system/web/services/InterceptorService.cfc index 2180336b4..8358100e7 100644 --- a/system/web/services/InterceptorService.cfc +++ b/system/web/services/InterceptorService.cfc @@ -674,6 +674,8 @@ component extends="coldbox.system.web.services.BaseService" accessors="true" { if ( arguments.metadata.keyExists( "extends" ) && + !structIsEmpty( arguments.metadata.extends ) + && arguments.metadata.extends.name neq "coldbox.system.EventHandler" ) { // Recursive lookup From 07acc4cb71fb1996543e275c0b1f4f3ebbbf41d0 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Tue, 10 Jun 2025 16:13:25 +0200 Subject: [PATCH 2/9] more wip on boxlang prime --- server-boxlang@1.json | 6 ++++-- system/core/database/SchemaInfo.cfc | 16 ---------------- system/logging/appenders/DBAppender.cfc | 14 +++++++------- test-harness/Application.cfc | 1 - test-harness/config/ApplicationMixins.cfm | 5 ++++- .../external/testHandlers/BaseTest.cfc | 15 +++++++-------- .../testHandlers/TestNoInheritance.cfc | 19 +++++++++++-------- test-harness/external/testHandlers/ehTest.cfc | 19 +++++++++++-------- .../external/testHandlers/forum/message.cfc | 19 +++++++++++-------- tests/specs/core/database/SchemaInfoTest.cfc | 5 ----- 10 files changed, 55 insertions(+), 64 deletions(-) diff --git a/server-boxlang@1.json b/server-boxlang@1.json index 207220816..498c97e8c 100644 --- a/server-boxlang@1.json +++ b/server-boxlang@1.json @@ -20,6 +20,7 @@ }, "JVM":{ "heapSize":"768", + "javaVersion":"openjdk21_jre", "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999" }, "cfconfig":{ @@ -29,6 +30,7 @@ "BOXLANG_DEBUG":true }, "scripts":{ - "onServerInitialInstall":"install bx-mail,bx-pdf,bx-mysql,bx-esapi,testbox@be --noSave" - } + "onServerInitialInstall":"install bx-mail,bx-pdf,bx-mysql,bx-esapi,bx-orm@be --noSave" + }, + "conosole":true } diff --git a/system/core/database/SchemaInfo.cfc b/system/core/database/SchemaInfo.cfc index 710ff7a6d..5727275c0 100644 --- a/system/core/database/SchemaInfo.cfc +++ b/system/core/database/SchemaInfo.cfc @@ -188,20 +188,4 @@ component singleton { } } - /** - * Get the query param type for a specific datasource for a date/time column - * - * @dsn The datasource name - * @username The username to use - * @password The password to use - * @deprecated There are no longer any instances where this would be different between engines. Deprecate in 7.x and remove in 8x. - */ - public string function getQueryParamDateTimeType( - required string dsn, - username = "", - password = "" - ){ - return "cf_sql_timestamp"; - } - } diff --git a/system/logging/appenders/DBAppender.cfc b/system/logging/appenders/DBAppender.cfc index f8e27140c..adc74a6c1 100644 --- a/system/logging/appenders/DBAppender.cfc +++ b/system/logging/appenders/DBAppender.cfc @@ -92,7 +92,7 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { // DB Rotation Time variables.lastDBRotation = ""; - variables.queryParamDataTimeType = variables.schemaInfo.getQueryParamDateTimeType( getProperty( "dsn" ) ); + variables.queryParamDataTimeType = "timestamp"; return this; } @@ -230,15 +230,15 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { ", { uuid : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#variables.uuid.randomUUID().toString()#" }, severity : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#arguments.data.severity#" }, category : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#arguments.data.category#" }, timestamp : { @@ -246,15 +246,15 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { value : "#arguments.data.timestamp#" }, name : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#left( getName(), 100 )#" }, message : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#arguments.data.message#" }, extraInfo : { - cfsqltype : "cf_sql_varchar", + cfsqltype : "varchar", value : "#arguments.data.extraInfo#" } }, diff --git a/test-harness/Application.cfc b/test-harness/Application.cfc index b33b0aea8..a9e01d19a 100644 --- a/test-harness/Application.cfc +++ b/test-harness/Application.cfc @@ -46,7 +46,6 @@ component { this.mappings[ "/coldbox" ] = rootPath; // Test Harness Path this.mappings[ "/cbtestharness" ] = COLDBOX_APP_ROOT_PATH; - // Core Application.cfc mixins - ORM Settings, etc include "config/ApplicationMixins.cfm"; diff --git a/test-harness/config/ApplicationMixins.cfm b/test-harness/config/ApplicationMixins.cfm index cba16d691..4053217a2 100644 --- a/test-harness/config/ApplicationMixins.cfm +++ b/test-harness/config/ApplicationMixins.cfm @@ -1,6 +1,6 @@ - // Lucee 5 Cache Definition + // Lucee Cache Definition this.cache.connections[ "default" ] = { "class" = 'lucee.runtime.cache.ram.RamCache' , "storage" = false @@ -15,7 +15,10 @@ this.ormEnabled = true; this.datasource = "coolblog"; this.ormSettings = { + // CFML Approach cfclocation = "/cbtestharness/models/entities", + // BoxLang approach + entityPaths = "/cbtestharness/models/entities", logSQL = false, flushAtRequestEnd = false, autoManageSession = false, diff --git a/test-harness/external/testHandlers/BaseTest.cfc b/test-harness/external/testHandlers/BaseTest.cfc index 2e3ad7a92..edcdaf000 100755 --- a/test-harness/external/testHandlers/BaseTest.cfc +++ b/test-harness/external/testHandlers/BaseTest.cfc @@ -1,8 +1,7 @@ - - - - var rc = Event.getCollection(); - Event.setView( "vwExternalHandler" ); - - - +component{ + + function dspExternal( event, rc, prc ){ + event.setView( "vwExternalHandler" ); + } + +} \ No newline at end of file diff --git a/test-harness/external/testHandlers/TestNoInheritance.cfc b/test-harness/external/testHandlers/TestNoInheritance.cfc index bdf86939f..e80539898 100755 --- a/test-harness/external/testHandlers/TestNoInheritance.cfc +++ b/test-harness/external/testHandlers/TestNoInheritance.cfc @@ -1,8 +1,11 @@ - - - - var rc = Event.getCollection(); - Event.setView( "vwExternalHandler" ); - - - +component{ + + /** + * This is a test handler that does not inherit from the base handler. + * It is used to test the behavior of handlers without inheritance. + */ + function dspExternal( event, rc, prc ){ + event.setView( "vwExternalHandler" ); + } + +} diff --git a/test-harness/external/testHandlers/ehTest.cfc b/test-harness/external/testHandlers/ehTest.cfc index 9a4a59b16..e3a2c4752 100755 --- a/test-harness/external/testHandlers/ehTest.cfc +++ b/test-harness/external/testHandlers/ehTest.cfc @@ -1,8 +1,11 @@ - - - - var rc = Event.getCollection(); - Event.setView( "vwExternalHandler" ); - - - +component{ + + /** + * This is a test handler for external testing + */ + function dspExternal( event, rc ){ + rc.message = "This is an external test handler"; + event.setView( "vwExternalHandler" ); + } + +} diff --git a/test-harness/external/testHandlers/forum/message.cfc b/test-harness/external/testHandlers/forum/message.cfc index b837974cc..b68c2af11 100755 --- a/test-harness/external/testHandlers/forum/message.cfc +++ b/test-harness/external/testHandlers/forum/message.cfc @@ -1,8 +1,11 @@ - - - - var rc = Event.getCollection(); - Event.setView( "vwExternalHandler" ); - - - +component{ + + /** + * This is a test handler for external testing + */ + function dspExternal( event, rc ){ + rc.message = "This is an external test handler"; + event.setView( "vwExternalHandler" ); + } + +} \ No newline at end of file diff --git a/tests/specs/core/database/SchemaInfoTest.cfc b/tests/specs/core/database/SchemaInfoTest.cfc index 21476d3b5..0ab1ecdcb 100644 --- a/tests/specs/core/database/SchemaInfoTest.cfc +++ b/tests/specs/core/database/SchemaInfoTest.cfc @@ -43,11 +43,6 @@ component extends="testbox.system.BaseSpec" { expect( data ).toBe( "LONGTEXT" ); } ); - it( "can get a query param data/time column type", function(){ - var data = schemaInfo.getQueryParamDateTimeType( dsn ); - expect( data ).toBe( "cf_sql_timestamp" ); - } ); - it( "can get all the tables on the specified datasource", function(){ var data = schemaInfo.getTables( dsn ); expect( data ).toBeArray(); From f5a9bc99a608bd0c8a0c8990811568667b2c8653 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 11 Jun 2025 11:32:44 +0200 Subject: [PATCH 3/9] small updates for testing --- server-boxlang-cfml@be.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server-boxlang-cfml@be.json b/server-boxlang-cfml@be.json index bb641beb6..b39bd4520 100644 --- a/server-boxlang-cfml@be.json +++ b/server-boxlang-cfml@be.json @@ -20,8 +20,7 @@ }, "JVM":{ "heapSize":"1024", - "javaVersion":"openjdk21_jre", - "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999" + "javaVersion":"openjdk21_jre" }, "cfconfig":{ "file":".cfconfig.json" From dc507ecc242394f40242bb53c7ad1df5536f8a9b Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 11 Jun 2025 11:33:01 +0200 Subject: [PATCH 4/9] boxlang prime switches --- test-harness/config/ApplicationMixins.cfm | 6 +- .../models/entities/BoxLangEventHandler.cfc | 164 ++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 test-harness/models/entities/BoxLangEventHandler.cfc diff --git a/test-harness/config/ApplicationMixins.cfm b/test-harness/config/ApplicationMixins.cfm index 4053217a2..b0aa27eb1 100644 --- a/test-harness/config/ApplicationMixins.cfm +++ b/test-harness/config/ApplicationMixins.cfm @@ -23,8 +23,12 @@ flushAtRequestEnd = false, autoManageSession = false, eventHandling = true, - eventHandler = "cbtestharness.models.entities.EventHandler", dialect = 'MySQL' }; + if( server.keyExists( "boxlang" ) ){ + this.ormSettings.eventHandler = "cbtestharness.models.entities.BoxLangEventHandler"; + } else { + this.ormSettings.eventHandler = "cbtestharness.models.entities.EventHandler"; + } diff --git a/test-harness/models/entities/BoxLangEventHandler.cfc b/test-harness/models/entities/BoxLangEventHandler.cfc new file mode 100644 index 000000000..2704b3cb8 --- /dev/null +++ b/test-harness/models/entities/BoxLangEventHandler.cfc @@ -0,0 +1,164 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * Generic Hibernate Event Handler that ties to the ColdBox proxy for ColdBox Operations. + * This is just a base class you can inherit from to give you access to your ColdBox + * Application and the CF9 ORM event handler methods. Then you just need to + * use a la carte. + * + * We also execute interception points that match the ORM events so you can eaisly + * chain ORM interceptions. + * + */ +component extends="coldbox.system.remote.ColdboxProxy" implements="orm.IEventHandler" { + + /** + * preLoad called by hibernate which in turn announces a coldbox interception: ORMPreLoad + */ + public void function preLoad( any entity ){ + announce( "ORMPreLoad", { entity : arguments.entity } ); + } + + /** + * postLoad called by hibernate which in turn announces a coldbox interception: ORMPostLoad + */ + public void function postLoad( any entity ){ + var sTime = getTickCount(); + + var args = { entity : arguments.entity, entityName : "" }; + + // Short-cut discovery via ActiveEntity + if ( structKeyExists( arguments.entity, "getEntityName" ) ) { + args.entityName = arguments.entity.getEntityName(); + } else { + // it must be in session. + args.entityName = ormGetSession().getEntityName( arguments.entity ); + } + + processEntityInjection( args.entityName, args.entity ); + + announce( "ORMPostLoad", args ); + + //systemOutput( "==> orm:postLoad:#getTickCount() - sTime#", true ); + } + + /** + * postDelete called by hibernate which in turn announces a coldbox interception: ORMPostDelete + */ + public void function postDelete( any entity ){ + announce( "ORMPostDelete", { entity : arguments.entity } ); + } + + /** + * preDelete called by hibernate which in turn announces a coldbox interception: ORMPreDelete + */ + public void function preDelete( any entity ){ + announce( "ORMPreDelete", { entity : arguments.entity } ); + } + + /** + * preUpdate called by hibernate which in turn announces a coldbox interception: ORMPreUpdate + */ + public void function preUpdate( any entity, Struct oldData = {} ){ + announce( "ORMPreUpdate", { entity : arguments.entity, oldData : arguments.oldData } ); + } + + /** + * postUpdate called by hibernate which in turn announces a coldbox interception: ORMPostUpdate + */ + public void function postUpdate( any entity ){ + announce( "ORMPostUpdate", { entity : arguments.entity } ); + } + + /** + * preInsert called by hibernate which in turn announces a coldbox interception: ORMPreInsert + */ + public void function preInsert( any entity ){ + announce( "ORMPreInsert", { entity : arguments.entity } ); + } + + /** + * postInsert called by hibernate which in turn announces a coldbox interception: ORMPostInsert + */ + public void function postInsert( any entity ){ + announce( "ORMPostInsert", { entity : arguments.entity } ); + } + + /** + * preSave called by ColdBox Base service before save() calls + */ + public void function preSave( any entity ){ + announce( "ORMPreSave", { entity : arguments.entity } ); + } + + /** + * postSave called by ColdBox Base service after transaction commit or rollback via the save() method + */ + public void function postSave( any entity ){ + announce( "ORMPostSave", { entity : arguments.entity } ); + } + + /** + * Called before the session is flushed. + */ + public void function preFlush( any entities ){ + announce( "ORMPreFlush", { entities : arguments.entities } ); + } + + /** + * Called after the session is flushed. + */ + public void function postFlush( any entities ){ + announce( "ORMPostFlush", { entities : arguments.entities } ); + } + + /** + * postNew called by ColdBox which in turn announces a coldbox interception: ORMPostNew + */ + public void function postNew( any entity, any entityName ){ + var args = { entity : arguments.entity, entityName : "" }; + + // Do we have an incoming name + if ( !isNull( arguments.entityName ) && len( arguments.entityName ) ) { + args.entityName = arguments.entityName; + } + + // If we don't have the entity name, then look it up + if ( !len( args.entityName ) ) { + // Short-cut discovery via ActiveEntity + if ( structKeyExists( arguments.entity, "getEntityName" ) ) { + args.entityName = arguments.entity.getEntityName(); + } else { + // Long Discovery + var md = getMetadata( arguments.entity ); + args.entityName = ( md.keyExists( "entityName" ) ? md.entityName : listLast( md.name, "." ) ); + } + } + + // Process the announcement + announce( "ORMPostNew", args ); + } + + /** + * Get the system Event Manager + */ + public any function getEventManager(){ + return getWireBox().getEventManager(); + } + + /** + * process entity injection + * + * @entityName the entity to process, we use hash codes to identify builders + * @entity The entity object + * + * @return The processed entity + */ + public function processEntityInjection( required entityName, required entity ){ + // Process DI + getWireBox().autowire( target = arguments.entity, targetID = "ORMEntity-#arguments.entityName#" ); + return arguments.entity; + } + +} From d1e8641f8ce47ebda23c63080a4421607a1ba7ff Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 18 Jun 2025 15:04:41 +0200 Subject: [PATCH 5/9] boxlang prime updates on sqltypes --- system/cache/store/JDBCStore.cfc | 120 +++++++++++++++++++----- system/logging/appenders/DBAppender.cfc | 8 ++ 2 files changed, 107 insertions(+), 21 deletions(-) diff --git a/system/cache/store/JDBCStore.cfc b/system/cache/store/JDBCStore.cfc index 8d5e88385..9e0313875 100644 --- a/system/cache/store/JDBCStore.cfc +++ b/system/cache/store/JDBCStore.cfc @@ -237,9 +237,21 @@ component implements="coldbox.system.cache.store.IObjectStore" accessors="true" var qStats = queryExecute( "#targetSQL#", { - lastAccessed : { value : "#now()#", cfsqltype : "timestamp" }, - id : { value : "#normalizedID#", cfsqltype : "varchar" }, - created : { value : "#now()#", cfsqltype : "timestamp" } + lastAccessed : { + value : "#now()#", + cfsqltype : "timestamp", + sqltype : "timestamp" + }, + id : { + value : "#normalizedID#", + cfsqltype : "varchar", + sqltype : "varchar" + }, + created : { + value : "#now()#", + cfsqltype : "timestamp", + sqltype : "timestamp" + } }, variables.queryOptions ); @@ -360,18 +372,51 @@ component implements="coldbox.system.cache.store.IObjectStore" accessors="true" ) ", { - id : { value : "#normalizedId#", cfsqltype : "varchar" }, - objectKey : { value : "#arguments.objectKey#", cfsqltype : "varchar" }, - objectValue : { value : "#arguments.object#", cfsqltype : "longvarchar" }, - hits : { value : "1", cfsqltype : "integer" }, - timeout : { value : "#arguments.timeout#", cfsqltype : "integer" }, + id : { + value : "#normalizedId#", + cfsqltype : "varchar", + sqltype : "varchar" + }, + objectKey : { + value : "#arguments.objectKey#", + cfsqltype : "varchar", + sqltype : "varchar" + }, + objectValue : { + value : "#arguments.object#", + cfsqltype : "longvarchar", + sqltype : "longvarchar" + }, + hits : { + value : "1", + cfsqltype : "integer", + sqltype : "integer" + }, + timeout : { + value : "#arguments.timeout#", + cfsqltype : "integer", + sqltype : "integer" + }, lastAccessTimeout : { value : "#arguments.lastAccessTimeout#", - cfsqltype : "integer" + cfsqltype : "integer", + sqltype : "integer" + }, + now : { + value : now(), + cfsqltype : "timestamp", + sqltype : "timestamp" }, - now : { value : now(), cfsqltype : "timestamp" }, - isExpired : { value : "0", cfsqltype : "bit" }, - isSimple : { value : "#isSimple#", cfsqltype : "bit" } + isExpired : { + value : "0", + cfsqltype : "bit", + sqltype : "bit" + }, + isSimple : { + value : "#isSimple#", + cfsqltype : "bit", + sqltype : "bit" + } }, variables.queryOptions ); @@ -393,18 +438,51 @@ component implements="coldbox.system.cache.store.IObjectStore" accessors="true" WHERE id = :id ", { - id : { value : "#normalizedId#", cfsqltype : "varchar" }, - objectKey : { value : "#arguments.objectKey#", cfsqltype : "varchar" }, - objectValue : { value : "#arguments.object#", cfsqltype : "longvarchar" }, - hits : { value : "1", cfsqltype : "integer" }, - timeout : { value : "#arguments.timeout#", cfsqltype : "integer" }, + id : { + value : "#normalizedId#", + cfsqltype : "varchar", + sqltype : "varchar" + }, + objectKey : { + value : "#arguments.objectKey#", + cfsqltype : "varchar", + sqltype : "varchar" + }, + objectValue : { + value : "#arguments.object#", + cfsqltype : "longvarchar", + sqltype : "longvarchar" + }, + hits : { + value : "1", + cfsqltype : "integer", + sqltype : "integer" + }, + timeout : { + value : "#arguments.timeout#", + cfsqltype : "integer", + sqltype : "integer" + }, lastAccessTimeout : { value : "#arguments.lastAccessTimeout#", - cfsqltype : "integer" + cfsqltype : "integer", + sqltype : "integer" + }, + now : { + value : now(), + cfsqltype : "timestamp", + sqltype : "timestamp" + }, + isExpired : { + value : "0", + cfsqltype : "bit", + sqltype : "bit" }, - now : { value : now(), cfsqltype : "timestamp" }, - isExpired : { value : "0", cfsqltype : "bit" }, - isSimple : { value : "#isSimple#", cfsqltype : "bit" } + isSimple : { + value : "#isSimple#", + cfsqltype : "bit", + sqltype : "bit" + } }, variables.queryOptions ); diff --git a/system/logging/appenders/DBAppender.cfc b/system/logging/appenders/DBAppender.cfc index adc74a6c1..473abca2d 100644 --- a/system/logging/appenders/DBAppender.cfc +++ b/system/logging/appenders/DBAppender.cfc @@ -170,6 +170,7 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { { datetime : { cfsqltype : variables.queryParamDataTimeType, + sqltype : variables.queryParamDataTimeType, value : "#dateFormat( targetDate, "mm/dd/yyyy" )#" } }, @@ -231,30 +232,37 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { { uuid : { cfsqltype : "varchar", + sqltype : "varchar", value : "#variables.uuid.randomUUID().toString()#" }, severity : { cfsqltype : "varchar", + sqltype : "varchar", value : "#arguments.data.severity#" }, category : { cfsqltype : "varchar", + sqltype : "varchar", value : "#arguments.data.category#" }, timestamp : { cfsqltype : variables.queryParamDataTimeType, + sqltype : variables.queryParamDataTimeType, value : "#arguments.data.timestamp#" }, name : { cfsqltype : "varchar", + sqltype : "varchar", value : "#left( getName(), 100 )#" }, message : { cfsqltype : "varchar", + sqltype : "varchar", value : "#arguments.data.message#" }, extraInfo : { cfsqltype : "varchar", + sqltype : "varchar", value : "#arguments.data.extraInfo#" } }, From 508c694cf420dc4f95d28bd5e25e2d2387bb7680 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 18 Jun 2025 16:45:19 +0200 Subject: [PATCH 6/9] more wip --- system/core/events/EventPoolManager.cfc | 6 +-- system/core/util/Util.cfc | 14 ++--- system/ioc/config/Mapping.cfc | 53 ++++++++++++------- .../modules/HTMLHelper/models/HTMLHelper.cfc | 23 ++++---- system/testing/BaseInterceptorTest.cfc | 32 ++++------- system/testing/BaseModelTest.cfc | 13 ++--- system/testing/BaseTestCase.cfc | 4 +- system/web/services/InterceptorService.cfc | 2 +- 8 files changed, 71 insertions(+), 76 deletions(-) diff --git a/system/core/events/EventPoolManager.cfc b/system/core/events/EventPoolManager.cfc index ea9e77cd7..332b2dd46 100644 --- a/system/core/events/EventPoolManager.cfc +++ b/system/core/events/EventPoolManager.cfc @@ -228,11 +228,11 @@ component accessors="true" { // Start Registering inheritances? if ( - structKeyExists( arguments.metadata, "extends" ) + arguments.metadata.keyExists( "extends" ) AND - !structIsEmpty( arguments.metadata.extends ) + !isNull( arguments.metadata.extends ) AND - NOT listFindNoCase( getStopRecursionClasses(), arguments.metadata.extends.name ) + !listFindNoCase( getStopRecursionClasses(), arguments.metadata.extends.name ) ) { parseMetadata( arguments.metadata.extends, arguments.eventsFound ); } diff --git a/system/core/util/Util.cfc b/system/core/util/Util.cfc index e9481f315..bf7318a35 100644 --- a/system/core/util/Util.cfc +++ b/system/core/util/Util.cfc @@ -416,18 +416,18 @@ component { if ( isObject( arguments.component ) ) { arguments.md = getMetadata( arguments.component ); } else { - arguments.md = server.keyExists( "boxlang" ) ? getClassMetadata( arguments.component ) : getComponentMetadata( - arguments.component - ); + arguments.md = server.keyExists( "boxlang" ) ? + getClassMetadata( arguments.component ) : + getComponentMetadata( arguments.component ); } } // If it has a parent, stop and calculate it first, unless of course, we've reached a class we shouldn't recurse into. if ( - structKeyExists( arguments.md, "extends" ) && - !structIsEmpty( arguments.md.extends ) && - arguments.md.type eq "component" && - stopClassRecursion( md.extends.name, arguments.stopRecursions ) EQ FALSE + arguments.md.keyExists( "extends" ) AND + !arguments.md.extends.isEmpty() AND + listFindNoCase( "class,component", arguments.md.extends.type ) AND + !stopClassRecursion( arguments.md.extends.name, arguments.stopRecursions ) ) { loc.parent = getInheritedMetaData( component = arguments.component, diff --git a/system/ioc/config/Mapping.cfc b/system/ioc/config/Mapping.cfc index c873357c0..9566095db 100644 --- a/system/ioc/config/Mapping.cfc +++ b/system/ioc/config/Mapping.cfc @@ -354,7 +354,7 @@ component accessors="true" { // check if already registered, if it is, just return for ( var x = 1; x lte arrayLen( variables.DIConstructorArguments ); x++ ) { if ( - structKeyExists( arguments, "name" ) AND + !isNull( arguments.name ) AND structKeyExists( variables.DIConstructorArguments[ x ], "name" ) AND variables.DIConstructorArguments[ x ].name == arguments.name ) { @@ -492,7 +492,10 @@ component accessors="true" { // Remove scope for setter injection definition.scope = ""; // Verify argument name, if not default it to setter name - if ( NOT structKeyExists( arguments, "argName" ) OR len( arguments.argName ) EQ 0 ) { + if ( + isNull( arguments.argName ) OR + len( arguments.argName ) EQ 0 + ) { arguments.argName = arguments.name; } // save incoming params @@ -1058,44 +1061,58 @@ component accessors="true" { } } + /** + * Checks if the property has an annotation value for the key + * + * @metadata The metadata to check + * @key The key to look for in the annotations or documentation + * + * @return boolean + */ private boolean function hasAnnotationValue( required struct metadata, required string key ){ - // Check if the property has an annotations struct - if ( structKeyExists( metadata, "annotations" ) && structKeyExists( metadata.annotations, key ) ) { - return true; - } + var annotations = arguments.metadata.keyExists( "annotations" ) ? arguments.metadata.annotations : arguments.metadata; + var documentation = arguments.metadata.keyExists( "documentation" ) ? arguments.metadata.documentation : arguments.metadata; - // Check if the property has a documentation struct - if ( structKeyExists( metadata, "documentation" ) && structKeyExists( metadata.documentation, key ) ) { + // Check in the annotations struct first + if ( structKeyExists( annotations, key ) ) { return true; } - // Check if the property has the key directly - else if ( structKeyExists( metadata, key ) ) { + // Check in the documentation struct second, to support CFML engines + if ( structKeyExists( documentation, key ) ) { return true; } return false; } + /** + * Get the annotation value for a given key in the metadata + * + * @metadata The metadata to check + * @key The key to look for in the annotations or documentation + * @defaultValue The default value to return if the key is not found + * + * @return any + */ private any function getAnnotationValue( required struct metadata, required string key, any defaultValue ){ + var annotations = arguments.metadata.keyExists( "annotations" ) ? arguments.metadata.annotations : arguments.metadata; + var documentation = arguments.metadata.keyExists( "documentation" ) ? arguments.metadata.documentation : arguments.metadata; + // Check if the property has an annotations struct - if ( structKeyExists( metadata, "annotations" ) && structKeyExists( metadata.annotations, key ) ) { - return metadata.annotations[ key ]; + if ( structKeyExists( annotations, key ) ) { + return annotations[ key ]; } // Check if the property has an documentation struct - if ( structKeyExists( metadata, "documentation" ) && structKeyExists( metadata.documentation, key ) ) { - return metadata.documentation[ key ]; + if ( structKeyExists( documentation, key ) ) { + return documentation[ key ]; } - // Check if the property has the key directly - else if ( structKeyExists( metadata, key ) ) { - return metadata[ key ]; - } // Return default value return defaultValue; } diff --git a/system/modules/HTMLHelper/models/HTMLHelper.cfc b/system/modules/HTMLHelper/models/HTMLHelper.cfc index ab0c85cba..e68a48ae6 100755 --- a/system/modules/HTMLHelper/models/HTMLHelper.cfc +++ b/system/modules/HTMLHelper/models/HTMLHelper.cfc @@ -205,21 +205,16 @@ component buffer = buffer ); - try { - // Prepare content output - if ( len( arguments.content ) ) { - // Value Encoding - if ( variables.settings.encodeValues ) { - arguments.content = encodeForHTML( arguments.content ); - } - // Output tag + content - buffer.append( ">#arguments.content#" ); - } else { - buffer.append( ">" ); + // Prepare content output + if ( len( arguments.content ) ) { + // Value Encoding + if ( variables.settings.encodeValues ) { + arguments.content = encodeForHTML( arguments.content ); } - } catch ( any e ) { - writeDump( var = arguments ); - rethrow; + // Output tag + content + buffer.append( ">#arguments.content#" ); + } else { + buffer.append( ">" ); } // Return HTML diff --git a/system/testing/BaseInterceptorTest.cfc b/system/testing/BaseInterceptorTest.cfc index f2a3f7401..7a7954099 100644 --- a/system/testing/BaseInterceptorTest.cfc +++ b/system/testing/BaseInterceptorTest.cfc @@ -13,6 +13,7 @@ component extends="coldbox.system.testing.BaseTestCase" { */ function setup(){ var md = getMetadata( this ); + var annotations = md.keyExists( "annotations" ) ? md.annotations : md; var mockBox = getMockBox(); var applicationHelper = []; @@ -22,41 +23,28 @@ component extends="coldbox.system.testing.BaseTestCase" { } // Check for interceptor else throw exception - if ( - NOT structKeyExists( md, "interceptor" ) && NOT ( - structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "interceptor" ) - ) - ) { + if ( !annotations.keyExists( "interceptor" ) ) { throw( - "interceptor annotation not found on component tag", - "Please declare a 'interceptor=path' annotation", - "BaseInterceptorTest.InvalidStateException" + message : "interceptor annotation not found on component tag", + detail : "Please declare a 'interceptor=path' annotation", + type: "BaseInterceptorTest.InvalidStateException" ); } + // Check for application helper - if ( - structKeyExists( md, "applicationHelper" ) || ( - structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "applicationHelper" ) - ) - ) { + if ( annotations.keyExists( "applicationHelper" ) ) { // inflate it, since it can't be an array in metadata - applicationHelper = listToArray( - structKeyExists( md, "annotations" ) ? md.annotations.applicationHelper : md.applicationHelper - ); + applicationHelper = listToArray( annotations.applicationHelper ); } // Check if user setup interceptor properties on scope param variables.configProperties = {}; // Create interceptor with Mocking capabilities - variables.interceptor = mockBox.createMock( - structKeyExists( md, "annotations" ) ? md.annotations.interceptor : md.interceptor - ); + variables.interceptor = mockBox.createMock( annotations.interceptor ); // Create Mock Objects variables.mockController = mockBox.createMock( "coldbox.system.testing.mock.web.MockController" ); - variables.mockInterceptorService = mockbox.createEmptyMock( - "coldbox.system.web.services.InterceptorService" - ); + variables.mockInterceptorService = mockBox.createEmptyMock( "coldbox.system.web.services.InterceptorService" ); variables.mockRequestContext = getMockRequestContext(); variables.mockRequestService = mockBox .createEmptyMock( "coldbox.system.web.services.RequestService" ) diff --git a/system/testing/BaseModelTest.cfc b/system/testing/BaseModelTest.cfc index 6dc69d17a..fc2ccc850 100644 --- a/system/testing/BaseModelTest.cfc +++ b/system/testing/BaseModelTest.cfc @@ -13,6 +13,7 @@ component extends="coldbox.system.testing.BaseTestCase" { */ function setup(){ var md = getMetadata( this ); + var annotations = md.keyExists( "annotations" ) ? md.annotations : md; var mockBox = getMockBox(); // Load ColdBox? @@ -21,15 +22,9 @@ component extends="coldbox.system.testing.BaseTestCase" { } // Check for model path annotation, and use it if declared. - if ( - structKeyExists( md, "model" ) || ( - structKeyExists( md, "annotations" ) && structKeyExists( md.annotations, "model" ) - ) - ) { - // Create model with Mocking capabilities - variables.model = mockBox.createMock( - structKeyExists( md, "annotations" ) ? md.annotations.model : md.model - ); + // Create model with Mocking capabilities + if ( annotations.keyExists( "model" ) ) { + variables.model = mockBox.createMock( annotations.model ); } // Create Mock Objects diff --git a/system/testing/BaseTestCase.cfc b/system/testing/BaseTestCase.cfc index 4c5bb4234..2fd68a363 100755 --- a/system/testing/BaseTestCase.cfc +++ b/system/testing/BaseTestCase.cfc @@ -234,7 +234,7 @@ component extends="testbox.system.compat.framework.TestCase" accessors="true" { var rcProps = structNew(); if ( arguments.clearMethods ) { - if ( structKeyExists( arguments, "decorator" ) ) { + if ( !isNull( arguments.decorator ) ) { return getMockBox().createEmptyMock( arguments.decorator ); } return getMockBox().createEmptyMock( "coldbox.system.web.context.RequestContext" ); @@ -256,7 +256,7 @@ component extends="testbox.system.compat.framework.TestCase" accessors="true" { mockRC.init( properties = rcProps, controller = mockController ); // return decorator context - if ( structKeyExists( arguments, "decorator" ) && !isNull( arguments.decorator ) ) { + if ( !isNull( arguments.decorator ) ) { return getMockBox().createMock( arguments.decorator ).init( mockRC, mockController ); } diff --git a/system/web/services/InterceptorService.cfc b/system/web/services/InterceptorService.cfc index 8358100e7..fb72a46f9 100644 --- a/system/web/services/InterceptorService.cfc +++ b/system/web/services/InterceptorService.cfc @@ -674,7 +674,7 @@ component extends="coldbox.system.web.services.BaseService" accessors="true" { if ( arguments.metadata.keyExists( "extends" ) && - !structIsEmpty( arguments.metadata.extends ) + !arguments.metadata.extends.isEmpty() && arguments.metadata.extends.name neq "coldbox.system.EventHandler" ) { From 6ad04599f14cd3481a4c347487b851ba1ca44865 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 18 Jun 2025 16:49:53 +0200 Subject: [PATCH 7/9] more fixes --- system/core/dynamic/ObjectPopulator.cfc | 2 ++ system/core/events/EventPoolManager.cfc | 2 +- system/exceptions/js/coldfusion-brush.js | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/system/core/dynamic/ObjectPopulator.cfc b/system/core/dynamic/ObjectPopulator.cfc index 1ae065ce7..6f7de577c 100644 --- a/system/core/dynamic/ObjectPopulator.cfc +++ b/system/core/dynamic/ObjectPopulator.cfc @@ -569,6 +569,8 @@ component accessors="true" singleton { var annotations = server.keyExists( "boxlang" ) ? getClassMetadata( arguments.relationalMeta.properties[ key ].cfc ).annotations : getComponentMetadata( arguments.relationalMeta.properties[ key ].cfc ); + + // Verify if the entityName annotation exists if ( annotations.keyExists( "entityName" ) ) { targetEntityName = annotations.entityName; } diff --git a/system/core/events/EventPoolManager.cfc b/system/core/events/EventPoolManager.cfc index 332b2dd46..fa6ab38b8 100644 --- a/system/core/events/EventPoolManager.cfc +++ b/system/core/events/EventPoolManager.cfc @@ -230,7 +230,7 @@ component accessors="true" { if ( arguments.metadata.keyExists( "extends" ) AND - !isNull( arguments.metadata.extends ) + !arguments.metadata.extends.isEmpty() AND !listFindNoCase( getStopRecursionClasses(), arguments.metadata.extends.name ) ) { diff --git a/system/exceptions/js/coldfusion-brush.js b/system/exceptions/js/coldfusion-brush.js index c75ad9326..ebae43679 100644 --- a/system/exceptions/js/coldfusion-brush.js +++ b/system/exceptions/js/coldfusion-brush.js @@ -34,7 +34,7 @@ 'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' + 'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' + 'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' + - 'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' + + 'GetClientVariablesList GetComponentMetaData GetClassMetadata GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' + 'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' + 'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' + 'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' + From ee2322290c6f355653f0708b29b238ef1e059738 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Wed, 18 Jun 2025 17:37:05 +0200 Subject: [PATCH 8/9] boxlang brush --- system/exceptions/js/boxlang-brush.js | 120 ++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 system/exceptions/js/boxlang-brush.js diff --git a/system/exceptions/js/boxlang-brush.js b/system/exceptions/js/boxlang-brush.js new file mode 100644 index 000000000..be3d89196 --- /dev/null +++ b/system/exceptions/js/boxlang-brush.js @@ -0,0 +1,120 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * This is the Brush for the BoxLang JVM language. + * More information about BoxLang can be found at: + * http://boxlang.io + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require( 'shCore' ).SyntaxHighlighter : null; + + function Brush() + { + // BoxLang Keywords from grammar + var keywords = 'abstract as assert break case castas catch class component continue default do does else final finally for function greater if imp import in include instanceof interface is less lock new package param property private public remote required return static switch than thread throw to transaction try var when while'; + + // BoxLang Built-in Functions + var functions = 'Abs Acos aiChat aiChatAsync aiChatRequest aiMessage aiService aiTool ApplicationRestart ApplicationStartTime ApplicationStop Argon2CheckHash ArgonHash ArgonVerify ArrayAppend ArrayAvg ArrayClear ArrayContains ArrayContainsNoCase ArrayDelete ArrayDeleteAt ArrayDeleteNoCase ArrayEach ArrayEvery ArrayFilter ArrayFind ArrayFindAll ArrayFindAllNoCase ArrayFindNoCase ArrayFirst ArrayGetMetadata ArrayIndexExists ArrayInsertAt ArrayIsDefined arrayIsEmpty ArrayLast ArrayLen ArrayMap ArrayMax ArrayMedian ArrayMerge ArrayMid ArrayMin ArrayNew ArrayPop ArrayPrepend ArrayPush ArrayRange ArrayReduce ArrayReduceRight ArrayResize ArrayReverse ArraySet ArrayShift ArraySlice ArraySome ArraySort ArraySplice ArraySum ArraySwap ArrayToList ArrayToStruct ArrayUnshift Ascii Asin Atn Attempt BCryptHash BCryptVerify BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr bitShln bitShrn BitXor BooleanFormat BoxAnnounce BoxAnnounceAsync BoxLangBIFProxy BoxRegisterInterceptionPoints BoxRegisterInterceptor BoxRegisterRequestInterceptor BoxUnregisterInterceptor BoxUnregisterRequestInterceptor Cache CacheFilter CacheNames CacheProviders CacheService CallStackGet CamelCase Canonicalize Ceiling Char CharsetDecode CharsetEncode ClearLocale ClearTimezone CLIClear CLIExit CLIGetArgs CLIRead Compare CompareNoCase Compress ContractPath Cos CreateDate CreateDateTime CreateDynamicProxy CreateGUID CreateObject CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTempDirectory CreateTempFile CreateTime CreateTimeSpan CreateUUID CurrencyFormat DataNavigate DateAdd DateCompare DateConvert DateDiff DateFormat DatePart DateTimeFormat Day DayOfWeek DayOfWeekAsString DayOfWeekShortAsString DayOfYear DaysInMonth DaysInYear DE DebugBoxContexts DecimalFormat DecodeFor DecodeForBase64 DecodeForHTML DecodeForJson DecodeFromURL DecrementValue Decrypt DecryptBinary DirectoryCopy DirectoryCreate DirectoryDelete DirectoryExists DirectoryList DirectoryMove DirectoryRename Dump Duplicate echo EncodeFor encodeForCSS encodeForDN EncodeForHTML encodeForHTMLAttribute encodeForJavaScript encodeForLDAP EncodeForSQL encodeForURL encodeForXML encodeForXMLAttribute encodeForXPath Encrypt EncryptBinary EntityDelete EntityLoad EntityLoadByExample EntityLoadByPK EntityMerge EntityNameArray EntityNameList EntityNew EntityReload EntitySave EntityToQuery esapiDecode esapiEncode Evaluate ExecutorGet ExecutorHas ExecutorList ExecutorNew ExecutorShutdown ExecutorStatus Exp ExpandPath Extract FileAppend FileClose FileCopy FileDelete FileExists FileGetMimeType FileInfo FileIsEOF FileMove FileOpen FileRead FileReadBinary FileReadLine FileSeek FileSetAccessMode FileSetAttribute FileSetLastModified FileSkipBytes FileUpload FileUploadAll FileWrite FileWriteLine Find FindNoCase FindOneOf FirstDayOfMonth Fix Floor FormatBaseN Forward FutureNew GenerateArgon2Hash GenerateBCryptHash GeneratePBKDFKey GenerateSCryptHash GenerateSecretKey GetApplicationMetadata GetBaseTagData GetBaseTagList GetBaseTemplatePath GetBoxContext GetBoxRuntime GetBoxVersionInfo GetCanonicalPath GetClassMetadata GetComponentList GetContextRoot GetCpuUsage GetCurrentTemplatePath GetDirectoryFromPath GetFileFromPath GetFileInfo GetFreeSpace GetFunctionCalledName GetFunctionList GetHardware GetHTTPRequestData GetHTTPTimeString GetIniFile GetJVMFreeMemory GetJVMMaxMemory GetJVMTotalMemory GetLocale GetLocaleDisplayName GetLocaleInfo GetMemoryUsage GetMetaData GetMockServer GetModuleInfo GetModuleList GetNumericDate GetOperatingSystem GetPageContext GetProfileSection GetProfileSections GetProfileString GetReadableImageFormats GetRequestClassLoader GetSafeHTML GetSemver GetSystemFreeMemory GetSystemInfo GetSystemSetting GetSystemTotalMemory GetTempDirectory getTempFile GetTickCount GetTime GetTimezone GetTimezoneInfo GetToken GetTotalSpace GetWriteableImageFormats Hash Hash40 Hmac Hour htmlEditFormat HtmlFooter HtmlHead IIF ImageAddBorder ImageBlur ImageClearRect ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawImage ImageDrawLine ImageDrawLines ImageDrawOval ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ImageGetExifMetaData ImageGetExifTag ImageGetHeight ImageGetIPTCMetadata ImageGetIPTCTag ImageGetWidth ImageGrayScale ImageGreyScale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntiAliasing ImageSetBackgroundColor ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 IncrementValue InputBaseN Insert Int Invoke IsArray IsBinary IsBoolean IsClosure IsCurrency IsDate IsDateObject IsDebugMode IsDefined IsEmpty IsFileObject IsImage IsImageFile IsInstanceOf IsInThread IsInTransaction IsIPv6 IsJSON IsLeapYear IsLocalHost IsNull IsNumeric IsNumericDate IsObject IsQuery IsSafeHTML IsSimpleValue IsStruct isThreadAlive IsThreadInterrupted IsValid IsWDDX IsWithinTransaction IsXML IsXmlAttribute IsXMLDoc IsXMLElem IsXMLNode IsXMLRoot IsZipFile JavaCast JSONDeserialize JSONPrettify JSONSerialize JSStringFormat KebabCase LCase Left Len ListAppend ListAvg ListChangeDelims ListCompact ListContains ListContainsNoCase ListDeleteAt ListEach ListEvery ListFilter ListFind ListFindNoCase ListFirst ListGetAt ListIndexExists ListInsertAt ListItemTrim ListLast ListLen ListMap ListPrepend ListQualify ListReduce ListReduceRight ListRemoveDuplicates ListRest ListSetAt ListSome ListSort ListToArray ListTrim ListValueCount ListValueCountNoCase LJustify Location Log Log10 LSCurrencyFormat LSIsCurrency LSIsNumeric LSNumberFormat LSParseCurrency LSParseNumber LTrim Max Mid Millisecond Min Minute Month MonthAsString MonthShortAsString Nanosecond Now NullValue NumberFormat ObjectDeserialize ObjectSerialize Offset ORMClearSession ORMCloseAllSessions ORMCloseSession ORMEvictCollection ORMEvictEntity ORMEvictQueries ORMExecuteQuery ORMFlush ORMFlushAll ORMGetHibernateVersion ORMGetSession ORMGetSessionFactory ORMReload PagePoolClear ParagraphFormat ParseCurrency ParseDateTime ParseNumber PascalCase Pi PrecisionEvaluate PreserveSingleQuotes Print Println Quarter QueryAddColumn QueryAddRow QueryAppend QueryClear QueryColumnArray QueryColumnCount QueryColumnData QueryColumnExists QueryColumnList QueryCurrentRow QueryDeleteColumn QueryDeleteRow QueryEach QueryEvery QueryExecute QueryFilter QueryGetCell QueryGetResult QueryInsertAt QueryKeyExists QueryMap QueryNew QueryPrepend QueryRecordCount QueryReduce QueryRegisterFunction QueryReverse QueryRowData QueryRowSwap QuerySetCell QuerySetRow QuerySlice QuerySome QuerySort QueryStringToStruct Rand Randomize RandRange ReEscape ReFind reFindNoCase ReMatch reMatchNoCase RemoveChars RemoveProfileSection RemoveProfileString RepeatString Replace ReplaceList ReplaceListNoCase ReplaceNoCase ReReplace reReplaceNoCase Reverse Right RJustify Round RTrim RunAsync RunThreadInContext SanitizeHTML SchedulerGet SchedulerGetAll SchedulerList SchedulerRestart SchedulerShutdown SchedulerStart SchedulerStats SCryptHash SCryptVerify Second SessionInvalidate SessionRotate SessionStartTime SetEncoding SetLocale SetProfileString SetTimezone Sgn Sin Sleep Slugify SnakeCase SpanExcluding SpanIncluding SQLPrettify Sqr StartMockRequest StringBind StringEach StringEvery StringFilter StringLen StringMap StringReduce StringReduceRight StringSome StringSort StripCR StructAppend StructClear StructCopy StructCount StructDelete StructEach StructEquals StructEvery StructFilter StructFind StructFindKey StructFindValue StructGet StructGetMetadata StructInsert StructIsCaseSensitive structIsEmpty StructIsOrdered StructKeyArray StructKeyExists StructKeyList StructKeyTranslate StructMap StructNew StructReduce StructSome StructSort StructToQueryString StructToSorted StructUpdate StructValueArray SystemCacheClear SystemExecute SystemOutput Tan ThreadInterrupt ThreadJoin ThreadNew ThreadTerminate Throw TimeFormat ToBase64 ToBinary ToModifiable ToNumeric ToScript ToString ToUnmodifiable Trace TransactionCommit TransactionRollback TransactionSetSavepoint TranspileCollectionKeySwap Trim TrueFalseFormat UCase UCFirst URLDecode URLEncodedFormat Val VerifyBCryptHash VerifySCryptHash Week Wrap writeDump WriteLog WriteOutput XMLChildPos XMLElemNew XMLFormat XMLGetNodeType XMLNew XMLParse XMLSearch XMLTransform XMLValidate Year YesNoFormat'; + + // BoxLang Components and Special Components + var components = 'abort application associate boxlangcomponentproxy cache component content cookie dbinfo directory document documentitem documentsection dump examplecomponent execute exit file flush gzip header htmlfooter htmlhead http httpparam include invoke invokeargument location lock log loop mail mailparam mailpart object output param processingdirective procparam procresult query queryparam savecontent setting silent sleep stopwatch storedproc thread throw timer trace transaction wddx xml zip zipparam'; + + // Special BoxLang components from grammar + var specialComponents = 'transaction lock thread abort exit param'; + + // Operators and logical constructs + var operators = 'and or not xor mod eq neq lt le gt ge equal contains instanceof does eqv imp'; + + // Boolean literals + var booleans = 'true false yes no'; + + // Null literal + var nullValue = 'null'; + + // Access modifiers and type keywords + var modifiers = 'public private remote package abstract final static required'; + + // Template syntax components (bx: prefixed) + var templateComponents = 'argument function set return if else elseif try catch finally import while break continue include property rethrow throw switch case defaultcase output query'; + + this.regexList = [ + // Comments + { regex: new RegExp('//.*$', 'gm'), css: 'comments' }, // single line comments + { regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'gm'), css: 'comments' }, // multi-line comments + { regex: new RegExp('', 'gm'), css: 'comments' }, // BoxLang template comments + + // Strings + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings + + // Numbers + { regex: new RegExp('\\b\\d+\\.\\d+\\b', 'g'), css: 'value' }, // float literals + { regex: new RegExp('\\b\\d+\\b', 'g'), css: 'value' }, // integer literals + + // Template interpolation + { regex: new RegExp('#[^#]*#', 'g'), css: 'color2' }, // #variable# interpolation + + // BoxLang template components (bx:) + { regex: new RegExp('=|<>|===|!==)', 'g'), css: 'color1' }, // comparison operators + { regex: new RegExp('(\\|\\||&&|\\?:|\\?\\.|\\?\\.)', 'g'), css: 'color1' }, // logical operators + { regex: new RegExp('(\\||&|\\^|~|<<|>>|>>>)', 'g'), css: 'color1' } // bitwise operators + ]; + } + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = [ 'boxlang', 'bx' ]; + + SyntaxHighlighter.brushes.BoxLang = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); \ No newline at end of file From 75ca89bd0b2f5c3d69ceae2ae67592291937d47d Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Fri, 20 Jun 2025 16:43:25 +0200 Subject: [PATCH 9/9] making sure our masks are ok for boxlang prime --- server-boxlang-cfml@1.json | 2 +- system/async/tasks/ScheduledTask.cfc | 14 +++++++------- .../report/skins/default/CacheContentReport.cfm | 4 ++-- system/cache/report/skins/default/CacheReport.cfm | 2 +- system/exceptions/BugReport.cfm | 4 ++-- system/exceptions/Whoops.cfm | 2 +- system/logging/appenders/ConsoleAppender.cfc | 2 +- system/logging/appenders/DBAppender.cfc | 2 +- system/logging/appenders/FileAppender.cfc | 2 +- system/logging/appenders/RollingFileAppender.cfc | 4 ++-- system/web/context/ExceptionBean.cfc | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/server-boxlang-cfml@1.json b/server-boxlang-cfml@1.json index ad59ad48b..9c5a33ed1 100644 --- a/server-boxlang-cfml@1.json +++ b/server-boxlang-cfml@1.json @@ -21,7 +21,7 @@ "JVM":{ "heapSize":"1024", "javaVersion":"openjdk21_jre", - "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999" + "args":"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9998" }, "cfconfig":{ "file":".cfconfig.json" diff --git a/system/async/tasks/ScheduledTask.cfc b/system/async/tasks/ScheduledTask.cfc index c19f1b1d2..86f406877 100644 --- a/system/async/tasks/ScheduledTask.cfc +++ b/system/async/tasks/ScheduledTask.cfc @@ -464,14 +464,14 @@ component accessors="true" { /** * Set when this task should start execution on. By default it starts automatically. * - * @date The date when this task should start execution on => yyyy-mm-dd format is preferred. + * @date The date when this task should start execution on => yyyy-MM-dd format is preferred. * @time The specific time using 24 hour format => HH:mm, defaults to 00:00 */ ScheduledTask function startOn( required date, string time = "00:00" ){ debugLog( "startOn", arguments ); variables.startOnDateTime = variables.dateTimeHelper.parse( - "#dateFormat( arguments.date, "yyyy-mm-dd" )#T#arguments.time#" + "#dateFormat( arguments.date, "yyyy-MM-dd" )#T#arguments.time#" ); return this; } @@ -479,14 +479,14 @@ component accessors="true" { /** * Set when this task should stop execution on. By default it never ends * - * @date The date when this task should stop execution on => yyyy-mm-dd format is preferred. + * @date The date when this task should stop execution on => yyyy-MM-dd format is preferred. * @time The specific time using 24 hour format => HH:mm, defaults to 00:00 */ ScheduledTask function endOn( required date, string time = "00:00" ){ debugLog( "endOn", arguments ); variables.endOnDateTime = variables.dateTimeHelper.parse( - "#dateFormat( arguments.date, "yyyy-mm-dd" )#T#arguments.time#" + "#dateFormat( arguments.date, "yyyy-MM-dd" )#T#arguments.time#" ); return this; } @@ -648,12 +648,12 @@ component accessors="true" { len( variables.endTime ) ) { var _startTime = variables.dateTimeHelper.parse( - dateFormat( getJavaNow().toString(), "yyyy-mm-dd" ) & "T" & ( + dateFormat( getJavaNow().toString(), "yyyy-MM-dd" ) & "T" & ( len( variables.startTime ) ? variables.startTime : "00:00:00" ) ); var _endTime = variables.dateTimeHelper.parse( - dateFormat( getJavaNow().toString(), "yyyy-mm-dd" ) & "T" & ( + dateFormat( getJavaNow().toString(), "yyyy-MM-dd" ) & "T" & ( len( variables.endTime ) ? variables.endTime : "23:59:59" ) ); @@ -1662,7 +1662,7 @@ component accessors="true" { function debugLog( required string caller, struct args = {} ){ if ( variables.debug ) { var message = [ - dateTimeFormat( now(), "yyyy-mm-dd hh:nn:ss" ), + dateTimeFormat( now(), "yyyy-MM-dd hh:mm:ss" ), "ScheduledTask", "group: #getGroup()#", "name: #getName()#", diff --git a/system/cache/report/skins/default/CacheContentReport.cfm b/system/cache/report/skins/default/CacheContentReport.cfm index dbeea8a2d..c7dc292f8 100644 --- a/system/cache/report/skins/default/CacheContentReport.cfm +++ b/system/cache/report/skins/default/CacheContentReport.cfm @@ -34,14 +34,14 @@ - #dateformat( cacheMetadata[thisKey][ cacheMDKeyLookup.Created ], "mmm-dd" )#
+ #dateformat( cacheMetadata[thisKey][ cacheMDKeyLookup.Created ], "MMM-dd" )#
#timeformat( cacheMetadata[thisKey][ cacheMDKeyLookup.created ], "hh:mm:ss tt" )#
- #dateformat(cacheMetadata[thisKey][ cacheMDKeyLookup.LastAccessed ],"mmm-dd")#
+ #dateformat(cacheMetadata[thisKey][ cacheMDKeyLookup.LastAccessed ],"MMM-dd")#
#timeformat(cacheMetadata[thisKey][ cacheMDKeyLookup.LastAccessed ],"hh:mm:ss tt")#
diff --git a/system/cache/report/skins/default/CacheReport.cfm b/system/cache/report/skins/default/CacheReport.cfm index 8feff0cb6..800741276 100644 --- a/system/cache/report/skins/default/CacheReport.cfm +++ b/system/cache/report/skins/default/CacheReport.cfm @@ -40,7 +40,7 @@ Last Reap
- #DateFormat(cacheStats.getlastReapDatetime(),"mmm-dd-yyyy")# + #DateFormat(cacheStats.getlastReapDatetime(),"MMM-dd-yyyy")# #TimeFormat(cacheStats.getlastReapDatetime(),"hh:mm:ss tt")#
diff --git a/system/exceptions/BugReport.cfm b/system/exceptions/BugReport.cfm index bd66f8d0b..de8f3cf9b 100644 --- a/system/exceptions/BugReport.cfm +++ b/system/exceptions/BugReport.cfm @@ -68,7 +68,7 @@ A reporting template about exceptions in your ColdBox Apps Timestamp: - #dateformat(now(), "mm/dd/yyyy")# #timeformat(now(),"hh:mm:ss tt")# + #dateformat(now(), "MM/dd/yyyy")# #timeformat(now(),"hh:mm:ss tt")# Event Details: @@ -155,7 +155,7 @@ A reporting template about exceptions in your ColdBox Apps - + diff --git a/system/exceptions/Whoops.cfm b/system/exceptions/Whoops.cfm index 789652403..400938c8d 100644 --- a/system/exceptions/Whoops.cfm +++ b/system/exceptions/Whoops.cfm @@ -201,7 +201,7 @@

- #dateTimeFormat( now(), "mm/dd/yyyy hh:nn tt" )# + #dateTimeFormat( now(), "MMM/dd/yyyy HH:mm:ss" )#

diff --git a/system/logging/appenders/ConsoleAppender.cfc b/system/logging/appenders/ConsoleAppender.cfc index edd29ab9c..64af4171f 100644 --- a/system/logging/appenders/ConsoleAppender.cfc +++ b/system/logging/appenders/ConsoleAppender.cfc @@ -53,7 +53,7 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { } // Entry string - entry = "#dateFormat( timestamp, "yyyy-mm-dd" )# #timeFormat( timestamp, "HH:MM:SS" )# #arguments.logEvent.getCategory()# #message#"; + entry = "#dateFormat( timestamp, "yyyy-MM-dd" )# #timeFormat( timestamp, "HH:mm:ss" )# #arguments.logEvent.getCategory()# #message#"; } // Log it diff --git a/system/logging/appenders/DBAppender.cfc b/system/logging/appenders/DBAppender.cfc index 473abca2d..c92dfd62b 100644 --- a/system/logging/appenders/DBAppender.cfc +++ b/system/logging/appenders/DBAppender.cfc @@ -171,7 +171,7 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { datetime : { cfsqltype : variables.queryParamDataTimeType, sqltype : variables.queryParamDataTimeType, - value : "#dateFormat( targetDate, "mm/dd/yyyy" )#" + value : "#dateFormat( targetDate, "MM/dd/yyyy" )#" } }, { datasource : dsn } diff --git a/system/logging/appenders/FileAppender.cfc b/system/logging/appenders/FileAppender.cfc index 09755598b..84d940158 100644 --- a/system/logging/appenders/FileAppender.cfc +++ b/system/logging/appenders/FileAppender.cfc @@ -108,7 +108,7 @@ component accessors="true" extends="coldbox.system.logging.AbstractAppender" { message = replace( message, chr( 13 ), " ", "all" ); // Entry string - entry = """#severityToString( logEvent.getSeverity() )#"",""#getname()#"",""#dateFormat( timestamp, "mm/dd/yyyy" )#"",""#timeFormat( timestamp, "HH:mm:ss" )#"",""#arguments.logEvent.getCategory()#"",""#message#"""; + entry = """#severityToString( logEvent.getSeverity() )#"",""#getname()#"",""#dateFormat( timestamp, "MM/dd/yyyy" )#"",""#timeFormat( timestamp, "HH:mm:ss" )#"",""#arguments.logEvent.getCategory()#"",""#message#"""; } // Queue it up diff --git a/system/logging/appenders/RollingFileAppender.cfc b/system/logging/appenders/RollingFileAppender.cfc index a81a56832..a5c003a42 100644 --- a/system/logging/appenders/RollingFileAppender.cfc +++ b/system/logging/appenders/RollingFileAppender.cfc @@ -53,7 +53,7 @@ component accessors="true" extends="coldbox.system.logging.appenders.FileAppende /** * Get the default archive layout: - * #filename#-#yyy-mm-dd#-#hh-mm#-#archiveNumber# + * #filename#-#yyy-MM-dd#-#hh-mm#-#archiveNumber# * DO NOT ADD EXTENSION TO IT, WE WILL ADD IT * * @filename The filename to use for the archive layout @@ -64,7 +64,7 @@ component accessors="true" extends="coldbox.system.logging.appenders.FileAppende function getDefaultArchiveLayout( required filename, required archiveCount ){ return arguments.fileName & "-" & - dateFormat( now(), "yyyy-mm-dd" ) & + dateFormat( now(), "yyyy-MM-dd" ) & "-" & timeFormat( now(), "HH-mm" ) & "-#arguments.archiveCount + 1#"; diff --git a/system/web/context/ExceptionBean.cfc b/system/web/context/ExceptionBean.cfc index 38b99313b..1332a9543 100644 --- a/system/web/context/ExceptionBean.cfc +++ b/system/web/context/ExceptionBean.cfc @@ -387,7 +387,7 @@ component accessors="true" { ); list.append( "

" );
Bug Date:#dateformat(now(), "mm/dd/yyyy")# #timeformat(now(),"hh:mm:ss tt")##dateformat(now(), "MM/dd/yyyy")# #timeformat(now(),"hh:mm:ss tt")#
" & - dateFormat( arguments.scope[ i ], "mm/dd/yyyy" ) & " " & + dateFormat( arguments.scope[ i ], "MM/dd/yyyy" ) & " " & timeFormat( arguments.scope[ i ], "HH:mm:ss" ) & "