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 83% rename from modules/cbjavaloader/ModuleConfig.cfc rename to ModuleConfig.cfc index 8f480ae..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( "Javalaoder 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/readme.md b/readme.md index b7b6004..d731d29 100644 --- a/readme.md +++ b/readme.md @@ -17,8 +17,8 @@ Apache License, Version 2.0. ## System Requirements -- Lucee 4.5+ -- ColdFusion 11+ +- Lucee 5+ +- ColdFusion 2016+ ## Instructions @@ -29,6 +29,7 @@ Just drop into your **modules** folder or use the box-cli to install The module has a default folder called `lib` where any jars you drop there will be class loaded automatically. However, we recommend using the `loadpaths` setting for selecting an array of locations to class load, so when the module updates you won't lose those files. ## Models + The module registers the following mapping in WireBox: `loader@cbjavaloader`. Which is the class you will use to class load, append paths and much more. Check out the included API Docs for much more information. The main methods of importance of the java loader are: * `create( class )` - Create a loaded Java class @@ -36,6 +37,7 @@ The module registers the following mapping in WireBox: `loader@cbjavaloader`. Wh * `getLoadedURLs()` - Get all the loaded URLs ## WireBox DSL + The module also registers a new WireBox DSL called `javaloader`. You can then use this custom DSL for injecting direct java class loaded classes very easily: ```js @@ -101,7 +103,8 @@ Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp www.ortussolutions.com ******************************************************************************** -#### HONOR GOES TO GOD ABOVE ALL +### HONOR GOES TO GOD ABOVE ALL + Because of His grace, this project exists. If you don't like this, then don't read it, its not for you. >"Therefore being justified by faith, we have peace with God through our Lord Jesus Christ: @@ -112,4 +115,5 @@ And hope maketh not ashamed; because the love of God is shed abroad in our heart Holy Ghost which is given unto us. ." Romans 5:5 ### THE DAILY BREAD + > "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12 \ 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