From 36a8737a7390d50e28e9bd06f69a8f8926cd6484 Mon Sep 17 00:00:00 2001 From: Luis Majano Date: Thu, 14 May 2020 10:18:24 -0500 Subject: [PATCH] ### Added * New module template support * ColdBox 5-6 Support * Modern Formatting ### Removed * Lucee 4.5 Support * ACF11 Support --- .cfformat.json | 62 ++ .cflintrc | 61 ++ .editorconfig | 20 + .gitignore | 29 +- .markdownlintrc.json | 8 + .module.properties | 3 - .travis.yml | 90 ++- .../ModuleConfig.cfc => ModuleConfig.cfc | 47 +- apidocs/Application.cfc | 18 - apidocs/box.json | 13 - apidocs/index.cfm | 22 - apidocs/server.json | 9 - box.json | 51 +- build/Build.cfc | 248 ++++++ build/release.boxr | 25 + changelog.md | 58 +- config/.htaccess | 4 - config/Application.cfm | 9 - config/Coldbox.cfc | 77 -- config/Routes.cfm | 20 - layouts/Main.cfm | 1 - .../lib => lib}/drop_jars_here.txt | 0 models/JavaLoaderDSL.cfc | 54 ++ models/Loader.cfc | 165 ++++ models/javaloader/JavaCompiler.cfc | 231 ++++++ models/javaloader/JavaLoader.cfc | 724 ++++++++++++++++++ models/javaloader/JavaProxy.cfc | 371 +++++++++ .../models => models}/javaloader/README.md | 0 .../lib/classloader-20120103162851.jar | Bin .../models => models}/javaloader/licence.txt | 0 .../cfcdynamicproxy/lib/cfcdynamicproxy.jar | Bin .../support/spring/lib/spring-coldfusion.jar | Bin .../javaloader/tmp/tmp_compiled.txt | 0 modules/cbjavaloader/box.json | 23 - modules/cbjavaloader/models/JavaLoaderDSL.cfc | 50 -- modules/cbjavaloader/models/Loader.cfc | 147 ---- .../models/javaloader/JavaCompiler.cfc | 178 ----- .../models/javaloader/JavaLoader.cfc | 608 --------------- .../models/javaloader/JavaProxy.cfc | 354 --------- server.json | 13 - test-harness/.cfconfig.json | 8 + test-harness/.cflintrc | 1 + .../Application.cfc | 46 +- test-harness/box.json | 20 + test-harness/config/Application.cfc | 7 + test-harness/config/Coldbox.cfc | 110 +++ test-harness/config/Routes.cfm | 46 ++ test-harness/config/WireBox.cfc | 46 ++ {handlers => test-harness/handlers}/Main.cfc | 2 +- index.cfm => test-harness/index.cfm | 2 +- {jars => test-harness/jars}/helloworld.jar | Bin test-harness/layouts/Main.cfm | 6 + test-harness/server-adobe@2016.json | 16 + test-harness/server-adobe@2018.json | 16 + test-harness/server-lucee@5.json | 16 + test-harness/tests/Application.cfc | 39 + test-harness/tests/index.cfm | 196 +++++ {tests => test-harness/tests}/runner.cfm | 0 test-harness/tests/specs/LoaderTest.cfc | 56 ++ {views => test-harness/views}/main/index.cfm | 0 tests/Application.cfc | 24 - tests/specs/LoaderTest.cfc | 60 -- tests/specs/put_test_bundles_here.txt | 0 tests/test.properties | 5 - tests/test.xml | 238 ------ 65 files changed, 2761 insertions(+), 1992 deletions(-) create mode 100644 .cfformat.json create mode 100644 .cflintrc create mode 100644 .editorconfig create mode 100644 .markdownlintrc.json delete mode 100644 .module.properties rename modules/cbjavaloader/ModuleConfig.cfc => ModuleConfig.cfc (85%) delete mode 100755 apidocs/Application.cfc delete mode 100644 apidocs/box.json delete mode 100644 apidocs/index.cfm delete mode 100644 apidocs/server.json create mode 100644 build/Build.cfc create mode 100755 build/release.boxr delete mode 100644 config/.htaccess delete mode 100644 config/Application.cfm delete mode 100644 config/Coldbox.cfc delete mode 100644 config/Routes.cfm delete mode 100644 layouts/Main.cfm rename {modules/cbjavaloader/lib => lib}/drop_jars_here.txt (100%) create mode 100644 models/JavaLoaderDSL.cfc create mode 100755 models/Loader.cfc create mode 100644 models/javaloader/JavaCompiler.cfc create mode 100644 models/javaloader/JavaLoader.cfc create mode 100644 models/javaloader/JavaProxy.cfc rename {modules/cbjavaloader/models => models}/javaloader/README.md (100%) rename {modules/cbjavaloader/models => models}/javaloader/lib/classloader-20120103162851.jar (100%) rename {modules/cbjavaloader/models => models}/javaloader/licence.txt (100%) rename {modules/cbjavaloader/models => models}/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar (100%) rename {modules/cbjavaloader/models => models}/javaloader/support/spring/lib/spring-coldfusion.jar (100%) rename {modules/cbjavaloader/models => models}/javaloader/tmp/tmp_compiled.txt (100%) delete mode 100644 modules/cbjavaloader/box.json delete mode 100644 modules/cbjavaloader/models/JavaLoaderDSL.cfc delete mode 100755 modules/cbjavaloader/models/Loader.cfc delete mode 100644 modules/cbjavaloader/models/javaloader/JavaCompiler.cfc delete mode 100644 modules/cbjavaloader/models/javaloader/JavaLoader.cfc delete mode 100644 modules/cbjavaloader/models/javaloader/JavaProxy.cfc delete mode 100644 server.json create mode 100644 test-harness/.cfconfig.json create mode 100644 test-harness/.cflintrc rename Application.cfc => test-harness/Application.cfc (51%) create mode 100644 test-harness/box.json create mode 100644 test-harness/config/Application.cfc create mode 100644 test-harness/config/Coldbox.cfc create mode 100644 test-harness/config/Routes.cfm create mode 100644 test-harness/config/WireBox.cfc rename {handlers => test-harness/handlers}/Main.cfc (98%) rename index.cfm => test-harness/index.cfm (89%) rename {jars => test-harness/jars}/helloworld.jar (100%) create mode 100644 test-harness/layouts/Main.cfm create mode 100644 test-harness/server-adobe@2016.json create mode 100644 test-harness/server-adobe@2018.json create mode 100644 test-harness/server-lucee@5.json create mode 100644 test-harness/tests/Application.cfc create mode 100644 test-harness/tests/index.cfm rename {tests => test-harness/tests}/runner.cfm (100%) create mode 100644 test-harness/tests/specs/LoaderTest.cfc rename {views => test-harness/views}/main/index.cfm (100%) delete mode 100644 tests/Application.cfc delete mode 100644 tests/specs/LoaderTest.cfc delete mode 100644 tests/specs/put_test_bundles_here.txt delete mode 100644 tests/test.properties delete mode 100644 tests/test.xml diff --git a/.cfformat.json b/.cfformat.json new file mode 100644 index 0000000..aa464f6 --- /dev/null +++ b/.cfformat.json @@ -0,0 +1,62 @@ +{ + "array.empty_padding": false, + "array.padding": true, + "array.multiline.min_length": 40, + "array.multiline.element_count": 2, + "array.multiline.leading_comma.padding": true, + "array.multiline.leading_comma": false, + "alignment.consecutive.assignments": true, + "alignment.consecutive.properties": true, + "alignment.consecutive.params": true, + "brackets.padding": true, + "comment.asterisks": "align", + "binary_operators.padding": true, + "for_loop_semicolons.padding": true, + "function_call.empty_padding": false, + "function_call.padding": true, + "function_call.multiline.leading_comma.padding": true, + "function_call.casing.builtin": "cfdocs", + "function_call.casing.userdefined": "camel", + "function_call.multiline.element_count": 3, + "function_call.multiline.leading_comma": false, + "function_call.multiline.min_length": 40, + "function_declaration.padding": true, + "function_declaration.empty_padding": false, + "function_declaration.multiline.leading_comma": false, + "function_declaration.multiline.leading_comma.padding": true, + "function_declaration.multiline.element_count": 3, + "function_declaration.multiline.min_length": 40, + "function_declaration.group_to_block_spacing": "spaced", + "function_anonymous.empty_padding": false, + "function_anonymous.group_to_block_spacing": "spaced", + "function_anonymous.multiline.element_count": 3, + "function_anonymous.multiline.leading_comma": false, + "function_anonymous.multiline.leading_comma.padding": true, + "function_anonymous.multiline.min_length": 40, + "function_anonymous.padding": true, + "indent_size": 4, + "keywords.block_to_keyword_spacing": "spaced", + "keywords.group_to_block_spacing": "spaced", + "keywords.padding_inside_group": true, + "keywords.spacing_to_block": "spaced", + "keywords.spacing_to_group": true, + "keywords.empty_group_spacing": false, + "max_columns": 120, + "metadata.multiline.element_count": 3, + "metadata.multiline.min_length": 40, + "newline":"\n", + "property.multiline.element_count": 3, + "property.multiline.min_length": 40, + "parentheses.padding": true, + "strings.quote": "double", + "strings.convertNestedQuotes": false, + "strings.attributes.quote": "double", + "struct.separator": " : ", + "struct.padding": true, + "struct.empty_padding": false, + "struct.multiline.leading_comma": false, + "struct.multiline.leading_comma.padding": true, + "struct.multiline.element_count": 2, + "struct.multiline.min_length": 40, + "tab_indent": true +} diff --git a/.cflintrc b/.cflintrc new file mode 100644 index 0000000..396a0b3 --- /dev/null +++ b/.cflintrc @@ -0,0 +1,61 @@ +{ + "rule": [], + "includes": [ + { "code": "AVOID_USING_CFINCLUDE_TAG" }, + { "code": "AVOID_USING_CFABORT_TAG" }, + { "code": "AVOID_USING_CFEXECUTE_TAG" }, + { "code": "AVOID_USING_DEBUG_ATTR" }, + { "code": "AVOID_USING_ABORT" }, + { "code": "AVOID_USING_ISDATE" }, + { "code": "AVOID_USING_ISDEBUGMODE" }, + { "code": "AVOID_USING_CFINSERT_TAG" }, + { "code": "AVOID_USING_CFUPDATE_TAG" }, + { "code": "ARG_VAR_CONFLICT" }, + { "code": "ARG_HINT_MISSING" }, + { "code": "ARG_HINT_MISSING_SCRIPT" }, + { "code" : "ARGUMENT_INVALID_NAME" }, + { "code" : "ARGUMENT_ALLCAPS_NAME" }, + { "code" : "ARGUMENT_TOO_WORDY" }, + { "code" : "ARGUMENT_IS_TEMPORARY" }, + { "code": "CFQUERYPARAM_REQ" }, + { "code": "COMPARE_INSTEAD_OF_ASSIGN" }, + { "code": "COMPONENT_HINT_MISSING" }, + { "code" : "COMPONENT_INVALID_NAME" }, + { "code" : "COMPONENT_ALLCAPS_NAME" }, + { "code" : "COMPONENT_TOO_SHORT" }, + { "code" : "COMPONENT_TOO_LONG" }, + { "code" : "COMPONENT_TOO_WORDY" }, + { "code" : "COMPONENT_IS_TEMPORARY" }, + { "code" : "COMPONENT_HAS_PREFIX_OR_POSTFIX" }, + { "code": "COMPLEX_BOOLEAN_CHECK" }, + { "code": "EXCESSIVE_FUNCTION_LENGTH" }, + { "code": "EXCESSIVE_COMPONENT_LENGTH" }, + { "code": "EXCESSIVE_ARGUMENTS" }, + { "code": "EXCESSIVE_FUNCTIONS" }, + { "code": "EXPLICIT_BOOLEAN_CHECK" }, + { "code": "FUNCTION_TOO_COMPLEX" }, + { "code": "FUNCTION_HINT_MISSING" }, + { "code": "FILE_SHOULD_START_WITH_LOWERCASE" }, + { "code": "LOCAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN" }, + { "code": "MISSING_VAR" }, + { "code" : "METHOD_INVALID_NAME" }, + { "code" : "METHOD_ALLCAPS_NAME" }, + { "code" : "METHOD_IS_TEMPORARY" }, + { "code": "NESTED_CFOUTPUT" }, + { "code": "NEVER_USE_QUERY_IN_CFM" }, + { "code": "OUTPUT_ATTR" }, + { "code" : "QUERYPARAM_REQ" }, + { "code": "UNUSED_LOCAL_VARIABLE" }, + { "code": "UNUSED_METHOD_ARGUMENT" }, + { "code": "SQL_SELECT_STAR" }, + { "code": "SCOPE_ALLCAPS_NAME" }, + { "code": "VAR_ALLCAPS_NAME" }, + { "code": "VAR_INVALID_NAME" }, + { "code": "VAR_TOO_WORDY" } + ], + "inheritParent": false, + "parameters": { + "TooManyFunctionsChecker.maximum" : 20 + } +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a2c8081 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# http://editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false +indent_style = tab +indent_size = 4 +tab_width = 4 + +[*.yml] +indent_style = space +indent_size = 2 + +[*.{md,markdown}] +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.gitignore b/.gitignore index aa6d7df..ddc3087 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,14 @@ -# IDE Stuff -.settings -settings.xml +.vscode -# Logs -logs/*.log +.artifacts/** +.tmp/** -# Test Results -tests/results/* +test-harness/.engine/** +test-harness/coldbox/** +test-harness/docbox/** +test-harness/testbox/** +test-harness/logs/** +test-harness/modules/** -# Dependenncies -coldbox/* -testbox/* -artifacts/* -apidocs/docbox/* -workbench/* -build/* - -# Engines -.engine/** -.project \ No newline at end of file +# log files +logs/** \ No newline at end of file diff --git a/.markdownlintrc.json b/.markdownlintrc.json new file mode 100644 index 0000000..ceacd1f --- /dev/null +++ b/.markdownlintrc.json @@ -0,0 +1,8 @@ +{ + "line-length": false, + "single-h1": false, + "first-line-h1": false, + "no-multiple-blanks": { + "maximum": 2 + } +} \ No newline at end of file diff --git a/.module.properties b/.module.properties deleted file mode 100644 index 9aee05c..0000000 --- a/.module.properties +++ /dev/null @@ -1,3 +0,0 @@ -project.name=cbjavaloader -project.version=2.0.0 -module.name=cbjavaloader \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 440c81a..88883bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,13 @@ notifications: secure: FIHlTn/YO7Wgumm1uIqmoEsqjQA7fV0AE94Rjc5yKzM3AquQa8HicgDVVk0d2GrKRnl0xt3j4ZJV//VJyIjlCd/QVKuj48R2ChjEY2im3+99HFPafCUI5/S2uyowKU6mJTFonH9v6p41eqxdbiAxJdDGOT0V2Gpt3UBSNuHz8ED9/aIHqv+P7M+VD6Xd2XYwctPniWlaSWx57sWcnG/VkFG45qFQAyha64uxOOe4M3ZmG/n5FfauZ8cBVLiRKEIr+CyNhh1ujfzi7+4uzMlSNL5t/BbZamAQuZzqGzGQ9RVvIlyPgUGNJtDEE/hWS09aagXF5T6EMj00szizErh4J1/x4qZwml5+TcBN31E0QmAhCtZe85sr3tYgic+hEz9XX1yymQzf/C7n4to2yNvq0r4g51xDk8IuP95WEh7zaqLlvFZvBFgxpHZBMYlRvhytjOYDeIFRMcGwHZcXosaG2ejqDwcGq/LC4oeG4sSwmg9sdRrtcmcanrNqrBka86WYO6LntI3JdZ86/1ACEUHzhCCwvrKELc9Ji1xxGAgS7QKH+s2/hnJuiMyv73gOVLKYC+wPMLt+fvOmPLSEl+PJiAIlToBq1KUBg03RSQLfPOLD7OrJ8VvDZsEPwejqlGDyc4wRglS9OTi7SnN5LYHSDNDdGdREegWqq9qDHEYEVLI= env: + # Fill out these global variables for build process global: - MODULE_ID=cbjavaloader matrix: - - ENGINE=lucee@4.5 - ENGINE=lucee@5 - - ENGINE=adobe@11 - ENGINE=adobe@2016 + - ENGINE=adobe@2018 branches: only: @@ -24,75 +24,103 @@ sudo: required before_install: # CommandBox Keys - - sudo apt-key adv --keyserver keys.gnupg.net --recv 6DA70622 + - curl -fsSl https://downloads.ortussolutions.com/debs/gpg | sudo apt-key add - - sudo echo "deb http://downloads.ortussolutions.com/debs/noarch /" | sudo tee -a /etc/apt/sources.list.d/commandbox.list install: # Install Commandbox - sudo apt-get update && sudo apt-get --assume-yes install rsync jq commandbox + # Install CommandBox Supporting Librarires + - box install commandbox-cfconfig,commandbox-dotenv,commandbox-docbox # If using auto-publish, you will need to provide your API token with this line: - box config set endpoints.forgebox.APIToken=$FORGEBOX_API_TOKEN > /dev/null - # Setup for our tests - - mkdir tests/results - - sudo chmod -R 775 tests/results -# Build script - note module versioning is passed to ANT script: + # Set Current Version and Travis Tag + - TARGET_VERSION=`cat $TRAVIS_BUILD_DIR/box.json | jq '.version' -r` + - TRAVIS_TAG=${TARGET_VERSION} + - echo "Starting build for ${MODULE_ID} v${TARGET_VERSION}" + # Replace version so builder can issue it + - box package set version=@build.version@+@build.number@ + # Startup the harness + - cd test-harness # run our dependency install to ensure the workbench is in place - box install - # add our module-specific build properties - - printf "\nmodule.name=$MODULE_ID" >> workbench/build.properties - - printf "\ncfengine=$ENGINE" >> workbench/build.properties - # execute our build - - ant -DisTravis=true -Dbuild.number=$TRAVIS_BUILD_NUMBER -Dbuild.branch=$TRAVIS_BRANCH -f workbench/build.xml + # run our matrix server + - box server start serverConfigFile="server-${ENGINE}.json" + # Startup the app + - curl http://localhost:60299 + # Debugging of tests + #- curl http://localhost:60299/tests/runner.cfm?reporter=json -o testresults.json && cat testresults.json + # move back to build dir to build it + - cd $TRAVIS_BUILD_DIR + # Build Project + - box task run taskfile=build/Build target=run :version=${TARGET_VERSION} :projectName=${MODULE_ID} :buildID=${TRAVIS_BUILD_NUMBER} :branch=${TRAVIS_BRANCH} + # Cat results for debugging + #- cat build/results.json after_failure: - - cd $TRAVIS_BUILD_DIR + - cd $TRAVIS_BUILD_DIR/test-harness # Display the contents of our root directory # Spit out our Commandbox log in case we need to debug - - box server log name=$ENGINE + - box server log server-${ENGINE}.json - cat `box system-log` -# Only executed when merging to master -before_deploy: - - cd $TRAVIS_BUILD_DIR - - mkdir -p s3deploy - - rsync -av ./artifacts/$MODULE_ID/ ./s3deploy/ - - rm -f ./s3deploy/box-repo.json - deploy: - #Module Deployment + # Module Deployment - provider: s3 on: - branch: + branch: - master - development - condition: "$ENGINE = lucee@4.5" + condition: "$ENGINE = lucee@5" skip_cleanup: true #AWS Credentials need to be set in Travis access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_ACCESS_SECRET + # Destination bucket: "downloads.ortussolutions.com" - local-dir: s3deploy + local-dir: $TRAVIS_BUILD_DIR/.artifacts/$MODULE_ID upload-dir: ortussolutions/coldbox-modules/$MODULE_ID acl: public_read - #API Docs Deployment + + # API Docs Deployment - provider: s3 on: - branch: + branch: - master - development - condition: "$ENGINE = lucee@4.5" + condition: "$ENGINE = lucee@5" skip_cleanup: true #AWS Credentials need to be set in Travis access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_ACCESS_SECRET bucket: "apidocs.ortussolutions.com" - local-dir: build/apidocs - upload-dir: coldbox-modules/$MODULE_ID + local-dir: $TRAVIS_BUILD_DIR/.tmp/apidocs + upload-dir: coldbox-modules/$MODULE_ID/$TARGET_VERSION acl: public_read + # Github Release only on Master + - provider: releases + api_key: ${GITHUB_TOKEN} + on: + branch: + - master + condition: "$ENGINE = lucee@5" + skip_cleanup: true + edge: true + file_glob: true + file: $TRAVIS_BUILD_DIR/.artifacts/$MODULE_ID/**/* + release_notes_file: changelog.md + name: v${TRAVIS_TAG} + tag_name: v${TRAVIS_TAG} + overwrite: true +# Once API Docs and Binaries are deployed to S3 Publish to ForgeBox after_deploy: - - cd $TRAVIS_BUILD_DIR/build && box forgebox publish + # Move to build out artifact + - cd ${TRAVIS_BUILD_DIR}/.tmp/${MODULE_ID} + - cat box.json + # Only publish once using the lucee matrix + - if [ ${ENGINE} = 'lucee@5' ]; then box forgebox publish; fi diff --git a/modules/cbjavaloader/ModuleConfig.cfc b/ModuleConfig.cfc similarity index 85% rename from modules/cbjavaloader/ModuleConfig.cfc rename to ModuleConfig.cfc index 049ac6b..0e7c3d9 100644 --- a/modules/cbjavaloader/ModuleConfig.cfc +++ b/ModuleConfig.cfc @@ -1,8 +1,8 @@ /** -* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -*/ + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + */ component { // Module Properties @@ -10,14 +10,13 @@ component { this.author = "Ortus Solutions"; this.webURL = "https://www.ortussolutions.com"; this.description = "A JavaLoader Module for ColdBox"; - this.version = "@build.version@+@build.number@"; this.cfmapping = "cbjavaloader"; /** - * Configure module - */ + * Configure module + */ function configure(){ - + settings = { // The array paths to load loadPaths = [], @@ -32,24 +31,24 @@ component { // Whether or not the source is trusted, i.e. it is going to change? Defaults to false, so changes will be recompiled and loaded trustedSource = false }; - + // Register Custom DSL, don't map it because it is too late, mapping DSLs are only good by the parent app wireBox .registerDSL( namespace="javaloader", path="#moduleMapping#.models.JavaLoaderDSL" ); } /** - * Fired when the module is registered and activated. - */ + * Fired when the module is registered and activated. + */ function onLoad(){ // Bind Core JavaLoader binder.map( "jl@cbjavaloader" ) .to( "#moduleMapping#.models.javaloader.JavaLoader" ); - + // Duplicating so our final change won't affect the main module settings var finalSettings = duplicate( settings ); - + // Start with empty array finalSettings.loadPaths = []; @@ -60,7 +59,7 @@ component { if( isSimpleValue( moduleSettingsLoadPath ) ) { moduleSettingsLoadPath = moduleSettingsLoadPath.listToArray(); } - + // Loop over settings, adding files and expanding directories for( var thisLocation in moduleSettingsLoadPath ){ if( directoryExists( thisLocation ) ) { @@ -68,7 +67,7 @@ component { } else if ( fileExists( thisLocation ) ) { finalSettings.loadPaths.append( thisLocation ); } else { - throw( "Javaloader cannot load #thisLocation# as it is not a valid path or file" ); + throw( "Javaloader cannot load #thisLocation# as it is not a valid path or file" ); } } @@ -77,25 +76,25 @@ component { finalSettings.loadPaths, variables.modulePath & "/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar" ); - + // Load JavaLoader and class loading wirebox.getInstance( "loader@cbjavaloader" ).setup( finalSettings ); } /** - * Get an array of jar files - */ + * Get an array of jar files + */ private array function getJars( required string dirPath, string filter="*.jar" ){ if( not directoryExists( arguments.dirPath ) ){ throw( message="Invalid library path", detail="The path is #arguments.dirPath#", type="JavaLoader.DirectoryNotFoundException" ); } - return directoryList( - arguments.dirPath, - true, - "array", - arguments.filter, - "name desc" + return directoryList( + arguments.dirPath, + true, + "array", + arguments.filter, + "name desc" ); } diff --git a/apidocs/Application.cfc b/apidocs/Application.cfc deleted file mode 100755 index 363f7d0..0000000 --- a/apidocs/Application.cfc +++ /dev/null @@ -1,18 +0,0 @@ -component{ - - this.name = "APIDocs" & hash(getCurrentTemplatePath()); - this.sessionManagement = true; - this.sessionTimeout = createTimeSpan(0,0,1,0); - - // API Root - API_ROOT = getDirectoryFromPath( getCurrentTemplatePath() ); - rootPath = REReplaceNoCase( API_ROOT, "apidocs(\\|\/)$", "" ); - - // MODULE NAME - request.moduleName = "cbjavaloader"; - - this.mappings[ "/docbox" ] = API_ROOT & "docbox"; - this.mappings[ "/root" ] = rootPath; - this.mappings[ "/#request.moduleName#" ] = rootPath & "modules/#request.moduleName#/models"; - -} \ No newline at end of file diff --git a/apidocs/box.json b/apidocs/box.json deleted file mode 100644 index 2875065..0000000 --- a/apidocs/box.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name":"API Docs", - "version":"1.0.0", - "slug":"module-apidocs", - "private":true, - "dependencies":{ - "docbox":"^2.2.1+27" - }, - "devDependencies":{}, - "installPaths":{ - "docbox":"docbox" - } -} \ No newline at end of file diff --git a/apidocs/index.cfm b/apidocs/index.cfm deleted file mode 100644 index 79d5ab6..0000000 --- a/apidocs/index.cfm +++ /dev/null @@ -1,22 +0,0 @@ - - - - docName = "#request.moduleName#-APIDocs"; - base = expandPath( "/#request.moduleName#" ); - docbox = new docbox.DocBox( properties = { - projectTitle = "#request.moduleName# v#url.version#", - outputDir = url.path - } ); - docbox.generate( source=base, mapping=request.moduleName ); - - - - - -

Done!

-Go to Docs! -
- diff --git a/apidocs/server.json b/apidocs/server.json deleted file mode 100644 index c37e697..0000000 --- a/apidocs/server.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "force":true, - "openbrowser":"false", - "web":{ - "http":{ - "port":"8511" - } - } -} \ No newline at end of file diff --git a/box.json b/box.json index 799dce9..e0d75e8 100644 --- a/box.json +++ b/box.json @@ -1,25 +1,32 @@ { - "name":"cbjavaloader Builder", - "version":"2.0.0", - "slug":"cbjavaloader-shell", - "private":false, - "defaultPort":0, - "dependencies":{ - "workbench":"git+https://github.com/Ortus-Solutions/unified-workbench.git", - "coldbox":"^4.3.0+188" - }, - "devDependencies":{ - "testbox":"^2.6.0+156" - }, - "installPaths":{ - "workbench":"workbench", - "coldbox":"coldbox", - "testbox":"testbox" - }, - "testbox":{ - "runner":"http://localhost:49616" - }, - "scripts":{ - "postVersion":"recipe workbench/bump.boxr" + "name" : "JavaLoader", + "author" : "Ortus Solutions.com ", + "version" : "2.0.0", + "location" : "http://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cbjavaloader/@build.version@/cbjavaloader-@build.version@.zip", + "slug" : "cbjavaloader", + "type" : "modules", + "homepage" : "https://github.com/coldbox-modules/cbox-javaloader", + "documentation" : "https://github.com/coldbox-modules/cbox-javaloader", + "repository" : { "type" : "git", "url" : "https://github.com/coldbox-modules/cbox-javaloader" }, + "shortDescription" : "A module to class load, compile and do much more with Java", + "license" : [ + { "type" : "Apache2", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } + ], + "contributors" : [ + "Brad Wood ", "Curt Gratz " + ], + "ignore":[ + "**/.*", + "tests", + "*/.md" + ], + "dependencies":{}, + "devDependencies":{}, + "installPaths":{}, + "scripts":{ + "release":"recipe build/release.boxr", + "format":"cfformat run models/,test-harness/tests/ --overwrite", + "format:watch":"cfformat watch models/,test-harness/tests/", + "format:check":"cfformat check models/,test-harness/tests/" } } \ No newline at end of file diff --git a/build/Build.cfc b/build/Build.cfc new file mode 100644 index 0000000..20d86e4 --- /dev/null +++ b/build/Build.cfc @@ -0,0 +1,248 @@ +/** + * Build process for ColdBox Modules + * Adapt to your needs. + */ +component{ + + /** + * Constructor + */ + function init(){ + // Setup Pathing + variables.cwd = getCWD().reReplace( "\.$", "" ); + variables.artifactsDir = cwd & "/.artifacts"; + variables.buildDir = cwd & "/.tmp"; + variables.apiDocsURL = "http://localhost:60299/apidocs/"; + variables.testRunner = "http://localhost:60299/tests/runner.cfm"; + + // Source Excludes Not Added to final binary + variables.excludes = [ + ".gitignore", + ".travis.yml", + ".artifacts", + ".tmp", + "build", + "test-harness", + ".DS_Store", + ".git" + ]; + + // Cleanup + Init Build Directories + [ variables.buildDir, variables.artifactsDir ].each( function( item ){ + if( directoryExists( item ) ){ + directoryDelete( item, true ); + } + // Create directories + directoryCreate( item, true, true ); + } ); + + // Create Mappings + fileSystemUtil.createMapping( "coldbox", variables.cwd & "test-harness/coldbox" ); + + return this; + } + + /** + * Run the build process: test, build source, docs, checksums + * + * @projectName The project name used for resources and slugs + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building + */ + function run( + required projectName, + version="1.0.0", + buildID=createUUID(), + branch="development" + ){ + // Create project mapping + fileSystemUtil.createMapping( arguments.projectName, variables.cwd ); + + // Run the tests + runTests(); + + // Build the source + buildSource( argumentCollection=arguments ); + + // Build Docs + arguments.outputDir = variables.buildDir & "/apidocs"; + docs( argumentCollection=arguments ); + + // checksums + buildChecksums(); + + // Finalize Message + print.line() + .boldMagentaLine( "Build Process is done! Enjoy your build!" ) + .toConsole(); + } + + /** + * Run the test suites + */ + function runTests(){ + // Tests First, if they fail then exit + print.blueLine( "Testing the package, please wait..." ).toConsole(); + + command( 'testbox run' ) + .params( + runner = variables.testRunner, + verbose = true, + outputFile = "build/results.json" + ) + .run(); + + // Check Exit Code? + if( shell.getExitCode() ){ + return error( "Cannot continue building, tests failed!" ); + } + } + + /** + * Build the source + * + * @projectName The project name used for resources and slugs + * @version The version you are building + * @buldID The build identifier + * @branch The branch you are building + */ + function buildSource( + required projectName, + version="1.0.0", + buildID=createUUID(), + branch="development" + ){ + // Build Notice ID + print.line() + .boldMagentaLine( "Building #arguments.projectName# v#arguments.version#+#arguments.buildID# from #cwd# using the #arguments.branch# branch." ) + .toConsole(); + + // Prepare exports directory + variables.exportsDir = variables.artifactsDir & "/#projectName#/#arguments.version#"; + directoryCreate( variables.exportsDir, true, true ); + + // Project Build Dir + variables.projectBuildDir = variables.buildDir & "/#projectName#"; + directoryCreate( variables.projectBuildDir, true, true ); + + // Copy source + print.blueLine( "Copying source to build folder..." ).toConsole(); + copy( variables.cwd, variables.projectBuildDir ); + + // Create build ID + fileWrite( "#variables.projectBuildDir#/#projectName#-#version#+#buildID#", "Built with love on #dateTimeFormat( now(), "full")#" ); + + // Updating Placeholders + print.greenLine( "Updating version identifier to #arguments.version#" ).toConsole(); + command( 'tokenReplace' ) + .params( + path = "/#variables.projectBuildDir#/**", + token = "@build.version@", + replacement = arguments.version + ) + .run(); + + print.greenLine( "Updating build identifier to #arguments.buildID#" ).toConsole(); + command( 'tokenReplace' ) + .params( + path = "/#variables.projectBuildDir#/**", + token = ( arguments.branch == "master" ? "@build.number@" : "+@build.number@" ), + replacement = ( arguments.branch == "master" ? arguments.buildID : "-snapshot" ) + ) + .run(); + + // zip up source + var destination = "#variables.exportsDir#/#projectName#-#version#.zip"; + print.greenLine( "Zipping code to #destination#" ).toConsole(); + cfzip( + action="zip", + file="#destination#", + source="#variables.projectBuildDir#", + overwrite=true, + recurse=true + ); + + // Copy box.json for convenience + fileCopy( "#variables.projectBuildDir#/box.json", variables.exportsDir ); + } + + /** + * Produce the API Docs + */ + function docs( required projectName, version="1.0.0", outputDir=".tmp/apidocs" ){ + // Generate Docs + print.greenLine( "Generating API Docs, please wait..." ).toConsole(); + directoryCreate( arguments.outputDir, true, true ); + + command( 'docbox generate' ) + .params( + "source" = "models", + "mapping" = "models", + "strategy-projectTitle" = "#arguments.projectName# v#arguments.version#", + "strategy-outputDir" = arguments.outputDir + ) + .run(); + + print.greenLine( "API Docs produced at #arguments.outputDir#" ).toConsole(); + + var destination = "#variables.exportsDir#/#projectName#-docs-#version#.zip"; + print.greenLine( "Zipping apidocs to #destination#" ).toConsole(); + cfzip( + action="zip", + file="#destination#", + source="#arguments.outputDir#", + overwrite=true, + recurse=true + ); + } + + /********************************************* PRIVATE HELPERS *********************************************/ + + /** + * Build Checksums + */ + private function buildChecksums(){ + print.greenLine( "Building checksums" ).toConsole(); + command( 'checksum' ) + .params( path = '#variables.exportsDir#/*.zip', algorithm = 'SHA-512', extension="sha512", write=true ) + .run(); + command( 'checksum' ) + .params( path = '#variables.exportsDir#/*.zip', algorithm = 'md5', extension="md5", write=true ) + .run(); + } + + /** + * DirectoryCopy is broken in lucee + */ + private function copy( src, target, recurse=true ){ + // process paths with excludes + directoryList( src, false, "path", function( path ){ + var isExcluded = false; + variables.excludes.each( function( item ){ + if( path.replaceNoCase( variables.cwd, "", "all" ).findNoCase( item ) ){ + isExcluded = true; + } + } ); + return !isExcluded; + }).each( function( item ){ + // Copy to target + if( fileExists( item ) ){ + print.blueLine( "Copying #item#" ).toConsole(); + fileCopy( item, target ); + } else { + print.greenLine( "Copying directory #item#" ).toConsole(); + directoryCopy( item, target & "/" & item.replace( src, "" ), true ); + } + } ); + } + + /** + * Gets the last Exit code to be used + **/ + private function getExitCode() { + return (createObject( 'java', 'java.lang.System' ).getProperty( 'cfml.cli.exitCode' ) ?: 0); + + } + +} \ No newline at end of file diff --git a/build/release.boxr b/build/release.boxr new file mode 100755 index 0000000..e216f22 --- /dev/null +++ b/build/release.boxr @@ -0,0 +1,25 @@ +# This recipe signifies a new release of the module by doing merges and bumps accordingly + +# Check out master and update it locally +!git checkout -f master +!git pull origin master + +# Merge development into it for release +!git merge --no-ff development + +# Tag the master repo with the version from box.json +!git tag v`box package show version` + +# Push all branches back out to github +!git push origin --all + +# Push all tags +!git push origin --tags + +# Check development again +!git checkout -f development + +# Bump to prepare for a new release, do minor, change if needed and don't tag +bump --minor --!tagVersion +!git commit -a -m "version bump" +!git push origin development \ No newline at end of file diff --git a/changelog.md b/changelog.md index 77b754c..879c668 100644 --- a/changelog.md +++ b/changelog.md @@ -1,45 +1,81 @@ -# CHANGELOG +# Changelog -## 1.5.0 +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +---- + +## [2.0.0] => 2020-MAY-14 + +### Added + +* New module template support +* ColdBox 5-6 Support +* Modern Formatting + +### Removed + +* Lucee 4.5 Support +* ACF11 Support + +---- + +## [1.5.0] => 2018-MAR-16 * Updated interfaces for Coldbox 5 support * More local testing updates * Updated dependencies * Dropped cf10 support -## 1.4.0 +---- + +## [1.4.0] * Updated internal core Javaloader library to latest 1.2 release * Added automatic dynamic proxy class loading * Deprecating support for cf10 -## 1.3.3 +---- + +## [1.3.3] * Cleanup of testing Application.cfc -## 1.3.2 +---- + +## [1.3.2] * Removal of security issues with Javaloader `tags` directory * Securing execution of Javaloader models * Updated to unified workbench -## 1.3.1 +---- + +## [1.3.1] * Travis Update Builds * Adobe CF 2016,11,10 compatiblity fixes -## 1.3.0 +---- + +## [1.3.0] * Adobe CF Compatiblity -## 1.2.0 +---- + +## [1.2.0] * Travis Updates * Changing the array of locations check so that it doesn't fail if a JAR file is passed in the array. * Readme Updates * ForgeBox2 Updates -## 1.1.0 +---- + +## [1.1.0] * Travis Integration * DocBox update @@ -48,6 +84,8 @@ * CCM-12 loadpaths setting doesn't allow directory * Better documentation -## 1.0.0 +---- + +## [1.0.0] * Create first module version \ No newline at end of file diff --git a/config/.htaccess b/config/.htaccess deleted file mode 100644 index 3d45d68..0000000 --- a/config/.htaccess +++ /dev/null @@ -1,4 +0,0 @@ -#apache access file to protect the config.xml.cfm file. Delete this if you do not use apache. -authtype Basic -deny from all -Options -Indexes \ No newline at end of file diff --git a/config/Application.cfm b/config/Application.cfm deleted file mode 100644 index 50762fb..0000000 --- a/config/Application.cfm +++ /dev/null @@ -1,9 +0,0 @@ - - \ No newline at end of file diff --git a/config/Coldbox.cfc b/config/Coldbox.cfc deleted file mode 100644 index 333796e..0000000 --- a/config/Coldbox.cfc +++ /dev/null @@ -1,77 +0,0 @@ -component{ - - // Configure ColdBox Application - function configure(){ - - // coldbox directives - coldbox = { - //Application Setup - appName = "Development Shell", - - //Development Settings - reinitPassword = "", - handlersIndexAutoReload = true, - - //Implicit Events - defaultEvent = "main.index", - requestStartHandler = "", - requestEndHandler = "", - applicationStartHandler = "main.onAppInit", - applicationEndHandler = "", - sessionStartHandler = "", - sessionEndHandler = "", - missingTemplateHandler = "", - - //Extension Points - ApplicationHelper = "", - coldboxExtensionsLocation = "", - modulesExternalLocation = [], - pluginsExternalLocation = "", - viewsExternalLocation = "", - layoutsExternalLocation = "", - handlersExternalLocation = "", - requestContextDecorator = "", - - //Error/Exception Handling - exceptionHandler = "", - onInvalidEvent = "", - customErrorTemplate = "/coldbox/system/includes/BugReport.cfm", - - //Application Aspects - handlerCaching = false, - eventCaching = false, - proxyReturnCollection = false - }; - - // custom settings - settings = { - }; - - - //LogBox DSL - logBox = { - // Define Appenders - appenders = { - files={class="coldbox.system.logging.appenders.RollingFileAppender", - properties = { - filename = "appshell", filePath="/#appMapping#/logs" - } - } - }, - // Root Logger - root = { levelmax="DEBUG", appenders="*" }, - // Implicit Level Categories - info = [ "coldbox.system" ] - }; - - //Register interceptors as an array, we need order - interceptors = [ - //SES - {class="coldbox.system.interceptors.SES", - properties={} - } - ]; - - } - -} \ No newline at end of file diff --git a/config/Routes.cfm b/config/Routes.cfm deleted file mode 100644 index 9acad99..0000000 --- a/config/Routes.cfm +++ /dev/null @@ -1,20 +0,0 @@ - - // Allow unique URL or combination (false) - setUniqueURLS(false); - // Auto reload configuration, true in dev makes sense - //setAutoReload(false); - // Sets automatic route extension detection and places the extension in the rc.format - // setExtensionDetection(true) - // setValidExtensions('xml,json,jsont,rss,html,htm'); - - // Base URL - if( len(getSetting('AppMapping') ) lte 1){ - setBaseURL("http://#cgi.HTTP_HOST#/index.cfm"); - } - else{ - setBaseURL("http://#cgi.HTTP_HOST#/#getSetting('AppMapping')#/index.cfm"); - } - - // Your Application Routes - addRoute(pattern=":handler/:action?"); - \ No newline at end of file diff --git a/layouts/Main.cfm b/layouts/Main.cfm deleted file mode 100644 index 4e613f1..0000000 --- a/layouts/Main.cfm +++ /dev/null @@ -1 +0,0 @@ - <cfoutput>#getSetting( "appName" )#</cfoutput> #renderView()# \ No newline at end of file diff --git a/modules/cbjavaloader/lib/drop_jars_here.txt b/lib/drop_jars_here.txt similarity index 100% rename from modules/cbjavaloader/lib/drop_jars_here.txt rename to lib/drop_jars_here.txt diff --git a/models/JavaLoaderDSL.cfc b/models/JavaLoaderDSL.cfc new file mode 100644 index 0000000..e8fb09b --- /dev/null +++ b/models/JavaLoaderDSL.cfc @@ -0,0 +1,54 @@ +/* + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * The JavaLoader WireBox DSL + */ +component accessors="true" { + + /** + * WireBox Injector + */ + property name="injector"; + + /** + * Logger + */ + property name="log"; + + + /** + * Constructor as per interface + */ + public any function init( required any injector ) { + variables.injector = arguments.injector; + variables.log = arguments.injector.getLogBox().getLogger( this ); + + return this; + } + + /** + * Process an incoming DSL definition and produce an object with it. + */ + public any function process( required definition, targetObject ) { + var DSLNamespace = listFirst( arguments.definition.dsl, ":" ); + switch ( DSLNamespace ) { + case "javaloader": { + return getJavaLoaderDSL( argumentCollection = arguments ); + } + } + } + + /** + * Get a JavaLoader Dependency + */ + function getJavaLoaderDSL( required definition, targetObject ) { + var className = listLast( arguments.definition.dsl, ":" ); + + // Get Dependency, if not found, exception is thrown + return variables.injector + .getInstance( "loader@cbjavaloader" ) + .create( className ); + } + +} diff --git a/models/Loader.cfc b/models/Loader.cfc new file mode 100755 index 0000000..52b6613 --- /dev/null +++ b/models/Loader.cfc @@ -0,0 +1,165 @@ +/** + * Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp + * www.ortussolutions.com + * --- + * Loads External Java Classes, while providing access to ColdFusion classes by interfacing with JavaLoader + * it Stores a reference in server scope to avoid leakage. + */ +component accessors="true" singleton { + + property name="wirebox" inject="wirebox"; + + /** + * ID key saved in server scope to avoid leakage + */ + property name="staticIDKey"; + + /** + * Constructor + */ + function init() { + // setup a static ID key according to coldbox app + variables.staticIDKey = "cbox-javaloader-#hash( getCurrentTemplatePath() )#"; + return this; + } + + /** + * Setup class loading + */ + function setup( required struct moduleSettings ) { + // verify we have it loaded + if ( not isJavaLoaderInScope() ) { + lock name="#variables.staticIDKey#" throwontimeout="true" timeout="30" type="exclusive" { + if ( not isJavaLoaderInScope() ) { + setJavaLoaderInScope( + variables.wirebox.getInstance( + name = "jl@cbjavaloader", + initArguments = moduleSettings + ) + ); + } + } + } else { + // reconfigure it, maybe settings changed + lock name="#variables.staticIDKey#" throwontimeout="true" timeout="30" type="exclusive" { + getJavaLoaderFromScope().init( argumentCollection = moduleSettings ); + } + } + } + + /** + * Get the original java loader object from scope + */ + function getJavaLoader() { + return getJavaLoaderFromScope(); + } + + /** + * Retrieves a reference to the java class. To create a instance, you must run init() on this object + */ + function create( required string className ) { + return getJavaLoaderFromScope().create( argumentCollection = arguments ); + } + + /** + * Appends a directory path of *.jar's,*.classes to the current loaded class loader. + * @dirPath.hint The directory absolute path to load + * @filter.hint The directory filter + */ + function appendPaths( required string dirPath, string filter = "*.jar" ) { + // Convert paths to array of file locations + var qFiles = arrayOfJars( argumentCollection = arguments ); + var iterator = qFiles.iterator(); + var thisFile = ""; + var URLClassLoader = ""; + + // Try to check if javaloader in scope? else, set it up. + if ( NOT isJavaLoaderInScope() ) { + setup( qFiles ); + return; + } + + // Get URL Class Loader + URLClassLoader = getURLClassLoader(); + + // Try to load new locations + while ( iterator.hasNext() ) { + thisFile = createObject( "java", "java.io.File" ).init( iterator.next() ); + if ( NOT thisFile.exists() ) { + throw( + message = "The path you have specified could not be found", + detail = thisFile.getAbsolutePath() & "does not exist", + type = "PathNotFoundException" + ); + } + // Load up the URL + URLClassLoader.addUrl( thisFile.toURL() ); + } + } + + /** + * Get all the loaded URLs + */ + array function getLoadedURLs() { + var loadedURLs = getURLClassLoader().getURLs(); + var returnArray = arrayNew( 1 ); + var x = 1; + + for ( x = 1; x lte arrayLen( loadedURLs ); x = x + 1 ) { + arrayAppend( returnArray, loadedURLs[ x ].toString() ); + } + + return returnArray; + } + + /** + * Returns the java.net.URLClassLoader in case you need access to it + */ + any function getURLClassLoader() { + return getJavaLoaderFromScope().getURLClassLoader(); + } + + /** + * Get the Javaloader Version + */ + string function getVersion() { + return getJavaLoaderFromScope().getVersion(); + } + + /** + * Get an array of jars from a directory location + */ + array function arrayOfJars( required string dirPath, string filter = "*.jar" ) { + if ( not directoryExists( arguments.dirPath ) ) { + throw( + message = "Invalid library path", + detail = "The path is #dirPath#", + type = "JavaLoader.DirectoryNotFoundException" + ); + } + + return directoryList( + arguments.dirPath, + true, + "array", + arguments.filter, + "name desc" + ); + } + + /************************************** private *********************************************/ + + private function setJavaLoaderInScope( required any javaLoader ) { + server[ getStaticIDKey() ] = arguments.javaLoader; + } + + private function getJavaLoaderFromScope() { + return server[ getstaticIDKey() ]; + } + + + private boolean function isJavaLoaderInScope() { + return structKeyExists( server, getstaticIDKey() ); + } + +} diff --git a/models/javaloader/JavaCompiler.cfc b/models/javaloader/JavaCompiler.cfc new file mode 100644 index 0000000..b531e1d --- /dev/null +++ b/models/javaloader/JavaCompiler.cfc @@ -0,0 +1,231 @@ + + + + + + + var data = {}; + var defaultCompiler = "com.sun.tools.javac.api.JavacTool"; + + // we have to manually go looking for the compiler + + try { + data.compiler = getPageContext() + .getClass() + .getClassLoader() + .loadClass( defaultCompiler ) + .newInstance(); + } catch ( any exc ) { + println( "Error loading compiler:" ); + println( exc.toString() ); + } + + /* + If not by THIS point do we have a compiler, then throw an exception + */ + if ( NOT structKeyExists( data, "compiler" ) ) { + throwException( + "javaCompiler.NoCompilerAvailableException", + "No Java Compiler is available", + "There is no Java Compiler available. Make sure tools.jar is in your classpath and you are running Java 1.6+" + ); + } + + setCompiler( data.compiler ); + setJarDirectory( arguments.jarDirectory ); + + return this; + + + + + + + + + // setup file manager with default exception handler, default locale, and default character set + var fileManager = getCompiler().getStandardFileManager( + javacast( "null", "" ), + javacast( "null", "" ), + javacast( "null", "" ) + ); + var qFiles = 0; + var fileArray = []; + var directoryToCompile = 0; + var fileObjects = 0; + var osw = createObject( "java", "java.io.StringWriter" ).init(); + var options = []; + var compilePass = 0; + var jarPath = getJarDirectory() & "/" & arguments.jarName; + + + + + + + + arrayAppend( fileArray, qFiles.directory & "/" & qFiles.name ); + + + + + if ( structKeyExists( arguments, "classLoader" ) ) { + options = addClassLoaderFiles( + options, + arguments.classLoader, + arguments.directoryArray + ); + } + + fileObjects = fileManager.getJavaFileObjectsFromStrings( fileArray ); + + + + + // does the compilation + compilePass = getCompiler() + .getTask( + osw, + fileManager, + javacast( "null", "" ), + options, + javacast( "null", "" ), + fileObjects + ) + .call(); + + if ( NOT compilePass ) { + throwException( + "javacompiler.SourceCompilationException", + "There was an error compiling your source code", + osw.toString() + ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + var urls = 0; + var uri = 0; + var classPaths = createObject( "java", "java.lang.StringBuilder" ).init(); + var File = createObject( "java", "java.io.File" ); + var path = 0; + + + + + + + + classPaths.append( uri.getFile() ).append( File.pathSeparator ); + + + + + + + + + + + + arrayAppend( arguments.options, "-classpath" ); + arrayAppend( arguments.options, classPaths.toString() ); + + return arguments.options; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + createObject( "Java", "java.lang.System" ).out.println( arguments.str ); + + + diff --git a/models/javaloader/JavaLoader.cfc b/models/javaloader/JavaLoader.cfc new file mode 100644 index 0000000..c2afe22 --- /dev/null +++ b/models/javaloader/JavaLoader.cfc @@ -0,0 +1,724 @@ + + + + instance = structNew(); + instance.static.uuid = "A0608BEC-0AEB-B46A-0E1E1EC5F3CE7C9C"; + + + + + + + + + + + + + + initUseJavaProxyCFC(); + + if ( arguments.loadColdFusionClassPath ) { + // arguments.parentClassLoader = createObject("java", "java.lang.Thread").currentThread().getContextClassLoader(); + // can't use above, as doesn't work in some... things + + arguments.parentClassLoader = getPageContext().getClass().getClassLoader(); + + // arguments.parentClassLoader = createObject("java", "java.lang.ClassLoader").getSystemClassLoader(); + // can't use the above, it doesn't have the CF stuff in it. + } + + setClassLoadPaths( arguments.loadPaths ); + setParentClassLoader( arguments.parentClassLoader ); + + ensureNetworkClassLoaderOnServerScope(); + + loadClasses(); + + if ( structKeyExists( arguments, "sourceDirectories" ) AND arrayLen( arguments.sourceDirectories ) ) { + setJavaCompiler( createObject( "component", "JavaCompiler" ).init( arguments.compileDirectory ) ); + setSourceDirectories( arguments.sourceDirectories ); + setCompileDirectory( arguments.compileDirectory ); + + setTrustedSource( arguments.trustedSource ); + + compileSource(); + + setSourceLastModified( calculateSourceLastModified() ); + + // do the method switching for non-trusted source + if ( NOT arguments.trustedSource ) { + variables.createWithoutCheck = variables.create; + + structDelete( this, "create" ); + structDelete( variables, "create" ); + + this.create = variables.createWithSourceCheck; + } + } + + return this; + + + + + + + try { + // do this in one line just for speed. + return createJavaProxy( getURLClassLoader().loadClass( arguments.className ) ); + } catch ( java.lang.ClassNotFoundException exc ) { + throwException( + "javaloader.ClassNotFoundException", + "The requested class could not be found.", + "The requested class '#arguments.className#' could not be found in the loaded jars/directories." + ); + } + + + + + + + + + + + + + + var local = {}; + var func = 0; // need this as cf8 doesn't like the structure with functions. + var System = createObject( "java", "java.lang.System" ); + var Thread = createObject( "java", "java.lang.Thread" ); + var currentClassloader = Thread.currentThread().getContextClassLoader(); + var classLoader = ""; + + if ( structCount( arguments ) == 4 ) { + // the last 2 arguments are the function arguments and class loader + classLoader = arguments[ 4 ]; + local.funcArgs = arguments[ 3 ]; + } else if ( structCount( arguments ) == 3 ) { + // 2nd argument could be classloader or function arguments + if ( isInstanceOf( arguments[ 2 ], "java.lang.ClassLoader" ) ) { + classLoader = arguments[ 2 ]; + } else if ( isStruct( arguments[ 2 ] ) ) { + local.funcArgs = arguments[ 2 ]; + } + + // 3rd argument could be classloader or function arguments + if ( isInstanceOf( arguments[ 3 ], "java.lang.ClassLoader" ) ) { + classLoader = arguments[ 3 ]; + } else if ( isStruct( arguments[ 3 ] ) ) { + local.funcArgs = arguments[ 3 ]; + } + } else if ( structCount( arguments ) == 2 ) { + // the 2nd argument could be a class loader or function arguments + if ( isInstanceOf( arguments[ 2 ], "java.lang.ClassLoader" ) ) { + classLoader = arguments[ 2 ]; + } else if ( isStruct( arguments[ 2 ] ) ) { + local.funcArgs = arguments[ 2 ]; + } + } + + if ( !structKeyExists( local, "funcArgs" ) ) { + local.funcArgs = {}; + } + + if ( isSimpleValue( classLoader ) ) { + classLoader = getURLClassLoader(); + } + + + + + Thread.currentThread().setContextClassLoader( classloader ); + + + + + + + func = arguments[ 1 ]; + local.return = func( argumentCollection = local.funcArgs ); + + + + + + + + + + Thread.currentThread().setContextClassLoader( currentClassloader ); + + + + + + + // need to do this twice, as cf8 has no finally. + Thread.currentThread().setContextClassLoader( currentClassloader ); + + if ( structKeyExists( local, "return" ) ) { + return local.return; + } + + + + + + + + + + + + + + + var dateLastModified = calculateSourceLastModified(); + + /* + If the source has changed in any way, recompile and load + */ + if ( dateCompare( dateLastModified, getSourceLastModified() ) eq 1 ) { + loadClasses(); + compileSource(); + } + + // if all the comilation goes according to plan, set the date last modified + setSourceLastModified( dateLastModified ); + + return createWithoutCheck( argumentCollection = arguments ); + + + + + + var iterator = getClassLoadPaths().iterator(); + var file = 0; + var classLoader = 0; + var networkClassLoaderClass = 0; + var networkClassLoaderProxy = 0; + + networkClassLoaderClass = getServerURLClassLoader().loadClass( + "com.compoundtheory.classloader.NetworkClassLoader" + ); + + networkClassLoaderProxy = createJavaProxy( networkClassLoaderClass ); + + if ( isObject( getParentClassLoader() ) ) { + classLoader = networkClassLoaderProxy.init( getParentClassLoader() ); + } else { + classLoader = networkClassLoaderProxy.init(); + } + + while ( iterator.hasNext() ) { + file = createObject( "java", "java.io.File" ).init( iterator.next() ); + if ( NOT file.exists() ) { + throwException( + "javaloader.PathNotFoundException", + "The path you have specified could not be found", + file.getAbsolutePath() & " does not exist" + ); + } + + classLoader.addUrl( file.toURL() ); + } + + setURLClassLoader( classLoader ); + + + + + + var dir = 0; + var path = 0; + + var paths = 0; + var file = 0; + var counter = 1; + var len = 0; + var directories = 0; + + // do check to see if the compiled jar is already there + var jarName = calculateJarName( getSourceDirectories() ); + var jar = getCompileDirectory() & "/" & jarName; + + + + + + + + + + + + + + + + + + + + // first we copy the source to our tmp dir + directories = getSourceDirectories(); + len = arrayLen( directories ); + for ( ; counter lte len; counter = counter + 1 ) { + dir = directories[ counter ]; + $directoryCopy( dir, path ); + } + + // then we compile it, and grab that jar + + paths = arrayNew( 1 ); // have to write it this way so CF7 compiles + arrayAppend( paths, path ); + + jar = getJavaCompiler().compile( paths, getURLClassLoader(), jarName ); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + var file = hash( arrayToList( arguments.directoryArray ) ) & ".jar"; + + return file; + + + + + + var lastModified = createDate( 1900, 1, 1 ); + var dir = 0; + var qLastModified = 0; + var directories = getSourceDirectories(); + var len = arrayLen( directories ); + var counter = 0; + + + + + + + // it's possible there are no source files. + if ( qLastModified.recordCount ) { + // get the latest date modified + if ( dateCompare( lastModified, qlastModified.dateLastModified ) eq -1 ) { + /* + This is here, because cfdirectory only ever gives you minute accurate modified + date, which is not good enough. + */ + lastModified = createObject( "java", "java.util.Date" ).init( + createObject( "java", "java.io.File" ) + .init( qLastModified.directory & "/" & qLastModified.name ) + .lastModified() + ); + } + } else { + lastModified = now(); + } + + + + + + + + + var Class = createObject( "java", "java.lang.Class" ); + var Array = createObject( "java", "java.lang.reflect.Array" ); + var jars = queryJars(); + var iterator = jars.iterator(); + var file = 0; + var urls = Array.newInstance( Class.forName( "java.net.URL" ), arrayLen( jars ) ); + var counter = 0; + var urlClassLoader = 0; + var key = instance.static.uuid & "." & getVersion(); + + + + + + if ( NOT structKeyExists( server, key ) ) { + while ( iterator.hasNext() ) { + Array.set( + urls, + counter, + createObject( "java", "java.io.File" ).init( iterator.next() ).toURL() + ); + counter = counter + 1; + } + + urlClassLoader = createObject( "java", "java.net.URLClassLoader" ).init( urls ); + + // put it on the server scope + server[ key ] = urlClassLoader; + } + + + + + + + + + return createObject( "java", "coldfusion.runtime.java.JavaProxy" ).init( arguments.class ); + + + + + + + return createObject( "component", "JavaProxy" )._init( arguments.class ); + + + + + + try { + createObject( "java", "coldfusion.runtime.java.JavaProxy" ); + } catch ( Object exc ) { + // do method replacement, as it will be much faster long term + variables.createJavaProxy = variables.createJavaProxyCFC; + } + + + + + + var qJars = 0; + // the path to my jar library + var path = getDirectoryFromPath( getMetadata( this ).path ) & "lib/"; + var jarList = ""; + var aJars = arrayNew( 1 ); + var libName = 0; + + + + + + libName = listGetAt( qJars.name, 1, "-" ); + // let's not use the lib's that have the same name, but a lower datestamp + if ( NOT listFind( jarList, libName ) ) { + arrayAppend( aJars, path & "/" & qJars.name ); + jarList = listAppend( jarList, libName ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/models/javaloader/JavaProxy.cfc b/models/javaloader/JavaProxy.cfc new file mode 100644 index 0000000..aad9595 --- /dev/null +++ b/models/javaloader/JavaProxy.cfc @@ -0,0 +1,371 @@ + + + + + + + + + var classLoader = createObject( "java", "java.lang.ClassLoader" ).getSystemClassLoader(); + var objectClass = classLoader.loadClass( "java.lang.Object" ); + + _setArray( createObject( "java", "java.lang.reflect.Array" ) ); + + _setClassMethod( objectClass.getMethod( "getClass", javacast( "null", 0 ) ) ); + + _setObjectClass( objectClass ); + + _setClass( arguments.class ); + + _setModifier( createObject( "java", "java.lang.reflect.Modifier" ) ); + + _setStaticFields(); + + _initMethodCollection(); + + return this; + + + + + + var constructor = 0; + var instance = 0; + + // make sure we only ever have one instance + if ( _hasClassInstance() ) { + return _getClassInstance(); + } + + constructor = _resolveMethodByParams( + "Constructor", + _getClass().getConstructors(), + arguments + ); + + instance = constructor.newInstance( _buildArgumentArray( arguments ) ); + + _setClassInstance( instance ); + + return _getClassInstance(); + + + + + + + + + var method = _findMethod( arguments.missingMethodName, arguments.missingMethodArguments ); + + if ( _getModifier().isStatic( method.getModifiers() ) ) { + return method.invoke( javacast( "null", 0 ), _buildArgumentArray( arguments.missingMethodArguments ) ); + } else { + if ( NOT _hasClassInstance() ) { + // run the default constructor, just like in normal CF, if there is no instance + init(); + } + + return method.invoke( _getClassInstance(), _buildArgumentArray( arguments.missingMethodArguments ) ); + } + + + + + + + + + + + + var fields = _getClass().getFields(); + var counter = 1; + var len = arrayLen( fields ); + var field = 0; + + for ( ; counter <= len; counter++ ) { + field = fields[ counter ]; + if ( _getModifier().isStatic( field.getModifiers() ) ) { + this[ field.getName() ] = field.get( javacast( "null", 0 ) ); + } + } + + + + + + + var len = structCount( args ); + var objArray = _getArray().newInstance( _getObjectClass(), len ); + var counter = 1; + var obj = 0; + + for ( ; counter <= len; counter++ ) { + obj = args[ counter ]; + _getArray().set( objArray, counter - 1, obj ); + } + + return objArray; + + + + + + + + var decision = 0; + + if ( structKeyExists( _getMethodCollection(), arguments.methodName ) ) { + decision = structFind( _getMethodCollection(), arguments.methodName ); + + // if there is only one option, try it, it's only going to throw a runtime exception if it doesn't work. + if ( arrayLen( decision ) == 1 ) { + return decision[ 1 ]; + } else { + return _resolveMethodByParams( + arguments.methodName, + decision, + arguments.methodArgs + ); + } + } + + throwException( + "JavaProxy.MethodNotFoundException", + "Could not find the designated method", + "Could not find the method '#arguments.methodName#' in the class #_getClass().getName()#" + ); + + + + + + + + + var decisionLen = arrayLen( arguments.decision ); + var method = 0; + var counter = 1; + var argLen = arrayLen( arguments.methodArgs ); + var parameters = 0; + var paramLen = 0; + var pCounter = 0; + var param = 0; + var class = 0; + var found = true; + + for ( ; counter <= decisionLen; counter++ ) { + method = arguments.decision[ counter ]; + parameters = method.getParameterTypes(); + paramLen = arrayLen( parameters ); + + found = true; + + if ( argLen eq paramLen ) { + for ( pCounter = 1; pCounter <= paramLen AND found; pCounter++ ) { + param = parameters[ pCounter ]; + class = _getClassMethod().invoke( arguments.methodArgs[ pCounter ], javacast( "null", 0 ) ); + + if ( param.isAssignableFrom( class ) ) { + found = true; + } else if ( param.isPrimitive() ) + // if it's a primitive, it can be mapped to object primtive classes + { + if ( param.getName() eq "boolean" AND class.getName() eq "java.lang.Boolean" ) { + found = true; + } else if ( param.getName() eq "int" AND class.getName() eq "java.lang.Integer" ) { + found = true; + } else if ( param.getName() eq "long" AND class.getName() eq "java.lang.Long" ) { + found = true; + } else if ( param.getName() eq "float" AND class.getName() eq "java.lang.Float" ) { + found = true; + } else if ( param.getName() eq "double" AND class.getName() eq "java.lang.Double" ) { + found = true; + } else if ( param.getName() eq "char" AND class.getName() eq "java.lang.Character" ) { + found = true; + } else if ( param.getName() eq "byte" AND class.getName() eq "java.lang.Byte" ) { + found = true; + } else if ( param.getName() eq "short" AND class.getName() eq "java.lang.Short" ) { + found = true; + } else { + found = false; + } + } +else { + found = false; + } + } + + if ( found ) { + return method; + } + } + } + + throwException( + "JavaProxy.MethodNotFoundException", + "Could not find the designated method", + "Could not find the method '#arguments.methodName#' in the class #_getClass().getName()#" + ); + + + + + + var methods = _getClass().getMethods(); + var len = arrayLen( methods ); + var counter = 1; + var method = 0; + + _setMethodCollection( structNew() ); + + for ( ; counter <= len; counter++ ) { + method = methods[ counter ]; + + if ( NOT structKeyExists( _getMethodCollection(), method.getName() ) ) { + structInsert( + _getMethodCollection(), + method.getName(), + arrayNew( 1 ) + ); + } + + arrayAppend( structFind( _getMethodCollection(), method.getName() ), method ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/cbjavaloader/models/javaloader/README.md b/models/javaloader/README.md similarity index 100% rename from modules/cbjavaloader/models/javaloader/README.md rename to models/javaloader/README.md diff --git a/modules/cbjavaloader/models/javaloader/lib/classloader-20120103162851.jar b/models/javaloader/lib/classloader-20120103162851.jar similarity index 100% rename from modules/cbjavaloader/models/javaloader/lib/classloader-20120103162851.jar rename to models/javaloader/lib/classloader-20120103162851.jar diff --git a/modules/cbjavaloader/models/javaloader/licence.txt b/models/javaloader/licence.txt similarity index 100% rename from modules/cbjavaloader/models/javaloader/licence.txt rename to models/javaloader/licence.txt diff --git a/modules/cbjavaloader/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar b/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar similarity index 100% rename from modules/cbjavaloader/models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar rename to models/javaloader/support/cfcdynamicproxy/lib/cfcdynamicproxy.jar diff --git a/modules/cbjavaloader/models/javaloader/support/spring/lib/spring-coldfusion.jar b/models/javaloader/support/spring/lib/spring-coldfusion.jar similarity index 100% rename from modules/cbjavaloader/models/javaloader/support/spring/lib/spring-coldfusion.jar rename to models/javaloader/support/spring/lib/spring-coldfusion.jar diff --git a/modules/cbjavaloader/models/javaloader/tmp/tmp_compiled.txt b/models/javaloader/tmp/tmp_compiled.txt similarity index 100% rename from modules/cbjavaloader/models/javaloader/tmp/tmp_compiled.txt rename to models/javaloader/tmp/tmp_compiled.txt diff --git a/modules/cbjavaloader/box.json b/modules/cbjavaloader/box.json deleted file mode 100644 index 8122b7d..0000000 --- a/modules/cbjavaloader/box.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name" : "JavaLoader", - "author" : "Ortus Solutions.com ", - "version" : "@build.version@+@build.number@", - "location" : "http://downloads.ortussolutions.com/ortussolutions/coldbox-modules/cbjavaloader/@build.version@/cbjavaloader-@build.version@.zip", - "slug" : "cbjavaloader", - "type" : "modules", - "homepage" : "https://github.com/coldbox-modules/cbox-javaloader", - "documentation" : "https://github.com/coldbox-modules/cbox-javaloader", - "repository" : { "type" : "git", "url" : "https://github.com/coldbox-modules/cbox-javaloader" }, - "shortDescription" : "A module to class load, compile and do much more with Java", - "license" : [ - { "type" : "Apache2", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } - ], - "contributors" : [ - "Brad Wood ", "Curt Gratz " - ], - "ignore":[ - "**/.*", - "tests", - "*/.md" - ] -} \ No newline at end of file diff --git a/modules/cbjavaloader/models/JavaLoaderDSL.cfc b/modules/cbjavaloader/models/JavaLoaderDSL.cfc deleted file mode 100644 index 81ebb86..0000000 --- a/modules/cbjavaloader/models/JavaLoaderDSL.cfc +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* The JavaLoader WireBox DSL -*/ -component accessors="true"{ - - /** - * WireBox Injector - */ - property name="injector"; - - /** - * Logger - */ - property name="log"; - - - /** - * Constructor as per interface - */ - public any function init( required any injector ){ - variables.injector = arguments.injector; - variables.log = arguments.injector.getLogBox().getLogger( this ); - - return this; - } - - /** - * Process an incoming DSL definition and produce an object with it. - */ - public any function process( required definition, targetObject ){ - var DSLNamespace = listFirst( arguments.definition.dsl, ":" ); - switch( DSLNamespace ){ - case "javaloader" : { return getJavaLoaderDSL( argumentCollection=arguments );} - } - } - - /** - * Get a JavaLoader Dependency - */ - function getJavaLoaderDSL( required definition, targetObject ){ - var className = listLast( arguments.definition.dsl, ":" ); - - // Get Dependency, if not found, exception is thrown - return variables.injector.getInstance( "loader@cbjavaloader" ).create( className ); - } - -} diff --git a/modules/cbjavaloader/models/Loader.cfc b/modules/cbjavaloader/models/Loader.cfc deleted file mode 100755 index 3a3c091..0000000 --- a/modules/cbjavaloader/models/Loader.cfc +++ /dev/null @@ -1,147 +0,0 @@ -/** -* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -* www.ortussolutions.com -* --- -* Loads External Java Classes, while providing access to ColdFusion classes by interfacing with JavaLoader -* it Stores a reference in server scope to avoid leakage. -*/ -component accessors="true" singleton { - property name="wirebox" inject="wirebox"; - - /** - * ID key saved in server scope to avoid leakage - */ - property name="staticIDKey"; - - /** - * Constructor - */ - function init(){ - // setup a static ID key according to coldbox app - variables.staticIDKey = "cbox-javaloader-#hash( getCurrentTemplatePath() )#"; - return this; - } - - /** - * Setup class loading - */ - function setup( required struct moduleSettings ){ - // verify we have it loaded - if( not isJavaLoaderInScope() ){ - lock name="#variables.staticIDKey#" throwontimeout="true" timeout="30" type="exclusive"{ - if( not isJavaLoaderInScope() ){ - setJavaLoaderInScope( variables.wirebox.getInstance( name="jl@cbjavaloader", initArguments=moduleSettings ) ); - } - } - } else { - // reconfigure it, maybe settings changed - lock name="#variables.staticIDKey#" throwontimeout="true" timeout="30" type="exclusive"{ - getJavaLoaderFromScope().init( argumentCollection=moduleSettings ); - } - } - } - - /** - * Get the original java loader object from scope - */ - function getJavaLoader(){ - return getJavaLoaderFromScope(); - } - - /** - * Retrieves a reference to the java class. To create a instance, you must run init() on this object - */ - function create( required string className ){ - return getJavaLoaderFromScope().create( argumentCollection=arguments ); - } - - /** - * Appends a directory path of *.jar's,*.classes to the current loaded class loader. - * @dirPath.hint The directory absolute path to load - * @filter.hint The directory filter - */ - function appendPaths( required string dirPath, string filter="*.jar" ){ - // Convert paths to array of file locations - var qFiles = arrayOfJars( argumentCollection=arguments ); - var iterator = qFiles.iterator(); - var thisFile = ""; - var URLClassLoader = ""; - - // Try to check if javaloader in scope? else, set it up. - if( NOT isJavaLoaderInScope() ){ - setup( qFiles ); - return; - } - - // Get URL Class Loader - URLClassLoader = getURLClassLoader(); - - // Try to load new locations - while( iterator.hasNext() ){ - thisFile = createObject( "java", "java.io.File" ).init( iterator.next() ); - if(NOT thisFile.exists()){ - throw( message="The path you have specified could not be found", - detail=thisFile.getAbsolutePath() & "does not exist", - type="PathNotFoundException" ); - } - // Load up the URL - URLClassLoader.addUrl( thisFile.toURL() ); - } - } - - /** - * Get all the loaded URLs - */ - array function getLoadedURLs(){ - var loadedURLs = getURLClassLoader().getURLs(); - var returnArray = arrayNew(1); - var x = 1; - - for(x=1; x lte ArrayLen(loadedURLs); x=x+1){ - arrayAppend(returnArray, loadedURLs[x].toString()); - } - - return returnArray; - } - - /** - * Returns the java.net.URLClassLoader in case you need access to it - */ - any function getURLClassLoader(){ - return getJavaLoaderFromScope().getURLClassLoader(); - } - - /** - * Get the Javaloader Version - */ - string function getVersion(){ - return getJavaLoaderFromScope().getVersion(); - } - - /** - * Get an array of jars from a directory location - */ - array function arrayOfJars( required string dirPath, string filter="*.jar" ){ - if( not directoryExists( arguments.dirPath ) ){ - throw( message="Invalid library path", detail="The path is #dirPath#", type="JavaLoader.DirectoryNotFoundException" ); - } - - return directoryList( arguments.dirPath, true, "array", arguments.filter, "name desc" ); - } - - /************************************** private *********************************************/ - - private function setJavaLoaderInScope( required any javaLoader ){ - server[ getStaticIDKey() ] = arguments.javaLoader; - } - - private function getJavaLoaderFromScope(){ - return server[ getstaticIDKey() ]; - } - - - private boolean function isJavaLoaderInScope(){ - return structKeyExists( server, getstaticIDKey()); - } - -} diff --git a/modules/cbjavaloader/models/javaloader/JavaCompiler.cfc b/modules/cbjavaloader/models/javaloader/JavaCompiler.cfc deleted file mode 100644 index 9f4f172..0000000 --- a/modules/cbjavaloader/models/javaloader/JavaCompiler.cfc +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - var data = {}; - var defaultCompiler = "com.sun.tools.javac.api.JavacTool"; - - //we have to manually go looking for the compiler - - try - { - data.compiler = getPageContext().getClass().getClassLoader().loadClass(defaultCompiler).newInstance(); - } - catch(any exc) - { - println("Error loading compiler:"); - println(exc.toString()); - } - - /* - If not by THIS point do we have a compiler, then throw an exception - */ - if(NOT StructKeyExists(data, "compiler")) - { - throwException("javaCompiler.NoCompilerAvailableException", - "No Java Compiler is available", - "There is no Java Compiler available. Make sure tools.jar is in your classpath and you are running Java 1.6+"); - } - - setCompiler(data.compiler); - setJarDirectory(arguments.jarDirectory); - - return this; - - - - - - - - - //setup file manager with default exception handler, default locale, and default character set - var fileManager = getCompiler().getStandardFileManager(JavaCast("null", ""), JavaCast("null", ""), JavaCast("null", "")); - var qFiles = 0; - var fileArray = []; - var directoryToCompile = 0; - var fileObjects = 0; - var osw = createObject("java", "java.io.StringWriter").init(); - var options = []; - var compilePass = 0; - var jarPath = getJarDirectory() & "/" & arguments.jarName; - - - - - - - - ArrayAppend(fileArray, qFiles.directory & "/" & qFiles.name); - - - - - if(structKeyExists(arguments, "classLoader")) - { - options = addClassLoaderFiles(options, arguments.classLoader, arguments.directoryArray); - } - - fileObjects = fileManager.getJavaFileObjectsFromStrings(fileArray); - - - - - //does the compilation - compilePass = getCompiler().getTask(osw, fileManager, JavaCast("null", ""), options, JavaCast("null", ""), fileObjects).call(); - - if(NOT compilePass) - { - throwException("javacompiler.SourceCompilationException", "There was an error compiling your source code", osw.toString()); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var urls = 0; - var uri = 0; - var classPaths = createObject("java", "java.lang.StringBuilder").init(); - var File = createObject("java", "java.io.File"); - var path = 0; - - - - - - - - classPaths.append(uri.getFile()).append(File.pathSeparator); - - - - - - - - - - - - ArrayAppend(arguments.options, "-classpath"); - ArrayAppend(arguments.options, classPaths.toString()); - - return arguments.options; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - createObject("Java", "java.lang.System").out.println(arguments.str); - - - - \ No newline at end of file diff --git a/modules/cbjavaloader/models/javaloader/JavaLoader.cfc b/modules/cbjavaloader/models/javaloader/JavaLoader.cfc deleted file mode 100644 index acef892..0000000 --- a/modules/cbjavaloader/models/javaloader/JavaLoader.cfc +++ /dev/null @@ -1,608 +0,0 @@ - - - - - instance = StructNew(); - instance.static.uuid = "A0608BEC-0AEB-B46A-0E1E1EC5F3CE7C9C"; - - - - - - - - - - - - - - - initUseJavaProxyCFC(); - - if(arguments.loadColdFusionClassPath) - { - //arguments.parentClassLoader = createObject("java", "java.lang.Thread").currentThread().getContextClassLoader(); - //can't use above, as doesn't work in some... things - - arguments.parentClassLoader = getPageContext().getClass().getClassLoader(); - - //arguments.parentClassLoader = createObject("java", "java.lang.ClassLoader").getSystemClassLoader(); - //can't use the above, it doesn't have the CF stuff in it. - } - - setClassLoadPaths(arguments.loadPaths); - setParentClassLoader(arguments.parentClassLoader); - - ensureNetworkClassLoaderOnServerScope(); - - loadClasses(); - - if(structKeyExists(arguments, "sourceDirectories") AND ArrayLen(arguments.sourceDirectories)) - { - setJavaCompiler(createObject("component", "JavaCompiler").init(arguments.compileDirectory)); - setSourceDirectories(arguments.sourceDirectories); - setCompileDirectory(arguments.compileDirectory); - - setTrustedSource(arguments.trustedSource); - - compileSource(); - - setSourceLastModified(calculateSourceLastModified()); - - //do the method switching for non-trusted source - if(NOT arguments.trustedSource) - { - variables.createWithoutCheck = variables.create; - - StructDelete(this, "create"); - StructDelete(variables, "create"); - - this.create = variables.createWithSourceCheck; - } - } - - return this; - - - - - - - try - { - //do this in one line just for speed. - return createJavaProxy(getURLClassLoader().loadClass(arguments.className)); - } - catch(java.lang.ClassNotFoundException exc) - { - throwException("javaloader.ClassNotFoundException", "The requested class could not be found.", "The requested class '#arguments.className#' could not be found in the loaded jars/directories."); - } - - - - - - - - - - - - - - - var local = {}; - var func = 0; //need this as cf8 doesn't like the structure with functions. - var System = createObject("java", "java.lang.System"); - var Thread = createObject("java", "java.lang.Thread"); - var currentClassloader = Thread.currentThread().getContextClassLoader(); - var classLoader = ""; - - if (structCount(arguments) == 4) - { - // the last 2 arguments are the function arguments and class loader - classLoader = arguments[4]; - local.funcArgs = arguments[3]; - } - else if (structCount(arguments) == 3) - { - // 2nd argument could be classloader or function arguments - if (isInstanceOf(arguments[2],"java.lang.ClassLoader")) - { - classLoader = arguments[2]; - } - else if (isStruct(arguments[2])) - { - local.funcArgs = arguments[2]; - } - - // 3rd argument could be classloader or function arguments - if (isInstanceOf(arguments[3],"java.lang.ClassLoader")) - { - classLoader = arguments[3]; - } - else if (isStruct(arguments[3])) - { - local.funcArgs = arguments[3]; - } - } - else if (structCount(arguments) == 2) - { - // the 2nd argument could be a class loader or function arguments - if (isInstanceOf(arguments[2],"java.lang.ClassLoader")) - { - classLoader = arguments[2]; - } - else if (isStruct(arguments[2])) - { - local.funcArgs = arguments[2]; - } - } - - if (!structKeyExists(local,"funcArgs")) - { - local.funcArgs = {}; - } - - if (isSimpleValue(classLoader)) - { - classLoader = getURLClassLoader(); - } - - - - - Thread.currentThread().setContextClassLoader(classloader); - - - - - - - func = arguments[1]; - local.return = func(argumentCollection = local.funcArgs); - - - - - - - - - - Thread.currentThread().setContextClassLoader(currentClassloader); - - - - - - - //need to do this twice, as cf8 has no finally. - Thread.currentThread().setContextClassLoader(currentClassloader); - - if(structKeyExists(local, "return")) - { - return local.return; - } - - - - - - - - - - - - - - - var dateLastModified = calculateSourceLastModified(); - - /* - If the source has changed in any way, recompile and load - */ - if(dateCompare(dateLastModified, getSourceLastModified()) eq 1) - { - loadClasses(); - compileSource(); - } - - //if all the comilation goes according to plan, set the date last modified - setSourceLastModified(dateLastModified); - - return createWithoutCheck(argumentCollection=arguments); - - - - - - var iterator = getClassLoadPaths().iterator(); - var file = 0; - var classLoader = 0; - var networkClassLoaderClass = 0; - var networkClassLoaderProxy = 0; - - networkClassLoaderClass = getServerURLClassLoader().loadClass("com.compoundtheory.classloader.NetworkClassLoader"); - - networkClassLoaderProxy = createJavaProxy(networkClassLoaderClass); - - if(isObject(getParentClassLoader())) - { - classLoader = networkClassLoaderProxy.init(getParentClassLoader()); - } - else - { - classLoader = networkClassLoaderProxy.init(); - } - - while(iterator.hasNext()) - { - file = createObject("java", "java.io.File").init(iterator.next()); - if(NOT file.exists()) - { - throwException("javaloader.PathNotFoundException", "The path you have specified could not be found", file.getAbsolutePath() & " does not exist"); - } - - classLoader.addUrl(file.toURL()); - } - - setURLClassLoader(classLoader); - - - - - - var dir = 0; - var path = 0; - - var paths = 0; - var file = 0; - var counter = 1; - var len = 0; - var directories = 0; - - //do check to see if the compiled jar is already there - var jarName = calculateJarName(getSourceDirectories()); - var jar = getCompileDirectory() & "/" & jarName; - - - - - - - - - - - - - - - - - - - - //first we copy the source to our tmp dir - directories = getSourceDirectories(); - len = arraylen(directories); - for(; counter lte len; counter = counter + 1) - { - dir = directories[counter]; - $directoryCopy(dir, path); - } - - //then we compile it, and grab that jar - - paths = ArrayNew(1); //have to write it this way so CF7 compiles - ArrayAppend(paths, path); - - jar = getJavaCompiler().compile(paths, getURLClassLoader(), jarName); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var file = hash(arrayToList(arguments.directoryArray)) & ".jar"; - - return file; - - - - - - var lastModified = createDate(1900, 1, 1); - var dir = 0; - var qLastModified = 0; - var directories = getSourceDirectories(); - var len = arraylen(directories); - var counter = 0; - - - - - - - //it's possible there are no source files. - if(qLastModified.recordCount) - { - //get the latest date modified - if(dateCompare(lastModified, qlastModified.dateLastModified) eq -1) - { - /* - This is here, because cfdirectory only ever gives you minute accurate modified - date, which is not good enough. - */ - lastModified = createObject("java", "java.util.Date").init(createObject("java", "java.io.File").init(qLastModified.directory & "/" & qLastModified.name).lastModified()); - } - } - else - { - lastModified = Now(); - } - - - - - - - - - var Class = createObject("java", "java.lang.Class"); - var Array = createObject("java", "java.lang.reflect.Array"); - var jars = queryJars(); - var iterator = jars.iterator(); - var file = 0; - var urls = Array.newInstance(Class.forName("java.net.URL"), ArrayLen(jars)); - var counter = 0; - var urlClassLoader = 0; - var key = instance.static.uuid & "." & getVersion(); - - - - - - if(NOT StructKeyExists(server, key)) - { - while(iterator.hasNext()) - { - Array.set(urls, counter, createObject("java", "java.io.File").init(iterator.next()).toURL()); - counter = counter + 1; - } - - urlClassLoader = createObject("java", "java.net.URLClassLoader").init(urls); - - //put it on the server scope - server[key] = urlClassLoader; - } - - - - - - - - - return createObject("java", "coldfusion.runtime.java.JavaProxy").init(arguments.class); - - - - - - - return createObject("component", "JavaProxy")._init(arguments.class); - - - - - - try - { - createObject("java", "coldfusion.runtime.java.JavaProxy"); - } - catch(Object exc) - { - //do method replacement, as it will be much faster long term - variables.createJavaProxy = variables.createJavaProxyCFC; - } - - - - - - var qJars = 0; - //the path to my jar library - var path = getDirectoryFromPath(getMetaData(this).path) & "lib/"; - var jarList = ""; - var aJars = ArrayNew(1); - var libName = 0; - - - - - - libName = ListGetAt(qJars.name, 1, "-"); - //let's not use the lib's that have the same name, but a lower datestamp - if(NOT ListFind(jarList, libName)) - { - ArrayAppend(aJars, path & "/" & qJars.name); - jarList = ListAppend(jarList, libName); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/cbjavaloader/models/javaloader/JavaProxy.cfc b/modules/cbjavaloader/models/javaloader/JavaProxy.cfc deleted file mode 100644 index 8da0d2d..0000000 --- a/modules/cbjavaloader/models/javaloader/JavaProxy.cfc +++ /dev/null @@ -1,354 +0,0 @@ - - - - - - - - - - var classLoader = createObject("java", "java.lang.ClassLoader").getSystemClassLoader(); - var objectClass = classLoader.loadClass("java.lang.Object"); - - _setArray(createObject("java", "java.lang.reflect.Array")); - - _setClassMethod(objectClass.getMethod("getClass", JavaCast("null", 0))); - - _setObjectClass(objectClass); - - _setClass(arguments.class); - - _setModifier(createObject("java", "java.lang.reflect.Modifier")); - - _setStaticFields(); - - _initMethodCollection(); - - return this; - - - - - - var constructor = 0; - var instance = 0; - - //make sure we only ever have one instance - if(_hasClassInstance()) - { - return _getClassInstance(); - } - - constructor = _resolveMethodByParams("Constructor", _getClass().getConstructors(), arguments); - - instance = constructor.newInstance(_buildArgumentArray(arguments)); - - _setClassInstance(instance); - - return _getClassInstance(); - - - - - - - - - var method = _findMethod(arguments.missingMethodName, arguments.missingMethodArguments); - - if(_getModifier().isStatic(method.getModifiers())) - { - return method.invoke(JavaCast("null", 0), _buildArgumentArray(arguments.missingMethodArguments)); - } - else - { - if(NOT _hasClassInstance()) - { - //run the default constructor, just like in normal CF, if there is no instance - init(); - } - - return method.invoke(_getClassInstance(), _buildArgumentArray(arguments.missingMethodArguments)); - } - - - - - - - - - - - - var fields = _getClass().getFields(); - var counter = 1; - var len = ArrayLen(fields); - var field = 0; - - for(; counter <= len; counter++) - { - field = fields[counter]; - if(_getModifier().isStatic(field.getModifiers())) - { - this[field.getName()] = field.get(JavaCast("null", 0)); - } - } - - - - - - - var len = StructCount(args); - var objArray = _getArray().newInstance(_getObjectClass(), len); - var counter = 1; - var obj = 0; - - for(; counter <= len; counter++) - { - obj = args[counter]; - _getArray().set(objArray, counter - 1, obj); - } - - return objArray; - - - - - - - - var decision = 0; - - if(StructKeyExists(_getMethodCollection(), arguments.methodName)) - { - decision = StructFind(_getMethodCollection(), arguments.methodName); - - //if there is only one option, try it, it's only going to throw a runtime exception if it doesn't work. - if(ArrayLen(decision) == 1) - { - return decision[1]; - } - else - { - return _resolveMethodByParams(arguments.methodName, decision, arguments.methodArgs); - } - } - - throwException("JavaProxy.MethodNotFoundException", "Could not find the designated method", "Could not find the method '#arguments.methodName#' in the class #_getClass().getName()#"); - - - - - - - - - var decisionLen = ArrayLen(arguments.decision); - var method = 0; - var counter = 1; - var argLen = ArrayLen(arguments.methodArgs); - var parameters = 0; - var paramLen = 0; - var pCounter = 0; - var param = 0; - var class = 0; - var found = true; - - for(; counter <= decisionLen; counter++) - { - method = arguments.decision[counter]; - parameters = method.getParameterTypes(); - paramLen = ArrayLen(parameters); - - found = true; - - if(argLen eq paramLen) - { - for(pCounter = 1; pCounter <= paramLen AND found; pCounter++) - { - param = parameters[pCounter]; - class = _getClassMethod().invoke(arguments.methodArgs[pCounter], JavaCast("null", 0)); - - if(param.isAssignableFrom(class)) - { - found = true; - } - else if(param.isPrimitive()) //if it's a primitive, it can be mapped to object primtive classes - { - if(param.getName() eq "boolean" AND class.getName() eq "java.lang.Boolean") - { - found = true; - } - else if(param.getName() eq "int" AND class.getName() eq "java.lang.Integer") - { - found = true; - } - else if(param.getName() eq "long" AND class.getName() eq "java.lang.Long") - { - found = true; - } - else if(param.getName() eq "float" AND class.getName() eq "java.lang.Float") - { - found = true; - } - else if(param.getName() eq "double" AND class.getName() eq "java.lang.Double") - { - found = true; - } - else if(param.getName() eq "char" AND class.getName() eq "java.lang.Character") - { - found = true; - } - else if(param.getName() eq "byte" AND class.getName() eq "java.lang.Byte") - { - found = true; - } - else if(param.getName() eq "short" AND class.getName() eq "java.lang.Short") - { - found = true; - } - else - { - found = false; - } - } - else - { - found = false; - } - } - - if(found) - { - return method; - } - } - } - - throwException("JavaProxy.MethodNotFoundException", "Could not find the designated method", "Could not find the method '#arguments.methodName#' in the class #_getClass().getName()#"); - - - - - - var methods = _getClass().getMethods(); - var len = ArrayLen(methods); - var counter = 1; - var method = 0; - - _setMethodCollection(StructNew()); - - for(; counter <= len; counter++) - { - method = methods[counter]; - - if(NOT StructKeyExists(_getMethodCollection(), method.getName())) - { - StructInsert(_getMethodCollection(), method.getName(), ArrayNew(1)); - } - - ArrayAppend(StructFind(_getMethodCollection(), method.getName()), method); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/server.json b/server.json deleted file mode 100644 index 874e324..0000000 --- a/server.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "force":true, - "openbrowser":"false", - "web":{ - "http":{ - "port":"49616" - } - }, - "app":{ - "cfengine":"lucee@4.5", - "serverHomeDirectory":".engine/lucee4" - } -} \ No newline at end of file diff --git a/test-harness/.cfconfig.json b/test-harness/.cfconfig.json new file mode 100644 index 0000000..bd49f5d --- /dev/null +++ b/test-harness/.cfconfig.json @@ -0,0 +1,8 @@ +{ + "debuggingEnabled":true, + "debuggingReportExecutionTimes":false, + "disableInternalCFJavaComponents":false, + "inspectTemplate":"always", + "requestTimeout":"0,0,0,90", + "robustExceptionEnabled":true +} \ No newline at end of file diff --git a/test-harness/.cflintrc b/test-harness/.cflintrc new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test-harness/.cflintrc @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Application.cfc b/test-harness/Application.cfc similarity index 51% rename from Application.cfc rename to test-harness/Application.cfc index e10f74c..d3824e3 100644 --- a/Application.cfc +++ b/test-harness/Application.cfc @@ -1,24 +1,51 @@ -/** +/** ******************************************************************************** Copyright 2005-2007 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldboxframework.com | www.luismajano.com | www.ortussolutions.com +www.ortussolutions.com ******************************************************************************** */ component{ + + // UPDATE THE NAME OF THE MODULE IN TESTING BELOW + request.MODULE_NAME = "cbjavaloader"; + // Application properties - this.name = hash( getCurrentTemplatePath() ); + this.name = hash( getCurrentTemplatePath() ); this.sessionManagement = true; - this.sessionTimeout = createTimeSpan(0,0,30,0); - this.setClientCookies = true; + this.sessionTimeout = createTimeSpan(0,0,15,0); + this.setClientCookies = true; + + /************************************** + LUCEE Specific Settings + **************************************/ + // buffer the output of a tag/function body to output in case of a exception + this.bufferOutput = true; + // Activate Gzip Compression + this.compression = false; + // Turn on/off white space managemetn + this.whiteSpaceManagement = "smart"; + // Turn on/off remote cfc content whitespace + this.suppressRemoteComponentContent = false; // COLDBOX STATIC PROPERTY, DO NOT CHANGE UNLESS THIS IS NOT THE ROOT OF YOUR COLDBOX APP - COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); + COLDBOX_APP_ROOT_PATH = getDirectoryFromPath( getCurrentTemplatePath() ); // The web server mapping to this application. Used for remote purposes or static purposes - COLDBOX_APP_MAPPING = ""; + COLDBOX_APP_MAPPING = ""; // COLDBOX PROPERTIES - COLDBOX_CONFIG_FILE = ""; + COLDBOX_CONFIG_FILE = ""; // COLDBOX APPLICATION KEY OVERRIDE - COLDBOX_APP_KEY = ""; + COLDBOX_APP_KEY = ""; + + // Mappings + this.mappings[ "/root" ] = COLDBOX_APP_ROOT_PATH; + + // Map back to its root + moduleRootPath = REReplaceNoCase( this.mappings[ "/root" ], "#request.MODULE_NAME#(\\|/)test-harness(\\|/)", "" ); + modulePath = REReplaceNoCase( this.mappings[ "/root" ], "test-harness(\\|/)", "" ); + + // Module Root + Path Mappings + this.mappings[ "/moduleroot" ] = moduleRootPath; + this.mappings[ "/#request.MODULE_NAME#" ] = modulePath; // application start public boolean function onApplicationStart(){ @@ -29,6 +56,7 @@ component{ // request start public boolean function onRequestStart(String targetPage){ + // Process ColdBox Request application.cbBootstrap.onRequestStart( arguments.targetPage ); diff --git a/test-harness/box.json b/test-harness/box.json new file mode 100644 index 0000000..f660017 --- /dev/null +++ b/test-harness/box.json @@ -0,0 +1,20 @@ +{ + "name":"Tester", + "version":"0.0.0", + "slug":"tester", + "private":true, + "description":"", + "dependencies":{ + "coldbox":"^5.0.0" + }, + "devDependencies":{ + "testbox":"^4.0.0" + }, + "installPaths":{ + "coldbox":"coldbox/", + "testbox":"testbox/" + }, + "testbox":{ + "runner":"http://localhost:60299/tests/runner.cfm" + } +} \ No newline at end of file diff --git a/test-harness/config/Application.cfc b/test-harness/config/Application.cfc new file mode 100644 index 0000000..23c5ad0 --- /dev/null +++ b/test-harness/config/Application.cfc @@ -0,0 +1,7 @@ +/** +* This is a protection Application cfm for the config file. You do not +* need to modify this file +*/ +component{ + abort; +} \ No newline at end of file diff --git a/test-harness/config/Coldbox.cfc b/test-harness/config/Coldbox.cfc new file mode 100644 index 0000000..6a3f72d --- /dev/null +++ b/test-harness/config/Coldbox.cfc @@ -0,0 +1,110 @@ +component{ + + // Configure ColdBox Application + function configure(){ + + // coldbox directives + coldbox = { + //Application Setup + appName = "Module Tester", + + //Development Settings + reinitPassword = "", + handlersIndexAutoReload = true, + modulesExternalLocation = [], + + //Implicit Events + defaultEvent = "", + requestStartHandler = "", + requestEndHandler = "", + applicationStartHandler = "main.onAppInit", + applicationEndHandler = "", + sessionStartHandler = "", + sessionEndHandler = "", + missingTemplateHandler = "", + + //Error/Exception Handling + exceptionHandler = "", + onInvalidEvent = "", + customErrorTemplate = "/coldbox/system/includes/BugReport.cfm", + + //Application Aspects + handlerCaching = false, + eventCaching = false + }; + + // environment settings, create a detectEnvironment() method to detect it yourself. + // create a function with the name of the environment so it can be executed if that environment is detected + // the value of the environment is a list of regex patterns to match the cgi.http_host. + environments = { + development = "localhost,127\.0\.0\.1" + }; + + // Module Directives + modules = { + // An array of modules names to load, empty means all of them + include = [], + // An array of modules names to NOT load, empty means none + exclude = [] + }; + + //Register interceptors as an array, we need order + interceptors = [ + //SES + { class="coldbox.system.interceptors.SES" } + ]; + + //LogBox DSL + logBox = { + // Define Appenders + appenders = { + files={class="coldbox.system.logging.appenders.RollingFileAppender", + properties = { + filename = "tester", filePath="/#appMapping#/logs" + } + } + }, + // Root Logger + root = { levelmax="DEBUG", appenders="*" }, + // Implicit Level Categories + info = [ "coldbox.system" ] + }; + + //Debugger Settings + debugger = { + // Debugger + debugMode = true, + debugPassword = "", + enableDumpVar = false, + persistentRequestProfilers = true, + maxPersistentRequestProfilers = 10, + maxRCPanelQueryRows = 50, + showRCSnapshots = true, + //Panels + showTracerPanel = true, + expandedTracerPanel = false, + showInfoPanel = true, + expandedInfoPanel = true, + showCachePanel = true, + expandedCachePanel = false, + showRCPanel = true, + expandedRCPanel = false, + showModulesPanel = true, + expandedModulesPanel = false, + wireboxCreationProfiler=true + }; + + } + + /** + * Load the Module you are testing + */ + function afterAspectsLoad( event, interceptData, rc, prc ){ + controller.getModuleService() + .registerAndActivateModule( + moduleName = request.MODULE_NAME, + invocationPath = "moduleroot" + ); + } + +} \ No newline at end of file diff --git a/test-harness/config/Routes.cfm b/test-harness/config/Routes.cfm new file mode 100644 index 0000000..a304d25 --- /dev/null +++ b/test-harness/config/Routes.cfm @@ -0,0 +1,46 @@ + + // Allow unique URL or combination of URLs, we recommend both enabled + setUniqueURLS(false); + // Auto reload configuration, true in dev makes sense to reload the routes on every request + //setAutoReload(false); + // Sets automatic route extension detection and places the extension in the rc.format variable + // setExtensionDetection(true); + // The valid extensions this interceptor will detect + // setValidExtensions('xml,json,jsont,rss,html,htm'); + // If enabled, the interceptor will throw a 406 exception that an invalid format was detected or just ignore it + // setThrowOnInvalidExtension(true); + + // Base URL + if( len(getSetting('AppMapping') ) lte 1){ + setBaseURL("http://#cgi.HTTP_HOST#/"); + } + else{ + setBaseURL("http://#cgi.HTTP_HOST#/#getSetting('AppMapping')#/"); + } + + // Your Application Routes + addRoute(pattern=":handler/:action?"); + + + /** Developers can modify the CGI.PATH_INFO value in advance of the SES + interceptor to do all sorts of manipulations in advance of route + detection. If provided, this function will be called by the SES + interceptor instead of referencing the value CGI.PATH_INFO. + + This is a great place to perform custom manipulations to fix systemic + URL issues your Web site may have or simplify routes for i18n sites. + + @Event The ColdBox RequestContext Object + **/ + function PathInfoProvider(Event){ + /* Example: + var URI = CGI.PATH_INFO; + if (URI eq "api/foo/bar") + { + Event.setProxyRequest(true); + return "some/other/value/for/your/routes"; + } + */ + return CGI.PATH_INFO; + } + \ No newline at end of file diff --git a/test-harness/config/WireBox.cfc b/test-harness/config/WireBox.cfc new file mode 100644 index 0000000..3aafc01 --- /dev/null +++ b/test-harness/config/WireBox.cfc @@ -0,0 +1,46 @@ +component extends="coldbox.system.ioc.config.Binder"{ + + /** + * Configure WireBox, that's it! + */ + function configure(){ + + // The WireBox configuration structure DSL + wireBox = { + // Scope registration, automatically register a wirebox injector instance on any CF scope + // By default it registeres itself on application scope + scopeRegistration = { + enabled = true, + scope = "application", // server, cluster, session, application + key = "wireBox" + }, + + // DSL Namespace registrations + customDSL = { + // namespace = "mapping name" + }, + + // Custom Storage Scopes + customScopes = { + // annotationName = "mapping name" + }, + + // Package scan locations + scanLocations = [], + + // Stop Recursions + stopRecursions = [], + + // Parent Injector to assign to the configured injector, this must be an object reference + parentInjector = "", + + // Register all event listeners here, they are created in the specified order + listeners = [ + // { class="", name="", properties={} } + ] + }; + + // Map Bindings below + } + +} \ No newline at end of file diff --git a/handlers/Main.cfc b/test-harness/handlers/Main.cfc similarity index 98% rename from handlers/Main.cfc rename to test-harness/handlers/Main.cfc index 2a71296..0f0b859 100644 --- a/handlers/Main.cfc +++ b/test-harness/handlers/Main.cfc @@ -1,4 +1,4 @@ -/** +/** * My Event Handler Hint */ component{ diff --git a/index.cfm b/test-harness/index.cfm similarity index 89% rename from index.cfm rename to test-harness/index.cfm index be3dc78..7331009 100644 --- a/index.cfm +++ b/test-harness/index.cfm @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + #testbox.init( directory=rootMapping & url.path ).run()# + +

Invalid incoming directory: #rootMapping & url.path#

+
+ + +
+ + + + + + + + + + + + + + + + + + TestBox Global Runner + + + + + + + + +
+
+ + +
+
v#testbox.getVersion()#
+ + +
+ +
+

TestBox Test Browser:

+

+ Below is a listing of the files and folders starting from your root #rootPath#. You can click on individual tests in order to execute them + or click on the Run All button on your left and it will execute a directory runner from the visible folder. +

+ +
Contents: #executePath# + +

+
+ + + + + + + + +#qResults.name#
+ + target="_blank"
>#qResults.name#
+ + target="_blank">#qResults.name#
+ + #qResults.name#
+ + +
+
+ +
+ +
+
+ + +
+ + + +
\ No newline at end of file diff --git a/tests/runner.cfm b/test-harness/tests/runner.cfm similarity index 100% rename from tests/runner.cfm rename to test-harness/tests/runner.cfm diff --git a/test-harness/tests/specs/LoaderTest.cfc b/test-harness/tests/specs/LoaderTest.cfc new file mode 100644 index 0000000..bdd2fad --- /dev/null +++ b/test-harness/tests/specs/LoaderTest.cfc @@ -0,0 +1,56 @@ +/** + * My BDD Test + */ +component extends="coldbox.system.testing.BaseTestCase" appMapping="/root" { + + /*********************************** LIFE CYCLE Methods ***********************************/ + + // executes before all suites+specs in the run() method + function beforeAll() { + super.beforeAll(); + } + + // executes after all suites+specs in the run() method + function afterAll() { + super.afterAll(); + structDelete( server, getLoader().getStaticIDKey() ); + } + + /*********************************** BDD SUITES ***********************************/ + + function run() { + // all your suites go here. + describe( "JavaLoader Module", function() { + beforeEach( function( currentSpec ) { + setup(); + } ); + + it( "should register loader proxy", function() { + var loader = getLoader(); + expect( loader ).toBeComponent(); + } ); + + it( "should class load jar files", function() { + var event = execute( "main.index" ); + var prc = event.getCollection( private = true ); + expect( prc.hello ).toBe( "Hello World" ); + } ); + + it( "should get loaded URLs", function() { + var loader = getLoader(); + expect( loader.getLoadedURls() ).toBeArray(); + expect( loader.getLoadedURLs() ).toHaveLength( 2 ); + } ); + + it( "should retrieve via custom DSL", function() { + var hello = getWireBox().getInstance( dsl = "javaloader:HelloWorld" ); + expect( isObject( hello ) ).toBeTrue(); + } ); + } ); + } + + private function getLoader() { + return getWireBox().getInstance( "loader@cbjavaloader" ); + } + +} diff --git a/views/main/index.cfm b/test-harness/views/main/index.cfm similarity index 100% rename from views/main/index.cfm rename to test-harness/views/main/index.cfm diff --git a/tests/Application.cfc b/tests/Application.cfc deleted file mode 100644 index b6f53ab..0000000 --- a/tests/Application.cfc +++ /dev/null @@ -1,24 +0,0 @@ -/** -* Copyright Since 2005 Ortus Solutions, Corp -* www.coldbox.org | www.luismajano.com | www.ortussolutions.com | www.gocontentbox.org -************************************************************************************** -*/ -component{ - this.name = "A TestBox Runner Suite " & hash( getCurrentTemplatePath() ); - // any other application.cfc stuff goes below: - this.sessionManagement = true; - // Turn on/off white space managemetn - this.whiteSpaceManagement = "smart"; - - // any mappings go here, we create one that points to the root called test. - this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() ); - rootPath = REReplaceNoCase( this.mappings[ "/tests" ], "tests(\\|/)", "" ); - this.mappings[ "/root" ] = rootPath; - - // any orm definitions go here. - - // request start - public boolean function onRequestStart( String targetPage ){ - return true; - } -} \ No newline at end of file diff --git a/tests/specs/LoaderTest.cfc b/tests/specs/LoaderTest.cfc deleted file mode 100644 index bacc631..0000000 --- a/tests/specs/LoaderTest.cfc +++ /dev/null @@ -1,60 +0,0 @@ -/** -* My BDD Test -*/ -component extends="coldbox.system.testing.BaseTestCase" appMapping="/root"{ - -/*********************************** LIFE CYCLE Methods ***********************************/ - - // executes before all suites+specs in the run() method - function beforeAll(){ - super.beforeAll(); - } - - // executes after all suites+specs in the run() method - function afterAll(){ - super.afterAll(); - structDelete( server, getLoader().getStaticIDKey() ); - } - -/*********************************** BDD SUITES ***********************************/ - - function run(){ - - // all your suites go here. - describe( "JavaLoader Module", function(){ - - beforeEach(function( currentSpec ){ - setup(); - }); - - it( "should register loader proxy", function(){ - var loader = getLoader(); - expect( loader ).toBeComponent(); - }); - - it( "should class load jar files", function(){ - var event = execute( "main.index" ); - var prc = event.getCollection( private=true ); - expect( prc.hello ) - .toBe( "Hello World" ); - }); - - it( "should get loaded URLs", function(){ - var loader = getLoader(); - expect( loader.getLoadedURls() ).toBeArray(); - expect( loader.getLoadedURLs() ).toHaveLength( 2 ); - }); - - it( "should retrieve via custom DSL", function(){ - var hello = getWireBox().getInstance( dsl="javaloader:HelloWorld" ); - expect( isObject( hello ) ).toBeTrue(); - }); - }); - - } - - private function getLoader(){ - return getWireBox().getInstance( "loader@cbjavaloader" ); - } - -} \ No newline at end of file diff --git a/tests/specs/put_test_bundles_here.txt b/tests/specs/put_test_bundles_here.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/test.properties b/tests/test.properties deleted file mode 100644 index 6e00f38..0000000 --- a/tests/test.properties +++ /dev/null @@ -1,5 +0,0 @@ -url.runners.lucee@4.5=http://127.0.0.1:50680/tests/runner.cfm? -url.runners.lucee@5=http://127.0.0.1:50685/tests/runner.cfm? -url.runners.adobe@10=http://127.0.0.1:49610/tests/runner.cfm? -url.runners.adobe@11=http://127.0.0.1:49611/tests/runner.cfm? -url.runners.adobe@2016=http://127.0.0.1:49616/tests/runner.cfm? \ No newline at end of file diff --git a/tests/test.xml b/tests/test.xml deleted file mode 100644 index ea2608e..0000000 --- a/tests/test.xml +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Loading properties from environment: ${environment} - - - - - Loading base properties - - - - - - - - - - - - Tests ran at ${start.TODAY} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file